diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 22d47f3..b7c73f4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -799,7 +799,7 @@ function AppContent() {
{settings.emailEnabled && settings.shoutrrrEnabled ? "🔔" : settings.emailEnabled ? "📧" : "🔔"} - {t('dashboard.reminders.active')} — {getReminderStatusText(settings.reminderDaysBefore, coverage.low, settings.lastAutoEmailSent, settings.lastNotificationType, settings.lastNotificationChannel, t, i18n.language)} + {t('dashboard.reminders.active')} — {getReminderStatusText(settings.reminderDaysBefore, settings.lowStockDays, coverage.low, coverage.all, settings.lastAutoEmailSent, settings.lastNotificationType, settings.lastNotificationChannel, t, i18n.language)} {settings.emailEnabled && settings.notificationEmail && → {settings.notificationEmail}}
@@ -2153,8 +2153,10 @@ function calculateCoverage(meds: Medication[], events: Array<{ medName: string; } function getReminderStatusText( - reminderDaysBefore: number, + reminderDaysBefore: number, + lowStockDays: number, lowStock: Coverage[], + allCoverage: Coverage[], lastSent: string | null, lastType: "stock" | "intake" | null, lastChannel: "email" | "push" | "both" | null, @@ -2199,6 +2201,23 @@ function getReminderStatusText( return ⚠ {t('dashboard.reminders.needReorder', { count: medsNeedingReminder.length })} — {t('dashboard.reminders.waitingFirstCheck')}; } + // Check if there are low stock medications (not yet needing reminder but running low) + const lowStockNotYetCritical = allCoverage.filter( + (c) => c.daysLeft !== null && c.daysLeft > reminderDaysBefore && c.daysLeft < lowStockDays + ); + + if (lowStockNotYetCritical.length > 0) { + // There are low stock meds but not critical yet + const nextMed = lowStockNotYetCritical.sort((a, b) => (a.daysLeft ?? 0) - (b.daysLeft ?? 0))[0]; + const daysUntilReminder = (nextMed.daysLeft ?? 0) - reminderDaysBefore; + return ( + <> + {t('dashboard.reminders.lowWarning', { count: lowStockNotYetCritical.length })} + {" · "}{t('dashboard.reminders.nextIn')}: {nextMed.name} {t('dashboard.reminders.inDays', { days: daysUntilReminder })} + + ); + } + // Calculate when next reminder would be triggered const allWithDepletion = lowStock .filter((c) => c.depletionTime !== null && c.daysLeft !== null) diff --git a/frontend/src/i18n/de.json b/frontend/src/i18n/de.json index 88d19b8..e98f55e 100644 --- a/frontend/src/i18n/de.json +++ b/frontend/src/i18n/de.json @@ -43,6 +43,8 @@ "noRemindersNeeded": "keine Erinnerungen nötig", "needReorder": "{{count}} Medikament nachbestellen", "needReorder_other": "{{count}} Medikamente nachbestellen", + "lowWarning": "{{count}} Medikament wird knapp", + "lowWarning_other": "{{count}} Medikamente werden knapp", "waitingFirstCheck": "warte auf erste Prüfung", "typeStock": "Bestand", "typeIntake": "Einnahme", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 1c8388c..100be8f 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -45,6 +45,8 @@ "noRemindersNeeded": "no reminders needed", "needReorder": "{{count}} med needs reorder", "needReorder_other": "{{count}} meds need reorder", + "lowWarning": "{{count}} medication running low", + "lowWarning_other": "{{count}} medications running low", "waitingFirstCheck": "waiting for first check", "typeStock": "Stock", "typeIntake": "Intake",