From 4fd23576d8c54e4cf8487dcbffa569e03f0a3b19 Mon Sep 17 00:00:00 2001 From: Maxim <74974283+maximka76667@users.noreply.github.com> Date: Sat, 6 Dec 2025 22:32:03 +0100 Subject: [PATCH 001/279] feat: add shadcn components and basic layout --- frontend/frontend-kit/ui/components.json | 6 +- frontend/frontend-kit/ui/package.json | 16 +- .../ui/src/components/shadcn/button.tsx | 20 +- .../ui/src/components/shadcn/collapsible.tsx | 33 + .../src/components/shadcn/dropdown-menu.tsx | 257 +++++ .../ui/src/components/shadcn/field.tsx | 248 +++++ .../ui/src/components/shadcn/index.ts | 17 +- .../ui/src/components/shadcn/input.tsx | 21 + .../ui/src/components/shadcn/label.tsx | 24 + .../ui/src/components/shadcn/popover.tsx | 48 + .../ui/src/components/shadcn/separator.tsx | 28 + .../ui/src/components/shadcn/sheet.tsx | 139 +++ .../ui/src/components/shadcn/sidebar.tsx | 726 ++++++++++++++ .../ui/src/components/shadcn/skeleton.tsx | 13 + .../ui/src/components/shadcn/tooltip.tsx | 61 ++ .../ui/src/hooks/darkMode/index.ts | 1 + .../ui/src/hooks/darkMode/use-dark-mode.ts | 3 + frontend/frontend-kit/ui/src/hooks/index.ts | 3 +- .../frontend-kit/ui/src/hooks/shadcn/index.ts | 1 + .../ui/src/hooks/shadcn/use-mobile.ts | 19 + .../frontend-kit/ui/src/hooks/useDarkMode.ts | 11 - frontend/frontend-kit/ui/src/icons/index.ts | 22 + frontend/frontend-kit/ui/src/store/index.ts | 2 + .../ui/src/store/useDarkModeStore.ts | 15 + .../frontend-kit/ui/src/store/useTabStore.ts | 30 + .../frontend-kit/ui/src/styles/globals.css | 48 +- frontend/pnpm-lock.yaml | 939 +++++++++++++++++- frontend/testing-view/package.json | 4 +- frontend/testing-view/src/App.tsx | 46 +- .../src/components/AddTabPopover.tsx | 165 +++ .../src/components/NavConnections.tsx | 46 + .../src/components/NavDarkModeToggle.tsx | 19 + .../testing-view/src/components/NavMain.tsx | 43 + .../src/components/NavSettings.tsx | 14 + .../src/components/TabSwitcher.tsx | 85 ++ .../testing-view/src/layout/AppLayout.tsx | 61 ++ .../testing-view/src/layout/AppSidebar.tsx | 48 + frontend/testing-view/src/layout/Footer.tsx | 17 + frontend/testing-view/src/main.tsx | 5 +- .../testing-view/src/pages/CameraView.tsx | 10 + frontend/testing-view/src/pages/Logs.tsx | 10 + frontend/testing-view/src/pages/Testing.tsx | 33 + 42 files changed, 3294 insertions(+), 63 deletions(-) create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/collapsible.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/field.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/input.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/label.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/popover.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/separator.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/sheet.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/sidebar.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/skeleton.tsx create mode 100644 frontend/frontend-kit/ui/src/components/shadcn/tooltip.tsx create mode 100644 frontend/frontend-kit/ui/src/hooks/darkMode/index.ts create mode 100644 frontend/frontend-kit/ui/src/hooks/darkMode/use-dark-mode.ts create mode 100644 frontend/frontend-kit/ui/src/hooks/shadcn/index.ts create mode 100644 frontend/frontend-kit/ui/src/hooks/shadcn/use-mobile.ts delete mode 100644 frontend/frontend-kit/ui/src/hooks/useDarkMode.ts create mode 100644 frontend/frontend-kit/ui/src/icons/index.ts create mode 100644 frontend/frontend-kit/ui/src/store/index.ts create mode 100644 frontend/frontend-kit/ui/src/store/useDarkModeStore.ts create mode 100644 frontend/frontend-kit/ui/src/store/useTabStore.ts create mode 100644 frontend/testing-view/src/components/AddTabPopover.tsx create mode 100644 frontend/testing-view/src/components/NavConnections.tsx create mode 100644 frontend/testing-view/src/components/NavDarkModeToggle.tsx create mode 100644 frontend/testing-view/src/components/NavMain.tsx create mode 100644 frontend/testing-view/src/components/NavSettings.tsx create mode 100644 frontend/testing-view/src/components/TabSwitcher.tsx create mode 100644 frontend/testing-view/src/layout/AppLayout.tsx create mode 100644 frontend/testing-view/src/layout/AppSidebar.tsx create mode 100644 frontend/testing-view/src/layout/Footer.tsx create mode 100644 frontend/testing-view/src/pages/CameraView.tsx create mode 100644 frontend/testing-view/src/pages/Logs.tsx create mode 100644 frontend/testing-view/src/pages/Testing.tsx diff --git a/frontend/frontend-kit/ui/components.json b/frontend/frontend-kit/ui/components.json index 814866f9..29e8e6d9 100644 --- a/frontend/frontend-kit/ui/components.json +++ b/frontend/frontend-kit/ui/components.json @@ -11,9 +11,9 @@ }, "iconLibrary": "lucide", "aliases": { - "components": "@/components", - "hooks": "@/hooks", - "lib": "@/lib", + "components": "@workspace/ui/components", + "hooks": "@workspace/ui/hooks/shadcn", + "lib": "@workspace/ui/lib", "utils": "@workspace/ui/lib/utils", "ui": "@workspace/ui/components/shadcn" } diff --git a/frontend/frontend-kit/ui/package.json b/frontend/frontend-kit/ui/package.json index 08c9a6a5..26783479 100644 --- a/frontend/frontend-kit/ui/package.json +++ b/frontend/frontend-kit/ui/package.json @@ -8,7 +8,14 @@ "lint": "eslint ." }, "dependencies": { - "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-collapsible": "^1.1.12", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.8", + "@radix-ui/react-popover": "^1.1.15", + "@radix-ui/react-separator": "^1.1.8", + "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-tooltip": "^1.2.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.475.0", @@ -17,7 +24,8 @@ "react-dom": "^19.0.0", "tailwind-merge": "^3.0.1", "tw-animate-css": "^1.2.4", - "zod": "^3.24.2" + "zod": "^3.24.2", + "zustand": "^5.0.9" }, "devDependencies": { "@tailwindcss/postcss": "^4.0.8", @@ -40,6 +48,8 @@ "./hooks": "./src/hooks/index.ts", "./lib/*": "./src/lib/*.ts", "./components/*": "./src/components/*.tsx", - "./hooks/*": "./src/hooks/*.ts" + "./hooks/*": "./src/hooks/*.ts", + "./store": "./src/store/index.ts", + "./icons": "./src/icons/index.ts" } } diff --git a/frontend/frontend-kit/ui/src/components/shadcn/button.tsx b/frontend/frontend-kit/ui/src/components/shadcn/button.tsx index 35c86efd..5879d2a5 100644 --- a/frontend/frontend-kit/ui/src/components/shadcn/button.tsx +++ b/frontend/frontend-kit/ui/src/components/shadcn/button.tsx @@ -1,8 +1,8 @@ -import * as React from "react"; -import { Slot } from "@radix-ui/react-slot"; -import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@workspace/ui/lib/utils"; +import { cn } from "@workspace/ui/lib/utils" const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", @@ -33,8 +33,8 @@ const buttonVariants = cva( variant: "default", size: "default", }, - }, -); + } +) function Button({ className, @@ -44,9 +44,9 @@ function Button({ ...props }: React.ComponentProps<"button"> & VariantProps & { - asChild?: boolean; + asChild?: boolean }) { - const Comp = asChild ? Slot : "button"; + const Comp = asChild ? Slot : "button" return ( - ); + ) } -export { Button, buttonVariants }; +export { Button, buttonVariants } diff --git a/frontend/frontend-kit/ui/src/components/shadcn/collapsible.tsx b/frontend/frontend-kit/ui/src/components/shadcn/collapsible.tsx new file mode 100644 index 00000000..ae9fad04 --- /dev/null +++ b/frontend/frontend-kit/ui/src/components/shadcn/collapsible.tsx @@ -0,0 +1,33 @@ +"use client" + +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" + +function Collapsible({ + ...props +}: React.ComponentProps) { + return +} + +function CollapsibleTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CollapsibleContent({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Collapsible, CollapsibleTrigger, CollapsibleContent } diff --git a/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx b/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx new file mode 100644 index 00000000..6c011e18 --- /dev/null +++ b/frontend/frontend-kit/ui/src/components/shadcn/dropdown-menu.tsx @@ -0,0 +1,257 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" + +import { cn } from "@workspace/ui/lib/utils" + +function DropdownMenu({ + ...props +}: React.ComponentProps) { + return +} + +function DropdownMenuPortal({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuContent({ + className, + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function DropdownMenuGroup({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuItem({ + className, + inset, + variant = "default", + ...props +}: React.ComponentProps & { + inset?: boolean + variant?: "default" | "destructive" +}) { + return ( + + ) +} + +function DropdownMenuCheckboxItem({ + className, + children, + checked, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuRadioGroup({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuRadioItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuLabel({ + className, + inset, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + ) +} + +function DropdownMenuSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +function DropdownMenuSub({ + ...props +}: React.ComponentProps) { + return +} + +function DropdownMenuSubTrigger({ + className, + inset, + children, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + {children} + + + ) +} + +function DropdownMenuSubContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + DropdownMenu, + DropdownMenuPortal, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuLabel, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, +} diff --git a/frontend/frontend-kit/ui/src/components/shadcn/field.tsx b/frontend/frontend-kit/ui/src/components/shadcn/field.tsx new file mode 100644 index 00000000..7d7b8745 --- /dev/null +++ b/frontend/frontend-kit/ui/src/components/shadcn/field.tsx @@ -0,0 +1,248 @@ +"use client" + +import { useMemo } from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@workspace/ui/lib/utils" +import { Label } from "@workspace/ui/components/shadcn/label" +import { Separator } from "@workspace/ui/components/shadcn/separator" + +function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { + return ( +
[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3", + className + )} + {...props} + /> + ) +} + +function FieldLegend({ + className, + variant = "legend", + ...props +}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) { + return ( + + ) +} + +function FieldGroup({ className, ...props }: React.ComponentProps<"div">) { + return ( +
[data-slot=field-group]]:gap-4", + className + )} + {...props} + /> + ) +} + +const fieldVariants = cva( + "group/field flex w-full gap-3 data-[invalid=true]:text-destructive", + { + variants: { + orientation: { + vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"], + horizontal: [ + "flex-row items-center", + "[&>[data-slot=field-label]]:flex-auto", + "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", + ], + responsive: [ + "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto", + "@md/field-group:[&>[data-slot=field-label]]:flex-auto", + "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", + ], + }, + }, + defaultVariants: { + orientation: "vertical", + }, + } +) + +function Field({ + className, + orientation = "vertical", + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ) +} + +function FieldContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function FieldLabel({ + className, + ...props +}: React.ComponentProps) { + return ( +