mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-21 00:48:45 -05:00
simplify form
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
import { BasePage, ConfigBox } from "@/Components/v2/design-elements";
|
||||
import { Autocomplete, Select } from "@/Components/v2/inputs";
|
||||
import { Stack, useTheme, MenuItem, type SelectChangeEvent } from "@mui/material";
|
||||
import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import DummyChart from "@/Pages/Settings/DummyChart";
|
||||
import { useGet } from "@/Hooks/UseApi";
|
||||
import { useSettingsForm } from "@/Hooks/useSettingsForm";
|
||||
import type { SettingsFormData } from "@/Validation/settings";
|
||||
|
||||
import {
|
||||
setTimezone,
|
||||
@@ -25,6 +31,23 @@ export const SettingsPage = () => {
|
||||
const theme = useTheme();
|
||||
const { t, i18n } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
// Fetch settings data from API
|
||||
const { data: fetchedSettings } = useGet<any>("/settings");
|
||||
|
||||
// Initialize form with schema and defaults
|
||||
const { schema, defaults } = useSettingsForm({ data: fetchedSettings?.settings });
|
||||
|
||||
const form = useForm<SettingsFormData>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: defaults,
|
||||
});
|
||||
|
||||
// Reset form when defaults change
|
||||
useEffect(() => {
|
||||
form.reset(defaults);
|
||||
}, [defaults, form]);
|
||||
|
||||
const {
|
||||
timezone: selectedTimezoneId,
|
||||
mode,
|
||||
@@ -61,7 +84,7 @@ export const SettingsPage = () => {
|
||||
const languages = Object.keys(i18n.options.resources || {});
|
||||
|
||||
return (
|
||||
<BasePage>
|
||||
<BasePage component="form">
|
||||
<Stack gap={theme.spacing(8)}>
|
||||
<ConfigBox
|
||||
title={t("pages.settings.form.timezone.title")}
|
||||
|
||||
@@ -1,69 +1,51 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// Helper to normalize empty strings to undefined
|
||||
const optionalString = () =>
|
||||
z.preprocess(
|
||||
(val) =>
|
||||
val === "" || val === null || val === undefined ? undefined : String(val).trim(),
|
||||
z.string().optional()
|
||||
);
|
||||
|
||||
// Helper for threshold fields
|
||||
const thresholdField = (min: number, max: number, unit: string) =>
|
||||
z.preprocess(
|
||||
(val) => (val === "" || val === null || val === undefined ? undefined : val),
|
||||
z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.min(min, `Min ${min}${unit}`)
|
||||
.max(max, `Max ${max}${unit}`)
|
||||
.optional()
|
||||
);
|
||||
|
||||
export const settingsSchema = z.object({
|
||||
systemEmailIgnoreTLS: z.boolean(),
|
||||
systemEmailRequireTLS: z.boolean(),
|
||||
systemEmailRejectUnauthorized: z.boolean(),
|
||||
systemEmailConnectionHost: optionalString(),
|
||||
systemEmailConnectionHost: z
|
||||
.string()
|
||||
.transform((val) => (val.trim() === "" ? undefined : val.trim()))
|
||||
.optional(),
|
||||
systemEmailSecure: z.boolean().optional(),
|
||||
systemEmailPool: z.boolean().optional(),
|
||||
showURL: z.boolean().optional(),
|
||||
checkTTL: z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.min(1, "Please enter a value")
|
||||
.max(365, "Maximum 365 days"),
|
||||
pagespeedApiKey: optionalString(),
|
||||
systemEmailHost: z.preprocess(
|
||||
(val) =>
|
||||
val === "" || val === null || val === undefined ? undefined : String(val).trim(),
|
||||
z
|
||||
.string()
|
||||
.regex(/^[a-zA-Z0-9.-]+$/, "Invalid hostname or IP address")
|
||||
.optional()
|
||||
),
|
||||
systemEmailPort: z.preprocess(
|
||||
(val) => (val === "" || val === null || val === undefined ? undefined : val),
|
||||
z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.min(1, "Port must be at least 1")
|
||||
.max(65535, "Port must be at most 65535")
|
||||
.optional()
|
||||
),
|
||||
systemEmailAddress: z.preprocess((val) => {
|
||||
if (val === "" || val === null || val === undefined) return undefined;
|
||||
return String(val).toLowerCase().trim();
|
||||
}, z.string().email("Please enter a valid email address").optional()),
|
||||
systemEmailUser: optionalString(),
|
||||
systemEmailPassword: optionalString(),
|
||||
systemEmailTLSServername: optionalString(),
|
||||
checkTTL: z.number().int().min(1, "Please enter a value").max(365, "Maximum 365 days"),
|
||||
pagespeedApiKey: z
|
||||
.string()
|
||||
.transform((val) => (val.trim() === "" ? undefined : val.trim()))
|
||||
.optional(),
|
||||
systemEmailHost: z
|
||||
.string()
|
||||
.regex(/^[a-zA-Z0-9.-]*$/, "Invalid hostname or IP address")
|
||||
.transform((val) => (val.trim() === "" ? undefined : val.trim()))
|
||||
.optional(),
|
||||
systemEmailPort: z.number().int().min(1).max(65535).optional(),
|
||||
systemEmailAddress: z
|
||||
.string()
|
||||
.email("Please enter a valid email address")
|
||||
.or(z.literal(""))
|
||||
.transform((val) => (val === "" ? undefined : val.toLowerCase().trim()))
|
||||
.optional(),
|
||||
systemEmailUser: z
|
||||
.string()
|
||||
.transform((val) => (val.trim() === "" ? undefined : val.trim()))
|
||||
.optional(),
|
||||
systemEmailPassword: z
|
||||
.string()
|
||||
.transform((val) => (val.trim() === "" ? undefined : val.trim()))
|
||||
.optional(),
|
||||
systemEmailTLSServername: z
|
||||
.string()
|
||||
.transform((val) => (val.trim() === "" ? undefined : val.trim()))
|
||||
.optional(),
|
||||
globalThresholds: z
|
||||
.object({
|
||||
cpu: thresholdField(0, 100, "%"),
|
||||
memory: thresholdField(0, 100, "%"),
|
||||
disk: thresholdField(0, 100, "%"),
|
||||
temperature: thresholdField(0, 150, "°C"),
|
||||
cpu: z.number().int().min(0).max(100).optional(),
|
||||
memory: z.number().int().min(0).max(100).optional(),
|
||||
disk: z.number().int().min(0).max(100).optional(),
|
||||
temperature: z.number().int().min(0).max(150).optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user