From 46b2b4c3ab0db38a7f2561eb099333337ffa0f34 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 9 Jun 2025 12:57:15 +0800 Subject: [PATCH] add hooks --- client/src/Hooks/useFetchUptimeMonitorById.js | 35 +++++++ client/src/Hooks/useNotifications.js | 91 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 client/src/Hooks/useFetchUptimeMonitorById.js create mode 100644 client/src/Hooks/useNotifications.js diff --git a/client/src/Hooks/useFetchUptimeMonitorById.js b/client/src/Hooks/useFetchUptimeMonitorById.js new file mode 100644 index 000000000..cb344569c --- /dev/null +++ b/client/src/Hooks/useFetchUptimeMonitorById.js @@ -0,0 +1,35 @@ +import { useState, useEffect } from "react"; +import { useDispatch } from "react-redux"; +import { getUptimeMonitorById } from "../Features/UptimeMonitors/uptimeMonitorsSlice"; +import { useNavigate } from "react-router"; + +const useFetchUptimeMonitorById = (monitorId, updateTrigger) => { + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const [monitor, setMonitor] = useState(null); + const navigate = useNavigate(); + const dispatch = useDispatch(); + useEffect(() => { + const fetchMonitor = async () => { + try { + setIsLoading(true); + const action = await dispatch(getUptimeMonitorById({ monitorId })); + + if (getUptimeMonitorById.fulfilled.match(action)) { + const monitor = action.payload.data; + setMonitor(monitor); + } else if (getUptimeMonitorById.rejected.match(action)) { + throw new Error(action.error.message); + } + } catch (error) { + navigate("/not-found", { replace: true }); + } finally { + setIsLoading(false); + } + }; + fetchMonitor(); + }, [monitorId, dispatch, navigate, updateTrigger]); + return [monitor, isLoading, error]; +}; + +export { useFetchUptimeMonitorById }; diff --git a/client/src/Hooks/useNotifications.js b/client/src/Hooks/useNotifications.js new file mode 100644 index 000000000..4ece55acd --- /dev/null +++ b/client/src/Hooks/useNotifications.js @@ -0,0 +1,91 @@ +import { useState, useEffect, useCallback } from "react"; +import { createToast } from "../Utils/toastUtils"; +import { networkService } from "../main"; +import { useNavigate } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { useTranslation } from "react-i18next"; + +const useCreateNotification = () => { + const navigate = useNavigate(); + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const createNotification = async (notification) => { + try { + setIsLoading(true); + await networkService.createNotification({ notification }); + createToast({ + body: t("notifications.create.success"), + }); + navigate("/notifications"); + } catch (error) { + setError(error); + createToast({ + body: t("notifications.create.failed"), + }); + } finally { + setIsLoading(false); + } + }; + + return [createNotification, isLoading, error]; +}; + +const useGetNotificationsByTeamId = (updateTrigger) => { + const [notifications, setNotifications] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const { user } = useSelector((state) => state.auth); + const { t } = useTranslation(); + + const getNotifications = useCallback(async () => { + try { + setIsLoading(true); + const response = await networkService.getNotificationsByTeamId({ + teamId: user.teamId, + }); + setNotifications(response?.data?.data ?? []); + } catch (error) { + setError(error); + createToast({ + body: t("notifications.fetch.failed"), + }); + } finally { + setIsLoading(false); + } + }, [user.teamId]); + + useEffect(() => { + getNotifications(); + }, [getNotifications, updateTrigger]); + + return [notifications, isLoading, error]; +}; + +const useDeleteNotification = () => { + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const { t } = useTranslation(); + + const deleteNotification = async (id, triggerUpdate) => { + try { + setIsLoading(true); + await networkService.deleteNotificationById({ id }); + createToast({ + body: t("notifications.delete.success"), + }); + triggerUpdate(); + } catch (error) { + setError(error); + createToast({ + body: t("notifications.delete.failed"), + }); + } finally { + setIsLoading(false); + } + }; + + return [deleteNotification, isLoading, error]; +}; +export { useCreateNotification, useGetNotificationsByTeamId, useDeleteNotification };