From d64b9eabfa4fb8c7f80fea9c1a4894d84dc060f7 Mon Sep 17 00:00:00 2001 From: Andreas Weyer Date: Thu, 4 Dec 2025 01:45:11 +0000 Subject: [PATCH] Update day-schedule add folding and summary badges with trend indicator --- src/components/day-schedule.tsx | 102 ++++++++++++++++++++++++++++++-- src/locales/de.ts | 7 ++- src/locales/en.ts | 7 ++- 3 files changed, 110 insertions(+), 6 deletions(-) diff --git a/src/components/day-schedule.tsx b/src/components/day-schedule.tsx index 8e2f27b..a63ba17 100644 --- a/src/components/day-schedule.tsx +++ b/src/components/day-schedule.tsx @@ -15,7 +15,7 @@ import { Badge } from './ui/badge'; import { FormTimeInput } from './ui/form-time-input'; import { FormNumericInput } from './ui/form-numeric-input'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip'; -import { Plus, Copy, Trash2, ArrowDownAZ } from 'lucide-react'; +import { Plus, Copy, Trash2, ArrowDownAZ, ChevronDown, ChevronUp, TrendingUp, TrendingDown } from 'lucide-react'; import type { DayGroup } from '../constants/defaults'; interface DayScheduleProps { @@ -43,6 +43,21 @@ const DaySchedule: React.FC = ({ }) => { const canAddDay = days.length < 3; + // Track collapsed state for each day (by day ID) + const [collapsedDays, setCollapsedDays] = React.useState>(new Set()); + + const toggleDayCollapse = (dayId: string) => { + setCollapsedDays(prev => { + const newSet = new Set(prev); + if (newSet.has(dayId)) { + newSet.delete(dayId); + } else { + newSet.add(dayId); + } + return newSet; + }); + }; + // Check if doses are sorted chronologically const isDaySorted = (day: DayGroup): boolean => { for (let i = 1; i < day.doses.length; i++) { @@ -57,17 +72,94 @@ const DaySchedule: React.FC = ({ return (
- {days.map((day, dayIndex) => ( + {days.map((day, dayIndex) => { + // Get template day for comparison + const templateDay = days.find(d => d.isTemplate); + + // Calculate differences for deviation days + let doseCountDiff = 0; + let totalMgDiff = 0; + + if (!day.isTemplate && templateDay) { + doseCountDiff = day.doses.length - templateDay.doses.length; + const dayTotal = day.doses.reduce((sum, dose) => sum + (parseFloat(dose.ldx) || 0), 0); + const templateTotal = templateDay.doses.reduce((sum, dose) => sum + (parseFloat(dose.ldx) || 0), 0); + totalMgDiff = dayTotal - templateTotal; + } + + return (
-
+
+ {day.isTemplate ? t('regularPlan') : t('deviatingPlan')} {t('day')} {dayIndex + 1} + {!day.isTemplate && doseCountDiff !== 0 ? ( + + + + 0 ? 'bg-blue-50' : 'bg-orange-50'}`} + > + {doseCountDiff > 0 ? : } + {day.doses.length} {day.doses.length === 1 ? t('dose') : t('doses')} + + + +

+ {doseCountDiff > 0 ? '+' : ''}{doseCountDiff} {Math.abs(doseCountDiff) === 1 ? t('dose') : t('doses')} {t('comparedToRegularPlan')} +

+
+
+
+ ) : ( + + {day.doses.length} {day.doses.length === 1 ? t('dose') : t('doses')} + + )} + {!day.isTemplate && Math.abs(totalMgDiff) > 0.1 ? ( + + + + 0 ? 'bg-blue-50' : 'bg-orange-50'}`} + > + {totalMgDiff > 0 ? : } + {day.doses.reduce((sum, dose) => sum + (parseFloat(dose.ldx) || 0), 0).toFixed(1)} mg + + + +

+ {totalMgDiff > 0 ? '+' : ''}{totalMgDiff.toFixed(1)} mg {t('comparedToRegularPlan')} +

+
+
+
+ ) : ( + + {day.doses.reduce((sum, dose) => sum + (parseFloat(dose.ldx) || 0), 0).toFixed(1)} mg + + )}
{canAddDay && ( @@ -94,6 +186,7 @@ const DaySchedule: React.FC = ({
+ {!collapsedDays.has(day.id) && ( {/* Dose table header */}
@@ -186,8 +279,9 @@ const DaySchedule: React.FC = ({ )} + )} - ))} + )})} {/* Add day button */} {canAddDay && ( diff --git a/src/locales/de.ts b/src/locales/de.ts index 80b2050..e41b264 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -98,13 +98,18 @@ export const de = { // Day-based schedule regularPlan: "Regulärer Plan", deviatingPlan: "Abweichung vom Plan", - regularPlanOverlay: "nach Plan", + regularPlanOverlay: "Regulär", dayNumber: "Tag {{number}}", cloneDay: "Tag klonen", addDay: "Tag hinzufügen", addDose: "Dosis hinzufügen", removeDose: "Dosis entfernen", removeDay: "Tag entfernen", + collapseDay: "Tag einklappen", + expandDay: "Tag ausklappen", + dose: "Dosis", + doses: "Dosen", + comparedToRegularPlan: "verglichen mit regulärem Plan", time: "Zeit", ldx: "LDX", damph: "d-amph", diff --git a/src/locales/en.ts b/src/locales/en.ts index 812e025..3e45987 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -107,13 +107,18 @@ export const en = { // Day-based schedule regularPlan: "Regular Plan", deviatingPlan: "Deviation from Plan", - regularPlanOverlay: "as planned", + regularPlanOverlay: "Regular", dayNumber: "Day {{number}}", cloneDay: "Clone day", addDay: "Add day", addDose: "Add dose", removeDose: "Remove dose", removeDay: "Remove day", + collapseDay: "Collapse day", + expandDay: "Expand day", + dose: "dose", + doses: "doses", + comparedToRegularPlan: "compared to regular plan", time: "Time", ldx: "LDX", damph: "d-amph",