"use client"; import { useEffect, useState } from "react"; import { LogoutButton } from "@/components/logout-button"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { clearDailyReminderSentToday, deliverTestDailyReminder, getNotificationPermissionLabel, getNotificationPermissionState, isNotificationSupported, requestNotificationPermission, } from "@/lib/daily-reminders"; import { getDailyReminderStatus } from "@/lib/daily-reminder-status"; import { getTodayDateKey } from "@/lib/habits-storage"; import { reminderDeliveryOptions, usesInAppReminders, usesSystemReminders, type ReminderDeliveryMethod, } from "@/lib/reminder-delivery"; import { avatarVibeOptions, defaultProfilePreferences, focusTopicOptions, getProfilePreferences, saveProfilePreferences, type ProfilePreferences, } from "@/lib/profile-preferences-storage"; type ProfilePreferencesFormProps = { email?: string | null; }; export function ProfilePreferencesForm({ email }: ProfilePreferencesFormProps) { const [preferences, setPreferences] = useState( defaultProfilePreferences, ); const [isReady, setIsReady] = useState(false); const [error, setError] = useState(null); const [isSaving, setIsSaving] = useState(false); const [notificationPermission, setNotificationPermission] = useState( getNotificationPermissionState(), ); const [notificationMessage, setNotificationMessage] = useState( null, ); useEffect(() => { setNotificationPermission(getNotificationPermissionState()); }, []); useEffect(() => { async function loadPreferences() { try { setPreferences(await getProfilePreferences()); } catch (loadError) { setError( loadError instanceof Error ? loadError.message : "Could not load profile preferences.", ); } finally { setIsReady(true); } } void loadPreferences(); }, []); const updatePreferences = async (updates: Partial) => { const nextPreferences = { ...preferences, ...updates }; setPreferences(nextPreferences); setIsSaving(true); setError(null); try { const savedPreferences = await saveProfilePreferences(nextPreferences); setPreferences(savedPreferences); if ( "dailyReminderEnabled" in updates || "dailyReminderTime" in updates || "dailyReminderDelivery" in updates ) { clearDailyReminderSentToday(getTodayDateKey()); } } catch (saveError) { setPreferences(preferences); setError( saveError instanceof Error ? saveError.message : "Could not save profile preferences.", ); } finally { setIsSaving(false); } }; const ensureSystemReminderPermission = async ( deliveryMethod: ReminderDeliveryMethod, ) => { if (!usesSystemReminders(deliveryMethod)) { return true; } if (!isNotificationSupported()) { setError("This browser does not support browser (OS) notifications."); return false; } const permission = await requestNotificationPermission(); setNotificationPermission(permission); if (permission !== "granted") { setError( permission === "denied" ? "Browser notifications are blocked. Enable them in your browser settings or choose In-app delivery." : "Browser notification permission was not granted.", ); return false; } return true; }; const handleDailyReminderToggle = async (checked: boolean) => { if (checked) { const allowed = await ensureSystemReminderPermission( preferences.dailyReminderDelivery, ); if (!allowed) { return; } } setError(null); await updatePreferences({ dailyReminderEnabled: checked }); }; const handleDeliveryMethodChange = async ( deliveryMethod: ReminderDeliveryMethod, ) => { if ( preferences.dailyReminderEnabled && usesSystemReminders(deliveryMethod) ) { const allowed = await ensureSystemReminderPermission(deliveryMethod); if (!allowed) { return; } } setError(null); await updatePreferences({ dailyReminderDelivery: deliveryMethod }); }; const handleTestNotification = async () => { setNotificationMessage(null); setError(null); const deliveryMethod = preferences.dailyReminderDelivery; if (usesSystemReminders(deliveryMethod)) { const allowed = await ensureSystemReminderPermission(deliveryMethod); if (!allowed) { return; } } const status = await getDailyReminderStatus(); const shown = deliverTestDailyReminder(status, deliveryMethod); if (!shown) { setError("Could not show a test reminder."); return; } if (deliveryMethod === "in_app") { setNotificationMessage( "In-app test reminder sent. Look for the banner above the bottom navigation.", ); return; } if (deliveryMethod === "system") { setNotificationMessage( "Browser test notification sent. Check your browser or OS notification center.", ); return; } setNotificationMessage( "Test reminder sent in-app and through your browser notification center.", ); }; if (!isReady) { return (

Loading profile...

); } return (
{error ?

{error}

: null} Profile information Your account details.
Focus topic preference Choose the one area you want your pet and daily tasks to focus on. {focusTopicOptions.map((topic) => ( ))} Avatar preferences Personalize your pet's vibe. {avatarVibeOptions.map((vibe) => ( ))} Notification preferences Control reminders for your daily quiz and habits.
void handleDailyReminderToggle(checked === true) } />
{reminderDeliveryOptions.map((option) => ( ))}
{usesSystemReminders(preferences.dailyReminderDelivery) ? (
Browser permission {getNotificationPermissionLabel(notificationPermission)}
) : null}
void updatePreferences({ dailyReminderTime: event.target.value }) } />

In-app reminders appear inside Habit Pet while a tab is open. Browser (OS) reminders use the Web Notifications API and may appear in your system notification center. Reminders fire once per day at your chosen local time.

{notificationMessage ? (

{notificationMessage}

) : null}
Account settings Session and onboarding status.
Onboarding Complete
); }