diff --git a/client/src/Components/v1/Animated/PulseDot.jsx b/client/src/Components/v1/Animated/PulseDot.jsx deleted file mode 100644 index 83513d56e..000000000 --- a/client/src/Components/v1/Animated/PulseDot.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import PropTypes from "prop-types"; -import { Box, Stack, useTheme } from "@mui/material"; -// import useUtils from "../../Pages/Uptime/utils"; - -/** - * A component that renders a pulsating dot with a specified color. - * - * @component - * @example - * // Example usage: - * - * - * @param {Object} props - * @param {string} props.color - The color of the dot. - * @returns {JSX.Element} The PulseDot component. - */ - -const PulseDot = ({ color }) => { - const theme = useTheme(); - // const { statusToTheme } = useUtils(); - /* TODO refactor so it gets status and gets theme color. Then uses theme.palette.[themeColor].lowContrast */ - /* const themeColor = statusToTheme[status]; */ - - return ( - - - - ); -}; - -PulseDot.propTypes = { - color: PropTypes.string.isRequired, -}; - -export default PulseDot; diff --git a/client/src/Components/v1/Buttons/RoundGradientButton.jsx b/client/src/Components/v1/Buttons/RoundGradientButton.jsx deleted file mode 100644 index ff22be955..000000000 --- a/client/src/Components/v1/Buttons/RoundGradientButton.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; -import Button from "@mui/material/Button"; -import { styled } from "@mui/material/styles"; - -const RoundGradientButton = styled(Button)(({ theme }) => ({ - position: "relative", - border: "5px solid transparent", - backgroundClip: "padding-box", - borderRadius: 30, - fontSize: "1.2rem", - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.background.main, - - "&:after": { - position: "absolute", - top: -3, - left: -3, - right: -3, - bottom: -3, - background: - theme.palette.mode === "dark" - ? "linear-gradient(90deg, #842bd2, #ff5451, #8c52ff)" - : "linear-gradient(90deg, #842bd2, #ff5451, #8c52ff)", - content: '""', - zIndex: -1, - borderRadius: 30, - }, -})); - -export default RoundGradientButton; diff --git a/client/src/Components/v1/Charts/AreaChart/index.jsx b/client/src/Components/v1/Charts/AreaChart/index.jsx deleted file mode 100644 index dd5a900d6..000000000 --- a/client/src/Components/v1/Charts/AreaChart/index.jsx +++ /dev/null @@ -1,214 +0,0 @@ -/** - * CustomAreaChart component for rendering an area chart with optional gradient and custom ticks. - * - * @param {Object} props - The properties object. - * @param {Array} props.data - The data array for the chart. - * @param {Array} props.dataKeys - An array of data keys to be plotted as separate areas. - * @param {string} props.xKey - The key for the x-axis data. - * @param {string} [props.yKey] - The key for the y-axis data (optional). - * @param {Object} [props.xTick] - Custom tick component for the x-axis. - * @param {Object} [props.yTick] - Custom tick component for the y-axis. - * @param {string} [props.strokeColor] - The base stroke color for the areas. - * If not provided, uses a predefined color palette. - * @param {string} [props.fillColor] - The base fill color for the areas. - * @param {boolean} [props.gradient=false] - Whether to apply a gradient fill to the areas. - * @param {string} [props.gradientDirection="vertical"] - The direction of the gradient. - * @param {string} [props.gradientStartColor] - The start color of the gradient. - * Defaults to the area's stroke color if not provided. - * @param {string} [props.gradientEndColor] - The end color of the gradient. - * @param {Object} [props.customTooltip] - Custom tooltip component for the chart. - * @param {string|number} [props.height="100%"] - Height of the chart container. - * - * @returns {JSX.Element} The rendered area chart component. - * - * @example - * // Single series chart - * - * - * @example - * // Multi-series chart with custom tooltip - * } - * yTick={} - * gradient={true} - * customTooltip={({ active, payload, label }) => ( - * - * )} - * /> - */ - -import { - AreaChart, - Area, - XAxis, - YAxis, - CartesianGrid, - Tooltip, - ResponsiveContainer, -} from "recharts"; -import { createGradient } from "../Utils/gradientUtils.jsx"; -import PropTypes from "prop-types"; -import { useTheme } from "@mui/material"; -import { useId } from "react"; -import { Fragment } from "react"; - -const CustomAreaChart = ({ - data, - dataKeys, - xKey, - xDomain, - yKey, - yDomain, - xTick, - yTick, - strokeColor, - fillColor, - gradient = false, - gradientDirection = "vertical", - gradientStartColor, - gradientEndColor, - customTooltip, - height = "100%", -}) => { - const theme = useTheme(); - const uniqueId = useId(); - - const AREA_COLORS = [ - // Blues - "#3182bd", // Deep blue - "#6baed6", // Medium blue - "#9ecae1", // Light blue - - // Greens - "#74c476", // Soft green - "#a1d99b", // Light green - "#c7e9c0", // Pale green - - // Oranges - "#fdae6b", // Warm orange - "#fdd0a2", // Light orange - "#feedde", // Pale orange - - // Purples - "#9467bd", // Lavender - "#a55194", // Deep magenta - "#c994c7", // Soft magenta - - // Reds - "#ff9896", // Soft red - "#de2d26", // Deep red - "#fc9272", // Medium red - - // Cyans/Teals - "#17becf", // Cyan - "#7fcdbb", // Teal - "#a1dab4", // Light teal - - // Yellows - "#fec44f", // Mustard - "#fee391", // Light yellow - "#ffffd4", // Pale yellow - - // Additional colors - "#e377c2", // Soft pink - "#bcbd22", // Olive - "#2ca02c", // Vibrant green - ]; - - return ( - - - - - - - {dataKeys.map((dataKey, index) => { - const gradientId = `gradient-${uniqueId}-${index}`; - - return ( - - {gradient === true && - createGradient({ - id: gradientId, - startColor: gradientStartColor || AREA_COLORS[index], - endColor: gradientEndColor, - direction: gradientDirection, - })} - - - ); - })} - {customTooltip ? ( - - ) : ( - - )} - - - ); -}; - -CustomAreaChart.propTypes = { - data: PropTypes.array.isRequired, - dataKeys: PropTypes.array.isRequired, - xTick: PropTypes.object, // Recharts takes an instance of component, so we can't pass the component itself - yTick: PropTypes.object, // Recharts takes an instance of component, so we can't pass the component itself - xKey: PropTypes.string.isRequired, - xDomain: PropTypes.array, - yKey: PropTypes.string, - yDomain: PropTypes.array, - fillColor: PropTypes.string, - strokeColor: PropTypes.string, - gradient: PropTypes.bool, - gradientDirection: PropTypes.string, - gradientStartColor: PropTypes.string, - gradientEndColor: PropTypes.string, - customTooltip: PropTypes.object, - height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), -}; - -export default CustomAreaChart; diff --git a/client/src/Components/v1/Charts/BarChart/index.css b/client/src/Components/v1/Charts/BarChart/index.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/Components/v1/Charts/BarChart/index.jsx b/client/src/Components/v1/Charts/BarChart/index.jsx deleted file mode 100644 index 77b836cae..000000000 --- a/client/src/Components/v1/Charts/BarChart/index.jsx +++ /dev/null @@ -1,181 +0,0 @@ -import { useTheme } from "@emotion/react"; -import { Box, Stack, Tooltip, Typography } from "@mui/material"; -import { formatDateWithTz } from "../../../../Utils/timeUtilsLegacy.js"; -import { useEffect, useState } from "react"; -import "./index.css"; -import { useSelector } from "react-redux"; - -/* TODO add prop validation and jsdocs */ -const BarChart = ({ checks = [] }) => { - const theme = useTheme(); - const [animate, setAnimate] = useState(false); - const uiTimezone = useSelector((state) => state.ui.timezone); - - useEffect(() => { - setAnimate(true); - }); - - // set responseTime to average if there's only one check - if (checks.length === 1) { - checks[0] = { ...checks[0], responseTime: 50 }; - } - - if (checks.length !== 25) { - const placeholders = Array(25 - checks.length).fill("placeholder"); - checks = [...checks, ...placeholders]; - } - - return ( - event.stopPropagation()} - sx={{ - cursor: "default", - }} - > - {checks.map((check, index) => - check === "placeholder" ? ( - /* TODO what is the purpose of this box? */ - // CAIO_REVIEW the purpose of this box is to make sure there are always at least 25 bars - // even if there are less than 25 checks - - ) : ( - - - {formatDateWithTz( - check.updatedAt, - "ddd, MMMM D, YYYY, HH:mm A", - uiTimezone - )} - - - - - - Response Time - - - {check.originalResponseTime} - - {" "} - ms - - - - - - } - placement="top" - key={`check-${check?.id}`} - slotProps={{ - popper: { - className: "bar-tooltip", - modifiers: [ - { - name: "offset", - options: { - offset: [0, -10], - }, - }, - ], - sx: { - "& .MuiTooltip-tooltip": { - backgroundColor: theme.palette.secondary.main, - border: 1, - borderColor: theme.palette.primary.lowContrast, - borderRadius: theme.shape.borderRadius, - boxShadow: theme.shape.boxShadow, - px: theme.spacing(4), - py: theme.spacing(3), - }, - "& .MuiTooltip-tooltip p": { - /* TODO Font size should point to theme */ - fontSize: 12, - color: theme.palette.secondary.contrastText, - fontWeight: 500, - }, - "& .MuiTooltip-tooltip span": { - /* TODO Font size should point to theme */ - fontSize: 11, - color: theme.palette.secondary.contrastText, - fontWeight: 600, - }, - }, - }, - }} - > - .MuiBox-root": { - filter: "brightness(0.8)", - }, */ - }} - > - - - - ) - )} - - ); -}; - -export default BarChart; diff --git a/client/src/Components/v1/Charts/ChartBox/EmptyView.jsx b/client/src/Components/v1/Charts/ChartBox/EmptyView.jsx deleted file mode 100644 index c1b60632d..000000000 --- a/client/src/Components/v1/Charts/ChartBox/EmptyView.jsx +++ /dev/null @@ -1,106 +0,0 @@ -// Components -import { Typography, Stack } from "@mui/material"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import IconBox from "../../IconBox/index.jsx"; - -/** - * `EmptyView` is a functional React component that displays an empty state view with an optional icon, header, and message. - * - * @component - * @param {Object} props - The properties that define the `EmptyView` component. - * @param {React.ReactNode} [props.icon] - An optional icon to display at the top of the empty view. - * @param {string} [props.header] - An optional header text displayed next to the icon. - * @param {string} [props.message="No Data"] - The message to be displayed in the empty view. - * @param {'h1' | 'h2' | 'h3'} [props.headingLevel="h2"] - The heading level for the message text. - * @param {string} [props.justifyContent="flex-start"] - The CSS `justify-content` value to align elements vertically. - * @param {string} [props.height="100%"] - The height of the empty view container. - * - * @example - * // Example usage of EmptyView component: - * } - * header="Average Response Time" - * message="No Response Time Available" - * headingLevel="h2" - * justifyContent="center" - * height="50%" - * /> - * - * @returns {React.Element} The `EmptyView` component with customizable icon, header, and message. - */ - -const EmptyView = ({ - icon, - header, - message = "No Data", - headingLevel = "h2", - justifyContent = "flex-start", - height = "100%", -}) => { - const theme = useTheme(); - return ( - - - - {icon && {icon}} - {header && {header}} - - - {message} - - - - ); -}; - -EmptyView.propTypes = { - message: PropTypes.string, - icon: PropTypes.node, - header: PropTypes.string, - headingLevel: PropTypes.oneOf(["h1", "h2", "h3"]), - justifyContent: PropTypes.string, - height: PropTypes.string, -}; - -export default EmptyView; diff --git a/client/src/Components/v1/Charts/ChartBox/index.jsx b/client/src/Components/v1/Charts/ChartBox/index.jsx deleted file mode 100644 index be2faf8ed..000000000 --- a/client/src/Components/v1/Charts/ChartBox/index.jsx +++ /dev/null @@ -1,104 +0,0 @@ -import { Stack, Typography } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import IconBox from "../../IconBox/index.jsx"; -import EmptyView from "./EmptyView.jsx"; -import PropTypes from "prop-types"; - -const ChartBox = ({ - children, - icon, - header, - height = "300px", - justifyContent = "space-between", - Legend, - borderRadiusRight = 4, - sx, - noDataMessage, - isEmpty = false, -}) => { - const theme = useTheme(); - if (isEmpty) { - return ( - - ); - } - 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 && {icon}} - {header && {header}} - - {children} - - {Legend && Legend} - - ); -}; - -export default ChartBox; - -ChartBox.propTypes = { - children: PropTypes.node, - icon: PropTypes.node, - header: PropTypes.string, - height: PropTypes.string, - noDataMessage: PropTypes.string, - isEmpty: PropTypes.bool, -}; diff --git a/client/src/Components/v1/Charts/CustomGauge/index.css b/client/src/Components/v1/Charts/CustomGauge/index.css deleted file mode 100644 index 1b64a6b9a..000000000 --- a/client/src/Components/v1/Charts/CustomGauge/index.css +++ /dev/null @@ -1,14 +0,0 @@ -.radial-chart { - position: relative; - display: inline-block; -} - -.radial-chart-base { - opacity: 0.3; -} - -.radial-chart-progress { - transform: rotate(-90deg); - transform-origin: center; - transition: stroke-dashoffset 1.5s ease-in-out; -} diff --git a/client/src/Components/v1/Charts/CustomGauge/index.jsx b/client/src/Components/v1/Charts/CustomGauge/index.jsx deleted file mode 100644 index 614b3774c..000000000 --- a/client/src/Components/v1/Charts/CustomGauge/index.jsx +++ /dev/null @@ -1,148 +0,0 @@ -import { useTheme } from "@emotion/react"; -import { useEffect, useState, useMemo } from "react"; -import Stack from "@mui/material/Stack"; -import { Box, Typography } from "@mui/material"; -import PropTypes from "prop-types"; -import "./index.css"; -import CircularProgress from "@mui/material/CircularProgress"; - -const MINIMUM_VALUE = 0; -const MAXIMUM_VALUE = 100; - -/** - * A Performant SVG based circular gauge - * - * @component - * @param {Object} props - Component properties - * @param {number} [props.progress=0] - Progress percentage (0-100) - * @param {number} [props.radius=60] - Radius of the gauge circle - * @param {number} [props.strokeWidth=15] - Width of the gauge stroke - * @param {number} [props.precision=1] - Precision of the progress percentage - * @param {string} [props.unit="%"] - Unit of progress - * - * @example - * - * - * @returns {React.ReactElement} Rendered CustomGauge component - */ -const CustomGauge = ({ - isLoading = false, - progress = 0, - radius = 70, - strokeWidth = 15, - precision = 1, - unit = "%", -}) => { - const theme = useTheme(); - // Calculate the length of the stroke for the circle - const { circumference, totalSize, strokeLength } = useMemo( - () => ({ - circumference: 2 * Math.PI * radius, - totalSize: radius * 2 + strokeWidth * 2, - strokeLength: (progress / 100) * (2 * Math.PI * radius), - }), - [radius, strokeWidth, progress] - ); - - // Handle initial animation - const [offset, setOffset] = useState(circumference); - useEffect(() => { - setOffset(circumference); - const timer = setTimeout(() => { - setOffset(circumference - strokeLength); - }, 100); - - return () => clearTimeout(timer); - }, [progress, circumference, strokeLength]); - - const progressWithinRange = Math.max(MINIMUM_VALUE, Math.min(progress, MAXIMUM_VALUE)); - - let fillColor; - if (progressWithinRange < 50) { - fillColor = theme.palette.success.main; - } else if (progressWithinRange < 80) { - fillColor = theme.palette.warning.lowContrast; - } else { - fillColor = theme.palette.error.lowContrast; - } - - if (isLoading) { - return ( - - - - ); - } - - return ( - - - - - - - - {`${progressWithinRange.toFixed(precision)}${unit}`} - - - ); -}; - -export default CustomGauge; - -CustomGauge.propTypes = { - isLoading: PropTypes.bool, - progress: PropTypes.number, - radius: PropTypes.number, - strokeWidth: PropTypes.number, - precision: PropTypes.number, - unit: PropTypes.string, -}; diff --git a/client/src/Components/v1/Charts/DePINStatusPageBarChart/index.jsx b/client/src/Components/v1/Charts/DePINStatusPageBarChart/index.jsx deleted file mode 100644 index 8b6c2b165..000000000 --- a/client/src/Components/v1/Charts/DePINStatusPageBarChart/index.jsx +++ /dev/null @@ -1,181 +0,0 @@ -// Components -import { Stack, Box, Tooltip, Typography } from "@mui/material"; - -// Utils -import { useTheme } from "@emotion/react"; -import { useState, useEffect } from "react"; -import PropTypes from "prop-types"; -import { formatDateWithTz } from "../../../../Utils/timeUtilsLegacy.js"; -import { useSelector } from "react-redux"; - -const PlaceholderCheck = ({ daysToShow }) => { - const theme = useTheme(); - - return ( - - ); -}; - -PlaceholderCheck.propTypes = { - daysToShow: PropTypes.number, -}; - -const Check = ({ check, daysToShow }) => { - const [animate, setAnimate] = useState(false); - - const theme = useTheme(); - useEffect(() => { - setAnimate(true); - }, []); - const uiTimezone = useSelector((state) => state.ui.timezone); - - return ( - - - {formatDateWithTz(check._id, "ddd, MMMM D, YYYY", uiTimezone)} - - - - - Uptime percentage - - - {check.upPercentage.toFixed(2)} - - {" "} - % - - - - - - } - placement="top" - key={`check-${check?._id}`} - slotProps={{ - popper: { - className: "bar-tooltip", - modifiers: [ - { - name: "offset", - options: { - offset: [0, -10], - }, - }, - ], - sx: { - "& .MuiTooltip-tooltip": { - backgroundColor: theme.palette.secondary.main, - border: 1, - borderColor: theme.palette.primary.lowContrast, - borderRadius: theme.shape.borderRadius, - boxShadow: theme.shape.boxShadow, - px: theme.spacing(4), - py: theme.spacing(3), - }, - "& .MuiTooltip-tooltip p": { - /* TODO Font size should point to theme */ - fontSize: 12, - color: theme.palette.secondary.contrastText, - fontWeight: 500, - }, - "& .MuiTooltip-tooltip span": { - /* TODO Font size should point to theme */ - fontSize: 11, - color: theme.palette.secondary.contrastText, - fontWeight: 600, - }, - }, - }, - }} - > - - - - - ); -}; - -Check.propTypes = { - check: PropTypes.object, - daysToShow: PropTypes.number, -}; - -const DePINStatusPageBarChart = ({ checks = [], daysToShow = 30 }) => { - if (checks.length !== daysToShow) { - const placeholders = Array(daysToShow - checks.length).fill("placeholder"); - checks = [...checks, ...placeholders]; - } - return ( - - {checks.map((check) => { - if (check === "placeholder") { - return ( - - ); - } - return ( - - ); - })} - - ); -}; - -DePINStatusPageBarChart.propTypes = { - checks: PropTypes.array, - daysToShow: PropTypes.number, -}; - -export default DePINStatusPageBarChart; diff --git a/client/src/Components/v1/Charts/LegendBox/index.jsx b/client/src/Components/v1/Charts/LegendBox/index.jsx deleted file mode 100644 index f19e09105..000000000 --- a/client/src/Components/v1/Charts/LegendBox/index.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Stack, Typography } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import IconBox from "../../IconBox/index.jsx"; -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/v1/Charts/MonitorDetailsAreaChart/index.css b/client/src/Components/v1/Charts/MonitorDetailsAreaChart/index.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/Components/v1/Charts/MonitorDetailsAreaChart/index.jsx b/client/src/Components/v1/Charts/MonitorDetailsAreaChart/index.jsx deleted file mode 100644 index dafca7b40..000000000 --- a/client/src/Components/v1/Charts/MonitorDetailsAreaChart/index.jsx +++ /dev/null @@ -1,222 +0,0 @@ -import PropTypes from "prop-types"; -import { - AreaChart, - Area, - XAxis, - Tooltip, - CartesianGrid, - ResponsiveContainer, - Text, -} from "recharts"; -import { Box, Stack, Typography } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import { useMemo, useState } from "react"; -import { useSelector } from "react-redux"; -import { formatDateWithTz } from "../../../../Utils/timeUtilsLegacy.js"; -import { - tooltipDateFormatLookup, - tickDateFormatLookup, -} from "../Utils/chartUtilFunctions.js"; - -import "./index.css"; -const CustomToolTip = ({ active, payload, label, dateRange }) => { - const format = tooltipDateFormatLookup(dateRange); - const uiTimezone = useSelector((state) => state.ui.timezone); - const theme = useTheme(); - if (active && payload && payload.length) { - const responseTime = payload[0]?.payload?.originalAvgResponseTime - ? payload[0]?.payload?.originalAvgResponseTime - : (payload[0]?.payload?.avgResponseTime ?? 0); - return ( - - - {formatDateWithTz(label, format, uiTimezone)} - - - - - - Response time: - - - {Math.floor(responseTime)} - - {" "} - ms - - - - - {/* Display original value */} - - ); - } - return null; -}; - -CustomToolTip.propTypes = { - active: PropTypes.bool, - payload: PropTypes.arrayOf( - PropTypes.shape({ - value: PropTypes.number, - payload: PropTypes.shape({ - _id: PropTypes.string, - avgResponseTime: PropTypes.number, - originalAvgResponseTime: PropTypes.number, - }), - }) - ), - label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - dateRange: PropTypes.string, -}; -const CustomTick = ({ x, y, payload, dateRange }) => { - const format = tickDateFormatLookup(dateRange); - const theme = useTheme(); - const uiTimezone = useSelector((state) => state.ui.timezone); - return ( - - {formatDateWithTz(payload?.value, format, uiTimezone)} - - ); -}; - -CustomTick.propTypes = { - x: PropTypes.number, - y: PropTypes.number, - payload: PropTypes.object, - index: PropTypes.number, - dateRange: PropTypes.string, -}; - -const MonitorDetailsAreaChart = ({ checks, dateRange }) => { - const theme = useTheme(); - const memoizedChecks = useMemo(() => checks, [checks[0]]); - const [isHovered, setIsHovered] = useState(false); - return ( - - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - > - - - - - - - - } - axisLine={false} - tickLine={false} - height={20} - /> - } - wrapperStyle={{ pointerEvents: "none" }} - /> - - - - ); -}; - -MonitorDetailsAreaChart.propTypes = { - checks: PropTypes.array, - dateRange: PropTypes.string, -}; - -export default MonitorDetailsAreaChart; diff --git a/client/src/Components/v1/Charts/StatusPageBarChart/index.jsx b/client/src/Components/v1/Charts/StatusPageBarChart/index.jsx deleted file mode 100644 index 2dc5e61f0..000000000 --- a/client/src/Components/v1/Charts/StatusPageBarChart/index.jsx +++ /dev/null @@ -1,217 +0,0 @@ -import { useTheme } from "@emotion/react"; -import { Box, Stack, Tooltip, Typography } from "@mui/material"; -import { formatDateWithTz } from "../../../../Utils/timeUtilsLegacy.js"; -import { useEffect, useState, forwardRef } from "react"; -import { useSelector } from "react-redux"; -import PropTypes from "prop-types"; - -/** - * A customizable Bar component that renders a colored bar with optional children. - * @component - * - * @param {string} width The width of the bar (e.g., "100px"). - * @param {string} height The height of the bar (e.g., "50px"). - * @param {string} backgroundColor The background color of the bar (e.g., "#FF5733"). - * @param {string} [borderRadius] Optional border radius for the bar (e.g., "8px"). - * @param {node} children The content to be rendered inside the bar. - * @returns {JSX.Element} The Bar component. - */ - -const Bar = forwardRef( - ({ width, height, backgroundColor, borderRadius, children, ...otherProps }, ref) => { - const theme = useTheme(); - - return ( - - {children} - - ); - } -); - -Bar.displayName = "Bar"; - -Bar.propTypes = { - width: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, - height: PropTypes.string.isRequired, - backgroundColor: PropTypes.string.isRequired, - borderRadius: PropTypes.string, - children: PropTypes.node, -}; - -/* TODO add prop validation and jsdocs */ -const StatusPageBarChart = ({ checks = [] }) => { - const theme = useTheme(); - const [animate, setAnimate] = useState(false); - const uiTimezone = useSelector((state) => state.ui.timezone); - - const barWidth = { - xs: "calc(60% / 25)", - xl: "calc(40% / 25)", - }; - - useEffect(() => { - setAnimate(true); - }, []); - - // set responseTime to average if there's only one check - if (checks.length === 1) { - checks[0] = { ...checks[0], responseTime: 50 }; - } - - if (checks.length !== 25) { - const placeholders = Array(25 - checks.length).fill("placeholder"); - checks = [...checks, ...placeholders]; - } - - return ( - event.stopPropagation()} - sx={{ - cursor: "default", - }} - > - {checks.map((check, index) => - check === "placeholder" ? ( - /* TODO what is the purpose of this box? */ - // CAIO_REVIEW the purpose of this box is to make sure there are always at least 25 bars - // even if there are less than 25 checks - - ) : ( - - - {formatDateWithTz( - check.createdAt, - "ddd, MMMM D, YYYY, HH:mm A", - uiTimezone - )} - - - - - - Response Time - - - {check.originalResponseTime} - - {" "} - ms - - - - - - } - placement="top" - key={`check-${check?.id}`} - slotProps={{ - popper: { - className: "bar-tooltip", - modifiers: [ - { - name: "offset", - options: { - offset: [0, -10], - }, - }, - ], - sx: { - "& .MuiTooltip-tooltip": { - backgroundColor: theme.palette.secondary.main, - border: 1, - borderColor: theme.palette.primary.lowContrast, - borderRadius: theme.shape.borderRadius, - boxShadow: theme.shape.boxShadow, - px: theme.spacing(4), - py: theme.spacing(3), - }, - "& .MuiTooltip-tooltip p": { - /* TODO Font size should point to theme */ - fontSize: 12, - color: theme.palette.secondary.contrastText, - fontWeight: 500, - }, - "& .MuiTooltip-tooltip span": { - /* TODO Font size should point to theme */ - fontSize: 11, - color: theme.palette.secondary.contrastText, - fontWeight: 600, - }, - }, - }, - }} - > - - - - - ) - )} - - ); -}; - -export default StatusPageBarChart; diff --git a/client/src/Components/v1/Charts/Utils/chartUtilFunctions.js b/client/src/Components/v1/Charts/Utils/chartUtilFunctions.js deleted file mode 100644 index 2851af93e..000000000 --- a/client/src/Components/v1/Charts/Utils/chartUtilFunctions.js +++ /dev/null @@ -1,27 +0,0 @@ -export const tooltipDateFormatLookup = (dateRange) => { - const dateFormatLookup = { - recent: "ddd. MMMM D, YYYY, hh:mm A", - day: "ddd. MMMM D, YYYY, hh:mm A", - week: "ddd. MMMM D, YYYY, hh:mm A", - month: "ddd. MMMM D, YYYY", - }; - const format = dateFormatLookup[dateRange]; - if (format === undefined) { - return ""; - } - return format; -}; - -export const tickDateFormatLookup = (dateRange) => { - const tickFormatLookup = { - recent: "h:mm A", - day: "h:mm A", - week: "MM/D, h:mm A", - month: "ddd. M/D", - }; - const format = tickFormatLookup[dateRange]; - if (format === undefined) { - return ""; - } - return format; -}; diff --git a/client/src/Components/v1/Charts/Utils/chartUtils.jsx b/client/src/Components/v1/Charts/Utils/chartUtils.jsx deleted file mode 100644 index 7797ba462..000000000 --- a/client/src/Components/v1/Charts/Utils/chartUtils.jsx +++ /dev/null @@ -1,337 +0,0 @@ -import PropTypes from "prop-types"; -import { useSelector } from "react-redux"; -import { useTheme } from "@mui/material"; -import { Text } from "recharts"; -import { formatDateWithTz } from "../../../../Utils/timeUtilsLegacy.js"; -import { Box, Stack, Typography } from "@mui/material"; -import { tickDateFormatLookup, tooltipDateFormatLookup } from "./chartUtilFunctions.js"; -/** - * Custom tick component for rendering time with timezone. - * - * @param {Object} props - The properties object. - * @param {number} props.x - The x-coordinate for the tick. - * @param {number} props.y - The y-coordinate for the tick. - * @param {Object} props.payload - The payload object containing tick data. - * @param {number} props.index - The index of the tick. - * @returns {JSX.Element} The rendered tick component. - */ -export const TzTick = ({ x, y, payload, index, dateRange }) => { - const theme = useTheme(); - const uiTimezone = useSelector((state) => state.ui.timezone); - const format = tickDateFormatLookup(dateRange); - return ( - - {formatDateWithTz(payload?.value, format, uiTimezone)} - - ); -}; - -TzTick.propTypes = { - x: PropTypes.number, - y: PropTypes.number, - payload: PropTypes.object, - index: PropTypes.number, - dateRange: PropTypes.string, -}; - -/** - * Custom tick component for rendering percentage values. - * - * @param {Object} props - The properties object. - * @param {number} props.x - The x-coordinate for the tick. - * @param {number} props.y - The y-coordinate for the tick. - * @param {Object} props.payload - The payload object containing tick data. - * @param {number} props.index - The index of the tick. - * @returns {JSX.Element|null} The rendered tick component or null for the first tick. - */ -export const PercentTick = ({ x, y, payload, index }) => { - const theme = useTheme(); - if (index === 0) return null; - return ( - - {`${(payload?.value * 100).toFixed()}%`} - - ); -}; - -PercentTick.propTypes = { - x: PropTypes.number, - y: PropTypes.number, - payload: PropTypes.object, - index: PropTypes.number, -}; - -/** - * Converts a decimal value to a formatted percentage string. - * - * @param {number} value - The decimal value to convert (e.g., 0.75) - * @returns {string} Formatted percentage string (e.g., "75.00%") or original input if not a number - * - * @example - * getFormattedPercentage(0.7543) // Returns "75.43%" - * getFormattedPercentage(1) // Returns "100.00%" - * getFormattedPercentage("test") // Returns "test" - */ -const getFormattedPercentage = (value) => { - if (typeof value !== "number") return value; - return `${(value * 100).toFixed(2)}%`; -}; - -/** - * Custom tick component for rendering network bytes per second. - * - * @param {Object} props - The properties object. - * @param {number} props.x - The x-coordinate for the tick. - * @param {number} props.y - The y-coordinate for the tick. - * @param {Object} props.payload - The payload object containing tick data. - * @param {number} props.index - The index of the tick. - * @returns {JSX.Element|null} The rendered tick component or null for the first tick. - */ -export const NetworkTick = ({ x, y, payload, index, formatter }) => { - const theme = useTheme(); - if (index === 0) return null; - - if (formatter === undefined) { - formatter = (value, space = false) => { - if (typeof value !== "number") return value; - // need to add space between value and unit - return `${(value / 1024).toFixed(1)}${space ? " " : ""}Kbps`; - }; - } - - return ( - - {formatter(payload?.value, true)} - - ); -}; - -NetworkTick.propTypes = { - x: PropTypes.number, - y: PropTypes.number, - payload: PropTypes.object, - index: PropTypes.number, - formatter: PropTypes.func, -}; - -/** - * Custom tooltip component for displaying infrastructure data. - * - * @param {Object} props - The properties object. - * @param {boolean} props.active - Indicates if the tooltip is active. - * @param {Array} props.payload - The payload array containing tooltip data. - * @param {string} props.label - The label for the tooltip. - * @param {string} props.yKey - The key for the y-axis data. - * @param {string} props.yLabel - The label for the y-axis data. - * @param {string} props.dotColor - The color of the dot in the tooltip. - * @returns {JSX.Element|null} The rendered tooltip component or null if inactive. - */ -export const InfrastructureTooltip = ({ - active, - payload, - label, - yKey, - yIdx = -1, - yLabel, - dotColor, - dateRange, - formatter = getFormattedPercentage, -}) => { - const uiTimezone = useSelector((state) => state.ui.timezone); - const theme = useTheme(); - - const format = tooltipDateFormatLookup(dateRange); - if (active && payload && payload.length) { - const [hardwareType, metric] = yKey.split("."); - return ( - - - {formatDateWithTz(label, format, uiTimezone)} - - - - - - {yIdx >= 0 - ? `${yLabel} ${formatter(payload[0].payload[hardwareType][yIdx][metric])}` - : `${yLabel} ${formatter(payload[0].payload[yKey])}`} - - - - {/* Display original value */} - - ); - } - return null; -}; - -InfrastructureTooltip.propTypes = { - active: PropTypes.bool, - payload: PropTypes.array, - label: PropTypes.oneOfType([ - PropTypes.instanceOf(Date), - PropTypes.string, - PropTypes.number, - ]), - yKey: PropTypes.string, - yIdx: PropTypes.number, - yLabel: PropTypes.string, - dotColor: PropTypes.string, - dateRange: PropTypes.string, -}; - -export const TemperatureTooltip = ({ - active, - payload, - label, - keys, - dotColor, - dateRange, -}) => { - const uiTimezone = useSelector((state) => state.ui.timezone); - const theme = useTheme(); - const format = tooltipDateFormatLookup(dateRange); - const formatCoreKey = (key) => { - return key.replace(/^core(\d+)$/, "Core $1"); - }; - if (active && payload && payload.length) { - return ( - - - {formatDateWithTz(label, format, uiTimezone)} - - - - {keys.map((key) => { - return ( - - - - - - {`${formatCoreKey(key)}: ${payload[0].payload[key]} °C`} - - - - - ); - })} - - - ); - } - return null; -}; - -TemperatureTooltip.propTypes = { - active: PropTypes.bool, - keys: PropTypes.array, - payload: PropTypes.array, - label: PropTypes.oneOfType([ - PropTypes.instanceOf(Date), - PropTypes.string, - PropTypes.number, - ]), - dotColor: PropTypes.string, - dateRange: PropTypes.string, -}; diff --git a/client/src/Components/v1/Charts/Utils/gradientUtils.jsx b/client/src/Components/v1/Charts/Utils/gradientUtils.jsx deleted file mode 100644 index b5920374d..000000000 --- a/client/src/Components/v1/Charts/Utils/gradientUtils.jsx +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Creates an SVG gradient definition for use in charts - * @param {Object} params - The gradient parameters - * @param {string} [params.id="colorUv"] - Unique identifier for the gradient - * @param {string} params.startColor - Starting color of the gradient (hex, rgb, or color name) - * @param {string} params.endColor - Ending color of the gradient (hex, rgb, or color name) - * @param {number} [params.startOpacity=0.8] - Starting opacity (0-1) - * @param {number} [params.endOpacity=0] - Ending opacity (0-1) - * @param {('vertical'|'horizontal')} [params.direction="vertical"] - Direction of the gradient - * @returns {JSX.Element} SVG gradient definition element - * @example - * createCustomGradient({ - * startColor: "#1976D2", - * endColor: "#42A5F5", - * direction: "horizontal" - * }) - */ - -export const createGradient = ({ - id, - startColor, - endColor, - startOpacity = 0.8, - endOpacity = 0, - direction = "vertical", // or "horizontal" -}) => ( - - - - - - -); diff --git a/client/src/Components/v1/Check/Check.jsx b/client/src/Components/v1/Check/Check.jsx deleted file mode 100644 index c40f3de3e..000000000 --- a/client/src/Components/v1/Check/Check.jsx +++ /dev/null @@ -1,80 +0,0 @@ -import "./check.css"; -import PropTypes from "prop-types"; -import Icon from "../Icon"; -import { Box, Stack, Typography } from "@mui/material"; -import { useTheme } from "@emotion/react"; - -/** - * `Check` is a functional React component that displays a check icon and a label. - * - * @component - * @param {Object} props - The properties that define the `Check` component. - * @param {string} props.text - The text to be displayed as the label next to the check icon. - * @param {'info' | 'error' | 'success'} [props.variant='info'] - The variant of the check component, affecting its styling. - * @param {boolean} [props.outlined] - Whether the check icon should be outlined or not. - * - * @example - * // To use this component, import it and use it in your JSX like this: - * - * - * @returns {React.Element} The `Check` component with a check icon and a label, defined by the `text` prop. - */ -const Check = ({ text, noHighlightText, variant = "info", outlined = false }) => { - const theme = useTheme(); - const colors = { - success: theme.palette.success.main, - error: theme.palette.error.main, - info: theme.palette.info.border, - }; - return ( - - {outlined ? ( - - ) : ( - - )} - - {noHighlightText && ( - - {noHighlightText} - - )}{" "} - {text} - - - ); -}; - -Check.propTypes = { - text: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), - noHighlightText: PropTypes.string, - variant: PropTypes.oneOf(["info", "error", "success"]), - outlined: PropTypes.bool, -}; - -export default Check; diff --git a/client/src/Components/v1/Check/check.css b/client/src/Components/v1/Check/check.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/Components/v1/CircularCount/index.jsx b/client/src/Components/v1/CircularCount/index.jsx deleted file mode 100644 index 8350a8c44..000000000 --- a/client/src/Components/v1/CircularCount/index.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Box } from "@mui/material"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -const CircularCount = ({ count }) => { - const theme = useTheme(); - return ( - - {count} - - ); -}; - -CircularCount.propTypes = { - count: PropTypes.number, -}; - -export default CircularCount; diff --git a/client/src/Components/v1/Common/AppBar.jsx b/client/src/Components/v1/Common/AppBar.jsx deleted file mode 100644 index 5cd3db5c1..000000000 --- a/client/src/Components/v1/Common/AppBar.jsx +++ /dev/null @@ -1,220 +0,0 @@ -import { useState } from "react"; -import { styled, alpha } from "@mui/material/styles"; -import Box from "@mui/material/Box"; -import AppBar from "@mui/material/AppBar"; -import Toolbar from "@mui/material/Toolbar"; -import Button from "@mui/material/Button"; -import IconButton from "@mui/material/IconButton"; -import Container from "@mui/material/Container"; -import MenuItem from "@mui/material/MenuItem"; -import Drawer from "@mui/material/Drawer"; -import Icon from "../Icon"; -import ThemeSwitch from "../ThemeSwitch/index.jsx"; -import { useTheme } from "@mui/material/styles"; -import { useSelector } from "react-redux"; -import { useLocation, useNavigate } from "react-router-dom"; - -const StyledToolbar = styled(Toolbar)(({ theme, mode }) => ({ - display: "flex", - alignItems: "center", - justifyContent: "space-between", - flexShrink: 0, - borderRadius: `calc(${theme.shape.borderRadius}px + 4px)`, - backdropFilter: "blur(24px)", - border: "1px solid", - borderColor: - mode === "light" - ? alpha(theme.palette.common.black, 0.1) - : alpha(theme.palette.common.white, 0.1), - backgroundColor: - mode === "light" - ? alpha(theme.palette.common.white, 0.4) - : alpha(theme.palette.common.black, 0.4), - boxShadow: theme.shadows[3], - padding: "8px 12px", -})); - -const StyledMenuItem = styled(MenuItem)(({ theme }) => ({ - fontSize: "1.1rem", - margin: theme.spacing(4, 2), -})); - -const AppAppBar = () => { - const [open, setOpen] = useState(false); - const theme = useTheme(); - const mode = useSelector((state) => state.ui.mode); - const location = useLocation(); - const navigate = useNavigate(); - - const logoSrc = - mode === "light" ? "/images/prism-black.png" : "/images/prism-white.png"; - - const toggleDrawer = (newOpen) => () => { - setOpen(newOpen); - }; - - const handleScroll = (id) => { - if (location.pathname === "/") { - const element = document.getElementById(id); - if (element) { - element.scrollIntoView({ behavior: "smooth" }); - } - } else { - navigate(`/#${id}`); - } - }; - - return ( - - - - - Prism Logo - - - - - - - - - {/* - */} - - - - - - - - - - - - - - Features - Testimonials - Highlights - FAQ - - Blog - - {/* - - - - - */} - - - - - - - - ); -}; - -export default AppAppBar; diff --git a/client/src/Components/v1/Common/Footer.jsx b/client/src/Components/v1/Common/Footer.jsx deleted file mode 100644 index 92f01a9ae..000000000 --- a/client/src/Components/v1/Common/Footer.jsx +++ /dev/null @@ -1,255 +0,0 @@ -import * as React from "react"; -import Box from "@mui/material/Box"; -import Container from "@mui/material/Container"; -import IconButton from "@mui/material/IconButton"; -import Link from "@mui/material/Link"; -import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import { FaFacebook, FaLinkedin, FaGithub, FaTwitter, FaEnvelope } from "react-icons/fa"; - -function Copyright() { - return ( - - {"Copyright © "} - - UpRock - -   - {new Date().getFullYear()} - - ); -} - -export default function Footer() { - return ( - - -
- - Privacy Policy - - -  •  - - - Terms of Service - - -
- - - - - - - - - - - - - - - - - -
- - - - Made with ❤️ by  - - UpRock  - - &  - - Bluewave Labs - - - - - Built on  - - - - - - - - - - - - - - - - - - - - -  Solana - - - -
- ); -} diff --git a/client/src/Components/v1/ConfigRow/index.jsx b/client/src/Components/v1/ConfigRow/index.jsx deleted file mode 100644 index 12fea923e..000000000 --- a/client/src/Components/v1/ConfigRow/index.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Box, Stack, Typography } from "@mui/material"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import ConfigBox from "../ConfigBox/index.jsx"; - -/** - * ConfigRow is a styled container used to layout content in a row format with specific padding, border, and spacing. - * It serves as the wrapper for ConfigBox, with the left section displaying the title and description, - * and the right section displaying the children. - * - * @component - * @example - * return ( - * - *
Left content (Title + Description)
- *
Right content (Children)
- *
- * ); - */ - -const ConfigRow = ({ title, description, children }) => { - const theme = useTheme(); - - return ( - - - - {title} - - {description && ( - - {description} - - )} - - - {children} - - - ); -}; - -ConfigRow.propTypes = { - title: PropTypes.string.isRequired, - description: PropTypes.string, - children: PropTypes.node, -}; - -export default ConfigRow; diff --git a/client/src/Components/v1/Dot/index.jsx b/client/src/Components/v1/Dot/index.jsx deleted file mode 100644 index 0676d0a6f..000000000 --- a/client/src/Components/v1/Dot/index.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from "prop-types"; - -const Dot = ({ color = "gray", size = "4px", style }) => { - return ( - - ); -}; - -Dot.propTypes = { - color: PropTypes.string, - size: PropTypes.string, -}; - -export default Dot; diff --git a/client/src/Components/v1/Fallback/FallBackActionButtons.jsx b/client/src/Components/v1/Fallback/FallBackActionButtons.jsx deleted file mode 100644 index 144b16501..000000000 --- a/client/src/Components/v1/Fallback/FallBackActionButtons.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Button, Stack } from "@mui/material"; -import { useTheme } from "@mui/material/styles"; -import { useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; -import PropTypes from "prop-types"; - -const FallbackActionButtons = ({ link, type }) => { - const theme = useTheme(); - const navigate = useNavigate(); - const { t } = useTranslation(); - - return ( - - - {type === "uptimeMonitor" && ( - - )} - - ); -}; -FallbackActionButtons.propTypes = { - title: PropTypes.string.isRequired, - link: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, -}; - -export default FallbackActionButtons; diff --git a/client/src/Components/v1/Fallback/FallbackBackground.jsx b/client/src/Components/v1/Fallback/FallbackBackground.jsx deleted file mode 100644 index 2182082fd..000000000 --- a/client/src/Components/v1/Fallback/FallbackBackground.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import { useTheme } from "@emotion/react"; -import Box from "@mui/material/Box"; -import Background from "../../../assets/Images/background-grid.svg?react"; -import OutputAnimation from "../../../assets/Animations/output.gif"; -import DarkmodeOutput from "../../../assets/Animations/darkmodeOutput.gif"; -import { useSelector } from "react-redux"; -const FallbackBackground = () => { - const theme = useTheme(); - const mode = useSelector((state) => state.ui.mode); - return ( - <> - - - - - - ); -}; - -export default FallbackBackground; diff --git a/client/src/Components/v1/Fallback/FallbackCheckList.jsx b/client/src/Components/v1/Fallback/FallbackCheckList.jsx deleted file mode 100644 index befb95185..000000000 --- a/client/src/Components/v1/Fallback/FallbackCheckList.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import PropTypes from "prop-types"; -import { useTheme } from "@mui/material/styles"; -import Box from "@mui/material/Box"; -import Stack from "@mui/material/Stack"; -import Check from "../Check/Check.jsx"; -const FallbackCheckList = ({ checks, type }) => { - const theme = useTheme(); - return ( - - {checks?.map((check, index) => ( - - ))} - - ); -}; - -FallbackCheckList.propTypes = { - checks: PropTypes.arrayOf(PropTypes.string).isRequired, - title: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, -}; - -export default FallbackCheckList; diff --git a/client/src/Components/v1/Fallback/FallbackContainer.jsx b/client/src/Components/v1/Fallback/FallbackContainer.jsx deleted file mode 100644 index 7a2ec5fe0..000000000 --- a/client/src/Components/v1/Fallback/FallbackContainer.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useTheme } from "@emotion/react"; -import { Box, Stack } from "@mui/material"; -import PropTypes from "prop-types"; - -const FallbackContainer = ({ children, type }) => { - const theme = useTheme(); - return ( - - - {children} - - - ); -}; - -FallbackContainer.propTypes = { - children: PropTypes.node, - type: PropTypes.string, -}; - -export default FallbackContainer; diff --git a/client/src/Components/v1/Fallback/FallbackPageSpeedWarning.jsx b/client/src/Components/v1/Fallback/FallbackPageSpeedWarning.jsx deleted file mode 100644 index 2cf52bd88..000000000 --- a/client/src/Components/v1/Fallback/FallbackPageSpeedWarning.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import Box from "@mui/material/Box"; -import { useTheme } from "@mui/material/styles"; -import Link from "@mui/material/Link"; -import { Link as RouterLink } from "react-router-dom"; -import { useTranslation } from "react-i18next"; -import Alert from "../Alert/index.jsx"; -import PropTypes from "prop-types"; - -const renderWarningMessage = (t) => { - return ( - <> - {t("pageSpeedWarning")}{" "} - - {t("pageSpeedLearnMoreLink")} - {" "} - {t("pageSpeedAddApiKey")} - - ); -}; - -const FallbackPageSpeedWarning = ({ settingsData }) => { - const theme = useTheme(); - const { t } = useTranslation(); - return ( - - svg": { - color: theme.palette.warningSecondary.contrastText, - }, - }, - }} - > - {settingsData?.pagespeedKeySet === false && ( - - )} - - - ); -}; - -FallbackPageSpeedWarning.propTypes = { - settingsData: PropTypes.shape({ - pagespeedKeySet: PropTypes.bool, - }), -}; - -export default FallbackPageSpeedWarning; diff --git a/client/src/Components/v1/Fallback/FallbackTitle.jsx b/client/src/Components/v1/Fallback/FallbackTitle.jsx deleted file mode 100644 index 69fee05c6..000000000 --- a/client/src/Components/v1/Fallback/FallbackTitle.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import { useTheme } from "@mui/material/styles"; -import { Typography } from "@mui/material"; -import PropTypes from "prop-types"; - -const FallbackTitle = ({ title }) => { - const theme = useTheme(); - return ( - - {title} - - ); -}; -FallbackTitle.propTypes = { - title: PropTypes.string.isRequired, -}; -export default FallbackTitle; diff --git a/client/src/Components/v1/Fallback/index.css b/client/src/Components/v1/Fallback/index.css deleted file mode 100644 index 6988fa5bf..000000000 --- a/client/src/Components/v1/Fallback/index.css +++ /dev/null @@ -1,40 +0,0 @@ -[class*="fallback__"] { - width: fit-content; - margin: auto; -} - -[class*="fallback__"] h1.MuiTypography-root { - font-size: var(--env-var-font-size-large); - font-weight: 600; -} - -[class*="fallback__"] button.MuiButtonBase-root, -[class*="fallback__"] .check { - width: max-content; -} - -[class*="fallback__"] button.MuiButtonBase-root { - min-height: 34px; -} - -[class*="fallback__"] .check span.MuiTypography-root, -[class*="fallback__"] button.MuiButtonBase-root { - font-size: var(--env-var-font-size-medium); -} - -[class*="fallback__"] .background-pattern-svg { - position: absolute; - top: 0; - left: 50%; - transform: translate(-50%, -50%); - z-index: 0; - - width: 100%; - max-width: 800px; - height: 100%; - max-height: 800px; - - background-position: center; - background-size: cover; - background-repeat: no-repeat; -} diff --git a/client/src/Components/v1/Fallback/index.jsx b/client/src/Components/v1/Fallback/index.jsx deleted file mode 100644 index 40113f882..000000000 --- a/client/src/Components/v1/Fallback/index.jsx +++ /dev/null @@ -1,75 +0,0 @@ -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import { Box, Stack } from "@mui/material"; -import "./index.css"; -import FallbackTitle from "./FallbackTitle.jsx"; -import FallbackCheckList from "./FallbackCheckList.jsx"; -import FallbackActionButtons from "./FallBackActionButtons.jsx"; -import FallbackBackground from "./FallbackBackground.jsx"; -import FallbackContainer from "./FallbackContainer.jsx"; -/** - * Fallback component to display a fallback UI with a title, a list of checks, and a navigation button. - * - * @param {Object} props - The component props. - * @param {string} props.title - The title to be displayed in the fallback UI. - * @param {string} props.type - The type of the fallback (e.g., "pageSpeed", "notifications"). - * @param {Array} props.checks - An array of strings representing the checks to display. - * @param {string} [props.link="/"] - The link to navigate to. - * @param {boolean} [props.showPageSpeedWarning=false] - Whether to show the PageSpeed API warning. - * @returns {JSX.Element} The rendered fallback UI. - */ - -const Fallback = ({ title, checks, link = "/", isAdmin, type, children }) => { - const theme = useTheme(); - return ( - - - - - - - - {isAdmin && ( - - - {children} - - )} - - - ); -}; -Fallback.propTypes = { - title: PropTypes.string.isRequired, - checks: PropTypes.arrayOf(PropTypes.string).isRequired, - link: PropTypes.string, - isAdmin: PropTypes.bool, - showPageSpeedWarning: PropTypes.bool, - type: PropTypes.string.isRequired, - children: PropTypes.node, -}; -export default Fallback; diff --git a/client/src/Components/v1/GenericFallback/NetworkError.jsx b/client/src/Components/v1/GenericFallback/NetworkError.jsx deleted file mode 100644 index ddffa1c31..000000000 --- a/client/src/Components/v1/GenericFallback/NetworkError.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Typography } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import { useTranslation } from "react-i18next"; - -const NetworkError = () => { - const theme = useTheme(); - const { t } = useTranslation(); - - return ( - <> - - {t("common.toasts.networkError")} - - {t("common.toasts.checkConnection")} - - ); -}; - -export default NetworkError; diff --git a/client/src/Components/v1/GenericFallback/index.jsx b/client/src/Components/v1/GenericFallback/index.jsx deleted file mode 100644 index 188c09f37..000000000 --- a/client/src/Components/v1/GenericFallback/index.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import { useTheme } from "@emotion/react"; -import { Box, Stack } from "@mui/material"; -import OutputAnimation from "../../../assets/Animations/output.gif"; -import DarkmodeOutput from "../../../assets/Animations/darkmodeOutput.gif"; -import Background from "../../../assets/Images/background-grid.svg?react"; -import { useSelector } from "react-redux"; - -/** - * Fallback component to display a fallback UI for network errors - * - * @returns {JSX.Element} The rendered fallback UI. - */ - -const GenericFallback = ({ children }) => { - const theme = useTheme(); - const mode = useSelector((state) => state.ui.mode); - - return ( - - - - - - - - {children} - - - - ); -}; - -export default GenericFallback; diff --git a/client/src/Components/v1/Heading/index.jsx b/client/src/Components/v1/Heading/index.jsx deleted file mode 100644 index 1a5f1a53b..000000000 --- a/client/src/Components/v1/Heading/index.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Typography } from "@mui/material"; -import PropTypes from "prop-types"; - -/** - * A heading component that renders text with a specific heading level. - * - * @param {Object} props - The properties passed to the Heading component. - * @param {('h1'|'h2'|'h3')} props.component - The heading level for the component. - * @param {Object} props.style - Custom styles to apply to the heading. - * @param {string} props.children - The content to display inside the heading. - * @returns {JSX.Element} The Typography component with specified heading properties. - */ - -function Heading({ component, style, children }) { - return ( - - {children} - - ); -} - -Heading.propTypes = { - component: PropTypes.oneOf(["h1", "h2", "h3"]).isRequired, - style: PropTypes.object, - children: PropTypes.string.isRequired, -}; -export { Heading }; diff --git a/client/src/Components/v1/Host/index.jsx b/client/src/Components/v1/Host/index.jsx deleted file mode 100644 index 6670722c1..000000000 --- a/client/src/Components/v1/Host/index.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Stack, Typography } from "@mui/material"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import Dot from "../Dot/index.jsx"; -import { StatusLabel } from "@/Components/v1/Label/index.jsx"; -/** - * Host component. - * This subcomponent receives a params object and displays the host details. - * - * @component - * @param {Object} params - An object containing the following properties: - * @param {string} params.url - The URL of the host. - * @param {string} params.title - The name of the host. - * @param {string} params.percentageColor - The color of the percentage text. - * @param {number} params.percentage - The percentage to display. - * @returns {React.ElementType} Returns a div element with the host details. - */ -const Host = ({ url, title, percentageColor, percentage, showURL, status }) => { - const theme = useTheme(); - return ( - - - - {title} - - - {percentageColor && percentage && ( - <> - - - {percentage}% - - {status && ( - - )} - - )} - - {showURL && {url}} - - ); -}; - -Host.propTypes = { - title: PropTypes.string, - percentageColor: PropTypes.string, - percentage: PropTypes.string, - url: PropTypes.string, - showURL: PropTypes.bool, - status: PropTypes.string, -}; - -export default Host; diff --git a/client/src/Components/v1/HttpStatusLabel/index.jsx b/client/src/Components/v1/HttpStatusLabel/index.jsx deleted file mode 100644 index 2253e323e..000000000 --- a/client/src/Components/v1/HttpStatusLabel/index.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from "prop-types"; -import { useTheme } from "@mui/material"; -import { BaseLabel } from "../Label/index.jsx"; - -/** - * @component - * @param {Object} props - * @param {number} props.status - The http status for the label - * @param {Styles} props.customStyles - CSS Styles passed from parent component - * @returns {JSX.Element} - * @example - * // Render a http status label - * - */ - -const DEFAULT_CODE = 9999; // Default code for unknown status - -const handleStatusCode = (status) => { - if (status) { - return status; - } - return DEFAULT_CODE; -}; - -const getRoundedStatusCode = (status) => { - return Math.floor(status / 100) * 100; -}; - -const HttpStatusLabel = ({ status, customStyles }) => { - const theme = useTheme(); - const colors = { - 400: { - color: theme.palette.warning.main, - borderColor: theme.palette.warning.lowContrast, - }, - 500: { - color: theme.palette.error.main, - borderColor: theme.palette.error.lowContrast, - }, - default: { - color: theme.palette.primary.contrastText, - borderColor: theme.palette.primary.contrastText, - }, - }; - - const statusCode = handleStatusCode(status); - - const { borderColor, color } = - colors[getRoundedStatusCode(statusCode)] || colors.default; - return ( - - ); -}; - -HttpStatusLabel.propTypes = { - status: PropTypes.number, - customStyles: PropTypes.object, -}; - -export { HttpStatusLabel }; diff --git a/client/src/Components/v1/IconBox/index.jsx b/client/src/Components/v1/IconBox/index.jsx deleted file mode 100644 index bb9770e6a..000000000 --- a/client/src/Components/v1/IconBox/index.jsx +++ /dev/null @@ -1,77 +0,0 @@ -import { Box, styled } from "@mui/material"; -import PropTypes from "prop-types"; - -/** - * IconBox - A styled box component for rendering icons with consistent sizing and styling - * - * @component - * @param {Object} [props] - Configuration options for the IconBox - * @param {number} [props.height=34] - Height of the icon box - * @param {number} [props.width=34] - Width of the icon box - * @param {number} [props.minWidth=34] - Minimum width of the icon box - * @param {number} [props.borderRadius=4] - Border radius of the icon box - * @param {number} [props.svgWidth=20] - Width of the SVG icon - * @param {number} [props.svgHeight=20] - Height of the SVG icon - * - * @example - * // Basic usage - * - * - * - * - * @example - * // Customized usage - * - * - * - * - * @returns {React.ReactElement} A styled box containing an icon - */ -const IconBox = styled(Box)( - ({ - theme, - height = 34, - width = 34, - minWidth = 34, - borderRadius = 4, - svgWidth = 20, - svgHeight = 20, - }) => ({ - height: height, - minWidth: minWidth, - width: width, - position: "relative", - border: 1, - borderStyle: "solid", - borderColor: theme.palette.primary.lowContrast, - borderRadius: borderRadius, - backgroundColor: theme.palette.tertiary.main, - "& svg": { - position: "absolute", - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)", - width: svgWidth, - height: svgHeight, - "& path": { - stroke: theme.palette.primary.contrastTextTertiary, - }, - }, - }) -); - -IconBox.propTypes = { - height: PropTypes.number, - width: PropTypes.number, - minWidth: PropTypes.number, - borderRadius: PropTypes.number, - svgWidth: PropTypes.number, - svgHeight: PropTypes.number, -}; - -export default IconBox; diff --git a/client/src/Components/v1/Image/index.jsx b/client/src/Components/v1/Image/index.jsx deleted file mode 100644 index 8f30f8a9e..000000000 --- a/client/src/Components/v1/Image/index.jsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Box } from "@mui/material"; -import PropTypes from "prop-types"; - -const isValidBase64Image = (data) => { - return /^[A-Za-z0-9+/=]+$/.test(data); -}; - -const Image = ({ - shouldRender = true, - src, - alt, - width = "auto", - height = "auto", - minWidth = "auto", - minHeight = "auto", - maxWidth = "auto", - maxHeight = "auto", - base64, - placeholder, - sx, -}) => { - if (shouldRender === false) { - return null; - } - - if (typeof src !== "undefined" && typeof base64 !== "undefined") { - console.warn("base64 takes precedence over src and overwrites it"); - } - - if (typeof base64 !== "undefined" && isValidBase64Image(base64)) { - src = `data:image/png;base64,${base64}`; - } - - if ( - typeof src === "undefined" && - typeof base64 === "undefined" && - typeof placeholder !== "undefined" - ) { - src = placeholder; - } - - return ( - - ); -}; - -Image.propTypes = { - shouldRender: PropTypes.bool, - src: PropTypes.string, - alt: PropTypes.string.isRequired, - width: PropTypes.string, - height: PropTypes.string, - minWidth: PropTypes.string, - minHeight: PropTypes.string, - maxWidth: PropTypes.string, - maxHeight: PropTypes.string, - base64: PropTypes.string, - sx: PropTypes.object, -}; - -export default Image; diff --git a/client/src/Components/v1/InfoBox/index.jsx b/client/src/Components/v1/InfoBox/index.jsx deleted file mode 100644 index 96e67975d..000000000 --- a/client/src/Components/v1/InfoBox/index.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import { RowContainer } from "../StandardContainer/index.jsx"; -import { Stack, Typography } from "@mui/material"; -import Image from "../Image/index.jsx"; - -import { useTheme } from "@mui/material/styles"; - -const InfoBox = ({ - img, - icon: Icon, - alt, - heading, - headingLevel = 2, - subHeading, - subHeadingLevel = "", - sx, -}) => { - const theme = useTheme(); - return ( - - {img && ( - {alt} - )} - {Icon && ( - - )} - - {heading} - - {subHeading} - - - - ); -}; - -export default InfoBox; diff --git a/client/src/Components/v1/MonitorCreateHeader/index.jsx b/client/src/Components/v1/MonitorCreateHeader/index.jsx deleted file mode 100644 index c3a979eb9..000000000 --- a/client/src/Components/v1/MonitorCreateHeader/index.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Stack, Button } from "@mui/material"; -import { useNavigate } from "react-router-dom"; -import PropTypes from "prop-types"; -import { useTranslation } from "react-i18next"; -import { useTheme } from "@emotion/react"; - -const CreateMonitorHeader = ({ isAdmin, label, isLoading = true, path, bulkPath }) => { - const navigate = useNavigate(); - const { t } = useTranslation(); - const theme = useTheme(); - - // Use the provided label or fall back to the translated default - - if (!isAdmin) return null; - - return ( - - - {/* {bulkPath && } */} - - ); -}; - -export default CreateMonitorHeader; - -CreateMonitorHeader.propTypes = { - isAdmin: PropTypes.bool.isRequired, - isLoading: PropTypes.bool, - path: PropTypes.string.isRequired, - label: PropTypes.string, - bulkPath: PropTypes.string, -}; diff --git a/client/src/Components/v1/MonitorCreateHeader/skeleton.jsx b/client/src/Components/v1/MonitorCreateHeader/skeleton.jsx deleted file mode 100644 index 7583f7849..000000000 --- a/client/src/Components/v1/MonitorCreateHeader/skeleton.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; - -const SkeletonLayout = () => { - return ( - - - - ); -}; - -export default SkeletonLayout; diff --git a/client/src/Components/v1/MonitorTimeFrameHeader/index.jsx b/client/src/Components/v1/MonitorTimeFrameHeader/index.jsx deleted file mode 100644 index 9d57edc41..000000000 --- a/client/src/Components/v1/MonitorTimeFrameHeader/index.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import { Stack, Typography, Button, ButtonGroup } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import SkeletonLayout from "./skeleton.jsx"; -import PropTypes from "prop-types"; - -const MonitorTimeFrameHeader = ({ - isLoading = false, - hasDateRange = true, - dateRange, - setDateRange, -}) => { - const theme = useTheme(); - - if (isLoading) { - return ; - } - - let timeFramePicker = null; - - if (hasDateRange) { - timeFramePicker = ( - - - - - - - ); - } - - return ( - - - Showing statistics for past{" "} - {dateRange === "recent" - ? "2 hours" - : dateRange === "day" - ? "24 hours" - : dateRange === "week" - ? "7 days" - : "30 days"} - . - - {timeFramePicker} - - ); -}; - -MonitorTimeFrameHeader.propTypes = { - isLoading: PropTypes.bool, - hasDateRange: PropTypes.bool, - dateRange: PropTypes.string, - setDateRange: PropTypes.func, -}; - -export default MonitorTimeFrameHeader; diff --git a/client/src/Components/v1/MonitorTimeFrameHeader/skeleton.jsx b/client/src/Components/v1/MonitorTimeFrameHeader/skeleton.jsx deleted file mode 100644 index d7c395d54..000000000 --- a/client/src/Components/v1/MonitorTimeFrameHeader/skeleton.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; - -const SkeletonLayout = () => { - return ( - - - - - ); -}; - -export default SkeletonLayout; diff --git a/client/src/Components/v1/PageStateWrapper/index.jsx b/client/src/Components/v1/PageStateWrapper/index.jsx deleted file mode 100644 index 08adbe514..000000000 --- a/client/src/Components/v1/PageStateWrapper/index.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import GenericFallback from "../GenericFallback/index.jsx"; -import Fallback from "../Fallback/index.jsx"; -import { Typography } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import { useTranslation } from "react-i18next"; -import { useIsAdmin } from "@/Hooks/useIsAdmin.js"; -import PropTypes from "prop-types"; -const PageStateWrapper = ({ - networkError, - isLoading, - items, - type, - fallbackLink, - fallbackChildren, - children, -}) => { - const theme = useTheme(); - const { t } = useTranslation(); - const isAdmin = useIsAdmin(); - const isEmpty = items === null || (Array.isArray(items) && items.length === 0); - const hasInitialized = items !== undefined && !(isLoading && isEmpty); - const showEmpty = !isLoading && isEmpty; - if (networkError) { - return ( - - - {t("common.toasts.networkError")} - - {t("common.toasts.checkConnection")} - - ); - } - if (!hasInitialized) { - return null; - } - if (showEmpty) { - return ( - - {fallbackChildren} - - ); - } - return <>{children}; -}; - -PageStateWrapper.propTypes = { - networkError: PropTypes.any, - isLoading: PropTypes.bool, - items: PropTypes.oneOfType([PropTypes.array, PropTypes.oneOf([null])]), - type: PropTypes.string, - fallbackLink: PropTypes.string, - fallbackChildren: PropTypes.node, - children: PropTypes.node, -}; - -export default PageStateWrapper; diff --git a/client/src/Components/v1/ProgressBars/index.css b/client/src/Components/v1/ProgressBars/index.css deleted file mode 100644 index 9b4ab2c7d..000000000 --- a/client/src/Components/v1/ProgressBars/index.css +++ /dev/null @@ -1,10 +0,0 @@ -.progress-bar-container h2.MuiTypography-root, -.progress-bar-container p.MuiTypography-root { - font-size: var(--env-var-font-size-medium); -} -.progress-bar-container p.MuiTypography-root:has(span) { - font-size: 12px; -} -.progress-bar-container p.MuiTypography-root span { - padding-left: 2px; -} diff --git a/client/src/Components/v1/ProgressBars/index.jsx b/client/src/Components/v1/ProgressBars/index.jsx deleted file mode 100644 index 86cedcbaa..000000000 --- a/client/src/Components/v1/ProgressBars/index.jsx +++ /dev/null @@ -1,180 +0,0 @@ -import { useTheme } from "@emotion/react"; -import PropTypes from "prop-types"; -import { Box, IconButton, LinearProgress, Stack, Typography } from "@mui/material"; -import Icon from "../Icon"; -import "./index.css"; - -/** - * @param {Object} props - The component props. - * @param {JSX.Element} props.icon - The icon element to display (optional). - * @param {string} props.label - The label text for the progress item. - * @param {string} props.size - The size information for the progress item. - * @param {number} props.progress - The current progress value (0-100). - * @param {function} props.onClick - The function to handle click events on the remove button. - * @param {string} props.error - Error message to display if there's an error (optional). - * @returns {JSX.Element} The rendered component. - */ - -const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) => { - const theme = useTheme(); - - return ( - .MuiStack-root > svg": { - fill: theme.palette.error.contrastText, - width: "20px", - height: "20px", - }, - }, - }} - > - - {error ? ( - - ) : icon ? ( - - {icon} - - ) : ( - "" - )} - {error ? ( - - {error} - - ) : ( - - - {error ? error : label} - - - {!error && size} - - - )} - - - - - {!error ? ( - - - - - - {progress} - % - - - ) : ( - "" - )} - - ); -}; - -ProgressUpload.propTypes = { - icon: PropTypes.element, // JSX element for the icon (optional) - label: PropTypes.string, // Label text for the progress item - size: PropTypes.string.isRequired, // Size information for the progress item - progress: PropTypes.number.isRequired, // Current progress value (0-100) - onClick: PropTypes.func.isRequired, // Function to handle click events on the remove button - error: PropTypes.string, // Error message to display if there's an error (optional) -}; - -export default ProgressUpload; diff --git a/client/src/Components/v1/ProgressStepper/index.css b/client/src/Components/v1/ProgressStepper/index.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/src/Components/v1/ProgressStepper/index.jsx b/client/src/Components/v1/ProgressStepper/index.jsx deleted file mode 100644 index 9fb0d15dc..000000000 --- a/client/src/Components/v1/ProgressStepper/index.jsx +++ /dev/null @@ -1,74 +0,0 @@ -import React from "react"; -import { Step, Stepper, StepLabel, Typography } from "@mui/material"; -import Icon from "../Icon"; -import PropTypes from "prop-types"; - -const CustomStepIcon = (props) => { - const { completed, active } = props; - return completed ? ( - - ) : ( - - ); -}; - -CustomStepIcon.propTypes = { - completed: PropTypes.bool.isRequired, - active: PropTypes.bool.isRequired, -}; - -/** - * @component - * @param {Object} props - * @param {Array} props.steps - */ - -const ProgressStepper = ({ steps }) => { - const [activeStep, setActiveStep] = React.useState(1); - return ( - - {steps.map((step, index) => { - const color = activeStep === index ? "primary" : "inherit"; - return ( - setActiveStep(index)} - > - - - {step.label} - - - - {step.content} - - - ); - })} - - ); -}; - -ProgressStepper.propTypes = { - steps: PropTypes.array.isRequired, -}; - -export default ProgressStepper; diff --git a/client/src/Components/v1/ShareComponent/index.jsx b/client/src/Components/v1/ShareComponent/index.jsx deleted file mode 100644 index 476b3672f..000000000 --- a/client/src/Components/v1/ShareComponent/index.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import html2canvas from "html2canvas"; -import Icon from "../Icon"; -import { Button } from "@mui/material"; -import { useTheme } from "@emotion/react"; - -const ShareComponent = ({ elementToCapture, fileName = "screenshot" }) => { - const theme = useTheme(); - const captureAndShare = async () => { - try { - // Temporarily apply styles directly to the element - const originalBackground = elementToCapture.current.style.background; - const originalPadding = elementToCapture.current.style.padding; - - elementToCapture.current.style.background = `radial-gradient(circle, ${theme.palette.gradient.color1}, ${theme.palette.gradient.color2}, ${theme.palette.gradient.color3}, ${theme.palette.gradient.color4}, ${theme.palette.gradient.color5})`; - elementToCapture.current.style.padding = `${theme.spacing(20)}`; - - // Capture the element directly - const canvas = await html2canvas(elementToCapture.current, { - useCORS: true, - scale: 2, - allowTaint: true, - backgroundColor: null, - }); - - // Restore original styles - elementToCapture.current.style.background = originalBackground; - elementToCapture.current.style.padding = originalPadding; - - const imageBlob = await new Promise((resolve) => - canvas.toBlob(resolve, "image/png") - ); - - const file = new File([imageBlob], `${fileName}.png`, { - type: "image/png", - }); - - if (navigator.share) { - await navigator.share({ - files: [file], - title: "Screenshot", - text: "Check out this screenshot!", - }); - } else { - const url = URL.createObjectURL(imageBlob); - const a = document.createElement("a"); - a.href = url; - a.download = `${fileName}.png`; - a.click(); - URL.revokeObjectURL(url); - } - } catch (error) { - console.error(error); - } - }; - return ( - - ); -}; - -export default ShareComponent; diff --git a/client/src/Components/v1/Skeletons/FullPage/index.jsx b/client/src/Components/v1/Skeletons/FullPage/index.jsx deleted file mode 100644 index 233fc3c06..000000000 --- a/client/src/Components/v1/Skeletons/FullPage/index.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; - -export const SkeletonLayout = () => { - return ( - - - - ); -}; - -export default SkeletonLayout; diff --git a/client/src/Components/v1/StandardContainer/index.jsx b/client/src/Components/v1/StandardContainer/index.jsx deleted file mode 100644 index c736b3ecc..000000000 --- a/client/src/Components/v1/StandardContainer/index.jsx +++ /dev/null @@ -1,51 +0,0 @@ -// Components -import { Stack } from "@mui/material"; - -// Utils -import { useTheme } from "@emotion/react"; - -const Container = ({ children, direction, backgroundColor, sx }) => { - const theme = useTheme(); - let bgColor = - typeof backgroundColor !== "undefined" - ? backgroundColor - : theme.palette.background.main; - return ( - - {children} - - ); -}; - -export const ColContainer = ({ children, backgroundColor, sx }) => { - return ( - - {children} - - ); -}; - -export const RowContainer = ({ children, backgroundColor, sx }) => { - return ( - - {children} - - ); -}; diff --git a/client/src/Components/v1/StatusBoxes/index.jsx b/client/src/Components/v1/StatusBoxes/index.jsx deleted file mode 100644 index a78337ba7..000000000 --- a/client/src/Components/v1/StatusBoxes/index.jsx +++ /dev/null @@ -1,37 +0,0 @@ -// Components -import { Stack } from "@mui/material"; -import SkeletonLayout from "./skeleton.jsx"; -// Utils -import { useTheme } from "@mui/material/styles"; -import PropTypes from "prop-types"; -const StatusBoxes = ({ shouldRender = true, flexWrap = "nowrap", children }) => { - const theme = useTheme(); - if (!shouldRender) { - return ( - - ); - } - - return ( - - {children} - - ); -}; - -StatusBoxes.propTypes = { - shouldRender: PropTypes.bool, - flexWrap: PropTypes.string, - children: PropTypes.node, -}; - -export default StatusBoxes; diff --git a/client/src/Components/v1/StatusBoxes/skeleton.jsx b/client/src/Components/v1/StatusBoxes/skeleton.jsx deleted file mode 100644 index bc8b18251..000000000 --- a/client/src/Components/v1/StatusBoxes/skeleton.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Stack, Skeleton } from "@mui/material"; -import { useTheme } from "@emotion/react"; -import PropTypes from "prop-types"; -const SkeletonLayout = ({ numBoxes, flexWrap }) => { - const theme = useTheme(); - return ( - - {Array.from({ length: numBoxes }).map((_, index) => { - const width = `${200 / numBoxes}%`; - return ( - - ); - })} - - ); -}; - -SkeletonLayout.propTypes = { - flexWrap: PropTypes.string, - numBoxes: PropTypes.number, -}; - -export default SkeletonLayout; diff --git a/client/src/Components/v1/Subheader/index.jsx b/client/src/Components/v1/Subheader/index.jsx deleted file mode 100644 index a76696567..000000000 --- a/client/src/Components/v1/Subheader/index.jsx +++ /dev/null @@ -1,83 +0,0 @@ -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import { Stack, Typography } from "@mui/material"; - -/** - - * - * @component - * @example - * - * @param {boolean} props.shouldRender - Whether to render the subheader - * @param {string} props.direction - Direction of the subheader - * @param {string} props.headerText - Header text - * @param {number} props.headerLevel - Font characteristic of the header - * @param {string} props.subHeaderText - Subheader text - * @param {number} props.subHeaderLevel - Font characteristic of the subheader - * @param {string} props.alignItems - Align items - * @param {node} props.children - Children - * @returns {JSX.Element} The rendered component - */ - -const SubHeader = ({ - shouldRender = true, - direction = "row", - headerText, - headerLevel = 1, - subHeaderText, - subHeaderLevel = 1, - alignItems = "center", - children, - ...props -}) => { - const theme = useTheme(); - - if (!shouldRender) { - return null; - } - - return ( - - - - - {headerText} - - - - {subHeaderText} - - - {children} - - ); -}; - -SubHeader.propTypes = { - shouldRender: PropTypes.bool, - direction: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - headerText: PropTypes.string, - headerLevel: PropTypes.number, - subHeaderText: PropTypes.string, - subHeaderLevel: PropTypes.number, - alignItems: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - children: PropTypes.node, -}; - -export default SubHeader; diff --git a/client/src/Components/v1/Tab/index.jsx b/client/src/Components/v1/Tab/index.jsx deleted file mode 100644 index 7609904d9..000000000 --- a/client/src/Components/v1/Tab/index.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Box, useTheme } from "@mui/material"; -import { TabList } from "@mui/lab"; -import PropTypes from "prop-types"; - -/** - * CustomTabList component - * @param {string} value - The currently selected tab's value. - * @param {function} onChange - Callback when a different tab is selected. - * @param {React.ReactNode} children - Tab components to render inside the TabList. - * @param {object} props - Additional props passed to the TabList component. - */ - -const CustomTabList = ({ value, onChange, children, ...props }) => { - const theme = useTheme(); - - return ( - - - {children} - - - ); -}; - -CustomTabList.propTypes = { - value: PropTypes.string, - onChange: PropTypes.func, - children: PropTypes.node, -}; - -export default CustomTabList; diff --git a/client/src/Components/v1/Table/TablePagination/Actions/index.jsx b/client/src/Components/v1/Table/TablePagination/Actions/index.jsx deleted file mode 100644 index 0df62878e..000000000 --- a/client/src/Components/v1/Table/TablePagination/Actions/index.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import PropTypes from "prop-types"; -import { Box, Button } from "@mui/material"; -import LeftArrow from "../../../ArrowLeft/index.jsx"; -import RightArrow from "../../../ArrowRight/index.jsx"; -import { useTheme } from "@emotion/react"; - -TablePaginationActions.propTypes = { - count: PropTypes.number.isRequired, - page: PropTypes.number.isRequired, - rowsPerPage: PropTypes.number.isRequired, - onPageChange: PropTypes.func.isRequired, -}; - -/** - * Component for pagination actions (first, previous, next, last). - * - * @component - * @param {Object} props - * @param {number} props.count - Total number of items. - * @param {number} props.page - Current page number. - * @param {number} props.rowsPerPage - Number of rows per page. - * @param {function} props.onPageChange - Callback function to handle page change. - * - * @returns {JSX.Element} Pagination actions component. - */ - -function TablePaginationActions({ count, page, rowsPerPage, onPageChange }) { - const handleFirstPageButtonClick = (event) => { - onPageChange(event, 0); - }; - const handleBackButtonClick = (event) => { - onPageChange(event, page - 1); - }; - const handleNextButtonClick = (event) => { - onPageChange(event, page + 1); - }; - const handleLastPageButtonClick = (event) => { - onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1)); - }; - - const theme = useTheme(); - - return ( - - - - - - - ); -} - -export { TablePaginationActions }; diff --git a/client/src/Components/v1/Table/TablePagination/index.jsx b/client/src/Components/v1/Table/TablePagination/index.jsx deleted file mode 100644 index 77ee5ded1..000000000 --- a/client/src/Components/v1/Table/TablePagination/index.jsx +++ /dev/null @@ -1,144 +0,0 @@ -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; -import { Stack, TablePagination, Typography } from "@mui/material"; -import { TablePaginationActions } from "./Actions/index.jsx"; -import Icon from "../../Icon"; - -Pagination.propTypes = { - paginationLabel: PropTypes.string, // Label for the pagination. - itemCount: PropTypes.number, // Total number of items for pagination. - page: PropTypes.number, // Current page index. - rowsPerPage: PropTypes.number, // Number of rows displayed per page. - handleChangePage: PropTypes.func.isRequired, // Function to handle page changes. - handleChangeRowsPerPage: PropTypes.func, // Function to handle changes in rows per page. -}; - -const ROWS_PER_PAGE_OPTIONS = [5, 10, 15, 25]; - -// Determine whether pagination buttons should be shown -const shouldShowPaginationButtons = (itemCount, rowsPerPage) => { - return Math.ceil(itemCount / rowsPerPage) > 1; -}; - -// Empty action component for pagination (no-op component) -const EmptyPaginationActions = () =>
; - -/** - * Pagination component for table navigation with customized styling and behavior. - * - * @param {object} props - Component properties. - * @param {string} props.paginationLabel - Label for the pagination. - * @param {number} props.monitorCount - Total number of monitors to paginate. - * @param {number} props.page - Current page index (0-based). - * @param {number} props.rowsPerPage - Number of rows to display per page. - * @param {function} props.handleChangePage - Callback for handling page changes. - * @param {function} props.handleChangeRowsPerPage - Callback for handling changes to rows per page. - * @returns {JSX.Element} The Pagination component. - */ -function Pagination({ - paginationLabel, - itemCount = 0, - page = 0, - rowsPerPage = 5, - handleChangePage, - handleChangeRowsPerPage, -}) { - const theme = useTheme(); - - const start = page * rowsPerPage + 1; - const end = Math.min(page * rowsPerPage + rowsPerPage, itemCount); - const range = `${start} - ${end}`; - - const showPaginationButtons = shouldShowPaginationButtons(itemCount, rowsPerPage); - - return ( - - - Showing {range} of {itemCount} {paginationLabel} - - - `Page ${page + 1} of ${Math.max(0, Math.ceil(count / rowsPerPage))}` - } - slotProps={{ - select: { - MenuProps: { - keepMounted: true, - disableScrollLock: true, - PaperProps: { - className: "pagination-dropdown", - sx: { - mt: 0, - mb: theme.spacing(2), - }, - }, - transformOrigin: { vertical: "bottom", horizontal: "left" }, - anchorOrigin: { vertical: "top", horizontal: "left" }, - sx: { - mt: theme.spacing(-2), - }, - }, - inputProps: { id: "pagination-dropdown" }, - IconComponent: () => ( - - ), - sx: { - ml: theme.spacing(4), - mr: theme.spacing(12), - minWidth: theme.spacing(20), - textAlign: "left", - "&.Mui-focused > div": { - backgroundColor: theme.palette.primary.main, - }, - "& .MuiSelect-icon": { - // Add this style override - position: "absolute", - right: 0, - top: "50%", - transform: "translateY(-50%)", - }, - }, - }, - }} - sx={{ - color: theme.palette.primary.contrastTextSecondary, - "& svg path": { - stroke: theme.palette.primary.contrastTextTertiary, - strokeWidth: 1.3, - }, - "& .MuiSelect-select": { - border: 1, - borderColor: theme.palette.primary.lowContrast, - borderRadius: theme.shape.borderRadius, - }, - }} - /> - - ); -} - -export default Pagination; diff --git a/client/src/Components/v1/Table/TableUtils.js b/client/src/Components/v1/Table/TableUtils.js deleted file mode 100644 index a9f95a5b7..000000000 --- a/client/src/Components/v1/Table/TableUtils.js +++ /dev/null @@ -1,11 +0,0 @@ -export const createHeaderFactory = (getCellSx = () => {}) => { - return ({ id, content, onClick = () => {}, render = () => {} }) => { - return { - id, - content, - onClick, - getCellSx, - render, - }; - }; -}; diff --git a/client/src/Components/v1/Table/index.jsx b/client/src/Components/v1/Table/index.jsx deleted file mode 100644 index 2113a2215..000000000 --- a/client/src/Components/v1/Table/index.jsx +++ /dev/null @@ -1,180 +0,0 @@ -import { - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, -} from "@mui/material"; -import Tooltip from "@mui/material/Tooltip"; -import SkeletonLayout from "./skeleton.jsx"; -import PropTypes from "prop-types"; -import { useTheme } from "@emotion/react"; - -/** - * @typedef {Object} Header - * @property {number|string} id - The unique identifier for the header. - * @property {React.ReactNode} content - The content to display in the header cell. - * @property {Function} onClick - A function to be called when this cell is clicked, receiving the event and row data as an argument. - * @property {Object} getCellSx - Function that takes a row and returns a style object for the table cell. - * @property {Function} render - A function to render the cell content for a given row. - */ - -/** - * @typedef {Object} Config - * @property {Function} onRowClick - A function to be called when a row is clicked, receiving the row data as an argument. - * @property {Object} rowSX - Style object for the table row. - */ - -/** - * DataTable component renders a table with headers and data. - * - * @param {Object} props - The component props. - * @param {Header[]} props.headers - An array of header objects, each containing an `id`, `content`, and `render` function. - * @param {Array} props.data - An array of data objects, each representing a row. - * @returns {JSX.Element} The rendered table component. - */ - -const DataTable = ({ - shouldRender = true, - headers = [], - data = [], - config = { - emptyView: "No data", - tooltipContent: null, - onRowClick: () => {}, - }, -}) => { - const theme = useTheme(); - if (!shouldRender) { - return ; - } - - if ((headers?.length ?? 0) === 0) { - return "No data"; - } - - return ( - - - - - {headers.map((header, index) => ( - - {header.content} - - ))} - - - - {(data?.length ?? 0) === 0 ? ( - - - {config.emptyView} - - - ) : ( - data.map((row) => { - const key = row.id || row._id || Math.random(); - return ( - { - return [popper.width / 2 + 20, -popper.height / 8]; - }, - }, - }, - ], - }, - }} - > - config.onRowClick(row) : null} - > - {headers.map((header, index) => { - return ( - header.onClick(e, row) : null} - sx={header.getCellSx ? header.getCellSx(row) : {}} - > - {header.render(row)} - - ); - })} - - - ); - }) - )} - -
-
- ); -}; - -DataTable.propTypes = { - shouldRender: PropTypes.bool, - headers: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, - content: PropTypes.node.isRequired, - render: PropTypes.func.isRequired, - }) - ).isRequired, - data: PropTypes.array, - config: PropTypes.shape({ - onRowClick: PropTypes.func, - rowSX: PropTypes.object, - emptyView: PropTypes.node, - }), -}; - -export default DataTable; diff --git a/client/src/Components/v1/Table/skeleton.jsx b/client/src/Components/v1/Table/skeleton.jsx deleted file mode 100644 index 062d39156..000000000 --- a/client/src/Components/v1/Table/skeleton.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Skeleton } from "@mui/material"; - -const TableSkeleton = () => { - return ( - - ); -}; - -export default TableSkeleton;