'use client'; import { useState } from 'react'; import { useParams } from 'next/navigation'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { circulationService } from '@/lib/services/circulation.service'; import { UpdateCirculationRoutingDto } from '@/types/circulation'; import { useCirculation, circulationKeys } from '@/hooks/use-circulation'; import { useWorkflowHistory } from '@/hooks/use-workflow-history'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { ArrowLeft, RefreshCw, CheckCircle2, AlertCircle } from 'lucide-react'; import Link from 'next/link'; import { format, isPast, addDays, parseISO } from 'date-fns'; import { toast } from 'sonner'; import { IntegratedBanner } from '@/components/workflow/integrated-banner'; import { WorkflowLifecycle } from '@/components/workflow/workflow-lifecycle'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; /** * EC-CIRC-003: ตรวจสอบว่า deadline เลยกำหนดแล้วหรือไม่ (overdue = วันถัดไปหลัง deadline + 1 วัน) */ function isOverdue(deadlineDate?: string): boolean { if (!deadlineDate) return false; return isPast(addDays(parseISO(deadlineDate), 1)); } /** * Get initials from name */ function getInitials(firstName?: string, lastName?: string): string { const first = firstName?.charAt(0) || ''; const last = lastName?.charAt(0) || ''; return (first + last).toUpperCase() || '?'; } /** * Get status badge variant */ function getStatusVariant(status: string): 'default' | 'secondary' | 'destructive' | 'outline' { switch (status?.toUpperCase()) { case 'PENDING': return 'outline'; case 'IN_PROGRESS': return 'default'; case 'COMPLETED': return 'secondary'; case 'REJECTED': return 'destructive'; default: return 'outline'; } } export default function CirculationDetailPage() { const params = useParams(); const queryClient = useQueryClient(); const uuid = params.uuid as string; const [pendingAttachmentIds, setPendingAttachmentIds] = useState([]); const { circulation, isLoading, error } = useCirculation(uuid); const { data: workflowHistory, isLoading: historyLoading, error: historyError, } = useWorkflowHistory(circulation?.workflowInstanceId); const completeMutation = useMutation({ mutationFn: ({ routingId, data }: { routingId: number; data: UpdateCirculationRoutingDto }) => circulationService.updateRouting(routingId, data), onSuccess: () => { toast.success('Task completed successfully'); queryClient.invalidateQueries({ queryKey: circulationKeys.detail(uuid) }); }, onError: () => { toast.error('Failed to update task status'); }, }); const handleComplete = (routingId: number) => { completeMutation.mutate({ routingId, data: { status: 'COMPLETED', comments: 'Completed via UI' }, }); }; if (isLoading) { return (
); } if (error || !circulation) { return (
Failed to load circulation details.
); } return (
{/* ADR-021: Integrated Banner — wired with live workflow data (v1.8.7) */} {/* Navigation Header */}
{/* Tabs — Details / Workflow */} รายละเอียด Workflow {/* Info Card */} Circulation Details

Organization

{circulation.organization?.organizationName || '-'}

Created By

{circulation.creator ? `${circulation.creator.firstName || ''} ${circulation.creator.lastName || ''}`.trim() || circulation.creator.username : '-'}

Created At

{format(new Date(circulation.createdAt), 'dd MMM yyyy, HH:mm')}

{circulation.correspondence && (

Linked Document

{circulation.correspondence.correspondenceNumber}
)} {circulation.deadlineDate && (

Deadline

{format(parseISO(circulation.deadlineDate), 'dd MMM yyyy')} {isOverdue(circulation.deadlineDate) && ( Overdue )}

)}
{/* Assignees/Routings */} Assignees {circulation.routings && circulation.routings.length > 0 ? (
{circulation.routings.map((routing) => (
{getInitials(routing.assignee?.firstName, routing.assignee?.lastName)}

{routing.assignee ? `${routing.assignee.firstName || ''} ${routing.assignee.lastName || ''}`.trim() || routing.assignee.username : 'Unassigned'}

Step {routing.stepNumber} {routing.comments && ` • ${routing.comments}`}

{routing.status} {routing.status === 'PENDING' && ( )}
))}
) : (

No assignees found

)}
{/* ADR-021: WorkflowLifecycle — wired with history data (v1.8.7) */}
); }