229 lines
8.7 KiB
TypeScript
229 lines
8.7 KiB
TypeScript
import { Formik, Field, Form } from "formik";
|
|
import FormGroup from "../components/FormGroup";
|
|
import { useReboots } from "../../../hooks/useReboots";
|
|
import { timezones } from "./timezones";
|
|
import SystemFileUpload from "./SystemFileUpload";
|
|
import type { SystemValues, SystemValuesErrors } from "../../../types/types";
|
|
import { useDNSSettings, useSystemConfig } from "../../../hooks/useSystemConfig";
|
|
import { ValidateIPaddress, isUtcOutOfSync } from "../../../utils/utils";
|
|
import { toast } from "sonner";
|
|
import { useSystemStatus } from "../../../hooks/useSystemStatus";
|
|
import ResetUserSettings from "./resetUserSettings/ResetUserSettings";
|
|
|
|
const SystemConfigFields = () => {
|
|
const { saveSystemSettings, systemSettingsData, saveSystemSettingsLoading } = useSystemConfig();
|
|
const { systemStatusQuery } = useSystemStatus();
|
|
const { hardRebootMutation } = useReboots();
|
|
const { dnsQuery, dnsMutation } = useDNSSettings();
|
|
|
|
if (systemStatusQuery?.isLoading || !systemStatusQuery?.data) {
|
|
return <div>Loading...</div>;
|
|
}
|
|
const utcTime = systemStatusQuery?.data?.SystemStatus?.utctime;
|
|
const localDate = systemStatusQuery?.data?.SystemStatus?.localdate;
|
|
const localTime = systemStatusQuery?.data?.SystemStatus?.localtime;
|
|
|
|
const utcOutOfSync = isUtcOutOfSync({
|
|
utctime: utcTime,
|
|
localdate: localDate,
|
|
localtime: localTime,
|
|
});
|
|
const syncTime = new Date(systemStatusQuery?.data?.SystemStatus?.synctime * 1000).toLocaleString();
|
|
|
|
const sntpInterval = systemSettingsData?.sntpInterval;
|
|
const dnsPrimary = dnsQuery?.data?.propNameServerPrimary?.value;
|
|
const dnsSecondary = dnsQuery?.data?.propNameServerSecondary?.value;
|
|
|
|
const initialvalues: SystemValues = {
|
|
deviceName: systemSettingsData?.deviceName ?? "",
|
|
timeZone: systemSettingsData?.timeZone ?? "",
|
|
sntpServer: systemSettingsData?.sntpServer ?? "",
|
|
sntpInterval: sntpInterval ?? 60,
|
|
serverPrimary: dnsPrimary ?? "",
|
|
serverSecondary: dnsSecondary ?? "",
|
|
softwareUpdate: null,
|
|
};
|
|
|
|
const handleSubmit = async (values: SystemValues) => {
|
|
saveSystemSettings(values);
|
|
await dnsMutation.mutateAsync(values);
|
|
};
|
|
|
|
const validateValues = (values: SystemValues) => {
|
|
const errors: SystemValuesErrors = {};
|
|
const interval = Number(values.sntpInterval);
|
|
if (!values.deviceName) errors.deviceName = "Required";
|
|
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;
|
|
};
|
|
|
|
// const handleSoftReboot = async () => {
|
|
// await softRebootMutation.mutate();
|
|
// };
|
|
|
|
const handleHardReboot = async () => {
|
|
await hardRebootMutation.mutate();
|
|
};
|
|
|
|
return (
|
|
<Formik
|
|
initialValues={initialvalues}
|
|
onSubmit={handleSubmit}
|
|
validate={validateValues}
|
|
enableReinitialize
|
|
validateOnChange={false}
|
|
validateOnBlur
|
|
>
|
|
{({ values, errors, touched, isSubmitting }) => (
|
|
<Form className="flex flex-col space-y-5 px-2">
|
|
<FormGroup>
|
|
<label htmlFor="deviceName" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
|
Device Name
|
|
</label>
|
|
{touched.deviceName && errors.deviceName && (
|
|
<small className="absolute right-0 -top-5 text-red-500">{errors.deviceName}</small>
|
|
)}
|
|
<Field
|
|
id="deviceName"
|
|
name="deviceName"
|
|
type="text"
|
|
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
|
placeholder="Enter device name"
|
|
autoComplete="off"
|
|
/>
|
|
</FormGroup>
|
|
<FormGroup>
|
|
<label htmlFor="timeZone" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
|
Local Time Zone
|
|
</label>
|
|
{touched.timeZone && errors.timeZone && (
|
|
<small className="absolute right-0 -top-5 text-red-500">{errors.timeZone}</small>
|
|
)}
|
|
<Field
|
|
id="timeZone"
|
|
name="timeZone"
|
|
as="select"
|
|
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full max-w-xs"
|
|
>
|
|
<option value="">Select a timezone…</option>
|
|
{timezones.map((timezone) => (
|
|
<option value={timezone.value} key={timezone.label}>
|
|
{timezone.label}
|
|
</option>
|
|
))}
|
|
</Field>
|
|
</FormGroup>
|
|
<FormGroup>
|
|
<label htmlFor="sntpServer" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
|
SNTP Server
|
|
</label>
|
|
{touched.sntpServer && errors.sntpServer && (
|
|
<small className="absolute right-0 -top-5 text-red-500">{errors.sntpServer}</small>
|
|
)}
|
|
<Field
|
|
id="sntpServer"
|
|
name="sntpServer"
|
|
type="text"
|
|
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
|
placeholder="Enter SNTP server address"
|
|
autoComplete="off"
|
|
/>
|
|
</FormGroup>
|
|
|
|
<FormGroup>
|
|
<label htmlFor="sntpInterval" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
|
SNTP Interval minutes
|
|
</label>
|
|
{touched.sntpInterval && errors.sntpInterval && (
|
|
<small className="absolute right-0 -top-5 text-red-500">{errors.sntpInterval}</small>
|
|
)}
|
|
<Field
|
|
id="sntpInterval"
|
|
name="sntpInterval"
|
|
type="number"
|
|
min={1}
|
|
inputMode="numeric"
|
|
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
|
/>
|
|
</FormGroup>
|
|
<FormGroup>
|
|
<label htmlFor="serverPrimary" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
|
Primary DNS Server
|
|
</label>
|
|
|
|
<Field
|
|
id="serverPrimary"
|
|
name="serverPrimary"
|
|
type="text"
|
|
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
|
placeholder="Enter DNS primary address"
|
|
autoComplete="off"
|
|
/>
|
|
</FormGroup>
|
|
<FormGroup>
|
|
<label htmlFor="serverSecondary" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
|
Secondary DNS Server
|
|
</label>
|
|
|
|
<Field
|
|
id="serverSecondary"
|
|
name="serverSecondary"
|
|
type="text"
|
|
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
|
placeholder="Enter DNS secondary address"
|
|
autoComplete="off"
|
|
/>
|
|
</FormGroup>
|
|
<div className="flex flex-col gap-2 w-70">
|
|
{utcOutOfSync?.outOfSync ? (
|
|
<span className="text-red-800 bg-red-300 border border-red-800 rounded-lg p-2 ">UTC is out of sync</span>
|
|
) : (
|
|
<span className="text-green-300 bg-green-800 border border-green-600 rounded-lg p-2">UTC is in sync</span>
|
|
)}
|
|
<p className="mt-2">Last Sync Time: {syncTime}</p>
|
|
</div>
|
|
<button
|
|
type="submit"
|
|
className="w-full md:w-1/4 text-white bg-green-700 hover:bg-green-800 font-small rounded-lg text-sm px-2 py-2.5"
|
|
disabled={isSubmitting}
|
|
>
|
|
{saveSystemSettingsLoading ? "Saving..." : "Save System Settings"}
|
|
</button>
|
|
<SystemFileUpload name={"softwareUpdate"} selectedFile={values.softwareUpdate} />
|
|
<div className="border-b border-gray-600">
|
|
<p>Reboot</p>
|
|
</div>
|
|
|
|
{/* <button
|
|
type="button"
|
|
className="bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700 transition w-full md:w-[50%]"
|
|
onClick={handleSoftReboot}
|
|
>
|
|
{softRebootMutation.isPending || isSubmitting ? "Rebooting..." : "Software Reboot"}
|
|
</button> */}
|
|
<button
|
|
type="button"
|
|
className="bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700 transition w-full md:w-[50%]"
|
|
onClick={handleHardReboot}
|
|
>
|
|
{hardRebootMutation.isPending || isSubmitting ? "Rebooting" : "Hardware Reboot"}
|
|
</button>
|
|
<ResetUserSettings />
|
|
</Form>
|
|
)}
|
|
</Formik>
|
|
);
|
|
};
|
|
|
|
export default SystemConfigFields;
|