"use client"; import { useState, useEffect } from "react"; import { Bell, Check, CheckCheck } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { formatRelativeDate } from "@/lib/utils"; import { cn } from "@/lib/utils"; import Link from "next/link"; interface Notification { id: string; type: string; title: string; message: string; data: Record | null; isRead: boolean; createdAt: string; } export function NotificationBell() { const [notifications, setNotifications] = useState([]); const [isLoading, setIsLoading] = useState(false); const unreadCount = notifications.filter((n) => !n.isRead).length; const fetchNotifications = async () => { setIsLoading(true); try { const res = await fetch("/api/notifications"); if (res.ok) { const data = await res.json(); setNotifications(data.notifications ?? []); } } catch { // silent } finally { setIsLoading(false); } }; const markAllRead = async () => { try { await fetch("/api/notifications", { method: "PATCH" }); setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true }))); } catch { // silent } }; const getNotificationHref = (n: Notification): string | null => { const data = n.data as Record | null; if (data?.versionId) return `/review/${data.versionId}`; return null; }; const getNotificationIcon = (type: string): string => { const icons: Record = { VERSION_UPLOADED: "đŸŽŦ", FEEDBACK_ADDED: "đŸ’Ŧ", SHOT_APPROVED: "✅", SHOT_REJECTED: "❌", COMMENT_REPLY: "â†Šī¸", REVISION_REQUESTED: "âš ī¸", }; return icons[type] ?? "🔔"; }; return ( open && fetchNotifications()}>
Notifications {unreadCount > 0 && ( )}
{isLoading ? (
) : notifications.length === 0 ? (

No notifications

) : (
{notifications.map((n) => { const href = getNotificationHref(n); const content = ( <> {getNotificationIcon(n.type)}

{n.message}

{formatRelativeDate(new Date(n.createdAt))}

{!n.isRead && (
)} ); const className = cn( "flex gap-3 px-4 py-3 hover:bg-secondary/50 transition-colors cursor-pointer border-b border-border/50 last:border-0", !n.isRead && "bg-primary/5" ); if (href) { return ( {content} ); } return (
{content}
); })}
)} ); }