import { useEffect, useState } from "react"; import { OverlayActions } from "../../../../components/ui/overlay-actions"; import type { Location } from "fhir/r4"; import { Check } from "lucide-react"; import { useAuthServiceContext, useLocationServiceContext, useValueSetServiceContext } from "../../../../services"; import { isSaveRetired, isSaveTimedOut, useSaveScope } from "../../../../utils/saveOperation"; import { withNewer } from "../../../../utils/versionOrder"; import { useLocationTimeZone } from "../../../../hooks/useLocationTimeZone"; import { formatSingleAddress } from "../../../../utils/fhirAddress"; import { withTimezoneExtension } from "../../../../utils/practiceTimezone"; import { describeWriteFailure, ownFailureSentence } from "../../../../utils/fetchFailureMessage"; import { DismissibleAlert } from "../../../../components/ui/dismissible-alert"; import LocationTimeZoneField from "../../../../components/LocationTimeZoneField/LocationTimeZoneField"; type LocationTimeZoneRepairProps = { location: Location; help: string; onSaved: (location: Location) => void; }; // A saved site with no time zone gets one from its own address. The zone is patched onto the // existing Location; nothing else on it changes. const LocationTimeZoneRepair = ({ location, help, onSaved }: LocationTimeZoneRepairProps) => { const { updateLocation, setLocationsList } = useLocationServiceContext(); const { fetchTimezoneOptions } = useValueSetServiceContext(); const [options, setOptions] = useState<{ label: string; value: string }[]>([]); const [saving, setSaving] = useState(false); const [error, setError] = useState(); // The save belongs to this opening and practice: closing it, or another practice or viewer, retires it, so a late // answer never closes or installs anything for whoever is on screen next. const { wpOrganization } = useAuthServiceContext(); const saveScope = useSaveScope(wpOrganization.current?.id ?? "no-practice", () => { setSaving(false); setError(undefined); }); const address = location.address; const timeZone = useLocationTimeZone({ street: address?.line?.[0], city: address?.city, state: address?.state, postalCode: address?.postalCode, }); useEffect(() => { let cancelled = false; fetchTimezoneOptions() .then((zones) => { if (!cancelled) setOptions(zones.map((z) => ({ label: z.display || z.code, value: z.code }))); }) .catch(() => undefined); return () => { cancelled = true; }; }, [fetchTimezoneOptions]); const save = async () => { const zone = timeZone.zone; if (!zone) return; const operation = saveScope.start(); setSaving(true); setError(undefined); try { const saved = await operation.step(() => updateLocation( { ...location, extension: withTimezoneExtension(location.extension, zone) }, location.meta?.versionId, operation.transport, ), true); setLocationsList((current) => withNewer(current, saved)); onSaved(saved); } catch (err) { if (isSaveRetired(err)) return; setError(isSaveTimedOut(err) ? ownFailureSentence(err) : describeWriteFailure(err, "The time zone could not be saved")); } finally { if (operation.belongs()) setSaving(false); } }; return (
{location.name || "Your primary location"} {address ? ` ยท ${formatSingleAddress(address)}` : ""} needs its time zone before its schedules can run.
{error && ( setError(undefined)}> {error} )}
); }; export default LocationTimeZoneRepair;