import { useMemo, useRef, useState, type FormEvent } from "react"; import { useShellStore } from "../app/shellStore"; import { DUNGEON_REPORT_COMMENT_MAX_LENGTH, submitDungeonReport } from "../app/dungeonReports"; import { dungeonById } from "../game/dungeonCatalog"; import { useGameStore } from "../game/store"; import { useMenuController, type MenuAction } from "../input/useMenuController"; import { ControllerButton } from "./ControllerButton"; export function DungeonIssueReportPanel() { const dungeonId = useGameStore((state) => state.activeDungeonId); const bossTest = useGameStore((state) => state.bossTest); const openOverlay = useGameStore((state) => state.openOverlay); const session = useShellStore((state) => state.session); const [comment, setComment] = useState(""); const [submitting, setSubmitting] = useState(false); const [submitted, setSubmitted] = useState(false); const [error, setError] = useState(""); const busy = useRef(false); const form = useRef(null); const back = () => { if (!busy.current) openOverlay(bossTest ? "boss-test-review" : "pause"); }; const canSubmit = Boolean(comment.trim()) && comment.length <= DUNGEON_REPORT_COMMENT_MAX_LENGTH && !submitting; const actions = useMemo(() => [ { id: "report-back", run: back, enabled: !submitting }, { id: "report-submit", run: () => form.current?.requestSubmit(), enabled: canSubmit && !submitted }, ], [bossTest, canSubmit, openOverlay, submitted, submitting]); const controller = useMenuController(actions, { initialId: "report-back", onBack: back }); const submit = async (event: FormEvent) => { event.preventDefault(); if (!canSubmit || busy.current || submitted) return; busy.current = true; setSubmitting(true); setError(""); try { await submitDungeonReport(session, bossTest?.sourceDungeonId ?? dungeonId, comment, bossTest ? { bossKey: bossTest.key, bossName: bossTest.name } : undefined); setSubmitted(true); } catch (failure) { setError(failure instanceof Error ? failure.message : "Your report could not be submitted. Please try again."); } finally { busy.current = false; setSubmitting(false); } }; return (

{bossTest ? "Boss feedback" : "Dungeon feedback"}

{bossTest ? "Submit a boss report" : "Report an issue"}

{bossTest ? `${bossTest.name} ยท ${dungeonById(bossTest.sourceDungeonId)?.title ?? bossTest.sourceDungeonId}` : dungeonById(dungeonId)?.title ?? dungeonId}

{submitted ?

Report submitted. You can follow its status in View Reports on the main menu.

: (
void submit(event)}>