'use client'; import { useMemo } from 'react'; import { useTranslations } from 'next-intl'; import { useAuth } from '@/lib/hooks/useAuth'; import { ChartCard } from '@/components/today/ChartCard'; import { TodayAreaChart } from '@/components/today/TodayAreaChart'; import { TodayBarChart } from '@/components/today/TodayBarChart'; import { formatTodayChartDayLabel, mapWeekChartBuckets, useTodayDayLabelFormatter, } from '@/components/today/chart-day-labels'; import { TodayDonutChart } from '@/components/today/TodayDonutChart'; import { TodayHorizontalBarChart } from '@/components/today/TodayHorizontalBarChart'; import { TodayRadialGaugeChart } from '@/components/today/TodayRadialGaugeChart'; import { TodayStackedBarChart } from '@/components/today/TodayStackedBarChart'; import { ChartCardSkeleton } from '@/components/today/TodaySkeleton'; import { prosthesisTypeColor, prosthesisTypeSwatchStyle } from '@/components/ui/treatment/prosthesisTypeDisplay'; import { treatmentTypeColor } from '@/components/ui/treatment/treatmentTypeDisplay'; import type { TodaySummaryCharts } from '@/types/today'; interface TodayChartsSectionProps { charts: TodaySummaryCharts; loading?: boolean; isInitialLoad?: boolean; className?: string; /** When true, chart cards render as siblings (no outer grid wrapper). */ embedded?: boolean; } export function TodayChartsSection({ charts, loading = false, isInitialLoad = false, className = '', embedded = false, }: TodayChartsSectionProps) { const t = useTranslations('today'); const dayLabelFormatter = useTodayDayLabelFormatter(); const { currentOrganization } = useAuth(); const orgType = currentOrganization?.type; const showAppointmentsByProvider = orgType === 'CLINIC' && charts.appointmentsByProvider !== undefined; const showAppointmentsWeekAll = orgType === 'CLINIC' && charts.appointmentsWeekAll !== undefined; const showAppointmentsWeekMine = orgType === 'CLINIC' && charts.appointmentsWeekMine !== undefined; const showTreatmentMix = orgType === 'CLINIC' && charts.treatmentMixWeek !== undefined; const showCaseCompletion = orgType === 'LAB' && charts.caseCompletion !== undefined; const showTasksByStep = orgType === 'LAB' && charts.tasksByWorkflowStep !== undefined; const showLabTaskActivityWeek = orgType === 'LAB' && charts.labTaskActivityWeek !== undefined; const showInProgressTasksByProsthesis = orgType === 'LAB' && charts.inProgressTasksByProsthesis !== undefined; const visibleChartCount = Number(showAppointmentsByProvider) + Number(showAppointmentsWeekAll) + Number(showAppointmentsWeekMine) + Number(showTreatmentMix) + Number(showCaseCompletion) + Number(showTasksByStep) + Number(showLabTaskActivityWeek) + Number(showInProgressTasksByProsthesis); const appointmentsByProviderData = charts.appointmentsByProvider ?? []; const appointmentsWeekAllData = useMemo( () => mapWeekChartBuckets(charts.appointmentsWeekAll ?? [], dayLabelFormatter), [charts.appointmentsWeekAll, dayLabelFormatter], ); const appointmentsWeekMineData = useMemo( () => mapWeekChartBuckets(charts.appointmentsWeekMine ?? [], dayLabelFormatter), [charts.appointmentsWeekMine, dayLabelFormatter], ); const treatmentData = charts.treatmentMixWeek ?? []; const tasksData = charts.tasksByWorkflowStep ?? []; const labTaskActivityData = useMemo( () => mapWeekChartBuckets(charts.labTaskActivityWeek ?? [], dayLabelFormatter), [charts.labTaskActivityWeek, dayLabelFormatter], ); const prosthesisData = charts.inProgressTasksByProsthesis ?? []; const caseCompletion = charts.caseCompletion ?? { completed: 0, total: 0, percent: 0 }; const formatDayLabel = (code: string) => formatTodayChartDayLabel(code, dayLabelFormatter); if (visibleChartCount === 0) { return null; } if (isInitialLoad) { const skeletons = Array.from({ length: Math.min(visibleChartCount, 4) }).map((_, index) => ( )); if (embedded) { return <>{skeletons}; } return (
{skeletons}
); } const gridClass = visibleChartCount > 1 ? 'grid grid-cols-1 lg:grid-cols-2' : 'grid grid-cols-1'; const chartCards = ( <> {showAppointmentsWeekAll ? ( row.count === 0)} emptyMessage={t('chartEmpty')} > ) : null} {showAppointmentsWeekMine ? ( row.count === 0)} emptyMessage={t('chartEmpty')} > ) : null} {showLabTaskActivityWeek ? ( row.completed === 0 && row.received === 0, )} emptyMessage={t('chartEmpty')} > ) : null} {showInProgressTasksByProsthesis ? ( prosthesisData.find((row) => row.code === code)?.label ?? code } colorForCode={(code, index) => prosthesisTypeColor(code, index)} swatchStyleForCode={(code, index) => prosthesisTypeSwatchStyle(code, index)} variant="pie" sideLegend /> ) : null} {showAppointmentsByProvider ? ( ) : null} {showTreatmentMix ? ( treatmentTypeColor(code, index)} /> ) : null} {showCaseCompletion ? ( ) : null} {showTasksByStep ? ( ) : null} ); if (embedded) { return chartCards; } return (
{chartCards}
); }