"use client"; import { useState, useEffect } from 'react'; import { Bell, BellOff, Send } from 'lucide-react'; import { urlBase64ToUint8Array } from '../utils/webPush'; export default function PushSubscription() { const [isSubscribed, setIsSubscribed] = useState(false); const [subscription, setSubscription] = useState(null); const [registration, setRegistration] = useState(null); const [isMenuOpen, setIsMenuOpen] = useState(false); useEffect(() => { if (typeof window !== 'undefined' && 'serviceWorker' in navigator && 'PushManager' in window) { // Register SW if not already (though it might be done in layout or separate file) navigator.serviceWorker.ready.then(reg => { setRegistration(reg); reg.pushManager.getSubscription().then(sub => { if (sub) { setSubscription(sub); setIsSubscribed(true); } }); }); } }, []); const subscribeUser = async () => { if (!registration) return; try { const response = await fetch('/api/push/vapid-public-key'); const { publicKey } = await response.json(); const convertedVapidKey = urlBase64ToUint8Array(publicKey); const sub = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: convertedVapidKey }); await fetch('/api/push/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(sub), }); setSubscription(sub); setIsSubscribed(true); alert('订阅成功!'); } catch (error) { console.error('Failed to subscribe the user: ', error); alert('订阅失败,请检查控制台日志。'); } }; const unsubscribeUser = async () => { if (!subscription) return; try { await subscription.unsubscribe(); // Optionally notify backend to remove subscription setSubscription(null); setIsSubscribed(false); alert('已取消订阅。'); } catch (error) { console.error('Error unsubscribing', error); } }; const sendTestPush = async () => { try { const res = await fetch('/api/push/test', { method: 'POST' }); if (!res.ok) throw new Error('Failed to send test push'); alert('测试推送已发送,请检查通知!'); } catch (error) { console.error('Failed to send test push', error); alert('发送测试推送失败'); } }; if (!registration) { return null; // Service Worker not ready or not supported } if (!isSubscribed) { return ( ); } return (
{isMenuOpen && ( <>
setIsMenuOpen(false)} />
)}
); }