diff --git a/apps/app/components/notifications/notification-header.tsx b/apps/app/components/notifications/notification-header.tsx index e1003f636d5..0d181da985b 100644 --- a/apps/app/components/notifications/notification-header.tsx +++ b/apps/app/components/notifications/notification-header.tsx @@ -1,7 +1,7 @@ import React from "react"; // components -import { Icon, Tooltip } from "components/ui"; +import { CustomMenu, Icon, Tooltip } from "components/ui"; // helpers import { getNumberCount } from "helpers/string.helper"; @@ -21,6 +21,7 @@ type NotificationHeaderProps = { setArchived: React.Dispatch>; setReadNotification: React.Dispatch>; setSelectedTab: React.Dispatch>; + markAllNotificationsAsRead: () => Promise; }; export const NotificationHeader: React.FC = (props) => { @@ -37,6 +38,7 @@ export const NotificationHeader: React.FC = (props) => setArchived, setReadNotification, setSelectedTab, + markAllNotificationsAsRead, } = props; const notificationTabs: Array<{ @@ -88,33 +90,51 @@ export const NotificationHeader: React.FC = (props) => - - - - - -
diff --git a/apps/app/components/notifications/notification-popover.tsx b/apps/app/components/notifications/notification-popover.tsx index 39e4d87649d..f01fdafd155 100644 --- a/apps/app/components/notifications/notification-popover.tsx +++ b/apps/app/components/notifications/notification-popover.tsx @@ -51,6 +51,7 @@ export const NotificationPopover = () => { hasMore, isRefreshing, setFetchNotifications, + markAllNotificationsAsRead, } = useUserNotification(); // theme context @@ -112,7 +113,7 @@ export const NotificationPopover = () => { leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-1" > - + { setArchived={setArchived} setReadNotification={setReadNotification} setSelectedTab={setSelectedTab} + markAllNotificationsAsRead={markAllNotificationsAsRead} /> {notifications ? ( diff --git a/apps/app/hooks/use-user-notifications.tsx b/apps/app/hooks/use-user-notifications.tsx index fe539d80534..5e6ea5d0b9f 100644 --- a/apps/app/hooks/use-user-notifications.tsx +++ b/apps/app/hooks/use-user-notifications.tsx @@ -9,11 +9,14 @@ import useSWRInfinite from "swr/infinite"; // services import userNotificationServices from "services/notifications.service"; +// hooks +import useToast from "./use-toast"; + // fetch-keys import { UNREAD_NOTIFICATIONS_COUNT, getPaginatedNotificationKey } from "constants/fetch-keys"; // type -import type { NotificationType, NotificationCount } from "types"; +import type { NotificationType, NotificationCount, IMarkAllAsReadPayload } from "types"; const PER_PAGE = 30; @@ -21,6 +24,8 @@ const useUserNotification = () => { const router = useRouter(); const { workspaceSlug } = router.query; + const { setToastAlert } = useToast(); + const [snoozed, setSnoozed] = useState(false); const [archived, setArchived] = useState(false); const [readNotification, setReadNotification] = useState(false); @@ -274,6 +279,29 @@ const useUserNotification = () => { } }; + const markAllNotificationsAsRead = async () => { + if (!workspaceSlug) return; + + let markAsReadParams: IMarkAllAsReadPayload; + + if (snoozed) markAsReadParams = { archived: false, snoozed: true }; + else if (archived) markAsReadParams = { archived: true, snoozed: false }; + else markAsReadParams = { archived: false, snoozed: false, type: selectedTab }; + + await userNotificationServices + .markAllNotificationsAsRead(workspaceSlug.toString(), markAsReadParams) + .catch(() => { + setToastAlert({ + type: "error", + title: "Error!", + message: "Something went wrong. Please try again.", + }); + }) + .finally(() => { + notificationMutate(); + }); + }; + return { notifications, notificationMutate, @@ -304,6 +332,7 @@ const useUserNotification = () => { isRefreshing, setFetchNotifications, markNotificationAsRead, + markAllNotificationsAsRead, }; }; diff --git a/apps/app/services/notifications.service.ts b/apps/app/services/notifications.service.ts index a8652b77763..01c139b5154 100644 --- a/apps/app/services/notifications.service.ts +++ b/apps/app/services/notifications.service.ts @@ -9,6 +9,7 @@ import type { INotificationParams, NotificationCount, PaginatedUserNotification, + IMarkAllAsReadPayload, } from "types"; class UserNotificationsServices extends APIService { @@ -172,6 +173,19 @@ class UserNotificationsServices extends APIService { throw error?.response?.data; }); } + + async markAllNotificationsAsRead( + workspaceSlug: string, + payload: IMarkAllAsReadPayload + ): Promise { + return this.post(`/api/workspaces/${workspaceSlug}/users/notifications/mark-all-read/`, { + ...payload, + }) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } } const userNotificationServices = new UserNotificationsServices(); diff --git a/apps/app/types/notifications.d.ts b/apps/app/types/notifications.d.ts index adb4e469a8a..8033c19a94e 100644 --- a/apps/app/types/notifications.d.ts +++ b/apps/app/types/notifications.d.ts @@ -71,3 +71,9 @@ export type NotificationCount = { my_issues: number; watching_issues: number; }; + +export interface IMarkAllAsReadPayload { + archived?: boolean; + snoozed?: boolean; + type?: NotificationType; +}