import { useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { environment } from '../../environments/environment'; import { useAuthServiceContext } from '../../services/AuthService.tsx'; import { useHttpService } from '../../services/HttpService.tsx'; import { relayServerFailure } from '../../utils/fetchFailureMessage'; import { clearNotificationLinkToken, destinationPath, destinationState, getNotificationLinkToken, type NotificationDestination, } from '../../utils/notificationLink'; import { DismissibleAlert } from '../ui/dismissible-alert.tsx'; /** * Once a person is signed in, opens the notification link they arrived with. The server answers only * the person it was sent to; any refusal is shown as what it is. */ export function NotificationLinkOpener() { const { isLoggedIn } = useAuthServiceContext(); const { post } = useHttpService(); const navigate = useNavigate(); const [refusal, setRefusal] = useState(null); const opening = useRef(false); useEffect(() => { const token = getNotificationLinkToken(); if (!isLoggedIn || !token || opening.current) return; opening.current = true; // Consumed before the request, so a failure never replays on the next render or sign-in. clearNotificationLinkToken(); post<{ destination: NotificationDestination; organization?: { id: string; name?: string } }>( `${environment.fhirBaseApi}/notification-link-resolve`, { token }, ) .then((result) => navigate(destinationPath(result.destination), { replace: true, state: destinationState(result.destination, result.organization), })) .catch((error: unknown) => { setRefusal(relayServerFailure(error, 'This notification link could not be opened. Everything it pointed to is still in your portal.')); }); }, [isLoggedIn, navigate, post]); if (!refusal) return null; return (
setRefusal(null)}> {refusal}
); }