diff --git a/web/package-lock.json b/web/package-lock.json index 27793517d..c85bb8743 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -23,6 +23,8 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@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", "apexcharts": "^3.45.1", "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": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", diff --git a/web/package.json b/web/package.json index bfc508ff7..ef6b9eb13 100644 --- a/web/package.json +++ b/web/package.json @@ -28,6 +28,8 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@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", "apexcharts": "^3.45.1", "axios": "^1.6.2", diff --git a/web/src/App.tsx b/web/src/App.tsx index 8a22b0842..0639a03a2 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -14,6 +14,7 @@ import Logs from "@/pages/Logs"; import NoMatch from "@/pages/NoMatch"; import Settings from "@/pages/Settings"; import UIPlayground from "./pages/UIPlayground"; +import Events from "./pages/Events"; function App() { const [sheetOpen, setSheetOpen] = useState(false); @@ -35,6 +36,7 @@ function App() { > } /> + } /> } /> } /> } /> diff --git a/web/src/components/ui/toggle-group.tsx b/web/src/components/ui/toggle-group.tsx new file mode 100644 index 000000000..19505f9a4 --- /dev/null +++ b/web/src/components/ui/toggle-group.tsx @@ -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 +>({ + size: "default", + variant: "default", +}) + +const ToggleGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, children, ...props }, ref) => ( + + + {children} + + +)) + +ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName + +const ToggleGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, children, variant, size, ...props }, ref) => { + const context = React.useContext(ToggleGroupContext) + + return ( + + {children} + + ) +}) + +ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName + +export { ToggleGroup, ToggleGroupItem } diff --git a/web/src/components/ui/toggle.tsx b/web/src/components/ui/toggle.tsx new file mode 100644 index 000000000..9ecac28ee --- /dev/null +++ b/web/src/components/ui/toggle.tsx @@ -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, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, ...props }, ref) => ( + +)) + +Toggle.displayName = TogglePrimitive.Root.displayName + +export { Toggle, toggleVariants } diff --git a/web/src/pages/Events.tsx b/web/src/pages/Events.tsx new file mode 100644 index 000000000..472bb2463 --- /dev/null +++ b/web/src/pages/Events.tsx @@ -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("alert"); + + return ( + <> +
+ setSeverity(value)} + > + + + Alerts + + + + Detections + + + + Motion + + +
+ + + +
+
+ + ); +} diff --git a/web/src/pages/site-navigation.ts b/web/src/pages/site-navigation.ts index ab94a9cd7..18578eb98 100644 --- a/web/src/pages/site-navigation.ts +++ b/web/src/pages/site-navigation.ts @@ -1,34 +1,41 @@ import { - LuConstruction, - LuFileUp, - LuFilm, - LuVideo, - } from "react-icons/lu"; + LuConstruction, + LuFileUp, + LuFilm, + LuFlag, + LuVideo, +} from "react-icons/lu"; export const navbarLinks = [ - { - id: 1, - icon: LuVideo, - title: "Live", - url: "/", - }, - { - id: 2, - icon: LuFilm, - title: "History", - url: "/history", - }, - { - id: 3, - icon: LuFileUp, - title: "Export", - url: "/export", - }, - { - id: 4, - icon: LuConstruction, - title: "UI Playground", - url: "/playground", - dev: true, - }, - ]; \ No newline at end of file + { + id: 1, + icon: LuVideo, + title: "Live", + url: "/", + }, + { + id: 2, + icon: LuFlag, + title: "Events", + url: "/events", + }, + { + id: 3, + icon: LuFilm, + title: "History", + url: "/history", + }, + { + id: 4, + icon: LuFileUp, + title: "Export", + url: "/export", + }, + { + id: 5, + icon: LuConstruction, + title: "UI Playground", + url: "/playground", + dev: true, + }, +];