Add ui for events

This commit is contained in:
Nicolas Mowen 2024-02-17 15:15:15 -07:00
parent be4b570346
commit 320677fe2b
7 changed files with 269 additions and 31 deletions

56
web/package-lock.json generated
View File

@ -23,6 +23,8 @@
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7", "@radix-ui/react-tooltip": "^1.0.7",
"apexcharts": "^3.45.1", "apexcharts": "^3.45.1",
"axios": "^1.6.2", "axios": "^1.6.2",
@ -1800,6 +1802,60 @@
} }
} }
}, },
"node_modules/@radix-ui/react-toggle": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz",
"integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-controllable-state": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toggle-group": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz",
"integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-direction": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-roving-focus": "1.0.4",
"@radix-ui/react-toggle": "1.0.3",
"@radix-ui/react-use-controllable-state": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-tooltip": { "node_modules/@radix-ui/react-tooltip": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz",

View File

@ -28,6 +28,8 @@
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7", "@radix-ui/react-tooltip": "^1.0.7",
"apexcharts": "^3.45.1", "apexcharts": "^3.45.1",
"axios": "^1.6.2", "axios": "^1.6.2",

View File

@ -14,6 +14,7 @@ import Logs from "@/pages/Logs";
import NoMatch from "@/pages/NoMatch"; import NoMatch from "@/pages/NoMatch";
import Settings from "@/pages/Settings"; import Settings from "@/pages/Settings";
import UIPlayground from "./pages/UIPlayground"; import UIPlayground from "./pages/UIPlayground";
import Events from "./pages/Events";
function App() { function App() {
const [sheetOpen, setSheetOpen] = useState(false); const [sheetOpen, setSheetOpen] = useState(false);
@ -35,6 +36,7 @@ function App() {
> >
<Routes> <Routes>
<Route path="/" element={<Live />} /> <Route path="/" element={<Live />} />
<Route path="/events" element={<Events />} />
<Route path="/history" element={<History />} /> <Route path="/history" element={<History />} />
<Route path="/export" element={<Export />} /> <Route path="/export" element={<Export />} />
<Route path="/storage" element={<Storage />} /> <Route path="/storage" element={<Storage />} />

View File

@ -0,0 +1,59 @@
import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
})
const ToggleGroup = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, children, ...props }, ref) => (
<ToggleGroupPrimitive.Root
ref={ref}
className={cn("flex items-center justify-center gap-1", className)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
))
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
const ToggleGroupItem = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
const context = React.useContext(ToggleGroupContext)
return (
<ToggleGroupPrimitive.Item
ref={ref}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
)
})
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
export { ToggleGroup, ToggleGroupItem }

View File

@ -0,0 +1,43 @@
import * as React from "react"
import * as TogglePrimitive from "@radix-ui/react-toggle"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const toggleVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-10 px-3",
sm: "h-9 px-2.5",
lg: "h-11 px-5",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
const Toggle = React.forwardRef<
React.ElementRef<typeof TogglePrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, ...props }, ref) => (
<TogglePrimitive.Root
ref={ref}
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
))
Toggle.displayName = TogglePrimitive.Root.displayName
export { Toggle, toggleVariants }

69
web/src/pages/Events.tsx Normal file
View File

@ -0,0 +1,69 @@
import { Button } from "@/components/ui/button";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { useState } from "react";
import { LuCalendar, LuFilter, LuVideo } from "react-icons/lu";
import { MdCircle } from "react-icons/md";
type ReviewSeverity = "alert" | "detection" | "significant_motion";
export default function Events() {
const [severity, setSeverity] = useState<ReviewSeverity>("alert");
return (
<>
<div className="w-full flex justify-between">
<ToggleGroup
type="single"
defaultValue="alert"
size="sm"
onValueChange={(value: ReviewSeverity) => setSeverity(value)}
>
<ToggleGroupItem
className={`px-3 py-4 rounded-2xl ${
severity == "alert" ? "" : "text-gray-500"
}`}
value="alert"
aria-label="Select alerts"
>
<MdCircle className="w-2 h-2 mr-[10px] text-danger" />
Alerts
</ToggleGroupItem>
<ToggleGroupItem
className={`px-3 py-4 rounded-2xl ${
severity == "detection" ? "" : "text-gray-500"
}`}
value="detection"
aria-label="Select detections"
>
<MdCircle className="w-2 h-2 mr-[10px] text-orange-400" />
Detections
</ToggleGroupItem>
<ToggleGroupItem
className={`px-3 py-4 rounded-2xl ${
severity == "significant_motion" ? "" : "text-gray-500"
}`}
value="significant_motion"
aria-label="Select motion"
>
<MdCircle className="w-2 h-2 mr-[10px] text-yellow-400" />
Motion
</ToggleGroupItem>
</ToggleGroup>
<div>
<Button className="mx-1" variant="secondary">
<LuVideo className=" mr-[10px]" />
All Cameras
</Button>
<Button className="mx-1" variant="secondary">
<LuCalendar className=" mr-[10px]" />
Fab 13
</Button>
<Button className="mx-1" variant="secondary">
<LuFilter className=" mr-[10px]" />
Filter
</Button>
</div>
</div>
</>
);
}

View File

@ -2,8 +2,9 @@ import {
LuConstruction, LuConstruction,
LuFileUp, LuFileUp,
LuFilm, LuFilm,
LuFlag,
LuVideo, LuVideo,
} from "react-icons/lu"; } from "react-icons/lu";
export const navbarLinks = [ export const navbarLinks = [
{ {
@ -14,21 +15,27 @@ export const navbarLinks = [
}, },
{ {
id: 2, id: 2,
icon: LuFlag,
title: "Events",
url: "/events",
},
{
id: 3,
icon: LuFilm, icon: LuFilm,
title: "History", title: "History",
url: "/history", url: "/history",
}, },
{ {
id: 3, id: 4,
icon: LuFileUp, icon: LuFileUp,
title: "Export", title: "Export",
url: "/export", url: "/export",
}, },
{ {
id: 4, id: 5,
icon: LuConstruction, icon: LuConstruction,
title: "UI Playground", title: "UI Playground",
url: "/playground", url: "/playground",
dev: true, dev: true,
}, },
]; ];