feat: add locale support for date formatting in reminders and planner routes
This commit is contained in:
@@ -2,6 +2,7 @@ import { FastifyInstance } from "fastify";
|
|||||||
import nodemailer from "nodemailer";
|
import nodemailer from "nodemailer";
|
||||||
import { updateReminderSentTime } from "../services/reminder-scheduler.js";
|
import { updateReminderSentTime } from "../services/reminder-scheduler.js";
|
||||||
import { loadNotificationSettings, sendShoutrrrNotification } from "./settings.js";
|
import { loadNotificationSettings, sendShoutrrrNotification } from "./settings.js";
|
||||||
|
import { getDateLocale } from "../i18n/translations.js";
|
||||||
|
|
||||||
type PlannerRow = {
|
type PlannerRow = {
|
||||||
medicationId: number;
|
medicationId: number;
|
||||||
@@ -52,13 +53,17 @@ export async function plannerRoutes(app: FastifyInstance) {
|
|||||||
return reply.status(400).send({ error: "SMTP not configured" });
|
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
|
// Format dates for display
|
||||||
const fromDate = new Date(from).toLocaleDateString("en-US", {
|
const fromDate = new Date(from).toLocaleDateString(locale, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
});
|
});
|
||||||
const untilDate = new Date(until).toLocaleDateString("en-US", {
|
const untilDate = new Date(until).toLocaleDateString(locale, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ type UpcomingIntake = {
|
|||||||
pillWeightMg: number | null;
|
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();
|
const now = Date.now();
|
||||||
// Window to detect if "now" is the right time to send reminder
|
// 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
|
// 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,
|
medName,
|
||||||
usage: slice.usage,
|
usage: slice.usage,
|
||||||
intakeTime: intakeDate,
|
intakeTime: intakeDate,
|
||||||
intakeTimeStr: intakeDate.toLocaleTimeString([], {
|
intakeTimeStr: intakeDate.toLocaleTimeString(locale, {
|
||||||
hour: "2-digit",
|
hour: "2-digit",
|
||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
timeZone: getTimezone()
|
timeZone: getTimezone()
|
||||||
@@ -283,11 +283,12 @@ async function checkAndSendIntakeReminders(logger: { info: (msg: string) => void
|
|||||||
|
|
||||||
const state = loadIntakeReminderState();
|
const state = loadIntakeReminderState();
|
||||||
const allUpcoming: UpcomingIntake[] = [];
|
const allUpcoming: UpcomingIntake[] = [];
|
||||||
|
const locale = getDateLocale(language);
|
||||||
|
|
||||||
// Find all upcoming intakes across all medications
|
// Find all upcoming intakes across all medications
|
||||||
for (const med of medsWithReminders) {
|
for (const med of medsWithReminders) {
|
||||||
const slices = parseSlices(med);
|
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);
|
allUpcoming.push(...upcoming);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1479,7 +1479,7 @@ export default function App() {
|
|||||||
<div key={idx} className="med-schedule-item">
|
<div key={idx} className="med-schedule-item">
|
||||||
<span className="med-schedule-usage">{slice.usage} {slice.usage !== 1 ? t('common.pills') : t('common.pill')}{selectedMed.pillWeightMg && ` (${slice.usage * selectedMed.pillWeightMg} mg)`}</span>
|
<span className="med-schedule-usage">{slice.usage} {slice.usage !== 1 ? t('common.pills') : t('common.pill')}{selectedMed.pillWeightMg && ` (${slice.usage * selectedMed.pillWeightMg} mg)`}</span>
|
||||||
<span className="med-schedule-freq">{t('form.slices.every')} {slice.every} {slice.every !== 1 ? t('common.days') : t('common.day')}</span>
|
<span className="med-schedule-freq">{t('form.slices.every')} {slice.every} {slice.every !== 1 ? t('common.days') : t('common.day')}</span>
|
||||||
<span className="med-schedule-time">{t('modal.at')} {new Date(slice.start).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</span>
|
<span className="med-schedule-time">{t('modal.at')} {new Date(slice.start).toLocaleTimeString(i18n.language, { hour: "2-digit", minute: "2-digit" })}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user