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;