import type { Language } from "@/lib/i18n"; import type { Province } from "@/types/province"; interface VapidKeyResponse { configured: boolean; publicKey: string | null; } export async function fetchVapidPublicKey(signal?: AbortSignal) { const response = await fetch("/api/notifications/vapid-key", { signal }); if (!response.ok) throw new Error("Unable to load Web Push configuration."); return response.json() as Promise; } interface SavePushSubscriptionOptions { morningBriefEnabled?: boolean; latitude?: number | null; longitude?: number | null; locationName?: string | null; countyTeryt?: string | null; } export async function savePushSubscription(subscription: PushSubscription, province: Province, language: Language, options: SavePushSubscriptionOptions = {}) { const response = await fetch("/api/notifications/subscriptions", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ subscription: subscription.toJSON(), province, language, enabled: true, morningBriefEnabled: options.morningBriefEnabled === true, latitude: options.latitude ?? null, longitude: options.longitude ?? null, locationName: options.locationName ?? null, countyTeryt: options.countyTeryt ?? null, }), }); if (!response.ok) throw new Error("Unable to save push subscription."); } export async function deletePushSubscription(endpoint: string) { const response = await fetch("/api/notifications/subscriptions", { method: "DELETE", headers: { "content-type": "application/json" }, body: JSON.stringify({ endpoint }), }); if (!response.ok) throw new Error("Unable to delete push subscription."); } export async function sendTestPushNotification(endpoint: string) { const response = await fetch("/api/notifications/test", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ endpoint }), }); if (!response.ok) throw new Error("Unable to send test notification."); } export function decodeBase64UrlKey(value: string) { const padding = "=".repeat((4 - (value.length % 4)) % 4); const base64 = `${value}${padding}`.replace(/-/g, "+").replace(/_/g, "/"); const raw = window.atob(base64); return Uint8Array.from(raw, (character) => character.charCodeAt(0)); }