// Related-person "act-as" account switcher, client Task 3 - the confirm-on-entry dialog. // Self-contained: it owns the useActAs().enter() call itself (rather than taking `enter` as a prop) // so it can be dropped in wherever a switcher entry point wants a "become {name}" confirmation // without any extra wiring - the header trigger and the switch-into page are both later tasks. // // House modal rule: no Cancel button - the dialog's built-in X (DialogContent's showCloseButton) // dismisses it; the single action sits bottom-right (see CoupledRemovalConfirmDialog for the same // pattern). Portal-aware via ui/dialog.tsx (getAkashicPortalContainer) - no extra wiring needed here. import { useEffect, useState } from 'react'; import { ArrowRightLeft } from 'lucide-react'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../ui/dialog'; import { Button } from '../ui/button'; import { useActAs } from '../../hooks/useActAs'; import type { ActingAsTarget } from '../../services/AuthService.tsx'; interface ConfirmActAsDialogProps { open: boolean; target: ActingAsTarget | null; onOpenChange: (open: boolean) => void; // Fired after enter() succeeds, once the dialog has already closed itself - e.g. to navigate // into the proxy view. Optional so this dialog can be mounted standalone before that navigation // exists. onEntered?: () => void; } const ConfirmActAsDialog = ({ open, target, onOpenChange, onEntered }: ConfirmActAsDialogProps) => { const { enter } = useActAs(); const [isEntering, setIsEntering] = useState(false); const [error, setError] = useState(null); // Clear any error left over from a previous, failed attempt whenever the dialog is reopened // (possibly against a different target). useEffect(() => { if (open) { setError(null); } }, [open, target]); const handleConfirm = async () => { if (!target || isEntering) return; setIsEntering(true); const ok = await enter(target); setIsEntering(false); if (ok) { onOpenChange(false); onEntered?.(); } else { // Never claim it was withdrawn: the same refusal covers a grant that changed, one // reduced because identity verification is unfinished, and one genuinely ended. setError( "You cannot switch into this account right now. The access may have been changed, " + "or your identity verification may still be unfinished." ); } }; const subjectLabel = target?.subjectName || 'this record'; return ( Switch to {subjectLabel}? You're about to view {subjectLabel}'s {target?.scope === 'billing' ? ' invoices' : target?.scope === 'messaging' ? ' messages' : ' record'}. Everything you do while switched in is attributed to you, acting on their behalf. {error && (

{error}

)}
); }; export default ConfirmActAsDialog;