"use client"; // components/DocumentsPanel.tsx // Shared document panel for directors and companies. // Lists documents, provides download + delete, and opens the upload modal. import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { pbList } from "@/lib/api"; import { deleteDirectorDocument, deleteCompanyDocument } from "@/lib/api"; import { useQueryClient } from "@tanstack/react-query"; import UploadDocumentModal from "./UploadDocumentModal"; import type { YsterbaardDirectorDocument, YsterbaardCompanyDocument } from "@/lib/types"; interface Props { context: "director" | "company"; entityId: string; } const PB_URL = process.env.NEXT_PUBLIC_PB_URL ?? "https://pb.agent.apphub.co.za"; type DocItem = YsterbaardDirectorDocument | YsterbaardCompanyDocument; function DocType({ doc }: { doc: DocItem }) { const dt = doc.expand?.document_type; if (!dt) return —; return ( {dt.name} {dt.description ? — {dt.description} : null} ); } function FileIcon({ filename }: { filename: string }) { const ext = filename?.split(".").pop()?.toLowerCase(); const isPdf = ext === "pdf"; return ( {ext?.toUpperCase()} ); } export default function DocumentsPanel({ context, entityId }: Props) { const qc = useQueryClient(); const [showUpload, setShowUpload] = useState(false); const [deleteId, setDeleteId] = useState(null); const [deleting, setDeleting] = useState(false); const [deleteError, setDeleteError] = useState(null); const collection = context === "director" ? "ysterbaard_director_documents" : "ysterbaard_company_documents"; const { data, isLoading } = useQuery({ queryKey: ["documents", context, entityId], queryFn: () => pbList({ collection, filter: context === "director" ? `director = '${entityId}'` : `company = '${entityId}'`, sort: "-uploaded_at", perPage: 100, expand: "document_type", fields: "*,expand.document_type.id,expand.document_type.name,expand.document_type.description", }), }); const docs = data?.items ?? []; const handleDelete = async () => { if (!deleteId) return; setDeleting(true); setDeleteError(null); try { if (context === "director") { await deleteDirectorDocument(deleteId); } else { await deleteCompanyDocument(deleteId); } await qc.invalidateQueries({ queryKey: ["documents", context, entityId] }); setDeleteId(null); } catch (err) { setDeleteError(err instanceof Error ? err.message : "Delete failed"); } finally { setDeleting(false); } }; return ( <> {/* Header */} Documents {docs.length} file{docs.length !== 1 ? "s" : ""} · PDF or JPEG, max 10MB setShowUpload(true)} className="shrink-0 px-4 py-2 rounded-lg bg-accent text-accent-on text-sm font-bold hover:bg-accent-hover transition-colors" > + Upload {/* List */} {isLoading ? ( Loading… ) : docs.length === 0 ? ( No documents yet. setShowUpload(true)} className="mt-2 text-accent text-sm font-semibold hover:underline" > Upload the first document → ) : ( {docs.map((doc) => { const fileUrl = `${PB_URL}/api/files/${collection}/${doc.id}/${doc.file}`; const uploadedAt = (doc as DocItem).uploaded_at ?? doc.created; const ext = (doc.file as string)?.split(".").pop()?.toLowerCase() ?? "pdf"; return ( {/* File type icon */} {ext.toUpperCase()} {/* Info */} {(doc as DocItem).file ?? "Uploaded file"} · {uploadedAt ? new Date(uploadedAt).toLocaleDateString("en-ZA") : "—"} {(doc as DocItem).notes ? ( <> · {(doc as DocItem).notes} > ) : null} {/* Actions */} ↓ Download setDeleteId(doc.id)} className="px-3 py-1.5 rounded border border-border bg-surface-warm text-xs font-semibold text-muted hover:border-red-500 hover:text-red-500 transition-colors" title="Delete document" > Delete ); })} )} {/* Upload modal */} setShowUpload(false)} onUploaded={() => { qc.invalidateQueries({ queryKey: ["documents", context, entityId] }); setShowUpload(false); }} /> {/* Delete confirmation */} {deleteId && ( { if (e.target === e.currentTarget) setDeleteId(null); }} className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4" role="dialog" aria-modal="true" > Delete this document? This will permanently delete the file from PocketBase. This action cannot be undone. {deleteError && ( {deleteError} )} setDeleteId(null)} className="flex-1 px-4 py-2.5 rounded-lg border border-border bg-surface-warm text-sm font-semibold text-fg hover:bg-surface" > Cancel {deleting ? "Deleting..." : "Yes, delete"} )} > ); }
{docs.length} file{docs.length !== 1 ? "s" : ""} · PDF or JPEG, max 10MB
No documents yet.
{(doc as DocItem).file ?? "Uploaded file"}
This will permanently delete the file from PocketBase. This action cannot be undone.