From 6a74db1e5c22256adff27ad2eebf713f08da3040 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 12 Mar 2026 12:29:56 +0800 Subject: [PATCH] feat(quick-2): initialize v2 project from sample_interface - Copy React app structure from sample_interface/src/ - Copy package.json, vite.config.ts, postcss.config.mjs - Copy guidelines/ design system --- v2/guidelines/Guidelines.md | 458 +++++++++++ v2/package.json | 88 +++ v2/postcss.config.mjs | 15 + v2/src/app/App.tsx | 6 + v2/src/app/components/DashboardLayout.tsx | 27 + v2/src/app/components/Header.tsx | 102 +++ v2/src/app/components/NavigationButtons.tsx | 39 + v2/src/app/components/Sidebar.tsx | 193 +++++ .../components/figma/ImageWithFallback.tsx | 27 + v2/src/app/components/ui/accordion.tsx | 66 ++ v2/src/app/components/ui/alert-dialog.tsx | 157 ++++ v2/src/app/components/ui/alert.tsx | 66 ++ v2/src/app/components/ui/aspect-ratio.tsx | 11 + v2/src/app/components/ui/avatar.tsx | 53 ++ v2/src/app/components/ui/badge.tsx | 46 ++ v2/src/app/components/ui/breadcrumb.tsx | 109 +++ v2/src/app/components/ui/button.tsx | 58 ++ v2/src/app/components/ui/calendar.tsx | 75 ++ v2/src/app/components/ui/card.tsx | 92 +++ v2/src/app/components/ui/carousel.tsx | 241 ++++++ v2/src/app/components/ui/chart.tsx | 353 +++++++++ v2/src/app/components/ui/checkbox.tsx | 32 + v2/src/app/components/ui/collapsible.tsx | 33 + v2/src/app/components/ui/command.tsx | 177 +++++ v2/src/app/components/ui/context-menu.tsx | 252 ++++++ v2/src/app/components/ui/dialog.tsx | 135 ++++ v2/src/app/components/ui/drawer.tsx | 132 ++++ v2/src/app/components/ui/dropdown-menu.tsx | 257 +++++++ v2/src/app/components/ui/form.tsx | 168 ++++ v2/src/app/components/ui/hover-card.tsx | 44 ++ v2/src/app/components/ui/input-otp.tsx | 77 ++ v2/src/app/components/ui/input.tsx | 21 + v2/src/app/components/ui/label.tsx | 24 + v2/src/app/components/ui/menubar.tsx | 276 +++++++ v2/src/app/components/ui/navigation-menu.tsx | 168 ++++ v2/src/app/components/ui/pagination.tsx | 127 +++ v2/src/app/components/ui/popover.tsx | 48 ++ v2/src/app/components/ui/progress.tsx | 31 + v2/src/app/components/ui/radio-group.tsx | 45 ++ v2/src/app/components/ui/resizable.tsx | 56 ++ v2/src/app/components/ui/scroll-area.tsx | 58 ++ v2/src/app/components/ui/select.tsx | 189 +++++ v2/src/app/components/ui/separator.tsx | 28 + v2/src/app/components/ui/sheet.tsx | 139 ++++ v2/src/app/components/ui/sidebar.tsx | 726 ++++++++++++++++++ v2/src/app/components/ui/skeleton.tsx | 13 + v2/src/app/components/ui/slider.tsx | 63 ++ v2/src/app/components/ui/sonner.tsx | 25 + v2/src/app/components/ui/switch.tsx | 31 + v2/src/app/components/ui/table.tsx | 116 +++ v2/src/app/components/ui/tabs.tsx | 66 ++ v2/src/app/components/ui/textarea.tsx | 18 + v2/src/app/components/ui/toggle-group.tsx | 73 ++ v2/src/app/components/ui/toggle.tsx | 47 ++ v2/src/app/components/ui/tooltip.tsx | 61 ++ v2/src/app/components/ui/use-mobile.ts | 21 + v2/src/app/components/ui/utils.ts | 6 + .../app/components/views/ADCSettingView.tsx | 83 ++ .../app/components/views/CalibrationView.tsx | 63 ++ .../components/views/DateTimeSettingView.tsx | 65 ++ .../app/components/views/EVAPSettingView.tsx | 54 ++ .../app/components/views/FlashMemoryView.tsx | 112 +++ .../app/components/views/GPRSSettingView.tsx | 68 ++ v2/src/app/components/views/GraphView.tsx | 51 ++ .../app/components/views/LevelSettingView.tsx | 78 ++ v2/src/app/components/views/LoginView.tsx | 61 ++ .../components/views/MobileSettingView.tsx | 70 ++ .../app/components/views/NetworkSetupView.tsx | 69 ++ .../components/views/RainfallSettingView.tsx | 69 ++ v2/src/app/components/views/RainfallView.tsx | 63 ++ v2/src/app/components/views/SettingView.tsx | 76 ++ .../app/components/views/SirenSettingView.tsx | 71 ++ .../app/components/views/StationInfoView.tsx | 40 + v2/src/app/routes.ts | 44 ++ v2/src/styles/fonts.css | 0 v2/src/styles/index.css | 3 + v2/src/styles/tailwind.css | 4 + v2/src/styles/theme.css | 191 +++++ v2/vite.config.ts | 22 + 79 files changed, 7422 insertions(+) create mode 100644 v2/guidelines/Guidelines.md create mode 100644 v2/package.json create mode 100644 v2/postcss.config.mjs create mode 100644 v2/src/app/App.tsx create mode 100644 v2/src/app/components/DashboardLayout.tsx create mode 100644 v2/src/app/components/Header.tsx create mode 100644 v2/src/app/components/NavigationButtons.tsx create mode 100644 v2/src/app/components/Sidebar.tsx create mode 100644 v2/src/app/components/figma/ImageWithFallback.tsx create mode 100644 v2/src/app/components/ui/accordion.tsx create mode 100644 v2/src/app/components/ui/alert-dialog.tsx create mode 100644 v2/src/app/components/ui/alert.tsx create mode 100644 v2/src/app/components/ui/aspect-ratio.tsx create mode 100644 v2/src/app/components/ui/avatar.tsx create mode 100644 v2/src/app/components/ui/badge.tsx create mode 100644 v2/src/app/components/ui/breadcrumb.tsx create mode 100644 v2/src/app/components/ui/button.tsx create mode 100644 v2/src/app/components/ui/calendar.tsx create mode 100644 v2/src/app/components/ui/card.tsx create mode 100644 v2/src/app/components/ui/carousel.tsx create mode 100644 v2/src/app/components/ui/chart.tsx create mode 100644 v2/src/app/components/ui/checkbox.tsx create mode 100644 v2/src/app/components/ui/collapsible.tsx create mode 100644 v2/src/app/components/ui/command.tsx create mode 100644 v2/src/app/components/ui/context-menu.tsx create mode 100644 v2/src/app/components/ui/dialog.tsx create mode 100644 v2/src/app/components/ui/drawer.tsx create mode 100644 v2/src/app/components/ui/dropdown-menu.tsx create mode 100644 v2/src/app/components/ui/form.tsx create mode 100644 v2/src/app/components/ui/hover-card.tsx create mode 100644 v2/src/app/components/ui/input-otp.tsx create mode 100644 v2/src/app/components/ui/input.tsx create mode 100644 v2/src/app/components/ui/label.tsx create mode 100644 v2/src/app/components/ui/menubar.tsx create mode 100644 v2/src/app/components/ui/navigation-menu.tsx create mode 100644 v2/src/app/components/ui/pagination.tsx create mode 100644 v2/src/app/components/ui/popover.tsx create mode 100644 v2/src/app/components/ui/progress.tsx create mode 100644 v2/src/app/components/ui/radio-group.tsx create mode 100644 v2/src/app/components/ui/resizable.tsx create mode 100644 v2/src/app/components/ui/scroll-area.tsx create mode 100644 v2/src/app/components/ui/select.tsx create mode 100644 v2/src/app/components/ui/separator.tsx create mode 100644 v2/src/app/components/ui/sheet.tsx create mode 100644 v2/src/app/components/ui/sidebar.tsx create mode 100644 v2/src/app/components/ui/skeleton.tsx create mode 100644 v2/src/app/components/ui/slider.tsx create mode 100644 v2/src/app/components/ui/sonner.tsx create mode 100644 v2/src/app/components/ui/switch.tsx create mode 100644 v2/src/app/components/ui/table.tsx create mode 100644 v2/src/app/components/ui/tabs.tsx create mode 100644 v2/src/app/components/ui/textarea.tsx create mode 100644 v2/src/app/components/ui/toggle-group.tsx create mode 100644 v2/src/app/components/ui/toggle.tsx create mode 100644 v2/src/app/components/ui/tooltip.tsx create mode 100644 v2/src/app/components/ui/use-mobile.ts create mode 100644 v2/src/app/components/ui/utils.ts create mode 100644 v2/src/app/components/views/ADCSettingView.tsx create mode 100644 v2/src/app/components/views/CalibrationView.tsx create mode 100644 v2/src/app/components/views/DateTimeSettingView.tsx create mode 100644 v2/src/app/components/views/EVAPSettingView.tsx create mode 100644 v2/src/app/components/views/FlashMemoryView.tsx create mode 100644 v2/src/app/components/views/GPRSSettingView.tsx create mode 100644 v2/src/app/components/views/GraphView.tsx create mode 100644 v2/src/app/components/views/LevelSettingView.tsx create mode 100644 v2/src/app/components/views/LoginView.tsx create mode 100644 v2/src/app/components/views/MobileSettingView.tsx create mode 100644 v2/src/app/components/views/NetworkSetupView.tsx create mode 100644 v2/src/app/components/views/RainfallSettingView.tsx create mode 100644 v2/src/app/components/views/RainfallView.tsx create mode 100644 v2/src/app/components/views/SettingView.tsx create mode 100644 v2/src/app/components/views/SirenSettingView.tsx create mode 100644 v2/src/app/components/views/StationInfoView.tsx create mode 100644 v2/src/app/routes.ts create mode 100644 v2/src/styles/fonts.css create mode 100644 v2/src/styles/index.css create mode 100644 v2/src/styles/tailwind.css create mode 100644 v2/src/styles/theme.css create mode 100644 v2/vite.config.ts diff --git a/v2/guidelines/Guidelines.md b/v2/guidelines/Guidelines.md new file mode 100644 index 000000000..e01435ab4 --- /dev/null +++ b/v2/guidelines/Guidelines.md @@ -0,0 +1,458 @@ +# Data Station Dashboard Design Guidelines + +## Overview +This dashboard is designed for 7-inch capacitive touchscreen displays used in industrial/environmental monitoring stations. The interface prioritizes touch-friendly interactions, clear information hierarchy, and robust functionality for field use. + +--- + +## Design Language + +### Color Palette + +**Background Colors:** +- Primary Background: `bg-gray-900` - Main content areas +- Secondary Background: `bg-gray-950` - Sidebar, header, elevated surfaces +- Tertiary Background: `bg-gray-800` - Cards, input fields, nested elements + +**Accent Colors:** +- Primary Action: `bg-blue-600`, `hover:bg-blue-700` - Buttons, active states +- Success/Positive: `text-green-400` - Online status, calibrated sensors, positive values +- Warning: `text-yellow-400` - Pending states, warnings +- Error/Critical: `text-red-400` - Offline status, errors, delete actions +- Info: `text-blue-400` - Icons, informational highlights +- Data Values: `text-cyan-400`, `text-purple-400` - Different data categories + +**Text Colors:** +- Primary Text: `text-white` - Headings, labels +- Secondary Text: `text-gray-300` - Body text, menu items +- Tertiary Text: `text-gray-400` - Supporting information, metadata +- Disabled Text: `text-gray-500` - Disabled states + +**Border Colors:** +- Default Borders: `border-gray-700` - Cards, inputs, dividers + +### Typography + +**Font Sizes:** +- Page Headers: `text-2xl` (h1) +- Card Titles: `text-sm` to `text-base` +- Body Text: `text-sm` +- Metadata/Labels: `text-xs` +- Tiny Text: `text-[10px]` (for dense information) +- Monospace: Use `font-mono` for time, data values, file contents + +**Font Weights:** +- Bold: `font-bold` - Page headers, important labels +- Semibold: `font-semibold` - Card titles, emphasized values +- Normal: Default weight for body text + +### Spacing + +**Component Spacing:** +- Between major sections: `space-y-4` +- Within cards: `space-y-3` or `space-y-4` +- Compact spacing: `space-y-2` +- Card padding: `p-3` or `p-4` +- Grid gaps: `gap-3` or `gap-4` + +**Touch Targets:** +- Minimum button height: `h-14` (56px) for primary touch actions +- Standard button size: `size-lg` +- Navigation buttons: `h-14 w-14` (56x56px minimum) +- List items: `p-2` to `p-3` for adequate touch area + +--- + +## Navigation + +### Sidebar Navigation + +**Structure:** +- Collapsible sidebar with icon-only mode +- Width: `w-64` (expanded), `w-16` (collapsed) +- Always visible on left side +- Dark background (`bg-gray-950`) + +**Menu Hierarchy:** +- Primary menu items: Icon + Label +- Expandable items: Show chevron indicator +- Sub-menu items: Indented with `pl-11` +- Active state: `bg-blue-600 text-white` +- Hover state: `hover:bg-gray-800 hover:text-white` + +**Menu Items:** +1. HOME - Rainfall dashboard (default view) +2. GRAPH - Data visualization +3. UTILITY - Expandable with 10 sub-items +4. CALIBRATION - Sensor calibration +5. FLASH MEMORY - File manager +6. SETTING - System settings +7. LOGIN - Authentication + +### Page Navigation + +**No Traditional Scrollbars:** +- All scrollbars are hidden for touchscreen usability +- Use permanent Up/Down buttons in top-right corner +- Buttons: 56x56px, `bg-blue-600`, positioned `fixed top-20 right-4` +- Smooth scroll behavior with 300px increments + +**Routing:** +- Use React Router for multi-page navigation +- Route structure: `/` (home), `/graph`, `/utility/[setting]`, etc. +- URL updates on navigation for state management + +--- + +## UI Elements + +### Buttons + +**Primary Button:** +- Style: `bg-blue-600 hover:bg-blue-700 text-white` +- Use for: Main actions, saving, applying settings +- Size: Default or `size-lg` for touch + +**Secondary Button (Outline):** +- Style: `variant="outline" border-gray-700 text-gray-300 hover:bg-gray-800` +- Use for: Alternative actions, cancel, secondary functions + +**Destructive Button:** +- Style: `variant="outline" border-red-700 text-red-400 hover:bg-red-950` +- Use for: Delete, reset, dangerous actions + +**Icon Buttons:** +- Size: Minimum 44x44px for touch +- Include text labels when space allows +- Use Lucide React icons consistently + +### Cards + +**Standard Card:** +```tsx + + + Title + + + {/* Content */} + + +``` + +**Data Display Card:** +- Use color-coded backgrounds for data categories +- Format: Value (large) + Unit (small) +- Example: `text-4xl font-bold text-blue-400` for values + +### Form Elements + +**Input Fields:** +- Style: `bg-gray-800 border-gray-700 text-white` +- Labels: `text-gray-300` above inputs +- Grid layout for multiple fields: `grid grid-cols-2 gap-4` + +**Switches:** +- Use for enable/disable settings +- Layout: Label on left, switch on right +- Container: `flex items-center justify-between p-3 bg-gray-800 rounded` + +**Dropdowns:** +- Style: `bg-gray-800 border border-gray-700 rounded text-white` +- Use native ` + ); +} + +export { Input }; diff --git a/v2/src/app/components/ui/label.tsx b/v2/src/app/components/ui/label.tsx new file mode 100644 index 000000000..af250e577 --- /dev/null +++ b/v2/src/app/components/ui/label.tsx @@ -0,0 +1,24 @@ +"use client"; + +import * as React from "react"; +import * as LabelPrimitive from "@radix-ui/react-label"; + +import { cn } from "./utils"; + +function Label({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { Label }; diff --git a/v2/src/app/components/ui/menubar.tsx b/v2/src/app/components/ui/menubar.tsx new file mode 100644 index 000000000..7d7ac86ff --- /dev/null +++ b/v2/src/app/components/ui/menubar.tsx @@ -0,0 +1,276 @@ +"use client"; + +import * as React from "react"; +import * as MenubarPrimitive from "@radix-ui/react-menubar"; +import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"; + +import { cn } from "./utils"; + +function Menubar({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function MenubarMenu({ + ...props +}: React.ComponentProps) { + return ; +} + +function MenubarGroup({ + ...props +}: React.ComponentProps) { + return ; +} + +function MenubarPortal({ + ...props +}: React.ComponentProps) { + return ; +} + +function MenubarRadioGroup({ + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function MenubarTrigger({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function MenubarContent({ + className, + align = "start", + alignOffset = -4, + sideOffset = 8, + ...props +}: React.ComponentProps) { + return ( + + + + ); +} + +function MenubarItem({ + className, + inset, + variant = "default", + ...props +}: React.ComponentProps & { + inset?: boolean; + variant?: "default" | "destructive"; +}) { + return ( + + ); +} + +function MenubarCheckboxItem({ + className, + children, + checked, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ); +} + +function MenubarRadioItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ); +} + +function MenubarLabel({ + className, + inset, + ...props +}: React.ComponentProps & { + inset?: boolean; +}) { + return ( + + ); +} + +function MenubarSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function MenubarShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ); +} + +function MenubarSub({ + ...props +}: React.ComponentProps) { + return ; +} + +function MenubarSubTrigger({ + className, + inset, + children, + ...props +}: React.ComponentProps & { + inset?: boolean; +}) { + return ( + + {children} + + + ); +} + +function MenubarSubContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + Menubar, + MenubarPortal, + MenubarMenu, + MenubarTrigger, + MenubarContent, + MenubarGroup, + MenubarSeparator, + MenubarLabel, + MenubarItem, + MenubarShortcut, + MenubarCheckboxItem, + MenubarRadioGroup, + MenubarRadioItem, + MenubarSub, + MenubarSubTrigger, + MenubarSubContent, +}; diff --git a/v2/src/app/components/ui/navigation-menu.tsx b/v2/src/app/components/ui/navigation-menu.tsx new file mode 100644 index 000000000..6a8d6f252 --- /dev/null +++ b/v2/src/app/components/ui/navigation-menu.tsx @@ -0,0 +1,168 @@ +import * as React from "react"; +import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"; +import { cva } from "class-variance-authority"; +import { ChevronDownIcon } from "lucide-react"; + +import { cn } from "./utils"; + +function NavigationMenu({ + className, + children, + viewport = true, + ...props +}: React.ComponentProps & { + viewport?: boolean; +}) { + return ( + + {children} + {viewport && } + + ); +} + +function NavigationMenuList({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function NavigationMenuItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +const navigationMenuTriggerStyle = cva( + "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1", +); + +function NavigationMenuTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + {children}{" "} + + ); +} + +function NavigationMenuContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function NavigationMenuViewport({ + className, + ...props +}: React.ComponentProps) { + return ( +
+ +
+ ); +} + +function NavigationMenuLink({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function NavigationMenuIndicator({ + className, + ...props +}: React.ComponentProps) { + return ( + +
+ + ); +} + +export { + NavigationMenu, + NavigationMenuList, + NavigationMenuItem, + NavigationMenuContent, + NavigationMenuTrigger, + NavigationMenuLink, + NavigationMenuIndicator, + NavigationMenuViewport, + navigationMenuTriggerStyle, +}; diff --git a/v2/src/app/components/ui/pagination.tsx b/v2/src/app/components/ui/pagination.tsx new file mode 100644 index 000000000..a23239db5 --- /dev/null +++ b/v2/src/app/components/ui/pagination.tsx @@ -0,0 +1,127 @@ +import * as React from "react"; +import { + ChevronLeftIcon, + ChevronRightIcon, + MoreHorizontalIcon, +} from "lucide-react"; + +import { cn } from "./utils"; +import { Button, buttonVariants } from "./button"; + +function Pagination({ className, ...props }: React.ComponentProps<"nav">) { + return ( +