"use client"; import { useState, useMemo } from "react"; import { FaInbox, FaTimes, FaBox, FaCalendarPlus, FaShoppingCart } from "react-icons/fa"; import { IoFilter, IoFilterCircleOutline, IoFilterOutline } from "react-icons/io5"; import { SetStateAction, Dispatch } from "react"; // Artifact type interface Artifact { id: number; name: string; description: string; location: string; earthquakeId: string; isRequired: boolean; isSold: boolean; isCollected: boolean; dateAdded: string; } // Warehouse Artifacts Data const warehouseArtifacts: Artifact[] = [ { 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[]; }) { return (
{options ? (
{options.map((opt) => (
onChange(opt)}> {opt || "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 && (
{value === "true" ? "Yes" : value === "false" ? "No" : value} onChange("")} />
)}
); } // Table Component function ArtifactTable({ artifacts, filters, setFilters, setEditArtifact, clearSort, }: { artifacts: Artifact[]; filters: Record; setFilters: Dispatch< SetStateAction<{ id: string; name: string; earthquakeId: string; location: string; description: string; isRequired: string; isSold: string; isCollected: string; dateAdded: string; }> >; setEditArtifact: (artifact: Artifact) => void; clearSort: () => void; }) { const [sortConfig, setSortConfig] = useState<{ key: keyof Artifact; direction: "asc" | "desc"; } | null>(null); const handleSort = (key: keyof Artifact) => { setSortConfig((prev) => { if (!prev || prev.key !== key) { return { key, direction: "asc" }; } return { key, direction: prev.direction === "asc" ? "desc" : "asc", }; }); }; const clearSortConfig = () => { setSortConfig(null); clearSort(); }; const sortedArtifacts = useMemo(() => { if (!sortConfig) return artifacts; const sorted = [...artifacts].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; }, [artifacts, sortConfig]); return ( {[ { label: "ID", key: "id" }, { label: "Name", key: "name" }, { label: "Earthquake ID", key: "earthquakeId" }, { label: "Location", key: "location" }, { label: "Description", key: "description" }, { label: "Required", key: "isRequired" }, { label: "Sold", key: "isSold" }, { label: "Collected", key: "isCollected" }, { label: "Date Added", key: "dateAdded" }, ].map(({ label, key }) => ( ))} {sortedArtifacts.map((artifact) => ( setEditArtifact(artifact)} > ))}
handleSort(key as keyof Artifact)} >
{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" ? "↑" : "↓"}}
{artifact.id} {artifact.name} {artifact.earthquakeId} {artifact.location} {artifact.description} {artifact.isRequired ? "Yes" : "No"} {artifact.isSold ? "Yes" : "No"} {artifact.isCollected ? "Yes" : "No"} {artifact.dateAdded}
); } // Modal Component for Logging Artifact 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 artifact. Please try again."); } finally { setIsSubmitting(false); } }; return (

Log New Artifact

{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="Artifact Name" disabled={isSubmitting} />