+
{dose.takenBy && {dose.takenBy}}
{isTaken ? (
diff --git a/frontend/src/components/UserFilterModal.tsx b/frontend/src/components/UserFilterModal.tsx
index f4cc876..c4e1533 100644
--- a/frontend/src/components/UserFilterModal.tsx
+++ b/frontend/src/components/UserFilterModal.tsx
@@ -66,7 +66,8 @@ export function UserFilterModal({
- {currentStock}/{formatNumber(packageSize)} {t("common.pills")}
+ {currentStock}/{formatNumber(packageSize)}{" "}
+ {packageSize === 1 ? t("common.pill") : t("common.pills")}
{status && {t(status.label)}}
diff --git a/frontend/src/context/AppContext.tsx b/frontend/src/context/AppContext.tsx
index 9a4efa0..b3f6f93 100644
--- a/frontend/src/context/AppContext.tsx
+++ b/frontend/src/context/AppContext.tsx
@@ -615,7 +615,9 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
settings.repeatRemindersEnabled !== savedSettings.repeatRemindersEnabled ||
settings.reminderRepeatIntervalMinutes !== savedSettings.reminderRepeatIntervalMinutes ||
settings.maxNaggingReminders !== savedSettings.maxNaggingReminders ||
- settings.stockCalculationMode !== savedSettings.stockCalculationMode
+ settings.stockCalculationMode !== savedSettings.stockCalculationMode ||
+ settings.shareStockStatus !== savedSettings.shareStockStatus ||
+ settings.expiryWarningDays !== savedSettings.expiryWarningDays
);
}, [settingsHook.settings, settingsHook.savedSettings]);
diff --git a/frontend/src/hooks/useSettings.ts b/frontend/src/hooks/useSettings.ts
index 748e166..7fcdd7e 100644
--- a/frontend/src/hooks/useSettings.ts
+++ b/frontend/src/hooks/useSettings.ts
@@ -30,6 +30,9 @@ export interface Settings {
lastNotificationChannel: "email" | "push" | "both" | null;
lastReminderMedName: string | null;
lastReminderTakenBy: string | null;
+ lastStockReminderSent: string | null;
+ lastStockReminderChannel: "email" | "push" | "both" | null;
+ lastStockReminderMedNames: string | null;
shoutrrrEnabled: boolean;
shoutrrrUrl: string;
emailStockReminders: boolean;
@@ -37,6 +40,7 @@ export interface Settings {
shoutrrrStockReminders: boolean;
shoutrrrIntakeReminders: boolean;
stockCalculationMode: "automatic" | "manual";
+ shareStockStatus: boolean;
expiryWarningDays: number;
}
@@ -65,6 +69,9 @@ const defaultSettings: Settings = {
lastNotificationChannel: null,
lastReminderMedName: null,
lastReminderTakenBy: null,
+ lastStockReminderSent: null,
+ lastStockReminderChannel: null,
+ lastStockReminderMedNames: null,
shoutrrrEnabled: false,
shoutrrrUrl: "",
emailStockReminders: true,
@@ -72,6 +79,7 @@ const defaultSettings: Settings = {
shoutrrrStockReminders: true,
shoutrrrIntakeReminders: true,
stockCalculationMode: "automatic",
+ shareStockStatus: true,
expiryWarningDays: 30,
};
@@ -141,6 +149,9 @@ export function useSettings(): UseSettingsReturn {
lastNotificationChannel: data.lastNotificationChannel ?? prev.lastNotificationChannel,
lastReminderMedName: data.lastReminderMedName ?? prev.lastReminderMedName,
lastReminderTakenBy: data.lastReminderTakenBy ?? prev.lastReminderTakenBy,
+ lastStockReminderSent: data.lastStockReminderSent ?? prev.lastStockReminderSent,
+ lastStockReminderChannel: data.lastStockReminderChannel ?? prev.lastStockReminderChannel,
+ lastStockReminderMedNames: data.lastStockReminderMedNames ?? prev.lastStockReminderMedNames,
}));
setSavedSettings((prev) => ({
...prev,
@@ -149,6 +160,9 @@ export function useSettings(): UseSettingsReturn {
lastNotificationChannel: data.lastNotificationChannel ?? prev.lastNotificationChannel,
lastReminderMedName: data.lastReminderMedName ?? prev.lastReminderMedName,
lastReminderTakenBy: data.lastReminderTakenBy ?? prev.lastReminderTakenBy,
+ lastStockReminderSent: data.lastStockReminderSent ?? prev.lastStockReminderSent,
+ lastStockReminderChannel: data.lastStockReminderChannel ?? prev.lastStockReminderChannel,
+ lastStockReminderMedNames: data.lastStockReminderMedNames ?? prev.lastStockReminderMedNames,
}));
})
.catch(() => {});
@@ -198,6 +212,7 @@ export function useSettings(): UseSettingsReturn {
shoutrrrStockReminders: settings.shoutrrrStockReminders,
shoutrrrIntakeReminders: settings.shoutrrrIntakeReminders,
stockCalculationMode: settings.stockCalculationMode,
+ shareStockStatus: settings.shareStockStatus,
language: i18n.language,
smtpHost: settings.smtpHost,
smtpPort: settings.smtpPort,
diff --git a/frontend/src/i18n/de.json b/frontend/src/i18n/de.json
index 7241d0c..77e7206 100644
--- a/frontend/src/i18n/de.json
+++ b/frontend/src/i18n/de.json
@@ -21,11 +21,11 @@
"badge": "Bestandsüberwachung",
"noMeds": "Noch keine Medikamente konfiguriert.",
"allGood": "Alles in Ordnung, genug Vorrat.",
- "lowWarning": "Genug Vorrat, aber {{meds}} wird knapp.",
- "lowWarning_other": "Genug Vorrat, aber {{meds}} werden knapp.",
+ "lowWarning": "Genug Vorrat, aber {{meds}} ist kritisch niedrig.",
+ "lowWarning_other": "Genug Vorrat, aber {{meds}} sind kritisch niedrig.",
"lowWarningPrefix": "Genug Vorrat, aber",
- "lowWarningSuffix": "wird knapp.",
- "lowWarningSuffix_other": "werden knapp.",
+ "lowWarningSuffix": "ist kritisch niedrig.",
+ "lowWarningSuffix_other": "sind kritisch niedrig.",
"sendReminder": "🔔 Erinnerung jetzt senden"
},
"overview": {
@@ -59,10 +59,11 @@
"reminders": {
"active": "Automatische Erinnerungen aktiv",
"status": "Status",
- "allStockOk": "Bestand OK",
- "allOk": "Alles OK",
+ "allStockOk": "Bestand gut",
+ "allOk": "Alles gut",
"lastReminder": "Letzte Einnahme-Erinnerung",
"lastSent": "Letzte Einnahme-Erinnerung",
+ "lastStockSent": "Letzte Bestands-Erinnerung",
"next": "Nachbestell-Erinnerung",
"nextIn": "Nachbestell-Erinnerung",
"inDays": "in {{days}} Tagen",
@@ -73,8 +74,8 @@
"needRefill_other": "{{count}} Medikamente nachfüllen",
"emptyStock": "{{count}} Medikament leer",
"emptyStock_other": "{{count}} Medikamente leer",
- "lowWarning": "{{count}} Medikament wird knapp",
- "lowWarning_other": "{{count}} Medikamente werden knapp",
+ "lowWarning": "{{count}} Medikament kritisch niedrig",
+ "lowWarning_other": "{{count}} Medikamente kritisch niedrig",
"waitingFirstCheck": "Warte auf erste Prüfung",
"type": "Typ",
"typeStock": "Bestand",
@@ -123,7 +124,9 @@
"pillsPerBlister": "Tabletten pro Blister",
"loose": "Lose",
"total": "Gesamt",
- "stock": "Bestand"
+ "stock": "Bestand",
+ "totalCapacity": "Kapazität",
+ "type": "Typ"
}
},
"form": {
@@ -181,6 +184,7 @@
"calculate": "Berechnen",
"calculating": "Wird berechnet...",
"sendEmail": "📧 Per E-Mail senden",
+ "sendNotification": "🔔 Bedarf senden",
"table": {
"medication": "Medikament",
"usage": "Verbrauch",
@@ -229,25 +233,34 @@
"intakeCheck": "Einnahmeprüfung",
"15minBefore": "15 Min. vor geplanter Zeit",
"nextCheck": "Nächste Bestandsprüfung",
- "lastSent": "Zuletzt gesendet",
+ "lastSent": "Letzte Benachrichtigung",
+ "lastStockSent": "Letzte Bestands-Erinnerung",
+ "lastIntakeSent": "Letzte Einnahme-Erinnerung",
"envHint": "Diese Werte können über REMINDER_HOUR und REMINDER_MINUTES_BEFORE in .env konfiguriert werden"
},
"stock": {
"title": "Bestand",
- "threshold": "Erinnerungsschwelle",
- "remindWhen": "Erinnern wenn Vorrat unter",
- "repeatDaily": "Täglich wiederholen",
- "repeatTooltip": "Wenn aktiviert, wird täglich eine Erinnerung gesendet solange der Bestand niedrig ist. Andernfalls nur einmal pro Medikament bis zum Auffüllen.",
"calculationMode": "Bestandsberechnung",
"automatic": "Automatisch",
"automaticDesc": "Bestand wird automatisch anhand des Einnahmeplans reduziert",
"manual": "Manuell",
"manualDesc": "Bestand wird nur reduziert wenn Dosen als genommen markiert werden",
- "display": "Anzeige",
- "lowStockDays": "Niedriger Bestand (Tage)",
- "lowStockTooltip": "Gelbe Warnung ab diesem Schwellenwert",
- "highStockDays": "Hoher Bestand (Tage)",
- "highStockTooltip": "Grün mit Stern ab diesem Schwellenwert"
+ "thresholds": "Schwellenwerte",
+ "criticalStockDays": "Kritisch (Tage)",
+ "criticalStockTooltip": "Bestand unter diesem Wert ist kritisch und erfordert sofortige Aufmerksamkeit",
+ "lowStockDays": "Niedrig (Tage)",
+ "lowStockTooltip": "Bestand unter diesem Wert bedeutet, dass bald nachbestellt werden sollte",
+ "highStockDays": "Hoch (Tage)",
+ "highStockTooltip": "Bestand über diesem Wert bedeutet, dass du gut versorgt bist",
+ "thresholdValidation": "Werte müssen sein: Kritisch < Niedrig < Hoch",
+ "shareStockStatus": "Bestand auf geteilten Links anzeigen",
+ "shareStockStatusDesc": "Bestandsstatus (Normal/Niedrig/Kritisch) und farbige Rahmen auf geteilten Zeitplan-Links für Einnahme-Nutzer anzeigen"
+ },
+ "stockReminder": {
+ "title": "Bestands-Erinnerung",
+ "description": "Benachrichtigung wenn Medikamentenbestand erreicht",
+ "repeatDaily": "Täglich wiederholen",
+ "repeatTooltip": "Wenn aktiviert, wird täglich eine Erinnerung gesendet solange der Bestand kritisch ist. Andernfalls nur einmal pro Medikament bis zum Auffüllen."
},
"saveSettings": "Einstellungen speichern"
},
@@ -288,6 +301,7 @@
"tooltips": {
"intakeReminders": "Einnahme-Erinnerungen aktiviert",
"hasNotes": "Hat Notizen",
+ "stockExceedsCapacity": "Bestand überschreitet Packungskapazität — Packungsanzahl anpassen",
"lightMode": "Zum hellen Modus wechseln",
"darkMode": "Zum dunklen Modus wechseln"
},
@@ -348,6 +362,9 @@
"common": {
"loading": "Wird geladen...",
"sending": "Wird gesendet...",
+ "sent": "Gesendet!",
+ "sendFailed": "Senden fehlgeschlagen",
+ "networkError": "Netzwerkfehler",
"saving": "Wird gespeichert...",
"unsavedChanges": {
"title": "Ungespeicherte Änderungen",
@@ -386,6 +403,9 @@
"fullBlisters": "volle Blister",
"inBlister": "in 1 Blister",
"total": "gesamt",
+ "pillsTotal": "{{count}} Tabletten gesamt",
+ "pillsTotal_one": "{{count}} Tablette gesamt",
+ "pillsTotal_other": "{{count}} Tabletten gesamt",
"max": "max"
},
"share": {
@@ -450,6 +470,7 @@
"refill": {
"title": "Nachfüllen",
"packs": "Packungen hinzufügen",
+ "pillsToAdd": "Tabletten hinzufügen",
"loosePills": "Lose Tabletten hinzufügen",
"pillsPerPack": "1 Packung = {{count}} Tabletten",
"addToStock": "Zum Bestand hinzufügen",
@@ -466,6 +487,7 @@
"editStock": {
"title": "Bestand korrigieren",
"hint": "Dies ist für die Korrektur von Bestandsabweichungen. Für normale Bestandsänderungen nutze 'Nachfüllen'.",
+ "totalPills": "Gesamte Tabletten",
"fullBlisters": "Volle Blister",
"partialBlisterPills": "Angebrochener Blister",
"pillsPerBlister": "(je {{count}} Tabletten)",
diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json
index daece7f..94bbb30 100644
--- a/frontend/src/i18n/en.json
+++ b/frontend/src/i18n/en.json
@@ -21,11 +21,11 @@
"badge": "Stock watch",
"noMeds": "No medications configured yet.",
"allGood": "All good, enough stock.",
- "lowWarning": "Enough stock for now, but {{meds}} is running low.",
- "lowWarning_other": "Enough stock for now, but {{meds}} are running low.",
+ "lowWarning": "Enough stock for now, but {{meds}} is running critically low.",
+ "lowWarning_other": "Enough stock for now, but {{meds}} are running critically low.",
"lowWarningPrefix": "Enough stock for now, but",
- "lowWarningSuffix": "is running low.",
- "lowWarningSuffix_other": "are running low.",
+ "lowWarningSuffix": "is running critically low.",
+ "lowWarningSuffix_other": "are running critically low.",
"sendReminder": "🔔 Send Reminder Now"
},
"overview": {
@@ -59,10 +59,11 @@
"reminders": {
"active": "Automatic reminders active",
"status": "Status",
- "allStockOk": "All stock OK",
- "allOk": "All OK",
+ "allStockOk": "All stock good",
+ "allOk": "All good",
"lastReminder": "Last intake reminder",
"lastSent": "Last intake reminder",
+ "lastStockSent": "Last stock reminder",
"next": "Refill reminder",
"nextIn": "Refill reminder",
"inDays": "in {{days}} days",
@@ -73,8 +74,8 @@
"needRefill_other": "{{count}} meds need refill",
"emptyStock": "{{count}} med is empty",
"emptyStock_other": "{{count}} meds are empty",
- "lowWarning": "{{count}} medication running low",
- "lowWarning_other": "{{count}} medications running low",
+ "lowWarning": "{{count}} medication running critically low",
+ "lowWarning_other": "{{count}} medications running critically low",
"waitingFirstCheck": "Waiting for first check",
"type": "Type",
"typeStock": "Stock",
@@ -123,7 +124,9 @@
"pillsPerBlister": "Pills per blister",
"loose": "Loose",
"total": "Total",
- "stock": "Stock"
+ "stock": "Stock",
+ "totalCapacity": "Capacity",
+ "type": "Type"
}
},
"form": {
@@ -181,6 +184,7 @@
"calculate": "Calculate",
"calculating": "Calculating...",
"sendEmail": "📧 Send via Email",
+ "sendNotification": "🔔 Send Demand",
"table": {
"medication": "Medication",
"usage": "Usage",
@@ -229,25 +233,34 @@
"intakeCheck": "Intake check",
"15minBefore": "15 min before scheduled time",
"nextCheck": "Next stock check",
- "lastSent": "Last sent",
+ "lastSent": "Last notification sent",
+ "lastStockSent": "Last stock reminder",
+ "lastIntakeSent": "Last intake reminder",
"envHint": "These values can be configured via REMINDER_HOUR and REMINDER_MINUTES_BEFORE in .env"
},
"stock": {
"title": "Stock",
- "threshold": "Reminder Threshold",
- "remindWhen": "Remind when supply drops below",
- "repeatDaily": "Repeat daily",
- "repeatTooltip": "When enabled, sends reminders every day while stock is low. Otherwise, only notifies once per medication until restocked.",
"calculationMode": "Stock Calculation",
"automatic": "Automatic",
"automaticDesc": "Stock automatically decreases based on schedule",
"manual": "Manual",
"manualDesc": "Stock only decreases when doses are marked as taken",
- "display": "Display",
- "lowStockDays": "Low Stock (days)",
- "lowStockTooltip": "Yellow warning color threshold",
- "highStockDays": "High Stock (days)",
- "highStockTooltip": "Green with star threshold"
+ "thresholds": "Thresholds",
+ "criticalStockDays": "Critical (days)",
+ "criticalStockTooltip": "Stock below this value is critical and needs immediate attention",
+ "lowStockDays": "Low (days)",
+ "lowStockTooltip": "Stock below this value means you should reorder soon",
+ "highStockDays": "High (days)",
+ "highStockTooltip": "Stock above this value means you are well supplied",
+ "thresholdValidation": "Values must be: Critical < Low < High",
+ "shareStockStatus": "Show Stock on Shared Links",
+ "shareStockStatusDesc": "Show stock status (Normal/Low/Critical) and colored borders on shared schedule links for intake users"
+ },
+ "stockReminder": {
+ "title": "Stock Reminder",
+ "description": "Sends notification when medication stock reaches",
+ "repeatDaily": "Repeat daily",
+ "repeatTooltip": "When enabled, sends reminders every day while stock is critical. Otherwise, only notifies once per medication until restocked."
},
"saveSettings": "Save Settings"
},
@@ -288,6 +301,7 @@
"tooltips": {
"intakeReminders": "Intake reminders enabled",
"hasNotes": "Has notes",
+ "stockExceedsCapacity": "Stock exceeds package capacity — consider updating pack count",
"lightMode": "Switch to light mode",
"darkMode": "Switch to dark mode"
},
@@ -348,6 +362,9 @@
"common": {
"loading": "Loading...",
"sending": "Sending...",
+ "sent": "Sent!",
+ "sendFailed": "Failed to send",
+ "networkError": "Network error",
"saving": "Saving...",
"unsavedChanges": {
"title": "Unsaved Changes",
@@ -386,6 +403,9 @@
"fullBlisters": "full blisters",
"inBlister": "in 1 blister",
"total": "total",
+ "pillsTotal": "{{count}} pills total",
+ "pillsTotal_one": "{{count}} pill total",
+ "pillsTotal_other": "{{count}} pills total",
"max": "max"
},
"share": {
@@ -450,6 +470,7 @@
"refill": {
"title": "Refill",
"packs": "Packs to add",
+ "pillsToAdd": "Pills to add",
"loosePills": "Loose pills to add",
"pillsPerPack": "1 pack = {{count}} pills",
"addToStock": "Add to Stock",
@@ -466,6 +487,7 @@
"editStock": {
"title": "Correct Stock",
"hint": "This is for correcting stock discrepancies. For regular stock changes, use 'Refill'.",
+ "totalPills": "Total pills",
"fullBlisters": "Full blisters",
"partialBlisterPills": "Partial blister",
"pillsPerBlister": "({{count}} pills each)",
diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx
index 07920d9..d72e7a1 100644
--- a/frontend/src/pages/DashboardPage.tsx
+++ b/frontend/src/pages/DashboardPage.tsx
@@ -1,3 +1,4 @@
+import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ConfirmModal, MedicationAvatar } from "../components";
import { useAuth } from "../components/Auth";
@@ -80,12 +81,16 @@ function getReminderStatusData(
_lastNotificationChannel: string | null,
lastReminderMedName: string | null,
lastReminderTakenBy: string | null,
+ lastStockReminderSent: string | null,
+ _lastStockReminderChannel: string | null,
+ lastStockReminderMedNames: string | null,
t: (key: string, options?: Record
) => string,
locale: string
): {
status: { text: string; className: string };
lowStockMeds: { name: string; daysLeft: number; isCritical: boolean }[];
- lastSent: { date: string; medName: string | null; takenBy: string | null } | null;
+ lastStockSent: { date: string; medNames: string | null } | null;
+ lastIntakeSent: { date: string; medName: string | null; takenBy: string | null } | null;
} {
const criticalCount = lowCoverage.length;
const lowCount = allCoverage.filter((c) => {
@@ -141,25 +146,40 @@ function getReminderStatusData(
// Convert to array and sort by days left (most urgent first)
const lowStockMeds = Array.from(lowStockMap.values()).sort((a, b) => a.daysLeft - b.daysLeft);
- // Parse last sent info
- let lastSent: { date: string; medName: string | null; takenBy: string | null } | null = null;
- if (lastAutoEmailSent) {
- const lastSentDate = new Date(lastAutoEmailSent);
- const formattedDate = lastSentDate.toLocaleDateString(locale, {
+ // Parse last stock reminder sent info (from dedicated stock tracking columns)
+ let lastStockSent: { date: string; medNames: string | null } | null = null;
+ if (lastStockReminderSent) {
+ const sentDate = new Date(lastStockReminderSent);
+ const formattedDate = sentDate.toLocaleDateString(locale, {
day: "2-digit",
month: "short",
hour: "2-digit",
minute: "2-digit",
});
+ lastStockSent = {
+ date: formattedDate,
+ medNames: lastStockReminderMedNames,
+ };
+ }
- lastSent = {
+ // Parse last intake reminder sent info (from intake tracking columns)
+ let lastIntakeSent: { date: string; medName: string | null; takenBy: string | null } | null = null;
+ if (lastAutoEmailSent) {
+ const sentDate = new Date(lastAutoEmailSent);
+ const formattedDate = sentDate.toLocaleDateString(locale, {
+ day: "2-digit",
+ month: "short",
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+ lastIntakeSent = {
date: formattedDate,
medName: lastReminderMedName,
takenBy: lastReminderTakenBy,
};
}
- return { status, lowStockMeds, lastSent };
+ return { status, lowStockMeds, lastStockSent, lastIntakeSent };
}
export function DashboardPage() {
@@ -199,6 +219,7 @@ export function DashboardPage() {
openShareDialog,
openScheduleLightbox,
stockThresholds,
+ loadSettings,
} = useAppContext();
// Get structured reminder data
@@ -212,6 +233,9 @@ export function DashboardPage() {
settings.lastNotificationChannel,
settings.lastReminderMedName,
settings.lastReminderTakenBy,
+ settings.lastStockReminderSent,
+ settings.lastStockReminderChannel,
+ settings.lastStockReminderMedNames,
t,
getSystemLocale(i18n.language)
);
@@ -225,6 +249,50 @@ export function DashboardPage() {
(settings.shoutrrrEnabled && settings.shoutrrrIntakeReminders);
const anyRemindersEnabled = stockRemindersEnabled || intakeRemindersEnabled;
+ // Manual reminder send state
+ const [sendingReminder, setSendingReminder] = useState(false);
+ const [reminderResult, setReminderResult] = useState<{ success: boolean; message: string } | null>(null);
+
+ async function sendManualReminder() {
+ if (!stockRemindersEnabled || reminderData.lowStockMeds.length === 0) return;
+ setSendingReminder(true);
+ setReminderResult(null);
+
+ try {
+ const lowStock = reminderData.lowStockMeds.map((m) => {
+ const cov = coverage.all.find((c) => c.name === m.name);
+ return {
+ name: m.name,
+ medsLeft: cov?.medsLeft ?? 0,
+ daysLeft: m.daysLeft,
+ depletionDate: cov?.depletionDate ?? null,
+ isCritical: m.isCritical,
+ };
+ });
+
+ const res = await fetch("/api/reminder/send-email", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ credentials: "include",
+ body: JSON.stringify({
+ email: settings.notificationEmail,
+ lowStock,
+ }),
+ });
+ const data = await res.json();
+ if (res.ok) {
+ setReminderResult({ success: true, message: data.message || t("common.sent") });
+ // Refresh settings so "Last stock reminder" row appears immediately
+ loadSettings();
+ } else {
+ setReminderResult({ success: false, message: data.error || t("common.sendFailed") });
+ }
+ } catch {
+ setReminderResult({ success: false, message: t("common.networkError") });
+ }
+ setSendingReminder(false);
+ }
+
return (
<>
{anyRemindersEnabled && (
@@ -234,14 +302,11 @@ export function DashboardPage() {
{t("dashboard.reminders.active")}
- {reminderData.lowStockMeds.length === 0 && (
-
- {reminderData.status.className === "success" && "✓ "}
- {reminderData.status.text}
-
- )}
+ {reminderData.status.text}
- {(reminderData.lowStockMeds.length > 0 || (intakeRemindersEnabled && reminderData.lastSent)) && (
+ {(reminderData.lowStockMeds.length > 0 ||
+ (stockRemindersEnabled && reminderData.lastStockSent) ||
+ (intakeRemindersEnabled && reminderData.lastIntakeSent)) && (
)}
+ {stockRemindersEnabled && reminderData.lowStockMeds.length > 0 && (
+
+ )}
)}
{/* Reorder Reminder card: Only show when reminders are NOT enabled (otherwise Reminder Bar shows the same info) */}
@@ -568,7 +671,7 @@ export function DashboardPage() {
return (