Add developer API, Prometheus metrics, and community links

This commit is contained in:
2026-10-12 19:59:37 +05:00
parent 3cc3136762
commit 018be5049e
50 changed files with 4087 additions and 31 deletions

View File

@@ -37,19 +37,26 @@ export function SupportInbox({ pagePath }: { pagePath: string }) {
[name, setName] = useState(""),
[file, setFile] = useState<File | null>(null);
const nonce = useRef<string | null>(null);
const [attempt, setAttempt] = useState(0);
const [loading, setLoading] = useState(true);
useEffect(() => {
let stopped = false;
setLoading(true);
setError("");
api<Inbox>("bug-reports")
.then((value) => {
if (!stopped) setInbox(value);
})
.catch((failure) => {
if (!stopped) setError(failure.message);
})
.finally(() => {
if (!stopped) setLoading(false);
});
return () => {
stopped = true;
};
}, []);
}, [attempt]);
async function submit() {
if (busy) return;
const clientId = (nonce.current ??= crypto.randomUUID());
@@ -109,7 +116,7 @@ export function SupportInbox({ pagePath }: { pagePath: string }) {
</span>
<h1>{t("Found a bug?")}</h1>
<p className="lead">{t("Tell us what happened. We’ll reply here.")}</p>
{!inbox?.signedIn && (
{inbox && !inbox.signedIn && (
<p className="muted">
{t(
"Guest reports stay in this browser. Sign in to keep your conversation in your account.",
@@ -120,6 +127,19 @@ export function SupportInbox({ pagePath }: { pagePath: string }) {
{error && (
<p className="error-message" role="alert">
{t(error)}
{!inbox && (
<>
{" "}
<button
type="button"
className="text-link"
disabled={loading}
onClick={() => setAttempt((value) => value + 1)}
>
{t("Retry")}
</button>
</>
)}
</p>
)}
{inbox && !inbox.ready && (
@@ -135,7 +155,7 @@ export function SupportInbox({ pagePath }: { pagePath: string }) {
void submit();
}}
>
{!inbox?.signedIn && (
{inbox && !inbox.signedIn && (
<>
<label htmlFor="report-name">{t("Your player name")}</label>
<input
@@ -199,7 +219,10 @@ export function SupportInbox({ pagePath }: { pagePath: string }) {
<small>
{t("PNG, JPG, or WebP, up to 5 MB. Shared privately with support.")}
</small>
<button className="button primary" disabled={busy || !inbox?.ready}>
<button
className="button primary"
disabled={busy || loading || !inbox?.ready}
>
<Send size={17} />
{busy ? t("Sending…") : t("Send bug report")}
</button>
@@ -207,9 +230,9 @@ export function SupportInbox({ pagePath }: { pagePath: string }) {
</section>
<section className="support-inbox">
<h2>{t("Your bug reports")}</h2>
{!inbox ? (
{!inbox && loading ? (
<p className="muted">{t("Loading…")}</p>
) : inbox.reports.length === 0 ? (
) : !inbox ? null : inbox.reports.length === 0 ? (
<p className="muted">
{t("Your reports and support replies will appear here.")}
</p>