diff --git a/client/src/Components/v2/monitors/HeaderMonitorControls.tsx b/client/src/Components/v2/monitors/HeaderMonitorControls.tsx index d1a0d078d..6d321cbb8 100644 --- a/client/src/Components/v2/monitors/HeaderMonitorControls.tsx +++ b/client/src/Components/v2/monitors/HeaderMonitorControls.tsx @@ -95,7 +95,7 @@ export const HeaderMonitorControls = ({ await refetch(); }} > - {monitor?.isActive ? t("pause") : t("resume")} + {monitor?.isActive ? t("common.buttons.pause") : t("common.buttons.resume")} )} {isAdmin && ( @@ -105,7 +105,7 @@ export const HeaderMonitorControls = ({ startIcon={} onClick={() => navigate(`/${path}/configure/${monitor.id}`)} > - Configure + {t("common.buttons.configure")} )} @@ -155,7 +155,7 @@ export const HeaderDeleteControls = ({ await refetch(); }} > - {monitor?.isActive ? t("pause") : t("resume")} + {monitor?.isActive ? t("common.buttons.pause") : t("common.buttons.resume")} )} {isAdmin && ( diff --git a/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx b/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx new file mode 100644 index 000000000..87349d703 --- /dev/null +++ b/client/src/Pages/StatusPage/Status/Components/HeaderStatusPageControls.tsx @@ -0,0 +1,87 @@ +import Stack from "@mui/material/Stack"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { Icon } from "@/Components/v2/design-elements"; +import { Button } from "@/Components/v2/inputs"; +import { Settings, ExternalLink } from "lucide-react"; + +import { useTheme } from "@mui/material"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import type { StatusPage } from "@/Types/StatusPage"; + +interface HeaderStatusPageControlsProps { + isAdmin: boolean; + statusPage: StatusPage; + isPublic?: boolean; +} +export const HeaderStatusPageControls = ({ + isAdmin, + statusPage, + isPublic = false, +}: HeaderStatusPageControlsProps) => { + const theme = useTheme(); + const navigate = useNavigate(); + const { t } = useTranslation(); + return ( + + + + {statusPage?.companyName} + + {statusPage?.isPublished && !isPublic && ( + <> + { + window.open( + `/status/uptime/public/${statusPage.url}`, + "_blank", + "noopener,noreferrer" + ); + }} + sx={{ + borderBottom: 1, + borderColor: "transparent", + ":hover": { + cursor: "pointer", + borderBottom: 1, + }, + }} + > + {t("publicLink")} + + + + + + )} + + {isAdmin && ( + + )} + + ); +}; diff --git a/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx b/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx new file mode 100644 index 000000000..c5aca4754 --- /dev/null +++ b/client/src/Pages/StatusPage/Status/Components/StatusBar.tsx @@ -0,0 +1,62 @@ +import { AlertTriangle, CircleCheck } from "lucide-react"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; + +import { useTranslation } from "react-i18next"; +import type { Theme } from "@mui/material"; +import { useTheme } from "@mui/material"; +import type { Monitor } from "@/Types/Monitor"; + +const getMonitorStatus = (monitors: Monitor[], theme: Theme, t: Function) => { + const monitorsStatus: Record = { + icon: , + }; + + if (monitors.every((monitor) => monitor.status === true)) { + monitorsStatus.msg = t("pages.statusPages.statusBar.allUp"); + monitorsStatus.color = theme.palette.success.main; + monitorsStatus.icon = ; + } + + if (monitors.every((monitor) => monitor.status === false)) { + monitorsStatus.msg = t("pages.statusPages.statusBar.allDown"); + monitorsStatus.color = theme.palette.error.main; + } + + if (monitors.some((monitor) => monitor.status === false)) { + monitorsStatus.msg = t("pages.statusPages.statusBar.degraded"); + monitorsStatus.color = theme.palette.warning.main; + } + + // Paused or unknown + if (monitors.some((monitor) => typeof monitor.status === "undefined")) { + monitorsStatus.msg = t("pages.statusPages.statusBar.unknown"); + monitorsStatus.color = theme.palette.warning.main; + } + return monitorsStatus; +}; + +interface StatusBarProps { + monitors: Monitor[]; +} + +export const StatusBar = ({ monitors }: StatusBarProps) => { + const theme = useTheme(); + const { t } = useTranslation(); + const monitorsStatus = getMonitorStatus(monitors, theme, t); + + return ( + + {monitorsStatus.icon} + {monitorsStatus.msg} + + ); +}; diff --git a/client/src/Pages/StatusPage/Status/index.tsx b/client/src/Pages/StatusPage/Status/index.tsx new file mode 100644 index 000000000..d35503011 --- /dev/null +++ b/client/src/Pages/StatusPage/Status/index.tsx @@ -0,0 +1,51 @@ +import { BasePage } from "@/Components/v2/design-elements"; +import { StatusBar } from "@/Pages/StatusPage/Status/Components/StatusBar"; +import Typography from "@mui/material/Typography"; + +import { useTranslation } from "react-i18next"; +import { useIsAdmin } from "@/Hooks/useIsAdmin"; +import { useLocation, useParams } from "react-router-dom"; +import { useGet } from "@/Hooks/UseApi"; +import type { StatusPageResponse } from "@/Types/StatusPage"; +import { HeaderStatusPageControls } from "./Components/HeaderStatusPageControls"; + +const StatusPageView = () => { + const { t } = useTranslation(); + const { url } = useParams(); + const isAdmin = useIsAdmin(); + const location = useLocation(); + const isPublic = location.pathname.startsWith("/status/uptime/public"); + + const apiUrl = url ? `/status-page/${url}?type=uptime` : null; + + const { data, isLoading, error } = useGet(apiUrl); + + const statusPage = data?.statusPage; + const monitors = data?.monitors ?? []; + + if (!statusPage || !monitors) { + return null; + } + + if (monitors.length === 0) { + return "poo"; + } + + return ( + + + {t("statusPageStatusServiceStatus")} + +
 {JSON.stringify(data, null, 2)}
+
+ ); +}; + +export default StatusPageView; diff --git a/client/src/Pages/StatusPage/Status/index.jsx b/client/src/Pages/StatusPage/Status/old.jsx similarity index 100% rename from client/src/Pages/StatusPage/Status/index.jsx rename to client/src/Pages/StatusPage/Status/old.jsx diff --git a/client/src/Routes/index.jsx b/client/src/Routes/index.jsx index aec872a0f..bbba8eac0 100644 --- a/client/src/Routes/index.jsx +++ b/client/src/Routes/index.jsx @@ -38,7 +38,7 @@ import Incidents from "../Pages/Incidents/"; // Status pages import CreateStatus from "../Pages/StatusPage/Create/index.jsx"; import StatusPages from "../Pages/StatusPage/StatusPages"; -import Status from "../Pages/StatusPage/Status/index.jsx"; +import Status from "../Pages/StatusPage/Status"; import Notifications from "../Pages/Notifications"; import CreateNotifications from "../Pages/Notifications/create"; @@ -238,7 +238,13 @@ const Routes = () => { } + element={ + <> + + + + + } /> { /> } + element={ + <> + + + + + } />