diff --git a/frontend/components/context/Notifications/Notification.tsx b/frontend/components/context/Notifications/Notification.tsx index 974843cf6f..e473ddb52b 100644 --- a/frontend/components/context/Notifications/Notification.tsx +++ b/frontend/components/context/Notifications/Notification.tsx @@ -1,3 +1,4 @@ +import { useEffect, useRef } from "react"; import { faXmarkCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import classnames from "classnames"; @@ -5,14 +6,35 @@ import classnames from "classnames"; import { Notification as NotificationType } from "./NotificationProvider"; interface NotificationProps { - notification: NotificationType; - clearNotification: (text?: string) => void; + notification: Required; + clearNotification: (text: string) => void; } const Notification = ({ notification, clearNotification, }: NotificationProps) => { + const timeout = useRef(); + + const handleClearNotification = () => clearNotification(notification.text); + + const setNotifTimeout = () => { + timeout.current = window.setTimeout( + handleClearNotification, + notification.timeoutMs + ); + }; + + const cancelNotifTimeout = () => { + clearTimeout(timeout.current); + }; + + useEffect(() => { + setNotifTimeout(); + + return cancelNotifTimeout; + }, []); + return (
void; + createNotification: (newNotification: Notification) => void; }; const NotificationContext = createContext({ @@ -24,26 +25,30 @@ interface NotificationProviderProps { } const NotificationProvider = ({ children }: NotificationProviderProps) => { - const [notifications, setNotifications] = useState([]); - - const clearNotification = (text?: string) => { - if (text) { - return setNotifications((state) => - state.filter((notif) => notif.text !== text) - ); - } + const [notifications, setNotifications] = useState[]>( + [] + ); - return setNotifications([]); + const clearNotification = (text: string) => { + return setNotifications((state) => + state.filter((notif) => notif.text !== text) + ); }; - const createNotification = ({ text, type = "success" }: Notification) => { + const createNotification = ({ + text, + type = "success", + timeoutMs = 2000, + }: Notification) => { const doesNotifExist = notifications.some((notif) => notif.text === text); if (doesNotifExist) { return; } - return setNotifications((state) => [...state, { text, type }]); + const newNotification: Required = { text, type, timeoutMs }; + + return setNotifications((state) => [...state, newNotification]); }; return ( diff --git a/frontend/components/context/Notifications/Notifications.tsx b/frontend/components/context/Notifications/Notifications.tsx index 856331e24b..6940c33454 100644 --- a/frontend/components/context/Notifications/Notifications.tsx +++ b/frontend/components/context/Notifications/Notifications.tsx @@ -2,25 +2,27 @@ import Notification from "./Notification"; import { Notification as NotificationType } from "./NotificationProvider"; interface NoticationsProps { - notifications: NotificationType[]; - clearNotification: (text?: string) => void; + notifications: Required[]; + clearNotification: (text: string) => void; } const Notifications = ({ notifications, clearNotification, }: NoticationsProps) => { + if (!notifications.length) { + return null; + } + return ( -
-
- {notifications.map((notif) => ( - - ))} -
+
+ {notifications.map((notif) => ( + + ))}
); };