added NPED cat sorting
This commit is contained in:
5
.env
5
.env
@@ -1,5 +1,5 @@
|
|||||||
VITE_BASEURL=http://192.168.75.11/
|
VITE_BASEURL=http://192.168.75.11/
|
||||||
VITE_CAM_BASE=http://100.72.72.70:8080
|
VITE_CAM_BASE=http://100.113.222.39
|
||||||
VITE_FOLKESTONE_BASE=http://100.116.253.81
|
VITE_FOLKESTONE_BASE=http://100.116.253.81
|
||||||
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
|
VITE_OUTSIDE_BASEURL=http://100.82.205.44/api
|
||||||
@@ -17,4 +17,5 @@ VITE_AGX_FRONT_BASE=http://100.72.72.70:8080/
|
|||||||
VITE_LOCAL=http://10.42.0.1:8080/SightingListRear/sightingSummary?mostRecentRef=
|
VITE_LOCAL=http://10.42.0.1:8080/SightingListRear/sightingSummary?mostRecentRef=
|
||||||
VITE_LOCAL_FRONT=http://10.42.0.1:8080/SightingListFront/sightingSummary?mostRecentRef=
|
VITE_LOCAL_FRONT=http://10.42.0.1:8080/SightingListFront/sightingSummary?mostRecentRef=
|
||||||
|
|
||||||
VITE_LOCAL_BASE=http://10.42.0.1:8080/
|
VITE_LOCAL_BASE=http://10.42.0.1:8080/
|
||||||
|
VITE_LOCAL_BASE_NEW=http://100.113.222.39
|
||||||
30
public/NPED_Cat_A.svg
Normal file
30
public/NPED_Cat_A.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 25 KiB |
31
public/NPED_Cat_B.svg
Normal file
31
public/NPED_Cat_B.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 25 KiB |
29
public/NPED_Cat_C.svg
Normal file
29
public/NPED_Cat_C.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 24 KiB |
@@ -1,6 +1,6 @@
|
|||||||
import Container from "./components/UI/Container";
|
import Container from "./components/UI/Container";
|
||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
import { Route, Routes } from "react-router";
|
import { Navigate, 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";
|
||||||
@@ -19,6 +19,7 @@ function App() {
|
|||||||
<Route path="rear-camera-settings" element={<RearCamera />} />
|
<Route path="rear-camera-settings" element={<RearCamera />} />
|
||||||
<Route path="system-settings" element={<SystemSettings />} />
|
<Route path="system-settings" element={<SystemSettings />} />
|
||||||
<Route path="session-settings" element={<Session />} />
|
<Route path="session-settings" element={<Session />} />
|
||||||
|
<Route path="*" element={<Navigate to="/" replace />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</AlertHitProvider>
|
</AlertHitProvider>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ const CameraSettings = ({ title, side }: { title: string; side: string }) => {
|
|||||||
updateCameraConfigError,
|
updateCameraConfigError,
|
||||||
} = useFetchCameraConfig(side);
|
} = useFetchCameraConfig(side);
|
||||||
console.log(updateCameraConfigError);
|
console.log(updateCameraConfigError);
|
||||||
console.log(isPending);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Field, useFormikContext } from "formik";
|
import { Field, useFormikContext } from "formik";
|
||||||
|
|
||||||
import FormToggle from "../components/FormToggle";
|
import FormToggle from "../components/FormToggle";
|
||||||
|
|
||||||
export const ValuesComponent = () => {
|
export const ValuesComponent = () => {
|
||||||
@@ -11,13 +10,13 @@ const BearerTypeFields = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col space-y-4">
|
<div className="flex flex-col space-y-4">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3 justify-between">
|
||||||
<label htmlFor="format">Format</label>
|
<label htmlFor="format">Format</label>
|
||||||
<Field
|
<Field
|
||||||
as="select"
|
as="select"
|
||||||
name="format"
|
name="format"
|
||||||
id="format"
|
id="format"
|
||||||
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445]"
|
className="p-2 border border-gray-400 rounded-lg text-white bg-[#253445] w-full md:w-60"
|
||||||
>
|
>
|
||||||
<option value="JSON">JSON</option>
|
<option value="JSON">JSON</option>
|
||||||
<option value="BOF2">BOF2</option>
|
<option value="BOF2">BOF2</option>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const ChannelFields = () => {
|
|||||||
type="text"
|
type="text"
|
||||||
id="backoffice"
|
id="backoffice"
|
||||||
placeholder="https://www.backoffice.com"
|
placeholder="https://www.backoffice.com"
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
className="p-1.5 border border-gray-400 rounded-lg w-full md:w-60"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
@@ -28,7 +28,7 @@ const ChannelFields = () => {
|
|||||||
type="text"
|
type="text"
|
||||||
id="username"
|
id="username"
|
||||||
placeholder="Back office username"
|
placeholder="Back office username"
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
className="p-1.5 border border-gray-400 rounded-lg w-full md:w-60"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
@@ -38,7 +38,7 @@ const ChannelFields = () => {
|
|||||||
type={showPwd ? "text" : "password"}
|
type={showPwd ? "text" : "password"}
|
||||||
id="password"
|
id="password"
|
||||||
placeholder="Back office password"
|
placeholder="Back office password"
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
className="p-1.5 border border-gray-400 rounded-lg w-full md:w-60"
|
||||||
/>
|
/>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
type="button"
|
type="button"
|
||||||
@@ -53,7 +53,7 @@ const ChannelFields = () => {
|
|||||||
name={"connectTimeoutSeconds"}
|
name={"connectTimeoutSeconds"}
|
||||||
type="number"
|
type="number"
|
||||||
id="connectTimeoutSeconds"
|
id="connectTimeoutSeconds"
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
className="p-1.5 border border-gray-400 rounded-lg w-full md:w-60"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
@@ -63,7 +63,7 @@ const ChannelFields = () => {
|
|||||||
type="number"
|
type="number"
|
||||||
id="readTimeoutSeconds"
|
id="readTimeoutSeconds"
|
||||||
placeholder="https://example.com"
|
placeholder="https://example.com"
|
||||||
className="p-1.5 border border-gray-400 rounded-lg"
|
className="p-1.5 border border-gray-400 rounded-lg w-full md:w-60"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Field } from "formik";
|
|||||||
|
|
||||||
const FormToggle = ({ name, label }: { name: string; label?: string }) => {
|
const FormToggle = ({ name, label }: { name: string; label?: string }) => {
|
||||||
return (
|
return (
|
||||||
<label className="flex items-center gap-3 cursor-pointer select-none w-50">
|
<label className="flex items-center gap-3 cursor-pointer select-none w-50 justify-between">
|
||||||
<span className="text-sm">{label}</span>
|
<span className="text-sm">{label}</span>
|
||||||
<Field id={name} type="checkbox" name={name} className="sr-only peer" />
|
<Field id={name} type="checkbox" name={name} className="sr-only peer" />
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { useAlertHitContext } from "../../context/AlertHitContext";
|
import { useAlertHitContext } from "../../context/AlertHitContext";
|
||||||
import { toast, Toaster } from "sonner";
|
import { toast, Toaster } from "sonner";
|
||||||
import HotListImg from "/Hotlist_Hit.svg";
|
import HotListImg from "/Hotlist_Hit.svg";
|
||||||
|
import NPED_CAT_A from "/NPED_Cat_A.svg";
|
||||||
|
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
||||||
|
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
||||||
|
|
||||||
type SightingModalProps = {
|
type SightingModalProps = {
|
||||||
isSightingModalOpen: boolean;
|
isSightingModalOpen: boolean;
|
||||||
@@ -33,6 +36,10 @@ const SightingModal = ({
|
|||||||
|
|
||||||
const motionAway = (sighting?.motion ?? "").toUpperCase() === "AWAY";
|
const motionAway = (sighting?.motion ?? "").toUpperCase() === "AWAY";
|
||||||
const isHotListHit = sighting?.metadata?.hotlistMatches?.Hotlist0 === true;
|
const isHotListHit = sighting?.metadata?.hotlistMatches?.Hotlist0 === true;
|
||||||
|
const isNPEDHitA = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
|
const isNPEDHitB = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
|
const isNPEDHitC = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
|
const isNPEDHitD = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "D";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -60,6 +67,34 @@ const SightingModal = ({
|
|||||||
className="h-20 object-contain rounded-md"
|
className="h-20 object-contain rounded-md"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{isNPEDHitA && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_A}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isNPEDHitB && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_B}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isNPEDHitC && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_C}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isNPEDHitD && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_A}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col md:flex-row items-center gap-3">
|
<div className="flex flex-col md:flex-row items-center gap-3">
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ type InfoBarprops = {
|
|||||||
};
|
};
|
||||||
const InfoBar = ({ obj }: InfoBarprops) => {
|
const InfoBar = ({ obj }: InfoBarprops) => {
|
||||||
// const isNPEDHit = obj?.metadata?.npedJSON?.status_code === 404;
|
// const isNPEDHit = obj?.metadata?.npedJSON?.status_code === 404;
|
||||||
|
const isNPEDHitD = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "D";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-3 text-xs bg-neutral-900 px-2 py-1 rounded justify-between">
|
<div className="flex items-center gap-3 text-xs bg-neutral-900 px-2 py-1 rounded justify-between">
|
||||||
@@ -19,11 +20,11 @@ const InfoBar = ({ obj }: InfoBarprops) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="min-w-14 opacity-80 ">
|
<div className="min-w-14 opacity-80 ">
|
||||||
{/* {isNPEDHit ? (
|
{isNPEDHitD ? (
|
||||||
<span className="text-red-500 font-semibold">NPED HIT</span>
|
<span className="text-amber-500 font-semibold">NPED HIT CAT D</span>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)} */}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,9 +7,12 @@ import CardHeader from "../UI/CardHeader";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { useSightingFeedContext } from "../../context/SightingFeedContext";
|
import { useSightingFeedContext } from "../../context/SightingFeedContext";
|
||||||
import SightingModal from "../SightingModal/SightingModal";
|
import SightingModal from "../SightingModal/SightingModal";
|
||||||
// import { useAlertHitContext } from "../../context/AlertHitContext";
|
import { useAlertHitContext } from "../../context/AlertHitContext";
|
||||||
import InfoBar from "./InfoBar";
|
import InfoBar from "./InfoBar";
|
||||||
import HotListImg from "/Hotlist_Hit.svg";
|
import HotListImg from "/Hotlist_Hit.svg";
|
||||||
|
import NPED_CAT_A from "/NPED_Cat_A.svg";
|
||||||
|
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
||||||
|
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
||||||
|
|
||||||
function useNow(tickMs = 1000) {
|
function useNow(tickMs = 1000) {
|
||||||
const [, setNow] = useState(() => Date.now());
|
const [, setNow] = useState(() => Date.now());
|
||||||
@@ -17,16 +20,16 @@ function useNow(tickMs = 1000) {
|
|||||||
const id = setInterval(() => setNow(Date.now()), tickMs);
|
const id = setInterval(() => setNow(Date.now()), tickMs);
|
||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
}, [tickMs]);
|
}, [tickMs]);
|
||||||
return undefined;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SightingHistoryProps = {
|
type SightingHistoryProps = {
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
entries?: number; // number of rows to show
|
entries?: number;
|
||||||
pollMs?: number; // poll frequency
|
pollMs?: number;
|
||||||
autoSelectLatest?: boolean;
|
autoSelectLatest?: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
className: React.HTMLAttributes<HTMLDivElement> | string;
|
className: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// /type SightingHistoryWidgetProps = React.HTMLAttributes<HTMLDivElement>;
|
// /type SightingHistoryWidgetProps = React.HTMLAttributes<HTMLDivElement>;
|
||||||
@@ -45,17 +48,17 @@ export default function SightingHistoryWidget({
|
|||||||
selectedSighting,
|
selectedSighting,
|
||||||
} = useSightingFeedContext();
|
} = useSightingFeedContext();
|
||||||
|
|
||||||
// const { dispatch } = useAlertHitContext();
|
const { dispatch } = useAlertHitContext();
|
||||||
|
|
||||||
const hasAutoOpenedRef = useRef(false);
|
const hasAutoOpenedRef = useRef(false);
|
||||||
|
|
||||||
const onRowClick = useCallback(
|
const onRowClick = useCallback(
|
||||||
(sighting: SightingType) => {
|
(sighting: SightingType) => {
|
||||||
if (!sighting) return;
|
if (!sighting) return;
|
||||||
setSightingModalOpen(!isSightingModalOpen);
|
setSightingModalOpen(true);
|
||||||
setSelectedSighting(sighting);
|
setSelectedSighting(sighting);
|
||||||
},
|
},
|
||||||
[isSightingModalOpen, setSelectedSighting, setSightingModalOpen]
|
[setSelectedSighting, setSightingModalOpen]
|
||||||
);
|
);
|
||||||
|
|
||||||
const rows = useMemo(
|
const rows = useMemo(
|
||||||
@@ -63,28 +66,34 @@ export default function SightingHistoryWidget({
|
|||||||
[sightings]
|
[sightings]
|
||||||
);
|
);
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// rows?.forEach((obj) => {
|
rows?.forEach((obj) => {
|
||||||
// const isNPEDHit = obj?.metadata?.npedJSON?.status_code === 404;
|
const isNPEDHitA = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
|
const isNPEDHitB = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
|
const isNPEDHitC = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
|
|
||||||
// if (isNPEDHit) {
|
if (isNPEDHitA || isNPEDHitB || isNPEDHitC) {
|
||||||
// dispatch({
|
dispatch({
|
||||||
// type: "ADD",
|
type: "ADD",
|
||||||
// payload: obj,
|
payload: obj,
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }, [rows, dispatch]);
|
}, [rows, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasAutoOpenedRef.current) return;
|
if (hasAutoOpenedRef.current) return;
|
||||||
const firstHot = rows?.find(
|
const firstHot = rows?.find((r) => {
|
||||||
(r) => r?.metadata?.hotlistMatches?.Hotlist0 === true
|
// const hotlistHit = r?.metadata?.hotlistMatches?.Hotlist0 === true;
|
||||||
);
|
const isNPEDHitA = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
|
const isNPEDHitB = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
|
const isNPEDHitC = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
|
return isNPEDHitA || isNPEDHitB || isNPEDHitC;
|
||||||
|
});
|
||||||
if (firstHot) {
|
if (firstHot) {
|
||||||
setSelectedSighting(firstHot);
|
setSelectedSighting(firstHot);
|
||||||
setSightingModalOpen(true);
|
setSightingModalOpen(true);
|
||||||
hasAutoOpenedRef.current = true; // prevent future auto-opens
|
hasAutoOpenedRef.current = true;
|
||||||
}
|
}
|
||||||
}, [rows, setSelectedSighting, setSightingModalOpen]);
|
}, [rows, setSelectedSighting, setSightingModalOpen]);
|
||||||
|
|
||||||
@@ -98,8 +107,15 @@ export default function SightingHistoryWidget({
|
|||||||
<div className="flex flex-col gap-3 ">
|
<div className="flex flex-col gap-3 ">
|
||||||
{/* Rows */}
|
{/* Rows */}
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{rows?.map((obj, idx) => {
|
{rows?.map((obj) => {
|
||||||
// const isNPEDHit = obj?.metadata?.npedJSON?.status_code === 404;
|
const isNPEDHitA =
|
||||||
|
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
|
const isNPEDHitB =
|
||||||
|
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
|
const isNPEDHitC =
|
||||||
|
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
|
const isNPEDHitD =
|
||||||
|
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "D";
|
||||||
const motionAway = (obj?.motion ?? "").toUpperCase() === "AWAY";
|
const motionAway = (obj?.motion ?? "").toUpperCase() === "AWAY";
|
||||||
const primaryIsColour = obj?.srcCam === 1;
|
const primaryIsColour = obj?.srcCam === 1;
|
||||||
const secondaryMissing = (obj?.vrmSecondary ?? "") === "";
|
const secondaryMissing = (obj?.vrmSecondary ?? "") === "";
|
||||||
@@ -107,14 +123,16 @@ export default function SightingHistoryWidget({
|
|||||||
obj?.metadata?.hotlistMatches?.Hotlist0 === true;
|
obj?.metadata?.hotlistMatches?.Hotlist0 === true;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={idx}
|
key={obj.ref}
|
||||||
className={`border border-neutral-700 rounded-md mb-2 p-2 cursor-pointer`}
|
className={`border border-neutral-700 rounded-md mb-2 p-2 cursor-pointer `}
|
||||||
onClick={() => onRowClick(obj)}
|
onClick={() => onRowClick(obj)}
|
||||||
>
|
>
|
||||||
<InfoBar obj={obj} />
|
<InfoBar obj={obj} />
|
||||||
{/* Patch row */}
|
{/* Patch row */}
|
||||||
<div
|
<div
|
||||||
className={`flex items-center gap-3 mt-2 justify-between`}
|
className={`flex items-center gap-3 mt-2 justify-between ${
|
||||||
|
isNPEDHitD ? "border border-amber-600" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`border p-1 ${
|
className={`border p-1 ${
|
||||||
@@ -135,6 +153,28 @@ export default function SightingHistoryWidget({
|
|||||||
className="h-20 object-contain rounded-md"
|
className="h-20 object-contain rounded-md"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{isNPEDHitA && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_A}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isNPEDHitB && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_B}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{isNPEDHitC && (
|
||||||
|
<img
|
||||||
|
src={NPED_CAT_C}
|
||||||
|
alt="hotlistHit"
|
||||||
|
className="h-20 object-contain rounded-md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<NumberPlate motion={motionAway} vrm={obj?.vrm} />
|
<NumberPlate motion={motionAway} vrm={obj?.vrm} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ const SightingWidgetDetails = ({
|
|||||||
</div>
|
</div>
|
||||||
{advancedDetailsEnabled && (
|
{advancedDetailsEnabled && (
|
||||||
<>
|
<>
|
||||||
{" "}
|
|
||||||
<div>
|
<div>
|
||||||
Country:{" "}
|
Country:{" "}
|
||||||
<span className="opacity-90">
|
<span className="opacity-90">
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default function Header() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col md:flex-row items-center space-x-24 justify-items-center">
|
<div className="flex flex-col md:flex-row items-center space-x-24 justify-items-center">
|
||||||
<div className="flex flex-col leading-tight text-white tabular-nums text-xl text-right mx-auto md:mx-10">
|
<div className="flex flex-col leading-tight text-white tabular-nums text-xl text-right mx-auto md:mx-10 space-y-1 my-2">
|
||||||
<h2>Local: {localStr}</h2>
|
<h2>Local: {localStr}</h2>
|
||||||
<h2>UTC: {utcStr}</h2>
|
<h2>UTC: {utcStr}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ export type HotlistMatches = {
|
|||||||
export type NpedJSON = {
|
export type NpedJSON = {
|
||||||
status_code: number;
|
status_code: number;
|
||||||
reason_phrase: string;
|
reason_phrase: string;
|
||||||
|
"NPED CATEGORY": "A" | "B" | "C" | "D";
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NPEDUser = {
|
export type NPEDUser = {
|
||||||
|
|||||||
Reference in New Issue
Block a user