'use client'; import { useState } from 'react'; import Link from 'next/link'; import { ClipboardSignature, FileText, Eye, Download } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { AggregatedSection } from './aggregated-section'; import { SigningDetailsDialog } from './signing-details-dialog'; import { FilePreviewDialog } from '@/components/files/file-preview-dialog'; import { useAggregatedFiles, useAggregatedWorkflows } from '@/hooks/use-aggregated-listing'; import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill'; import { apiFetch } from '@/lib/api/client'; import { toastError } from '@/lib/api/toast-error'; import { triggerUrlDownload } from '@/lib/utils/download'; import type { AggregatedFile, AggregatedGroup, AggregatedWorkflow, } from '@/hooks/use-aggregated-listing'; interface Props { portSlug: string; entityType: 'client' | 'company' | 'yacht'; entityId: string; } function mapWorkflowStatus(status: string): StatusPillStatus { const known: Record = { draft: 'draft', sent: 'sent', partially_signed: 'partial', completed: 'completed', expired: 'expired', cancelled: 'cancelled', }; return known[status] ?? 'pending'; } async function handleFileDownload(fileId: string) { try { const res = await apiFetch<{ data: { url: string; filename: string } }>( `/api/v1/files/${fileId}/download`, ); triggerUrlDownload(res.data.url, res.data.filename); } catch (err) { toastError(err); } } export function EntityFolderView({ portSlug, entityType, entityId }: Props) { const [detailsId, setDetailsId] = useState(null); const [previewFile, setPreviewFile] = useState<{ id: string; name: string; mimeType: string | null; } | null>(null); // Hook data is the bare AggregatedGroup[] array (hooks unwrap the API envelope). const { data: workflowGroups = [], isLoading: workflowsLoading } = useAggregatedWorkflows( entityType, entityId, ); const { data: fileGroups = [], isLoading: filesLoading } = useAggregatedFiles( entityType, entityId, ); return (
title="Signing in progress" icon={} groups={workflowGroups} loading={workflowsLoading} emptyMessage="No workflows in flight for this entity." renderRow={(w: AggregatedWorkflow, _group: AggregatedGroup) => (
{w.title} {w.status.replace(/_/g, ' ')}
)} /> title="Files" icon={} groups={fileGroups} loading={filesLoading} emptyMessage="No files for this entity yet." renderRow={(f: AggregatedFile, _group: AggregatedGroup) => { const signedFromDocumentId = f.signedFromDocumentId; return (
{new Date(f.createdAt).toLocaleDateString('en-GB')} {signedFromDocumentId ? ( ) : null}
); }} /> !open && setDetailsId(null)} /> { if (!open) setPreviewFile(null); }} fileId={previewFile?.id} fileName={previewFile?.name} mimeType={previewFile?.mimeType ?? undefined} />
); }