From 274595a5339c02dc0f6587915c8bb35da422fcde Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 9 Jun 2025 10:17:09 +0800 Subject: [PATCH] purge distributed uptime --- client/src/Components/Sidebar/index.jsx | 18 +- client/src/Hooks/useFetchDepinStatusPage.js | 58 --- .../src/Hooks/useSubscribeToDepinDetails.js | 96 ----- .../src/Hooks/useSubscribeToDepinMonitors.js | 95 ----- .../useCreateDistributedUptimeMonitor.jsx | 31 -- .../Create/Hooks/useMonitorFetch.jsx | 31 -- .../Pages/DistributedUptime/Create/index.jsx | 349 ------------------ .../Details/Components/Chatbot/index.jsx | 50 --- .../Components/ControlsHeader/index.jsx | 92 ----- .../Details/Components/DeviceTicker/index.jsx | 98 ----- .../DistributedUptimeMapStyle.json | 169 --------- .../DistributedUptimeMap/buildStyle.js | 33 -- .../Components/DistributedUptimeMap/index.jsx | 118 ------ .../Area/index.jsx | 95 ----- .../Bar/index.jsx | 95 ----- .../Helpers/Tick.jsx | 31 -- .../Helpers/ToolTip.jsx | 89 ----- .../DistributedUptimeResponseChart/index.jsx | 53 --- .../Details/Components/Footer/index.jsx | 34 -- .../Details/Components/LastUpdate/index.jsx | 15 - .../Components/MonitorHeader/index.jsx | 23 -- .../Components/NextExpectedCheck/index.jsx | 30 -- .../Details/Components/Skeleton/index.jsx | 14 - .../Details/Components/StatBoxes/index.jsx | 60 --- .../Details/Components/StatusHeader/index.jsx | 94 ----- .../Details/Hooks/useDeleteMonitor.jsx | 25 -- .../Pages/DistributedUptime/Details/index.jsx | 148 -------- .../Components/MonitorTable/index.jsx | 93 ----- .../Monitors/Components/Skeleton/index.jsx | 14 - .../DistributedUptime/Monitors/index.jsx | 102 ----- .../Components/VisuallyHiddenInput/index.jsx | 22 -- .../DistributedUptimeStatus/Create/index.jsx | 322 ---------------- .../Status/Components/MonitorsList/index.jsx | 66 ---- .../Status/Components/Skeleton/index.jsx | 14 - .../Components/TimeframeHeader/index.jsx | 42 --- .../DistributedUptimeStatus/Status/index.jsx | 319 ---------------- .../Components/ControlsHeader/index.jsx | 6 - .../Components/StatusPagesTable/index.jsx | 11 +- client/src/Routes/index.jsx | 73 ---- client/src/Utils/NetworkService.js | 151 +------- client/src/Validation/validation.js | 2 +- client/src/locales/en.json | 9 - client/src/locales/pt-BR.json | 1 - client/src/locales/ru.json | 5 - server/controllers/diagnosticController.js | 14 - .../distributedUptimeController.js | 339 ----------------- server/controllers/monitorController.js | 12 +- server/controllers/statusPageController.js | 23 -- server/db/models/DistributedUptimeCheck.js | 137 ------- server/db/models/Monitor.js | 11 +- server/db/models/StatusPage.js | 2 +- server/db/mongo/MongoDB.js | 6 - server/db/mongo/modules/checkModule.js | 10 +- server/db/mongo/modules/diagnosticModule.js | 50 +-- .../mongo/modules/distributedCheckModule.js | 156 -------- server/db/mongo/modules/monitorModule.js | 68 ---- .../db/mongo/modules/monitorModuleQueries.js | 32 -- server/db/mongo/modules/statusPageModule.js | 100 ----- server/db/mongo/utils/seedDb.js | 102 ----- server/index.js | 15 +- server/routes/diagnosticRoute.js | 5 - server/routes/distributedUptimeRoute.js | 44 --- server/routes/statusPageRoute.js | 4 - server/service/JobQueue/JobQueue.js | 3 +- server/service/JobQueue/JobQueueHelper.js | 7 - server/service/PulseQueue/PulseQueueHelper.js | 4 - server/service/bufferService.js | 3 - server/service/networkService.js | 34 -- server/service/statusService.js | 17 - server/validation/joi.js | 17 +- 70 files changed, 17 insertions(+), 4494 deletions(-) delete mode 100644 client/src/Hooks/useFetchDepinStatusPage.js delete mode 100644 client/src/Hooks/useSubscribeToDepinDetails.js delete mode 100644 client/src/Hooks/useSubscribeToDepinMonitors.js delete mode 100644 client/src/Pages/DistributedUptime/Create/Hooks/useCreateDistributedUptimeMonitor.jsx delete mode 100644 client/src/Pages/DistributedUptime/Create/Hooks/useMonitorFetch.jsx delete mode 100644 client/src/Pages/DistributedUptime/Create/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/Chatbot/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/ControlsHeader/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DeviceTicker/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/DistributedUptimeMapStyle.json delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/buildStyle.js delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeMap/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeResponseChart/Area/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeResponseChart/Bar/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeResponseChart/Helpers/Tick.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeResponseChart/Helpers/ToolTip.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/DistributedUptimeResponseChart/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/Footer/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/LastUpdate/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/MonitorHeader/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/NextExpectedCheck/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/Skeleton/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/StatBoxes/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/Hooks/useDeleteMonitor.jsx delete mode 100644 client/src/Pages/DistributedUptime/Details/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Monitors/Components/MonitorTable/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Monitors/Components/Skeleton/index.jsx delete mode 100644 client/src/Pages/DistributedUptime/Monitors/index.jsx delete mode 100644 client/src/Pages/DistributedUptimeStatus/Create/Components/VisuallyHiddenInput/index.jsx delete mode 100644 client/src/Pages/DistributedUptimeStatus/Create/index.jsx delete mode 100644 client/src/Pages/DistributedUptimeStatus/Status/Components/MonitorsList/index.jsx delete mode 100644 client/src/Pages/DistributedUptimeStatus/Status/Components/Skeleton/index.jsx delete mode 100644 client/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx delete mode 100644 client/src/Pages/DistributedUptimeStatus/Status/index.jsx delete mode 100755 server/controllers/distributedUptimeController.js delete mode 100755 server/db/models/DistributedUptimeCheck.js delete mode 100755 server/db/mongo/modules/distributedCheckModule.js delete mode 100755 server/routes/distributedUptimeRoute.js diff --git a/client/src/Components/Sidebar/index.jsx b/client/src/Components/Sidebar/index.jsx index f78ac62f0..6073f428d 100644 --- a/client/src/Components/Sidebar/index.jsx +++ b/client/src/Components/Sidebar/index.jsx @@ -23,7 +23,6 @@ import UserSvg from "../../assets/icons/user.svg?react"; import TeamSvg from "../../assets/icons/user-two.svg?react"; import LogoutSvg from "../../assets/icons/logout.svg?react"; import Support from "../../assets/icons/support.svg?react"; -import Account from "../../assets/icons/user-edit.svg?react"; import Maintenance from "../../assets/icons/maintenance.svg?react"; import Monitors from "../../assets/icons/monitors.svg?react"; import Incidents from "../../assets/icons/incidents.svg?react"; @@ -37,10 +36,8 @@ import ArrowLeft from "../../assets/icons/left-arrow.svg?react"; import DotsVertical from "../../assets/icons/dots-vertical.svg?react"; import ChangeLog from "../../assets/icons/changeLog.svg?react"; import Docs from "../../assets/icons/docs.svg?react"; -import Folder from "../../assets/icons/folder.svg?react"; import StatusPages from "../../assets/icons/status-pages.svg?react"; import Discussions from "../../assets/icons/discussions.svg?react"; -import DistributedUptimeIcon from "../../assets/icons/distributed-uptime.svg?react"; import "./index.css"; // Utils @@ -56,11 +53,7 @@ const getMenu = (t) => [ { name: t("menu.uptime"), path: "uptime", icon: }, { name: t("menu.pagespeed"), path: "pagespeed", icon: }, { name: t("menu.infrastructure"), path: "infrastructure", icon: }, - { - name: t("menu.distributedUptime"), - path: "distributed-uptime", - icon: , - }, + { name: t("menu.incidents"), path: "incidents", icon: }, { name: t("menu.statusPages"), path: "status", icon: }, @@ -95,14 +88,13 @@ const URL_MAP = { support: "https://discord.com/invite/NAb6H3UTjK", discussions: "https://github.com/bluewave-labs/checkmate/discussions", docs: "https://bluewavelabs.gitbook.io/checkmate", - changelog: "https://github.com/bluewave-labs/bluewave-uptime/releases", + changelog: "https://github.com/bluewave-labs/checkmate/releases", }; const PATH_MAP = { monitors: "Dashboard", pagespeed: "Dashboard", infrastructure: "Dashboard", - ["distributed-uptime"]: "Dashboard", account: "Account", settings: "Settings", }; @@ -375,12 +367,6 @@ function Sidebar() { }} > {menu.map((item) => { - if ( - item.path === "distributed-uptime" && - distributedUptimeEnabled === false - ) { - return null; - } return item.path ? ( /* If item has a path */ { - 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/client/src/Hooks/useSubscribeToDepinDetails.js b/client/src/Hooks/useSubscribeToDepinDetails.js deleted file mode 100644 index 0e8c2744f..000000000 --- a/client/src/Hooks/useSubscribeToDepinDetails.js +++ /dev/null @@ -1,96 +0,0 @@ -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, - isPublic, - }); - 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/client/src/Hooks/useSubscribeToDepinMonitors.js b/client/src/Hooks/useSubscribeToDepinMonitors.js deleted file mode 100644 index 918ead6bc..000000000 --- a/client/src/Hooks/useSubscribeToDepinMonitors.js +++ /dev/null @@ -1,95 +0,0 @@ -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); - setNetworkError(true); - }, - }); - - return cleanup; - } catch (error) { - createToast({ - body: error.message, - }); - setNetworkError(true); - } - }, [user, getMonitorWithPercentage, theme, isLoading, page, rowsPerPage]); - return [monitors, count, isLoading, networkError]; -}; -export { useSubscribeToDepinMonitors }; diff --git a/client/src/Pages/DistributedUptime/Create/Hooks/useCreateDistributedUptimeMonitor.jsx b/client/src/Pages/DistributedUptime/Create/Hooks/useCreateDistributedUptimeMonitor.jsx deleted file mode 100644 index b2634e9a7..000000000 --- a/client/src/Pages/DistributedUptime/Create/Hooks/useCreateDistributedUptimeMonitor.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useState } from "react"; -import { networkService } from "../../../../main"; -import { useSelector } from "react-redux"; -import { createToast } from "../../../../Utils/toastUtils"; - -const useCreateDistributedUptimeMonitor = ({ isCreate, monitorId }) => { - const [isLoading, setIsLoading] = useState(false); - const [networkError, setNetworkError] = useState(false); - const createDistributedUptimeMonitor = async ({ form }) => { - setIsLoading(true); - try { - if (isCreate) { - await networkService.createMonitor({ monitor: form }); - } else { - await networkService.updateMonitor({ monitor: form, monitorId }); - } - - return true; - } catch (error) { - setNetworkError(true); - createToast({ body: error?.response?.data?.msg ?? error.message }); - return false; - } finally { - setIsLoading(false); - } - }; - - return [createDistributedUptimeMonitor, isLoading, networkError]; -}; - -export { useCreateDistributedUptimeMonitor }; diff --git a/client/src/Pages/DistributedUptime/Create/Hooks/useMonitorFetch.jsx b/client/src/Pages/DistributedUptime/Create/Hooks/useMonitorFetch.jsx deleted file mode 100644 index efffbe437..000000000 --- a/client/src/Pages/DistributedUptime/Create/Hooks/useMonitorFetch.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useEffect, useState } from "react"; -import { networkService } from "../../../../main"; -import { createToast } from "../../../../Utils/toastUtils"; - -export const useMonitorFetch = ({ monitorId, isCreate }) => { - const [networkError, setNetworkError] = useState(false); - const [isLoading, setIsLoading] = useState(true); - const [monitor, setMonitor] = useState(undefined); - - useEffect(() => { - const fetchMonitors = async () => { - try { - if (isCreate) return; - const res = await networkService.getUptimeDetailsById({ - monitorId: monitorId, - normalize: true, - }); - setMonitor(res?.data?.data ?? {}); - } catch (error) { - setNetworkError(true); - createToast({ body: error.message }); - } finally { - setIsLoading(false); - } - }; - fetchMonitors(); - }, [monitorId, isCreate]); - return [monitor, isLoading, networkError]; -}; - -export default useMonitorFetch; diff --git a/client/src/Pages/DistributedUptime/Create/index.jsx b/client/src/Pages/DistributedUptime/Create/index.jsx deleted file mode 100644 index aff2a7d22..000000000 --- a/client/src/Pages/DistributedUptime/Create/index.jsx +++ /dev/null @@ -1,349 +0,0 @@ -// Components -import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material"; - -import Breadcrumbs from "../../../Components/Breadcrumbs"; -import ConfigBox from "../../../Components/ConfigBox"; -import TextInput from "../../../Components/Inputs/TextInput"; -import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments"; -import Radio from "../../../Components/Inputs/Radio"; -import Checkbox from "../../../Components/Inputs/Checkbox"; -import Select from "../../../Components/Inputs/Select"; -import { createToast } from "../../../Utils/toastUtils"; - -// Utility -import { useTheme } from "@emotion/react"; -import { useState, useEffect } from "react"; -import { useNavigate } from "react-router-dom"; -import { useSelector } from "react-redux"; -import { monitorValidation } from "../../../Validation/validation"; -import { useParams } from "react-router-dom"; -import { useCreateDistributedUptimeMonitor } from "./Hooks/useCreateDistributedUptimeMonitor"; -import { useMonitorFetch } from "./Hooks/useMonitorFetch"; -import { useTranslation } from "react-i18next"; - -// Constants -const MS_PER_MINUTE = 60000; -const SELECT_VALUES = [ - { _id: 1, name: "1 minute" }, - { _id: 2, name: "2 minutes" }, - { _id: 3, name: "3 minutes" }, - { _id: 4, name: "4 minutes" }, - { _id: 5, name: "5 minutes" }, -]; - -const parseUrl = (url) => { - try { - return new URL(url); - } catch (error) { - return null; - } -}; - -const CreateDistributedUptime = () => { - const { monitorId } = useParams(); - const isCreate = typeof monitorId === "undefined"; - const { t } = useTranslation(); - - let BREADCRUMBS = [ - { name: `distributed uptime`, path: "/distributed-uptime" }, - ...(isCreate ? [] : [{ name: "details", path: `/distributed-uptime/${monitorId}` }]), - { name: isCreate ? "create" : "configure", path: `` }, - ]; - - // Redux state - const { user } = useSelector((state) => state.auth); - - // Local state - const [https, setHttps] = useState(true); - const [notifications, setNotifications] = useState([]); - const [form, setForm] = useState({ - type: "distributed_http", - name: "", - url: "", - interval: 1, - }); - const [errors, setErrors] = useState({}); - - //utils - const theme = useTheme(); - const navigate = useNavigate(); - const [createDistributedUptimeMonitor, isLoading, networkError] = - useCreateDistributedUptimeMonitor({ isCreate, monitorId }); - - const [monitor, monitorIsLoading, monitorNetworkError] = useMonitorFetch({ - monitorId, - isCreate, - }); - - // Effect to set monitor to fetched monitor - useEffect(() => { - if (typeof monitor !== "undefined") { - const parsedUrl = parseUrl(monitor?.url); - const protocol = parsedUrl?.protocol?.replace(":", "") || ""; - setHttps(protocol === "https"); - - const newForm = { - name: monitor.name, - interval: monitor.interval / MS_PER_MINUTE, - url: parsedUrl.host, - type: monitor.type, - }; - - setForm(newForm); - } - }, [monitor]); - - // Handlers - const handleCreateMonitor = async () => { - const monitorToSubmit = { ...form }; - - // Prepend protocol to url - monitorToSubmit.url = `http${https ? "s" : ""}://` + monitorToSubmit.url; - - const { error } = monitorValidation.validate(monitorToSubmit, { - abortEarly: false, - }); - if (error) { - const newErrors = {}; - error.details.forEach((err) => { - newErrors[err.path[0]] = err.message; - }); - setErrors(newErrors); - createToast({ body: "Please check the form for errors." }); - return; - } - - // Append needed fields - monitorToSubmit.description = form.name; - monitorToSubmit.interval = form.interval * MS_PER_MINUTE; - monitorToSubmit.teamId = user.teamId; - monitorToSubmit.userId = user._id; - monitorToSubmit.notifications = notifications; - - const success = await createDistributedUptimeMonitor({ form: monitorToSubmit }); - if (success) { - createToast({ body: "Monitor created successfully!" }); - navigate("/distributed-uptime"); - } else { - createToast({ body: "Failed to create monitor." }); - } - }; - - const handleChange = (event) => { - let { name, value } = event.target; - - setForm({ - ...form, - [name]: value, - }); - const { error } = monitorValidation.validate( - { [name]: value }, - { abortEarly: false } - ); - setErrors((prev) => ({ - ...prev, - ...(error ? { [name]: error.details[0].message } : { [name]: undefined }), - })); - }; - - const handleNotifications = (event, type) => { - const { value } = event.target; - let currentNotifications = [...notifications]; - const notificationAlreadyExists = notifications.some((notification) => { - if (notification.type === type && notification.address === value) { - return true; - } - return false; - }); - if (notificationAlreadyExists) { - currentNotifications = currentNotifications.filter((notification) => { - if (notification.type === type && notification.address === value) { - return false; - } - return true; - }); - } else { - currentNotifications.push({ type, address: value }); - } - setNotifications(currentNotifications); - }; - - return ( - - - console.log("submit")} - > - - - {isCreate ? "Create your" : "Edit your"}{" "} - - - {t("monitor")} - - - - - {t("settingsGeneralSettings")} - {t("distributedUptimeCreateSelectURL")} - - - } - label="URL to monitor" - https={https} - placeholder={"www.google.com"} - disabled={!isCreate} - value={form.url} - name="url" - onChange={handleChange} - error={errors["url"] ? true : false} - helperText={errors["url"]} - /> - - - - - - {t("distributedUptimeCreateChecks")} - - {t("distributedUptimeCreateChecksDescription")} - - - - - - {form.type === "http" || form.type === "distributed_http" ? ( - - - - - ) : ( - "" - )} - - - {errors["type"] ? ( - - - {errors["type"]} - - - ) : ( - "" - )} - - - - - - {t("distributedUptimeCreateIncidentNotification")} - - - {t("distributedUptimeCreateIncidentDescription")} - - - - notification.type === "email" - )} - value={user?.email} - onChange={(event) => handleNotifications(event, "email")} - /> - - - - - - {t("distributedUptimeCreateAdvancedSettings")} - - - - - ); -}; - -export default VisuallyHiddenInput; diff --git a/client/src/Pages/DistributedUptimeStatus/Create/index.jsx b/client/src/Pages/DistributedUptimeStatus/Create/index.jsx deleted file mode 100644 index 308f9489b..000000000 --- a/client/src/Pages/DistributedUptimeStatus/Create/index.jsx +++ /dev/null @@ -1,322 +0,0 @@ -// Components -import { Stack, Typography, Button, Box } from "@mui/material"; -import ConfigBox from "../../../Components/ConfigBox"; -import Checkbox from "../../../Components/Inputs/Checkbox"; -import TextInput from "../../../Components/Inputs/TextInput"; -import VisuallyHiddenInput from "./Components/VisuallyHiddenInput"; -import Image from "../../../Components/Image"; -import LogoPlaceholder from "../../../assets/Images/logo_placeholder.svg"; -import Breadcrumbs from "../../../Components/Breadcrumbs"; -import Search from "../../../Components/Inputs/Search"; -import MonitorList from "../../StatusPage/Create/Components/MonitorList"; -// Utils -import { useTheme } from "@emotion/react"; -import { useState, useEffect } from "react"; -import { useParams } from "react-router-dom"; -import { useCreateStatusPage } from "../../StatusPage/Create/Hooks/useCreateStatusPage"; -import { statusPageValidation } from "../../../Validation/validation"; -import { buildErrors } from "../../../Validation/error"; -import { createToast } from "../../../Utils/toastUtils"; -import { useNavigate } from "react-router-dom"; -import { useMonitorsFetch } from "../../StatusPage/Create/Hooks/useMonitorsFetch"; -import { useTranslation } from "react-i18next"; -import { useFetchDepinStatusPage } from "../../../Hooks/useFetchDepinStatusPage"; -const CreateStatus = () => { - const theme = useTheme(); - const { monitorId, url } = useParams(); - const navigate = useNavigate(); - const { t } = useTranslation(); - const isCreate = typeof url === "undefined"; - - const [createStatusPage, isLoading, networkError] = useCreateStatusPage(isCreate); - - const [statusPageIsLoading, statusPageNetworkError, statusPage, _, isPublished] = - useFetchDepinStatusPage({ - url, - timeFrame: 30, - isCreate, - }); - - const [monitors, monitorsIsLoading, monitorsNetworkError] = useMonitorsFetch(); - - const BREADCRUMBS = [ - { name: "distributed uptime", path: "/distributed-uptime" }, - { - name: "details", - path: `/distributed-uptime/${isCreate ? monitorId : statusPage?.monitors[0]}`, - }, - { name: isCreate ? "create status page" : "edit status page", path: `` }, - ]; - // Local state - const [form, setForm] = useState({ - type: "distributed", - isPublished: false, - url: url ?? Math.floor(Math.random() * 1000000).toFixed(0), - logo: undefined, - companyName: "", - monitors: [monitorId], - }); - const [errors, setErrors] = useState({}); - const [search, setSearch] = useState(""); - const [selectedMonitors, setSelectedMonitors] = useState([]); - - const handleFormChange = (e) => { - const { name, value, checked, type } = e.target; - - // Check for errors - const { error } = statusPageValidation.validate( - { [name]: value }, - { abortEarly: false } - ); - - setErrors((prev) => buildErrors(prev, name, error)); - - if (type === "checkbox") { - setForm({ ...form, [name]: checked }); - return; - } - setForm({ ...form, [name]: value }); - }; - - const handleMonitorsChange = (selectedMonitors) => { - handleFormChange({ - target: { - name: "subMonitors", - value: selectedMonitors.map((monitor) => monitor._id), - }, - }); - setSelectedMonitors(selectedMonitors); - }; - - const handleImageUpload = (e) => { - const img = e.target?.files?.[0]; - setForm((prev) => ({ - ...prev, - logo: img, - })); - }; - const handleSubmit = async () => { - let logoToSubmit = undefined; - - // Handle image - if (typeof form.logo !== "undefined" && typeof form.logo.src === "undefined") { - logoToSubmit = { - src: URL.createObjectURL(form.logo), - name: form.logo.name, - type: form.logo.type, - size: form.logo.size, - }; - } else if (typeof form.logo !== "undefined") { - logoToSubmit = form.logo; - } - const formToSubmit = { ...form }; - if (typeof logoToSubmit !== "undefined") { - formToSubmit.logo = logoToSubmit; - } - // Validate - const { error } = statusPageValidation.validate(formToSubmit, { abortEarly: false }); - if (typeof error === "undefined") { - const success = await createStatusPage({ form: formToSubmit }); - if (success) { - const verb = isCreate ? "created" : "updated"; - createToast({ body: `Status page ${verb} successfully` }); - navigate(`/status/distributed/${form.url}`); - } - return; - } - const newErrors = {}; - error?.details?.forEach((err) => { - newErrors[err.path[0]] = err.message; - }); - setErrors((prev) => ({ ...prev, ...newErrors })); - }; - - // If we are configuring, populate fields - useEffect(() => { - if (isCreate) return; - if (typeof statusPage === "undefined") { - return; - } - - let newLogo = undefined; - if (statusPage.logo) { - newLogo = { - src: `data:${statusPage.logo.contentType};base64,${statusPage.logo.data}`, - name: "logo", - type: statusPage.logo.contentType, - size: null, - }; - } - - setForm((prev) => { - return { - ...prev, - companyName: statusPage?.companyName, - isPublished: statusPage?.isPublished, - timezone: statusPage?.timezone, - monitors: statusPage?.monitors, - subMonitors: statusPage?.subMonitors.map((monitor) => monitor._id), - color: statusPage?.color, - logo: newLogo, - }; - }); - setSelectedMonitors(statusPage?.subMonitors); - }, [isCreate, statusPage]); - - const imgSrc = form?.logo?.src - ? form.logo.src - : form.logo - ? URL.createObjectURL(form.logo) - : undefined; - - return ( - - - - - {isCreate - ? t("distributedUptimeStatusCreateYour") - : t("distributedUptimeStatusEditYour")}{" "} - - - {t("distributedUptimeStatusCreateStatusPage")} - - - - - - {t("distributedUptimeStatusCreateStatusPageAccess")} - - - {t("distributedUptimeStatusCreateStatusPageReady")} - - - - - - - - - - {t("distributedUptimeStatusBasicInfoHeader")} - - - {t("distributedUptimeStatusBasicInfoDescription")} - - - - - - - - - - {t("distributedUptimeStatusLogoHeader")} - - {t("distributedUptimeStatusLogoDescription")}{" "} - - - - Logo - - - - - - - - - {t("distributedUptimeStatusStandardMonitorsHeader")} - - - {t("distributedUptimeStatusStandardMonitorsDescription")} - - - - - - - - - - - - ); -}; - -export default CreateStatus; diff --git a/client/src/Pages/DistributedUptimeStatus/Status/Components/MonitorsList/index.jsx b/client/src/Pages/DistributedUptimeStatus/Status/Components/MonitorsList/index.jsx deleted file mode 100644 index d9ed16e63..000000000 --- a/client/src/Pages/DistributedUptimeStatus/Status/Components/MonitorsList/index.jsx +++ /dev/null @@ -1,66 +0,0 @@ -// Components -import { Stack, Box } from "@mui/material"; -import Host from "../../../../../Components/Host"; -import DePINStatusPageBarChart from "../../../../../Components/Charts/DePINStatusPageBarChart"; -import { StatusLabel } from "../../../../../Components/Label"; - -//Utils -import { useTheme } from "@mui/material/styles"; -import useUtils from "../../../../Uptime/Monitors/Hooks/useUtils"; -import PropTypes from "prop-types"; -const MonitorsList = ({ - isLoading = false, - shouldRender = true, - monitors = [], - timeFrame, -}) => { - const theme = useTheme(); - const { determineState } = useUtils(); - return ( - <> - {monitors?.map((monitor) => { - const status = determineState(monitor); - return ( - - - - - - - - - - - - ); - })} - - ); -}; - -MonitorsList.propTypes = { - monitors: PropTypes.array.isRequired, -}; - -export default MonitorsList; diff --git a/client/src/Pages/DistributedUptimeStatus/Status/Components/Skeleton/index.jsx b/client/src/Pages/DistributedUptimeStatus/Status/Components/Skeleton/index.jsx deleted file mode 100644 index 233fc3c06..000000000 --- a/client/src/Pages/DistributedUptimeStatus/Status/Components/Skeleton/index.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; - -export const SkeletonLayout = () => { - return ( - - - - ); -}; - -export default SkeletonLayout; diff --git a/client/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx b/client/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx deleted file mode 100644 index 7ee4ff292..000000000 --- a/client/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Stack, Button, ButtonGroup } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import { useTranslation } from "react-i18next"; - -const TimeFrameHeader = ({ timeFrame, setTimeFrame, sx, ...props }) => { - const theme = useTheme(); - const { t } = useTranslation(); - return ( - - - - - - - - ); -}; - -export default TimeFrameHeader; diff --git a/client/src/Pages/DistributedUptimeStatus/Status/index.jsx b/client/src/Pages/DistributedUptimeStatus/Status/index.jsx deleted file mode 100644 index 117a297e5..000000000 --- a/client/src/Pages/DistributedUptimeStatus/Status/index.jsx +++ /dev/null @@ -1,319 +0,0 @@ -//Components -import DistributedUptimeMap from "../../DistributedUptime/Details/Components/DistributedUptimeMap"; -import Breadcrumbs from "../../../Components/Breadcrumbs"; -import { Stack, Typography } from "@mui/material"; -import DeviceTicker from "../../DistributedUptime/Details/Components/DeviceTicker"; -import DistributedUptimeResponseChart from "../../DistributedUptime/Details/Components/DistributedUptimeResponseChart"; -import NextExpectedCheck from "../../DistributedUptime/Details/Components/NextExpectedCheck"; -import Footer from "../../DistributedUptime/Details/Components/Footer"; -import StatBoxes from "../../DistributedUptime/Details/Components/StatBoxes"; -import ControlsHeader from "../../StatusPage/Status/Components/ControlsHeader"; -import MonitorTimeFrameHeader from "../../../Components/MonitorTimeFrameHeader"; -import GenericFallback from "../../../Components/GenericFallback"; -import Dialog from "../../../Components/Dialog"; -import SkeletonLayout from "./Components/Skeleton"; -import UptLogo from "../../../assets/icons/upt_logo.png"; -import PeopleAltOutlinedIcon from "@mui/icons-material/PeopleAltOutlined"; -import InfoBox from "../../../Components/InfoBox"; -import StatusHeader from "../../DistributedUptime/Details/Components/StatusHeader"; -import MonitorsList from "./Components/MonitorsList"; -import { RowContainer } from "../../../Components/StandardContainer"; - -//Utils -import { useTheme } from "@mui/material/styles"; -import { useState, useEffect, useRef } from "react"; -import { useParams } from "react-router-dom"; -import { useFetchDepinStatusPage } from "../../../Hooks/useFetchDepinStatusPage"; -import { useSubscribeToDepinDetails } from "../../../Hooks/useSubscribeToDepinDetails"; -import { useStatusPageDelete } from "../../StatusPage/Status/Hooks/useStatusPageDelete"; -import TimeFrameHeader from "./Components/TimeframeHeader"; -import SubHeader from "../../../Components/Subheader"; -import { safelyParseFloat } from "../../../Utils/utils"; -import { useNavigate, useLocation } from "react-router-dom"; -import { useTranslation } from "react-i18next"; -import { useSelector, useDispatch } from "react-redux"; -import { setMode } from "../../../Features/UI/uiSlice"; - -// Responsive -import { useMediaQuery } from "@mui/material"; - -const DistributedUptimeStatus = () => { - const { url } = useParams(); - const location = useLocation(); - const { t } = useTranslation(); - const isPublic = location.pathname.startsWith("/status/distributed/public"); - const elementToCapture = useRef(null); - - // Redux state - const mode = useSelector((state) => state.ui.mode); - const originalModeRef = useRef(null); - - // Local State - const [dateRange, setDateRange] = useState("recent"); - const [isDeleteOpen, setIsDeleteOpen] = useState(false); - const [timeFrame, setTimeFrame] = useState(30); - // Utils - const theme = useTheme(); - const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm")); - const navigate = useNavigate(); - const dispatch = useDispatch(); - - const [ - statusPageIsLoading, - statusPageNetworkError, - statusPage, - monitorId, - isPublished, - ] = useFetchDepinStatusPage({ - url, - timeFrame, - }); - - const [isLoading, networkError, connectionStatus, monitor, lastUpdateTrigger] = - useSubscribeToDepinDetails({ monitorId, dateRange, isPublic, isPublished }); - - const [deleteStatusPage, isDeleting] = useStatusPageDelete(() => { - navigate("/distributed-uptime"); - }, url); - // Constants - const BREADCRUMBS = [ - { name: "Distributed Uptime", path: "/distributed-uptime" }, - { name: "details", path: `/distributed-uptime/${monitorId}` }, - { name: "status", path: `` }, - ]; - - let sx = {}; - if (isPublic) { - sx = { - paddingTop: "10vh", - paddingRight: "10vw", - paddingBottom: "10vh", - paddingLeft: "10vw", - }; - } - - // Default to dark mode - useEffect(() => { - const cleanup = () => { - if (originalModeRef.current === null) { - originalModeRef.current = mode; - } - - if (isPublic) { - dispatch(setMode(originalModeRef.current)); - } - }; - - if (isPublic) { - dispatch(setMode("dark")); - } - - window.addEventListener("beforeunload", cleanup); - return () => { - window.removeEventListener("beforeunload", cleanup); - }; - }, [dispatch, isPublic]); - - // Done loading, a status page doesn't exist - if (!statusPageIsLoading && typeof statusPage === "undefined") { - return ( - - - - {t("distributedUptimeStatusPageNotSetUp")} - - {t("distributedUptimeStatusContactAdmin")} - - - ); - } - - // Done loading, a status page exists but is not public - if (!statusPageIsLoading && isPublic && statusPage.isPublished === false) { - return ( - - - {t("distributedUptimeStatusPageNotPublic")} - - - ); - } - - if (isLoading || statusPageIsLoading) { - return ; - } - - if (networkError || statusPageNetworkError) { - return ( - - - {t("networkError")} - - {t("checkConnection")} - - ); - } - - if ( - typeof statusPage === "undefined" || - typeof monitor === "undefined" || - monitor.totalChecks === 0 - ) { - return ( - - - - {t("distributedUptimeDetailsNoMonitorHistory")} - - - ); - } - - return ( - - {!isPublic && } - - - - - - - - - {t("distributedRightCategoryTitle")} - - {statusPage.companyName} - - - - - - - - - - - - - - - - - - - - - 0} - direction={{ s: "column", md: "row" }} - headerText={t("distributedStatusServerMonitors")} - subHeaderText={t("distributedStatusServerMonitorsDescription")} - gap={isSmallScreen ? theme.spacing(10) : 0} - alignItems={{ s: "flex-start", md: "flex-end" }} - > - - - - -