mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-01 22:20:03 -05:00
add status header and chatbot
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// Components
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { ColContainer } from "../../../../../Components/StandardContainer";
|
||||
import SmartToyIcon from "@mui/icons-material/SmartToy";
|
||||
import Dot from "../../../../../Components/Dot";
|
||||
// Utils
|
||||
import { useTheme } from "@emotion/react";
|
||||
|
||||
const MESSAGES = [
|
||||
"I've checked the network status, and we're seeing excellent performance across all regions.",
|
||||
"The network is stable and functioning optimally. All connections are active and stable.",
|
||||
"I've reviewed the network status, and everything looks great. No issues detected.",
|
||||
"The network is up and running smoothly. All connections are active and stable.",
|
||||
"I've checked the network status, and everything is looking good. No issues detected.",
|
||||
];
|
||||
|
||||
const ChatBot = ({ sx }) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<ColContainer
|
||||
backgroundColor={theme.palette.chatbot.background}
|
||||
sx={{ ...sx }}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
gap={theme.spacing(4)}
|
||||
>
|
||||
<SmartToyIcon sx={{ color: theme.palette.chatbot.textAccent }} />
|
||||
<Typography color={theme.palette.chatbot.textAccent}>Status Bot</Typography>
|
||||
<Dot
|
||||
color={theme.palette.chatbot.textAccent}
|
||||
style={{ opacity: 0.4 }}
|
||||
/>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={theme.palette.chatbot.textAccent}
|
||||
sx={{ opacity: 0.4 }}
|
||||
>
|
||||
Now
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography>{MESSAGES[Math.floor(Math.random() * MESSAGES.length)]}</Typography>
|
||||
</ColContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatBot;
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Stack, Typography, List, ListItem } from "@mui/material";
|
||||
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;
|
||||
@@ -14,21 +15,9 @@ const DeviceTicker = ({ data, width = "100%", connectionStatus }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction="column"
|
||||
gap={theme.spacing(2)}
|
||||
width={width}
|
||||
sx={{
|
||||
padding: `${theme.spacing(BASE_BOX_PADDING_VERTICAL)} ${theme.spacing(BASE_BOX_PADDING_HORIZONTAL)}`,
|
||||
backgroundColor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderStyle: "solid",
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
}}
|
||||
>
|
||||
<ColContainer>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent={"center"}
|
||||
gap={theme.spacing(4)}
|
||||
>
|
||||
<PulseDot color={statusColor[connectionStatus]} />
|
||||
@@ -41,30 +30,53 @@ const DeviceTicker = ({ data, width = "100%", connectionStatus }) => {
|
||||
{connectionStatus === "up" ? "Connected" : "No connection"}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<List>
|
||||
{data.slice(Math.max(data.length - 5, 0)).map((dataPoint) => {
|
||||
const countryCode = dataPoint?.countryCode?.toLowerCase() ?? null;
|
||||
const flag = countryCode ? `fi fi-${countryCode}` : null;
|
||||
return (
|
||||
<ListItem key={Math.random()}>
|
||||
<Stack direction="column">
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
gap={theme.spacing(4)}
|
||||
>
|
||||
{flag && <span className={flag} />}
|
||||
<Typography variant="h2">{dataPoint?.city || "Unknown"}</Typography>
|
||||
</Stack>
|
||||
<Typography variant="p">{`Response time: ${Math.floor(dataPoint?.responseTime ?? 0)} ms`}</Typography>
|
||||
<Typography variant="p">{`UPT burned: ${dataPoint.uptBurnt}`}</Typography>
|
||||
<Typography variant="p">{`${dataPoint?.device?.manufacturer} ${dataPoint?.device?.model}`}</Typography>
|
||||
</Stack>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</Stack>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ textAlign: "left" }}>
|
||||
<Typography>COUNTRY</Typography>
|
||||
</th>
|
||||
<th style={{ textAlign: "left" }}>
|
||||
<Typography>CITY</Typography>
|
||||
</th>
|
||||
<th style={{ textAlign: "right" }}>
|
||||
<Typography>RESPONSE</Typography>
|
||||
</th>
|
||||
<th style={{ textAlign: "right" }}>
|
||||
<Typography>UPT BURNED</Typography>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((dataPoint) => {
|
||||
const countryCode = dataPoint?.countryCode?.toLowerCase() ?? null;
|
||||
const flag = countryCode ? `fi fi-${countryCode}` : null;
|
||||
const city = dataPoint?.city !== "" ? dataPoint?.city : "Unknown";
|
||||
return (
|
||||
<tr key={Math.random()}>
|
||||
<td style={{ padding: theme.spacing(4) }}>
|
||||
<Typography>
|
||||
{flag ? <span className={flag} /> : null}{" "}
|
||||
{countryCode?.toUpperCase() ?? "N/A"}
|
||||
</Typography>
|
||||
</td>
|
||||
<td>
|
||||
<Typography>{city}</Typography>
|
||||
</td>
|
||||
<td style={{ textAlign: "right" }}>
|
||||
<Typography>{Math.floor(dataPoint.responseTime)} ms</Typography>
|
||||
</td>
|
||||
<td style={{ textAlign: "right" }}>
|
||||
<Typography color={theme.palette.warning.main}>
|
||||
+{dataPoint.uptBurnt}
|
||||
</Typography>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</ColContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -28,12 +28,17 @@ const DistributedUptimeMap = ({ width = "100%", checks }) => {
|
||||
useEffect(() => {
|
||||
if (mapContainer.current && !map.current) {
|
||||
const initialStyle = buildStyle(initialTheme.current, initialMode.current);
|
||||
|
||||
map.current = new maplibregl.Map({
|
||||
container: mapContainer.current,
|
||||
style: initialStyle,
|
||||
center: [0, 20],
|
||||
zoom: 0.8,
|
||||
attributionControl: false,
|
||||
canvasContextAttributes: {
|
||||
antialias: true,
|
||||
preserveDrawingBuffer: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
map.current.on("load", () => {
|
||||
@@ -87,6 +92,10 @@ const DistributedUptimeMap = ({ width = "100%", checks }) => {
|
||||
ref={mapContainer}
|
||||
style={{
|
||||
width: width,
|
||||
borderRadius: theme.spacing(4),
|
||||
borderColor: theme.palette.primary.lowContrast,
|
||||
borderStyle: "solid",
|
||||
borderWidth: 1,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Components
|
||||
import { Stack } from "@mui/material";
|
||||
import StatBox from "../../../../../Components/StatBox";
|
||||
import InfoBox from "../../../../../Components/InfoBox";
|
||||
import LastUpdate from "../LastUpdate";
|
||||
import UptLogo from "../../../../../assets/icons/upt_logo.png";
|
||||
|
||||
@@ -14,17 +14,21 @@ const StatBoxes = ({ monitor, lastUpdateTrigger }) => {
|
||||
return (
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.spacing(8)}
|
||||
>
|
||||
<StatBox
|
||||
<InfoBox
|
||||
sx={{ flex: 1 }}
|
||||
heading="Avg Response Time"
|
||||
subHeading={`${Math.floor(monitor?.avgResponseTime ?? 0)} ms`}
|
||||
/>
|
||||
<StatBox
|
||||
<InfoBox
|
||||
sx={{ flex: 1 }}
|
||||
heading="Checking every"
|
||||
subHeading={`${(monitor?.interval ?? 0) / 1000} seconds`}
|
||||
/>
|
||||
<StatBox
|
||||
<InfoBox
|
||||
sx={{ flex: 1 }}
|
||||
heading={"Last check"}
|
||||
subHeading={
|
||||
<LastUpdate
|
||||
@@ -33,7 +37,8 @@ const StatBoxes = ({ monitor, lastUpdateTrigger }) => {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<StatBox
|
||||
<InfoBox
|
||||
sx={{ flex: 1 }}
|
||||
heading="Last server push"
|
||||
subHeading={
|
||||
<LastUpdate
|
||||
@@ -43,13 +48,6 @@ const StatBoxes = ({ monitor, lastUpdateTrigger }) => {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<StatBox
|
||||
heading="UPT Burned"
|
||||
subHeading={monitor?.totalUptBurnt ?? 0}
|
||||
img={UptLogo}
|
||||
alt="Upt Logo"
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// Components
|
||||
import { ColContainer } from "../../../../../Components/StandardContainer";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import PulseDot from "../../../../../Components/Animated/PulseDot";
|
||||
import LastUpdate from "../LastUpdate";
|
||||
import ChatBot from "../Chatbot";
|
||||
import ShareComponent from "../../../../../Components/ShareComponent";
|
||||
|
||||
// Utils
|
||||
import { useTheme } from "@emotion/react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const StatusHeader = ({ monitor, connectionStatus, elementToCapture }) => {
|
||||
const theme = useTheme();
|
||||
const COLOR_MAP = {
|
||||
up: theme.palette.successSecondary.main,
|
||||
down: theme.palette.error.lowContrast,
|
||||
};
|
||||
|
||||
const MSG_MAP = {
|
||||
up: "All Systems Operational",
|
||||
down: "Last Check Failed",
|
||||
};
|
||||
|
||||
const PULSE_COLOR = {
|
||||
up: theme.palette.success.main,
|
||||
down: theme.palette.error.main,
|
||||
};
|
||||
|
||||
let bgColor = COLOR_MAP[connectionStatus];
|
||||
|
||||
return (
|
||||
<ColContainer backgroundColor={bgColor}>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.spacing(8)}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(8)}
|
||||
>
|
||||
<PulseDot color={PULSE_COLOR[connectionStatus]} />
|
||||
<Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(8)}
|
||||
>
|
||||
<Typography
|
||||
variant="h1"
|
||||
color={theme.palette.success.lowContrast}
|
||||
>
|
||||
{MSG_MAP[connectionStatus]}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
borderRadius={theme.spacing(8)}
|
||||
padding={theme.spacing(4)}
|
||||
backgroundColor={theme.palette.successSecondary.lowContrast}
|
||||
color={theme.palette.success.lowContrast}
|
||||
>
|
||||
Uptime: {(monitor.totalUptime * 100).toFixed(2)}%
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={theme.palette.success.lowContrast}
|
||||
>
|
||||
Last updated{" "}
|
||||
<LastUpdate
|
||||
suffix={"seconds ago"}
|
||||
lastUpdateTime={monitor.timeSinceLastCheck}
|
||||
/>
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<ShareComponent
|
||||
elementToCapture={elementToCapture}
|
||||
fileName={monitor.name}
|
||||
/>
|
||||
</Stack>
|
||||
<ChatBot sx={{ marginTop: theme.spacing(10) }} />
|
||||
</ColContainer>
|
||||
);
|
||||
};
|
||||
|
||||
StatusHeader.propTypes = {
|
||||
monitor: PropTypes.object,
|
||||
connectionStatus: PropTypes.string,
|
||||
};
|
||||
|
||||
export default StatusHeader;
|
||||
Reference in New Issue
Block a user