diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index fe2cdf4..6ad7511 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1076,18 +1076,27 @@ function AppContent() {
{/* Past days toggle */} - {pastDays.length > 0 && ( -
setShowPastDays(!showPastDays)} - > - {showPastDays ? '▼' : '▶'} - - {showPastDays ? t('dashboard.schedules.hidePastDays') : t('dashboard.schedules.showPastDays')} - - ({t('dashboard.schedules.pastDaysCount', { count: pastDays.length })}) -
- )} + {pastDays.length > 0 && (() => { + const totalPastDoses = pastDays.flatMap(d => d.meds.flatMap(m => m.doses.map(dose => dose.id))); + const missedPastDoses = totalPastDoses.filter(id => !takenDoses.has(id)).length; + return ( +
0 ? 'has-missed' : ''}`} + onClick={() => setShowPastDays(!showPastDays)} + > + {showPastDays ? '▼' : '▶'} + + {showPastDays ? t('dashboard.schedules.hidePastDays') : t('dashboard.schedules.showPastDays')} + + ({t('dashboard.schedules.pastDaysCount', { count: pastDays.length })}) + {missedPastDoses > 0 ? ( + ⚠️ {missedPastDoses} + ) : totalPastDoses.length > 0 ? ( + + ) : null} +
+ ); + })()} {/* Past days (when expanded) */} {showPastDays && pastDays.map((day) => { const allDoseIds = day.meds.flatMap((item) => item.doses.map((d) => d.id)); @@ -1110,7 +1119,7 @@ function AppContent() { {allDayTaken ? ( ✓ {t('dashboard.schedules.allTaken')} ) : ( - {takenCount}/{allDoseIds.length} + <>⚠️{takenCount}/{allDoseIds.length} )}
@@ -1841,18 +1850,23 @@ function AppContent() {
{/* Past days toggle */} - {pastDays.length > 0 && ( -
setShowPastDays(!showPastDays)} - > - {showPastDays ? '▼' : '▶'} - - {showPastDays ? t('dashboard.schedules.hidePastDays') : t('dashboard.schedules.showPastDays')} - - ({t('dashboard.schedules.pastDaysCount', { count: pastDays.length })}) -
- )} + {pastDays.length > 0 && (() => { + const totalPastDoses = pastDays.flatMap(d => d.meds.flatMap(m => m.doses.map(dose => dose.id))); + const missedPastDoses = totalPastDoses.filter(id => !takenDoses.has(id)).length; + return ( +
0 ? 'has-missed' : ''}`} + onClick={() => setShowPastDays(!showPastDays)} + > + {showPastDays ? '▼' : '▶'} + + {showPastDays ? t('dashboard.schedules.hidePastDays') : t('dashboard.schedules.showPastDays')} + + ({t('dashboard.schedules.pastDaysCount', { count: pastDays.length })}) + {missedPastDoses > 0 && ⚠️ {missedPastDoses}} +
+ ); + })()} {/* Past days (when expanded) */} {showPastDays && pastDays.map((day) => { const allDoseIds = day.meds.flatMap((item) => item.doses.map((d) => d.id)); @@ -1874,7 +1888,7 @@ function AppContent() { {allDayTaken ? ( ✓ {t('dashboard.schedules.allTaken')} ) : ( - {takenCount}/{allDoseIds.length} + <>⚠️{takenCount}/{allDoseIds.length} )}
@@ -3062,18 +3076,27 @@ function SharedSchedule() { ) : ( <> {/* Past days toggle */} - {pastDays.length > 0 && ( -
setShowPastDays(!showPastDays)} - > - {showPastDays ? '▼' : '▶'} - - {showPastDays ? t('dashboard.schedules.hidePastDays') : t('dashboard.schedules.showPastDays')} - - ({t('dashboard.schedules.pastDaysCount', { count: pastDays.length })}) -
- )} + {pastDays.length > 0 && (() => { + const totalPastDoses = pastDays.flatMap(d => d.meds.flatMap(m => m.doses.map(dose => dose.id))); + const missedPastDoses = totalPastDoses.filter(id => !takenDoses.has(id)).length; + return ( +
0 ? 'has-missed' : ''}`} + onClick={() => setShowPastDays(!showPastDays)} + > + {showPastDays ? '▼' : '▶'} + + {showPastDays ? t('dashboard.schedules.hidePastDays') : t('dashboard.schedules.showPastDays')} + + ({t('dashboard.schedules.pastDaysCount', { count: pastDays.length })}) + {missedPastDoses > 0 ? ( + ⚠️ {missedPastDoses} + ) : totalPastDoses.length > 0 ? ( + + ) : null} +
+ ); + })()} {/* Past days (when expanded) */} {showPastDays && pastDays.map((day) => { const allDoseIds = day.meds.flatMap((item) => item.doses.map((d) => d.id)); @@ -3098,7 +3121,7 @@ function SharedSchedule() { {allDayTaken ? ( ✓ {t('dashboard.schedules.allTaken')} ) : ( - {takenCount}/{allDoseIds.length} + <>⚠️{takenCount}/{allDoseIds.length} )} diff --git a/frontend/src/i18n/de.json b/frontend/src/i18n/de.json index e967b5c..d953a4d 100644 --- a/frontend/src/i18n/de.json +++ b/frontend/src/i18n/de.json @@ -36,7 +36,9 @@ "showPastDays": "Vergangene Tage anzeigen", "hidePastDays": "Vergangene Tage ausblenden", "pastDaysCount": "{{count}} vergangener Tag", - "pastDaysCount_other": "{{count}} vergangene Tage" + "pastDaysCount_other": "{{count}} vergangene Tage", + "missedDoses": "{{count}} verpasste Dosis", + "missedDoses_other": "{{count}} verpasste Dosen" }, "reminders": { "active": "Automatische Erinnerungen aktiv", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 3f46478..49486a7 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -38,7 +38,9 @@ "showPastDays": "Show past days", "hidePastDays": "Hide past days", "pastDaysCount": "{{count}} past day", - "pastDaysCount_other": "{{count}} past days" + "pastDaysCount_other": "{{count}} past days", + "missedDoses": "{{count}} missed dose", + "missedDoses_other": "{{count}} missed doses" }, "reminders": { "active": "Automatic reminders active", diff --git a/frontend/src/styles.css b/frontend/src/styles.css index c89bc9e..9d816a3 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -432,6 +432,25 @@ textarea { opacity: 0.6; font-size: 0.85rem; } +.past-days-warning { + margin-left: auto; + color: var(--warning); + font-size: 0.9rem; + font-weight: 600; + display: flex; + align-items: center; + gap: 0.25rem; +} +.past-days-complete { + margin-left: auto; + color: var(--success); + font-size: 1rem; + font-weight: 700; +} +.past-days-toggle.has-missed { + border-color: var(--warning); + background: rgba(234, 179, 8, 0.08); +} /* Past day blocks styling */ .day-block.past { @@ -489,6 +508,7 @@ textarea { } .day-complete { color: var(--success); } .day-progress { color: var(--text-secondary); } +.day-warning { margin-right: 0.35rem; } .day-block.collapsed .day-divider { margin-bottom: 0; padding-bottom: 0;