import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useNavigate } from "react-router-dom"; import { Loader2, CheckCheck, FlaskConical, AlertTriangle, CheckCircle, XCircle, Bell, } from "lucide-react"; import { getNotifications, markAsRead, markAllAsRead, type NotificationItem, } from "../api/notifications"; const typeIcons: Record = { test_assigned: , validation_needed: , test_rejected: , test_validated: , test_state_changed: , }; export default function NotificationDropdown({ onClose }: { onClose: () => void }) { const navigate = useNavigate(); const queryClient = useQueryClient(); const { data: notifications, isLoading } = useQuery({ queryKey: ["notifications", "list"], queryFn: () => getNotifications(0, 20), }); const markReadMutation = useMutation({ mutationFn: markAsRead, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["notifications"] }); }, }); const markAllMutation = useMutation({ mutationFn: markAllAsRead, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["notifications"] }); }, }); const handleClick = (notif: NotificationItem) => { if (!notif.read) { markReadMutation.mutate(notif.id); } if (notif.entity_type === "test" && notif.entity_id) { navigate(`/tests/${notif.entity_id}`); } else if (notif.entity_type === "technique" && notif.entity_id) { navigate(`/techniques/${notif.entity_id}`); } onClose(); }; const formatTime = (dateStr: string | null) => { if (!dateStr) return ""; const d = new Date(dateStr); const now = new Date(); const diffMs = now.getTime() - d.getTime(); const diffMin = Math.floor(diffMs / 60000); if (diffMin < 1) return "just now"; if (diffMin < 60) return `${diffMin}m ago`; const diffH = Math.floor(diffMin / 60); if (diffH < 24) return `${diffH}h ago`; const diffD = Math.floor(diffH / 24); return `${diffD}d ago`; }; return (
{/* Header */}

Notifications

{/* List */}
{isLoading ? (
) : notifications && notifications.length > 0 ? ( notifications.map((notif) => ( )) ) : (
No notifications yet
)}
); }