"use client"; import { useEffect, useState } from "react"; import { Bell, BellOff, X } from "lucide-react"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Notification } from "@/app/api/notifications/route"; export default function PushNotificationManager() { const [notifications, setNotifications] = useState([]); const [permission, setPermission] = useState("default"); const [loading, setLoading] = useState(true); useEffect(() => { if (typeof window !== "undefined" && "Notification" in window && window.Notification) { setPermission(window.Notification.permission); } fetchNotifications(); }, []); const fetchNotifications = async () => { try { const response = await fetch("/api/notifications"); const data = await response.json(); setNotifications(data); } catch (error) { console.error("Erreur lors du chargement des notifications:", error); } finally { setLoading(false); } }; const requestPermission = async () => { if (typeof window === "undefined" || !("Notification" in window) || !window.Notification) { alert("Votre navigateur ne supporte pas les notifications"); return; } const permission = await window.Notification.requestPermission(); setPermission(permission); if (permission === "granted") { // Enregistrer le service worker pour les notifications push if ("serviceWorker" in navigator) { try { const registration = await navigator.serviceWorker.ready; // Vérifier périodiquement les nouvelles notifications setInterval(async () => { try { const response = await fetch("/api/notifications"); const newNotifications = await response.json(); const unread = newNotifications.filter((n: Notification) => !n.read); // Afficher une notification pour chaque nouvelle alerte non lue if (typeof window !== "undefined" && window.Notification) { unread.forEach((notification: Notification) => { if (window.Notification.permission === "granted") { new window.Notification(notification.title, { body: notification.message, icon: "/icon-192x192.png", badge: "/icon-192x192.png", tag: notification.id, requireInteraction: notification.type === "whale", }); } }); } } catch (error) { console.error("Erreur lors de la vérification des notifications:", error); } }, 60000); // Vérifier toutes les minutes } catch (error) { console.error("Erreur lors de l'enregistrement du service worker:", error); } } } }; const showTestNotification = () => { if (permission === "granted" && typeof window !== "undefined" && window.Notification) { new window.Notification("Test de notification", { body: "Les notifications fonctionnent correctement !", icon: "/icon-192x192.png", badge: "/icon-192x192.png", }); } }; const markAsRead = async (id: string) => { try { await fetch("/api/notifications", { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id, read: true }), }); setNotifications( notifications.map((n) => (n.id === id ? { ...n, read: true } : n)) ); } catch (error) { console.error("Erreur lors de la mise à jour:", error); } }; const getNotificationIcon = (type: string) => { switch (type) { case "whale": return "🐋"; case "weather": return "🌦️"; case "excursion": return "🚤"; default: return "ℹ️"; } }; if (loading) { return (
Chargement...
); } const unreadCount = notifications.filter((n) => !n.read).length; return ( Notifications {unreadCount > 0 && ( {unreadCount} )} {permission === "default" && (

Activez les notifications pour recevoir des alertes importantes (baleines, météo, etc.)

)} {permission === "denied" && (

Les notifications sont désactivées. Veuillez les activer dans les paramètres de votre navigateur.

)} {permission === "granted" && (

Notifications activées

)}
{notifications.length === 0 ? (

Aucune notification pour le moment

) : ( notifications.map((notification) => (
{getNotificationIcon(notification.type)}

{notification.title}

{!notification.read && ( Nouveau )}

{notification.message}

{new Date(notification.timestamp).toLocaleString("fr-FR")}

{!notification.read && ( )}
)) )}
); }