"use client"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useRouter } from "next/navigation"; import type { Asset, Loadout, LockerStorage } from "@/payload-types"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Item, ItemContent, ItemHeader, ItemTitle } from "@/components/ui/item"; import { EventLedger } from "@/components/frontend/storage/EventLedger"; import { LockerGrid } from "./LockerGrid"; import { LockerGridToolbar } from "./LockerGridToolbar"; import { AddLockerItemDialog } from "./AddLockerItemDialog"; import { LoadoutsPanel } from "./LoadoutsPanel"; import { WardrobePanel } from "./WardrobePanel"; import { EquipmentEditorDialog } from "./EquipmentEditorDialog"; import { LockerSearch } from "./LockerSearch"; import { getAssetTypeLabel, type LockerGridItem } from "@/lib/locker"; import type { LockerSearchEntry } from "@/lib/locker/search"; import { autoArrangeLocker, attachItemFromGrid, mergeLockerStacks, moveLockerItem, removeLockerItem, rotateLockerItem, splitLockerStack, } from "@/app/(frontend)/locker/actions"; interface LockerViewProps { locker: LockerStorage; gridWidth: number; gridHeight: number; loadouts: Loadout[]; assetsCatalog: Asset[]; isManager: boolean; userName: string; } export function LockerView({ locker, gridWidth, gridHeight, loadouts, assetsCatalog, isManager, userName, }: LockerViewProps) { const router = useRouter(); const [tab, setTab] = useState("wardrobe"); const [viewMode, setViewMode] = useState<"grid" | "list">("grid"); const [selectedId, setSelectedId] = useState(null); const [customizeId, setCustomizeId] = useState(null); const [highlightId, setHighlightId] = useState(null); const [eventLogKey, setEventLogKey] = useState(0); const items: LockerGridItem[] = useMemo( () => (locker.items ?? []) .filter((entry) => entry.asset && typeof entry.asset === "object" && "id" in entry.asset) .map((entry) => { const asset = entry.asset as Asset; return { id: entry.id ?? `${asset.id}-${entry.gridX}-${entry.gridY}`, assetId: asset.id, quantity: entry.quantity, gridX: entry.gridX ?? 0, gridY: entry.gridY ?? 0, rotated: entry.rotated ?? false, asset, equipment: entry.equipment ?? undefined, }; }), [locker.items], ); const selectedItem = useMemo( () => items.find((i) => i.id === selectedId) ?? null, [items, selectedId], ); const customizeItem = useMemo( () => items.find((i) => i.id === customizeId) ?? null, [items, customizeId], ); useEffect(() => { if (!highlightId) return; const timer = setTimeout(() => setHighlightId(null), 3000); return () => clearTimeout(timer); }, [highlightId]); const refresh = useCallback(() => { router.refresh(); setEventLogKey((k) => k + 1); }, [router]); const handleMoveItem = useCallback( async (entryId: string, gridX: number, gridY: number, rotated?: boolean) => { const result = await moveLockerItem(entryId, gridX, gridY, rotated); if (result.success) refresh(); }, [refresh], ); const handleMergeStacks = useCallback( async (sourceId: string, targetId: string) => { const result = await mergeLockerStacks(sourceId, targetId); if (result.success) refresh(); }, [refresh], ); const handleRotateItem = useCallback( async (entryId: string) => { const result = await rotateLockerItem(entryId); if (result.success) refresh(); }, [refresh], ); const handleRemoveItem = useCallback( async (entryId: string) => { const result = await removeLockerItem(entryId); if (result.success) { setSelectedId(null); refresh(); } }, [refresh], ); const handleSplitStack = useCallback( async (entryId: string, amount: number) => { const result = await splitLockerStack(entryId, amount); if (result.success) refresh(); }, [refresh], ); const handleAutoArrange = useCallback(async () => { const result = await autoArrangeLocker(); if (result.success) refresh(); }, [refresh]); const handleAttachItem = useCallback( async (weaponEntryId: string, attachmentEntryId: string) => { const result = await attachItemFromGrid(weaponEntryId, attachmentEntryId); if (result.success) refresh(); return result; }, [refresh], ); const handleSearchSelect = useCallback( (entry: LockerSearchEntry) => { setViewMode("grid"); setTab("inventory"); const gridItem = items.find((i) => i.assetId === entry.assetId) ?? null; if (gridItem && entry.asset.assetType === "weapon") { setSelectedId(gridItem.id); setCustomizeId(gridItem.id); return; } const parentId = entry.locations.find( (l) => (l.kind === "attached" || l.kind === "skin") && l.parentEntryId, )?.parentEntryId; if (parentId) { const parent = items.find((i) => i.id === parentId); if (parent && parent.asset.assetType === "weapon") { setSelectedId(parent.id); setCustomizeId(parent.id); return; } } if (gridItem) setHighlightId(gridItem.id); }, [items], ); return (
Wardrobe Inventory Loadouts
l.equipped) ?? null} items={items} />
setCustomizeId(selectedItem?.id ?? null)} /> {isManager && }
{items.length === 0 ? ( Empty Locker

{isManager ? "Your locker is empty. Add items to get started." : "Your locker is empty. Reach out to logistics to have equipment issued."}

) : viewMode === "grid" ? ( setSelectedId(item?.id ?? null)} selectedItem={selectedItem} highlightId={highlightId} onAttachItem={handleAttachItem} /> ) : (
{items.map((entry, index) => (
{index < items.length - 1 &&
}
))}
)} { if (!open) setCustomizeId(null); }} /> ); }