1bc2de655a
Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
54 lines
2.4 KiB
TypeScript
54 lines
2.4 KiB
TypeScript
"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>
|
||
);
|
||
}
|