make status page responsive

This commit is contained in:
Alex Holliday
2025-02-26 11:41:36 -08:00
parent 4e7600067c
commit 9d2743798f
8 changed files with 58 additions and 23 deletions

View File

@@ -1,7 +1,6 @@
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { Box, Stack, Typography } from "@mui/material";
import { RowContainer } from "../StandardContainer";
import { Stack, Typography } from "@mui/material";
/**
@@ -9,6 +8,7 @@ import { RowContainer } from "../StandardContainer";
* @component
* @example
*
* @param {string} props.direction - Direction of the subheader
* @param {string} props.headerText - Header text
* @param {number} props.headerLevel - Font characteristic of the header
* @param {string} props.subHeaderText - Subheader text
@@ -19,19 +19,22 @@ import { RowContainer } from "../StandardContainer";
*/
const SubHeader = ({
direction = "row",
headerText,
headerLevel = 1,
subHeaderText,
subHeaderLevel = 1,
alignItems = "center",
children,
...props
}) => {
const theme = useTheme();
return (
<Stack
direction="row"
direction={direction}
alignItems={alignItems}
justifyContent="space-between"
{...props}
>
<Stack direction={"column"}>
<Typography
@@ -60,11 +63,12 @@ const SubHeader = ({
};
SubHeader.propTypes = {
direction: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
headerText: PropTypes.string,
headerLevel: PropTypes.number,
subHeaderText: PropTypes.string,
subHeaderLevel: PropTypes.number,
alignItems: PropTypes.string,
alignItems: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
children: PropTypes.node,
};

View File

@@ -1,14 +1,17 @@
// Components
import { Stack, Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import PulseDot from "../../../../../Components/Animated/PulseDot";
import "flag-icons/css/flag-icons.min.css";
import { ColContainer } from "../../../../../Components/StandardContainer";
const BASE_BOX_PADDING_VERTICAL = 16;
const BASE_BOX_PADDING_HORIZONTAL = 8;
// Utils
import { useMediaQuery } from "@mui/material";
import { useTheme } from "@emotion/react";
import { safelyParseFloat } from "../../../../../Utils/utils";
const DeviceTicker = ({ data, width = "100%", connectionStatus }) => {
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));
const statusColor = {
up: theme.palette.success.main,
down: theme.palette.error.main,
@@ -43,7 +46,7 @@ const DeviceTicker = ({ data, width = "100%", connectionStatus }) => {
<Typography>RESPONSE</Typography>
</th>
<th style={{ textAlign: "right" }}>
<Typography>UPT BURNED</Typography>
<Typography>{isSmallScreen ? "UPT" : "UPT BURNED"}</Typography>
</th>
</tr>
</thead>
@@ -68,7 +71,10 @@ const DeviceTicker = ({ data, width = "100%", connectionStatus }) => {
</td>
<td style={{ textAlign: "right" }}>
<Typography color={theme.palette.warning.main}>
+{dataPoint.uptBurnt}
+
{isSmallScreen
? safelyParseFloat(dataPoint.uptBurnt).toFixed(4)
: dataPoint.uptBurnt}
</Typography>
</td>
</tr>

View File

@@ -6,7 +6,12 @@ import maplibregl from "maplibre-gl";
import { useSelector } from "react-redux";
import buildStyle from "./buildStyle";
const DistributedUptimeMap = ({ width = "100%", checks }) => {
const DistributedUptimeMap = ({
width = "100%",
checks,
height,
minHeight = "350px",
}) => {
const mapContainer = useRef(null);
const map = useRef(null);
const theme = useTheme();
@@ -92,6 +97,8 @@ const DistributedUptimeMap = ({ width = "100%", checks }) => {
ref={mapContainer}
style={{
width: width,
height: height,
minHeight: minHeight,
borderRadius: theme.spacing(4),
borderColor: theme.palette.primary.lowContrast,
borderStyle: "solid",
@@ -105,6 +112,7 @@ DistributedUptimeMap.propTypes = {
checks: PropTypes.array,
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
minHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
};
export default DistributedUptimeMap;

View File

@@ -2,7 +2,6 @@
import { Stack } from "@mui/material";
import InfoBox from "../../../../../Components/InfoBox";
import LastUpdate from "../LastUpdate";
import UptLogo from "../../../../../assets/icons/upt_logo.png";
// Utils
import { useTheme } from "@mui/material/styles";
@@ -15,6 +14,7 @@ const StatBoxes = ({ monitor, lastUpdateTrigger }) => {
<Stack
direction="row"
justifyContent="space-between"
flexWrap="wrap"
gap={theme.spacing(8)}
>
<InfoBox

View File

@@ -32,7 +32,7 @@ const StatusHeader = ({ monitor, connectionStatus, elementToCapture }) => {
return (
<ColContainer backgroundColor={bgColor}>
<Stack
direction="row"
direction={{ s: "column", md: "row" }}
justifyContent="space-between"
gap={theme.spacing(8)}
>

View File

@@ -1,13 +1,14 @@
import { Stack, Button, ButtonGroup } from "@mui/material";
import { RowContainer } from "../../../../../Components/StandardContainer";
import { useTheme } from "@emotion/react";
const TimeFrameHeader = ({ timeFrame, setTimeFrame }) => {
const TimeFrameHeader = ({ timeFrame, setTimeFrame, sx, ...props }) => {
const theme = useTheme();
return (
<Stack
direction="row"
justifyContent="flex-end"
sx={{ ...sx }}
{...props}
>
<ButtonGroup>
<Button

View File

@@ -28,10 +28,13 @@ import { useDUStatusPageFetchByUrl } from "./Hooks/useDUStatusPageFetchByUrl";
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";
// Responsive
import { useMediaQuery } from "@mui/material";
const DistributedUptimeStatus = () => {
const { url } = useParams();
const location = useLocation();
@@ -45,6 +48,7 @@ const DistributedUptimeStatus = () => {
const [timeFrame, setTimeFrame] = useState(30);
// Utils
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));
const navigate = useNavigate();
const [
@@ -170,8 +174,11 @@ const DistributedUptimeStatus = () => {
/>
<SubHeader
direction={{ s: "column", md: "row" }}
headerText={t("distributedStatusHeaderText")}
subHeaderText={t("distributedStatusSubHeaderText")}
gap={isSmallScreen ? theme.spacing(10) : 0}
alignItems={{ s: "flex-start", md: "flex-end" }}
>
<RowContainer>
<Stack>
@@ -195,16 +202,15 @@ const DistributedUptimeStatus = () => {
setDateRange={setDateRange}
/>
<Stack
direction="row"
gap={theme.spacing(8)}
direction={{ s: "column", md: "row" }}
>
<DistributedUptimeMap
checks={monitor?.groupedMapChecks ?? []}
height={"100%"}
width={"50%"}
width={isSmallScreen ? "100%" : "50%"}
/>
<Stack
width={"50%"}
width={{ s: "100%", md: "50%" }}
gap={theme.spacing(8)}
>
<Stack
@@ -219,8 +225,8 @@ const DistributedUptimeStatus = () => {
sx={{ width: "50%" }}
/>
<InfoBox
heading="UPT Burned"
subHeading={monitor?.totalUptBurnt ?? 0}
heading={isSmallScreen ? "UPT" : "UPT Burned"}
subHeading={safelyParseFloat(monitor?.totalUptBurnt).toFixed(4)}
img={UptLogo}
alt="Upt Logo"
sx={{ width: "50%" }}
@@ -240,13 +246,16 @@ const DistributedUptimeStatus = () => {
/>
<SubHeader
direction={{ s: "column", md: "row" }}
headerText={t("distributedStatusServerMonitors")}
subHeaderText={t("distributedStatusServerMonitorsDescription")}
alignItems="end"
gap={isSmallScreen ? theme.spacing(10) : 0}
alignItems={{ s: "flex-start", md: "flex-end" }}
>
<TimeFrameHeader
timeFrame={timeFrame}
setTimeFrame={setTimeFrame}
alignSelf="flex-start"
/>
</SubHeader>

7
src/Utils/utils.js Normal file
View File

@@ -0,0 +1,7 @@
export const safelyParseFloat = (value) => {
const parsedValue = parseFloat(value);
if (isNaN(parsedValue)) {
return 0;
}
return parsedValue;
};