"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { useSocket } from "@/components/socket-provider"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Separator } from "@/components/ui/separator"; import { Bell, CheckCheck, ArrowLeft } from "lucide-react"; import { useGetNotifications } from "@/features/notifications/api/use-get-notifications"; import { useMarkNotificationsRead } from "@/features/notifications/api/use-mark-notifications-read"; import { formatDistanceToNow } from "date-fns"; import { toast } from "sonner"; interface Notification { id: string; type: "MENTION" | "TASK_ASSIGNED" | "WORKSPACE_ADDED" | "COMMENT_REPLY"; title: string; message: string; isRead: boolean; createdAt: string; task?: { id: string; name: string; }; comment?: { id: string; content: string; }; workspace: { id: string; name: string; }; data?: any; } export default function NotificationsPage() { const router = useRouter(); const [selectedIds, setSelectedIds] = useState([]); const { socket } = useSocket(); const { data: notifications = [], refetch } = useGetNotifications({}); const { mutate: markAsRead, isPending } = useMarkNotificationsRead(); const unreadNotifications = notifications.filter((n: Notification) => !n.isRead); const readNotifications = notifications.filter((n: Notification) => n.isRead); // Listen for real-time notifications useEffect(() => { if (socket) { const handleNewNotification = () => { refetch(); }; socket.on("notification", handleNewNotification); return () => { socket.off("notification", handleNewNotification); }; } }, [socket, refetch]); const handleNotificationClick = (notification: Notification) => { // Mark as read if not already read if (!notification.isRead) { markAsRead( { json: { notificationIds: [notification.id] } }, { onSuccess: () => { refetch(); }, } ); } // Navigate to the relevant page if (notification.task) { if (notification.comment) { // Navigate to task and scroll to comment router.push(`/workspaces/${notification.workspace.id}/tasks/${notification.task.id}?comment=${notification.comment.id}`); } else { // Navigate to task router.push(`/workspaces/${notification.workspace.id}/tasks/${notification.task.id}`); } } else if (notification.type === "WORKSPACE_ADDED") { // Navigate to workspace router.push(`/workspaces/${notification.workspace.id}`); } }; const handleMarkAllAsRead = () => { const unreadIds = unreadNotifications.map((n: Notification) => n.id); if (unreadIds.length === 0) { toast.info("No unread notifications"); return; } markAsRead( { json: { notificationIds: unreadIds } }, { onSuccess: () => { refetch(); toast.success("All notifications marked as read"); }, } ); }; const getNotificationIcon = (type: string) => { switch (type) { case "MENTION": return "@"; case "TASK_ASSIGNED": return "📋"; case "COMMENT_REPLY": return "💬"; case "WORKSPACE_ADDED": return "🏢"; default: return "🔔"; } }; const getNotificationTypeColor = (type: string) => { switch (type) { case "MENTION": return "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300"; case "TASK_ASSIGNED": return "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300"; case "COMMENT_REPLY": return "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300"; case "WORKSPACE_ADDED": return "bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300"; default: return "bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300"; } }; const renderNotification = (notification: Notification) => ( handleNotificationClick(notification)} >
{getNotificationIcon(notification.type)}

{notification.title}

{!notification.isRead && (
)}

{notification.message}

{notification.type.replace("_", " ").toLowerCase()} {formatDistanceToNow(new Date(notification.createdAt), { addSuffix: true })}
); return (

All Notifications

{unreadNotifications.length > 0 && ( {unreadNotifications.length} )}
{unreadNotifications.length > 0 && ( )}
{unreadNotifications.length > 0 && (

Unread ({unreadNotifications.length})

{unreadNotifications.map(renderNotification)}
)} {unreadNotifications.length > 0 && readNotifications.length > 0 && ( )} {readNotifications.length > 0 && (

Read ({readNotifications.length})

{readNotifications.map(renderNotification)}
)} {notifications.length === 0 && (

No notifications yet

You'll see notifications here when you're mentioned, assigned tasks, or added to workspaces.

)}
); }