- updated state for tracking sessions
- removed un used state in sighting feed - added groupings depending on sightings
This commit is contained in:
@@ -19,6 +19,8 @@ const AlertItem = ({ item }: AlertItemProps) => {
|
|||||||
|
|
||||||
// const {d} = useCameraBlackboard();
|
// const {d} = useCameraBlackboard();
|
||||||
const motionAway = (item?.motion ?? "").toUpperCase() === "AWAY";
|
const motionAway = (item?.motion ?? "").toUpperCase() === "AWAY";
|
||||||
|
// [34].metadata.hotlistMatches["MAV_Hotlist.csv"]
|
||||||
|
//check if true is in any hotlist property
|
||||||
const isHotListHit = item?.metadata?.hotlistMatches?.Hotlist0 === true;
|
const isHotListHit = item?.metadata?.hotlistMatches?.Hotlist0 === true;
|
||||||
const isNPEDHitA = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
const isNPEDHitA = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
const isNPEDHitB = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
const isNPEDHitB = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
|
|||||||
@@ -1,32 +1,80 @@
|
|||||||
import Card from "../UI/Card";
|
import Card from "../UI/Card";
|
||||||
import CardHeader from "../UI/CardHeader";
|
import CardHeader from "../UI/CardHeader";
|
||||||
import { useNPEDContext } from "../../context/NPEDUserContext";
|
import { useNPEDContext } from "../../context/NPEDUserContext";
|
||||||
|
import type { ReducedSightingType } from "../../types/types";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
const SessionCard = () => {
|
const SessionCard = () => {
|
||||||
const { sessionStarted, setSessionStarted, sessionList } = useNPEDContext();
|
const { sessionStarted, setSessionStarted, sessionList } = useNPEDContext();
|
||||||
|
|
||||||
const handleStartClick = () => {
|
const handleStartClick = () => {
|
||||||
setSessionStarted(!sessionStarted);
|
setSessionStarted(!sessionStarted);
|
||||||
|
toast(
|
||||||
|
`${
|
||||||
|
sessionStarted
|
||||||
|
? "Vehicle tracking session Ended"
|
||||||
|
: "Vehicle tracking session Started"
|
||||||
|
}`
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sightings = [
|
||||||
|
...new Map(sessionList.map((vehicle) => [vehicle.vrm, vehicle])),
|
||||||
|
];
|
||||||
|
|
||||||
|
const dedupedSightings = sightings.map((sighting) => sighting[1]);
|
||||||
|
|
||||||
|
const vehicles = dedupedSightings.reduce<
|
||||||
|
Record<string, ReducedSightingType[]>
|
||||||
|
>(
|
||||||
|
(acc, item) => {
|
||||||
|
if (item.metadata?.npedJSON["NPED CATEGORY"] === "A")
|
||||||
|
acc.npedCatA.push(item);
|
||||||
|
if (item.metadata?.npedJSON["NPED CATEGORY"] === "B")
|
||||||
|
acc.npedCatB.push(item);
|
||||||
|
if (item.metadata?.npedJSON["NPED CATEGORY"] === "C")
|
||||||
|
acc.npedCatC.push(item);
|
||||||
|
if (item.metadata?.npedJSON["NPED CATEGORY"] === "D")
|
||||||
|
acc.npedCatD.push(item);
|
||||||
|
if (item.metadata?.npedJSON["TAX STATUS"] === false)
|
||||||
|
acc.notTaxed.push(item);
|
||||||
|
if (item.metadata?.npedJSON["MOT STATUS"] === false)
|
||||||
|
acc.notMOT.push(item);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
npedCatA: [],
|
||||||
|
npedCatB: [],
|
||||||
|
npedCatC: [],
|
||||||
|
npedCatD: [],
|
||||||
|
notTaxed: [],
|
||||||
|
notMOT: [],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="p-4">
|
<Card className="p-4">
|
||||||
<CardHeader title="Session" />
|
<CardHeader title="Session" />
|
||||||
<div className="flex flex-col gap-4 px-2">
|
<div className="flex flex-col gap-4 px-2">
|
||||||
<button
|
<button
|
||||||
className="bg-[#26B170] text-white px-4 py-2 rounded hover:bg-green-700 transition w-full"
|
className={`${
|
||||||
|
sessionStarted ? "bg-red-600" : "bg-[#26B170]"
|
||||||
|
} text-white px-4 py-2 rounded ${
|
||||||
|
sessionStarted ? "hover:bg-red-700" : "hover:bg-green-700"
|
||||||
|
} transition w-full`}
|
||||||
onClick={handleStartClick}
|
onClick={handleStartClick}
|
||||||
>
|
>
|
||||||
Start Session
|
{sessionStarted ? "End Session" : "Start Session"}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul className="text-white space-y-2">
|
<ul className="text-white space-y-2">
|
||||||
<li>Number of Vehicles: {sessionList.length} </li>
|
<li>Number of Vehicles: {dedupedSightings.length} </li>
|
||||||
<li>Vehicles without Tax: </li>
|
<li>Vehicles without Tax: {vehicles.notTaxed.length}</li>
|
||||||
<li>Vehicles without MOT: </li>
|
<li>Vehicles without MOT: {vehicles.notMOT.length}</li>
|
||||||
<li>Vehicles with NPED Cat A: </li>
|
<li>Vehicles with NPED Cat A: {vehicles.npedCatA.length}</li>
|
||||||
<li>Vehicles with NPED Cat B: </li>
|
<li>Vehicles with NPED Cat B: {vehicles.npedCatB.length}</li>
|
||||||
<li>Vehicles with NPED Cat C: </li>
|
<li>Vehicles with NPED Cat C: {vehicles.npedCatC.length}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import type { SightingType } from "../../types/types";
|
import type { ReducedSightingType, SightingType } from "../../types/types";
|
||||||
import { BLANK_IMG, getSoundFileURL } from "../../utils/utils";
|
import { BLANK_IMG, getSoundFileURL } from "../../utils/utils";
|
||||||
import NumberPlate from "../PlateStack/NumberPlate";
|
import NumberPlate from "../PlateStack/NumberPlate";
|
||||||
import Card from "../UI/Card";
|
import Card from "../UI/Card";
|
||||||
@@ -61,10 +61,18 @@ export default function SightingHistoryWidget({
|
|||||||
const { dispatch } = useAlertHitContext();
|
const { dispatch } = useAlertHitContext();
|
||||||
const { sessionStarted, setSessionList, sessionList } = useNPEDContext();
|
const { sessionStarted, setSessionList, sessionList } = useNPEDContext();
|
||||||
|
|
||||||
|
const reduceObject = (obj: SightingType): ReducedSightingType => {
|
||||||
|
return {
|
||||||
|
vrm: obj.vrm,
|
||||||
|
metadata: obj?.metadata,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (sessionStarted) {
|
if (sessionStarted) {
|
||||||
if (!mostRecent) return;
|
if (!mostRecent) return;
|
||||||
setSessionList([...sessionList, mostRecent]);
|
const reducedMostRecent = reduceObject(mostRecent);
|
||||||
|
setSessionList([...sessionList, reducedMostRecent]);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [mostRecent, sessionStarted, setSessionList]);
|
}, [mostRecent, sessionStarted, setSessionList]);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { createContext, useContext, type SetStateAction } from "react";
|
import { createContext, useContext, type SetStateAction } from "react";
|
||||||
import type { NPEDUser, SightingType } from "../types/types";
|
import type { NPEDUser, ReducedSightingType } from "../types/types";
|
||||||
|
|
||||||
type UserContextValue = {
|
type UserContextValue = {
|
||||||
user: NPEDUser | null;
|
user: NPEDUser | null;
|
||||||
setUser: React.Dispatch<SetStateAction<NPEDUser | null>>;
|
setUser: React.Dispatch<SetStateAction<NPEDUser | null>>;
|
||||||
sessionStarted: boolean;
|
sessionStarted: boolean;
|
||||||
setSessionStarted: React.Dispatch<SetStateAction<boolean>>;
|
setSessionStarted: React.Dispatch<SetStateAction<boolean>>;
|
||||||
sessionList: SightingType[];
|
sessionList: ReducedSightingType[];
|
||||||
setSessionList: React.Dispatch<SetStateAction<SightingType[]>>;
|
setSessionList: React.Dispatch<SetStateAction<ReducedSightingType[]>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NPEDUserContext = createContext<UserContextValue | undefined>(
|
export const NPEDUserContext = createContext<UserContextValue | undefined>(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, type ReactNode } from "react";
|
import { useState, type ReactNode } from "react";
|
||||||
import type { NPEDUser, SightingType } from "../../types/types";
|
import type { NPEDUser, ReducedSightingType } from "../../types/types";
|
||||||
import { NPEDUserContext } from "../NPEDUserContext";
|
import { NPEDUserContext } from "../NPEDUserContext";
|
||||||
|
|
||||||
type NPEDUserProviderType = {
|
type NPEDUserProviderType = {
|
||||||
@@ -9,7 +9,7 @@ type NPEDUserProviderType = {
|
|||||||
export const NPEDUserProvider = ({ children }: NPEDUserProviderType) => {
|
export const NPEDUserProvider = ({ children }: NPEDUserProviderType) => {
|
||||||
const [user, setUser] = useState<NPEDUser | null>(null);
|
const [user, setUser] = useState<NPEDUser | null>(null);
|
||||||
const [sessionStarted, setSessionStarted] = useState(false);
|
const [sessionStarted, setSessionStarted] = useState(false);
|
||||||
const [sessionList, setSessionList] = useState<SightingType[]>([]);
|
const [sessionList, setSessionList] = useState<ReducedSightingType[]>([]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NPEDUserContext.Provider
|
<NPEDUserContext.Provider
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ export function useSightingFeed(url: string | undefined) {
|
|||||||
const [sightings, setSightings] = useState<SightingType[]>([]);
|
const [sightings, setSightings] = useState<SightingType[]>([]);
|
||||||
const [selectedRef, setSelectedRef] = useState<number | null>(null);
|
const [selectedRef, setSelectedRef] = useState<number | null>(null);
|
||||||
const [sessionStarted, setSessionStarted] = useState(false);
|
const [sessionStarted, setSessionStarted] = useState(false);
|
||||||
const [sessionList, setSessionList] = useState<SightingType[]>([]);
|
|
||||||
const mostRecent = sightings[0] ?? null;
|
const mostRecent = sightings[0] ?? null;
|
||||||
const latestRef = mostRecent?.ref ?? null;
|
const latestRef = mostRecent?.ref ?? null;
|
||||||
const [selectedSighting, setSelectedSighting] = useState<SightingType | null>(
|
const [selectedSighting, setSelectedSighting] = useState<SightingType | null>(
|
||||||
@@ -76,13 +75,6 @@ export function useSightingFeed(url: string | undefined) {
|
|||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (sessionStarted) {
|
|
||||||
if (!mostRecent) return;
|
|
||||||
setSessionList([...sessionList, mostRecent]);
|
|
||||||
}
|
|
||||||
}, [mostRecent, sessionList, sessionStarted]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const data = query.data;
|
const data = query.data;
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
@@ -129,7 +121,6 @@ export function useSightingFeed(url: string | undefined) {
|
|||||||
setSelectedRef,
|
setSelectedRef,
|
||||||
mostRecent,
|
mostRecent,
|
||||||
selectedSighting,
|
selectedSighting,
|
||||||
sessionList,
|
|
||||||
sessionStarted,
|
sessionStarted,
|
||||||
setSessionStarted,
|
setSessionStarted,
|
||||||
setSelectedSighting,
|
setSelectedSighting,
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ export type SightingType = {
|
|||||||
metadata?: Metadata;
|
metadata?: Metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ReducedSightingType = {
|
||||||
|
vrm: string;
|
||||||
|
metadata?: Metadata;
|
||||||
|
};
|
||||||
|
|
||||||
export type CameraSettingValues = {
|
export type CameraSettingValues = {
|
||||||
friendlyName: string;
|
friendlyName: string;
|
||||||
cameraAddress: string;
|
cameraAddress: string;
|
||||||
@@ -103,6 +108,10 @@ export type NpedJSON = {
|
|||||||
status_code: number;
|
status_code: number;
|
||||||
reason_phrase: string;
|
reason_phrase: string;
|
||||||
"NPED CATEGORY": "A" | "B" | "C" | "D";
|
"NPED CATEGORY": "A" | "B" | "C" | "D";
|
||||||
|
"MOT STATUS": boolean;
|
||||||
|
"TAX STATUS": boolean;
|
||||||
|
vrm: string;
|
||||||
|
"INSURANCE STATUS": string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NPEDUser = {
|
export type NPEDUser = {
|
||||||
|
|||||||
Reference in New Issue
Block a user