"use client"; import { useState, useMemo } from "react"; import { FaCalendarPlus, FaWarehouse, FaCartShopping } from "react-icons/fa6"; import { IoFilter, IoFilterCircleOutline, IoFilterOutline, IoToday } from "react-icons/io5"; import { FaTimes } from "react-icons/fa"; import { SetStateAction, Dispatch } from "react"; // import type { Artefact } from "@prisma/client"; interface Artefact { id: number; name: string; description: string; location: string; earthquakeId: string; isRequired: boolean; isSold: boolean; isCollected: boolean; dateAdded: string; } // Warehouse Artefacts Data const warehouseArtefacts: Artefact[] = [ { id: 1, name: "Solidified Lava Chunk", description: "A chunk of solidified lava from the 2023 Iceland eruption.", location: "Reykjanes, Iceland", earthquakeId: "EQ2023ICL", isRequired: true, isSold: false, isCollected: false, dateAdded: "2025-05-04", }, { id: 2, name: "Tephra Sample", description: "Foreign debris from the 2022 Tonga volcanic eruption.", location: "Tonga", earthquakeId: "EQ2022TGA", isRequired: false, isSold: true, isCollected: true, dateAdded: "2025-05-03", }, { id: 3, name: "Ash Sample", description: "Volcanic ash from the 2021 La Palma eruption.", location: "La Palma, Spain", earthquakeId: "EQ2021LPA", isRequired: false, isSold: false, isCollected: false, dateAdded: "2025-05-04", }, { id: 4, name: "Ground Soil", description: "Soil sample from the 2020 Croatia earthquake site.", location: "Zagreb, Croatia", earthquakeId: "EQ2020CRO", isRequired: true, isSold: false, isCollected: false, dateAdded: "2025-05-02", }, { id: 5, name: "Basalt Fragment", description: "Basalt rock from the 2019 New Zealand eruption.", location: "White Island, New Zealand", earthquakeId: "EQ2019NZL", isRequired: false, isSold: true, isCollected: false, dateAdded: "2025-05-04", }, ]; // Filter Component function FilterInput({ value, onChange, type = "text", options, }: { value: string; onChange: (value: string) => void; type?: string; options?: string[]; }) { const showSelectedFilter = type === "text" && !["true", "false"].includes(options?.at(-1)!); return (
{options ? (
{options.map((opt) => (
onChange(opt)}> {opt ? (opt === "true" ? "Yes" : "No") : "All"}
))}
) : ( onChange(e.target.value)} className="w-full p-1 border border-neutral-300 rounded-md text-sm" placeholder="Filter..." aria-label="Filter input" /> )}
{value && showSelectedFilter && (
{value === "true" ? "Yes" : value === "false" ? "No" : value} onChange("")} />
)}
); } // Table Component function ArtefactTable({ artefacts, filters, setFilters, setEditArtefact, clearSort, }: { artefacts: Artefact[]; filters: Record; setFilters: Dispatch< SetStateAction<{ id: string; name: string; earthquakeId: string; location: string; description: string; isRequired: string; isSold: string; isCollected: string; dateAdded: string; }> >; setEditArtefact: (artefact: Artefact) => void; clearSort: () => void; }) { const [sortConfig, setSortConfig] = useState<{ key: keyof Artefact; direction: "asc" | "desc"; } | null>(null); const handleSort = (key: keyof Artefact) => { setSortConfig((prev) => { if (!prev || prev.key !== key) { return { key, direction: "asc" }; } else if (prev.direction === "asc") { return { key, direction: "desc" }; } return null; }); }; const clearSortConfig = () => { setSortConfig(null); clearSort(); }; const sortedArtefacts = useMemo(() => { if (!sortConfig) return artefacts; const sorted = [...artefacts].sort((a, b) => { const aValue = a[sortConfig.key]; const bValue = b[sortConfig.key]; if (aValue < bValue) return sortConfig.direction === "asc" ? -1 : 1; if (aValue > bValue) return sortConfig.direction === "asc" ? 1 : -1; return 0; }); return sorted; }, [artefacts, sortConfig]); const columns: { label: string; key: keyof Artefact; width: string }[] = [ { label: "ID", key: "id", width: "5%" }, { label: "Name", key: "name", width: "12%" }, { label: "Earthquake ID", key: "earthquakeId", width: "10%" }, { label: "Location", key: "location", width: "12%" }, { label: "Description", key: "description", width: "25%" }, { label: "Required", key: "isRequired", width: "6%" }, { label: "Sold", key: "isSold", width: "5%" }, { label: "Collected", key: "isCollected", width: "7%" }, { label: "Date Added", key: "dateAdded", width: "8%" }, ]; return ( {columns.map(({ label, key, width }) => ( ))} {sortedArtefacts.map((artefact) => ( setEditArtefact(artefact)} > {columns.map(({ key, width }) => ( ))} ))}
handleSort(key as keyof Artefact)}>
{label}
{ setFilters({ ...filters, [key]: value } as { id: string; name: string; earthquakeId: string; location: string; description: string; isRequired: string; isSold: string; isCollected: string; dateAdded: string; }); if (value === "") clearSortConfig(); }} type={key === "dateAdded" ? "date" : "text"} options={["isRequired", "isSold", "isCollected"].includes(key) ? ["", "true", "false"] : undefined} /> {sortConfig?.key === key && (
{sortConfig.direction === "asc" ? "↑" : "↓"}
)}
{key === "isRequired" ? artefact.isRequired ? "Yes" : "No" : key === "isSold" ? artefact.isSold ? "Yes" : "No" : key === "isCollected" ? artefact.isCollected ? "Yes" : "No" : artefact[key]}
); } // Modal Component for Logging Artefact function LogModal({ onClose }: { onClose: () => void }) { const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [location, setLocation] = useState(""); const [earthquakeId, setEarthquakeId] = useState(""); const [storageLocation, setStorageLocation] = useState(""); const [isRequired, setIsRequired] = useState(true); const [error, setError] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const handleOverlayClick = (e: { target: any; currentTarget: any }) => { if (e.target === e.currentTarget) { onClose(); } }; const handleLog = async () => { if (!name || !description || !location || !earthquakeId || !storageLocation) { setError("All fields are required."); return; } setIsSubmitting(true); try { await new Promise((resolve) => setTimeout(resolve, 500)); // Simulated API call alert(`Logged ${name} to storage: ${storageLocation}`); onClose(); } catch { setError("Failed to log artefact. Please try again."); } finally { setIsSubmitting(false); } }; return (

Log New Artefact

{error &&

{error}

}
setName(e.target.value)} className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500" aria-label="Artefact Name" disabled={isSubmitting} />