import React, { useEffect, useState } from 'react'; import common from '../src/helpers/common'; // Ensure this path is correct //use session to get user role import { useSession } from "next-auth/react" function PwaManager() { const [deferredPrompt, setDeferredPrompt] = useState(null); const [isPWAInstalled, setIsPWAInstalled] = useState(false); const [isStandAlone, setIsStandAlone] = useState(false); const [isSubscribed, setIsSubscribed] = useState(false); const [subscription, setSubscription] = useState(null); const [registration, setRegistration] = useState(null); const [notificationPermission, setNotificationPermission] = useState(Notification.permission); const { data: session } = useSession(); // Handle PWA installation useEffect(() => { setNotificationPermission(Notification.permission); // Handle Push Notification Subscription if ('serviceWorker' in navigator && 'PushManager' in window) { navigator.serviceWorker.ready.then(reg => { reg.pushManager.getSubscription().then(sub => { if (sub) { setSubscription(sub); setIsSubscribed(true); } }); setRegistration(reg); }); } // Check if the app is running in standalone mode if (window.matchMedia('(display-mode: standalone)').matches) { setIsStandAlone(true); } const handleBeforeInstallPrompt = (e) => { e.preventDefault(); setDeferredPrompt(e); }; const handleAppInstalled = () => { setIsPWAInstalled(true); }; window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt); window.addEventListener('appinstalled', handleAppInstalled); return () => { window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt); window.removeEventListener('appinstalled', handleAppInstalled); }; }, []); const installPWA = async (e) => { console.log('installing PWA'); e.preventDefault(); if (deferredPrompt) { deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; if (outcome === 'accepted') { setIsPWAInstalled(true); } setDeferredPrompt(null); } }; // Utility function for converting base64 string to Uint8Array const base64ToUint8Array = base64 => { const padding = '='.repeat((4 - (base64.length % 4)) % 4); const b64 = (base64 + padding).replace(/-/g, '+').replace(/_/g, '/'); const rawData = window.atob(b64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; }; const subscribeToNotifications = async (e) => { try { e.preventDefault(); if (!navigator.serviceWorker) { console.error('Service worker is not supported by this browser.'); return; } const registration = await navigator.serviceWorker.ready; if (!registration) { console.error('Service worker registration not found.'); return; } let vapidPublicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY; if (!vapidPublicKey) { // Fetch the public key from the server if not present in env variables const response = await fetch('/api/notify', { method: 'GET' }); vapidPublicKey = await response.text(); if (!vapidPublicKey) { throw new Error("Failed to fetch VAPID public key from server."); } } const sub = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: base64ToUint8Array(vapidPublicKey) }); // Call your API to save subscription data on server if (session.user?.id != null) { await fetch(`/api/notify`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ subscription: sub, id: session.user.id }) }).then(response => { if (!response.ok) { throw new Error('Failed to save subscription data on server.'); } else { console.log('Subscription data saved on server.'); setSubscription(sub); setIsSubscribed(true); console.log('Web push subscribed!'); } }); } console.log(sub); } catch (error) { console.error('Error subscribing to notifications:', error); } }; const unsubscribeFromNotifications = async (e) => { try { e.preventDefault(); await subscription.unsubscribe(); // Call your API to delete or invalidate subscription data on server setSubscription(null); setIsSubscribed(false); if (session?.user?.id != null) { await fetch(`/api/notify`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: session?.user.id }), } ).then(response => { if (!response.ok) { throw new Error('Failed to delete subscription data on server.'); } else { console.log('Subscription data deleted on server.'); } }); } console.log('Web push unsubscribed!'); } catch (error) { console.error('Error unsubscribing from notifications:', error); } }; // Function to request push notification permission const requestNotificationPermission = async (e) => { e.preventDefault(); const permission = await Notification.requestPermission(); setNotificationPermission(permission); if (permission === "granted") { // User granted permission subscribeToNotifications(null); // Pass the required argument here } else { // User denied or dismissed permission console.log("Push notifications permission denied."); } }; // Function to toggle push notifications const togglePushNotifications = async (e) => { e.preventDefault(); if (notificationPermission === "granted") { // If already subscribed, unsubscribe unsubscribeFromNotifications(null); // Pass null as the argument } else if (notificationPermission === "default" || notificationPermission === "denied") { // Request permission if not already granted await requestNotificationPermission(e); } }; const sendTestNotification = async (e) => { e.preventDefault(); if (!subscription) { console.error('Web push not subscribed'); return; } await fetch('/api/notify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ subscription }) }); }; return ( <>

PWA Manager

{!isStandAlone && !isPWAInstalled && ( )} {isPWAInstalled &&

App is installed!

} {isStandAlone &&

PWA App

}
{notificationPermission !== "granted" && ( )}
Телеграм Телеграм
Apple sign-in
); } export default PwaManager;