Pagespeed fixes

This commit is contained in:
Alex Holliday
2024-09-04 22:51:00 -07:00
parent 8869adf103
commit adf75b701a
4 changed files with 151 additions and 139 deletions
@@ -183,7 +183,7 @@ const uptimeMonitorsSlice = createSlice({
extraReducers: (builder) => {
builder
// *****************************************************
// Monitors by userId
// Monitors by teamId
// *****************************************************
.addCase(getUptimeMonitorsByTeamId.pending, (state) => {
+78
View File
@@ -0,0 +1,78 @@
import { getLastChecked } from "../../Utils/monitorUtils";
import { formatDate, formatDurationRounded } from "../../Utils/timeUtils";
import PageSpeedIcon from "../../assets/icons/page-speed.svg?react";
import { StatusLabel } from "../../Components/Label";
import { Box, Grid, Stack, Typography } from "@mui/material";
import { useNavigate } from "react-router";
import { useTheme } from "@emotion/react";
import PropTypes from "prop-types";
const Card = ({ data }) => {
const theme = useTheme();
const navigate = useNavigate();
return (
<Grid
item
lg={6}
flexGrow={1}
sx={{
"&:hover > .MuiStack-root": {
backgroundColor: theme.palette.background.accent,
},
}}
>
<Stack
direction="row"
gap={theme.spacing(6)}
p={theme.spacing(8)}
onClick={() => navigate(`/pagespeed/${data._id}`)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
sx={{
cursor: "pointer",
"& svg path": { stroke: theme.palette.other.icon, strokeWidth: 0.8 },
}}
>
<PageSpeedIcon
style={{ width: theme.spacing(8), height: theme.spacing(8) }}
/>
<Box flex={1}>
<Stack direction="row" justifyContent="space-between">
<Typography
component="h2"
mb={theme.spacing(2)}
color={theme.palette.primary.main}
>
{data.name}
</Typography>
<StatusLabel
status={data.status ? "up" : "cannot resolve"}
text={data.status ? "Live (collecting data)" : "Inactive"}
/>
</Stack>
<Typography fontSize={13}>
{data.url.replace(/^https?:\/\//, "")}
</Typography>
<Typography mt={theme.spacing(12)}>
<Typography component="span" fontWeight={600}>
Last checked:{" "}
</Typography>
{formatDate(getLastChecked(data.checks, false))}{" "}
<Typography component="span" fontStyle="italic">
({formatDurationRounded(getLastChecked(data.checks))} ago)
</Typography>
</Typography>
</Box>
</Stack>
</Grid>
);
};
Card.propTypes = {
data: PropTypes.object.isRequired,
};
export default Card;
+7 -138
View File
@@ -1,154 +1,23 @@
import { Box, Button, Grid, Skeleton, Stack, Typography } from "@mui/material";
import { Box, Button, Grid, Stack } from "@mui/material";
import { useEffect } from "react";
import { useTheme } from "@emotion/react";
import { formatDate, formatDurationRounded } from "../../Utils/timeUtils";
import { StatusLabel } from "../../Components/Label";
import { useDispatch, useSelector } from "react-redux";
import { getPageSpeedByTeamId } from "../../Features/PageSpeedMonitor/pageSpeedMonitorSlice";
import PageSpeedIcon from "../../assets/icons/page-speed.svg?react";
import Fallback from "../../Components/Fallback";
import "./index.css";
import { useNavigate } from "react-router";
import { getLastChecked } from "../../Utils/monitorUtils";
import PropTypes from "prop-types";
import Breadcrumbs from "../../Components/Breadcrumbs";
import Greeting from "../../Utils/greeting";
const Card = ({ data }) => {
const theme = useTheme();
const navigate = useNavigate();
return (
<Grid
item
lg={6}
flexGrow={1}
sx={{
"&:hover > .MuiStack-root": {
backgroundColor: theme.palette.background.accent,
},
}}
>
<Stack
direction="row"
gap={theme.spacing(6)}
p={theme.spacing(8)}
onClick={() => navigate(`/pagespeed/${data._id}`)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
sx={{
cursor: "pointer",
"& svg path": { stroke: theme.palette.other.icon, strokeWidth: 0.8 },
}}
>
<PageSpeedIcon
style={{ width: theme.spacing(8), height: theme.spacing(8) }}
/>
<Box flex={1}>
<Stack direction="row" justifyContent="space-between">
<Typography
component="h2"
mb={theme.spacing(2)}
color={theme.palette.primary.main}
>
{data.name}
</Typography>
<StatusLabel
status={data.status ? "up" : "cannot resolve"}
text={data.status ? "Live (collecting data)" : "Inactive"}
/>
</Stack>
<Typography fontSize={13}>
{data.url.replace(/^https?:\/\//, "")}
</Typography>
<Typography mt={theme.spacing(12)}>
<Typography component="span" fontWeight={600}>
Last checked:{" "}
</Typography>
{formatDate(getLastChecked(data.checks, false))}{" "}
<Typography component="span" fontStyle="italic">
({formatDurationRounded(getLastChecked(data.checks))} ago)
</Typography>
</Typography>
</Box>
</Stack>
</Grid>
);
};
Card.propTypes = {
data: PropTypes.object.isRequired,
};
/**
* Renders a skeleton layout.
*
* @returns {JSX.Element}
*/
const SkeletonLayout = () => {
const theme = useTheme();
return (
<Stack gap={theme.spacing(2)}>
<Stack
direction="row"
justifyContent="space-between"
mb={theme.spacing(12)}
>
<Box width="80%">
<Skeleton variant="rounded" width="25%" height={24} />
<Skeleton
variant="rounded"
width="50%"
height={19.5}
sx={{ mt: theme.spacing(2) }}
/>
</Box>
<Skeleton
variant="rounded"
width="20%"
height={34}
sx={{ alignSelf: "flex-end" }}
/>
</Stack>
<Stack direction="row" flexWrap="wrap" gap={theme.spacing(12)}>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
</Stack>
</Stack>
);
};
import SkeletonLayout from "./skeleton";
import Card from "./card";
const PageSpeed = ({ isAdmin }) => {
const theme = useTheme();
const dispatch = useDispatch();
const navigate = useNavigate();
const { authToken, user } = useSelector((state) => state.auth);
const { authToken } = useSelector((state) => state.auth);
const { monitors, isLoading } = useSelector(
(state) => state.pageSpeedMonitors
);
@@ -158,7 +27,7 @@ const PageSpeed = ({ isAdmin }) => {
// will show skeletons only on initial load
// since monitor state is being added to redux persist, there's no reason to display skeletons on every render
let isActuallyLoading = isLoading && monitors.length === 0;
let isActuallyLoading = isLoading && monitors?.monitors.length === 0;
return (
<Box
@@ -177,7 +46,7 @@ const PageSpeed = ({ isAdmin }) => {
>
{isActuallyLoading ? (
<SkeletonLayout />
) : monitors?.length !== 0 ? (
) : monitors?.monitors?.length !== 0 ? (
<Box
sx={{
"& p": {
@@ -204,7 +73,7 @@ const PageSpeed = ({ isAdmin }) => {
</Stack>
</Box>
<Grid container spacing={theme.spacing(12)}>
{monitors?.map((monitor) => (
{monitors?.monitors?.map((monitor) => (
<Card data={monitor} key={`monitor-${monitor._id}`} />
))}
</Grid>
+65
View File
@@ -0,0 +1,65 @@
import { Box, Skeleton, Stack } from "@mui/material";
import { useTheme } from "@emotion/react";
/**
* Renders a skeleton layout.
*
* @returns {JSX.Element}
*/
const SkeletonLayout = () => {
const theme = useTheme();
return (
<Stack gap={theme.spacing(2)}>
<Stack
direction="row"
justifyContent="space-between"
mb={theme.spacing(12)}
>
<Box width="80%">
<Skeleton variant="rounded" width="25%" height={24} />
<Skeleton
variant="rounded"
width="50%"
height={19.5}
sx={{ mt: theme.spacing(2) }}
/>
</Box>
<Skeleton
variant="rounded"
width="20%"
height={34}
sx={{ alignSelf: "flex-end" }}
/>
</Stack>
<Stack direction="row" flexWrap="wrap" gap={theme.spacing(12)}>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
<Skeleton
variant="rounded"
width="100%"
height={120}
sx={{ flex: "35%" }}
/>
</Stack>
</Stack>
);
};
export default SkeletonLayout;