import React from 'react'; import { Item, ItemGroup } from "../components/ui/item-group"; import { LocationHoursOfOperation, PractitionerRoleAvailableTime, HealthcareServiceAvailableTime } from 'fhir/r4'; import { Flex, FlexItem } from '../components/ui/flex'; import { Text } from '../components/ui/text'; import { useValueSetServiceContext } from '../services'; interface FhirOperationalHoursDisplayProps { hours: LocationHoursOfOperation[] | PractitionerRoleAvailableTime[] | HealthcareServiceAvailableTime[] | undefined | null; emptyText?: string; className?: string; } const formatTime = (time: string | undefined): string => { if (!time) return ''; const [hours, minutes] = time.split(':'); const hour24 = parseInt(hours, 10); const hour12 = hour24 === 0 ? 12 : hour24 > 12 ? hour24 - 12 : hour24; const ampm = hour24 >= 12 ? 'PM' : 'AM'; return `${hour12}:${minutes} ${ampm}`; }; export const formatOperationalHours = ( hours: LocationHoursOfOperation[] | PractitionerRoleAvailableTime[] | HealthcareServiceAvailableTime[] | undefined | null, daysOfWeek: any[], emptyText: string = 'No hours recorded' ): string => { if (!hours || hours.length === 0) { return emptyText; } const formattedHours: string[] = []; hours.forEach((hourEntry) => { if (!hourEntry.daysOfWeek || hourEntry.daysOfWeek.length === 0) return; hourEntry.daysOfWeek.forEach((dayCode) => { const dayDisplay = daysOfWeek.find(day => day.code === dayCode)?.display || dayCode; if (hourEntry.allDay) { formattedHours.push(`${dayDisplay}: All Day`); } else { const openingTime = formatTime((hourEntry as any).openingTime || (hourEntry as any).availableStartTime); const closingTime = formatTime((hourEntry as any).closingTime || (hourEntry as any).availableEndTime); if (openingTime && closingTime) { formattedHours.push(`${dayDisplay}: ${openingTime} - ${closingTime}`); } else if (openingTime) { formattedHours.push(`${dayDisplay}: From ${openingTime}`); } else if (closingTime) { formattedHours.push(`${dayDisplay}: Until ${closingTime}`); } else { formattedHours.push(`${dayDisplay}: Hours not specified`); } } }); }); return formattedHours.join('\n'); }; export const useFhirOperationalHours = ( hours: LocationHoursOfOperation[] | PractitionerRoleAvailableTime[] | HealthcareServiceAvailableTime[] | undefined | null, emptyText: string = 'No hours recorded' ): string => { const { daysOfWeek } = useValueSetServiceContext(); return formatOperationalHours(hours, daysOfWeek, emptyText); }; export const FhirOperationalHoursDisplay: React.FC = ({ hours, emptyText = 'No hours recorded', className }) => { const { daysOfWeek } = useValueSetServiceContext(); if (!hours || hours.length === 0) { return ( {emptyText} ); } const dayHoursMap: { [key: string]: string } = {}; hours.forEach((hourEntry) => { if (!hourEntry.daysOfWeek || hourEntry.daysOfWeek.length === 0) return; hourEntry.daysOfWeek.forEach((dayCode) => { const dayDisplay = daysOfWeek.find(day => day.code === dayCode)?.display || dayCode; if (hourEntry.allDay) { dayHoursMap[dayDisplay] = 'All Day'; } else { const openingTime = formatTime((hourEntry as any).openingTime || (hourEntry as any).availableStartTime); const closingTime = formatTime((hourEntry as any).closingTime || (hourEntry as any).availableEndTime); if (openingTime && closingTime) { dayHoursMap[dayDisplay] = `${openingTime} - ${closingTime}`; } else if (openingTime) { dayHoursMap[dayDisplay] = `From ${openingTime}`; } else if (closingTime) { dayHoursMap[dayDisplay] = `Until ${closingTime}`; } else { dayHoursMap[dayDisplay] = 'Hours not specified'; } } }); }); const dayOrder = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; const sortedDays = Object.keys(dayHoursMap).sort((a, b) => { const indexA = dayOrder.indexOf(a); const indexB = dayOrder.indexOf(b); return (indexA === -1 ? 999 : indexA) - (indexB === -1 ? 999 : indexB); }); if (sortedDays.length === 0) { return ( {emptyText} ); } return ( {sortedDays.map((day) => ( {day} {dayHoursMap[day]} ))} ); };