mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-21 17:19:00 -05:00
Merge pull request #703 from bluewave-labs/feat/status-dot-animated
Feat/status dot animated
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Box, Stack } from "@mui/material";
|
||||
|
||||
/**
|
||||
* A component that renders a pulsating dot with a specified color.
|
||||
*
|
||||
* @component
|
||||
* @example
|
||||
* // Example usage:
|
||||
* <PulseDot color="#f00" />
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {string} props.color - The color of the dot.
|
||||
* @returns {JSX.Element} The PulseDot component.
|
||||
*/
|
||||
|
||||
const PulseDot = ({ color }) => {
|
||||
return (
|
||||
<Stack
|
||||
width="26px"
|
||||
height="24px"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Box
|
||||
minWidth="16px"
|
||||
minHeight="16px"
|
||||
sx={{
|
||||
position: "relative",
|
||||
backgroundColor: color,
|
||||
borderRadius: "50%",
|
||||
"&::before": {
|
||||
content: `""`,
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: "inherit",
|
||||
borderRadius: "50%",
|
||||
animation: "ripple 1.8s ease-out infinite",
|
||||
},
|
||||
"&::after": {
|
||||
content: `""`,
|
||||
position: "absolute",
|
||||
width: "6px",
|
||||
height: "6px",
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "white",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
PulseDot.propTypes = {
|
||||
color: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default PulseDot;
|
||||
@@ -2,24 +2,23 @@ import { useNavigate, useParams } from "react-router";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useEffect, useState } from "react";
|
||||
import Button from "../../../Components/Button";
|
||||
import Field from "../../../Components/Inputs/Field";
|
||||
import { Box, Modal, Skeleton, Stack, Typography } from "@mui/material";
|
||||
import GreenCheck from "../../../assets/icons/checkbox-green.svg?react";
|
||||
import RedCheck from "../../../assets/icons/checkbox-red.svg?react";
|
||||
import PauseCircleOutlineIcon from "@mui/icons-material/PauseCircleOutline";
|
||||
import { monitorValidation } from "../../../Validation/validation";
|
||||
import Select from "../../../Components/Inputs/Select";
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import {
|
||||
updateUptimeMonitor,
|
||||
getUptimeMonitorsByUserId,
|
||||
deleteUptimeMonitor,
|
||||
} from "../../../Features/UptimeMonitors/uptimeMonitorsSlice";
|
||||
import Button from "../../../Components/Button";
|
||||
import Field from "../../../Components/Inputs/Field";
|
||||
import PauseCircleOutlineIcon from "@mui/icons-material/PauseCircleOutline";
|
||||
import Select from "../../../Components/Inputs/Select";
|
||||
import Checkbox from "../../../Components/Inputs/Checkbox";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import PulseDot from "../../../Components/Animated/PulseDot";
|
||||
import "./index.css";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
|
||||
/**
|
||||
* Parses a URL string and returns a URL object.
|
||||
@@ -229,8 +228,14 @@ const Configure = () => {
|
||||
gap={theme.gap.large}
|
||||
flex={1}
|
||||
>
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
{monitor?.status ? <GreenCheck /> : <RedCheck />}
|
||||
<Stack direction="row" gap={theme.gap.xs}>
|
||||
<PulseDot
|
||||
color={
|
||||
monitor?.status
|
||||
? theme.label.up.dotColor
|
||||
: theme.label.down.dotColor
|
||||
}
|
||||
/>
|
||||
<Box>
|
||||
{parsedUrl?.host ? (
|
||||
<Typography component="h1" mb={theme.gap.xs} lineHeight={1}>
|
||||
|
||||
@@ -4,20 +4,19 @@ import { Box, Skeleton, Stack, Typography, useTheme } from "@mui/material";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { networkService } from "../../../main";
|
||||
import MonitorDetailsAreaChart from "../../../Components/Charts/MonitorDetailsAreaChart";
|
||||
import ButtonGroup from "@mui/material/ButtonGroup";
|
||||
import Button from "../../../Components/Button";
|
||||
import GreenCheck from "../../../assets/icons/checkbox-green.svg?react";
|
||||
import RedCheck from "../../../assets/icons/checkbox-red.svg?react";
|
||||
import SettingsIcon from "../../../assets/icons/settings-bold.svg?react";
|
||||
import PaginationTable from "./PaginationTable";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import {
|
||||
formatDuration,
|
||||
formatDurationRounded,
|
||||
} from "../../../Utils/timeUtils";
|
||||
import "./index.css";
|
||||
import MonitorDetailsAreaChart from "../../../Components/Charts/MonitorDetailsAreaChart";
|
||||
import ButtonGroup from "@mui/material/ButtonGroup";
|
||||
import Button from "../../../Components/Button";
|
||||
import SettingsIcon from "../../../assets/icons/settings-bold.svg?react";
|
||||
import PaginationTable from "./PaginationTable";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import PulseDot from "../../../Components/Animated/PulseDot";
|
||||
import "./index.css";
|
||||
|
||||
const StatBox = ({ title, value }) => {
|
||||
return (
|
||||
@@ -171,8 +170,14 @@ const DetailsPage = () => {
|
||||
]}
|
||||
/>
|
||||
<Stack gap={theme.gap.large} mt={theme.gap.large}>
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
{monitor?.status ? <GreenCheck /> : <RedCheck />}
|
||||
<Stack direction="row" gap={theme.gap.xs}>
|
||||
<PulseDot
|
||||
color={
|
||||
monitor?.status
|
||||
? theme.label.up.dotColor
|
||||
: theme.label.down.dotColor
|
||||
}
|
||||
/>
|
||||
<Box>
|
||||
<Typography component="h1" sx={{ lineHeight: 1 }}>
|
||||
{monitor.url?.replace(/^https?:\/\//, "") || "..."}
|
||||
|
||||
@@ -10,15 +10,14 @@ import {
|
||||
} from "../../../Features/PageSpeedMonitor/pageSpeedMonitorSlice";
|
||||
import { monitorValidation } from "../../../Validation/validation";
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import Button from "../../../Components/Button";
|
||||
import Field from "../../../Components/Inputs/Field";
|
||||
import Select from "../../../Components/Inputs/Select";
|
||||
import Checkbox from "../../../Components/Inputs/Checkbox";
|
||||
import PauseCircleOutlineIcon from "@mui/icons-material/PauseCircleOutline";
|
||||
import GreenCheck from "../../../assets/icons/checkbox-green.svg?react";
|
||||
import RedCheck from "../../../assets/icons/checkbox-red.svg?react";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import PulseDot from "../../../Components/Animated/PulseDot";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
@@ -168,8 +167,14 @@ const PageSpeedConfigure = () => {
|
||||
flex={1}
|
||||
gap={theme.gap.large}
|
||||
>
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
{monitor?.status ? <GreenCheck /> : <RedCheck />}
|
||||
<Stack direction="row" gap={theme.gap.xs}>
|
||||
<PulseDot
|
||||
color={
|
||||
monitor?.status
|
||||
? theme.label.up.dotColor
|
||||
: theme.label.down.dotColor
|
||||
}
|
||||
/>
|
||||
<Box>
|
||||
<Typography
|
||||
component="h1"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Box, Skeleton, Stack, Typography } from "@mui/material";
|
||||
import { PieChart } from "@mui/x-charts/PieChart";
|
||||
import { useDrawingArea } from "@mui/x-charts";
|
||||
@@ -9,19 +10,17 @@ import {
|
||||
formatDuration,
|
||||
formatDurationRounded,
|
||||
} from "../../../Utils/timeUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import { networkService } from "../../../main";
|
||||
import Button from "../../../Components/Button";
|
||||
import SettingsIcon from "../../../assets/icons/settings-bold.svg?react";
|
||||
import LastCheckedIcon from "../../../assets/icons/calendar-check.svg?react";
|
||||
import ClockIcon from "../../../assets/icons/maintenance.svg?react";
|
||||
import IntervalCheckIcon from "../../../assets/icons/interval-check.svg?react";
|
||||
import GreenCheck from "../../../assets/icons/checkbox-green.svg?react";
|
||||
import RedCheck from "../../../assets/icons/checkbox-red.svg?react";
|
||||
import PageSpeedLineChart from "../../../Components/Charts/PagespeedLineChart";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import PulseDot from "../../../Components/Animated/PulseDot";
|
||||
import "./index.css";
|
||||
import PropTypes from "prop-types";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
|
||||
const StatBox = ({ icon, title, value }) => {
|
||||
const theme = useTheme();
|
||||
@@ -325,8 +324,14 @@ const PageSpeedDetails = () => {
|
||||
{ name: "details", path: `/pagespeed/${monitorId}` },
|
||||
]}
|
||||
/>
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
{monitor?.status ? <GreenCheck /> : <RedCheck />}
|
||||
<Stack direction="row" gap={theme.gap.xs}>
|
||||
<PulseDot
|
||||
color={
|
||||
monitor?.status
|
||||
? theme.label.up.dotColor
|
||||
: theme.label.down.dotColor
|
||||
}
|
||||
/>
|
||||
<Box>
|
||||
<Typography
|
||||
component="h1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { toast } from "react-toastify";
|
||||
import { toast, Slide } from "react-toastify";
|
||||
import Alert from "../Components/Alert";
|
||||
|
||||
/**
|
||||
@@ -23,6 +23,7 @@ export const createToast = ({
|
||||
autoClose: 3000,
|
||||
hideProgressBar: true,
|
||||
closeButton: false,
|
||||
transition: Slide,
|
||||
...config,
|
||||
};
|
||||
|
||||
|
||||
@@ -168,6 +168,17 @@ body .MuiSkeleton-root {
|
||||
background-color: var(--env-var-color-15);
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: scale(0);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: scale(2);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
|
||||
Reference in New Issue
Block a user