Download apps/admin/src/lib/notifications.ts from safetrack/edtech: direct link, hf CLI and curl.
- Browser
- Download file 2.53 kB
-
https://huggingface.co/spaces/safetrack/edtech/resolve/main/apps/admin/src/lib/notifications.ts
- Command line
-
hf download hf://spaces/safetrack/edtech/apps/admin/src/lib/notifications.ts
-
curl -L -o notifications.ts https://huggingface.co/spaces/safetrack/edtech/resolve/main/apps/admin/src/lib/notifications.ts
2.53 kB
| /** | |
| * Push Notification Helper | |
| */ | |
| import { logError, logWarn } from './logger'; | |
| function urlBase64ToUint8Array(base64String: string) { | |
| const padding = '='.repeat((4 - (base64String.length % 4)) % 4); | |
| const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); | |
| const rawData = window.atob(base64); | |
| const outputArray = new Uint8Array(rawData.length); | |
| for (let i = 0; i < rawData.length; ++i) { | |
| outputArray[i] = rawData.charCodeAt(i); | |
| } | |
| return outputArray; | |
| } | |
| export const setupNotifications = async (token: string, orgId: string) => { | |
| if (!('serviceWorker' in navigator) || !('PushManager' in window)) { | |
| logWarn('Push notifications are not supported in this browser.'); | |
| return; | |
| } | |
| try { | |
| // 1. Check existing permission — ne pas re-demander si déjà refusé | |
| if (Notification.permission === 'denied') { | |
| return; // silencieux : l'utilisateur a déjà dit non | |
| } | |
| // 2. Register Service Worker | |
| const registration = await navigator.serviceWorker.register('/sw.js'); | |
| // 3. Request Permission (seulement si 'default', pas 'denied') | |
| const permission = Notification.permission === 'granted' | |
| ? 'granted' | |
| : await Notification.requestPermission(); | |
| if (permission !== 'granted') { | |
| return; // silencieux | |
| } | |
| // 3. Get VAPID public key from server | |
| const keyRes = await fetch(`${import.meta.env.VITE_API_URL}/v1/notifications/vapid-key`, { | |
| headers: { 'Authorization': `Bearer ${token}`, 'x-organization-id': orgId } | |
| }); | |
| const { publicKey } = await keyRes.json(); | |
| if (!publicKey) { | |
| logWarn('VAPID public key missing from server'); | |
| return; | |
| } | |
| // 4. Subscribe to Push | |
| const subscription = await registration.pushManager.subscribe({ | |
| userVisibleOnly: true, | |
| applicationServerKey: urlBase64ToUint8Array(publicKey) | |
| }); | |
| // 5. Send subscription to server | |
| await fetch(`${import.meta.env.VITE_API_URL}/v1/notifications/subscribe`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${token}`, | |
| 'x-organization-id': orgId | |
| }, | |
| body: JSON.stringify({ subscription }) | |
| }); | |
| } catch (err) { | |
| logError('Failed to setup push notifications', err); | |
| } | |
| }; | |