- Report Issue button in portal header files a Forgejo issue (portal + claude-queue labels) - Windows scheduled watcher runs headless Claude Code on queued issues and opens a PR - .forgejo/workflows/deploy.yml deploys v* release tags via the pms1 host runner (pm2 restart ppms) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
130 lines
4.5 KiB
TypeScript
130 lines
4.5 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useTransition } from "react";
|
|
import { usePathname } from "next/navigation";
|
|
import { Bug } from "lucide-react";
|
|
import { AdminDialog } from "@/components/ui/admin-dialog";
|
|
import { reportIssue } from "./report-issue-actions";
|
|
|
|
const PRIORITIES = [
|
|
"P0 — Critical (broken / blocking)",
|
|
"P1 — High",
|
|
"P2 — Medium",
|
|
"P3 — Low",
|
|
] as const;
|
|
|
|
export function ReportIssueButton() {
|
|
const pathname = usePathname();
|
|
const [open, setOpen] = useState(false);
|
|
const [pending, startTransition] = useTransition();
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [filedIssue, setFiledIssue] = useState<{ number: number; url: string } | null>(null);
|
|
|
|
function close() {
|
|
setOpen(false);
|
|
setError(null);
|
|
setFiledIssue(null);
|
|
}
|
|
|
|
function onSubmit(e: React.FormEvent<HTMLFormElement>) {
|
|
e.preventDefault();
|
|
setError(null);
|
|
const formData = new FormData(e.currentTarget);
|
|
formData.set("page", pathname);
|
|
startTransition(async () => {
|
|
const result = await reportIssue(formData);
|
|
if ("error" in result) {
|
|
setError(result.error);
|
|
} else {
|
|
setFiledIssue({ number: result.issueNumber, url: result.issueUrl });
|
|
}
|
|
});
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<button
|
|
onClick={() => setOpen(true)}
|
|
className="flex items-center gap-1.5 rounded-lg p-2 text-neutral-500 hover:bg-neutral-100 hover:text-neutral-700 transition-colors"
|
|
title="Report an issue"
|
|
>
|
|
<Bug className="h-4 w-4" />
|
|
</button>
|
|
|
|
<AdminDialog title="Report an issue" open={open} onClose={close}>
|
|
{filedIssue ? (
|
|
<div className="space-y-4">
|
|
<p className="text-sm text-neutral-700">
|
|
Thanks — issue <span className="font-semibold">#{filedIssue.number}</span> has been
|
|
filed and queued for an automated fix. You'll see the change in an upcoming
|
|
release.
|
|
</p>
|
|
<button
|
|
onClick={close}
|
|
className="w-full rounded-lg bg-neutral-900 px-4 py-2 text-sm font-medium text-white hover:bg-neutral-700 transition-colors"
|
|
>
|
|
Done
|
|
</button>
|
|
</div>
|
|
) : (
|
|
<form onSubmit={onSubmit} className="space-y-4">
|
|
<div>
|
|
<label className="mb-1 block text-sm font-medium text-neutral-700" htmlFor="ri-title">
|
|
Title
|
|
</label>
|
|
<input
|
|
id="ri-title"
|
|
name="title"
|
|
required
|
|
minLength={5}
|
|
maxLength={150}
|
|
placeholder="Short summary of the problem"
|
|
className="w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-neutral-500 focus:outline-none"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="mb-1 block text-sm font-medium text-neutral-700" htmlFor="ri-description">
|
|
Description
|
|
</label>
|
|
<textarea
|
|
id="ri-description"
|
|
name="description"
|
|
required
|
|
minLength={10}
|
|
maxLength={5000}
|
|
rows={5}
|
|
placeholder="What happened? What did you expect? Steps to reproduce if it's a bug."
|
|
className="w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-neutral-500 focus:outline-none"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="mb-1 block text-sm font-medium text-neutral-700" htmlFor="ri-priority">
|
|
Priority
|
|
</label>
|
|
<select
|
|
id="ri-priority"
|
|
name="priority"
|
|
defaultValue={PRIORITIES[2]}
|
|
className="w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-neutral-500 focus:outline-none"
|
|
>
|
|
{PRIORITIES.map((p) => (
|
|
<option key={p} value={p}>
|
|
{p}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
{error && <p className="text-sm text-red-600">{error}</p>}
|
|
<button
|
|
type="submit"
|
|
disabled={pending}
|
|
className="w-full rounded-lg bg-neutral-900 px-4 py-2 text-sm font-medium text-white hover:bg-neutral-700 transition-colors disabled:opacity-50"
|
|
>
|
|
{pending ? "Filing issue…" : "Report issue"}
|
|
</button>
|
|
</form>
|
|
)}
|
|
</AdminDialog>
|
|
</>
|
|
);
|
|
}
|