updated forms along with addg tabs

This commit is contained in:
2025-08-18 12:53:30 +01:00
parent d537a32e2c
commit be7f0cf1de
29 changed files with 704 additions and 120 deletions

View File

@@ -3,14 +3,18 @@ import NavigationArrow from "../UI/NavigationArrow";
type SnapshotContainerProps = {
side: string;
settingsPage?: boolean;
};
export const SnapshotContainer = ({ side }: SnapshotContainerProps) => {
export const SnapshotContainer = ({
side,
settingsPage,
}: SnapshotContainerProps) => {
const { canvasRef } = useGetOverviewSnapshot(side);
return (
<div className="relative w-full aspect-video">
<NavigationArrow side={side} />
<NavigationArrow side={side} settingsPage={settingsPage} />
<canvas ref={canvasRef} className="w-full h-full object-contain block " />
</div>
);

View File

@@ -5,21 +5,20 @@ import type {
} from "../../types/types";
const CameraSettingFields = () => {
const initialValues = {
const initialValues: CameraSettingValues = {
friendlyName: "",
cameraAddress: "",
userName: "",
password: "",
setupCamera: 1,
};
const validateValues = (values: CameraSettingValues) => {
const errors: CameraSettingErrorValues = {};
if (!values.friendlyName) errors.friendlyName = "Required";
if (!values.cameraAddress) errors.cameraAddress = "Required";
if (!values.userName) errors.userName = "Required";
if (!values.password) errors.password = "Required";
console.log(errors);
return errors;
};
@@ -35,100 +34,101 @@ const CameraSettingFields = () => {
validate={validateValues}
validateOnChange={false}
>
{({ errors }) => {
return (
<Form className="flex flex-col space-y-4 p-2">
<div className="flex flex-col space-y-2">
<label htmlFor="friendlyName" className="relative">
Friendly Name
</label>
{errors.friendlyName && (
<small className="absolute right-0 text-red-500">
{errors?.friendlyName}
</small>
)}
<Field
name={"friendlyName"}
type="text"
className="p-2 border border-gray-400 rounded-lg"
placeholder="Enter camera name"
/>
</div>
<div className="flex flex-col">
<label htmlFor="setupCamera" className="relative">
Setup Camera
</label>
{({ errors, touched, setFieldValue }) => (
<Form className="flex flex-col space-y-4 p-2">
<div className="flex flex-col space-y-2 relative">
<label htmlFor="friendlyName">Friendly Name</label>
{touched.friendlyName && errors.friendlyName && (
<small className="absolute right-0 top-0 text-red-500">
{errors.friendlyName}
</small>
)}
<Field
id="friendlyName"
name="friendlyName"
type="text"
className="p-2 border border-gray-400 rounded-lg"
placeholder="Enter camera name"
/>
</div>
<Field
as="select"
name="setupCamera"
className="p-2 border border-gray-400 rounded-lg text-white"
>
<option value={1} className="bg-[#253445]">
1
</option>
<option value={2} className="bg-[#253445]">
2
</option>
<option value={3} className="bg-[#253445]">
3
</option>
<option value={4} className="bg-[#253445]">
4
</option>
</Field>
</div>
<div className="flex flex-col">
<label htmlFor="cameraAddress">Camera Address</label>
{errors.cameraAddress && (
<small className="absolute right-0 text-red-500">
{errors?.cameraAddress}
</small>
)}
<Field
name={"cameraAddress"}
type="text"
className="p-2 border border-gray-400 rounded-lg"
placeholder="123, London Road..."
/>
</div>
<div className="flex flex-col">
<label htmlFor="userName">User Name</label>
{errors.userName && (
<small className="absolute right-0 text-red-500">
{errors?.userName}
</small>
)}
<Field
name={"userName"}
type="text"
className="p-2 border border-gray-400 rounded-lg"
placeholder="Enter user name"
/>
</div>
<div className="flex flex-col">
<label htmlFor="password">Password</label>
{errors.password && (
<small className="absolute right-0 text-red-500">
{errors?.password}
</small>
)}
<Field
name={"password"}
type="password"
className="p-2 border border-gray-400 rounded-lg"
placeholder="Enter password"
/>
</div>
<button
type="submit"
className="bg-blue-800 rounded-lg p-2 mx-auto"
<div className="flex flex-col space-y-2 relative">
<label htmlFor="setupCamera">Setup Camera</label>
<Field
as="select"
id="setupCamera"
name="setupCamera"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setFieldValue("setupCamera", parseInt(e.target.value, 10))
}
>
Save settings
</button>
</Form>
);
}}
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
</Field>
</div>
<div className="flex flex-col space-y-2 relative">
<label htmlFor="cameraAddress">Camera Address</label>
{touched.cameraAddress && errors.cameraAddress && (
<small className="absolute right-0 top-0 text-red-500">
{errors.cameraAddress}
</small>
)}
<Field
id="cameraAddress"
name="cameraAddress"
type="text"
className="p-2 border border-gray-400 rounded-lg"
placeholder="123, London Road..."
autoComplete="street-address"
/>
</div>
<div className="flex flex-col space-y-2 relative">
<label htmlFor="userName">User Name</label>
{touched.userName && errors.userName && (
<small className="absolute right-0 top-0 text-red-500">
{errors.userName}
</small>
)}
<Field
id="userName"
name="userName"
type="text"
className="p-2 border border-gray-400 rounded-lg"
placeholder="Enter user name"
autoComplete="username"
/>
</div>
<div className="flex flex-col space-y-2 relative">
<label htmlFor="password">Password</label>
{touched.password && errors.password && (
<small className="absolute right-0 top-0 text-red-500">
{errors.password}
</small>
)}
<Field
id="password"
name="password"
type="password"
className="p-2 border border-gray-400 rounded-lg"
placeholder="Enter password"
autoComplete="new-password"
/>
</div>
<button
type="submit"
className="bg-blue-800 text-white rounded-lg p-2 mx-auto"
>
Save settings
</button>
</Form>
)}
</Formik>
);
};

View File

@@ -19,7 +19,7 @@ const FrontCameraOverviewCard = () => {
<Card className={clsx("relative min-h-[40vh] md:min-h-[60vh] h-auto")}>
<div className="flex flex-col space-y-3 h-full" {...handlers}>
<CardHeader title="Front Overiew" icon={faCamera} />
<SnapshotContainer side="CameraFront" />
<SnapshotContainer side="TargetDetectionFront" />
</div>
</Card>
);

View File

@@ -7,15 +7,17 @@ import CardHeader from "../UI/CardHeader";
const OverviewVideoContainer = ({
title,
side,
settingsPage,
}: {
title: string;
side: string;
settingsPage?: boolean;
}) => {
return (
<Card className={clsx("min-h-[40vh] md:min-h-[60vh] h-auto")}>
<div className="relative flex flex-col space-y-3 h-full">
<CardHeader title={title} icon={faCamera} />
<SnapshotContainer side={side} />
<SnapshotContainer side={side} settingsPage={settingsPage} />
</div>
</Card>
);

View File

@@ -0,0 +1,13 @@
import { Formik, Form, Field } from "formik";
const OutputForm = () => {
const initialValues = {
includeVRM: false,
includeMotion: false,
includeTimestamp: false,
timeStampFormat: "utc",
};
return <div>OutputForm</div>;
};
export default OutputForm;

View File

@@ -1,9 +1,9 @@
import { GB } from "country-flag-icons/react/3x2";
import { formatNumberPlate } from "../../utils/utils";
import type { Sighting } from "../../types/types";
import type { SightingType } from "../../types/types";
type NumberPlateProps = {
sighting: Sighting;
sighting: SightingType;
};
const NumberPlate = ({ sighting }: NumberPlateProps) => {

View File

@@ -0,0 +1,14 @@
import Card from "../../UI/Card";
import CardHeader from "../../UI/CardHeader";
import BearerTypeFields from "./BearerTypeFields";
const BearerTypeCard = () => {
return (
<Card>
<CardHeader title="Bearer Type" />
<BearerTypeFields />
</Card>
);
};
export default BearerTypeCard;

View File

@@ -0,0 +1,35 @@
import { Field, useFormikContext } from "formik";
import FormToggle from "../components/FormToggle";
export const ValuesComponent = () => {
return null;
};
const BearerTypeFields = () => {
const { values } = useFormikContext();
console.log(values);
return (
<div className="flex flex-col space-y-4">
<div className="flex items-center gap-3">
<label htmlFor="format">Format</label>
<Field
as="select"
name="format"
id="format"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="JSON">JSON</option>
<option value="BOF2">BOF2</option>
</Field>
</div>
<div className="flex flex-col space-y-4">
<FormToggle name="enabled" label="Enabled" />
<FormToggle name="verbose" label="Verbose" />
</div>
</div>
);
};
export default BearerTypeFields;

View File

@@ -0,0 +1,14 @@
import Card from "../../UI/Card";
import CardHeader from "../../UI/CardHeader";
import ChannelFields from "./ChannelFields";
const ChannelCard = () => {
return (
<Card>
<CardHeader title="Channel 1 (JSON)" />
<ChannelFields />
</Card>
);
};
export default ChannelCard;

View File

@@ -0,0 +1,64 @@
import { Field, useFormikContext } from "formik";
import FormGroup from "../components/FormGroup";
const ChannelFields = () => {
useFormikContext();
return (
<div className="flex flex-col space-y-2">
<FormGroup>
<label htmlFor="backoffice" className="m-0">
Back Office URL
</label>
<Field
name={"backOfficeURL"}
type="text"
id="backoffice"
placeholder="https://www.backoffice.com"
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
<FormGroup>
<label htmlFor="username">Username</label>
<Field
name={"username"}
type="text"
id="username"
placeholder="Back office username"
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
<FormGroup>
<label htmlFor="password">Password</label>
<Field
name={"password"}
type="password"
id="password"
placeholder="Back office password"
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
<FormGroup>
<label htmlFor="connectTimeoutSeconds">Connect Timeout Seconds</label>
<Field
name={"connectTimeoutSeconds"}
type="number"
id="connectTimeoutSeconds"
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
<FormGroup>
<label htmlFor="readTimeoutSeconds">Read Timeout Seconds</label>
<Field
name={"readTimeoutSeconds"}
type="number"
id="readTimeoutSeconds"
placeholder="https://example.com"
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
</div>
);
};
export default ChannelFields;

View File

@@ -0,0 +1,12 @@
import Card from "../../UI/Card";
import CardHeader from "../../UI/CardHeader";
const NPEDCard = () => {
return (
<Card>
<CardHeader title={"NPED Config and Hotlist"} />
</Card>
);
};
export default NPEDCard;

View File

@@ -0,0 +1,14 @@
import Card from "../../UI/Card";
import CardHeader from "../../UI/CardHeader";
import OverviewTextFields from "./OverviewTextFields";
const OverviewTextCard = () => {
return (
<Card>
<CardHeader title={"Overview Text"} />
<OverviewTextFields />
</Card>
);
};
export default OverviewTextCard;

View File

@@ -0,0 +1,53 @@
import { Field, useFormikContext } from "formik";
import FormGroup from "../components/FormGroup";
import FormToggle from "../components/FormToggle";
const OverviewTextFields = () => {
useFormikContext();
return (
<div className="flex flex-col space-y-2">
<FormGroup>
<label htmlFor="overviewQuality">Include VRM</label>
<FormToggle name="includeVRM" />
</FormGroup>
<FormGroup>
<label htmlFor="includeMotion">Include Motion</label>
<FormToggle name="includeMotion" />
</FormGroup>
<FormGroup>
<label htmlFor="includeCameraName">Include Camera Name</label>
<FormToggle name="includeCameraName" />
</FormGroup>
<FormGroup>
<label htmlFor="includeTimestamp">Include Timestamp</label>
<FormToggle name="includeTimestamp" />
</FormGroup>
<FormGroup>
<label htmlFor="">Timestamp Format</label>
<Field
as="select"
name="timestampFormat"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value={"UTC"}>UTC</option>
<option value={"LOCAL"}>Local</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="overlayPosition">Overlay Position</label>
<Field
as="select"
name="overlayPosition"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value={"Top"}>Top</option>
<option value={"Bottom"}>Bottom</option>
</Field>
</FormGroup>
</div>
);
};
export default OverviewTextFields;

View File

@@ -0,0 +1,84 @@
import { Formik, Form } from "formik";
import BearerTypeCard from "../BearerType/BearerTypeCard";
import ChannelCard from "../Channel1-JSON/ChannelCard";
import type { InitialValuesForm } from "../../../types/types";
import { useState } from "react";
import AdvancedToggle from "../../UI/AdvancedToggle";
import OverviewTextCard from "../OverviewText/OverviewTextCard";
import SightingDataCard from "../SightingData/SightingDataCard";
const SettingForms = () => {
const [advancedToggle, setAdvancedToggle] = useState(false);
const initialValues = {
format: "JSON",
enabled: false,
verbose: false,
backOfficeURL: "",
username: "",
password: "",
connectTimeoutSeconds: 0,
readTimeoutSeconds: 0,
overviewQuality: "high",
overviewImageScaleFactor: "full",
overviewType: "Plate Overview",
invertMotion: false,
maxPlateValueLength: 0,
vrmToTransit: "plain VRM ASCII (default)",
staticReadAction: "Use Lane Direction",
noRegionAction: "send",
countryCodeType: "IBAN 2 Character code (default)",
filterMinConfidence: 0,
filterMaxConfidence: 100,
overviewQualityOverride: 0,
sightingDataEnabled: false,
sighthingDataVerbose: false,
includeVRM: false,
includeMotion: false,
includeTimestamp: false,
timestampFormat: "UTC",
includeCameraName: false,
customFieldA: "",
customFieldB: "",
customFieldC: "",
customFieldD: "",
overlayPosition: "Top",
};
const handleSubmit = (values: InitialValuesForm) => {
alert(JSON.stringify(values));
};
return (
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
<Form className="flex flex-col space-y-3">
<div className="mx-auto grid grid-cols-1 sm:grid-cols-1 lg:grid-cols-2 gap-2 px-2 sm:px-4 lg:px-0 w-full">
<BearerTypeCard />
<ChannelCard />
</div>
<AdvancedToggle
advancedToggle={advancedToggle}
onAdvancedChange={setAdvancedToggle}
/>
{advancedToggle && (
<>
<div className="md:col-span-2">
<SightingDataCard />
</div>
<div className="md:col-span-2">
<OverviewTextCard />
</div>
</>
)}
<button
type="submit"
className="w-1/4 text-white bg-blue-700 hover:bg-blue-800 font-small rounded-lg text-sm px-2 py-2.5"
>
Save changes
</button>
</Form>
</Formik>
);
};
export default SettingForms;

View File

@@ -0,0 +1,14 @@
import Card from "../../UI/Card";
import CardHeader from "../../UI/CardHeader";
import SightingDataFields from "./SightingDataFields";
const SightingDataCard = () => {
return (
<Card>
<CardHeader title={"Sighting Data"} />
<SightingDataFields />
</Card>
);
};
export default SightingDataCard;

View File

@@ -0,0 +1,123 @@
import { Field, useFormikContext } from "formik";
import FormGroup from "../components/FormGroup";
import FormToggle from "../components/FormToggle";
const SightingDataFields = () => {
useFormikContext();
return (
<div className="flex flex-col space-y-2">
<FormGroup>
<label htmlFor="overviewQuality">Overview Quality</label>
<Field
name="overviewQuality"
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="HIGH">High</option>
<option value="MEDIUM">Medium</option>
<option value="LOW">Low</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="overviewImageScaleFactor">
Overview Image Scale Factor
</label>
<Field
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="HIGH">Full</option>
<option value="MEDIUM">3/4</option>
<option value="LOW">2/4</option>
<option value="LOW">1/4</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="overviewType">Overview Type</label>
<Field
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="PlainOverview">Plain Overview</option>
<option value="IncludePlatePatches">Include Plate Patches</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="invertMotion">Invert Motion</label>
<FormToggle name="invertMotion" />
</FormGroup>
<FormGroup>
<label htmlFor="maxPlateValueLength">Max Plate Value Length</label>
<Field
name="maxPlateValueLength"
type={"number"}
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
<FormGroup>
<label htmlFor="vrmToTransit">VRM To Transit</label>
<Field
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="PlainOverview">plain VRM ASCII (default)</option>
<option value="IncludePlatePatches">plain VRM ASCII (default)</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="staticReadAction">Static Read Action</label>
<Field
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="UseLaneDirection">Use Lane Direction</option>
<option value="IncludePlatePatches">plain VRM ASCII (default)</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="noRegionAction">No Region Action</label>
<Field
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="UseLaneDirection">Send</option>
<option value="IncludePlatePatches">plain VRM ASCII (default)</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="countryCodeType">Country Code Type</label>
<Field
as="select"
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
>
<option value="IBAN 2 Character code (default)">
IBAN 2 Character code (default)
</option>
<option value="IncludePlatePatches">plain VRM ASCII (default)</option>
</Field>
</FormGroup>
<FormGroup>
<label htmlFor="overviewQualityOverride">
Overview Quality Override
</label>
<Field
name="maxPlateValueLength"
type={"number"}
className="p-1.5 border border-gray-400 rounded-lg"
/>
</FormGroup>
<FormGroup>
<label htmlFor="sightingDataEnabled">Sighting Data Enabled</label>
<FormToggle name="sightingDataEnabled" />
</FormGroup>
<FormGroup>
<label htmlFor="sighthingDataVerbose">Sighting Data Verbose</label>
<FormToggle name="sighthingDataVerbose" />
</FormGroup>
</div>
);
};
export default SightingDataFields;

View File

@@ -0,0 +1,15 @@
import React from "react";
type FormGroupProps = {
children: React.ReactNode;
};
const FormGroup = ({ children }: FormGroupProps) => {
return (
<div className="flex flex-col md:flex-row items-center justify-between">
{children}
</div>
);
};
export default FormGroup;

View File

@@ -0,0 +1,17 @@
import { Field } from "formik";
const FormToggle = ({ name, label }: { name: string; label?: string }) => {
return (
<label className="flex items-center gap-3 cursor-pointer select-none w-50">
<span className="text-sm">{label}</span>
<Field id={name} type="checkbox" name={name} className="sr-only peer" />
<div
className="relative w-10 h-5 rounded-full bg-gray-300 transition peer-checked:bg-blue-500 after:content-['']
after:absolute after:top-0.5 after:left-0.5 after:w-4 after:h-4 after:rounded-full after:bg-white after:shadow after:transition
after:duration-300 peer-checked:after:translate-x-5"
/>
</label>
);
};
export default FormToggle;

View File

@@ -0,0 +1,32 @@
type AdvancedToggleProps = {
advancedToggle: boolean;
onAdvancedChange: (advancedToggle: boolean) => void;
};
const AdvancedToggle = ({
advancedToggle,
onAdvancedChange,
}: AdvancedToggleProps) => {
return (
<div className="mx-auto">
<label className="flex flex-row space-x-2">
<span>Advanced Settings</span>
<input
name="advancedSettings"
type="checkbox"
id="advancedSettings"
className="sr-only peer"
value=""
/>
<div
className="relative w-10 h-5 rounded-full bg-gray-300 transition peer-checked:bg-blue-500 after:content-['']
after:absolute after:top-0.5 after:left-0.5 after:w-4 after:h-4 after:rounded-full after:bg-white after:shadow after:transition
after:duration-300 peer-checked:after:translate-x-5"
onClick={() => onAdvancedChange(!advancedToggle)}
></div>
</label>
</div>
);
};
export default AdvancedToggle;

View File

@@ -5,7 +5,7 @@ import clsx from "clsx";
type CameraOverviewHeaderProps = {
title: string;
icon: IconProp;
icon?: IconProp;
};
const CardHeader = ({ title, icon }: CameraOverviewHeaderProps) => {
@@ -15,7 +15,7 @@ const CardHeader = ({ title, icon }: CameraOverviewHeaderProps) => {
"w-full border-b border-gray-600 flex flex-row items-center space-x-2 md:mb-6"
)}
>
<FontAwesomeIcon icon={icon} className="size-4" />
{icon && <FontAwesomeIcon icon={icon} className="size-4" />}
<h2 className="text-xl">{title}</h2>
</div>
);

View File

@@ -4,25 +4,48 @@ import { useNavigate } from "react-router";
type NavigationArrowProps = {
side: string;
settingsPage?: boolean;
};
const NavigationArrow = ({ side }: NavigationArrowProps) => {
const NavigationArrow = ({ side, settingsPage }: NavigationArrowProps) => {
const navigate = useNavigate();
const navigationDest = (side: string) => {
if (side === "CameraFront") {
navigate("/front-camera-settings");
} else if (side === "Rear") {
if (settingsPage) {
navigate("/");
return;
}
if (side === "TargetDetectionFront") {
navigate("/front-camera-settings");
} else if (side === "TargetDetectionRear") {
navigate("/Rear-Camera-settings");
} else {
navigate("/");
}
};
if (settingsPage) {
return (
<>
{side === "TargetDetectionFront" ? (
<FontAwesomeIcon
icon={faArrowRight}
className="absolute top-[50%] right-[2%] backdrop-blur-md hover:cursor-pointer animate-bounce"
onClick={() => navigationDest(side)}
/>
) : (
<FontAwesomeIcon
icon={faArrowLeft}
className="absolute top-[50%] left-[2%] backdrop-blur-md hover:cursor-pointer animate-bounce"
onClick={() => navigationDest(side)}
/>
)}
</>
);
}
return (
<>
{side === "CameraFront" || side === "Rear" ? (
{side === "TargetDetectionFront" ? (
<FontAwesomeIcon
icon={faArrowLeft}
className="absolute top-[50%] left-[2%] backdrop-blur-md hover:cursor-pointer animate-bounce"

View File

@@ -5,8 +5,8 @@ const apiUrl = import.meta.env.VITE_BASEURL;
async function fetchSnapshot(cameraSide: string) {
const response = await fetch(
`http://100.116.253.81/Colour-preview`
//`${apiUrl}/${cameraSide}-preview`
// `http://100.116.253.81/Colour-preview`
`${apiUrl}/${cameraSide}-preview`
);
if (!response.ok) {
throw new Error("Cannot reach endpoint");

View File

@@ -15,7 +15,11 @@ const FrontCamera = () => {
className="mx-auto grid grid-cols-1 sm:grid-cols-1 lg:grid-cols-2 gap-4 px-2 sm:px-4 lg:px-0 w-full"
{...handlers}
>
<OverviewVideoContainer title={"Front Camera"} side="Front" />
<OverviewVideoContainer
title={"Front Camera"}
side="TargetDetectionFront"
settingsPage={true}
/>
<CameraSettings title="Front Camera Settings" />
</div>
);

View File

@@ -16,7 +16,11 @@ const RearCamera = () => {
{...handlers}
>
<CameraSettings title="Rear Camera Settings" />
<OverviewVideoContainer title={"Rear Camera"} side={"Rear"} />
<OverviewVideoContainer
title={"Rear Camera"}
side={"TargetDetectionRear"}
settingsPage={true}
/>
</div>
);
};

View File

@@ -1,10 +1,27 @@
import Output from "../components/Output/Output";
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import "react-tabs/style/react-tabs.css";
import NPEDCard from "../components/SettingForms/NPED/NPEDCard";
import SettingForms from "../components/SettingForms/SettingForms/SettingForms";
const SystemSettings = () => {
return (
<div className="mx-auto grid grid-cols-1 sm:grid-cols-1 lg:grid-cols-2 gap-2 px-2 sm:px-4 lg:px-0 w-full">
<Output />
<Output />
<div className="m-4">
<Tabs selectedTabClassName="bg-gray-300 text-gray-900 font-semibold border-none">
<TabList>
<Tab>Output</Tab>
<Tab>Integrations</Tab>
</TabList>
<TabPanel>
<div className="flex flex-col space-y-3">
<SettingForms />
</div>
</TabPanel>
<TabPanel>
<div className="mx-auto grid grid-cols-1 sm:grid-cols-1 lg:grid-cols-2 gap-2 px-2 sm:px-4 lg:px-0 w-full">
<NPEDCard />
</div>
</TabPanel>
</Tabs>
</div>
);
};

View File

@@ -40,3 +40,20 @@ export type CameraSettingValues = {
export type CameraSettingErrorValues = Partial<
Record<keyof CameraSettingValues, string>
>;
export type BearerTypeFieldType = {
format: string;
enabled: boolean;
verbose: boolean;
};
export type InitialValuesForm = {
format: string;
enabled: boolean;
verbose: boolean;
backOfficeURL: string;
username: string;
password: string;
connectTimeoutSeconds: number;
readTimeoutSeconds: number;
};