- added session sighting component

- add new session paused state and stop adding to session when true
This commit is contained in:
2025-10-24 12:10:10 +01:00
parent b58181e551
commit c83122cd52
6 changed files with 84 additions and 56 deletions

View File

@@ -5,19 +5,26 @@ import type { ReducedSightingType } from "../../types/types";
import { toast } from "sonner";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faFloppyDisk, faPause, faPlay, faStop } from "@fortawesome/free-solid-svg-icons";
import VehicleSessionItem from "../UI/VehicleSessionItem";
const SessionCard = () => {
const { sessionStarted, setSessionStarted, sessionList } = useNPEDContext();
const { sessionStarted, setSessionStarted, sessionList, setSessionPaused, sessionPaused } = useNPEDContext();
const handleStartClick = () => {
setSessionStarted(!sessionStarted);
toast(`${sessionStarted ? "Vehicle tracking session Ended" : "Vehicle tracking session Started"}`);
setSessionPaused(false);
toast(`${sessionStarted ? "Vehicle tracking session ended" : "Vehicle tracking session started"}`);
};
const handleSaveCick = () => {
console.log("clicked");
};
const handlepauseClick = () => {
setSessionPaused(!sessionPaused);
toast(`${sessionStarted ? "Vehicle tracking session paused" : "Vehicle tracking session resumed"}`);
};
const sightings = [...new Map(sessionList.map((vehicle) => [vehicle.vrm, vehicle]))];
const dedupedSightings = sightings.map((sighting) => sighting[1]);
@@ -75,45 +82,52 @@ const SessionCard = () => {
{sessionStarted && (
<button
className={`bg-gray-300 text-gray-800 px-4 py-2 rounded transition w-full lg:w-[50%]`}
onClick={handleSaveCick}
onClick={handlepauseClick}
>
<div className="flex flex-row gap-3 items-center justify-self-center">
<FontAwesomeIcon icon={faPause} />
<p>Pause session</p>
<FontAwesomeIcon icon={sessionPaused ? faPlay : faPause} />
<p>{sessionPaused ? "Resume session" : "Pause session"}</p>
</div>
</button>
)}
</div>
<ul className="text-white space-y-2">
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
<p>Number of Vehicles sightings:</p>
<span className="font-bold text-green-600 text-xl">{dedupedSightings.length}</span>
</li>
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
<p>Vehicles without Tax:</p>
<span className="font-bold text-amber-600 text-xl">{vehicles.notTaxed.length}</span>
</li>
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
<p>Vehicles without MOT:</p>{" "}
<span className="font-bold text-red-500 text-xl">{vehicles.notMOT.length}</span>
</li>
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
<p>Vehicles on Hotlists:</p>{" "}
<span className="font-bold text-blue-500 text-xl">{vehicles.hotlistHit.length}</span>
</li>
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
<p>Vehicles with NPED Cat A:</p>
<span className="font-bold text-gray-300 text-xl">{vehicles.npedCatA.length}</span>
</li>
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
<p>Vehicles with NPED Cat B:</p>{" "}
<span className="font-bold text-gray-300 text-xl">{vehicles.npedCatB.length}</span>
</li>
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between">
Vehicles with NPED Cat C:{" "}
<span className="font-bold text-gray-300 text-xl">{vehicles.npedCatC.length}</span>
</li>
<VehicleSessionItem
sessionNumber={dedupedSightings.length}
textColour="text-green-400"
vehicleTag={"Number of Vehicles sightings:"}
/>
<VehicleSessionItem
sessionNumber={vehicles.notTaxed.length}
textColour="text-amber-400"
vehicleTag={"Vehicles without Tax:"}
/>
<VehicleSessionItem
sessionNumber={vehicles.notMOT.length}
textColour="text-red-500"
vehicleTag={"Vehicles without MOT:"}
/>
<VehicleSessionItem
sessionNumber={vehicles.hotlistHit.length}
textColour="text-blue-400"
vehicleTag={"Vehicles on Hotlists:"}
/>
<VehicleSessionItem
sessionNumber={vehicles.npedCatA.length}
textColour="text-gray-300"
vehicleTag={"Vehicles with NPED Cat A:"}
/>
<VehicleSessionItem
sessionNumber={vehicles.npedCatB.length}
textColour="text-gray-300"
vehicleTag={"Vehicles with NPED Cat B:"}
/>
<VehicleSessionItem
sessionNumber={vehicles.npedCatC.length}
textColour="text-gray-300"
vehicleTag={"Vehicles with NPED Cat C:"}
/>
</ul>
</div>
</Card>

View File

@@ -71,7 +71,7 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
} = useSightingFeedContext();
const { dispatch } = useAlertHitContext();
const { sessionStarted, setSessionList, sessionList } = useNPEDContext();
const { sessionStarted, setSessionList, sessionList, sessionPaused } = useNPEDContext();
const processedRefs = useRef<Set<number | string>>(new Set());
@@ -88,6 +88,7 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
useEffect(() => {
if (sessionStarted) {
if (!mostRecent) return;
if (sessionPaused) return;
const reducedMostRecent = reduceObject(mostRecent);
setSessionList([...sessionList, reducedMostRecent]);
}

View File

@@ -1,21 +1,14 @@
import { Link } from "react-router";
import Logo from "/MAV.svg";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faGear,
faHome,
faListCheck,
faMaximize,
faMinimize,
faRotate,
} from "@fortawesome/free-solid-svg-icons";
import { faGear, faHome, faListCheck, faMaximize, faMinimize, faRotate } from "@fortawesome/free-solid-svg-icons";
import { useState } from "react";
import SoundBtn from "./SoundBtn";
import { useNPEDContext } from "../../context/NPEDUserContext";
export default function Header() {
const [isFullscreen, setIsFullscreen] = useState(false);
const { sessionStarted } = useNPEDContext();
const { sessionStarted, sessionPaused } = useNPEDContext();
const toggleFullscreen = () => {
if (!document.fullscreenElement) {
@@ -39,9 +32,13 @@ export default function Header() {
</Link>
</div>
<div className="flex flex-col lg:flex-row items-center space-x-24 justify-items-center">
{sessionStarted && (
<div className="text-green-400 font-bold">Session Active</div>
)}
<div className="flex flex-row lg:flex-row space-x-2">
{sessionStarted && sessionPaused ? (
<p className="text-gray-400 font-bold">Session Paused</p>
) : (
sessionStarted && <p className="text-green-400 font-bold">Session Active</p>
)}
</div>
<div className="flex flex-row space-x-8">
<Link to={"/"}>
@@ -59,11 +56,7 @@ export default function Header() {
</div>
<SoundBtn />
<Link to={"/session-settings"}>
<FontAwesomeIcon
className="text-white"
icon={faListCheck}
size="2x"
/>
<FontAwesomeIcon className="text-white" icon={faListCheck} size="2x" />
</Link>
<Link to={"/system-settings"}>

View File

@@ -0,0 +1,18 @@
import clsx from "clsx";
type VehicleSessionItemProps = {
sessionNumber: number;
textColour: string;
vehicleTag: string;
};
const VehicleSessionItem = ({ sessionNumber, textColour, vehicleTag }: VehicleSessionItemProps) => {
return (
<li className="rounded-xl border border-slate-800 bg-slate-800/60 p-3 shadow-sm flex flex-row justify-between items-center">
<p>{vehicleTag}</p>
<span className={`font-bold text-xl bg-slate-700 px-2 rounded-md ${clsx(textColour)}`}>{sessionNumber}</span>
</li>
);
};
export default VehicleSessionItem;