import { useState, useEffect, useCallback } from 'react'; import { Item, ItemGroup } from "../../../components/ui/item-group"; import { useNavigate } from 'react-router-dom'; import { Icon } from "../../../components/ui/icon"; import { Heading } from '../../../components/ui/heading'; import { Flex, FlexItem, FlexBlock } from '../../../components/ui/flex'; import { Text } from '../../../components/ui/text'; import { Spacer } from '../../../components/ui/spacer'; // `shield`/`info` still feed WordPress's here - the separate icon sweep, not this one. import { Plus, Shield as shield, Info as info } from 'lucide-react'; import { Consent } from 'fhir/r4'; import { useConsentServiceContext, usePatientServiceContext } from '../../../services'; import { AppSpinner } from '../../../components'; import { ResourceListStatus } from '../../../components/ui/resource-list-status'; import { formatDate } from '../../../utils/dateUtils'; const ConsentsPage = () => { const navigate = useNavigate(); const { patientState } = usePatientServiceContext(); const { fetchConsentsWithPolling, shouldReload, setShouldReload, consentsBundle, consentsList, setUnsaved, } = useConsentServiceContext(); const [loading, setLoading] = useState(false); // - this page had NO error state at all: a failed load was swallowed into console.error // and the screen then asserted "No consent records found." Consent records are exactly the kind // of record whose absence is acted upon, so the failure has to be visible. const [error, setError] = useState(null); const loadData = useCallback(async () => { setLoading(true); setError(null); try { await fetchConsentsWithPolling(); } catch (err) { console.error('Failed to load consents:', err); setError('Failed to load consents.'); } finally { setLoading(false); if (shouldReload) { setShouldReload(false); } } }, [shouldReload, fetchConsentsWithPolling, setShouldReload]); useEffect(() => { if (!consentsBundle || shouldReload) { loadData(); } setUnsaved(false); }, [loadData, consentsBundle, shouldReload, setUnsaved]); const viewConsent = (consent: Consent) => { navigate(consent.id as string, { relative: 'route', state: { consent: consent } }); }; const addConsent = () => { navigate('new', { relative: 'route', state: { consent: null } }); }; const getScopeDisplay = (consent: Consent): string => { return consent.scope?.coding?.[0]?.display || consent.scope?.text || 'Unknown Scope'; }; const getCategoryDisplay = (consent: Consent): string => { if (!consent.category || consent.category.length === 0) { return ''; } return consent.category[0]?.coding?.[0]?.display || consent.category[0]?.text || 'Uncategorized'; }; const getStatusInfo = (consent: Consent): { status: string, isActive: boolean } => { const status = consent.status || 'unknown'; const isActive = status === 'active'; return { status: status.charAt(0).toUpperCase() + status.slice(1), isActive }; }; const getOrganizationCount = (consent: Consent): number => { return consent.organization?.length || 0; }; return (
Consents setError(null)} /> <> {loading ? ( ) : ( <> {consentsList.length !== 0 && ( {consentsList.map((consent: Consent) => { const scope = getScopeDisplay(consent); const category = getCategoryDisplay(consent); const { status, isActive } = getStatusInfo(consent); const organizationCount = getOrganizationCount(consent); return ( viewConsent(consent)} > {scope} {category && ( {` ${category}`} )} {consent.dateTime && ( {` [Date: ${formatDate(consent.dateTime)}]`} )} {organizationCount > 0 && ( {organizationCount} organization{organizationCount !== 1 ? 's' : ''} )} {status} ); })} )} )}
); }; export default ConsentsPage;