forked from phenom/healer-man
Release Healer Man 0.1.38
This commit is contained in:
1 parent
361734bc41
commit
b417b7c3c3
48 files changed
+1982
-90
No files matched your search
@@ -0,0 +1,69 @@
|
||||
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 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<HTMLFormElement>(null);
|
||||
const back = () => { if (!busy.current) openOverlay("pause"); };
|
||||
const canSubmit = Boolean(comment.trim()) && comment.length <= DUNGEON_REPORT_COMMENT_MAX_LENGTH && !submitting;
|
||||
const actions = useMemo<MenuAction[]>(() => [
|
||||
{ id: "report-back", run: back, enabled: !submitting },
|
||||
{ id: "report-submit", run: () => form.current?.requestSubmit(), enabled: canSubmit && !submitted },
|
||||
], [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, dungeonId, comment);
|
||||
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 (
|
||||
<div className="modal-backdrop" role="presentation">
|
||||
<section className="pause-menu dungeon-issue-report" role="dialog" aria-modal="true" aria-labelledby="issue-report-title">
|
||||
<p className="eyebrow">Dungeon feedback</p>
|
||||
<h2 id="issue-report-title">Report an issue</h2>
|
||||
<p>{dungeonById(dungeonId)?.title ?? dungeonId}</p>
|
||||
{submitted ? <p role="status">Report submitted. You can follow its status in View Reports on the main menu.</p> : (
|
||||
<form ref={form} onSubmit={(event) => void submit(event)}>
|
||||
<label htmlFor="dungeon-issue-comment">Describe the issue</label>
|
||||
<textarea id="dungeon-issue-comment" autoFocus required maxLength={DUNGEON_REPORT_COMMENT_MAX_LENGTH}
|
||||
value={comment} disabled={submitting} onChange={(event) => setComment(event.target.value)}
|
||||
aria-describedby="dungeon-issue-count" placeholder="What happened, and what were you doing when it happened?" />
|
||||
<small id="dungeon-issue-count">{comment.length} / {DUNGEON_REPORT_COMMENT_MAX_LENGTH} characters</small>
|
||||
{error && <p role="alert" className="dungeon-report-error">{error}</p>}
|
||||
<ControllerButton controlId="report-submit" selectedId={controller.selectedId} select={controller.select}
|
||||
className="button button--primary" type="submit" disabled={!canSubmit}>
|
||||
{submitting ? "Submitting..." : "Submit report"}
|
||||
</ControllerButton>
|
||||
</form>
|
||||
)}
|
||||
<ControllerButton controlId="report-back" selectedId={controller.selectedId} select={controller.select}
|
||||
className="button" type="button" onClick={back} disabled={submitting}>Back to pause menu</ControllerButton>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user