Compare commits
3 Commits
enhancemen
...
feature/se
| Author | SHA1 | Date | |
|---|---|---|---|
| d9594546a0 | |||
| dbadc7388c | |||
| 748be931ed |
25
src/features/settings/components/Settings.tsx
Normal file
25
src/features/settings/components/Settings.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Tabs, Tab, TabList, TabPanel } from "react-tabs";
|
||||
import "react-tabs/style/react-tabs.css";
|
||||
import Card from "../../../ui/Card";
|
||||
import SystemConfig from "./SystemConfig";
|
||||
import CardHeader from "../../../ui/CardHeader";
|
||||
|
||||
const Settings = () => {
|
||||
return (
|
||||
<div>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
<Tab>Systems</Tab>
|
||||
</TabList>
|
||||
<TabPanel>
|
||||
<Card className="p-4">
|
||||
<CardHeader title="System Configuration" />
|
||||
<SystemConfig />
|
||||
</Card>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
133
src/features/settings/components/SystemConfig.tsx
Normal file
133
src/features/settings/components/SystemConfig.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import { Formik, Form, Field } from "formik";
|
||||
import { useSystemSettings } from "../hooks/useSystemSettings";
|
||||
import type { SystemSettings } from "../../../types/types";
|
||||
import { toast } from "sonner";
|
||||
|
||||
const SystemConfig = () => {
|
||||
const { systemSettingsQuery, systemSettingsMutation } = useSystemSettings();
|
||||
|
||||
const timeZoneOptions = systemSettingsQuery?.data?.propLocalTimeZone?.accepted;
|
||||
const timeZoneOpts = timeZoneOptions?.split(",").map((option: string) => option.trim().replace(/\[|\]/g, ""));
|
||||
const timeSourceOptions = systemSettingsQuery?.data?.propTimeSource?.accepted;
|
||||
const timeSourceOpts = timeSourceOptions?.split(",").map((option: string) => option.trim().replace(/\[|\]/g, ""));
|
||||
const deviceName = systemSettingsQuery?.data?.propDeviceName?.value;
|
||||
const timeZone = systemSettingsQuery?.data?.propLocalTimeZone?.value;
|
||||
const SNTPServer = systemSettingsQuery?.data?.propSNTPServer?.value;
|
||||
const SNTPInterval = systemSettingsQuery?.data?.propSNTPIntervalMinutes?.value;
|
||||
const timeSource = systemSettingsQuery?.data?.propTimeSource?.value;
|
||||
// const primaryServer = systemSettingsQuery?.data?.propPrimaryDNSServer?.value;
|
||||
// const secondaryServer = systemSettingsQuery?.data?.propSecondaryDNSServer?.value;
|
||||
|
||||
const initialValues = {
|
||||
deviceName: deviceName ?? "",
|
||||
timeZone: timeZone ?? "",
|
||||
localTimeZone: timeZone ?? "",
|
||||
SNTPServer: SNTPServer ?? "",
|
||||
SNTPInterval: SNTPInterval ?? 60,
|
||||
SNTPIntervalMinutes: SNTPInterval ?? 60,
|
||||
primaryServer: "",
|
||||
secondaryServer: "",
|
||||
timeSource: timeSource ?? "",
|
||||
};
|
||||
|
||||
const handleSubmit = async (values: SystemSettings) => {
|
||||
const result = await systemSettingsMutation.mutateAsync(values);
|
||||
console.log(result);
|
||||
if (result.id) {
|
||||
toast.success("System settings updated successfully");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Formik initialValues={initialValues} onSubmit={handleSubmit} enableReinitialize>
|
||||
<Form>
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="deviceName">Device Name</label>
|
||||
<Field
|
||||
name="deviceName"
|
||||
type="text"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
||||
placeholder="Enter device name"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="timeZone">Timezone</label>
|
||||
<Field
|
||||
name="timeZone"
|
||||
as="select"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs bg-[#253445] "
|
||||
autoComplete="off"
|
||||
>
|
||||
{timeZoneOpts?.map((option: string) => (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="timeSource">Time Source</label>
|
||||
<Field
|
||||
name="timeSource"
|
||||
as="select"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs bg-[#253445] "
|
||||
autoComplete="off"
|
||||
>
|
||||
{timeSourceOpts?.map((option: string) => (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
))}
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="SNTPServer">SNTP Server</label>
|
||||
<Field
|
||||
name="SNTPServer"
|
||||
type="text"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
||||
placeholder="Enter SNTP server"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="SNTPInterval">SNTP Interval</label>
|
||||
<Field
|
||||
name="SNTPInterval"
|
||||
type="number"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
||||
placeholder="Enter SNTP interval"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="primaryServer">Primary DNS Server</label>
|
||||
<Field
|
||||
name="primaryServer"
|
||||
type="text"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
||||
placeholder="Enter primary DNS server"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between items-center mb-4">
|
||||
<label htmlFor="secondaryServer">Secondary DNS Server</label>
|
||||
<Field
|
||||
name="secondaryServer"
|
||||
type="text"
|
||||
className="p-2 border border-gray-400 rounded-lg w-full max-w-xs"
|
||||
placeholder="Enter secondary DNS server"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="px-4 py-2 bg-green-700 text-white rounded-lg">
|
||||
Save Settings
|
||||
</button>
|
||||
</Form>
|
||||
</Formik>
|
||||
);
|
||||
};
|
||||
|
||||
export default SystemConfig;
|
||||
54
src/features/settings/hooks/useSystemSettings.ts
Normal file
54
src/features/settings/hooks/useSystemSettings.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||
import { CAMBASE } from "../../../utils/config";
|
||||
import type { SystemSettings } from "../../../types/types";
|
||||
const camBase = import.meta.env.MODE !== "development" ? CAMBASE : "";
|
||||
|
||||
const fetchSystemSettings = async () => {
|
||||
const response = await fetch(`${camBase}/api/fetch-config?id=GLOBAL--Device`);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch system settings");
|
||||
}
|
||||
return response.json();
|
||||
};
|
||||
|
||||
const postSystemSettings = async (settings: SystemSettings) => {
|
||||
const systemSettingConfig = {
|
||||
id: "GLOBAL--Device",
|
||||
fields: [
|
||||
{ property: "propDeviceName", value: settings.deviceName },
|
||||
{ property: "propSNTPServer", value: settings.SNTPServer },
|
||||
{
|
||||
property: "propSNTPIntervalMinutes",
|
||||
value: Number(settings.SNTPIntervalMinutes),
|
||||
},
|
||||
{ property: "propLocalTimeZone", value: settings.localTimeZone },
|
||||
{ property: "propTimeSource", value: settings.timeSource },
|
||||
],
|
||||
};
|
||||
|
||||
const response = await fetch(`${camBase}/api/update-config`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(systemSettingConfig),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to update system settings");
|
||||
}
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const useSystemSettings = () => {
|
||||
const systemSettingsQuery = useQuery({
|
||||
queryKey: ["systemSettings"],
|
||||
queryFn: fetchSystemSettings,
|
||||
});
|
||||
|
||||
const systemSettingsMutation = useMutation({
|
||||
mutationKey: ["updateSystemSettings"],
|
||||
mutationFn: postSystemSettings,
|
||||
});
|
||||
|
||||
return { systemSettingsQuery, systemSettingsMutation };
|
||||
};
|
||||
@@ -2,12 +2,14 @@ import { createRootRoute, Outlet } from "@tanstack/react-router";
|
||||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||
import Header from "../ui/Header";
|
||||
import Footer from "../ui/Footer";
|
||||
import { Toaster } from "sonner";
|
||||
|
||||
const RootLayout = () => (
|
||||
<>
|
||||
<Header />
|
||||
<main className="p-4 min-h-screen">
|
||||
<Outlet />
|
||||
<Toaster />
|
||||
</main>
|
||||
<Footer />
|
||||
<TanStackRouterDevtools position="bottom-right" />
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import CameraGrid from "../features/cameras/components/CameraGrid";
|
||||
import { Toaster } from "sonner";
|
||||
|
||||
export const Route = createFileRoute("/baywatch")({
|
||||
component: RouteComponent,
|
||||
@@ -10,7 +9,6 @@ function RouteComponent() {
|
||||
return (
|
||||
<div>
|
||||
<CameraGrid />
|
||||
<Toaster />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import Settings from "../features/settings/components/Settings";
|
||||
|
||||
export const Route = createFileRoute('/settings')({
|
||||
export const Route = createFileRoute("/settings")({
|
||||
component: RouteComponent,
|
||||
})
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return <div>Hello "/settings"!</div>
|
||||
return (
|
||||
<div>
|
||||
<Settings />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,3 +175,13 @@ export type ColourDetectionPayload = {
|
||||
cameraFeedID: "A" | "B" | "C";
|
||||
regions: ColourData[];
|
||||
};
|
||||
|
||||
export type SystemSettings = {
|
||||
deviceName: string;
|
||||
localTimeZone: string;
|
||||
timeSource: string;
|
||||
SNTPServer: string;
|
||||
SNTPIntervalMinutes: number;
|
||||
primaryServer?: string;
|
||||
secondaryServer?: string;
|
||||
};
|
||||
|
||||
@@ -13,4 +13,12 @@ export default defineConfig({
|
||||
react(),
|
||||
tailwindcss(),
|
||||
],
|
||||
server: {
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: "http://100.115.125.56",
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user