'use client'; import { useState } from 'react'; import { NotificationManager, type NotificationRequest, WebPushManager } from '../utils/notifications'; interface LocationData { name: string; lat: number; lng: number; available: boolean; passType: string; } interface NotificationPanelProps { locations: LocationData[]; } export default function NotificationPanel({ locations }: { readonly locations: LocationData[] }) { const [notifications, setNotifications] = useState(() => NotificationManager.getNotifications() ); const [showAddForm, setShowAddForm] = useState(false); const [selectedLibrary, setSelectedLibrary] = useState(''); const [selectedPassTypes, setSelectedPassTypes] = useState([]); const [notificationPermission, setNotificationPermission] = useState( WebPushManager.isSupported() ? WebPushManager.getPermissionStatus() : 'denied' ); const handlePassTypeChange = (type: string, checked: boolean) => { if (checked) { setSelectedPassTypes(prev => [...prev, type]); } else { setSelectedPassTypes(prev => prev.filter(t => t !== type)); } }; const requestNotificationPermission = async () => { const granted = await WebPushManager.requestPermission(); setNotificationPermission(granted ? 'granted' : 'denied'); }; const handleAddNotification = () => { if (!selectedLibrary || selectedPassTypes.length === 0) return; const newNotification = NotificationManager.addNotification({ libraryName: selectedLibrary, passTypes: selectedPassTypes as ('Pass Only' | 'Backpack Only' | 'Both')[], }); setNotifications(prev => [...prev, newNotification]); setShowAddForm(false); setSelectedLibrary(''); setSelectedPassTypes([]); }; const handleRemoveNotification = (id: string) => { NotificationManager.removeNotification(id); setNotifications(prev => prev.filter(n => n.id !== id)); }; const checkNotifications = async () => { const availableNow = notifications.filter(notification => { const library = locations.find(loc => loc.name === notification.libraryName); return library && library.available && ( notification.passTypes.includes('Both') || notification.passTypes.some(type => library.passType.includes(type.replace(' Only', ''))) ); }); if (availableNow.length > 0) { const message = availableNow.map(n => `${n.libraryName} has passes available!`).join('\n'); // Try web notification first if (notificationPermission === 'granted') { for (const notification of availableNow) { await WebPushManager.showNotification( '🎉 Beach Pass Available!', `${notification.libraryName} has ${notification.passTypes.join(' and ')} available!`, { tag: `park-pass-${notification.id}`, requireInteraction: true, } ); } } // Also show alert for immediate feedback alert(`🎉 Great news!\n\n${message}`); // Update last checked for all notifications notifications.forEach(n => NotificationManager.updateLastChecked(n.id)); } else { alert('No passes currently available for your requested libraries.'); } }; return (

🔔 Notifications ({notifications.length})

{/* Notification Permission Status */} {WebPushManager.isSupported() && (
Push Notifications: {notificationPermission === 'granted' ? '✅ Enabled' : '❌ Disabled'}
{notificationPermission !== 'granted' && (
Enable push notifications to get alerts when passes become available.
)}
)} {showAddForm && (
Library:
Pass Types:
{['Pass Only', 'Backpack Only', 'Both'].map(type => (
handlePassTypeChange(type, e.target.checked)} style={{ marginRight: '6px' }} id={`passtype-${type}`} />
))}
)} {notifications.length > 0 && ( <>
{notifications.map(notification => (
{notification.libraryName}
{notification.passTypes.join(', ')}
))}
)}
); }