From f148e2d9ad9bf49b2b8f0d60789de48ab1f5ff8f Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 6 Dec 2024 14:25:11 +0800 Subject: [PATCH 1/2] Refactor Create PageSpeed --- .../Pages/PageSpeed/CreatePageSpeed/index.jsx | 313 ++++++++---------- 1 file changed, 142 insertions(+), 171 deletions(-) diff --git a/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx b/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx index ba3a7bb4a..6823cfe21 100644 --- a/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx +++ b/Client/src/Pages/PageSpeed/CreatePageSpeed/index.jsx @@ -1,42 +1,52 @@ +// React, Redux, Router +import { useNavigate, useParams } from "react-router-dom"; +import { useEffect } from "react"; import { useState } from "react"; -import { Box, Button, ButtonGroup, Stack, Typography } from "@mui/material"; -import LoadingButton from "@mui/lab/LoadingButton"; import { useSelector, useDispatch } from "react-redux"; + +// Utility and Network +import { logger } from "../../../Utils/Logger"; import { monitorValidation } from "../../../Validation/validation"; -import { useNavigate } from "react-router-dom"; -import { useTheme } from "@emotion/react"; import { createPageSpeed, checkEndpointResolution, } from "../../../Features/PageSpeedMonitor/pageSpeedMonitorSlice"; -import { createToast } from "../../../Utils/toastUtils"; -import { logger } from "../../../Utils/Logger"; -import { ConfigBox } from "../../Monitors/styled"; -import Radio from "../../../Components/Inputs/Radio"; +import { parseDomainName } from "../../../Utils/monitorUtils"; + +// MUI +import { useTheme } from "@emotion/react"; +import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material"; +import LoadingButton from "@mui/lab/LoadingButton"; + +//Components +import Breadcrumbs from "../../../Components/Breadcrumbs"; import TextInput from "../../../Components/Inputs/TextInput"; import { HttpAdornment } from "../../../Components/Inputs/TextInput/Adornments"; -import Select from "../../../Components/Inputs/Select"; +import { ConfigBox } from "../../Monitors/styled"; + +import { createToast } from "../../../Utils/toastUtils"; +import Radio from "../../../Components/Inputs/Radio"; import Checkbox from "../../../Components/Inputs/Checkbox"; -import Breadcrumbs from "../../../Components/Breadcrumbs"; -import { parseDomainName } from "../../../Utils/monitorUtils"; -import "./index.css"; +import Select from "../../../Components/Inputs/Select"; const CreatePageSpeed = () => { const MS_PER_MINUTE = 60000; - const { user, authToken } = useSelector((state) => state.auth); - const { isLoading } = useSelector((state) => state.pageSpeedMonitors); - const dispatch = useDispatch(); - const navigate = useNavigate(); - const theme = useTheme(); - const idMap = { - "monitor-url": "url", - "monitor-name": "name", - "monitor-checks-http": "type", - "monitor-checks-ping": "type", - "notify-email-default": "notification-email", - }; + const CRUMBS = [ + { name: "pagespeed", path: "/pagespeed" }, + { name: "create", path: `/pagespeed/create` }, + ]; + const SELECT_VALUES = [ + { _id: 3, name: "3 minutes" }, + { _id: 5, name: "5 minutes" }, + { _id: 10, name: "10 minutes" }, + { _id: 20, name: "20 minutes" }, + { _id: 60, name: "1 hour" }, + { _id: 1440, name: "1 day" }, + { _id: 10080, name: "1 week" }, + ]; + // State const [monitor, setMonitor] = useState({ url: "", name: "", @@ -44,71 +54,20 @@ const CreatePageSpeed = () => { notifications: [], interval: 3, }); + const [https, setHttps] = useState(true); const [errors, setErrors] = useState({}); + const { user, authToken } = useSelector((state) => state.auth); + const { isLoading } = useSelector((state) => state.pageSpeedMonitors); - const handleChange = (event, name) => { - const { value, id } = event.target; - if (!name) name = idMap[id]; - - 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 { - setMonitor((prev) => ({ - ...prev, - [name]: value, - })); - - const { error } = monitorValidation.validate( - { [name]: value }, - { abortEarly: false } - ); - - setErrors((prev) => { - const updatedErrors = { ...prev }; - if (error) updatedErrors[name] = error.details[0].message; - else delete updatedErrors[name]; - return updatedErrors; - }); - } - }; - - const onUrlBlur = (event) => { - const { value } = event.target; - if (monitor.name === "") { - setMonitor((prev) => ({ - ...prev, - name: parseDomainName(value), - })); - } - }; + // Setup + const dispatch = useDispatch(); + const navigate = useNavigate(); + const theme = useTheme(); + // Handlers const handleCreateMonitor = async (event) => { event.preventDefault(); - //obj to submit let form = { url: `http${https ? "s" : ""}://` + monitor.url, name: monitor.name === "" ? monitor.url : monitor.name, @@ -126,46 +85,98 @@ const CreatePageSpeed = () => { newErrors[err.path[0]] = err.message; }); setErrors(newErrors); - createToast({ body: "Error validation data." }); - } else { - const checkEndpointAction = await dispatch( - checkEndpointResolution({ authToken, monitorURL: form.url }) - ); - if (checkEndpointAction.meta.requestStatus === "rejected") { - createToast({ - body: "The endpoint you entered doesn't resolve. Check the URL again.", - }); - setErrors({ url: "The entered URL is not reachable." }); - return; - } + createToast({ body: "Please check the form for errors." }); + return; + } - form = { - ...form, - description: form.name, - teamId: user.teamId, - userId: user._id, - notifications: monitor.notifications, - }; - const action = await dispatch(createPageSpeed({ authToken, monitor: form })); - if (action.meta.requestStatus === "fulfilled") { - createToast({ body: "Monitor created successfully!" }); - navigate("/pagespeed"); - } else { - createToast({ body: "Failed to create monitor." }); - } + const checkEndpointAction = await dispatch( + checkEndpointResolution({ authToken, monitorURL: form.url }) + ); + + if (checkEndpointAction.meta.requestStatus === "rejected") { + createToast({ + body: "The endpoint you entered doesn't resolve. Check the URL again.", + }); + setErrors({ url: "The entered URL is not reachable." }); + return; + } + + form = { + ...form, + description: form.name, + teamId: user.teamId, + userId: user._id, + notifications: monitor.notifications, + }; + + const action = await dispatch(createPageSpeed({ authToken, monitor: form })); + if (action.meta.requestStatus === "fulfilled") { + createToast({ body: "Monitor created successfully!" }); + navigate("/pagespeed"); + } else { + createToast({ body: "Failed to create monitor." }); + } + }; + + const handleChange = (event, formItemName) => { + const { value } = event.target; + setMonitor({ + ...monitor, + [formItemName]: value, + }); + + const { error } = monitorValidation.validate( + { [formItemName]: value }, + { abortEarly: false } + ); + + setErrors((prev) => ({ + ...prev, + ...(error + ? { [formItemName]: error.details[0].message } + : { [formItemName]: undefined }), + })); + }; + + const handleNotifications = (event, type) => { + const { value } = event.target; + let notifications = [...monitor.notifications]; + const notificationExists = notifications.some((notification) => { + if (notification.type === type && notification.address === value) { + return true; + } + return false; + }); + if (notificationExists) { + notifications = notifications.filter((notification) => { + if (notification.type === type && notification.address === value) { + return false; + } + return true; + }); + } else { + notifications.push({ type, address: value }); + } + + setMonitor((prev) => ({ + ...prev, + notifications, + })); + }; + + const handleBlur = (event, formItemName) => { + if (formItemName === "url") { + const { value } = event.target; + if (monitor.name !== "") { + return; + } + setMonitor((prev) => ({ + ...prev, + name: parseDomainName(value), + })); } }; - //select values - const frequencies = [ - { _id: 3, name: "3 minutes" }, - { _id: 5, name: "5 minutes" }, - { _id: 10, name: "10 minutes" }, - { _id: 20, name: "20 minutes" }, - { _id: 60, name: "1 hour" }, - { _id: 1440, name: "1 day" }, - { _id: 10080, name: "1 week" }, - ]; return ( { }, }} > - + { fontWeight="inherit" color={theme.palette.text.secondary} > - pagespeed monitor + PageSpeed monitor @@ -224,8 +230,8 @@ const CreatePageSpeed = () => { startAdornment={} placeholder="google.com" value={monitor.url} - onChange={handleChange} - onBlur={onUrlBlur} + onChange={(event) => handleChange(event, "url")} + onBlur={(event) => handleBlur(event, "url")} error={errors["url"] ? true : false} helperText={errors["url"]} /> @@ -236,7 +242,7 @@ const CreatePageSpeed = () => { isOptional={true} placeholder="Google" value={monitor.name} - onChange={handleChange} + onChange={(event) => handleChange(event, "name")} error={errors["name"] ? true : false} helperText={errors["name"]} /> @@ -253,8 +259,8 @@ const CreatePageSpeed = () => { { HTTPS