ThreadCount Community edition
Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
|
||||
/* The reveal control: a button, a reason, a confirmation. On success the page reloads and the
|
||||
* server renders the contacts through the reveal role — the values never travel in this response. */
|
||||
export default function Reveal({ facilityId, minutes }: { facilityId: string; minutes: number }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [reason, setReason] = useState("");
|
||||
const [err, setErr] = useState("");
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
async function submit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
setBusy(true); setErr("");
|
||||
try {
|
||||
const r = await fetch("/api/ops/reveal", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ facilityId, reason }) });
|
||||
const j = await r.json().catch(() => ({}));
|
||||
if (!r.ok) { setErr(j.error || "That didn’t work."); return; }
|
||||
window.location.reload();
|
||||
} catch {
|
||||
setErr("No connection — check the network and try again.");
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!open) {
|
||||
return <button type="button" className="btn" onClick={() => setOpen(true)} style={{ marginTop: 12 }}>Reveal contacts…</button>;
|
||||
}
|
||||
return (
|
||||
<form onSubmit={submit} style={{ marginTop: 12, display: "grid", gap: 8 }}>
|
||||
<label htmlFor="reveal-reason" style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--color-neutral-600)" }}>
|
||||
Reason — goes in the trail and the email
|
||||
</label>
|
||||
<textarea
|
||||
id="reveal-reason"
|
||||
className="input"
|
||||
rows={3}
|
||||
maxLength={400}
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
placeholder="e.g. Coordinator emailed support about a restore; calling back."
|
||||
autoFocus
|
||||
required
|
||||
/>
|
||||
{err && <div role="alert" style={{ border: "2px solid var(--color-accent)", padding: "8px 12px", fontSize: 13, fontWeight: 600, color: "var(--color-accent-700)" }}>{err}</div>}
|
||||
<div style={{ display: "flex", gap: 8 }}>
|
||||
<button type="submit" className="btn btn-primary" disabled={busy || reason.trim().length < 8}>{busy ? "Revealing…" : `Reveal for ${minutes} minutes`}</button>
|
||||
<button type="button" className="btn" onClick={() => { setOpen(false); setErr(""); }} disabled={busy}>Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user