import { useState, useEffect } from "react"; import { Check, Download, Info } from "lucide-react"; import { LuFileSpreadsheet } from "react-icons/lu"; import { io } from "socket.io-client"; import * as NotificationService from "../../services/NotificationService"; import type { UINotification, BackendNotification } from "../../types/notification.types"; const getCookieToken = () => { return document.cookie .split("; ") .find((row) => row.startsWith("token=")) ?.split("=")[1]; }; export default function NotificationList() { const [notifications, setNotifications] = useState([]); useEffect(() => { const loadNotifications = async () => { try { const data = await NotificationService.getNotifications(); const mapped = data.map(NotificationService.mapNotificationToUI); setNotifications(mapped); } catch (err) { console.error("Failed to load notifications:", err); } }; loadNotifications(); const token = getCookieToken(); if (!token) return; const socketUrl = import.meta.env.VITE_API_BASE_URL || "http://localhost:9000"; const socket = io(socketUrl, { auth: { token }, transports: ["websocket"] }); socket.on("connect", () => { console.log("WebSocket connected for notifications"); }); socket.on("notification", (notif: BackendNotification) => { console.log("New realtime notification received:", notif); const mapped = NotificationService.mapNotificationToUI(notif); setNotifications(prev => { if (prev.some(p => p.id === mapped.id)) { return prev; } return [mapped, ...prev]; }); }); socket.on("disconnect", () => { console.log("WebSocket disconnected for notifications"); }); return () => { socket.disconnect(); }; }, []); // eslint-disable-next-line @typescript-eslint/no-unused-vars const handleMarkAllRead = async () => { try { await NotificationService.markAllAsRead(); setNotifications(prev => prev.map(n => ({ ...n, isNew: false }))); alert("All notifications marked as read!"); } catch (err) { console.error("Failed to mark all as read:", err); } }; return (
{/* Header */}

Notifications

Keep track of your interns' progress and system updates.

{notifications.length === 0 && (

Belum ada notifikasi.

)}
{/* Render Group TODAY */}
{notifications.filter(n => n.group === "TODAY").map((item) => (
{/* Icon Container */}
{item.type === 'new-task' && } {item.type === 'achievement' && }
{/* Content text */}
{item.isNew && ( NEW )}

{item.title}

{/* Custom description coloring logic */}

{item.description}

{/* Conditional Actions */} {item.type === 'new-task' && (
)} {item.type === 'achievement' && ( )}
{/* Time */} {item.time}
))}
{/* Header Section YESTERDAY */}

YESTERDAY

{notifications.filter(n => n.group === "YESTERDAY").map((item) => (

{item.title}

{item.description}

{item.time}
))}
); }