initial commit
This commit is contained in:
22
src/components/CameraOverview/CameraOverviewHeader.tsx
Normal file
22
src/components/CameraOverview/CameraOverviewHeader.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { faCamera } from "@fortawesome/free-regular-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import clsx from "clsx";
|
||||
|
||||
type CameraOverviewHeaderProps = {
|
||||
title: string;
|
||||
};
|
||||
|
||||
const CameraOverviewHeader = ({ title }: CameraOverviewHeaderProps) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"w-full border-b border-gray-600 flex flex-row items-center space-x-2 md:mb-6"
|
||||
)}
|
||||
>
|
||||
<FontAwesomeIcon icon={faCamera} className="size-4" />
|
||||
<h2 className="text-xl">{title}</h2>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CameraOverviewHeader;
|
||||
32
src/components/CameraOverview/SnapshotContainer.tsx
Normal file
32
src/components/CameraOverview/SnapshotContainer.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { faArrowLeft, faArrowRight } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useGetOverviewSnapshot } from "../../hooks/useGetOverviewSnapshot";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
type SnapshotContainerProps = {
|
||||
side: string;
|
||||
};
|
||||
|
||||
export const SnapshotContainer = ({ side }: SnapshotContainerProps) => {
|
||||
const { canvasRef } = useGetOverviewSnapshot(side);
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="relative w-full aspect-video">
|
||||
{side === "CameraFront" || side === "Rear" ? (
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowLeft}
|
||||
className="absolute top-[50%] left-[2%] backdrop-blur-md hover:cursor-pointer"
|
||||
onClick={() => navigate("/front-camera-settings")}
|
||||
/>
|
||||
) : (
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowRight}
|
||||
className="absolute top-[50%] right-[2%] backdrop-blur-md"
|
||||
/>
|
||||
)}
|
||||
|
||||
<canvas ref={canvasRef} className="w-full h-full object-contain block" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
5
src/components/CameraSettings/CameraSettingFields.tsx
Normal file
5
src/components/CameraSettings/CameraSettingFields.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
const CameraSettingFields = () => {
|
||||
return <div>CameraSettingFields</div>;
|
||||
};
|
||||
|
||||
export default CameraSettingFields;
|
||||
14
src/components/CameraSettings/CameraSettings.tsx
Normal file
14
src/components/CameraSettings/CameraSettings.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import Card from "../UI/Card";
|
||||
import CameraOverviewHeader from "../CameraOverview/CameraOverviewHeader";
|
||||
|
||||
const CameraSettings = ({ title }: { title: string }) => {
|
||||
return (
|
||||
<Card>
|
||||
<div className="relative flex flex-col space-y-3 h-full">
|
||||
<CameraOverviewHeader title={title} />
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default CameraSettings;
|
||||
@@ -0,0 +1,27 @@
|
||||
import clsx from "clsx";
|
||||
import Card from "../UI/Card";
|
||||
import CameraOverviewHeader from "../CameraOverview/CameraOverviewHeader";
|
||||
import { SnapshotContainer } from "../CameraOverview/SnapshotContainer";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useOverviewVideo } from "../../hooks/useOverviewVideo";
|
||||
|
||||
const FrontCameraOverviewCard = () => {
|
||||
useOverviewVideo();
|
||||
const navigate = useNavigate();
|
||||
const handlers = useSwipeable({
|
||||
onSwipedRight: () => navigate("/front-camera-settings"),
|
||||
trackMouse: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<Card className={clsx("relative min-h-[40vh] md:min-h-[60vh] h-auto")}>
|
||||
<div className="flex flex-col space-y-3 h-full" {...handlers}>
|
||||
<CameraOverviewHeader title="Front Overiew" />
|
||||
<SnapshotContainer side="CameraFront" />
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default FrontCameraOverviewCard;
|
||||
@@ -0,0 +1,23 @@
|
||||
import clsx from "clsx";
|
||||
import { SnapshotContainer } from "../CameraOverview/SnapshotContainer";
|
||||
import Card from "../UI/Card";
|
||||
import CameraOverviewHeader from "../CameraOverview/CameraOverviewHeader";
|
||||
|
||||
const OverviewVideoContainer = ({
|
||||
title,
|
||||
side,
|
||||
}: {
|
||||
title: string;
|
||||
side: string;
|
||||
}) => {
|
||||
return (
|
||||
<Card className={clsx("min-h-[40vh] md:min-h-[60vh] h-auto")}>
|
||||
<div className="relative flex flex-col space-y-3 h-full">
|
||||
<CameraOverviewHeader title={title} />
|
||||
<SnapshotContainer side={side} />
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default OverviewVideoContainer;
|
||||
29
src/components/PlateStack/NumberPlate.tsx
Normal file
29
src/components/PlateStack/NumberPlate.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { GB } from "country-flag-icons/react/3x2";
|
||||
import { formatNumberPlate } from "../../utils/utils";
|
||||
import type { Sighting } from "../../types/types";
|
||||
|
||||
type NumberPlateProps = {
|
||||
sighting: Sighting;
|
||||
};
|
||||
|
||||
const NumberPlate = ({ sighting }: NumberPlateProps) => {
|
||||
return (
|
||||
<div
|
||||
className={`relative w-[8rem] border-4 border-black rounded-lg text-nowrap
|
||||
text-black px-3
|
||||
${sighting?.motion !== "towards" ? "bg-yellow-400" : "bg-white"}
|
||||
`}
|
||||
>
|
||||
<div className="">
|
||||
<div className="absolute inset-y-0 left-0 bg-blue-600 w-4 flex flex-col">
|
||||
<GB />
|
||||
</div>
|
||||
<p className=" pl-2 font-extrabold text-right">
|
||||
{formatNumberPlate(sighting?.vrm)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NumberPlate;
|
||||
20
src/components/PlateStack/Sighting.tsx
Normal file
20
src/components/PlateStack/Sighting.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import NumberPlate from "./NumberPlate";
|
||||
import SightingCanvas from "../SightingOverview/SightingCanvas";
|
||||
import type { Sighting } from "../../types/types";
|
||||
|
||||
type SightingProps = {
|
||||
sighting: Sighting;
|
||||
};
|
||||
|
||||
const Sighting = ({ sighting }: SightingProps) => {
|
||||
return (
|
||||
<div className="bg-gray-700 flex flex-col md:flex-row m-1 items-center justify-between w-full rounded-md p-4 space-y-4">
|
||||
<SightingCanvas />
|
||||
<div className="flex flex-row m-1 items-center space-x-4">
|
||||
<NumberPlate sighting={sighting} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sighting;
|
||||
17
src/components/PlateStack/SightingHeader.tsx
Normal file
17
src/components/PlateStack/SightingHeader.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { faEye } from "@fortawesome/free-regular-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
type SightingHeaderProps = {
|
||||
title: string;
|
||||
};
|
||||
|
||||
const SightingHeader = ({ title }: SightingHeaderProps) => {
|
||||
return (
|
||||
<div className="w-full border-b border-gray-600 flex flex-row items-center space-x-2 md:mb-6">
|
||||
<FontAwesomeIcon icon={faEye} className="size-4" />
|
||||
<h2 className="text-xl">{title}</h2>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SightingHeader;
|
||||
27
src/components/PlateStack/Sightings.tsx
Normal file
27
src/components/PlateStack/Sightings.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import Card from "../UI/Card";
|
||||
import SightingHeader from "./SightingHeader";
|
||||
import Sighting from "./Sighting";
|
||||
import { useLatestSighting } from "../../hooks/useLatestSighting";
|
||||
|
||||
type SightingProps = {
|
||||
title: string;
|
||||
};
|
||||
|
||||
const Sightings = ({ title }: SightingProps) => {
|
||||
const [sightings, setSightings] = useState([]);
|
||||
const { data } = useLatestSighting();
|
||||
// console.log(data);
|
||||
// useEffect(() => {
|
||||
// setSightings([...sightings, data]);
|
||||
// }, [data]);
|
||||
|
||||
return (
|
||||
<Card className="h-[10rem] md:h-[15rem] overflow-x-hidden">
|
||||
<SightingHeader title={title} />
|
||||
<Sighting sighting={data} />
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sightings;
|
||||
25
src/components/RearCameraOverview/RearCameraOverviewCard.tsx
Normal file
25
src/components/RearCameraOverview/RearCameraOverviewCard.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import clsx from "clsx";
|
||||
import Card from "../UI/Card";
|
||||
import { SnapshotContainer } from "../CameraOverview/SnapshotContainer";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import { useNavigate } from "react-router";
|
||||
import CameraOverviewHeader from "../CameraOverview/CameraOverviewHeader";
|
||||
|
||||
const RearCameraOverviewCard = () => {
|
||||
const navigate = useNavigate();
|
||||
const handlers = useSwipeable({
|
||||
onSwipedLeft: () => navigate("/rear-camera-settings"),
|
||||
trackMouse: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<Card className={clsx("min-h-[40vh] md:min-h-[60vh] h-auto")}>
|
||||
<div className="flex flex-col space-y-3 h-full" {...handlers}>
|
||||
<CameraOverviewHeader title="Rear Overiew" />
|
||||
<SnapshotContainer side="TargetDetectionRear" />
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default RearCameraOverviewCard;
|
||||
15
src/components/SightingOverview/SightingCanvas.tsx
Normal file
15
src/components/SightingOverview/SightingCanvas.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { useLatestSighting } from "../../hooks/useLatestSighting";
|
||||
|
||||
const SightingCanvas = () => {
|
||||
const { canvasRef } = useLatestSighting();
|
||||
return (
|
||||
<div className="w-70 flex flex-col">
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="items-center w-full h-10 object-contain block"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SightingCanvas;
|
||||
22
src/components/UI/Card.tsx
Normal file
22
src/components/UI/Card.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
type CardProps = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const Card = ({ children, className }: CardProps) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"bg-[#253445] rounded-lg mt-6 mx-4 px-4 py-4 shadow-2xl overflow-y-auto md:row-span-1",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Card;
|
||||
15
src/components/UI/Container.tsx
Normal file
15
src/components/UI/Container.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import Header from "./Header";
|
||||
import Footer from "./Footer";
|
||||
import { Outlet } from "react-router";
|
||||
|
||||
const Container = () => {
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<Outlet />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Container;
|
||||
14
src/components/UI/Footer.tsx
Normal file
14
src/components/UI/Footer.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import Logo from "/MAV.svg";
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer className="bg-gray-900 border-t border-gray-700 text-white py-5 text-left p-8 h-30 mt-5 flex flex-col space-y-4">
|
||||
<img src={Logo} alt="Logo" width={100} height={100} />
|
||||
<p className="text-sm">
|
||||
{new Date().getFullYear()} MAV Systems © All rights reserved.
|
||||
</p>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
16
src/components/UI/Header.tsx
Normal file
16
src/components/UI/Header.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Link } from "react-router";
|
||||
import Logo from "/MAV.svg";
|
||||
|
||||
const Header = () => {
|
||||
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="w-30">
|
||||
<Link to={"/"}>
|
||||
<img src={Logo} alt="Logo" width={100} height={100} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
Reference in New Issue
Block a user