From 55dd9bbff5478af3a989c0b6982d5c23c2fc348b Mon Sep 17 00:00:00 2001 From: Daniel Volz Date: Thu, 25 Dec 2025 13:19:41 +0100 Subject: [PATCH] feat: add locale support for date formatting in reminders and planner routes --- backend/src/routes/planner.ts | 9 +++++++-- backend/src/services/intake-reminder-scheduler.ts | 7 ++++--- frontend/src/App.tsx | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/backend/src/routes/planner.ts b/backend/src/routes/planner.ts index 3086328..58e1ba0 100644 --- a/backend/src/routes/planner.ts +++ b/backend/src/routes/planner.ts @@ -2,6 +2,7 @@ import { FastifyInstance } from "fastify"; import nodemailer from "nodemailer"; import { updateReminderSentTime } from "../services/reminder-scheduler.js"; import { loadNotificationSettings, sendShoutrrrNotification } from "./settings.js"; +import { getDateLocale } from "../i18n/translations.js"; type PlannerRow = { medicationId: number; @@ -52,13 +53,17 @@ export async function plannerRoutes(app: FastifyInstance) { return reply.status(400).send({ error: "SMTP not configured" }); } + // Get locale from settings + const settings = loadNotificationSettings(); + const locale = getDateLocale(settings.language); + // Format dates for display - const fromDate = new Date(from).toLocaleDateString("en-US", { + const fromDate = new Date(from).toLocaleDateString(locale, { year: "numeric", month: "long", day: "numeric", }); - const untilDate = new Date(until).toLocaleDateString("en-US", { + const untilDate = new Date(until).toLocaleDateString(locale, { year: "numeric", month: "long", day: "numeric", diff --git a/backend/src/services/intake-reminder-scheduler.ts b/backend/src/services/intake-reminder-scheduler.ts index 9889f40..db80463 100644 --- a/backend/src/services/intake-reminder-scheduler.ts +++ b/backend/src/services/intake-reminder-scheduler.ts @@ -66,7 +66,7 @@ type UpcomingIntake = { pillWeightMg: number | null; }; -function getUpcomingIntakes(medName: string, slices: Slice[], minutesBefore: number, takenBy: string | null, pillWeightMg: number | null): UpcomingIntake[] { +function getUpcomingIntakes(medName: string, slices: Slice[], minutesBefore: number, takenBy: string | null, pillWeightMg: number | null, locale: string): UpcomingIntake[] { const now = Date.now(); // Window to detect if "now" is the right time to send reminder // We check if the notify time (intake - 15min) falls within current minute ±1 @@ -113,7 +113,7 @@ function getUpcomingIntakes(medName: string, slices: Slice[], minutesBefore: num medName, usage: slice.usage, intakeTime: intakeDate, - intakeTimeStr: intakeDate.toLocaleTimeString([], { + intakeTimeStr: intakeDate.toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit", timeZone: getTimezone() @@ -283,11 +283,12 @@ async function checkAndSendIntakeReminders(logger: { info: (msg: string) => void const state = loadIntakeReminderState(); const allUpcoming: UpcomingIntake[] = []; + const locale = getDateLocale(language); // Find all upcoming intakes across all medications for (const med of medsWithReminders) { const slices = parseSlices(med); - const upcoming = getUpcomingIntakes(med.name, slices, REMINDER_MINUTES_BEFORE, med.takenBy, med.pillWeightMg); + const upcoming = getUpcomingIntakes(med.name, slices, REMINDER_MINUTES_BEFORE, med.takenBy, med.pillWeightMg, locale); allUpcoming.push(...upcoming); } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6b68aa0..2048b3a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1479,7 +1479,7 @@ export default function App() {
{slice.usage} {slice.usage !== 1 ? t('common.pills') : t('common.pill')}{selectedMed.pillWeightMg && ` (${slice.usage * selectedMed.pillWeightMg} mg)`} {t('form.slices.every')} {slice.every} {slice.every !== 1 ? t('common.days') : t('common.day')} - {t('modal.at')} {new Date(slice.start).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} + {t('modal.at')} {new Date(slice.start).toLocaleTimeString(i18n.language, { hour: "2-digit", minute: "2-digit" })}
))}