updated NPED code
This commit is contained in:
3
.env
3
.env
@@ -1,2 +1,3 @@
|
|||||||
VITE_BASEURL=http://192.168.75.11/
|
VITE_BASEURL=http://192.168.75.11/
|
||||||
VITE_TESTURL=http://100.82.205.44/SightingListRear/sightingSummary?mostRecentRef=-1
|
VITE_TESTURL=http://100.82.205.44/SightingListRear/sightingSummary?mostRecentRef=-1
|
||||||
|
VITE_OUTSIDE_BASEURL=http://100.82.205.44/api
|
||||||
19
src/App.tsx
19
src/App.tsx
@@ -4,17 +4,20 @@ import { Route, Routes } from "react-router";
|
|||||||
import FrontCamera from "./pages/FrontCamera";
|
import FrontCamera from "./pages/FrontCamera";
|
||||||
import RearCamera from "./pages/RearCamera";
|
import RearCamera from "./pages/RearCamera";
|
||||||
import SystemSettings from "./pages/SystemSettings";
|
import SystemSettings from "./pages/SystemSettings";
|
||||||
|
import { NPEDUserProvider } from "./context/providers/NPEDUserContextProvider";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<NPEDUserProvider>
|
||||||
<Route path="/" element={<Container />}>
|
<Routes>
|
||||||
<Route index element={<Dashboard />} />
|
<Route path="/" element={<Container />}>
|
||||||
<Route path="front-camera-settings" element={<FrontCamera />} />
|
<Route index element={<Dashboard />} />
|
||||||
<Route path="rear-camera-settings" element={<RearCamera />} />
|
<Route path="front-camera-settings" element={<FrontCamera />} />
|
||||||
<Route path="system-settings" element={<SystemSettings />} />
|
<Route path="rear-camera-settings" element={<RearCamera />} />
|
||||||
</Route>
|
<Route path="system-settings" element={<SystemSettings />} />
|
||||||
</Routes>
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</NPEDUserProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import Card from "../../UI/Card";
|
import Card from "../../UI/Card";
|
||||||
import CardHeader from "../../UI/CardHeader";
|
import CardHeader from "../../UI/CardHeader";
|
||||||
import NPEDFields from "./NPEDFields";
|
import NPEDFields from "./NPEDFields";
|
||||||
|
import { useNPEDContext } from "../../../context/NPEDUserContext";
|
||||||
|
|
||||||
const NPEDCard = () => {
|
const NPEDCard = () => {
|
||||||
|
const { user } = useNPEDContext();
|
||||||
|
console.log(user);
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader title={"NPED Config"} />
|
<CardHeader title={"NPED Config"} />
|
||||||
|
|||||||
@@ -1,62 +1,97 @@
|
|||||||
import { Form, Formik, Field } from "formik";
|
import { Form, Formik, Field } from "formik";
|
||||||
import FormGroup from "../components/FormGroup";
|
import FormGroup from "../components/FormGroup";
|
||||||
import type { NPEDFieldType } from "../../../types/types";
|
import type { NPEDErrorValues, NPEDFieldType } from "../../../types/types";
|
||||||
import { useNPEDAuth } from "../../../hooks/useNPEDAuh";
|
import { useNPEDAuth } from "../../../hooks/useNPEDAuth";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
const NPEDFields = () => {
|
const NPEDFields = () => {
|
||||||
const { signIn, isError } = useNPEDAuth();
|
const { signIn } = useNPEDAuth();
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
username: "",
|
username: "",
|
||||||
password: "",
|
password: "",
|
||||||
clientId: "",
|
clientId: "",
|
||||||
|
frontId: "NPEDFront",
|
||||||
|
rearId: "NPEDRear",
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = (values: NPEDFieldType) => {
|
const handleSubmit = (values: NPEDFieldType) => {
|
||||||
console.log(isError);
|
const valuesToSend = {
|
||||||
signIn(values);
|
...values,
|
||||||
|
};
|
||||||
|
signIn(valuesToSend);
|
||||||
|
toast("Signed in successfully");
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateValues = (values: NPEDFieldType) => {
|
||||||
|
const errors: NPEDErrorValues = {};
|
||||||
|
if (!values.username) errors.username = "Required";
|
||||||
|
if (!values.password) errors.password = "Required";
|
||||||
|
if (!values.clientId) errors.clientId = "Required";
|
||||||
|
return errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
<Formik
|
||||||
<Form className="flex flex-col space-y-2">
|
initialValues={initialValues}
|
||||||
<FormGroup>
|
onSubmit={handleSubmit}
|
||||||
<label htmlFor="username">Username</label>
|
validate={validateValues}
|
||||||
<Field
|
>
|
||||||
name="username"
|
{({ errors, touched }) => (
|
||||||
type="text"
|
<Form className="flex flex-col space-y-5">
|
||||||
id="username"
|
<FormGroup>
|
||||||
placeholder="NPED username"
|
<label htmlFor="username">Username</label>
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
{touched.username && errors.username && (
|
||||||
/>
|
<small className="absolute right-0 -top-5 text-red-500">
|
||||||
</FormGroup>
|
{errors.username}
|
||||||
<FormGroup>
|
</small>
|
||||||
<label htmlFor="password">Password</label>
|
)}
|
||||||
<Field
|
<Field
|
||||||
name="password"
|
name="username"
|
||||||
type="password"
|
type="text"
|
||||||
id="password"
|
id="username"
|
||||||
placeholder="NPED Password"
|
placeholder="NPED username"
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
className="p-1.5 border border-gray-400 rounded-lg"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<label htmlFor="clientId">Client ID</label>
|
<label htmlFor="password">Password</label>
|
||||||
<Field
|
{touched.password && errors.password && (
|
||||||
name="clientId"
|
<small className="absolute right-0 -top-5 text-red-500">
|
||||||
type="text"
|
{errors.password}
|
||||||
id="clientId"
|
</small>
|
||||||
placeholder="NPED client ID"
|
)}
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
<Field
|
||||||
/>
|
name="password"
|
||||||
</FormGroup>
|
type="password"
|
||||||
<button
|
id="password"
|
||||||
type="submit"
|
placeholder="NPED Password"
|
||||||
className="w-1/4 text-white bg-green-700 hover:bg-green-800 font-small rounded-lg text-sm px-2 py-2.5"
|
className="p-1.5 border border-gray-400 rounded-lg"
|
||||||
>
|
/>
|
||||||
Login
|
</FormGroup>
|
||||||
</button>
|
<FormGroup>
|
||||||
</Form>
|
<label htmlFor="clientId">Client ID</label>
|
||||||
|
{touched.clientId && errors.clientId && (
|
||||||
|
<small className="absolute right-0 -top-5 text-red-500">
|
||||||
|
{errors.clientId}
|
||||||
|
</small>
|
||||||
|
)}
|
||||||
|
<Field
|
||||||
|
name="clientId"
|
||||||
|
type="text"
|
||||||
|
id="clientId"
|
||||||
|
placeholder="NPED client ID"
|
||||||
|
className="p-1.5 border border-gray-400 rounded-lg"
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-1/4 text-white bg-green-700 hover:bg-green-800 font-small rounded-lg text-sm px-2 py-2.5"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ type FormGroupProps = {
|
|||||||
|
|
||||||
const FormGroup = ({ children }: FormGroupProps) => {
|
const FormGroup = ({ children }: FormGroupProps) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col md:flex-row items-center justify-between">
|
<div className="flex flex-col md:flex-row items-center justify-between relative">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
import { Link } from "react-router";
|
import { Link } from "react-router";
|
||||||
import Logo from "/MAV.svg";
|
import Logo from "/MAV.svg";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { faSliders } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
return (
|
return (
|
||||||
<div className="relative bg-[#253445] border-b border-gray-500 items-center mx-auto px-2 sm:px-6 lg:px-8 p-4">
|
<div className="relative bg-[#253445] border-b border-gray-500 items-center mx-auto px-2 sm:px-6 lg:px-8 p-4 flex flex-row justify-between">
|
||||||
<div className="w-30">
|
<div className="w-30">
|
||||||
<Link to={"/"}>
|
<Link to={"/"}>
|
||||||
<img src={Logo} alt="Logo" width={100} height={100} />
|
<img src={Logo} alt="Logo" width={100} height={100} />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
<Link to={"/system-settings"}>
|
||||||
|
<FontAwesomeIcon icon={faSliders} />
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
17
src/context/NPEDUserContext.tsx
Normal file
17
src/context/NPEDUserContext.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { createContext, useContext, type SetStateAction } from "react";
|
||||||
|
import type { NPEDUser } from "../types/types";
|
||||||
|
|
||||||
|
type UserContextValue = {
|
||||||
|
user: NPEDUser | null;
|
||||||
|
setUser: React.Dispatch<SetStateAction<NPEDUser | null>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NPEDUserContext = createContext<UserContextValue | undefined>(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
export const useNPEDContext = () => {
|
||||||
|
const ctx = useContext(NPEDUserContext);
|
||||||
|
if (!ctx)
|
||||||
|
throw new Error("useNPEDContext must be used within <NPEDUserProvider>");
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { createContext, useContext, type ReactNode } from "react";
|
import { createContext, useContext } from "react";
|
||||||
import type { SightingWidgetType } from "../types/types";
|
import type { SightingWidgetType } from "../types/types";
|
||||||
import { useSightingFeed } from "../hooks/useSightingFeed";
|
|
||||||
|
|
||||||
type SightingFeedContextType = {
|
type SightingFeedContextType = {
|
||||||
sightings: (SightingWidgetType | null | undefined)[];
|
sightings: (SightingWidgetType | null | undefined)[];
|
||||||
@@ -13,50 +12,10 @@ type SightingFeedContextType = {
|
|||||||
noSighting: boolean;
|
noSighting: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SightingFeedProviderProps = {
|
export const SightingFeedContext = createContext<
|
||||||
url: string;
|
SightingFeedContextType | undefined
|
||||||
children: ReactNode;
|
>(undefined);
|
||||||
side: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const SightingFeedContext = createContext<SightingFeedContextType | undefined>(
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
export const SightingFeedProvider = ({
|
|
||||||
children,
|
|
||||||
url,
|
|
||||||
side,
|
|
||||||
}: SightingFeedProviderProps) => {
|
|
||||||
const {
|
|
||||||
sightings,
|
|
||||||
selectedRef,
|
|
||||||
setSelectedRef,
|
|
||||||
effectiveSelected,
|
|
||||||
mostRecent,
|
|
||||||
isPending,
|
|
||||||
noSighting,
|
|
||||||
} = useSightingFeed(url);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SightingFeedContext.Provider
|
|
||||||
value={{
|
|
||||||
sightings,
|
|
||||||
selectedRef,
|
|
||||||
setSelectedRef,
|
|
||||||
effectiveSelected,
|
|
||||||
mostRecent,
|
|
||||||
side,
|
|
||||||
isPending,
|
|
||||||
noSighting,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</SightingFeedContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// eslint-disable-next-line react-refresh/only-export-components
|
|
||||||
export const useSightingFeedContext = () => {
|
export const useSightingFeedContext = () => {
|
||||||
const ctx = useContext(SightingFeedContext);
|
const ctx = useContext(SightingFeedContext);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
|
|||||||
17
src/context/providers/NPEDUserContextProvider.tsx
Normal file
17
src/context/providers/NPEDUserContextProvider.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { useState, type ReactNode } from "react";
|
||||||
|
import type { NPEDUser } from "../../types/types";
|
||||||
|
import { NPEDUserContext } from "../NPEDUserContext";
|
||||||
|
|
||||||
|
type NPEDUserProviderType = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NPEDUserProvider = ({ children }: NPEDUserProviderType) => {
|
||||||
|
const [user, setUser] = useState<NPEDUser | null>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NPEDUserContext.Provider value={{ user, setUser }}>
|
||||||
|
{children}
|
||||||
|
</NPEDUserContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
42
src/context/providers/SightingFeedProvider.tsx
Normal file
42
src/context/providers/SightingFeedProvider.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import { useSightingFeed } from "../../hooks/useSightingFeed";
|
||||||
|
import { SightingFeedContext } from "../SightingFeedContext";
|
||||||
|
|
||||||
|
type SightingFeedProviderProps = {
|
||||||
|
url: string;
|
||||||
|
children: ReactNode;
|
||||||
|
side: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SightingFeedProvider = ({
|
||||||
|
children,
|
||||||
|
url,
|
||||||
|
side,
|
||||||
|
}: SightingFeedProviderProps) => {
|
||||||
|
const {
|
||||||
|
sightings,
|
||||||
|
selectedRef,
|
||||||
|
setSelectedRef,
|
||||||
|
effectiveSelected,
|
||||||
|
mostRecent,
|
||||||
|
isPending,
|
||||||
|
noSighting,
|
||||||
|
} = useSightingFeed(url);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SightingFeedContext.Provider
|
||||||
|
value={{
|
||||||
|
sightings,
|
||||||
|
selectedRef,
|
||||||
|
setSelectedRef,
|
||||||
|
effectiveSelected,
|
||||||
|
mostRecent,
|
||||||
|
side,
|
||||||
|
isPending,
|
||||||
|
noSighting,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SightingFeedContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import { useMutation } from "@tanstack/react-query";
|
|
||||||
import type { NPEDFieldType } from "../types/types";
|
|
||||||
|
|
||||||
const url = "https://jsonplaceholder.typicode.com/posts";
|
|
||||||
|
|
||||||
async function signIn(loginDetails: NPEDFieldType) {
|
|
||||||
console.log(loginDetails);
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(loginDetails),
|
|
||||||
});
|
|
||||||
if (!response.ok) throw new Error("cannot reach NPED endpoint");
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function signOut() {
|
|
||||||
const response = await fetch(url, { method: "POST" });
|
|
||||||
if (!response.ok) throw new Error("cannot reach NPED sign out endpoint");
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUserContext(user) {
|
|
||||||
console.log(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useNPEDAuth = () => {
|
|
||||||
const signInMutation = useMutation({
|
|
||||||
mutationKey: ["NPEDSignin"],
|
|
||||||
mutationFn: signIn,
|
|
||||||
onSuccess: (data) => setUserContext(data),
|
|
||||||
});
|
|
||||||
|
|
||||||
const signOutMutation = useMutation({
|
|
||||||
mutationKey: ["auth", "NPEDSignOut"],
|
|
||||||
mutationFn: signOut,
|
|
||||||
onSuccess: () => setUserContext(null),
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
signIn: signInMutation.mutate,
|
|
||||||
signInAsync: signInMutation.mutateAsync,
|
|
||||||
isPending: signInMutation.isPending,
|
|
||||||
isError: signInMutation.isError,
|
|
||||||
error: signInMutation.error,
|
|
||||||
data: signInMutation.data,
|
|
||||||
|
|
||||||
signOut: signOutMutation.mutate,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
85
src/hooks/useNPEDAuth.ts
Normal file
85
src/hooks/useNPEDAuth.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import { useMutation } from "@tanstack/react-query";
|
||||||
|
import type { NPEDFieldType } from "../types/types";
|
||||||
|
import { useNPEDContext } from "../context/NPEDUserContext";
|
||||||
|
|
||||||
|
const base_url = import.meta.env.VITE_OUTSIDE_BASEURL;
|
||||||
|
|
||||||
|
async function signIn(loginDetails: NPEDFieldType) {
|
||||||
|
const { frontId, rearId, username, password, clientId } = loginDetails;
|
||||||
|
|
||||||
|
const NPEDLoginURLFront = `${base_url}/update-config?id=${frontId}`;
|
||||||
|
const NPEDLoginURLRear = `${base_url}/update-config?id=${rearId}`;
|
||||||
|
|
||||||
|
const frontCameraPayload = {
|
||||||
|
id: frontId,
|
||||||
|
fields: [
|
||||||
|
{ property: "propEnabled", value: true },
|
||||||
|
{ property: "propUsername", value: username },
|
||||||
|
{ property: "propPassword", value: password },
|
||||||
|
{ property: "propClientID", value: clientId },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const rearCameraPayload = {
|
||||||
|
id: rearId,
|
||||||
|
fields: [
|
||||||
|
{ property: "propEnabled", value: true },
|
||||||
|
{ property: "propUsername", value: username },
|
||||||
|
{ property: "propPassword", value: password },
|
||||||
|
{ property: "propClientID", value: clientId },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const frontCameraResponse = await fetch(NPEDLoginURLFront, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(frontCameraPayload),
|
||||||
|
});
|
||||||
|
|
||||||
|
const rearCameraResponse = await fetch(NPEDLoginURLRear, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(rearCameraPayload),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!frontCameraResponse.ok) throw new Error("cannot reach NPED endpoint");
|
||||||
|
if (!rearCameraResponse.ok) throw new Error("cannot reach NPED endpoint");
|
||||||
|
|
||||||
|
console.log(frontCameraResponse);
|
||||||
|
console.log(rearCameraResponse);
|
||||||
|
return {
|
||||||
|
frontResponse: frontCameraResponse.json(),
|
||||||
|
rearResponse: rearCameraResponse.json(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function signOut() {
|
||||||
|
const response = await fetch(url, { method: "POST" });
|
||||||
|
if (!response.ok) throw new Error("cannot reach NPED sign out endpoint");
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useNPEDAuth = () => {
|
||||||
|
const { setUser } = useNPEDContext();
|
||||||
|
|
||||||
|
const signInMutation = useMutation({
|
||||||
|
mutationKey: ["NPEDSignin"],
|
||||||
|
mutationFn: signIn,
|
||||||
|
onSuccess: async (data) => setUser(await data.frontResponse),
|
||||||
|
});
|
||||||
|
|
||||||
|
const signOutMutation = useMutation({
|
||||||
|
mutationKey: ["auth", "NPEDSignOut"],
|
||||||
|
mutationFn: signOut,
|
||||||
|
onSuccess: () => setUser(null),
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
signIn: signInMutation.mutate,
|
||||||
|
signInAsync: signInMutation.mutateAsync,
|
||||||
|
isPending: signInMutation.isPending,
|
||||||
|
isError: signInMutation.isError,
|
||||||
|
error: signInMutation.error,
|
||||||
|
data: signInMutation.data,
|
||||||
|
|
||||||
|
signOut: signOutMutation.mutate,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -2,7 +2,7 @@ import FrontCameraOverviewCard from "../components/FrontCameraOverview/FrontCame
|
|||||||
import RearCameraOverviewCard from "../components/RearCameraOverview/RearCameraOverviewCard";
|
import RearCameraOverviewCard from "../components/RearCameraOverview/RearCameraOverviewCard";
|
||||||
|
|
||||||
import SightingHistoryWidget from "../components/SightingsWidget/SightingWidget";
|
import SightingHistoryWidget from "../components/SightingsWidget/SightingWidget";
|
||||||
import { SightingFeedProvider } from "../context/SightingFeedContext";
|
import { SightingFeedProvider } from "../context/providers/SightingFeedProvider";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import "react-tabs/style/react-tabs.css";
|
|||||||
import NPEDCard from "../components/SettingForms/NPED/NPEDCard";
|
import NPEDCard from "../components/SettingForms/NPED/NPEDCard";
|
||||||
import SettingForms from "../components/SettingForms/SettingForms/SettingForms";
|
import SettingForms from "../components/SettingForms/SettingForms/SettingForms";
|
||||||
import NPEDHotlistCard from "../components/SettingForms/NPED/NPEDHotlistCard";
|
import NPEDHotlistCard from "../components/SettingForms/NPED/NPEDHotlistCard";
|
||||||
|
import { Toaster } from "sonner";
|
||||||
|
|
||||||
const SystemSettings = () => {
|
const SystemSettings = () => {
|
||||||
return (
|
return (
|
||||||
@@ -24,6 +25,7 @@ const SystemSettings = () => {
|
|||||||
</div>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
<Toaster />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -59,9 +59,11 @@ export type InitialValuesForm = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type NPEDFieldType = {
|
export type NPEDFieldType = {
|
||||||
|
frontId: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
clientId: string;
|
clientId: string;
|
||||||
|
rearId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HotlistUploadType = {
|
export type HotlistUploadType = {
|
||||||
@@ -97,3 +99,15 @@ export type SightingWidgetType = {
|
|||||||
overviewPlateRect?: [number, number, number, number]; // [x,y,w,h] normalized 0..1
|
overviewPlateRect?: [number, number, number, number]; // [x,y,w,h] normalized 0..1
|
||||||
plateTrack?: [number, number, number, number][]; // list of rects normalized 0..1
|
plateTrack?: [number, number, number, number][]; // list of rects normalized 0..1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type NPEDUser = {
|
||||||
|
username: string;
|
||||||
|
clientId: string;
|
||||||
|
password?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NPEDErrorValues = {
|
||||||
|
username?: string | undefined;
|
||||||
|
password?: string | undefined;
|
||||||
|
clientId?: string | undefined;
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ import tailwindcss from "@tailwindcss/vite";
|
|||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss()],
|
||||||
|
server: { host: true },
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user