diff --git a/src/Hooks/useFetchDepinStatusPage.js b/src/Hooks/useFetchDepinStatusPage.js new file mode 100644 index 000000000..cb436d6d6 --- /dev/null +++ b/src/Hooks/useFetchDepinStatusPage.js @@ -0,0 +1,58 @@ +import { useState, useEffect } from "react"; +import { networkService } from "../main"; +import { createToast } from "../Utils/toastUtils"; +import { useSelector } from "react-redux"; +import { useTheme } from "@emotion/react"; +import { useMonitorUtils } from "./useMonitorUtils"; + +const useFetchDepinStatusPage = ({ url, timeFrame, isCreate = false }) => { + const [isLoading, setIsLoading] = useState(true); + const [networkError, setNetworkError] = useState(false); + const [statusPage, setStatusPage] = useState(undefined); + const [monitorId, setMonitorId] = useState(undefined); + const [isPublished, setIsPublished] = useState(false); + const { authToken } = useSelector((state) => state.auth); + const theme = useTheme(); + const { getMonitorWithPercentage } = useMonitorUtils(); + + useEffect(() => { + if (isCreate) return; + const fetchStatusPageByUrl = async () => { + try { + const response = await networkService.getDistributedStatusPageByUrl({ + authToken, + url, + type: "distributed", + timeFrame, + }); + if (!response?.data?.data) return; + const statusPage = response.data.data; + + const monitorsWithPercentage = statusPage?.subMonitors.map((monitor) => + getMonitorWithPercentage(monitor, theme) + ); + + const statusPageWithSubmonitorPercentages = { + ...statusPage, + subMonitors: monitorsWithPercentage, + }; + setStatusPage(statusPageWithSubmonitorPercentages); + + setMonitorId(statusPage?.monitors[0]); + setIsPublished(statusPage?.isPublished); + } catch (error) { + setNetworkError(true); + createToast({ + body: error.message, + }); + } finally { + setIsLoading(false); + } + }; + fetchStatusPageByUrl(); + }, [authToken, url, getMonitorWithPercentage, theme, timeFrame, isCreate]); + + return [isLoading, networkError, statusPage, monitorId, isPublished]; +}; + +export { useFetchDepinStatusPage }; diff --git a/src/Hooks/useSubscribeToDepinDetails.js b/src/Hooks/useSubscribeToDepinDetails.js new file mode 100644 index 000000000..67b7c898f --- /dev/null +++ b/src/Hooks/useSubscribeToDepinDetails.js @@ -0,0 +1,95 @@ +import { useState, useEffect } from "react"; +import { networkService } from "../main"; +import { createToast } from "../Utils/toastUtils"; + +const useSubscribeToDepinDetails = ({ monitorId, isPublic, isPublished, dateRange }) => { + const [isLoading, setIsLoading] = useState(true); + const [connectionStatus, setConnectionStatus] = useState(undefined); + const [retryCount, setRetryCount] = useState(0); + const [networkError, setNetworkError] = useState(false); + const [monitor, setMonitor] = useState(undefined); + const [lastUpdateTrigger, setLastUpdateTrigger] = useState(0); + + useEffect(() => { + if (typeof monitorId === "undefined") { + return; + } + // If this page is public and not published, don't subscribe to details + if (isPublic && isPublished === false) { + return; + } + + // Get initial data + + const fetchInitialData = async () => { + try { + const res = await networkService.getDistributedUptimeDetails({ + monitorId, + dateRange: dateRange, + normalize: true, + }); + const responseData = res?.data?.data; + + if (typeof responseData === "undefined") { + throw new Error("No data"); + } + setConnectionStatus("up"); + setLastUpdateTrigger(Date.now()); + setMonitor(responseData); + } catch (error) { + setNetworkError(true); + setConnectionStatus("down"); + createToast({ + body: error.message, + }); + } finally { + setIsLoading(false); + } + }; + + fetchInitialData(); + + try { + const cleanup = networkService.subscribeToDistributedUptimeDetails({ + monitorId, + dateRange: dateRange, + normalize: true, + onUpdate: (data) => { + if (isLoading === true) { + setIsLoading(false); + } + if (networkError === true) { + setNetworkError(false); + } + setLastUpdateTrigger(Date.now()); + setMonitor(data.monitor); + }, + onOpen: () => { + setConnectionStatus("up"); + setRetryCount(0); // Reset retry count on successful connection + }, + onError: () => { + setIsLoading(false); + setNetworkError(true); + setConnectionStatus("down"); + }, + }); + return cleanup; + } catch (error) { + setNetworkError(true); + } + }, [ + dateRange, + monitorId, + retryCount, + setConnectionStatus, + networkError, + isLoading, + isPublic, + isPublished, + ]); + + return [isLoading, networkError, connectionStatus, monitor, lastUpdateTrigger]; +}; + +export { useSubscribeToDepinDetails }; diff --git a/src/Hooks/useSubscribeToDepinMonitors.js b/src/Hooks/useSubscribeToDepinMonitors.js new file mode 100644 index 000000000..3bc098afa --- /dev/null +++ b/src/Hooks/useSubscribeToDepinMonitors.js @@ -0,0 +1,94 @@ +import { useEffect, useState } from "react"; +import { networkService } from "../main"; +import { useSelector } from "react-redux"; +import { useTheme } from "@emotion/react"; +import { useMonitorUtils } from "./useMonitorUtils"; +import { createToast } from "../Utils/toastUtils"; + +const useSubscribeToDepinMonitors = (page, rowsPerPage) => { + // Redux + const { user } = useSelector((state) => state.auth); + + // Local state + const [isLoading, setIsLoading] = useState(true); + const [networkError, setNetworkError] = useState(false); + const [count, setCount] = useState(undefined); + const [monitors, setMonitors] = useState(undefined); + + const theme = useTheme(); + const { getMonitorWithPercentage } = useMonitorUtils(); + + useEffect(() => { + const fetchInitialData = async () => { + try { + const initialDataRes = await networkService.getDistributedUptimeMonitors({ + teamId: user.teamId, + limit: 25, + types: ["distributed_http"], + page, + rowsPerPage, + }); + + const { count, monitors } = initialDataRes?.data?.data ?? {}; + const responseData = initialDataRes?.data?.data; + if (typeof responseData === "undefined") throw new Error("No data"); + + const mappedMonitors = monitors?.map((monitor) => + getMonitorWithPercentage(monitor, theme) + ); + + setMonitors(mappedMonitors); + setCount(count?.monitorsCount ?? 0); + } catch (error) { + setNetworkError(true); + createToast({ + body: error.message, + }); + } finally { + setIsLoading(false); + } + }; + + fetchInitialData(); + + try { + const cleanup = networkService.subscribeToDistributedUptimeMonitors({ + teamId: user.teamId, + limit: 25, + types: [ + typeof import.meta.env.VITE_DEPIN_TESTING === "undefined" + ? "distributed_http" + : "distributed_test", + ], + page, + rowsPerPage, + filter: null, + field: null, + order: null, + onUpdate: (data) => { + if (isLoading === true) { + setIsLoading(false); + } + const { count, monitors } = data; + const mappedMonitors = monitors.map((monitor) => + getMonitorWithPercentage(monitor, theme) + ); + setMonitors(mappedMonitors); + setCount(count?.monitorsCount ?? 0); + }, + onError: () => { + setIsLoading(false); + }, + }); + + return cleanup; + } catch (error) { + createToast({ + body: error.message, + }); + setNetworkError(true); + } + }, [user, getMonitorWithPercentage, theme, isLoading, page, rowsPerPage]); + return [monitors, count, isLoading, networkError]; +}; +export { useSubscribeToDepinMonitors };