"use client"; import { useEffect, useRef } from "react"; import { useSession } from "@/lib/auth-client"; import { ReminderKind, loadHellthData } from "@/lib/hellth-data"; const labels: Record = { water: "Wasser", snack: "Snack", movement: "Bewegung", }; function minutesOfDay(value: string) { const [hours = "0", minutes = "0"] = value.split(":"); return Number(hours) * 60 + Number(minutes); } function canNotifyNow(startTime: string, endTime: string) { const now = new Date(); const current = now.getHours() * 60 + now.getMinutes(); return current >= minutesOfDay(startTime) && current <= minutesOfDay(endTime); } async function showReminder(kind: ReminderKind, message: string) { if (typeof window === "undefined" || !("Notification" in window)) return; if (Notification.permission !== "granted") return; const title = `Hellth Hub: ${labels[kind]}`; if ("serviceWorker" in navigator) { try { const registration = await navigator.serviceWorker.ready; await registration.showNotification(title, { body: message, tag: `hellth-${kind}`, badge: "/icon-192.png", }); return; } catch { // Fall through to regular notification. } } new Notification(title, { body: message, tag: `hellth-${kind}` }); } export function ReminderRunner() { const { data: session } = useSession(); const userKey = session?.user?.id ?? session?.user?.email ?? null; const lastSentRef = useRef>({}); useEffect(() => { if (!("serviceWorker" in navigator)) return; void navigator.serviceWorker.register("/hellth-sw.js").catch(() => undefined); }, []); useEffect(() => { if (!userKey) return; function tick() { const data = loadHellthData(userKey); const reminders = data.reminders; if (!reminders.enabled) return; if (typeof Notification === "undefined" || Notification.permission !== "granted") return; const now = Date.now(); (Object.keys(reminders.rules) as ReminderKind[]).forEach((kind) => { const rule = reminders.rules[kind]; if (!rule.enabled) return; if (!canNotifyNow(rule.startTime, rule.endTime)) return; const lastSentKey = `${userKey}:${kind}`; const lastSent = lastSentRef.current[lastSentKey] ?? 0; if (now - lastSent < rule.intervalMinutes * 60_000) return; lastSentRef.current[lastSentKey] = now; void showReminder(kind, rule.message); }); } tick(); const interval = window.setInterval(tick, 60_000); return () => window.clearInterval(interval); }, [userKey]); return null; }