Files
Checkmate/client/src/Pages/StatusPage/Status/Components/PageSpeedMetrics.tsx
T

131 lines
3.0 KiB
TypeScript

import Typography from "@mui/material/Typography";
import { Gauge } from "@/Components/design-elements";
import { useTheme } from "@mui/material/styles";
import { useTranslation } from "react-i18next";
import type { Monitor } from "@/Types/Monitor";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
import { LAYOUT, SPACING } from "@/Utils/Theme/constants";
import { getPageSpeedGaugeColor } from "@/Utils/MonitorUtils";
const GAUGE_RADIUS = 60;
const GAUGE_STROKE_WIDTH = 12;
interface StatusPageMonitor extends Monitor {
checks?: Monitor["recentChecks"];
}
interface PageSpeedCheck {
performance: number;
accessibility: number;
bestPractices: number;
seo: number;
}
interface MetricConfig {
key: string;
label: string;
progress: number;
}
const MetricItem = ({ label, progress }: MetricConfig) => {
const theme = useTheme();
return (
<Grid
size={{ xs: 12, md: 3 }}
display="flex"
flexDirection="column"
alignItems="center"
textAlign="center"
gap={theme.spacing(SPACING.LG)}
padding={theme.spacing(LAYOUT.XS)}
sx={{
borderRight: { xs: "none", md: `1px solid ${theme.palette.divider}` },
borderBottom: { xs: `1px solid ${theme.palette.divider}`, md: "none" },
"&:last-child": {
borderRight: "none",
borderBottom: "none",
paddingBottom: theme.spacing(SPACING.LG),
},
}}
>
<Box
display="flex"
flexDirection="column"
alignItems="center"
>
<Gauge
progress={progress}
radius={GAUGE_RADIUS}
strokeWidth={GAUGE_STROKE_WIDTH}
colorFn={getPageSpeedGaugeColor}
/>
<Typography variant="body2">{label}</Typography>
</Box>
</Grid>
);
};
const buildMetrics = (
check: PageSpeedCheck,
t: (key: string) => string
): MetricConfig[] => [
{
key: "performance",
label: t("pages.statusPages.monitorsList.pagespeed.performance"),
progress: check.performance,
},
{
key: "accessibility",
label: t("pages.statusPages.monitorsList.pagespeed.accessibility"),
progress: check.accessibility,
},
{
key: "bestPractices",
label: t("pages.statusPages.monitorsList.pagespeed.bestPractices"),
progress: check.bestPractices,
},
{
key: "seo",
label: t("pages.statusPages.monitorsList.pagespeed.seo"),
progress: check.seo,
},
];
export const PageSpeedMetrics = ({ monitor }: { monitor: StatusPageMonitor }) => {
const theme = useTheme();
const { t } = useTranslation();
const latestCheck = monitor.recentChecks?.[0] ?? monitor.checks?.[0];
if (!latestCheck) {
return (
<Typography
variant="body2"
color={theme.palette.text.secondary}
>
{t("pages.statusPages.monitorsList.noData")}
</Typography>
);
}
const metrics = buildMetrics(latestCheck as PageSpeedCheck, t);
return (
<Grid
container
alignItems="center"
padding={theme.spacing(LAYOUT.LG)}
flex={1}
>
{metrics.map((metric) => (
<MetricItem
key={metric.key}
label={metric.label}
progress={metric.progress}
/>
))}
</Grid>
);
};