mirror of
https://github.com/Tony0410/quietthanks.git
synced 2026-05-25 05:41:38 +08:00
Implement server-side push notifications with scheduler and always-remind option
This commit is contained in:
@@ -11,6 +11,7 @@ import Link from "next/link";
|
||||
interface UserSettings {
|
||||
reminderEnabled: boolean;
|
||||
reminderTime: string;
|
||||
reminderAlways: boolean;
|
||||
llmProvider: string | null;
|
||||
hasLlmKey: boolean;
|
||||
llmModel: string | null;
|
||||
@@ -30,7 +31,7 @@ const PROVIDERS = [
|
||||
|
||||
export default function SettingsPage() {
|
||||
const { user, logout } = useAuth();
|
||||
const { isSupported: swSupported, isRegistered: swRegistered, showNotification } = useServiceWorker();
|
||||
const { isSupported: swSupported, isRegistered: swRegistered, showNotification, subscribeToPush } = useServiceWorker();
|
||||
const [settings, setSettings] = useState<UserSettings | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
@@ -78,6 +79,13 @@ export default function SettingsPage() {
|
||||
setIsPWA(isStandalone);
|
||||
}, []);
|
||||
|
||||
// Ensure push subscription is active if permissions are granted
|
||||
useEffect(() => {
|
||||
if (notificationPermission === "granted" && swRegistered) {
|
||||
subscribeToPush().catch(console.error);
|
||||
}
|
||||
}, [notificationPermission, swRegistered, subscribeToPush]);
|
||||
|
||||
const updateSetting = async (key: string, value: unknown) => {
|
||||
setIsSaving(true);
|
||||
try {
|
||||
@@ -102,6 +110,14 @@ export default function SettingsPage() {
|
||||
setNotificationPermission(permission);
|
||||
if (permission === "granted") {
|
||||
updateSetting("reminderEnabled", true);
|
||||
const subscribed = await subscribeToPush();
|
||||
if (subscribed) {
|
||||
showNotification(APP_NAME, {
|
||||
body: "Notifications enabled! You will receive daily reminders.",
|
||||
icon: "/icons/icon.svg",
|
||||
tag: "welcome-notification",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -308,14 +324,28 @@ export default function SettingsPage() {
|
||||
</button>
|
||||
</div>
|
||||
{settings.reminderEnabled && (
|
||||
<div className="mt-4 flex items-center gap-3">
|
||||
<label className="text-sm text-muted">Remind me at:</label>
|
||||
<input
|
||||
type="time"
|
||||
value={settings.reminderTime}
|
||||
onChange={(e) => updateSetting("reminderTime", e.target.value)}
|
||||
className="px-3 py-1 bg-background border border-border rounded-lg text-sm focus:outline-none focus:border-muted"
|
||||
/>
|
||||
<div className="mt-4 space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<label className="text-sm text-muted">Remind me at:</label>
|
||||
<input
|
||||
type="time"
|
||||
value={settings.reminderTime}
|
||||
onChange={(e) => updateSetting("reminderTime", e.target.value)}
|
||||
className="px-3 py-1 bg-background border border-border rounded-lg text-sm focus:outline-none focus:border-muted"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="reminderAlways"
|
||||
checked={settings.reminderAlways}
|
||||
onChange={(e) => updateSetting("reminderAlways", e.target.checked)}
|
||||
className="w-4 h-4 rounded border-border text-accent focus:ring-accent"
|
||||
/>
|
||||
<label htmlFor="reminderAlways" className="text-sm text-muted cursor-pointer">
|
||||
Always remind me, even if I've already journaled today
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{settings.reminderEnabled && notificationPermission === "granted" && swRegistered && (
|
||||
|
||||
Reference in New Issue
Block a user