"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

{/* List */} {isLoading ? (
Loading…
) : docs.length === 0 ? (

No documents yet.

) : (
    {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
  • ); })}
)}
{/* 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}
)}
)} ); }