From 11ed4320da5203a21c2ca5b28d55d75f1926f81c Mon Sep 17 00:00:00 2001 From: Vishal Date: Fri, 23 Aug 2024 15:22:48 +0530 Subject: [PATCH] feat: Add NotificationIcon component and Notification page Signed-off-by: Vishal --- src/assets/NotificationIcon.tsx | 38 ++++++++++++++ src/pages/Notification/index.tsx | 87 ++++++++++++++++++++++++++++++++ src/router/routeMap.tsx | 9 ++++ src/types/notification.ts | 43 ++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 src/assets/NotificationIcon.tsx create mode 100644 src/pages/Notification/index.tsx create mode 100644 src/types/notification.ts diff --git a/src/assets/NotificationIcon.tsx b/src/assets/NotificationIcon.tsx new file mode 100644 index 0000000..8daacc0 --- /dev/null +++ b/src/assets/NotificationIcon.tsx @@ -0,0 +1,38 @@ +export default function NotificationIcon(props: React.SVGProps) { + return ( + + + + + + ); +} diff --git a/src/pages/Notification/index.tsx b/src/pages/Notification/index.tsx new file mode 100644 index 0000000..2f6f1c7 --- /dev/null +++ b/src/pages/Notification/index.tsx @@ -0,0 +1,87 @@ +import { Spinner } from "@/components/Spinner"; +import { ErrorContext } from "@/contexts/error"; +import API from "@/services/API"; +import { INotification } from "@/types/notification"; +import React, { useEffect, useState } from "react"; + +interface NotificationCardProps { + notif: INotification; +} + +function NotificationCard({ notif }: NotificationCardProps) { + const wrap_link = (child: React.ReactNode, link?: string) => + link ? ( + + {child} + + ) : ( + child + ); + + return ( +
+ {wrap_link( + <> +

+ {notif.data.title} +

+

{notif.data.description}

+ , + notif.data.link, + )} + + {notif.data.actions.map((action) => { + return ( + + {action.action} + + ); + })} + + {new Date(notif.updated_at).toLocaleString()} +
+ ); +} + +export default function NotificationPage() { + const { setError } = React.useContext(ErrorContext); + + const [notifications, setNotifs] = useState(null); + + useEffect(() => { + const notifications = "/notification"; + API.get(notifications) + .then((response) => { + const userData = response.data.data; + setNotifs(userData); + }) + .catch((error) => { + setError(error); + }); + }, []); + + if (notifications === null) + return ( +
+ +
+ ); + + return ( +
+

Latest Updates

+ {notifications.map((notif) => { + return ; + })} +
+ ); +} diff --git a/src/router/routeMap.tsx b/src/router/routeMap.tsx index cc4956f..39adf68 100644 --- a/src/router/routeMap.tsx +++ b/src/router/routeMap.tsx @@ -16,6 +16,7 @@ import Permission from "@/types/permissions"; import CustomRouteElement from "@/types/routeElement"; import React from "react"; import ProfileIcon from "@/assets/ProfileIcon"; +import NotificationIcon from "@/assets/NotificationIcon"; //lazy imports const Login = React.lazy(() => import("@/pages/auth/Login")); @@ -39,6 +40,7 @@ const AllEditions = React.lazy(() => import("@/pages/Edition/AllEditions")); const Logs = React.lazy(() => import("@/pages/Logs")); const MemberProfile = React.lazy(() => import("@/pages/Member/MemberProfile")); const EditMember = React.lazy(() => import("@/pages/Member/EditMember")); +const NotificationPage = React.lazy(() => import("@/pages/Notification")); /** This route map serves the routes as well as is used to * generate nav bar menu, so the links can never be broken */ @@ -236,6 +238,13 @@ const routeMap: CustomRouteElement[] = [ permission: [Permission.AccessLogs], label: "Logs", }, + { + path: "notification/", + element: , + icon: , + permission: [], + label: "Notifications", + }, ]; const make_protected = (routes: CustomRouteElement[]) => { diff --git a/src/types/notification.ts b/src/types/notification.ts new file mode 100644 index 0000000..252a3fa --- /dev/null +++ b/src/types/notification.ts @@ -0,0 +1,43 @@ +export type Update = "Added" | "Removed" | "Modified" | "Unchanged" | "Inherit"; + +export interface TabUpdate { + title: string; + data: DataUpdate[]; + update: Update; +} + +export interface LinkNodeUpdate { + title: string; + link: Link; + update: Update; +} + +export interface DataUpdate { + title: string; + link?: Link; + children: LinkNodeUpdate[]; + date?: string; + update: Update; +} + +export type InformationUpdate = TabUpdate[]; + +type Link = string; + +export interface INotification { + _id: string; + data: ClientNotification; + updated_at: string; +} + +export interface ClientNotification { + title: string; + description: string; + actions: ClientNotificationAction[]; + link?: string; +} + +export interface ClientNotificationAction { + action: string; + link: string; +}