From 2ccc26ebdc4a9cd1118c4bae4b11c2b0eb5e3fbb Mon Sep 17 00:00:00 2001 From: Toba Ojo Date: Tue, 11 Nov 2025 16:22:30 +0000 Subject: [PATCH 1/2] - added additional modem settings and ip validation --- .../SettingForms/WiFi&Modem/ModemCard.tsx | 1 - .../SettingForms/WiFi&Modem/ModemSettings.tsx | 52 ++++++++++++++++++- src/types/types.ts | 2 + src/utils/utils.ts | 13 +++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/components/SettingForms/WiFi&Modem/ModemCard.tsx b/src/components/SettingForms/WiFi&Modem/ModemCard.tsx index dcc2dfc..46cbb16 100644 --- a/src/components/SettingForms/WiFi&Modem/ModemCard.tsx +++ b/src/components/SettingForms/WiFi&Modem/ModemCard.tsx @@ -6,7 +6,6 @@ const ModemCard = () => { return ( - ); diff --git a/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx b/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx index 56cc831..ca43bba 100644 --- a/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx +++ b/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx @@ -6,6 +6,8 @@ import { useEffect, useState } from "react"; import ModemToggle from "./ModemToggle"; import { faEyeSlash, faEye } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { ValidateIPaddress } from "../../../utils/utils"; +import { toast, Toaster } from "sonner"; const ModemSettings = () => { const [showSettings, setShowSettings] = useState(false); @@ -16,6 +18,8 @@ const ModemSettings = () => { const username = modemQuery?.data?.propUsername.value; const password = modemQuery?.data?.propPassword?.value; const mode = modemQuery?.data?.propMode?.value; + const serverPrimary = modemQuery?.data?.propNameServerPrimary?.value; + const serverSecondary = modemQuery?.data?.propNameServerSecondary?.value; useEffect(() => { setShowSettings(mode === "AUTO"); @@ -26,6 +30,8 @@ const ModemSettings = () => { username: username ?? "", password: password ?? "", authenticationType: "PAP", + serverPrimary: serverPrimary ?? "", + serverSecondary: serverSecondary ?? "", }; const handleSubmit = async (values: ModemSettingsType) => { @@ -49,9 +55,24 @@ const ModemSettings = () => { property: "propMode", value: showSettings ? "AUTO" : "MANUAL", }, + { + property: "propNameServerPrimary", + value: values.serverPrimary, + }, + { + property: "propNameServerSecondary", + value: values.serverSecondary, + }, ], }; - await modemMutation.mutateAsync(modemConfig); + + const response = await modemMutation.mutateAsync(modemConfig); + + if (response?.id) { + toast.success("Modem settings updated successfully", { + id: "modemSettings", + }); + } }; return ( @@ -107,9 +128,35 @@ const ModemSettings = () => { /> + + + + + + + + { )} + ); }; diff --git a/src/types/types.ts b/src/types/types.ts index fbf4f0e..9d5cfdf 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -403,6 +403,8 @@ export type ModemSettingsType = { username: string; password: string; authenticationType: string; + serverPrimary: string; + serverSecondary: string; }; export type HitKind = "NPED" | "HOTLIST"; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index ed80a28..9707968 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -184,3 +184,16 @@ export const reverseZoomMapping = (magnification: string) => { break; } }; + +export function ValidateIPaddress(ipaddress: string) { + if (!ipaddress) { + return undefined; + } else if ( + !/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test( + ipaddress + ) + ) { + return "Invalid IP"; + } + return undefined; +} From ed271964d8831cdcecde1b4490e74dd76c2968b0 Mon Sep 17 00:00:00 2001 From: Toba Ojo Date: Wed, 12 Nov 2025 09:46:59 +0000 Subject: [PATCH 2/2] updated and improved ip address validation --- .../System/SystemConfigFields.tsx | 12 ++++++++++- .../SettingForms/WiFi&Modem/ModemSettings.tsx | 12 ++++++++--- src/utils/utils.ts | 20 +++++++++---------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/components/SettingForms/System/SystemConfigFields.tsx b/src/components/SettingForms/System/SystemConfigFields.tsx index 7d8951f..b830dd2 100644 --- a/src/components/SettingForms/System/SystemConfigFields.tsx +++ b/src/components/SettingForms/System/SystemConfigFields.tsx @@ -5,6 +5,8 @@ import { timezones } from "./timezones"; import SystemFileUpload from "./SystemFileUpload"; import type { SystemValues, SystemValuesErrors } from "../../../types/types"; import { useDNSSettings, useSystemConfig } from "../../../hooks/useSystemConfig"; +import { ValidateIPaddress } from "../../../utils/utils"; +import { toast } from "sonner"; const SystemConfigFields = () => { const { saveSystemSettings, systemSettingsData, saveSystemSettingsLoading } = useSystemConfig(); @@ -35,6 +37,14 @@ const SystemConfigFields = () => { if (!values.timeZone) errors.timeZone = "Required"; if (isNaN(interval) || interval <= 0) errors.sntpInterval = "Cannot be less than 0"; if (!values.sntpServer) errors.sntpServer = "Required"; + const invalidPrimary = ValidateIPaddress(values.serverPrimary); + const invalidSecondary = ValidateIPaddress(values.serverSecondary); + + if (invalidPrimary || invalidSecondary) { + toast.error(invalidPrimary || invalidSecondary, { + id: "invalid-ip", + }); + } return errors; }; @@ -52,7 +62,7 @@ const SystemConfigFields = () => { onSubmit={handleSubmit} validate={validateValues} enableReinitialize - validateOnChange + validateOnChange={false} validateOnBlur > {({ values, errors, touched, isSubmitting }) => ( diff --git a/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx b/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx index ca43bba..a381f2b 100644 --- a/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx +++ b/src/components/SettingForms/WiFi&Modem/ModemSettings.tsx @@ -35,6 +35,14 @@ const ModemSettings = () => { }; const handleSubmit = async (values: ModemSettingsType) => { + const invalidPrimary = ValidateIPaddress(values.serverPrimary); + const invalidSecondary = ValidateIPaddress(values.serverSecondary); + if (invalidPrimary || invalidSecondary) { + toast.error(invalidPrimary || invalidSecondary, { + id: "invalid-ip", + }); + return; + } const modemConfig = { id: "ModemAndWifiManager-modem", fields: [ @@ -68,7 +76,7 @@ const ModemSettings = () => { const response = await modemMutation.mutateAsync(modemConfig); - if (response?.id) { + if (!response?.id) { toast.success("Modem settings updated successfully", { id: "modemSettings", }); @@ -138,7 +146,6 @@ const ModemSettings = () => { id="serverPrimary" type="text" className="p-1.5 border border-gray-400 rounded-lg" - validate={ValidateIPaddress} /> @@ -151,7 +158,6 @@ const ModemSettings = () => { id="serverSecondary" type="text" className="p-1.5 border border-gray-400 rounded-lg" - validate={ValidateIPaddress} /> diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 9707968..7cdc0a8 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -185,15 +185,13 @@ export const reverseZoomMapping = (magnification: string) => { } }; -export function ValidateIPaddress(ipaddress: string) { - if (!ipaddress) { - return undefined; - } else if ( - !/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test( - ipaddress - ) - ) { - return "Invalid IP"; +export const ValidateIPaddress = (value: string | undefined) => { + if (!value) return; + + const regex = + /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/; + + if (!regex.test(value)) { + return "Invalid IP address format"; } - return undefined; -} +};