import * as Icons from "@/components/Icons.tsx"; import type { AnyDocument, DocumentId } from "@/lib/types"; import { Dialog, DialogPanel, Transition, TransitionChild, } from "@headlessui/react"; import { Fragment, useCallback, useState } from "react"; type Props = { title?: React.ReactNode; error?: React.ReactNode; items: T[]; renderRow: (item: T) => React.ReactNode; newItemForm: (onSubmit: () => void) => React.ReactNode; removeItem: (itemId: DocumentId) => void; }; /** * DocumentList is a generic list component for displaying document items with a dialog for adding new items. * * @param title - The title displayed above the list (left-aligned) * @param items - The array of document items to display * @param renderRow - Function to render each row's content * @param newItemForm - Function that renders a form for creating a new item; receives an onSubmit callback */ export function DocumentList({ title, error, items, renderRow, newItemForm, removeItem, }: Props) { const [open, setOpen] = useState(false); const [isEditing, setIsEditing] = useState(false); const toggleEditMode = useCallback( () => setIsEditing((x) => !x), [setIsEditing], ); // Handles closing the dialog after form submission const handleFormSubmit = (): void => { setOpen(false); }; return (
{title &&

{title}

}
{isEditing && ( )}
{error && (
{error}
)}
    {items.map((item) => (
  • {renderRow(item)} {isEditing && (
    )}
  • ))}
{newItemForm(handleFormSubmit)}
); }