diff --git a/client/src/Components/v2/inputs/ColorPicker.tsx b/client/src/Components/v2/inputs/ColorPicker.tsx
new file mode 100644
index 000000000..f52e66317
--- /dev/null
+++ b/client/src/Components/v2/inputs/ColorPicker.tsx
@@ -0,0 +1,48 @@
+import { MuiColorInput } from "mui-color-input";
+import type { MuiColorInputProps } from "mui-color-input";
+import { typographyLevels } from "@/Utils/Theme/v2Palette";
+import { useTheme } from "@mui/material";
+import Stack from "@mui/material/Stack";
+import { FieldLabel } from "@/Components/v2/inputs/FieldLabel";
+
+interface ColorPickerProps extends MuiColorInputProps {
+ fieldLabel?: string;
+ required?: boolean;
+}
+
+export const ColorInput = ({ fieldLabel, required, ...props }: ColorPickerProps) => {
+ const theme = useTheme();
+ const input = (
+
+ );
+ if (fieldLabel) {
+ return (
+
+ {fieldLabel}
+ {input}
+
+ );
+ }
+
+ return input;
+};
diff --git a/client/src/Components/v2/inputs/index.tsx b/client/src/Components/v2/inputs/index.tsx
index ad7c984bd..fa04903c9 100644
--- a/client/src/Components/v2/inputs/index.tsx
+++ b/client/src/Components/v2/inputs/index.tsx
@@ -13,3 +13,4 @@ export * from "./Radio";
export * from "./Switch";
export * from "./Slider";
export * from "./ImageUpload";
+export * from "./ColorPicker";
diff --git a/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx b/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx
deleted file mode 100644
index 349571fe8..000000000
--- a/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx
+++ /dev/null
@@ -1,110 +0,0 @@
-// Components
-import { Stack, Typography } from "@mui/material";
-import Icon from "@/Components/v1/Icon";
-
-// Utils
-import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
-import { useTheme } from "@emotion/react";
-const MonitorListItem = ({
- monitor,
- innerRef,
- draggableProps,
- dragHandleProps,
- onDelete,
-}) => {
- const theme = useTheme();
- return (
-
-
- {monitor.name}
- {
- onDelete(monitor);
- }}
- />
-
- );
-};
-
-const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => {
- const onDelete = (monitorToDelete) => {
- const newMonitors = selectedMonitors.filter(
- (monitor) => monitor.id !== monitorToDelete.id
- );
- setSelectedMonitors(newMonitors);
- };
- const reorder = (list, startIndex, endIndex) => {
- const result = Array.from(list);
- const [removed] = result.splice(startIndex, 1);
- result.splice(endIndex, 0, removed);
-
- return result;
- };
-
- const onDragEnd = (result) => {
- // dropped outside the list
- if (!result.destination) {
- return;
- }
-
- const reorderedMonitors = reorder(
- selectedMonitors,
- result.source.index,
- result.destination.index
- );
-
- setSelectedMonitors(reorderedMonitors);
- };
-
- return (
-
-
- {(provided, snapshot) => (
-
- {selectedMonitors?.map((monitor, index) => (
-
- {(provided, snapshot) => (
-
- )}
-
- ))}
- {provided.placeholder}
-
- )}
-
-
- );
-};
-
-export default MonitorList;
diff --git a/client/src/Pages/StatusPage/Create/Components/Progress/index.jsx b/client/src/Pages/StatusPage/Create/Components/Progress/index.jsx
deleted file mode 100644
index 594fd9709..000000000
--- a/client/src/Pages/StatusPage/Create/Components/Progress/index.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Button, Box } from "@mui/material";
-import ProgressUpload from "@/Components/v1/ProgressBars/index.jsx";
-import Icon from "@/Components/v1/Icon";
-import { useTranslation } from "react-i18next";
-import { formatBytes } from "../../../../../Utils/fileUtils.js";
-const Progress = ({ isLoading, progressValue, logo, logoType, removeLogo, errors }) => {
- const { t } = useTranslation();
- if (isLoading) {
- return (
-
- }
- label={logo?.name}
- size={formatBytes(logo?.size)}
- progress={progressValue}
- onClick={removeLogo}
- />
- );
- }
-
- if (logo && logoType) {
- return (
-
-
-
- );
- }
-};
-
-export default Progress;
diff --git a/client/src/Pages/StatusPage/Create/Components/Skeleton/index.jsx b/client/src/Pages/StatusPage/Create/Components/Skeleton/index.jsx
deleted file mode 100644
index 482c490fb..000000000
--- a/client/src/Pages/StatusPage/Create/Components/Skeleton/index.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Stack, Skeleton } from "@mui/material";
-
-const SkeletonLayout = () => {
- return (
-
-
-
- );
-};
-
-export default SkeletonLayout;
diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx
deleted file mode 100644
index f31c456ef..000000000
--- a/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Stack, Typography } from "@mui/material";
-import ConfigBox from "@/Components/v1/ConfigBox/index.jsx";
-import PropTypes from "prop-types";
-import { useTheme } from "@emotion/react";
-
-// This can be used to add any extra/additional section/stacks on top of existing sections on the tab
-const ConfigStack = ({ title, description, children }) => {
- const theme = useTheme();
- return (
-
-
-
- {title}
-
- {description}
-
- {children}
-
- );
-};
-
-ConfigStack.propTypes = {
- title: PropTypes.string.isRequired, // Title must be a string and is required
- description: PropTypes.string.isRequired, // Description must be a string and is required
- children: PropTypes.node.isRequired,
-};
-
-export default ConfigStack;
diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx
deleted file mode 100644
index e84de16dc..000000000
--- a/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx
+++ /dev/null
@@ -1,107 +0,0 @@
-// Components
-import { Stack, Typography } from "@mui/material";
-import { TabPanel } from "@mui/lab";
-import MonitorList from "../MonitorList/index.jsx";
-import Search from "@/Components/v1/Inputs/Search/index.jsx";
-import Checkbox from "@/Components/v1/Inputs/Checkbox/index.jsx";
-// Utils
-import { useState } from "react";
-import { useTheme } from "@emotion/react";
-import { useTranslation } from "react-i18next";
-import ConfigStack from "./ConfigStack.jsx";
-const Content = ({
- tabValue,
- form,
- monitors,
- handleFormChange,
- errors,
- selectedMonitors,
- setSelectedMonitors,
-}) => {
- // Local state
- const [search, setSearch] = useState("");
-
- // Handlers
- const handleMonitorsChange = (selectedMonitors) => {
- handleFormChange({
- target: { name: "monitors", value: selectedMonitors.map((monitor) => monitor.id) },
- });
- setSelectedMonitors(selectedMonitors);
- };
-
- // Utils
- const theme = useTheme();
- const { t } = useTranslation();
-
- return (
-
-
-
-
-
-
-
-
- {errors["monitors"]}
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default Content;
diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
deleted file mode 100644
index d4c583d3a..000000000
--- a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
+++ /dev/null
@@ -1,187 +0,0 @@
-// Components
-import { Stack, Typography } from "@mui/material";
-import { TabPanel } from "@mui/lab";
-import ConfigBox from "@/Components/v1/ConfigBox/index.jsx";
-import Checkbox from "@/Components/v1/Inputs/Checkbox/index.jsx";
-import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
-import Search from "@/Components/v1/Inputs/Search/index.jsx";
-import ImageUpload from "@/Components/v1/Inputs/ImageUpload/index.jsx";
-import ColorPicker from "@/Components/v1/Inputs/ColorPicker/index.jsx";
-import Progress from "../Progress/index.jsx";
-
-// Utils
-import { useTheme } from "@emotion/react";
-import timezones from "../../../../../Utils/timezones.json";
-import PropTypes from "prop-types";
-import { useTranslation } from "react-i18next";
-import { useMemo, useState, useCallback } from "react";
-
-const TabSettings = ({
- isCreate,
- tabValue,
- form,
- handleFormChange,
- handleImageChange,
- progress,
- removeLogo,
- errors,
-}) => {
- // Utils
- const theme = useTheme();
- const { t } = useTranslation();
- const [rawInput, setRawInput] = useState("");
-
- const selectedTimezone = useMemo(
- () => timezones.find((tz) => tz._id === form.timezone) ?? null,
- [form.timezone]
- );
-
- const handleTimezoneChange = useCallback(
- (newValue) => {
- setRawInput("");
- handleFormChange({
- target: {
- name: "timezone",
- value: newValue?._id ?? "",
- },
- });
- },
- [handleFormChange]
- );
-
- return (
-
-
-
-
-
- {t("access")}
-
- {t("statusPageCreateSettings")}
-
-
-
-
-
-
-
-
- {t("basicInformation")}
-
-
- {t("statusPageCreateBasicInfoDescription")}
-
-
-
-
-
-
-
-
-
-
- {t("timezone")}
-
-
- {t("statusPageCreateSelectTimeZoneDescription")}
-
-
-
- setRawInput(newVal)}
- handleChange={handleTimezoneChange}
- isAdorned={true}
- unit="timezone"
- />
-
-
-
-
-
- {t("statusPageCreateAppearanceTitle")}
-
-
- {t("statusPageCreateAppearanceDescription")}
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-TabSettings.propTypes = {
- isCreate: PropTypes.bool,
- tabValue: PropTypes.string,
- form: PropTypes.object,
- handleFormChange: PropTypes.func,
- handleImageChange: PropTypes.func,
- progress: PropTypes.object,
- removeLogo: PropTypes.func,
- errors: PropTypes.object,
-};
-
-export default TabSettings;
diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx
deleted file mode 100644
index e8669c474..000000000
--- a/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx
+++ /dev/null
@@ -1,99 +0,0 @@
-// Components
-import { TabContext } from "@mui/lab";
-import { Tab } from "@mui/material";
-import Settings from "./Settings.jsx";
-import Content from "./Content.jsx";
-
-// Utils
-import PropTypes from "prop-types";
-import CustomTabList from "@/Components/v1/Tab/index.jsx";
-
-const Tabs = ({
- isCreate,
- form,
- errors,
- monitors,
- selectedMonitors,
- setSelectedMonitors,
- handleFormChange,
- handleImageChange,
- progress,
- removeLogo,
- tab,
- setTab,
- TAB_LIST,
- handleDelete,
- isDeleteOpen,
- setIsDeleteOpen,
- isDeleting,
- isLoading,
-}) => {
- return (
-
- {
- setTab(TAB_LIST.indexOf(selected));
- }}
- aria-label="status page tabs"
- >
- {TAB_LIST.map((tabLabel) => (
-
- ))}
-
- {tab === 0 ? (
-
- ) : (
-
- )}
-
- );
-};
-
-Tabs.propTypes = {
- isCreate: PropTypes.bool,
- form: PropTypes.object,
- errors: PropTypes.object,
- monitors: PropTypes.array,
- selectedMonitors: PropTypes.array,
- setSelectedMonitors: PropTypes.func,
- handleFormChange: PropTypes.func,
- handleImageChange: PropTypes.func,
- progress: PropTypes.object,
- removeLogo: PropTypes.func,
- tab: PropTypes.number,
- setTab: PropTypes.func,
- TAB_LIST: PropTypes.array,
- handleDelete: PropTypes.func,
- isDeleteOpen: PropTypes.bool,
- setIsDeleteOpen: PropTypes.func,
- isDeleting: PropTypes.bool,
- isLoading: PropTypes.bool,
-};
-
-export default Tabs;
diff --git a/client/src/Pages/StatusPage/Create/Hooks/useCreateStatusPage.jsx b/client/src/Pages/StatusPage/Create/Hooks/useCreateStatusPage.jsx
deleted file mode 100644
index c0bcf5ab4..000000000
--- a/client/src/Pages/StatusPage/Create/Hooks/useCreateStatusPage.jsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useState } from "react";
-import { networkService } from "../../../../main.jsx";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
-
-const useCreateStatusPage = (isCreate) => {
- const [isLoading, setIsLoading] = useState(false);
- const [networkError, setNetworkError] = useState(false);
- const createStatusPage = async ({ form, id }) => {
- setIsLoading(true);
- try {
- await networkService.createStatusPage({ form, isCreate, id });
- return true;
- } catch (error) {
- setNetworkError(true);
- createToast({ body: error?.response?.data?.msg ?? error.message });
- return false;
- } finally {
- setIsLoading(false);
- }
- };
-
- return [createStatusPage, isLoading, networkError];
-};
-
-export { useCreateStatusPage };
diff --git a/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx b/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx
deleted file mode 100644
index 03ebb07bf..000000000
--- a/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { useEffect, useState } from "react";
-import { networkService } from "../../../../main.jsx";
-import { useSelector } from "react-redux";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
-
-const useMonitorsFetch = () => {
- const { user } = useSelector((state) => state.auth);
-
- const [monitors, setMonitors] = useState(undefined);
- const [isLoading, setIsLoading] = useState(true);
- const [networkError, setNetworkError] = useState(false);
- useEffect(() => {
- const fetchMonitors = async () => {
- try {
- const response = await networkService.getMonitorsByTeamId({
- limit: null, // donot return any checks for the monitors
- types: ["http", "ping", "port", "game"], // include game servers in status page monitor selection
- });
- setMonitors(response.data.data);
- } catch (error) {
- setNetworkError(true);
- createToast({ body: error.message });
- } finally {
- setIsLoading(false);
- }
- };
- fetchMonitors();
- }, [user]);
-
- return [monitors, isLoading, networkError];
-};
-
-export { useMonitorsFetch };
diff --git a/client/src/Pages/StatusPage/Create/index.tsx b/client/src/Pages/StatusPage/Create/index.tsx
index 83286277b..f5eff80ca 100644
--- a/client/src/Pages/StatusPage/Create/index.tsx
+++ b/client/src/Pages/StatusPage/Create/index.tsx
@@ -14,6 +14,7 @@ import {
Autocomplete,
Checkbox,
Dialog,
+ ColorInput,
} from "@/Components/v2/inputs";
import { useTheme } from "@mui/material/styles";
@@ -29,7 +30,6 @@ import type { StatusPageResponse } from "@/Types/StatusPage";
import timezones from "@/Utils/timezones.json";
import { useNavigate, useParams } from "react-router-dom";
import axios from "axios";
-import { MuiColorInput } from "mui-color-input";
import { HeaderConfigStatusControls } from "./Components/HeaderConfigStatusControls";
interface TimezoneOption {
@@ -393,11 +393,11 @@ const CreateStatusPage = () => {
name="color"
control={control}
render={({ field }) => (
-
)}
/>
diff --git a/client/src/Pages/StatusPage/Create/old.jsx b/client/src/Pages/StatusPage/Create/old.jsx
deleted file mode 100644
index c5aee4b0a..000000000
--- a/client/src/Pages/StatusPage/Create/old.jsx
+++ /dev/null
@@ -1,311 +0,0 @@
-// Components
-import { Stack, Button, Typography } from "@mui/material";
-import Tabs from "./Components/Tabs/index.jsx";
-import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
-import SkeletonLayout from "./Components/Skeleton/index.jsx";
-import Dialog from "@/Components/v1/Dialog/index.jsx";
-import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
-//Utils
-import { useTheme } from "@emotion/react";
-import { useState, useEffect, useRef, useCallback } from "react";
-import { statusPageValidation } from "../../../Validation/validation.js";
-import { buildErrors } from "../../../Validation/error.js";
-import { useMonitorsFetch } from "./Hooks/useMonitorsFetch.jsx";
-import { useCreateStatusPage } from "./Hooks/useCreateStatusPage.jsx";
-import { createToast } from "../../../Utils/toastUtils.jsx";
-import { useNavigate } from "react-router-dom";
-import { useStatusPageFetch } from "../Status/Hooks/useStatusPageFetch.jsx";
-import { useParams } from "react-router-dom";
-import { useTranslation } from "react-i18next";
-//Constants
-const ERROR_TAB_MAPPING = [
- ["companyName", "url", "timezone", "color", "isPublished", "logo"],
- ["monitors", "showUptimePercentage", "showCharts", "showAdminLoginLink"],
-];
-
-const CreateStatusPage = () => {
- const { url } = useParams();
- //Local state
- const [tab, setTab] = useState(0);
- const [progress, setProgress] = useState({ value: 0, isLoading: false });
- const [isDeleteOpen, setIsDeleteOpen] = useState(false);
- const [form, setForm] = useState({
- isPublished: false,
- companyName: "",
- url: url ?? Math.floor(Math.random() * 1000000).toFixed(0),
- logo: undefined,
- timezone: "America/Toronto",
- color: "#4169E1",
- type: "uptime",
- monitors: [],
- showCharts: true,
- showUptimePercentage: true,
- showAdminLoginLink: false,
- });
- const [errors, setErrors] = useState({});
- const [selectedMonitors, setSelectedMonitors] = useState([]);
- // Refs
- const intervalRef = useRef(null);
-
- // Setup
- const isCreate = typeof url === "undefined";
-
- //Utils
- const theme = useTheme();
- const [monitors, isLoading, networkError] = useMonitorsFetch();
- const navigate = useNavigate();
- const { t } = useTranslation();
-
- const [createStatusPage] = useCreateStatusPage(isCreate);
- const [statusPage, statusPageMonitors, statusPageIsLoading, , fetchStatusPage] =
- useStatusPageFetch(isCreate, url);
- // const [deleteStatusPage, isDeleting] = useStatusPageDelete(fetchStatusPage, url);
-
- // Handlers
- const handleFormChange = (e) => {
- let { type, name, value, checked } = e.target;
- // Handle errors
- const { error } = statusPageValidation.validate(
- { [name]: value },
- { abortEarly: false }
- );
- setErrors((prev) => {
- return buildErrors(prev, name, error);
- });
-
- //Handle checkbox
- if (type === "checkbox") {
- setForm((prev) => ({
- ...prev,
- [name]: checked,
- }));
- return;
- }
-
- // Handle other inputs
- setForm((prev) => ({
- ...prev,
- [name]: value,
- }));
- };
-
- const handleImageChange = useCallback((fileObj) => {
- if (!fileObj || !fileObj.file) return;
-
- setForm((prev) => ({
- ...prev,
- logo: {
- src: fileObj.src,
- name: fileObj.name,
- type: fileObj.file.type,
- size: fileObj.file.size,
- },
- }));
-
- intervalRef.current = setInterval(() => {
- const buffer = 12;
- setProgress((prev) => {
- if (prev.value + buffer >= 100) {
- clearInterval(intervalRef.current);
- return { value: 100, isLoading: false };
- }
- return { ...prev, value: prev.value + buffer };
- });
- }, 120);
- }, []);
-
- const removeLogo = () => {
- setForm((prev) => ({
- ...prev,
- logo: undefined,
- }));
- // interrupt interval if image upload is canceled prior to completing the process
- clearInterval(intervalRef.current);
- setProgress({ value: 0, isLoading: false });
- };
-
- /**
- * Handle status page deletion with optimistic UI update
- * Immediately navigates away without waiting for the deletion to complete
- * to prevent unnecessary network requests for the deleted page
- */
- const handleDelete = async () => {
- setIsDeleteOpen(false);
- // Start deletion process but don't wait for it
- // deleteStatusPage();
- // Immediately navigate away to prevent additional fetches for the deleted page
- navigate("/status");
- };
-
- const handleSubmit = async () => {
- let toSubmit = {
- ...form,
- logo: { type: form.logo?.type ?? null, size: form.logo?.size ?? null },
- };
-
- const { error } = statusPageValidation.validate(toSubmit, {
- abortEarly: false,
- });
-
- if (typeof error === "undefined") {
- const success = await createStatusPage({ form, id: statusPage?.id });
- if (success) {
- createToast({
- body: isCreate ? t("statusPage.createSuccess") : t("statusPage.updateSuccess"),
- });
- navigate(`/status/uptime/${form.url}`);
- }
- return;
- }
-
- const newErrors = {};
- error?.details?.forEach((err) => {
- newErrors[err.path[0]] = err.message;
- });
- setErrors((prev) => ({ ...prev, ...newErrors }));
- const errorTabs = Object.keys(newErrors).map((err) => {
- return ERROR_TAB_MAPPING.findIndex((tab) => tab.includes(err));
- });
-
- // If there's an error in the current tab, don't change the tab
- if (errorTabs.some((errorTab) => errorTab === tab)) {
- return;
- }
-
- // If we get -1, there's an unknown error
- if (errorTabs[0] === -1) {
- createToast({ body: t("common.toasts.unknownError") });
- return;
- }
-
- // Otherwise go to tab with error
- setTab(errorTabs[0]);
- };
-
- // If we are configuring, populate fields
- useEffect(() => {
- if (isCreate) return;
- if (typeof statusPage === "undefined") {
- return;
- }
-
- let newLogo = undefined;
- if (statusPage.logo && Object.keys(statusPage.logo).length > 0) {
- 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: statusPageMonitors.map((monitor) => monitor.id),
- color: statusPage?.color,
- logo: newLogo,
- showCharts: statusPage?.showCharts ?? true,
- showUptimePercentage: statusPage?.showUptimePercentage ?? true,
- showAdminLoginLink: statusPage?.showAdminLoginLink ?? false,
- };
- });
- setSelectedMonitors(statusPageMonitors);
- }, [isCreate, statusPage, statusPageMonitors]);
-
- if (networkError === true) {
- return (
-
-
- {t("common.toasts.networkError")}
-
- {t("common.toasts.checkConnection")}
-
- );
- }
-
- if (isLoading) return ;
-
- // Load fields
- return (
-
-
- {!isCreate && (
-
-
-
- )}
-
-
-
-
-
- );
-};
-
-export default CreateStatusPage;
diff --git a/client/src/Pages/StatusPage/Status/Hooks/useStatusPageDelete.jsx b/client/src/Pages/StatusPage/Status/Hooks/useStatusPageDelete.jsx
deleted file mode 100644
index 73b9a8a5f..000000000
--- a/client/src/Pages/StatusPage/Status/Hooks/useStatusPageDelete.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { useState } from "react";
-import { networkService } from "../../../../Utils/NetworkService.js";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
-import { useTranslation } from "react-i18next";
-
-/**
- * Hook for deleting a status page with optimistic UI update
- * @param {Function} fetchStatusPage - Function to fetch status page data
- * @param {string} url - URL of the status page
- * @returns {Array} - [deleteStatusPage function, isLoading state]
- */
-const useStatusPageDelete = (fetchStatusPage, url) => {
- const [isLoading, setIsLoading] = useState(false);
- const { t } = useTranslation();
-
- /**
- * Delete a status page with optimistic UI update
- * @returns {Promise} - Success status
- */
- const deleteStatusPage = async () => {
- // We don't need to call fetchStatusPage after deletion
- // This prevents the 404 error when trying to fetch a deleted status page
- try {
- setIsLoading(true);
- await networkService.deleteStatusPage({ url });
- createToast({
- body: t("statusPage.deleteSuccess", "Status page deleted successfully"),
- });
- return true;
- } catch (error) {
- createToast({
- body: t("statusPage.deleteFailed", "Failed to delete status page"),
- });
- return false;
- } finally {
- setIsLoading(false);
- }
- };
-
- return [deleteStatusPage, isLoading];
-};
-
-export { useStatusPageDelete };
diff --git a/client/src/Pages/StatusPage/Status/Hooks/useStatusPageFetch.jsx b/client/src/Pages/StatusPage/Status/Hooks/useStatusPageFetch.jsx
deleted file mode 100644
index 7db6b6c5e..000000000
--- a/client/src/Pages/StatusPage/Status/Hooks/useStatusPageFetch.jsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { useEffect, useState, useCallback } from "react";
-import { networkService } from "../../../../main.jsx";
-import { useSelector } from "react-redux";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
-import { useTheme } from "@emotion/react";
-import { useMonitorUtils } from "../../../../Hooks/useMonitorUtils.js";
-
-const useStatusPageFetch = (isCreate = false, url) => {
- const [isLoading, setIsLoading] = useState(true);
- const [networkError, setNetworkError] = useState(false);
- const [statusPage, setStatusPage] = useState(undefined);
- const [monitors, setMonitors] = useState(undefined);
- const theme = useTheme();
- const { getMonitorWithPercentage } = useMonitorUtils();
- const fetchStatusPage = useCallback(async () => {
- try {
- const response = await networkService.getStatusPageByUrl({
- url,
- type: "uptime",
- });
- if (!response?.data?.data) return;
- const { statusPage, monitors } = response.data.data;
- setStatusPage(statusPage);
-
- const monitorsWithPercentage = monitors.map((monitor) =>
- getMonitorWithPercentage(monitor, theme)
- );
-
- setMonitors(monitorsWithPercentage);
- } catch (error) {
- // If there is a 404, status page is not found
- if (error?.response?.status === 404) {
- setStatusPage(undefined);
- return;
- }
- createToast({ body: error.message });
- setNetworkError(true);
- } finally {
- setIsLoading(false);
- }
- }, [theme, getMonitorWithPercentage, url]);
-
- useEffect(() => {
- if (isCreate === true) {
- return;
- }
- fetchStatusPage();
- }, [isCreate, fetchStatusPage]);
-
- return [statusPage, monitors, isLoading, networkError, fetchStatusPage];
-};
-
-export { useStatusPageFetch };
diff --git a/client/src/locales/en.json b/client/src/locales/en.json
index 04eca42b0..a26f1808e 100644
--- a/client/src/locales/en.json
+++ b/client/src/locales/en.json
@@ -359,7 +359,6 @@
"errors": "Errors",
"expectedValue": "Expected value",
"failedToSendEmail": "Failed to send email",
- "features": "Features",
"FirstName": "First name",
"frequency": "Frequency",
"friendlyNameInput": "Friendly name",
@@ -1044,7 +1043,6 @@
},
"rate": "Rate",
"remove": "Remove",
- "removeLogo": "Remove Logo",
"repeat": "Repeat",
"reset": "Reset",
"response": "RESPONSE",
@@ -1058,7 +1056,6 @@
},
"save": "Save",
"selectAll": "Select all",
- "settingsDisplayTimezone": "Display timezone",
"settingsFailedToClearStats": "Failed to clear stats",
"settingsFailedToDeleteMonitors": "Failed to delete all monitors",
"settingsFailedToSave": "Failed to save settings",
@@ -1151,25 +1148,18 @@
"settingsTestEmailFailedWithReason": "Failed to send test email: {{reason}}",
"settingsTestEmailSuccess": "Test email sent successfully",
"settingsTestEmailUnknownError": "Unknown error",
- "showAdminLoginLink": "Show \"Administrator? Login Here\" link on the status page",
- "showCharts": "Show charts",
"shown": "Shown",
- "showUptimePercentage": "Show uptime percentage",
"starPromptDescription": "See the latest releases and help grow the community on GitHub",
"starPromptTitle": "Star Checkmate",
"startTime": "Start time",
"state": "State",
"status": "Status",
- "statusBreadCrumbsDetails": "Details",
- "statusBreadCrumbsStatusPages": "Status Pages",
"statusCode": "Status code",
"statusPage": {
"contents": "Contents",
- "createSuccess": "Status page created successfully",
"deleteFailed": "Failed to delete status page",
"deleteSuccess": "Status page deleted successfully",
"generalSettings": "General settings",
- "updateSuccess": "Status page updated successfully",
"details": {
"statusHeader": {
"allUp": "All systems operational",
@@ -1181,16 +1171,6 @@
"statusPageCreate": {
"buttonSave": "Save"
},
- "statusPageCreateAppearanceDescription": "Define the default look and feel of your public status page.",
- "statusPageCreateAppearanceTitle": "Appearance",
- "statusPageCreateBasicInfoDescription": "Define company name and the subdomain that your status page points to.",
- "statusPageCreateBasicInfoStatusPageAddress": "Your status page address",
- "statusPageCreateSelectTimeZoneDescription": "Select the timezone that your status page will be displayed in.",
- "statusPageCreateSettings": "If your status page is ready, you can mark it as published.",
- "statusPageCreateSettingsCheckboxLabel": "Published and visible to the public",
- "statusPageCreateTabsContent": "Status page servers",
- "statusPageCreateTabsContentDescription": "You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience.",
- "statusPageCreateTabsContentFeaturesDescription": "Show more details on the status page",
"statusPageStatusServiceStatus": "Service status",
"submit": "Submit",
"SupportedFormats": "Supported formats",