Implement server-side push notifications with scheduler and always-remind option

This commit is contained in:
Gemini Agent
2026-01-25 03:14:04 +00:00
parent ad8b45ee1f
commit 90f54766a5
17 changed files with 2429 additions and 21 deletions

View File

@@ -0,0 +1,75 @@
"use client";
import { useEffect, useRef } from "react";
import { useServiceWorker } from "./ServiceWorkerProvider";
import { useAuth } from "./AuthProvider";
import { APP_NAME } from "@/lib/constants";
export function ReminderScheduler() {
const { showNotification } = useServiceWorker();
const { user } = useAuth();
const lastShownMinuteRef = useRef<number>(-1);
useEffect(() => {
if (!user) return;
let settings: { reminderEnabled: boolean; reminderTime: string } | null = null;
async function fetchSettings() {
try {
const res = await fetch("/api/settings");
if (res.ok) {
const data = await res.json();
settings = {
reminderEnabled: data.reminderEnabled,
reminderTime: data.reminderTime,
};
}
} catch {
// Ignore
}
}
async function checkReminder() {
if (!settings?.reminderEnabled || !settings?.reminderTime) return;
const now = new Date();
const [hours, minutes] = settings.reminderTime.split(":").map(Number);
const currentMinute = now.getHours() * 60 + now.getMinutes();
const targetMinute = hours * 60 + minutes;
if (currentMinute === targetMinute && currentMinute !== lastShownMinuteRef.current) {
lastShownMinuteRef.current = currentMinute;
if (Notification.permission === "granted") {
console.log("[Reminder] Showing notification at", now.toLocaleTimeString());
await showNotification(APP_NAME, {
body: "Take a moment to reflect on what you're grateful for today.",
icon: "/icons/icon-192.png",
tag: "daily-reminder",
});
}
}
}
// Initial fetch
fetchSettings();
// Refresh settings periodically (in case user changes them)
const settingsInterval = setInterval(fetchSettings, 60000);
// Check reminder every 30 seconds for more reliable timing
const reminderInterval = setInterval(checkReminder, 30000);
// Also check immediately after settings load
const initialCheck = setTimeout(checkReminder, 2000);
return () => {
clearInterval(settingsInterval);
clearInterval(reminderInterval);
clearTimeout(initialCheck);
};
}, [user, showNotification]);
return null;
}