import React, { useState, useEffect, useCallback, useMemo } from 'react' import { Link, useNavigate } from 'react-router-dom' import { Clock, CheckCircle2, FolderKanban, Play, Square, TrendingUp, Plus, Sparkles, ArrowRight, Flame, RefreshCw, Folder, Tag, Activity, AlertCircle, } from 'lucide-react' import { useAuth } from '../contexts/AuthContext' import { useTimer } from '../contexts/TimerContext' import { taskService } from '../services/taskService' import { projectService } from '../services/projectService' import type { Task, Project } from '../types/task' import { calculateTaskTotalSeconds, formatSecondsToHuman, formatSecondsToTimer } from '../lib/timeUtils' import { CreateTaskModal } from '../components/tasks/CreateTaskModal' export const DashboardPage: React.FC = () => { const { user, activeOrg } = useAuth() const { activeTask, activeSeconds, startTimer, stopTimer, syncWithTasks } = useTimer() const navigate = useNavigate() const [tasks, setTasks] = useState([]) const [projects, setProjects] = useState([]) const [loading, setLoading] = useState(true) const [refreshing, setRefreshing] = useState(false) const [error, setError] = useState(null) // Modal const [isModalOpen, setIsModalOpen] = useState(false) const activeOrgId = activeOrg?.id const loadData = useCallback(async () => { if (!activeOrgId) return try { setRefreshing(true) const [tasksRes, projsRes] = await Promise.allSettled([ taskService.listTasks({ organizationId: activeOrgId }), projectService.listProjects(activeOrgId), ]) const loadedTasks = tasksRes.status === 'fulfilled' ? tasksRes.value || [] : [] setTasks(loadedTasks) syncWithTasks(loadedTasks) if (projsRes.status === 'fulfilled') { setProjects(projsRes.value || []) } } catch (err: unknown) { console.error(err) setError('Falha ao atualizar dados do dashboard.') } finally { setLoading(false) setRefreshing(false) } }, [activeOrgId, syncWithTasks]) useEffect(() => { loadData() }, [loadData]) // KPIs const stats = useMemo(() => { const inProgress = tasks.filter((t) => t.status === 'IN_PROGRESS').length const completed = tasks.filter((t) => t.status === 'COMPLETED').length const notStarted = tasks.filter((t) => t.status === 'NOT_STARTED').length const totalSeconds = tasks.reduce((acc, t) => acc + calculateTaskTotalSeconds(t), 0) return { inProgress, completed, notStarted, totalSeconds, projectsCount: projects.length, } }, [tasks, projects]) // Recent 5 tasks const recentTasks = useMemo(() => { return [...tasks].slice(0, 5) }, [tasks]) // Toggle timer on a task const handleToggleTimer = async (task: Task) => { try { if (activeTask?.id === task.id) { const stopped = await stopTimer(task) if (stopped) { setTasks((prev) => prev.map((t) => (t.id === stopped.id ? stopped : t))) } } else { const started = await startTimer(task) setTasks((prev) => prev.map((t) => (t.id === started.id ? started : t))) } } catch (err: unknown) { console.error(err) setError('Erro ao acionar cron么metro.') } } const handleModalSubmit = async (taskData: { title: string description: string status: 'NOT_STARTED' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELED' projectId?: number categoryId?: number assigneeUserId?: number }) => { if (!activeOrgId) return const created = await taskService.createTask({ title: taskData.title, description: taskData.description, status: taskData.status, projectId: taskData.projectId, categoryId: taskData.categoryId, assigneeUserId: taskData.assigneeUserId, organizationId: activeOrgId, }) setTasks((prev) => [created, ...prev]) } // Priority task to focus on if none running const suggestedTask = useMemo(() => { return tasks.find((t) => t.status === 'IN_PROGRESS') || tasks.find((t) => t.status === 'NOT_STARTED') || tasks[0] }, [tasks]) return (
{/* Header */}

Ol谩, {user?.name?.split(' ')[0] || 'Desenvolvedor'}! 馃憢

{activeOrg?.name || 'Workspace'}

Vis茫o geral da sua produtividade, metas e atividades recentes no workspace.

{error && (
{error}
)} {/* KPI Cards */} {loading ? (
{[1, 2, 3, 4].map((i) => (
))}
) : (
{/* In Progress */}
Tarefas em Andamento

{stats.inProgress}

{stats.notStarted} no backlog para iniciar

{/* Completed */}
Entregas Conclu铆das

{stats.completed}

de {tasks.length} tarefas cadastradas

{/* Time Tracked */}
Tempo Total Dedicado

{formatSecondsToTimer(stats.totalSeconds)}

{formatSecondsToHuman(stats.totalSeconds)} acumuladas

{/* Projects */}
Projetos Ativos

{stats.projectsCount}

Iniciativas no workspace

)} {/* Main Content: Focus Session (Left) + Recent Tasks (Right) */}
{/* Focus Session Card (Left 5 cols) */}

Sess茫o em Foco

Cron么metro em tempo real

{activeTask ? 'ATIVO' : 'EM ESPERA'}
{/* Active or Suggested Task Info */} {activeTask ? (
{activeTask.project && ( {activeTask.project.name} )} {activeTask.category && ( {activeTask.category.name} )}

{activeTask.title}

) : suggestedTask ? (
Pr贸xima da fila {suggestedTask.project && ( {suggestedTask.project.name} )}

{suggestedTask.title}

) : (
Nenhuma tarefa pendente. Crie uma nova tarefa para iniciar o foco!
)} {/* Big Timer Display */}
{activeTask ? 'Tempo Decorrido na Tarefa' : 'Pronto para Cronometrar'}

{activeTask ? formatSecondsToTimer(activeSeconds) : '00:00:00'}

{/* Controls */} {activeTask ? ( ) : suggestedTask ? ( ) : ( )}
Usu谩rio ativo: {user?.name || user?.email}
{/* Quick Shortcuts */}
Atalhos de Gest茫o
Projetos Analytics
{/* Recent Tasks List (Right 7 cols) */}

Tarefas Recentes

Ver todas
{loading ? (
{[1, 2, 3].map((i) => (
))}
) : recentTasks.length === 0 ? (

Nenhuma tarefa encontrada neste workspace.

) : (
{recentTasks.map((task) => { const isTracking = activeTask?.id === task.id const taskSec = isTracking ? activeSeconds : calculateTaskTotalSeconds(task) return (
{task.project && ( {task.project.name} )} {task.category && ( {task.category.name} )}

navigate('/tasks')} className="text-xs font-bold text-foreground hover:text-brand cursor-pointer truncate" > {task.title}

{formatSecondsToTimer(taskSec)}
) })}
)}
{/* Task Creation Modal */} {activeOrgId && ( setIsModalOpen(false)} onSubmit={handleModalSubmit} organizationId={activeOrgId} initialStatus="NOT_STARTED" /> )}
) }