From 2b6c2bad6ab1ccc42b86dfc6bfe59e0d537aa1fc Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 17 Oct 2024 11:59:31 +0800 Subject: [PATCH] Change validation error toast to a user friendly message --- .../Pages/Monitors/CreateMonitor/index.jsx | 708 +++++++++--------- 1 file changed, 356 insertions(+), 352 deletions(-) diff --git a/Client/src/Pages/Monitors/CreateMonitor/index.jsx b/Client/src/Pages/Monitors/CreateMonitor/index.jsx index ac68ea7eb..b8ab53bee 100644 --- a/Client/src/Pages/Monitors/CreateMonitor/index.jsx +++ b/Client/src/Pages/Monitors/CreateMonitor/index.jsx @@ -17,370 +17,374 @@ import { getUptimeMonitorById } from "../../../Features/UptimeMonitors/uptimeMon import "./index.css"; const CreateMonitor = () => { - const MS_PER_MINUTE = 60000; - const { user, authToken } = useSelector((state) => state.auth); - const { monitors } = useSelector((state) => state.uptimeMonitors); - const dispatch = useDispatch(); - const navigate = useNavigate(); - const theme = useTheme(); + const MS_PER_MINUTE = 60000; + const { user, authToken } = useSelector((state) => state.auth); + const { monitors } = useSelector((state) => state.uptimeMonitors); + 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 idMap = { + "monitor-url": "url", + "monitor-name": "name", + "monitor-checks-http": "type", + "monitor-checks-ping": "type", + "notify-email-default": "notification-email", + }; - const { monitorId } = useParams(); - const [monitor, setMonitor] = useState({ - url: "", - name: "", - type: "http", - notifications: [], - interval: 1, - }); - const [https, setHttps] = useState(true); - const [errors, setErrors] = useState({}); + const { monitorId } = useParams(); + const [monitor, setMonitor] = useState({ + url: "", + name: "", + type: "http", + notifications: [], + interval: 1, + }); + const [https, setHttps] = useState(true); + const [errors, setErrors] = useState({}); - useEffect(() => { - const fetchMonitor = async () => { - if (monitorId) { - const action = await dispatch( - getUptimeMonitorById({ authToken, monitorId }) - ); + useEffect(() => { + const fetchMonitor = async () => { + if (monitorId) { + const action = await dispatch(getUptimeMonitorById({ authToken, monitorId })); - if (action.payload.success) { - const data = action.payload.data; - const { name, ...rest } = data; //data.name is read-only - if (rest.type === "http") { - const url = new URL(rest.url); - rest.url = url.host; - } - rest.name = `${name} (Clone)`; - rest.interval /= MS_PER_MINUTE; - setMonitor({ - ...rest, - }); - } else { - navigate("/not-found", { replace: true }); - createToast({ - body: "There was an error cloning the monitor.", - }); - } - } - }; - fetchMonitor(); - }, [monitorId, authToken, monitors]); + if (action.payload.success) { + const data = action.payload.data; + const { name, ...rest } = data; //data.name is read-only + if (rest.type === "http") { + const url = new URL(rest.url); + rest.url = url.host; + } + rest.name = `${name} (Clone)`; + rest.interval /= MS_PER_MINUTE; + setMonitor({ + ...rest, + }); + } else { + navigate("/not-found", { replace: true }); + createToast({ + body: "There was an error cloning the monitor.", + }); + } + } + }; + fetchMonitor(); + }, [monitorId, authToken, monitors]); - const handleChange = (event, name) => { - const { value, id } = event.target; - if (!name) name = idMap[id]; + 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, - })); + 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 } - ); - console.log(error); - setErrors((prev) => { - const updatedErrors = { ...prev }; - if (error) updatedErrors[name] = error.details[0].message; - else delete updatedErrors[name]; - return updatedErrors; - }); - } - }; + const { error } = monitorValidation.validate( + { [name]: value }, + { abortEarly: false } + ); + console.log(error); + setErrors((prev) => { + const updatedErrors = { ...prev }; + if (error) updatedErrors[name] = error.details[0].message; + else delete updatedErrors[name]; + return updatedErrors; + }); + } + }; - const handleCreateMonitor = async (event) => { - event.preventDefault(); - //obj to submit - let form = { - url: - //preprending protocol for url - monitor.type === "http" - ? `http${https ? "s" : ""}://` + monitor.url - : monitor.url, - name: monitor.name === "" ? monitor.url : monitor.name, - type: monitor.type, - interval: monitor.interval * MS_PER_MINUTE, - }; + const handleCreateMonitor = async (event) => { + event.preventDefault(); + //obj to submit + let form = { + url: + //preprending protocol for url + monitor.type === "http" + ? `http${https ? "s" : ""}://` + monitor.url + : monitor.url, + name: monitor.name === "" ? monitor.url : monitor.name, + type: monitor.type, + interval: monitor.interval * MS_PER_MINUTE, + }; - const { error } = monitorValidation.validate(form, { - abortEarly: false, - }); + const { error } = monitorValidation.validate(form, { + abortEarly: false, + }); - if (error) { - const newErrors = {}; - error.details.forEach((err) => { - newErrors[err.path[0]] = err.message; - }); - setErrors(newErrors); - createToast({ body: "Error validation data." }); - } else { - form = { - ...form, - description: form.name, - teamId: user.teamId, - userId: user._id, - notifications: monitor.notifications, - }; - const action = await dispatch( - createUptimeMonitor({ authToken, monitor: form }) - ); - if (action.meta.requestStatus === "fulfilled") { - createToast({ body: "Monitor created successfully!" }); - navigate("/monitors"); - } else { - createToast({ body: "Failed to create monitor." }); - } - } - }; + if (error) { + const newErrors = {}; + error.details.forEach((err) => { + newErrors[err.path[0]] = err.message; + }); + setErrors(newErrors); + createToast({ body: "Please check your input for errors and try again" }); + } else { + form = { + ...form, + description: form.name, + teamId: user.teamId, + userId: user._id, + notifications: monitor.notifications, + }; + const action = await dispatch(createUptimeMonitor({ authToken, monitor: form })); + if (action.meta.requestStatus === "fulfilled") { + createToast({ body: "Monitor created successfully!" }); + navigate("/monitors"); + } else { + createToast({ body: "Failed to create monitor." }); + } + } + }; - //select values - const frequencies = [ - { _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" }, - ]; + //select values + const frequencies = [ + { _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" }, + ]; - return ( - - - - - - Create your{" "} - - - monitor - - - - - General settings - - Here you can select the URL of the host, together with the type of - monitor. - - - - - - - - - - Checks to perform - - You can always add or remove checks after adding your site. - - - - - handleChange(event)} - /> - {monitor.type === "http" ? ( - - - - - ) : ( - "" - )} - - handleChange(event)} - /> - {errors["type"] ? ( - - - {errors["type"]} - - - ) : ( - "" - )} - - - - - Incident notifications - - When there is an incident, notify users. - - - - When there is a new incident, - logger.warn("disabled")} - isDisabled={true} - /> - notification.type === "email" - )} - value={user?.email} - onChange={(event) => handleChange(event)} - /> - logger.warn("disabled")} - isDisabled={true} - /> - {monitor.notifications.some( - (notification) => notification.type === "emails" - ) ? ( - - logger.warn("disabled")} - /> - - You can separate multiple emails with a comma - - - ) : ( - "" - )} - - - - - Advanced settings - - - handleChange(event, "interval")} + items={frequencies} + /> + + + + + + + + ); }; export default CreateMonitor;