From 3b187d076f39621b51a80fdec18585de86ffe18a Mon Sep 17 00:00:00 2001
From: ameer2468 <33054370+ameer2468@users.noreply.github.com>
Date: Fri, 8 Aug 2025 17:55:10 +0300
Subject: [PATCH] mark as read on click

---
 .../actions/notifications/mark-all-as-read.ts | 26 --------------
 .../web/actions/notifications/mark-as-read.ts | 34 +++++++++++++++++++
 .../Notifications/NotificationHeader.tsx      |  8 ++---
 .../Notifications/NotificationItem.tsx        | 10 ++++++
 4 files changed, 48 insertions(+), 30 deletions(-)
 delete mode 100644 apps/web/actions/notifications/mark-all-as-read.ts
 create mode 100644 apps/web/actions/notifications/mark-as-read.ts

diff --git a/apps/web/actions/notifications/mark-all-as-read.ts b/apps/web/actions/notifications/mark-all-as-read.ts
deleted file mode 100644
index 318d44e30d..0000000000
--- a/apps/web/actions/notifications/mark-all-as-read.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-"use server";
-
-import { getCurrentUser } from "@cap/database/auth/session";
-import { notifications } from "@cap/database/schema";
-import { db } from "@cap/database";
-import { eq } from "drizzle-orm";
-import { revalidatePath } from "next/cache";
-
-export const markAllAsRead = async () => {
-  const currentUser = await getCurrentUser();
-  if (!currentUser) {
-    throw new Error("User not found");
-  }
-
-  try {
-    await db()
-      .update(notifications)
-      .set({ readAt: new Date() })
-      .where(eq(notifications.recipientId, currentUser.id));
-  } catch (error) {
-    console.log(error);
-    throw new Error("Error marking notifications as read");
-  }
-
-  revalidatePath("/dashboard");
-};
diff --git a/apps/web/actions/notifications/mark-as-read.ts b/apps/web/actions/notifications/mark-as-read.ts
new file mode 100644
index 0000000000..3a6e7bc96f
--- /dev/null
+++ b/apps/web/actions/notifications/mark-as-read.ts
@@ -0,0 +1,34 @@
+"use server";
+
+import { getCurrentUser } from "@cap/database/auth/session";
+import { notifications } from "@cap/database/schema";
+import { db } from "@cap/database";
+import { eq } from "drizzle-orm";
+import { revalidatePath } from "next/cache";
+
+export const markAsRead = async (notificationId?: string) => {
+  const currentUser = await getCurrentUser();
+  if (!currentUser) {
+    throw new Error("User not found");
+  }
+
+  try {
+    const now = new Date();
+    if (notificationId) {
+      await db()
+        .update(notifications)
+        .set({ readAt: now })
+        .where(eq(notifications.id, notificationId));
+    } else {
+      await db()
+        .update(notifications)
+        .set({ readAt: now })
+        .where(eq(notifications.recipientId, currentUser.id));
+    }
+  } catch (error) {
+    console.log(error);
+    throw new Error("Error marking notification(s) as read");
+  }
+
+  revalidatePath("/dashboard");
+};
diff --git a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationHeader.tsx b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationHeader.tsx
index ca26cb597a..cd2a466ab8 100644
--- a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationHeader.tsx
+++ b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationHeader.tsx
@@ -2,7 +2,7 @@ import { faCheckDouble } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { toast } from "sonner";
 import clsx from "clsx";
-import { markAllAsRead } from "@/actions/notifications/mark-all-as-read";
+import { markAsRead } from "@/actions/notifications/mark-as-read";
 import { useQueryClient } from "@tanstack/react-query";
 import { useState } from "react";
 
@@ -11,10 +11,10 @@ export const NotificationHeader = () => {
   const [loading, setLoading] = useState(false);
   const queryClient = useQueryClient();
 
-  const markAllAsReadHandler = async () => {
+  const markAsReadHandler = async () => {
     try {
       setLoading(true);
-      await markAllAsRead();
+      await markAsRead();
       toast.success("Notifications marked as read");
       queryClient.invalidateQueries({
         queryKey: ["notifications"],
@@ -31,7 +31,7 @@ export const NotificationHeader = () => {
     <div className="flex justify-between items-center px-6 py-3 rounded-t-xl border bg-gray-3 border-gray-4">
       <p className="text-md text-gray-12">Notifications</p>
       <div
-        onClick={markAllAsReadHandler}
+        onClick={markAsReadHandler}
         className={clsx("flex gap-1 items-center transition-opacity duration-200 cursor-pointer hover:opacity-70", loading ? "opacity-50 cursor-not-allowed" : "")}
       >
         <FontAwesomeIcon
diff --git a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx
index 4c121fe61b..335039927e 100644
--- a/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx
+++ b/apps/web/app/(org)/dashboard/_components/Notifications/NotificationItem.tsx
@@ -4,6 +4,7 @@ import clsx from "clsx";
 import Link from "next/link";
 import moment from "moment";
 import { NotificationType } from "@/lib/Notification";
+import { markAsRead } from "@/actions/notifications/mark-as-read";
 import { Notification as APINotification } from "@cap/web-api-contract";
 
 type NotificationItemProps = {
@@ -25,9 +26,18 @@ export const NotificationItem = ({
 }: NotificationItemProps) => {
   const link = getLink(notification);
 
+  const markAsReadHandler = async () => {
+    try {
+      await markAsRead(notification.id);
+    } catch (error) {
+      console.error("Error marking notification as read:", error);
+    }
+  };
+
   return (
     <Link
       href={link}
+      onClick={markAsReadHandler}
       className={clsx(
         "flex gap-3 p-4 transition-colors cursor-pointer min-h-fit border-gray-3 hover:bg-gray-2",
         className
