import type { ClientView } from '@/lib/client-view'; import type { Comment } from '@/db/schema'; import { Progress } from '@/components/ui/progress'; import { Card } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { ApproveButton } from './client/ApproveButton'; import { CommentList } from './client/CommentList'; import { CommentForm } from './client/CommentForm'; interface PhaseTimelineProps { phases: ClientView['phases']; token: string; comments: Comment[]; } function PhaseStatusIcon({ status }: { status: 'upcoming' | 'active' | 'done' }) { if (status === 'done') { return ( ); } if (status === 'active') { return ( ); } return ( ); } function TaskStatusIcon({ status }: { status: 'todo' | 'in_progress' | 'done' }) { if (status === 'done') { return ( ); } if (status === 'in_progress') { return ( ); } return ( ); } const phaseStatusLabel: Record<'upcoming' | 'active' | 'done', string> = { upcoming: 'In arrivo', active: 'In corso', done: 'Completata', }; const phaseStatusStyle: Record<'upcoming' | 'active' | 'done', string> = { upcoming: 'border-transparent bg-[#999999] text-white', active: 'border-transparent bg-[#0066cc] text-white', done: 'border-transparent bg-[#16a34a] text-white', }; export function PhaseTimeline({ phases, token, comments }: PhaseTimelineProps) { if (phases.length === 0) { return (

Nessuna fase ancora configurata.

); } // Helper: filter pre-fetched comments by entity id const commentsFor = (entityId: string) => comments.filter((c) => c.entity_id === entityId); return (
{phases.map((phase, index) => { const doneCount = phase.tasks.filter((t) => t.status === 'done').length; const isLast = index === phases.length - 1; return (
{/* Colonna sinistra: indicatore timeline */}
{/* Cerchio con icona stato */}
{/* Linea verticale verso la fase successiva */} {!isLast && (
)}
{/* Colonna destra: contenuto fase */}
{/* Header fase */}

{phase.title}

{phaseStatusLabel[phase.status]}
{/* Barra progresso fase (D-08) */}

{doneCount} di {phase.tasks.length} task

{phase.progress_pct}%

{/* Lista task */} {phase.tasks.length === 0 ? (

Nessun task ancora configurato.

) : (
    {phase.tasks.map((task) => (
  • {task.title}

    {task.description && (

    {task.description}

    )} {/* Deliverable annidati con ApproveButton + CommentiDeliverable */} {task.deliverables.length > 0 && (
      {task.deliverables.map((d) => (
    • {d.title} {/* ApproveButton: shown for pending/submitted; shows date badge once approved */} {(d.status === 'pending' || d.status === 'submitted' || d.approved_at !== null) && ( )}
      {/* Comments on this deliverable */}
    • ))}
    )} {/* Comments on the task itself */}
  • ))}
)}
); })}
); }