diff --git a/src/components/documents/document-list.tsx b/src/components/documents/document-list.tsx index 38a51e78..4840fb18 100644 --- a/src/components/documents/document-list.tsx +++ b/src/components/documents/document-list.tsx @@ -1,5 +1,7 @@ 'use client'; +import { useState } from 'react'; +import { FolderInput } from 'lucide-react'; import { useQueryClient } from '@tanstack/react-query'; import { Badge } from '@/components/ui/badge'; @@ -10,8 +12,10 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; +import { PermissionGate } from '@/components/shared/permission-gate'; import { usePaginatedQuery } from '@/hooks/use-paginated-query'; import { apiFetch } from '@/lib/api/client'; +import { MoveToFolderDialog } from './move-to-folder-dialog'; interface DocumentRow { id: string; @@ -19,6 +23,7 @@ interface DocumentRow { title: string; status: string; createdAt: string; + folderId: string | null; signers?: Array<{ status: string }>; } @@ -47,6 +52,73 @@ const TYPE_LABELS: Record = { other: 'Other', }; +interface DocRowProps { + doc: DocumentRow; + onDelete: (doc: DocumentRow) => void; + onSend: (doc: DocumentRow) => void; +} + +function DocRow({ doc, onDelete, onSend }: DocRowProps) { + const [moveOpen, setMoveOpen] = useState(false); + + const signerProgress = (() => { + if (!doc.signers) return '-'; + const signed = doc.signers.filter((s) => s.status === 'signed').length; + return `${signed}/${doc.signers.length} signed`; + })(); + + return ( + <> + + + {TYPE_LABELS[doc.documentType] ?? doc.documentType} + + {doc.title} + + {doc.status} + + {signerProgress} + + {new Date(doc.createdAt).toLocaleDateString('en-GB')} + + + + + + + + {doc.status === 'draft' && ( + onSend(doc)}>Send for Signing + )} + + setMoveOpen(true)}> + + Move to folder… + + + onDelete(doc)} + className="text-destructive focus:text-destructive" + > + Delete + + + + + + + + ); +} + export function DocumentList({ interestId, clientId, emptyState }: DocumentListProps) { const queryClient = useQueryClient(); @@ -79,12 +151,6 @@ export function DocumentList({ interestId, clientId, emptyState }: DocumentListP } }; - const getSignerProgress = (doc: DocumentRow) => { - if (!doc.signers) return '-'; - const signed = doc.signers.filter((s) => s.status === 'signed').length; - return `${signed}/${doc.signers.length} signed`; - }; - if (isLoading) { return (
Loading documents...
@@ -111,41 +177,7 @@ export function DocumentList({ interestId, clientId, emptyState }: DocumentListP {data.map((doc) => ( - - - {TYPE_LABELS[doc.documentType] ?? doc.documentType} - - {doc.title} - - {doc.status} - - {getSignerProgress(doc)} - - {new Date(doc.createdAt).toLocaleDateString('en-GB')} - - - - - - - - {doc.status === 'draft' && ( - handleSend(doc)}> - Send for Signing - - )} - handleDelete(doc)} - className="text-destructive focus:text-destructive" - > - Delete - - - - - + ))} diff --git a/src/components/documents/documents-hub.tsx b/src/components/documents/documents-hub.tsx index d2c39b08..54431e39 100644 --- a/src/components/documents/documents-hub.tsx +++ b/src/components/documents/documents-hub.tsx @@ -7,13 +7,7 @@ import { ChevronDown, ChevronRight, FileText, Plus } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; +import { cn } from '@/lib/utils'; import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill'; import { EmptyState } from '@/components/ui/empty-state'; @@ -96,7 +90,7 @@ interface DocumentsHubProps { export function DocumentsHub({ portSlug, initialTab = 'all' }: DocumentsHubProps) { const [tab, setTab] = useState(initialTab); const [search, setSearch] = useState(''); - const [typeFilter, setTypeFilter] = useState('all'); + const [typeFilter, setTypeFilter] = useState(undefined); // undefined = "All documents" (no folder filter), null = root only, // string = a specific folder id. const [selectedFolderId, setSelectedFolderId] = useState(undefined); @@ -106,7 +100,7 @@ export function DocumentsHub({ portSlug, initialTab = 'all' }: DocumentsHubProps const params = new URLSearchParams(); params.set('tab', tab); if (search) params.set('search', search); - if (typeFilter && typeFilter !== 'all') params.set('documentType', typeFilter); + if (typeFilter) params.set('documentType', typeFilter); if (selectedFolderId !== undefined) { params.set('folderId', selectedFolderId ?? ''); } @@ -290,19 +284,39 @@ export function DocumentsHub({ portSlug, initialTab = 'all' }: DocumentsHubProps onChange={(e) => setSearch(e.target.value)} className="max-w-xs h-9" /> - + {(() => { + const seenTypes = Array.from( + new Set(documents.map((d) => d.documentType)), + ).sort(); + if (seenTypes.length === 0) return null; + return ( +
+ + {seenTypes.map((t) => ( + + ))} +
+ ); + })()} {isLoading ? (