diff --git a/src/routes/archive.index.tsx b/src/routes/archive.index.tsx index 2e32482..2747d0a 100644 --- a/src/routes/archive.index.tsx +++ b/src/routes/archive.index.tsx @@ -19,7 +19,7 @@ import { import { supabase } from "@/integrations/supabase/client"; import { useAuth } from "@/lib/auth"; import { toast } from "sonner"; -import { Archive as ArchiveIcon, Plus, Upload, Trash2, FileSpreadsheet } from "lucide-react"; +import { Archive as ArchiveIcon, Plus, Upload, Trash2, FileSpreadsheet, Lock, Unlock } from "lucide-react"; import { formatDateTime } from "@/lib/format"; export const Route = createFileRoute("/archive/")({ @@ -62,6 +62,24 @@ function ArchivePage() { const [totalCount, setTotalCount] = useState(0); const [uploadOpen, setUploadOpen] = useState(false); const [newCatOpen, setNewCatOpen] = useState(false); + const [lockedTabs, setLockedTabs] = useState>(() => { + if (typeof window === "undefined") return {}; + try { + return JSON.parse(localStorage.getItem("archive-locked-tabs") || "{}"); + } catch { + return {}; + } + }); + const isLocked = activeId ? lockedTabs[activeId] !== false : true; // default locked + const toggleLock = () => { + if (!activeId) return; + const next = { ...lockedTabs, [activeId]: !isLocked }; + setLockedTabs(next); + try { + localStorage.setItem("archive-locked-tabs", JSON.stringify(next)); + } catch {} + toast.success(next[activeId] ? "Tab locked" : "Tab unlocked"); + }; // Debounce search input (300ms) useEffect(() => { @@ -153,6 +171,10 @@ function ArchivePage() { }, [rows]); const deleteRow = async (id: string) => { + if (isLocked) { + toast.error("Tab is locked. Unlock it to delete records."); + return; + } if (!confirm("Delete this record?")) return; const { error } = await supabase.from("archive_records").delete().eq("id", id); if (error) { @@ -166,6 +188,10 @@ function ArchivePage() { const deleteAllInCategory = async () => { if (!activeCategory) return; + if (isLocked) { + toast.error("Tab is locked. Unlock it to clear records."); + return; + } if (!confirm(`Delete ALL ${totalCount} records in "${activeCategory.label}"? This cannot be undone.`)) return; const { error } = await supabase.from("archive_records").delete().eq("category_id", activeCategory.id); if (error) { @@ -232,8 +258,32 @@ function ArchivePage() {
Showing {rows.length} of {totalCount} {debouncedSearch ? "matching" : ""} rows
+ {isAdmin && activeId && ( + + )} {isAdmin && rows.length > 0 && ( - )} @@ -290,10 +340,11 @@ function ArchivePage() { size="sm" variant="ghost" onClick={() => deleteRow(r.id)} - title="Delete row" + disabled={isLocked} + title={isLocked ? "Tab locked" : "Delete row"} className="text-destructive hover:text-destructive h-7 w-7 p-0" > - + {isLocked ? : } )}