diff --git a/vite-frontend/src/components/navbar.tsx b/vite-frontend/src/components/navbar.tsx index 78d7c7a..04a0a61 100644 --- a/vite-frontend/src/components/navbar.tsx +++ b/vite-frontend/src/components/navbar.tsx @@ -1,12 +1,12 @@ import { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; + import { Link } from "@/shadcn-bridge/heroui/link"; import { Navbar as HeroUINavbar, NavbarBrand, NavbarContent, } from "@/shadcn-bridge/heroui/navbar"; -import { useNavigate } from "react-router-dom"; - import { Logo } from "@/components/icons"; import { siteConfig, getCachedConfig } from "@/config/site"; import { useWebViewMode } from "@/hooks/useWebViewMode"; diff --git a/vite-frontend/src/components/theme-provider.tsx b/vite-frontend/src/components/theme-provider.tsx index 72c60c6..3e2f6d7 100644 --- a/vite-frontend/src/components/theme-provider.tsx +++ b/vite-frontend/src/components/theme-provider.tsx @@ -1,4 +1,5 @@ import React, { useEffect } from "react"; + import { useTheme } from "@/shadcn-bridge/heroui/use-theme"; interface ThemeProviderProps { diff --git a/vite-frontend/src/components/ui/alert.tsx b/vite-frontend/src/components/ui/alert.tsx index 96ed73d..e1d59de 100644 --- a/vite-frontend/src/components/ui/alert.tsx +++ b/vite-frontend/src/components/ui/alert.tsx @@ -9,9 +9,12 @@ const alertVariants = cva( variants: { variant: { default: "border-default-200 bg-default-50/70 text-foreground", - destructive: "border-danger-200 bg-danger-50 text-danger-700 dark:text-danger-300", - success: "border-success-200 bg-success-50 text-success-700 dark:text-success-300", - warning: "border-warning-200 bg-warning-50 text-warning-700 dark:text-warning-300", + destructive: + "border-danger-200 bg-danger-50 text-danger-700 dark:text-danger-300", + success: + "border-success-200 bg-success-50 text-success-700 dark:text-success-300", + warning: + "border-warning-200 bg-warning-50 text-warning-700 dark:text-warning-300", }, }, defaultVariants: { @@ -45,9 +48,16 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"h5">) { ); } -function AlertDescription({ className, ...props }: React.ComponentProps<"div">) { +function AlertDescription({ + className, + ...props +}: React.ComponentProps<"div">) { return ( -
+
); } diff --git a/vite-frontend/src/components/ui/button.tsx b/vite-frontend/src/components/ui/button.tsx index ba4ffb7..14fe8bb 100644 --- a/vite-frontend/src/components/ui/button.tsx +++ b/vite-frontend/src/components/ui/button.tsx @@ -11,11 +11,15 @@ const buttonVariants = cva( variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-danger text-white hover:bg-danger/90", - outline: "border border-input bg-background hover:bg-default-100 hover:text-foreground dark:hover:bg-default-200/40", - secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-default-100 hover:text-foreground dark:hover:bg-default-200/40", + outline: + "border border-input bg-background hover:bg-default-100 hover:text-foreground dark:hover:bg-default-200/40", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-default-100 hover:text-foreground dark:hover:bg-default-200/40", link: "text-primary underline-offset-4 hover:underline", - light: "bg-transparent hover:bg-default-100 dark:hover:bg-default-200/40", + light: + "bg-transparent hover:bg-default-100 dark:hover:bg-default-200/40", flat: "bg-default-100 text-foreground hover:bg-default-200 dark:bg-default-100/40", }, size: { @@ -43,9 +47,9 @@ const Button = React.forwardRef( return ( ); diff --git a/vite-frontend/src/components/ui/card.tsx b/vite-frontend/src/components/ui/card.tsx index 7d031ab..525a9b3 100644 --- a/vite-frontend/src/components/ui/card.tsx +++ b/vite-frontend/src/components/ui/card.tsx @@ -28,7 +28,10 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) { function CardTitle({ className, ...props }: React.ComponentProps<"h3">) { return (

@@ -47,7 +50,11 @@ function CardDescription({ className, ...props }: React.ComponentProps<"p">) { function CardContent({ className, ...props }: React.ComponentProps<"div">) { return ( -
+
); } @@ -61,4 +68,11 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { ); } -export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }; +export { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +}; diff --git a/vite-frontend/src/components/ui/checkbox.tsx b/vite-frontend/src/components/ui/checkbox.tsx index 7a48c1c..30748e6 100644 --- a/vite-frontend/src/components/ui/checkbox.tsx +++ b/vite-frontend/src/components/ui/checkbox.tsx @@ -4,7 +4,10 @@ import { CheckIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -function Checkbox({ className, ...props }: React.ComponentProps) { +function Checkbox({ + className, + ...props +}: React.ComponentProps) { return ( ) { +function Dialog({ + ...props +}: React.ComponentProps) { return ; } -function DialogTrigger({ ...props }: React.ComponentProps) { +function DialogTrigger({ + ...props +}: React.ComponentProps) { return ; } -function DialogPortal({ ...props }: React.ComponentProps) { +function DialogPortal({ + ...props +}: React.ComponentProps) { return ; } -function DialogClose({ ...props }: React.ComponentProps) { +function DialogClose({ + ...props +}: React.ComponentProps) { return ; } -function DialogOverlay({ className, ...props }: React.ComponentProps) { +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { return ( {children} {showCloseButton && ( - + Close @@ -69,7 +78,10 @@ function DialogContent({ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { return (
@@ -79,17 +91,26 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { return (
); } -function DialogTitle({ className, ...props }: React.ComponentProps) { +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { return ( diff --git a/vite-frontend/src/components/ui/dropdown-menu.tsx b/vite-frontend/src/components/ui/dropdown-menu.tsx index 5ac423c..24f7148 100644 --- a/vite-frontend/src/components/ui/dropdown-menu.tsx +++ b/vite-frontend/src/components/ui/dropdown-menu.tsx @@ -4,32 +4,54 @@ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -function DropdownMenu({ ...props }: React.ComponentProps) { +function DropdownMenu({ + ...props +}: React.ComponentProps) { return ; } function DropdownMenuTrigger({ ...props }: React.ComponentProps) { - return ; + return ( + + ); } -function DropdownMenuGroup({ ...props }: React.ComponentProps) { - return ; +function DropdownMenuGroup({ + ...props +}: React.ComponentProps) { + return ( + + ); } -function DropdownMenuPortal({ ...props }: React.ComponentProps) { - return ; +function DropdownMenuPortal({ + ...props +}: React.ComponentProps) { + return ( + + ); } -function DropdownMenuSub({ ...props }: React.ComponentProps) { +function DropdownMenuSub({ + ...props +}: React.ComponentProps) { return ; } function DropdownMenuRadioGroup({ ...props }: React.ComponentProps) { - return ; + return ( + + ); } function DropdownMenuSubTrigger({ @@ -171,7 +193,11 @@ function DropdownMenuLabel({ }) { return ( @@ -191,10 +217,16 @@ function DropdownMenuSeparator({ ); } -function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) { +function DropdownMenuShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { return ( diff --git a/vite-frontend/src/components/ui/label.tsx b/vite-frontend/src/components/ui/label.tsx index 9391551..c660011 100644 --- a/vite-frontend/src/components/ui/label.tsx +++ b/vite-frontend/src/components/ui/label.tsx @@ -3,7 +3,10 @@ import * as LabelPrimitive from "@radix-ui/react-label"; import { cn } from "@/lib/utils"; -function Label({ className, ...props }: React.ComponentProps) { +function Label({ + className, + ...props +}: React.ComponentProps) { return ( diff --git a/vite-frontend/src/components/ui/radio-group.tsx b/vite-frontend/src/components/ui/radio-group.tsx index 34ad09c..e0a0833 100644 --- a/vite-frontend/src/components/ui/radio-group.tsx +++ b/vite-frontend/src/components/ui/radio-group.tsx @@ -4,7 +4,10 @@ import { CircleIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -function RadioGroup({ className, ...props }: React.ComponentProps) { +function RadioGroup({ + className, + ...props +}: React.ComponentProps) { return ( - + diff --git a/vite-frontend/src/components/ui/select.tsx b/vite-frontend/src/components/ui/select.tsx index 9a28ac6..150a3cc 100644 --- a/vite-frontend/src/components/ui/select.tsx +++ b/vite-frontend/src/components/ui/select.tsx @@ -4,15 +4,21 @@ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -function Select({ ...props }: React.ComponentProps) { +function Select({ + ...props +}: React.ComponentProps) { return ; } -function SelectGroup({ ...props }: React.ComponentProps) { +function SelectGroup({ + ...props +}: React.ComponentProps) { return ; } -function SelectValue({ ...props }: React.ComponentProps) { +function SelectValue({ + ...props +}: React.ComponentProps) { return ; } @@ -44,7 +50,10 @@ function SelectScrollUpButton({ }: React.ComponentProps) { return ( @@ -59,7 +68,10 @@ function SelectScrollDownButton({ }: React.ComponentProps) { return ( @@ -103,7 +115,10 @@ function SelectContent({ ); } -function SelectLabel({ className, ...props }: React.ComponentProps) { +function SelectLabel({ + className, + ...props +}: React.ComponentProps) { return ( ) { +function Switch({ + className, + ...props +}: React.ComponentProps) { return ( ) { return (
- +
); } @@ -33,7 +37,10 @@ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { return ( tr]:last:border-b-0", className)} + className={cn( + "border-t bg-default-50/70 font-medium [&>tr]:last:border-b-0", + className, + )} data-slot="table-footer" {...props} /> @@ -43,7 +50,10 @@ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { function TableRow({ className, ...props }: React.ComponentProps<"tr">) { return ( @@ -66,16 +76,26 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) { function TableCell({ className, ...props }: React.ComponentProps<"td">) { return ( ; + return ( + + ); } export function TableCell({ className, ...props }: React.ComponentProps<"td">) { diff --git a/vite-frontend/src/shadcn-bridge/heroui/use-theme.tsx b/vite-frontend/src/shadcn-bridge/heroui/use-theme.tsx index e82f999..c1f930f 100644 --- a/vite-frontend/src/shadcn-bridge/heroui/use-theme.tsx +++ b/vite-frontend/src/shadcn-bridge/heroui/use-theme.tsx @@ -10,11 +10,14 @@ function resolveInitialTheme(): ThemeMode { } const fromStorage = window.localStorage.getItem(STORAGE_KEY); + if (fromStorage === "dark" || fromStorage === "light") { return fromStorage; } - return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; + return window.matchMedia("(prefers-color-scheme: dark)").matches + ? "dark" + : "light"; } let currentTheme: ThemeMode = resolveInitialTheme();
); } -function TableCaption({ className, ...props }: React.ComponentProps<"caption">) { +function TableCaption({ + className, + ...props +}: React.ComponentProps<"caption">) { return ( -
+ ); } diff --git a/vite-frontend/src/components/ui/tabs.tsx b/vite-frontend/src/components/ui/tabs.tsx index e57c653..cc7e6f6 100644 --- a/vite-frontend/src/components/ui/tabs.tsx +++ b/vite-frontend/src/components/ui/tabs.tsx @@ -3,13 +3,23 @@ import * as TabsPrimitive from "@radix-ui/react-tabs"; import { cn } from "@/lib/utils"; -function Tabs({ className, ...props }: React.ComponentProps) { +function Tabs({ + className, + ...props +}: React.ComponentProps) { return ( - + ); } -function TabsList({ className, ...props }: React.ComponentProps) { +function TabsList({ + className, + ...props +}: React.ComponentProps) { return ( ) { +function TabsTrigger({ + className, + ...props +}: React.ComponentProps) { return ( ) { +function TabsContent({ + className, + ...props +}: React.ComponentProps) { return ( - +

基本设置

@@ -609,7 +609,7 @@ export default function ConfigPage() { - + {CONFIG_ITEMS.map((item, index) => { // 检查配置项是否应该显示 if (!shouldShowItem(item)) { @@ -660,7 +660,7 @@ export default function ConfigPage() { )} - +

公告管理

@@ -673,7 +673,7 @@ export default function ConfigPage() { - + {announcementLoading ? (
@@ -727,7 +727,7 @@ export default function ConfigPage() { {/* 备份与恢复 */} - +

数据备份与恢复

@@ -740,7 +740,7 @@ export default function ConfigPage() { - + {/* 导出部分 */}

导出数据

diff --git a/vite-frontend/src/pages/dashboard.tsx b/vite-frontend/src/pages/dashboard.tsx index 6a1fb45..652b2f1 100644 --- a/vite-frontend/src/pages/dashboard.tsx +++ b/vite-frontend/src/pages/dashboard.tsx @@ -1,9 +1,14 @@ -import { Card, CardBody, CardHeader } from "@/shadcn-bridge/heroui/card"; -import { Button } from "@/shadcn-bridge/heroui/button"; -import { Modal, ModalContent, ModalHeader, ModalBody } from "@/shadcn-bridge/heroui/modal"; import { useState } from "react"; import toast from "react-hot-toast"; +import { Card, CardBody, CardHeader } from "@/shadcn-bridge/heroui/card"; +import { Button } from "@/shadcn-bridge/heroui/button"; +import { + Modal, + ModalContent, + ModalHeader, + ModalBody, +} from "@/shadcn-bridge/heroui/modal"; import { PageEmptyState, PageLoadingState } from "@/components/page-state"; import { AnnouncementBanner } from "@/pages/dashboard/components/announcement-banner"; import { FlowChartCard } from "@/pages/dashboard/components/flow-chart-card"; diff --git a/vite-frontend/src/pages/dashboard/components/announcement-banner.tsx b/vite-frontend/src/pages/dashboard/components/announcement-banner.tsx index fa45614..979b2fa 100644 --- a/vite-frontend/src/pages/dashboard/components/announcement-banner.tsx +++ b/vite-frontend/src/pages/dashboard/components/announcement-banner.tsx @@ -16,7 +16,7 @@ export const AnnouncementBanner = ({ return ( -
+
已选择 {selectedIds.size} 项 - - - - +
+ ); + }) + )} +
+ ); + }; + return ( ({ > {selectionMode === "multiple" ? (
- {isExpanded ? ( -
- {options.length === 0 ? ( -
- 暂无可选项 -
- ) : ( - options.map((option) => { - const optionDisabled = isDisabled || disabled.has(option.key); - - return ( -
- - updateMultipleSelection(option.key, value === true) - } - /> - -
- ); - }) - )} -
- ) : null} + {renderMultipleListbox()}
) : ( {children}
@@ -29,7 +36,11 @@ export function Table({ children, className, classNames, ...props }: TableProps) ); } -export function TableHeader({ children, className, ...props }: React.ComponentProps<"thead">) { +export function TableHeader({ + children, + className, + ...props +}: React.ComponentProps<"thead">) { const childArray = React.Children.toArray(children); const hasRow = childArray.some( (child) => React.isValidElement(child) && child.type === TableRow, @@ -42,7 +53,8 @@ export function TableHeader({ children, className, ...props }: React.ComponentPr ); } -interface TableBodyProps extends Omit, "children"> { +interface TableBodyProps + extends Omit, "children"> { children?: React.ReactNode | ((item: T) => React.ReactNode); emptyContent?: React.ReactNode; isLoading?: boolean; @@ -120,19 +132,28 @@ export function TableBody({ ); } -export function TableColumn({ className, ...props }: React.ComponentProps<"th">) { +export function TableColumn({ + className, + ...props +}: React.ComponentProps<"th">) { const { thClassName } = React.useContext(TableStyleContext); return (
); } export function TableRow({ className, ...props }: React.ComponentProps<"tr">) { - return