diff --git a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js index bf7f0378e..05c182f5f 100644 --- a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js +++ b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js @@ -77,6 +77,7 @@ export const updateUptimeMonitor = createAsyncThunk( name: monitor.name, description: monitor.description, interval: monitor.interval, + notifications: monitor.notifications }; const res = await axiosInstance.post( `/monitors/edit/${monitor._id}`, diff --git a/Client/src/Pages/Account/index.css b/Client/src/Pages/Account/index.css index ee28b1c30..29d41aeff 100644 --- a/Client/src/Pages/Account/index.css +++ b/Client/src/Pages/Account/index.css @@ -31,6 +31,9 @@ .account .MuiButtonGroup-root button { border-color: var(--env-var-color-16); } +.account button{ + height: 34px; +} .account [class$="-form"] { width: inherit; } diff --git a/Client/src/Pages/Auth/index.css b/Client/src/Pages/Auth/index.css index e2e5d4d56..c9fa48fe5 100644 --- a/Client/src/Pages/Auth/index.css +++ b/Client/src/Pages/Auth/index.css @@ -103,7 +103,7 @@ /* ///// */ .login-page .MuiStack-root:not(:has(> .MuiButtonBase-root)) - span:not(.MuiTypography-root) { + span:not(.MuiTypography-root):not(.field-required) { color: var(--env-var-color-3); cursor: pointer; font-weight: 600; diff --git a/Client/src/Pages/Monitors/Configure/index.css b/Client/src/Pages/Monitors/Configure/index.css index 005c97188..a594348ab 100644 --- a/Client/src/Pages/Monitors/Configure/index.css +++ b/Client/src/Pages/Monitors/Configure/index.css @@ -12,6 +12,9 @@ .configure-monitor .MuiSelect-select { color: var(--env-var-color-5); } +.configure-monitor .MuiModal-root h2.MuiTypography-root { + color: var(--env-var-color-1); +} .configure-monitor p.MuiTypography-root, .configure-monitor .MuiSelect-select { font-size: var(--env-var-font-size-medium); @@ -51,6 +54,9 @@ position: absolute; top: 100%; } +.configure-monitor .MuiInputBase-root:has(> .Mui-disabled) { + background-color: var(--env-var-color-13); +} .MuiInputBase-root:has(#monitor-interval) { height: 34px; diff --git a/Client/src/Pages/Monitors/Configure/index.jsx b/Client/src/Pages/Monitors/Configure/index.jsx index 9a2f44d5f..cde71bdf7 100644 --- a/Client/src/Pages/Monitors/Configure/index.jsx +++ b/Client/src/Pages/Monitors/Configure/index.jsx @@ -4,7 +4,7 @@ import { useDispatch, useSelector } from "react-redux"; import { useEffect, useState } from "react"; import Button from "../../../Components/Button"; import Field from "../../../Components/Inputs/Field"; -import { Box, Stack, Typography } from "@mui/material"; +import { Box, Modal, Stack, Typography } from "@mui/material"; import WestRoundedIcon from "@mui/icons-material/WestRounded"; import GreenCheck from "../../../assets/icons/checkbox-green.svg?react"; import RedCheck from "../../../assets/icons/checkbox-red.svg?react"; @@ -20,6 +20,8 @@ import { getUptimeMonitorsByUserId, deleteUptimeMonitor, } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice"; +import Checkbox from "../../../Components/Inputs/Checkbox"; + /** * Parses a URL string and returns a URL object. * @@ -55,7 +57,7 @@ const Configure = () => { const navigate = useNavigate(); const theme = useTheme(); const dispatch = useDispatch(); - const { authToken } = useSelector((state) => state.auth); + const { user, authToken } = useSelector((state) => state.auth); const { monitors } = useSelector((state) => state.uptimeMonitors); const [monitor, setMonitor] = useState(); const [duration, setDuration] = useState(0); @@ -67,6 +69,7 @@ const Configure = () => { "monitor-name": "name", "monitor-checks-http": "type", "monitor-checks-ping": "type", + "notify-email-default": "notification-email", }; useEffect(() => { @@ -80,27 +83,55 @@ const Configure = () => { const handleChange = (event, name) => { let { value, id } = event.target; if (!name) name = idMap[id]; - if (name === "interval") { - value = value * MS_PER_MINUTE; + + if (name.includes("notification-")) { + name = name.replace("notification-", ""); + let hasNotif = monitor.notifications.some( + (notification) => notification.type === name + ); + setMonitor((prev) => { + const notifs = [...prev.notifications]; + if (hasNotif) { + return { + ...prev, + notifications: notifs.filter((notif) => notif.type !== name), + }; + } else { + return { + ...prev, + notifications: [ + ...notifs, + name === "email" + ? { type: name, address: value } + : // TODO - phone number + { type: name, phone: value }, + ], + }; + } + }); + } else { + if (name === "interval") { + value = value * MS_PER_MINUTE; + } + setMonitor((prev) => ({ + ...prev, + [name]: value, + })); + + const validation = monitorValidation.validate( + { [name]: value }, + { abortEarly: false } + ); + + setErrors((prev) => { + const updatedErrors = { ...prev }; + + if (validation.error) + updatedErrors[name] = validation.error.details[0].message; + else delete updatedErrors[name]; + return updatedErrors; + }); } - setMonitor((prev) => ({ - ...prev, - [name]: value, - })); - - const validation = monitorValidation.validate( - { [name]: value }, - { abortEarly: false } - ); - - setErrors((prev) => { - const updatedErrors = { ...prev }; - - if (validation.error) - updatedErrors[name] = validation.error.details[0].message; - else delete updatedErrors[name]; - return updatedErrors; - }); }; const handleSubmit = async (event) => { @@ -116,9 +147,9 @@ const Configure = () => { } }; - const hanldeRemove = async (event) => { + const [isOpen, setIsOpen] = useState(false); + const handleRemove = async (event) => { event.preventDefault(); - // TODO add confirm const action = await dispatch(deleteUptimeMonitor({ authToken, monitor })); if (action.meta.requestStatus === "fulfilled") { navigate("/monitors"); @@ -139,6 +170,8 @@ const Configure = () => { const parsedUrl = parseUrl(monitor?.url); const protocol = parsedUrl?.protocol?.replace(":", "") || ""; + var lastChecked = formatDurationRounded(getLastChecked(monitor?.checks)); + return (