import { useEffect, useState } from "react"; import { ShieldCheck } from "lucide-react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../../../components/ui/dialog"; import { Button } from "../../../components/ui/button"; import { Checkbox } from "../../../components/ui/checkbox"; import { REFERRAL_AUTH_HEADLINE, REFERRAL_AUTH_SUMMARY } from "../../../services"; interface ReferralAuthorizationDialogProps { open: boolean; /** Who is being granted access - shown so the patient is agreeing about a NAMED person. */ subject: React.ReactNode; /** * - whether `subject` is an ACTUAL NAME or a fallback. * * This cannot be inferred from `subject`, and that is exactly how the defect shipped: it is a * ReactNode, so a resolved name and a raw `Practitioner/{uuid}` are indistinguishable by the time * they arrive here. The dialog rendered the UUID and offered the button. * * Defaults to `true` so existing callers that already pass a resolved name are unaffected; the * patient-approval path passes the real resolution. */ subjectIdentified?: boolean; busy?: boolean; /** What agreeing does here: approving a referral, sending an invitation, or giving a member access. */ agreeLabel?: string; onAgree: () => void; onCancel: () => void; } // S1c-c (client half) - the patient's authorization for a referral grant. // // The server refuses to mint the referral Consent without a recorded authorization, so this is not // a courtesy confirmation: it is the capture surface for the gate. That is also why it is a // deliberate two-step (read, then tick, then agree) rather than a yes/no confirm - the whole point // of the gate is that approving is NOT one silent tap on something that hands a stranger the // patient's entire chart. // // Radix `ui/dialog`, which portals into the in-app overlay root rather than document.body, so it // cannot bleed into (or be styled by) the surrounding WordPress theme. export const ReferralAuthorizationDialog = ({ open, subject, subjectIdentified = true, busy = false, agreeLabel = "Agree and approve", onAgree, onCancel, }: ReferralAuthorizationDialogProps) => { const [agreed, setAgreed] = useState(false); // Never carry a tick between subjects: reopening for a DIFFERENT practitioner must start // un-agreed, or one considered decision silently authorizes the next one. useEffect(() => { if (!open) setAgreed(false); }, [open]); return ( { if (!next) onCancel(); }}> {/* The close button's tap target is wider than the shared title reserve, so this long heading keeps its own clearance. */} {REFERRAL_AUTH_HEADLINE} {subjectIdentified ? ( <> You are about to give {subject} access to your medical record. ) : ( // An unusable dialog beats an uninformed agreement. Naming nobody is the honest state; // showing the reference and a button turns "we could not identify them" into a consent. <>We cannot confirm who this practitioner is, so we will not ask you to give them access. )} {subjectIdentified ? ( <> ) : (

This is not something you can fix. Please contact the practice that referred them.

)} {/* No agree button at all when the subject is unnamed — not a disabled one. A disabled control reads as "something is missing that you could supply", and there is nothing the patient can do here. The way out is Cancel. */} {subjectIdentified && ( )}
); }; export default ReferralAuthorizationDialog;