Feat: Status Boxes in Incidents Page

This commit is contained in:
Br0wnHammer committed 2025-07-01 15:54:50 +05:30
1 parent 07b2ddc29e
commit 35a9c081b5
5 files changed
+201 -2

No files matched your search

@@ -87,13 +87,13 @@ const OptionsHeader = ({
>
{t("incidentsOptionsHeaderFilterCannotResolve")}
</Button>
{/* <Button
<Button
variant="group"
filled={(filter === "resolved").toString()}
onClick={() => setFilter("resolved")}
>
{t("incidentsOptionsHeaderFilterResolved")}
</Button> */}
</Button>
</ButtonGroup>
</Stack>
<Stack {...stackStyles}>
@@ -0,0 +1,116 @@
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { Box, Stack, Typography } from "@mui/material";
import Background from "../../../../assets/Images/background-grid.svg?react";
import MonitorHeartOutlinedIcon from "@mui/icons-material/MonitorHeartOutlined";
import TaskAltOutlinedIcon from "@mui/icons-material/TaskAltOutlined";
import CancelOutlinedIcon from "@mui/icons-material/CancelOutlined";
import WarningAmberRoundedIcon from "@mui/icons-material/WarningAmberRounded";
const StatusBox = ({ title, value, status }) => {
const theme = useTheme();
let sharedStyles = {
position: "absolute",
right: 8,
opacity: 0.5,
"& svg path": { stroke: theme.palette.primary.contrastTextTertiary },
};
let color;
let icon;
if (status === "up") {
color = theme.palette.success.lowContrast;
icon = (
<Box sx={{ ...sharedStyles, top: 8 }}>
<TaskAltOutlinedIcon fontSize="small"/>
</Box>
);
} else if (status === "down") {
color = theme.palette.error.lowContrast;
icon = (
<Box sx={{ ...sharedStyles, transform: "rotate(180deg)", top: 5 }}>
<CancelOutlinedIcon fontSize="small"/>
</Box>
);
} else if (status === "paused") {
color = theme.palette.warning.lowContrast;
icon = (
<Box sx={{ ...sharedStyles, top: 12, right: 12 }}>
<WarningAmberRoundedIcon fontSize="small"/>
</Box>
);
} else {
color = theme.palette.accent.main;
icon = (
<Box sx={{ ...sharedStyles, top: 12, right: 12 }}>
<MonitorHeartOutlinedIcon fontSize="small"/>
</Box>
);
}
return (
<Box
position="relative"
flex={1}
border={1}
backgroundColor={theme.palette.primary.main}
borderColor={theme.palette.primary.lowContrast}
borderRadius={theme.shape.borderRadius}
p={theme.spacing(8)}
overflow="hidden"
>
<Box
position="absolute"
top="-10%"
left="5%"
>
<Background />
</Box>
<Stack direction="column">
<Stack
direction="row"
alignItems="center"
mb={theme.spacing(8)}
>
<Typography
variant={"h2"}
textTransform="uppercase"
color={theme.palette.primary.contrastTextTertiary}
>
{title}
</Typography>
{icon}
</Stack>
<Stack
direction="row"
alignItems="flex-start"
fontSize={36}
fontWeight={600}
color={color}
gap="2px"
>
{value}
<Typography
fontSize={20}
fontWeight={300}
color={theme.palette.primary.contrastTextSecondary}
sx={{
opacity: 0.3,
}}
>
#
</Typography>
</Stack>
</Stack>
</Box>
);
};
StatusBox.propTypes = {
title: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
status: PropTypes.string,
};
export default StatusBox;
@@ -0,0 +1,43 @@
import PropTypes from "prop-types";
import { Stack } from "@mui/material";
import StatusBox from "./StatusBox";
import { useTheme } from "@emotion/react";
import SkeletonLayout from "./skeleton";
const StatusBoxes = ({ shouldRender }) => {
const theme = useTheme();
if (!shouldRender) return <SkeletonLayout shouldRender={shouldRender} />;
return (
<Stack
gap={theme.spacing(12)}
direction="row"
justifyContent="space-between"
>
<StatusBox
title={"Total Incidents"}
value={6}
/>
<StatusBox
title={"Resolved"}
status="up"
value={3}
/>
<StatusBox
title={"Cannot Resolve"}
status="paused"
value={2}
/>
<StatusBox
title={"Down"}
status="down"
value={1}
/>
</Stack>
);
};
StatusBoxes.propTypes = {
shouldRender: PropTypes.bool,
};
export default StatusBoxes;
@@ -0,0 +1,36 @@
import { Skeleton, Stack } from "@mui/material";
import { useTheme } from "@emotion/react";
const SkeletonLayout = () => {
const theme = useTheme();
return (
<Stack
gap={theme.spacing(12)}
direction="row"
justifyContent="space-between"
>
<Skeleton
variant="rounded"
width="100%"
height={100}
/>
<Skeleton
variant="rounded"
width="100%"
height={100}
/>
<Skeleton
variant="rounded"
width="100%"
height={100}
/>
<Skeleton
variant="rounded"
width="100%"
height={100}
/>
</Stack>
);
};
export default SkeletonLayout;
+4
View File
@@ -4,6 +4,7 @@ import Breadcrumbs from "../../Components/Breadcrumbs";
import GenericFallback from "../../Components/GenericFallback";
import IncidentTable from "./Components/IncidentTable";
import OptionsHeader from "./Components/OptionsHeader";
import StatusBoxes from "./Components/StatusBoxes";
//Utils
import { useTheme } from "@emotion/react";
@@ -62,6 +63,9 @@ const Incidents = () => {
return (
<Stack gap={theme.spacing(10)}>
<Breadcrumbs list={BREADCRUMBS} />
<StatusBoxes
shouldRender={!isLoading}
/>
<OptionsHeader
shouldRender={!isLoading}
monitors={monitorLookup}