"use client"; import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import type { Loadout } from "@/payload-types"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { LOADOUT_SLOTS, type LockerGridItem, type LoadoutSlots, } from "@/lib/locker"; import { createLoadout, setLoadoutSlot, updateLoadout, } from "@/app/(frontend)/locker/actions"; interface LoadoutEditorProps { mode: "create" | "edit"; loadout?: Loadout | null; ownedItems: LockerGridItem[]; open: boolean; onOpenChange: (open: boolean) => void; } function assetIdOf(value: unknown): string { if (value == null) return ""; if (typeof value === "object" && "id" in value) return String(value.id); return String(value); } export function LoadoutEditor({ mode, loadout, ownedItems, open, onOpenChange, }: LoadoutEditorProps) { const router = useRouter(); const [name, setName] = useState(""); const [description, setDescription] = useState(""); const [slots, setSlots] = useState>({}); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { if (!open) return; setLoading(false); setName(loadout?.name ?? ""); setDescription(loadout?.description ?? ""); const initial: Record = {}; if (loadout) { const current = (loadout.slots ?? {}) as LoadoutSlots; for (const slot of LOADOUT_SLOTS) { initial[slot.name] = assetIdOf(current[slot.name]); } } setSlots(initial); setError(null); }, [open, loadout]); const ownedByType = (assetTypes: readonly string[]) => { const types = new Set(assetTypes); const seen = new Set(); return ownedItems.filter((item) => { if (seen.has(item.assetId)) return false; if (!types.has(item.asset.assetType as string)) return false; seen.add(item.assetId); return true; }); }; async function handleSubmit() { if (!name.trim()) { setError("A loadout name is required."); return; } setLoading(true); setError(null); if (mode === "create") { const res = await createLoadout({ name: name.trim(), description: description.trim() || undefined, }); if (!res.success || res.data == null) { setError(res.error ?? "Failed to create loadout."); setLoading(false); return; } const loadoutId = res.data; for (const slot of LOADOUT_SLOTS) { const value = slots[slot.name]; if (value) { await setLoadoutSlot(loadoutId, slot.name, Number(value)); } } setLoading(false); onOpenChange(false); router.refresh(); return; } if (!loadout) return; const res = await updateLoadout(loadout.id, { name: name.trim(), description: description.trim() || undefined, }); if (!res.success) { setError(res.error ?? "Failed to update loadout."); setLoading(false); return; } for (const slot of LOADOUT_SLOTS) { const value = slots[slot.name]; await setLoadoutSlot(loadout.id, slot.name, value ? Number(value) : null); } setLoading(false); onOpenChange(false); router.refresh(); } return ( {mode === "create" ? "New Loadout" : "Edit Loadout"} Define a loadout and assign assets from your locker to each equipment slot.
setName(e.target.value)} placeholder="e.g., CQB" />