import React from "react"; import { QuestForm } from "../components/quest-form"; import { QuestTable } from "../components/quest-table"; import { SectionHeader } from "../components/section-header"; import { toast } from "sonner"; interface QuestListItem { id: number; name: string; description: string | null; triggerEvent: string; requirements: { target?: number }; rewards: { xp?: number; balance?: number }; } export function AdminQuests() { const [quests, setQuests] = React.useState([]); const [isInitialLoading, setIsInitialLoading] = React.useState(true); const [isRefreshing, setIsRefreshing] = React.useState(false); const [lastCreatedQuestId, setLastCreatedQuestId] = React.useState(null); const [editingQuest, setEditingQuest] = React.useState(null); const [isFormModeEdit, setIsFormModeEdit] = React.useState(false); const formRef = React.useRef(null); const fetchQuests = React.useCallback(async (isRefresh = false) => { if (isRefresh) { setIsRefreshing(true); } else { setIsInitialLoading(true); } try { const response = await fetch("/api/quests"); if (!response.ok) { throw new Error("Failed to fetch quests"); } const data = await response.json(); if (data.success && Array.isArray(data.data)) { setQuests(data.data); } } catch (error) { console.error("Error fetching quests:", error); toast.error("Failed to load quests", { description: error instanceof Error ? error.message : "Unknown error", }); } finally { setIsInitialLoading(false); setIsRefreshing(false); } }, []); React.useEffect(() => { fetchQuests(false); }, [fetchQuests]); React.useEffect(() => { if (lastCreatedQuestId !== null) { const element = document.getElementById(`quest-row-${lastCreatedQuestId}`); if (element) { element.scrollIntoView({ behavior: "smooth", block: "center" }); element.classList.add("bg-primary/10"); setTimeout(() => { element.classList.remove("bg-primary/10"); }, 2000); } setLastCreatedQuestId(null); } }, [lastCreatedQuestId, quests]); const handleQuestCreated = () => { fetchQuests(true); toast.success("Quest list updated", { description: "The quest inventory has been refreshed.", }); }; const handleDeleteQuest = async (id: number) => { try { const response = await fetch(`/api/quests/${id}`, { method: "DELETE", }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.message || "Failed to delete quest"); } setQuests((prev) => prev.filter((q) => q.id !== id)); toast.success("Quest deleted", { description: `Quest #${id} has been successfully deleted.`, }); } catch (error) { console.error("Error deleting quest:", error); toast.error("Failed to delete quest", { description: error instanceof Error ? error.message : "Unknown error", }); } }; const handleEditQuest = (id: number) => { const quest = quests.find(q => q.id === id); if (quest) { setEditingQuest(quest); setIsFormModeEdit(true); formRef.current?.scrollIntoView({ behavior: "smooth", block: "center" }); } }; const handleQuestUpdated = () => { fetchQuests(true); setEditingQuest(null); setIsFormModeEdit(false); toast.success("Quest list updated", { description: "The quest inventory has been refreshed.", }); }; const handleFormCancel = () => { setEditingQuest(null); setIsFormModeEdit(false); }; return (
fetchQuests(true)} onDelete={handleDeleteQuest} onEdit={handleEditQuest} />
); } export default AdminQuests;