diff --git a/Client/src/Components/Charts/ChartBox/index.jsx b/Client/src/Components/Charts/ChartBox/index.jsx new file mode 100644 index 000000000..eed3efd0d --- /dev/null +++ b/Client/src/Components/Charts/ChartBox/index.jsx @@ -0,0 +1,90 @@ +import { Stack, Typography } from "@mui/material"; +import { useTheme } from "@emotion/react"; +import IconBox from "../../IconBox"; +import PropTypes from "prop-types"; + +const ChartBox = ({ + children, + icon, + header, + height = "300px", + justifyContent = "space-between", + Legend, + borderRadiusRight = 4, +}) => { + const theme = useTheme(); + return ( + + span": { + color: theme.palette.primary.contrastText, + fontSize: 20, + "& span": { + opacity: 0.8, + marginLeft: 2, + fontSize: 15, + }, + }, + + "& tspan, & text": { + fill: theme.palette.primary.contrastTextTertiary, + }, + "& path": { + transition: "fill 300ms ease, stroke-width 400ms ease", + }, + }} + > + + {icon} + {header} + + {children} + + {Legend && Legend} + + ); +}; + +export default ChartBox; + +ChartBox.propTypes = { + children: PropTypes.node, + icon: PropTypes.node.isRequired, + header: PropTypes.string.isRequired, + height: PropTypes.string, +}; diff --git a/Client/src/Components/Charts/LegendBox/index.jsx b/Client/src/Components/Charts/LegendBox/index.jsx new file mode 100644 index 000000000..ac14669e3 --- /dev/null +++ b/Client/src/Components/Charts/LegendBox/index.jsx @@ -0,0 +1,42 @@ +import { Stack, Typography } from "@mui/material"; +import { useTheme } from "@emotion/react"; +import IconBox from "../../IconBox"; +import PropTypes from "prop-types"; + +const LegendBox = ({ children, icon, header, sx }) => { + const theme = useTheme(); + return ( + + + {icon} + {header} + + {children} + + ); +}; + +LegendBox.propTypes = { + children: PropTypes.node, + icon: PropTypes.node, + header: PropTypes.string, +}; + +export default LegendBox; diff --git a/Client/src/Components/MonitorStatusHeader/ConfigButton/index.jsx b/Client/src/Components/MonitorStatusHeader/ConfigButton/index.jsx new file mode 100644 index 000000000..fc6407f31 --- /dev/null +++ b/Client/src/Components/MonitorStatusHeader/ConfigButton/index.jsx @@ -0,0 +1,40 @@ +import { Button, Box } from "@mui/material"; +import { useTheme } from "@emotion/react"; +import { useNavigate } from "react-router-dom"; +import SettingsIcon from "../../../assets/icons/settings-bold.svg?react"; +import PropTypes from "prop-types"; +const ConfigButton = ({ shouldRender, monitorId }) => { + const theme = useTheme(); + const navigate = useNavigate(); + + if (!shouldRender) return null; + + return ( + + + + ); +}; + +ConfigButton.propTypes = { + shouldRender: PropTypes.bool, + monitorId: PropTypes.string, +}; + +export default ConfigButton; diff --git a/Client/src/Components/MonitorStatusHeader/index.jsx b/Client/src/Components/MonitorStatusHeader/index.jsx new file mode 100644 index 000000000..6a7188775 --- /dev/null +++ b/Client/src/Components/MonitorStatusHeader/index.jsx @@ -0,0 +1,54 @@ +import { Stack, Typography } from "@mui/material"; +import PulseDot from "../Animated/PulseDot"; +import Dot from "../Dot"; +import { useTheme } from "@emotion/react"; +import useUtils from "../../Pages/Uptime/Monitors/Hooks/useUtils"; +import { formatDurationRounded } from "../../Utils/timeUtils"; +import ConfigButton from "./ConfigButton"; +import SkeletonLayout from "./skeleton"; +import PropTypes from "prop-types"; + +const MonitorHeader = ({ shouldRender = true, isAdmin, monitor }) => { + const theme = useTheme(); + const { statusColor, statusMsg, determineState } = useUtils(); + if (!shouldRender) { + return ; + } + + return ( + + + {monitor.name} + + + + {monitor?.url?.replace(/^https?:\/\//, "") || "..."} + + + + Checking every {formatDurationRounded(monitor?.interval)}. + + + + + + ); +}; + +MonitorHeader.propTypes = { + shouldRender: PropTypes.bool, + isAdmin: PropTypes.bool, + monitor: PropTypes.object, +}; + +export default MonitorHeader; diff --git a/Client/src/Components/MonitorStatusHeader/skeleton.jsx b/Client/src/Components/MonitorStatusHeader/skeleton.jsx new file mode 100644 index 000000000..64dc0547f --- /dev/null +++ b/Client/src/Components/MonitorStatusHeader/skeleton.jsx @@ -0,0 +1,23 @@ +import { Stack, Skeleton } from "@mui/material"; + +const SkeletonLayout = () => { + return ( + + + + + ); +}; + +export default SkeletonLayout; diff --git a/Client/src/Pages/PageSpeed/Details/Charts/AreaChart.jsx b/Client/src/Pages/PageSpeed/Details/Components/Charts/AreaChart.jsx similarity index 95% rename from Client/src/Pages/PageSpeed/Details/Charts/AreaChart.jsx rename to Client/src/Pages/PageSpeed/Details/Components/Charts/AreaChart.jsx index a854eb094..40fec0ab6 100644 --- a/Client/src/Pages/PageSpeed/Details/Charts/AreaChart.jsx +++ b/Client/src/Pages/PageSpeed/Details/Components/Charts/AreaChart.jsx @@ -11,7 +11,7 @@ import { import { useTheme } from "@emotion/react"; import { useMemo, useState } from "react"; import { Box, Stack, Typography } from "@mui/material"; -import { formatDateWithTz } from "../../../../Utils/timeUtils"; +import { formatDateWithTz } from "../../../../../Utils/timeUtils"; import { useSelector } from "react-redux"; const config = { @@ -211,10 +211,13 @@ CustomTick.propTypes = { * @returns {JSX.Element} The area chart component. */ -const PagespeedDetailsAreaChart = ({ data, interval, metrics }) => { +const PageSpeedAreaChart = ({ data, monitor, metrics }) => { const theme = useTheme(); const [isHovered, setIsHovered] = useState(false); - const memoizedData = useMemo(() => processDataWithGaps(data, interval), [data[0]]); + const memoizedData = useMemo( + () => processDataWithGaps(data, monitor.interval), + [data[0]] + ); const filteredConfig = Object.keys(config).reduce((result, key) => { if (metrics[key]) { @@ -310,7 +313,7 @@ const PagespeedDetailsAreaChart = ({ data, interval, metrics }) => { ); }; -PagespeedDetailsAreaChart.propTypes = { +PageSpeedAreaChart.propTypes = { data: PropTypes.arrayOf( PropTypes.shape({ createdAt: PropTypes.string.isRequired, @@ -320,8 +323,8 @@ PagespeedDetailsAreaChart.propTypes = { seo: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, }) ).isRequired, - interval: PropTypes.number.isRequired, + monitor: PropTypes.object.isRequired, metrics: PropTypes.object, }; -export default PagespeedDetailsAreaChart; +export default PageSpeedAreaChart; diff --git a/Client/src/Pages/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx b/Client/src/Pages/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx new file mode 100644 index 000000000..1d3d5ddef --- /dev/null +++ b/Client/src/Pages/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx @@ -0,0 +1,56 @@ +import { Box, Typography, Divider } from "@mui/material"; +import Checkbox from "../../../../../Components/Inputs/Checkbox"; +import MetricsIcon from "../../../../../assets/icons/ruler-icon.svg?react"; +import LegendBox from "../../../../../Components/Charts/LegendBox"; + +import { useTheme } from "@emotion/react"; + +const AreaChartLegend = ({ metrics, handleMetrics }) => { + const theme = useTheme(); + return ( + } + header="Metrics" + > + + + Shown + + + + handleMetrics("accessibility")} + /> + + handleMetrics("bestPractices")} + /> + + handleMetrics("performance")} + /> + + handleMetrics("seo")} + /> + + + ); +}; + +export default AreaChartLegend; diff --git a/Client/src/Pages/PageSpeed/Details/Charts/PieChart.jsx b/Client/src/Pages/PageSpeed/Details/Components/Charts/PieChart.jsx similarity index 99% rename from Client/src/Pages/PageSpeed/Details/Charts/PieChart.jsx rename to Client/src/Pages/PageSpeed/Details/Components/Charts/PieChart.jsx index 193841e7e..aad697f9f 100644 --- a/Client/src/Pages/PageSpeed/Details/Charts/PieChart.jsx +++ b/Client/src/Pages/PageSpeed/Details/Components/Charts/PieChart.jsx @@ -115,6 +115,10 @@ const weights = { const PieChart = ({ audits }) => { const theme = useTheme(); + const [highlightedItem, setHighLightedItem] = useState(null); + const [expand, setExpand] = useState(false); + + if (typeof audits === "undefined") return null; /** * Retrieves color properties based on the performance value. @@ -216,8 +220,6 @@ const PieChart = ({ audits }) => { const pieData = getPieData(audits); const colorMap = getColors(performance); - const [highlightedItem, setHighLightedItem] = useState(null); - const [expand, setExpand] = useState(false); return ( setExpand(false)}> {expand ? ( diff --git a/Client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx b/Client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx new file mode 100644 index 000000000..c7612821f --- /dev/null +++ b/Client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx @@ -0,0 +1,96 @@ +import { Stack, Box, Typography } from "@mui/material"; +import { useTheme } from "@emotion/react"; +import LegendBox from "../../../../../Components/Charts/LegendBox"; +import SpeedometerIcon from "../../../../../assets/icons/speedometer-icon.svg?react"; +import PropTypes from "prop-types"; + +const PieChartLegend = ({ audits }) => { + const theme = useTheme(); + + if (typeof audits === "undefined") return null; + return ( + } + header="Performance metrics" + sx={{ flex: 1 }} + > + {Object.keys(audits).map((key) => { + if (key === "_id") return; + + let audit = audits[key]; + let score = audit.score * 100; + let bg = + score >= 90 + ? theme.palette.success.main + : score >= 50 + ? theme.palette.warning.main + : score >= 0 + ? theme.palette.error.main + : theme.palette.tertiary.main; + + // Find the position where the number ends and the unit begins + const match = audit.displayValue.match(/(\d+\.?\d*)\s*([a-zA-Z]+)/); + let value; + let unit; + if (match) { + value = match[1]; + match[2] === "s" ? (unit = "seconds") : (unit = match[2]); + } else { + value = audit.displayValue; + } + + return ( + + + + {audit.title} + + + {value} + + {unit} + + + + + + ); + })} + + ); +}; + +PieChartLegend.propTypes = { + audits: PropTypes.object, +}; + +export default PieChartLegend; diff --git a/Client/src/Pages/PageSpeed/Details/Components/EmptyView/index.jsx b/Client/src/Pages/PageSpeed/Details/Components/EmptyView/index.jsx new file mode 100644 index 000000000..e69de29bb diff --git a/Client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx b/Client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx new file mode 100644 index 000000000..1046a8ca3 --- /dev/null +++ b/Client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx @@ -0,0 +1,45 @@ +import ChartBox from "../../../../../Components/Charts/ChartBox"; +import AreaChart from "../Charts/AreaChart"; +import AreaChartLegend from "../Charts/AreaChartLegend"; +import ScoreIcon from "../../../../../assets/icons/monitor-graph-line.svg?react"; +import { Stack } from "@mui/material"; + +import { useTheme } from "@emotion/react"; + +const PageSpeedAreaChart = ({ shouldRender, monitor, metrics, handleMetrics }) => { + const theme = useTheme(); + if (typeof monitor === "undefined") { + return null; + } + + const data = monitor?.checks ? [...monitor.checks].reverse() : []; + + return ( + + } + header="Score history" + height="100%" + borderRadiusRight={16} + Legend={ + + } + > + + + + ); +}; + +export default PageSpeedAreaChart; diff --git a/Client/src/Pages/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx b/Client/src/Pages/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx new file mode 100644 index 000000000..5bce18df6 --- /dev/null +++ b/Client/src/Pages/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx @@ -0,0 +1,41 @@ +import StatusBoxes from "../../../../../Components/StatusBoxes"; +import StatBox from "../../../../../Components/StatBox"; +import { Typography } from "@mui/material"; +import { getHumanReadableDuration } from "../../../../../Utils/timeUtils"; + +const PageSpeedStatusBoxes = ({ shouldRender, monitor }) => { + const { time: uptimeDuration, units: uptimeUnits } = getHumanReadableDuration( + monitor?.uptimeDuration + ); + + const { time: lastCheckTime, units: lastCheckUnits } = getHumanReadableDuration( + monitor?.lastChecked + ); + + return ( + + + {uptimeDuration} + {uptimeUnits} + ago + + } + /> + + {lastCheckTime} + {lastCheckUnits} + ago + + } + /> + + ); +}; + +export default PageSpeedStatusBoxes; diff --git a/Client/src/Pages/PageSpeed/Details/Components/PerformanceReport/index.jsx b/Client/src/Pages/PageSpeed/Details/Components/PerformanceReport/index.jsx new file mode 100644 index 000000000..8f34dbf19 --- /dev/null +++ b/Client/src/Pages/PageSpeed/Details/Components/PerformanceReport/index.jsx @@ -0,0 +1,45 @@ +import ChartBox from "../../../../../Components/Charts/ChartBox"; +import PerformanceIcon from "../../../../../assets/icons/performance-report.svg?react"; +import PieChart from "../Charts/PieChart"; +import { Typography } from "@mui/material"; +import { useTheme } from "@emotion/react"; +import PieChartLegend from "../Charts/PieChartLegend"; + +const PerformanceReport = ({ audits }) => { + const theme = useTheme(); + return ( + } + header="Performance report" + Legend={} + borderRadiusRight={16} + > + + + Values are estimated and may vary.{" "} + + See calculator + + + + ); +}; + +export default PerformanceReport; diff --git a/Client/src/Pages/PageSpeed/Details/Hooks/useMonitorFetch.jsx b/Client/src/Pages/PageSpeed/Details/Hooks/useMonitorFetch.jsx new file mode 100644 index 000000000..340d4cf5e --- /dev/null +++ b/Client/src/Pages/PageSpeed/Details/Hooks/useMonitorFetch.jsx @@ -0,0 +1,40 @@ +import { useEffect, useState } from "react"; +import { networkService } from "../../../../main"; +import { logger } from "../../../../Utils/Logger"; +import { useNavigate } from "react-router-dom"; +const useMonitorFetch = ({ authToken, monitorId }) => { + const navigate = useNavigate(); + + const [monitor, setMonitor] = useState(undefined); + const [audits, setAudits] = useState(undefined); + const [isLoading, setIsLoading] = useState(true); + useEffect(() => { + const fetchMonitor = async () => { + try { + setIsLoading(true); + const res = await networkService.getStatsByMonitorId({ + authToken: authToken, + monitorId: monitorId, + sortOrder: "desc", + limit: 50, + dateRange: "day", + numToDisplay: null, + normalize: null, + }); + setMonitor(res?.data?.data ?? undefined); + setAudits(res?.data?.data?.checks?.[0]?.audits ?? undefined); + } catch (error) { + logger.error(logger); + navigate("/not-found", { replace: true }); + } finally { + setIsLoading(false); + } + }; + + fetchMonitor(); + }, [authToken, monitorId, navigate]); + + return { monitor, audits, isLoading }; +}; + +export { useMonitorFetch }; diff --git a/Client/src/Pages/PageSpeed/Details/index.css b/Client/src/Pages/PageSpeed/Details/index.css deleted file mode 100644 index 0d0699b3d..000000000 --- a/Client/src/Pages/PageSpeed/Details/index.css +++ /dev/null @@ -1,18 +0,0 @@ -.page-speed-details button.MuiButtonBase-root { - min-height: 34px; -} - -.page-speed-details .MuiPieArcLabel-root { - font-size: var(--env-var-font-size-small-plus); - transition: fill 300ms ease; -} -.page-speed-details .MuiPieArcLabel-faded { - fill: rgba(0, 0, 0, 0.3); -} -.page-speed-details .pie-label, -.page-speed-details .pie-value-label { - transition: all 400ms ease; -} -.page-speed-details .MuiPieArc-root { - stroke: inherit; -} diff --git a/Client/src/Pages/PageSpeed/Details/index.jsx b/Client/src/Pages/PageSpeed/Details/index.jsx index 4c4bceb1b..1a4cbc7e4 100644 --- a/Client/src/Pages/PageSpeed/Details/index.jsx +++ b/Client/src/Pages/PageSpeed/Details/index.jsx @@ -1,75 +1,37 @@ -import PropTypes from "prop-types"; -import { Box, Button, Divider, Stack, Tooltip, Typography } from "@mui/material"; -import { useEffect, useState } from "react"; -import { useTheme } from "@emotion/react"; -import { useNavigate, useParams } from "react-router-dom"; -import { useSelector } from "react-redux"; -import { formatDurationRounded, formatDurationSplit } from "../../../Utils/timeUtils"; -import { ChartBox } from "./styled"; -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"; +// Components +import { Stack, Typography } from "@mui/material"; import Breadcrumbs from "../../../Components/Breadcrumbs"; -import PulseDot from "../../../Components/Animated/PulseDot"; -import PagespeedDetailsAreaChart from "./Charts/AreaChart"; -import Checkbox from "../../../Components/Inputs/Checkbox"; -import PieChart from "./Charts/PieChart"; -import useUtils from "../../Uptime/Monitors/Hooks/useUtils"; -import "./index.css"; +import MonitorStatusHeader from "../../../Components/MonitorStatusHeader"; +import PageSpeedStatusBoxes from "./Components/PageSpeedStatusBoxes"; +import PageSpeedAreaChart from "./Components/PageSpeedAreaChart"; +import PerformanceReport from "./Components/PerformanceReport"; +import Fallback from "../../../Components/Fallback"; +// Utils +import { useTheme } from "@emotion/react"; import { useIsAdmin } from "../../../Hooks/useIsAdmin"; -import StatBox from "../../../Components/StatBox"; -import IconBox from "../../../Components/IconBox"; +import { useParams } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { useMonitorFetch } from "./Hooks/useMonitorFetch"; +import { useState } from "react"; +// Constants +const BREADCRUMBS = [ + { name: "pagespeed", path: "/pagespeed" }, + { name: "details", path: `` }, + // { name: "details", path: `/pagespeed/${monitorId}` }, // Not needed? +]; const PageSpeedDetails = () => { const theme = useTheme(); - const navigate = useNavigate(); const isAdmin = useIsAdmin(); - const { statusColor, pagespeedStatusMsg, determineState } = useUtils(); - const [monitor, setMonitor] = useState({}); - const [audits, setAudits] = useState({}); const { monitorId } = useParams(); const { authToken } = useSelector((state) => state.auth); - useEffect(() => { - const fetchMonitor = async () => { - try { - const res = await networkService.getStatsByMonitorId({ - authToken: authToken, - monitorId: monitorId, - sortOrder: "desc", - limit: 50, - dateRange: "day", - numToDisplay: null, - normalize: null, - }); - setMonitor(res?.data?.data ?? {}); - setAudits(res?.data?.data?.checks?.[0]?.audits ?? {}); - } catch (error) { - logger.error(logger); - navigate("/not-found", { replace: true }); - } - }; + const { monitor, audits, isLoading } = useMonitorFetch({ + authToken, + monitorId, + }); - fetchMonitor(); - }, [monitorId, authToken, navigate]); - - let loading = Object.keys(monitor).length === 0; - const data = monitor?.checks ? [...monitor.checks].reverse() : []; - - const splitDuration = (duration) => { - const { time, format } = formatDurationSplit(duration); - return ( - <> - {time} - {format} - - ); - }; + console.log(monitor, audits, isLoading); const [metrics, setMetrics] = useState({ accessibility: true, @@ -77,371 +39,46 @@ const PageSpeedDetails = () => { performance: true, seo: true, }); + const handleMetrics = (id) => { setMetrics((prev) => ({ ...prev, [id]: !prev[id] })); }; + if (isLoading) { + return "funk"; + } + + if (typeof audits === "undefined") { + return "No Data"; + } + return ( - - {loading ? ( - - ) : ( - <> - - - - - {monitor.name} - - - - - - - - - {monitor?.url} - - - Checking every {formatDurationRounded(monitor?.interval)}. - - - - {isAdmin && ( - - )} - - - - {splitDuration(monitor?.uptimeDuration)} - ago - - } - /> - - {splitDuration(monitor?.lastChecked)} - ago - - } - /> - - - - Showing statistics for past 24 hours. - - - - - - - Score history - - - - - - - - - - Metrics - - - - - Shown - - - - handleMetrics("accessibility")} - /> - - handleMetrics("bestPractices")} - /> - - handleMetrics("performance")} - /> - - handleMetrics("seo")} - /> - - - - - - - - - - - Performance report - - - - - Values are estimated and may vary.{" "} - - See calculator - - - - - - - - - Performance Metrics - - - {Object.keys(audits).map((key) => { - if (key === "_id") return; - - let audit = audits[key]; - let score = audit.score * 100; - let bg = - score >= 90 - ? theme.palette.success.main - : score >= 50 - ? theme.palette.warning.main - : score >= 0 - ? theme.palette.error.contrastText - : theme.palette.tertiary.main; - - // Find the position where the number ends and the unit begins - const match = audit.displayValue.match(/(\d+\.?\d*)\s*([a-zA-Z]+)/); - let value; - let unit; - if (match) { - value = match[1]; - match[2] === "s" ? (unit = "seconds") : (unit = match[2]); - } else { - value = audit.displayValue; - } - - return ( - - - - {audit.title} - - - {value} - - {unit} - - - - - - ); - })} - - - - - )} + + + + + + Showing statistics for past 24 hours. + + + ); }; -PageSpeedDetails.propTypes = { - isAdmin: PropTypes.bool, - push: PropTypes.func, -}; - export default PageSpeedDetails; diff --git a/Client/src/Pages/PageSpeed/Details/skeleton.jsx b/Client/src/Pages/PageSpeed/Details/skeleton.jsx deleted file mode 100644 index 1d55a5039..000000000 --- a/Client/src/Pages/PageSpeed/Details/skeleton.jsx +++ /dev/null @@ -1,93 +0,0 @@ -import { Box, Skeleton, Stack } from "@mui/material"; - -/** - * Renders a skeleton layout. - * - * @returns {JSX.Element} - */ -const SkeletonLayout = () => { - return ( - <> - - - - - - - - - - - - - - - - - - - - ); -}; - -export default SkeletonLayout; diff --git a/Client/src/Pages/PageSpeed/Details/styled.jsx b/Client/src/Pages/PageSpeed/Details/styled.jsx deleted file mode 100644 index 291d0c6f2..000000000 --- a/Client/src/Pages/PageSpeed/Details/styled.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Stack, styled } from "@mui/material"; - -export const ChartBox = styled(Stack)(({ theme }) => ({ - display: "grid", - minHeight: 300, - minWidth: 250, - border: 1, - borderStyle: "solid", - borderColor: theme.palette.primary.lowContrast, - borderRadius: 4, - borderTopRightRadius: 16, - borderBottomRightRadius: 16, - backgroundColor: theme.palette.primary.main, - "& h2": { - color: theme.palette.primary.contrastTextSecondary, - fontSize: 15, - fontWeight: 500, - }, - "& p": { color: theme.palette.primary.contrastTextTertiary }, - "& > :nth-of-type(1)": { - gridColumn: 1, - gridRow: 1, - height: "fit-content", - paddingTop: theme.spacing(8), - paddingLeft: theme.spacing(8), - }, - "& > :nth-of-type(2)": { gridColumn: 1, gridRow: 2 }, - "& > :nth-of-type(3)": { - gridColumn: 2, - gridRow: "span 2", - padding: theme.spacing(8), - borderLeft: 1, - borderLeftStyle: "solid", - borderLeftColor: theme.palette.primary.lowContrast, - borderRadius: 16, - backgroundColor: theme.palette.primary.main, - background: `linear-gradient(325deg, ${theme.palette.tertiary.main} 20%, ${theme.palette.primary.main} 45%)`, - }, - "& path": { - transition: "stroke-width 400ms ease", - }, -})); diff --git a/Client/src/Pages/PageSpeed/Monitors/index.jsx b/Client/src/Pages/PageSpeed/Monitors/index.jsx index 228e522ff..e921bc15a 100644 --- a/Client/src/Pages/PageSpeed/Monitors/index.jsx +++ b/Client/src/Pages/PageSpeed/Monitors/index.jsx @@ -1,6 +1,6 @@ // Components import Breadcrumbs from "../../../Components/Breadcrumbs"; -import { Stack, Box } from "@mui/material"; +import { Stack } from "@mui/material"; import CreateMonitorHeader from "../../../Components/CreateMonitorHeader"; import MonitorCountHeader from "../../../Components/MonitorCountHeader"; import MonitorGrid from "./Components/MonitorGrid";