diff --git a/components/notifications/push-toggle.tsx b/components/notifications/push-toggle.tsx new file mode 100644 index 0000000..0351335 --- /dev/null +++ b/components/notifications/push-toggle.tsx @@ -0,0 +1,116 @@ +'use client' + +import { useEffect, useState } from 'react' +import { toast } from 'sonner' +import { Button } from '@/components/ui/button' +import { + isPushSupported, + isIOSSafari, + isStandalonePWA, + subscribeToPush, + unsubscribeFromPush, +} from '@/lib/push-client' + +type PushStatus = + | 'loading' + | 'unsupported' + | 'ios-needs-install' + | 'denied' + | 'subscribed' + | 'unsubscribed' + +interface PushToggleProps { + vapidPublicKey?: string +} + +export function PushToggle({ vapidPublicKey }: PushToggleProps) { + const [status, setStatus] = useState('loading') + + useEffect(() => { + async function detectStatus() { + if (!isPushSupported()) { + if (isIOSSafari() && !isStandalonePWA()) { + setStatus('ios-needs-install') + } else { + setStatus('unsupported') + } + return + } + + if (Notification.permission === 'denied') { + setStatus('denied') + return + } + + try { + const reg = await navigator.serviceWorker.getRegistration() + const sub = await reg?.pushManager.getSubscription() + setStatus(sub ? 'subscribed' : 'unsubscribed') + } catch { + setStatus('unsubscribed') + } + } + + detectStatus() + }, []) + + async function handleSubscribe() { + if (!vapidPublicKey) { + toast.error('Push niet beschikbaar — VAPID-sleutel ontbreekt') + return + } + try { + await subscribeToPush(vapidPublicKey) + setStatus('subscribed') + toast.success('Push-notificaties geactiveerd') + } catch { + if (Notification.permission === 'denied') { + setStatus('denied') + } + toast.error('Kon push niet activeren. Controleer je browserinstellingen.') + } + } + + async function handleUnsubscribe() { + try { + await unsubscribeFromPush() + setStatus('unsubscribed') + toast.success('Push-notificaties uitgeschakeld') + } catch { + toast.error('Kon push niet uitschakelen') + } + } + + if (status === 'loading' || status === 'unsupported') return null + + if (status === 'ios-needs-install') { + return ( +
+ Op iPhone/iPad: tik op het delen-icoon en kies{' '} + Zet op beginscherm. Daarna kun je notificaties activeren. +
+ ) + } + + if (status === 'denied') { + return ( +

+ Notificaties zijn geblokkeerd. Schakel ze in via je browser-instellingen. +

+ ) + } + + if (status === 'unsubscribed') { + return ( + + ) + } + + return ( + + ) +}