Fix duplicate notifications and improve push titles

This commit is contained in:
Avery Felts 2026-01-27 17:43:34 -07:00
parent c438e4f552
commit 39c8e92f92
2 changed files with 4 additions and 80 deletions

View File

@ -78,8 +78,9 @@ export async function GET(request: NextRequest) {
}
if (shouldSend) {
const title = user.frequency === 'hourly' ? 'QuitTraq Hourly Check-in' : 'QuitTraq Reminder';
const payload = JSON.stringify({
title: 'QuitTraq',
title: title,
body: notificationBody,
tag: tag,
url: '/'

View File

@ -170,89 +170,12 @@ export function useNotifications(reminderSettings: ReminderSettings) {
// Track previous settings to detect changes
const [prevSettings, setPrevSettings] = useState(reminderSettings);
// Check and send reminder
const checkAndSendReminder = useCallback(() => {
if (!reminderSettings.enabled || permission !== 'granted') return;
const now = new Date();
// 'en-CA' outputs YYYY-MM-DD in local timezone
const today = now.toLocaleDateString('en-CA');
if (reminderSettings.frequency === 'hourly') {
const LAST_HOURLY_KEY = 'quittraq_last_hourly_notification';
const lastNotifiedHour = localStorage.getItem(LAST_HOURLY_KEY);
const currentHourKey = `${today}-${now.getHours()}`;
if (lastNotifiedHour === currentHourKey) return; // Already notified this hour
// Check active hours
const startParts = (reminderSettings.hourlyStart || '09:00').split(':').map(Number);
const endParts = (reminderSettings.hourlyEnd || '21:00').split(':').map(Number);
const startMinutes = startParts[0] * 60 + startParts[1];
const endMinutes = endParts[0] * 60 + endParts[1];
const currentMinutes = now.getHours() * 60 + now.getMinutes();
if (currentMinutes >= startMinutes && currentMinutes <= endMinutes) {
playNotificationSound();
sendNotification('QuitTraq Hourly Check-in', {
body: "How are you doing? Log your status to stay on track!",
tag: 'hourly-reminder',
requireInteraction: true,
});
localStorage.setItem(LAST_HOURLY_KEY, currentHourKey);
}
} else {
// Daily logic
const lastNotified = localStorage.getItem(LAST_NOTIFICATION_KEY);
if (lastNotified === today) return; // Already notified today
const [hours, minutes] = reminderSettings.reminderTime.split(':').map(Number);
const reminderTime = new Date();
reminderTime.setHours(hours, minutes, 0, 0);
// If current time is past the reminder time, send it
if (now >= reminderTime) {
playNotificationSound();
sendNotification('QuitTraq Reminder', {
body: "Time to log your daily usage! Every day counts on your journey.",
tag: 'daily-reminder', // Tag ensures we don't stack multiple notifications
requireInteraction: true, // Keep it visible until user interacts
});
localStorage.setItem(LAST_NOTIFICATION_KEY, today);
}
}
}, [reminderSettings, permission, sendNotification, playNotificationSound]);
// If settings change, we might need to reset notification history to allow "update and resend"
// This effect MUST be after checkAndSendReminder is defined so we can call it immediately
// If settings change, we record it
useEffect(() => {
if (JSON.stringify(prevSettings) !== JSON.stringify(reminderSettings)) {
// Only reset if time changed significantly or if toggled.
// We can simply clear the 'last notified' date if the reminderTime changed.
if (prevSettings.reminderTime !== reminderSettings.reminderTime && reminderSettings.frequency === 'daily') {
localStorage.removeItem(LAST_NOTIFICATION_KEY);
// Force immediate check
checkAndSendReminder();
}
setPrevSettings(reminderSettings);
}
}, [reminderSettings, prevSettings, checkAndSendReminder]);
// Set up interval to check for reminder time
useEffect(() => {
if (!reminderSettings.enabled || permission !== 'granted') return;
// Check immediately
checkAndSendReminder();
// Check every minute
const interval = setInterval(checkAndSendReminder, 60000);
return () => clearInterval(interval);
}, [reminderSettings, permission, checkAndSendReminder]);
}, [reminderSettings, prevSettings]);
return {
isSupported,