Revamped performance section and removed redundant code

This commit is contained in:
Daniel Cojocea
2024-09-12 20:08:04 -04:00
parent c0c1cf64ac
commit 06e1c35e77
3 changed files with 49 additions and 226 deletions

View File

@@ -1,14 +1,3 @@
.page-speed-details h6 {
font-size: var(--env-var-font-size-large);
}
.page-speed-details h4,
.page-speed-details p > span {
font-size: var(--env-var-font-size-medium);
}
.page-speed-details h1 + span,
.page-speed-details h4 > span {
font-size: var(--env-var-font-size-small-plus);
}
.page-speed-details button.MuiButtonBase-root {
height: 34px;
}
@@ -27,8 +16,3 @@
.page-speed-details .MuiPieArc-root {
stroke: inherit;
}
.page-speed-details .metric {
min-width: 200px;
flex: 1;
}

View File

@@ -21,104 +21,16 @@ import { logger } from "../../../Utils/Logger";
import { networkService } from "../../../main";
import SkeletonLayout from "./skeleton";
import SettingsIcon from "../../../assets/icons/settings-bold.svg?react";
import SpedometerIcon from "../../../assets/icons/spedometer-icon.svg?react";
import MetricsIcon from "../../../assets/icons/ruler-icon.svg?react";
import ScoreIcon from "../../../assets/icons/monitor-graph-line.svg?react";
import PerformanceIcon from "../../../assets/icons/performance-report.svg?react";
import Breadcrumbs from "../../../Components/Breadcrumbs";
import PulseDot from "../../../Components/Animated/PulseDot";
import PagespeedDetailsAreaChart from "./Charts/AreaChart";
import "./index.css";
import Checkbox from "../../../Components/Inputs/Checkbox";
import PieChart from "./Charts/PieChart";
/**
* Renders a centered label within a pie chart.
*
* @param {Object} props
* @param {string | number} props.value - The value to display in the label.
* @param {string} props.color - The color of the text.
* @returns {JSX.Element}
*/
const PieCenterLabel = ({ value, color, setExpand }) => {
const { width, height } = useDrawingArea();
return (
<g
transform={`translate(${width / 2}, ${height / 2})`}
onMouseEnter={() => setExpand(true)}
>
<circle cx={0} cy={0} r={width / 3} fill="transparent" />
<text
className="pie-label"
style={{
fill: color,
fontSize: "45px",
textAnchor: "middle",
dominantBaseline: "central",
userSelect: "none",
}}
>
{value}
</text>
</g>
);
};
PieCenterLabel.propTypes = {
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
color: PropTypes.string,
setExpand: PropTypes.func,
};
/**
* A component that renders a label on a pie chart slice.
* The label is positioned relative to the center of the pie chart and is optionally highlighted.
*
* @param {Object} props
* @param {number} props.value - The value to display inside the pie slice.
* @param {number} props.startAngle - The starting angle of the pie slice in degrees.
* @param {number} props.endAngle - The ending angle of the pie slice in degrees.
* @param {string} props.color - The color of the label text when highlighted.
* @param {boolean} props.highlighted - Determines if the label should be highlighted or not.
* @returns {JSX.Element}
*/
const PieValueLabel = ({ value, startAngle, endAngle, color, highlighted }) => {
const { width, height } = useDrawingArea();
// Compute the midpoint angle in radians
const angle = (((startAngle + endAngle) / 2) * Math.PI) / 180;
const radius = height / 3.5; // length from center of the circle to where the text is positioned
// Calculate x and y positions
const x = Math.sin(angle) * radius;
const y = -Math.cos(angle) * radius;
return (
<g transform={`translate(${width / 2}, ${height / 2})`}>
<text
className="pie-value-label"
x={x}
y={y}
style={{
fill: highlighted ? color : "rgba(0,0,0,0)",
fontSize: "12px",
textAnchor: "middle",
dominantBaseline: "central",
userSelect: "none",
}}
>
+{value}
</text>
</g>
);
};
PieValueLabel.propTypes = {
value: PropTypes.number,
startAngle: PropTypes.number,
endAngle: PropTypes.number,
color: PropTypes.string,
highlighted: PropTypes.bool,
};
import "./index.css";
const PageSpeedDetails = () => {
const theme = useTheme();
@@ -174,38 +86,6 @@ const PageSpeedDetails = () => {
setMetrics((prev) => ({ ...prev, [id]: !prev[id] }));
};
/**
* Retrieves color properties based on the performance value.
*
* @param {number} value - The performance score used to determine the color properties.
* @returns {{stroke: string, text: string, shape: string}} The color properties for the given performance value.
*/
const getColors = (value) => {
if (value >= 90 && value <= 100)
return {
stroke: theme.palette.success.main,
text: theme.palette.success.text,
shape: "circle",
};
else if (value >= 50 && value < 90)
return {
stroke: theme.palette.warning.main,
text: theme.palette.warning.text,
shape: "square",
};
else if (value >= 0 && value < 50)
return {
stroke: theme.palette.error.text,
text: theme.palette.error.text,
shape: "circle",
};
return {
stroke: theme.palette.unresolved.main,
text: theme.palette.unresolved.main,
shape: "",
};
};
return (
<Stack className="page-speed-details" gap={theme.spacing(10)}>
{loading ? (
@@ -412,8 +292,7 @@ const PageSpeedDetails = () => {
</Box>
<ChartBox
flex={1}
mt={theme.spacing(2)}
sx={{ gridTemplateColumns: "35% 65%", gridTemplateRows: "15% 85%" }}
sx={{ gridTemplateColumns: "50% 50%", gridTemplateRows: "15% 85%" }}
>
<Stack direction="row" alignItems="center" gap={theme.spacing(6)}>
<IconBox>
@@ -433,11 +312,17 @@ const PageSpeedDetails = () => {
Values are estimated and may vary.{" "}
<Typography
component="span"
fontSize="inherit"
sx={{
color: theme.palette.primary.main,
fontWeight: 500,
textDecoration: "underline",
textUnderlineOffset: 2,
transition: "all 200ms",
cursor: "pointer",
"&:hover": {
textUnderlineOffset: 4,
},
}}
>
See calculator
@@ -445,84 +330,30 @@ const PageSpeedDetails = () => {
</Typography>
</Stack>
<Box px={theme.spacing(20)} py={theme.spacing(8)} height="100%">
<Typography
mb={theme.spacing(6)}
pb={theme.spacing(8)}
color={theme.palette.text.secondary}
textAlign="center"
sx={{
borderBottom: 1,
borderBottomColor: theme.palette.border.light,
borderBottomStyle: "dashed",
}}
>
The{" "}
<Typography
component="span"
sx={{
color: theme.palette.primary.main,
fontWeight: 500,
textDecoration: "underline",
cursor: "pointer",
}}
>
performance score is calculated
</Typography>{" "}
directly from these{" "}
<Typography component="span" fontWeight={600}>
metrics
</Typography>
.
</Typography>
<Stack direction="row" alignItems="center" gap={theme.spacing(6)}>
<IconBox>
<SpedometerIcon />
</IconBox>
<Typography component="h2">Performance Metrics</Typography>
</Stack>
<Stack
direction="row"
flexWrap="wrap"
pt={theme.spacing(8)}
gap={theme.spacing(8)}
mt={theme.spacing(8)}
gap={theme.spacing(3)}
>
{Object.keys(audits).map((key) => {
if (key === "_id") return;
let audit = audits[key];
let metricParams = getColors(audit.score * 100);
let shape = (
<Box
sx={{
width: theme.spacing(6),
height: theme.spacing(6),
borderRadius: "50%",
backgroundColor: metricParams.stroke,
}}
></Box>
);
if (metricParams.shape === "square")
shape = (
<Box
sx={{
width: theme.spacing(6),
height: theme.spacing(6),
backgroundColor: metricParams.stroke,
}}
></Box>
);
else if (metricParams.shape === "triangle")
shape = (
<Box
sx={{
width: 0,
height: 0,
ml: `calc((${theme.spacing(6)} - ${theme.spacing(
4
)}) / -2)`,
borderLeft: `${theme.spacing(4)} solid transparent`,
borderRight: `${theme.spacing(4)} solid transparent`,
borderBottom: `${theme.spacing(6)} solid ${
metricParams.stroke
}`,
}}
></Box>
);
let score = audit.score * 100;
let bg =
score >= 90
? theme.palette.success.main
: score >= 50
? theme.palette.warning.main
: score >= 0
? theme.palette.error.text
: theme.palette.unresolved.main;
// Find the position where the number ends and the unit begins
const match = audit.displayValue.match(
@@ -532,44 +363,49 @@ const PageSpeedDetails = () => {
let unit;
if (match) {
value = match[1];
unit = match[2];
match[2] === "s" ? (unit = "seconds") : (unit = match[2]);
} else {
value = audit.displayValue;
}
return (
<Stack
className="metric"
key={`${key}-box`}
justifyContent="space-between"
direction="row"
gap={theme.spacing(4)}
gap={theme.spacing(3)}
p={theme.spacing(3)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={4}
>
{shape}
<Box>
<Typography sx={{ lineHeight: 1 }}>
<Typography
fontSize={12}
fontWeight={500}
lineHeight={1}
mb={1}
textTransform="uppercase"
>
{audit.title}
</Typography>
<Typography
component="span"
sx={{
color: metricParams.text,
fontSize: "16px",
fontWeight: 600,
}}
fontSize={14}
fontWeight={500}
>
{value}
<Typography
component="span"
ml="2px"
sx={{
color: theme.palette.text.secondary,
fontSize: 13,
}}
fontSize={12}
color={theme.palette.text.tertiary}
ml={2}
>
{unit}
</Typography>
</Typography>
</Box>
<Box width={4} backgroundColor={bg} borderRadius={4} />
</Stack>
);
})}

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12M22 12C22 6.47715 17.5228 2 12 2M22 12H19.5M2 12C2 6.47715 6.47715 2 12 2M2 12H4.5M12 2V4.5M19.0784 5L13.4999 10.5M19.0784 19.0784L18.8745 18.8745C18.1827 18.1827 17.8368 17.8368 17.4331 17.5894C17.0753 17.3701 16.6851 17.2085 16.2769 17.1105C15.8166 17 15.3274 17 14.349 17L9.65096 17C8.6726 17 8.18342 17 7.72307 17.1106C7.31493 17.2086 6.92475 17.3702 6.56686 17.5895C6.1632 17.8369 5.8173 18.1828 5.12549 18.8746L4.92163 19.0784M4.92163 5L6.65808 6.73645M14 12C14 13.1046 13.1046 14 12 14C10.8954 14 10 13.1046 10 12C10 10.8954 10.8954 10 12 10C13.1046 10 14 10.8954 14 12Z" stroke="black" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 834 B