Skip to content

Commit

Permalink
Merge pull request #703 from bluewave-labs/feat/status-dot-animated
Browse files Browse the repository at this point in the history
Feat/status dot animated
  • Loading branch information
ajhollid authored Aug 22, 2024
2 parents 506e3e8 + 0183e13 commit d5daa14
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 31 deletions.
62 changes: 62 additions & 0 deletions Client/src/Components/Animated/PulseDot.jsx
Original file line number Diff line number Diff line change
@@ -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;
23 changes: 14 additions & 9 deletions Client/src/Pages/Monitors/Configure/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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}>
Expand Down
25 changes: 15 additions & 10 deletions Client/src/Pages/Monitors/Details/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 { logger } from "../../../Utils/Logger";
import {
formatDuration,
formatDurationRounded,
} from "../../../Utils/timeUtils";
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 {
formatDuration,
formatDurationRounded,
} from "../../../Utils/timeUtils";
import "./index.css";
import Breadcrumbs from "../../../Components/Breadcrumbs";
import { logger } from "../../../Utils/Logger";
import PulseDot from "../../../Components/Animated/PulseDot";
import "./index.css";

const StatBox = ({ title, value }) => {
return (
Expand Down Expand Up @@ -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?:\/\//, "") || "..."}
Expand Down
15 changes: 10 additions & 5 deletions Client/src/Pages/PageSpeed/Configure/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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"
Expand Down
17 changes: 11 additions & 6 deletions Client/src/Pages/PageSpeed/Details/index.jsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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();
Expand Down Expand Up @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion Client/src/Utils/toastUtils.jsx
Original file line number Diff line number Diff line change
@@ -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";

/**
Expand All @@ -23,6 +23,7 @@ export const createToast = ({
autoClose: 3000,
hideProgressBar: true,
closeButton: false,
transition: Slide,
...config,
};

Expand Down
11 changes: 11 additions & 0 deletions Client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit d5daa14

Please sign in to comment.