diff --git a/Client/src/Pages/DistributedUptime/Create/index.jsx b/Client/src/Pages/DistributedUptime/Create/index.jsx new file mode 100644 index 000000000..2df0a4482 --- /dev/null +++ b/Client/src/Pages/DistributedUptime/Create/index.jsx @@ -0,0 +1,307 @@ +// Components +import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material"; +import LoadingButton from "@mui/lab/LoadingButton"; + +import Breadcrumbs from "../../../Components/Breadcrumbs"; +import ConfigBox from "../../../Components/ConfigBox"; +import TextInput from "../../../Components/Inputs/TextInput"; +import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments"; +import Radio from "../../../Components/Inputs/Radio"; +import Checkbox from "../../../Components/Inputs/Checkbox"; +import Select from "../../../Components/Inputs/Select"; +import { createToast } from "../../../Utils/toastUtils"; + +// Utility +import { useTheme } from "@emotion/react"; +import { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { monitorValidation } from "../../../Validation/validation"; +import { createUptimeMonitor } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice"; + +// Constants +const BREADCRUMBS = [ + { name: `distributed uptime`, path: "/distributed-uptime" }, + { name: "create", path: `/distributed-uptime/create` }, +]; +const MS_PER_MINUTE = 60000; +const SELECT_VALUES = [ + { _id: 1, name: "1 minute" }, + { _id: 2, name: "2 minutes" }, + { _id: 3, name: "3 minutes" }, + { _id: 4, name: "4 minutes" }, + { _id: 5, name: "5 minutes" }, +]; + +const CreateDistributedUptime = () => { + // Redux state + const { user, authToken } = useSelector((state) => state.auth); + const isLoading = useSelector((state) => state.uptimeMonitors.isLoading); + + // Local state + const [https, setHttps] = useState(true); + const [notifications, setNotifications] = useState([]); + const [monitor, setMonitor] = useState({ + type: "distributed_http", + name: "", + url: "", + interval: 1, + }); + const [errors, setErrors] = useState({}); + + //utils + const theme = useTheme(); + const dispatch = useDispatch(); + const navigate = useNavigate(); + + // Handlers + const handleCreateMonitor = async (event) => { + const monitorToSubmit = { ...monitor }; + + // Prepend protocol to url + monitorToSubmit.url = `http${https ? "s" : ""}://` + monitorToSubmit.url; + + const { error } = monitorValidation.validate(monitorToSubmit, { + abortEarly: false, + }); + + if (error) { + const newErrors = {}; + error.details.forEach((err) => { + newErrors[err.path[0]] = err.message; + }); + setErrors(newErrors); + createToast({ body: "Please check the form for errors." }); + return; + } + + // Append needed fields + monitorToSubmit.description = monitor.name; + monitorToSubmit.interval = monitor.interval * MS_PER_MINUTE; + monitorToSubmit.teamId = user.teamId; + monitorToSubmit.userId = user._id; + monitorToSubmit.notifications = notifications; + + const action = await dispatch( + createUptimeMonitor({ authToken, monitor: monitorToSubmit }) + ); + if (action.meta.requestStatus === "fulfilled") { + createToast({ body: "Monitor created successfully!" }); + navigate("/distributed-uptime"); + } else { + createToast({ body: "Failed to create monitor." }); + } + }; + + const handleChange = (event) => { + const { name, value } = event.target; + setMonitor({ + ...monitor, + [name]: value, + }); + const { error } = monitorValidation.validate( + { [name]: value }, + { abortEarly: false } + ); + console.log(name); + setErrors((prev) => ({ + ...prev, + ...(error ? { [name]: error.details[0].message } : { [name]: undefined }), + })); + }; + + const handleNotifications = (event, type) => { + const { value } = event.target; + let currentNotifications = [...notifications]; + const notificationAlreadyExists = notifications.some((notification) => { + if (notification.type === type && notification.address === value) { + return true; + } + return false; + }); + if (notificationAlreadyExists) { + currentNotifications = currentNotifications.filter((notification) => { + if (notification.type === type && notification.address === value) { + return false; + } + return true; + }); + } else { + currentNotifications.push({ type, address: value }); + } + setNotifications(currentNotifications); + }; + + return ( + + + console.log("submit")} + > + + + Create your{" "} + + + monitor + + + + + General settings + + Here you can select the URL of the host, together with the type of monitor. + + + + } + label="URL to monitor" + https={https} + placeholder={"www.google.com"} + value={monitor.url} + name="url" + onChange={handleChange} + error={errors["url"] ? true : false} + helperText={errors["url"]} + /> + + + + + + Checks to perform + + You can always add or remove checks after adding your site. + + + + + + {monitor.type === "http" || monitor.type === "distributed_http" ? ( + + + + + ) : ( + "" + )} + + + {errors["type"] ? ( + + + {errors["type"]} + + + ) : ( + "" + )} + + + + + Incident notifications + + When there is an incident, notify users. + + + + notification.type === "email" + )} + value={user?.email} + onChange={(event) => handleNotifications(event, "email")} + /> + + + + + Advanced settings + + +