import React, { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Progress } from '@/components/ui/progress'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { ArrowLeft, Play, Pause, Download, RefreshCw } from 'lucide-react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; import '../App.css'; const ProjectView = ({ projectId, onBack }) => { const [project, setProject] = useState(null); const [logs, setLogs] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); useEffect(() => { fetchProject(); fetchLogs(); // Auto-refresh if project is running const interval = setInterval(() => { if (project?.status === 'running') { fetchProject(); fetchLogs(); } }, 5000); return () => clearInterval(interval); }, [projectId, project?.status]); const fetchProject = async () => { try { const response = await fetch(`/api/projects/${projectId}`); const data = await response.json(); setProject(data); } catch (error) { console.error('Erro ao buscar projeto:', error); } finally { setLoading(false); } }; const fetchLogs = async () => { try { const response = await fetch(`/api/projects/${projectId}/logs`); const data = await response.json(); setLogs(data.logs || []); } catch (error) { console.error('Erro ao buscar logs:', error); } }; const handleRefresh = async () => { setRefreshing(true); await fetchProject(); await fetchLogs(); setRefreshing(false); }; const handleStartTraining = async () => { try { await fetch(`/api/projects/${projectId}/start-training`, { method: 'POST', }); fetchProject(); } catch (error) { console.error('Erro ao iniciar treinamento:', error); } }; const handleStopTraining = async () => { try { await fetch(`/api/projects/${projectId}/stop-training`, { method: 'POST', }); fetchProject(); } catch (error) { console.error('Erro ao parar treinamento:', error); } }; const getStatusColor = (status) => { switch (status) { case 'completed': return 'bg-green-500'; case 'running': return 'bg-blue-500'; case 'failed': return 'bg-red-500'; case 'pending': return 'bg-yellow-500'; default: return 'bg-gray-500'; } }; const getStatusText = (status) => { switch (status) { case 'completed': return 'Concluído'; case 'running': return 'Treinando'; case 'failed': return 'Falhou'; case 'pending': return 'Pendente'; case 'cancelled': return 'Cancelado'; default: return 'Desconhecido'; } }; // Generate mock training data for chart const generateTrainingData = () => { if (!project || !project.current_epoch) return []; const data = []; for (let i = 1; i <= project.current_epoch; i++) { data.push({ epoch: i, loss: Math.max(0.1, 1.0 - (i / project.num_epochs) * 0.8 + (Math.random() - 0.5) * 0.1) }); } return data; }; if (loading) { return (
Carregando projeto...
); } if (!project) { return (
Projeto não encontrado
); } return (
{/* Header */}

{project.name}

{project.description || 'Sem descrição'}

{project.status === 'pending' || project.status === 'failed' ? ( ) : project.status === 'running' ? ( ) : project.status === 'completed' ? ( ) : null}
{/* Status Card */}
Status do Projeto {getStatusText(project.status)}
Modelo Base
{project.base_model}
Progresso
Época {project.current_epoch || 0} de {project.num_epochs}
Criado em
{new Date(project.created_at).toLocaleDateString('pt-BR')}
{project.status === 'running' && (
Progresso do Treinamento {Math.round((project.progress || 0) * 100)}%
{project.current_loss && (
Loss atual: {project.current_loss.toFixed(4)}
)}
)} {project.error_message && (
Erro: {project.error_message}
)}
{/* Tabs */} Configuração Treinamento Logs
Parâmetros LoRA
Rank: {project.rank}
Alpha: {project.alpha}
Dropout: {project.dropout}
Parâmetros de Treinamento
Taxa de Aprendizado: {project.learning_rate}
Batch Size: {project.batch_size}
Épocas: {project.num_epochs}
Otimizações
Otimizador 8-bit: {project.use_8bit_optimizer ? 'Sim' : 'Não'}
Gradient Checkpointing: {project.use_gradient_checkpointing ? 'Sim' : 'Não'}
Precisão Mista: {project.mixed_precision}
Dataset
Caminho: {project.dataset_path || 'Não carregado'}
Número de Imagens: {project.num_images || 'N/A'}
Gráfico de Loss Acompanhe a evolução da loss durante o treinamento
Logs de Treinamento Logs em tempo real do processo de treinamento
{logs.length === 0 ? (
Nenhum log disponível
) : ( logs.map((log, index) => (
{log}
)) )}
); }; export default ProjectView;