import { useEffect, useMemo, useState, type ReactNode } from 'react'; import { Outlet, useLocation } from 'react-router-dom'; import { useAuthServiceContext } from '../../../../services/AuthService'; import { authSessionId } from '../../../../services/authStorage'; import { AgreementBlocks } from '../../../../components/FirstSignInGate/AgreementBlocks'; import { useMsaRecovery, type MsaRecoveryLocator, type MsaRecoveryOpening } from '../../../../hooks/useMsaRecovery'; import { heldMsaKey, msaOperationId, readHeldMsa, type HeldMsaOperation } from '../../../../utils/msaRecovery'; import { msaClosingLines, resolveMsaBlocks } from '../../../../utils/msaAgreement'; import { formatDayMonthYear } from '../../../../utils/dateUtils'; import type { BaaSignFormParts } from './BaaSignForm'; type Parts = (parts: BaaSignFormParts) => ReactNode; const RecoveryView = ({ opening, children }: { opening: MsaRecoveryOpening; children: Parts }) => { const { read, busy, error, actorMatches, canResume, check, resume } = opening; const preview = actorMatches && read?.actorMayResume ? read.frozen?.preview : undefined; const request = read?.frozen?.request; const facts = preview && request ? { ...preview.facts, signerName: request.signerName, signerTitle: request.signerTitle, signDate: request.signDate } : undefined; const body =

This checks the acceptance you already started. It does not start a new agreement or change your Business Associate Agreement.

{busy &&

Checking your original acceptance…

} {error &&

{error}

} {!busy && read?.state === 'accepted' && actorMatches &&

Version {read.version} accepted on {formatDayMonthYear(read.acceptedAt ?? '')}. Your original acceptance is confirmed.

} {!busy && read?.state === 'absent' &&

Your original acceptance has not been found yet. Check again; a delayed request may still arrive.

} {!busy && read?.state === 'conflict' &&

This acceptance needs Akashic support. Its original reference has been kept.

} {!busy && read && read.state !== 'absent' && !actorMatches &&

This acceptance belongs to another sign-in. Use the original account to check it.

} {!busy && read?.state === 'admitted' && actorMatches && (!read.actorMayResume || !preview) &&

The original agreement could not be confirmed for recording. Check again before continuing.

} {!busy && read?.state === 'admitted' && actorMatches && read.actorMayResume && preview &&

Your acceptance could not be confirmed yet. Resume recording to finish that same acceptance.

} {preview && facts &&

{preview.title}

{msaClosingLines(facts).map((line) =>

{line}

)}
}
; const actions =
{canResume && }
; return <>{children({ body, actions, wide: true })}; }; export const MsaRecoveryPage = ({ opening }: { opening: MsaRecoveryOpening }) =>

Master Subscription Agreement

{({ body, actions }) => <>{body}{actions}}
; const HeldOpening = ({ locator, onAccepted, children }: { locator: MsaRecoveryLocator; onAccepted: () => void; children: Parts }) => { const opening = useMsaRecovery(locator, onAccepted); return {children}; }; export const MsaHeldForm = ({ held, onAccepted, children }: { held: HeldMsaOperation; onAccepted: () => void; children: Parts }) => { const { currentUser, wpOrganization, actingAsSessionRef } = useAuthServiceContext(); const practitionerId = currentUser?.fhir?.resourceType === 'Practitioner' ? currentUser.fhir.id : undefined; if (!practitionerId || currentUser?.cognito?.sub !== held.actorId || wpOrganization.current?.id !== held.organizationId) { return

Use the original sign-in and practice to check this acceptance.

; } const key = [held.request.operationId, held.actorId, practitionerId, authSessionId(), actingAsSessionRef.current].join('|'); return {children}; }; const RouteOpening = ({ locator, renderOpening }: { locator: MsaRecoveryLocator; renderOpening?: (opening: MsaRecoveryOpening) => ReactNode }) => { const [captured] = useState(locator); const opening = useMsaRecovery(captured); return opening.canOpen ? <>{renderOpening ? renderOpening(opening) : } : ; }; /** Only this MSA route receives the recovery opening; the existing fresh-owner sheet remains its fallback. */ export const MsaRecoveryAccess = ({ fallback, renderOpening }: { fallback: ReactNode; renderOpening?: (opening: MsaRecoveryOpening) => ReactNode }) => { const { currentUser, wpOrganization, actingAsSessionRef } = useAuthServiceContext(); const { search } = useLocation(); const organizationId = wpOrganization.current?.id; const actorId = currentUser?.cognito?.sub; const practitionerId = currentUser?.fhir?.resourceType === 'Practitioner' ? currentUser.fhir.id : undefined; const [revision, setRevision] = useState(0); useEffect(() => { const changed = (event: StorageEvent) => { if (organizationId && actorId && (event.key === null || event.key === heldMsaKey(organizationId, actorId) || event.key?.startsWith(heldMsaKey(organizationId, actorId) + '.op.'))) setRevision((n) => n + 1); }; window.addEventListener('storage', changed); return () => window.removeEventListener('storage', changed); }, [organizationId, actorId]); const held = useMemo(() => organizationId && actorId ? readHeldMsa(organizationId, actorId) : undefined, [organizationId, actorId, revision]); const requested = new URLSearchParams(search).get('msaOperation'); if (!held && requested === null) return <>{fallback}; const operationId = requested ?? (held && held !== 'unavailable' ? held.request.operationId : undefined); if (!organizationId || !actorId || !practitionerId || !msaOperationId(operationId)) return

Your previous acceptance could not be read safely. Contact Akashic support before starting another.

; const saved = held && held !== 'unavailable' && held.request.operationId === operationId ? held : undefined; const key = [organizationId, actorId, practitionerId, operationId, authSessionId(), actingAsSessionRef.current, saved ? JSON.stringify(saved.request) : 'discovered'].join('|'); return ; };