import { useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; import { fetchDueReminders } from "@/api/diet.api"; import { isAuthenticated } from "@/store/authStore"; const POLL_MS = 60_000; const notifiedKeys = new Set(); function slotKey(id: number, date: string, hour: number, minute: number): string { return `${date}:${hour}:${minute}:${id}`; } export function useReminderNotifications(): void { const { t } = useTranslation(); const permissionRef = useRef("default"); useEffect(() => { if (typeof Notification === "undefined") { permissionRef.current = "unsupported"; return; } permissionRef.current = Notification.permission; if (Notification.permission === "default") { void Notification.requestPermission().then((p) => { permissionRef.current = p; }); } }, []); useEffect(() => { if (!isAuthenticated()) return; const tick = async () => { if (permissionRef.current !== "granted") return; try { const due = await fetchDueReminders(); const now = new Date(); const date = now.toISOString().slice(0, 10); for (const r of due) { const key = slotKey(r.id, date, now.getHours(), now.getMinutes()); if (notifiedKeys.has(key)) continue; notifiedKeys.add(key); new Notification(r.title, { body: r.message ?? t("diet.reminderNotificationBody"), tag: key, }); } } catch { // ignore polling errors } }; void tick(); const id = window.setInterval(() => void tick(), POLL_MS); return () => window.clearInterval(id); }, [t]); }