From 6df1f643760245da17bdb86009d7135d67937b4b Mon Sep 17 00:00:00 2001
From: liguang <1590686939@qq.com>
Date: Tue, 17 Jun 2025 13:44:42 +0800
Subject: [PATCH] =?UTF-8?q?refactor(layout):=20=E9=87=8D=E6=9E=84=E4=BE=A7?=
=?UTF-8?q?=E8=BE=B9=E6=A0=8F=E5=92=8C=E7=94=A8=E6=88=B7=E5=AF=BC=E8=88=AA?=
=?UTF-8?q?=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 更新了 AppSidebar、NavMain 和 NavUser 组件的结构和样式
- 添加了新的导航项和图标
- 调整了用户信息的展示方式
- 优化了侧边栏的布局和样式
---
bun.lock | 20 +-
package.json | 8 +-
src/app/dashboard/data.json | 122 +++++
src/app/dashboard/page.tsx | 17 +
src/app/globals.css | 41 +-
src/components/app-sidebar.tsx | 212 +++++----
src/components/chart-area-interactive.tsx | 292 ++++++++++++
src/components/data-table.tsx | 548 ++++++++++++++++++++++
src/components/nav-documents.tsx | 85 ++++
src/components/nav-main.tsx | 111 ++---
src/components/nav-secondary.tsx | 42 ++
src/components/nav-user.tsx | 85 ++--
src/components/section-cards.tsx | 101 ++++
src/components/site-header.tsx | 11 +
tailwind.config.ts | 164 +++----
15 files changed, 1567 insertions(+), 292 deletions(-)
create mode 100644 src/app/dashboard/data.json
create mode 100644 src/app/dashboard/page.tsx
create mode 100644 src/components/chart-area-interactive.tsx
create mode 100644 src/components/data-table.tsx
create mode 100644 src/components/nav-documents.tsx
create mode 100644 src/components/nav-secondary.tsx
create mode 100644 src/components/section-cards.tsx
create mode 100644 src/components/site-header.tsx
diff --git a/bun.lock b/bun.lock
index 8f61547..2a048e0 100644
--- a/bun.lock
+++ b/bun.lock
@@ -8,6 +8,10 @@
"@ai-sdk/openai": "^1.3.0",
"@ai-sdk/react": "^1.2.0",
"@auth/prisma-adapter": "^2.8.0",
+ "@dnd-kit/core": "^6.3.1",
+ "@dnd-kit/modifiers": "^9.0.0",
+ "@dnd-kit/sortable": "^10.0.0",
+ "@dnd-kit/utilities": "^3.2.2",
"@fontsource/fira-code": "^5.1.1",
"@hookform/resolvers": "^5.1.1",
"@monaco-editor/react": "^4.7.0",
@@ -38,7 +42,7 @@
"@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.7",
- "@tanstack/react-table": "^8.21.2",
+ "@tanstack/react-table": "^8.21.3",
"@types/vscode": "^1.97.0",
"ai": "^4.2.0",
"bcryptjs": "^3.0.2",
@@ -83,7 +87,7 @@
"vaul": "^1.1.2",
"vscode-languageclient": "^9.0.1",
"vscode-ws-jsonrpc": "^3.4.0",
- "zod": "^3.25.64",
+ "zod": "^3.25.67",
"zustand": "^5.0.3",
},
"devDependencies": {
@@ -141,6 +145,16 @@
"@date-fns/tz": ["@date-fns/tz@1.2.0", "https://registry.npmmirror.com/@date-fns/tz/-/tz-1.2.0.tgz", {}, "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg=="],
+ "@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "https://registry.npmmirror.com/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="],
+
+ "@dnd-kit/core": ["@dnd-kit/core@6.3.1", "https://registry.npmmirror.com/@dnd-kit/core/-/core-6.3.1.tgz", { "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ=="],
+
+ "@dnd-kit/modifiers": ["@dnd-kit/modifiers@9.0.0", "https://registry.npmmirror.com/@dnd-kit/modifiers/-/modifiers-9.0.0.tgz", { "dependencies": { "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw=="],
+
+ "@dnd-kit/sortable": ["@dnd-kit/sortable@10.0.0", "https://registry.npmmirror.com/@dnd-kit/sortable/-/sortable-10.0.0.tgz", { "dependencies": { "@dnd-kit/utilities": "^3.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg=="],
+
+ "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "https://registry.npmmirror.com/@dnd-kit/utilities/-/utilities-3.2.2.tgz", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="],
+
"@emnapi/core": ["@emnapi/core@1.4.3", "https://registry.npmmirror.com/@emnapi/core/-/core-1.4.3.tgz", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" } }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="],
"@emnapi/runtime": ["@emnapi/runtime@1.4.3", "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.4.3.tgz", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
@@ -1943,7 +1957,7 @@
"yocto-queue": ["yocto-queue@0.1.0", "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
- "zod": ["zod@3.25.64", "https://registry.npmmirror.com/zod/-/zod-3.25.64.tgz", {}, "sha512-hbP9FpSZf7pkS7hRVUrOjhwKJNyampPgtXKc3AN6DsWtoHsg2Sb4SQaS4Tcay380zSwd2VPo9G9180emBACp5g=="],
+ "zod": ["zod@3.25.67", "https://registry.npmmirror.com/zod/-/zod-3.25.67.tgz", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="],
"zod-to-json-schema": ["zod-to-json-schema@3.24.5", "https://registry.npmmirror.com/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="],
diff --git a/package.json b/package.json
index b417046..99cec9b 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,10 @@
"@ai-sdk/openai": "^1.3.0",
"@ai-sdk/react": "^1.2.0",
"@auth/prisma-adapter": "^2.8.0",
+ "@dnd-kit/core": "^6.3.1",
+ "@dnd-kit/modifiers": "^9.0.0",
+ "@dnd-kit/sortable": "^10.0.0",
+ "@dnd-kit/utilities": "^3.2.2",
"@fontsource/fira-code": "^5.1.1",
"@hookform/resolvers": "^5.1.1",
"@monaco-editor/react": "^4.7.0",
@@ -47,7 +51,7 @@
"@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.7",
- "@tanstack/react-table": "^8.21.2",
+ "@tanstack/react-table": "^8.21.3",
"@types/vscode": "^1.97.0",
"ai": "^4.2.0",
"bcryptjs": "^3.0.2",
@@ -92,7 +96,7 @@
"vaul": "^1.1.2",
"vscode-languageclient": "^9.0.1",
"vscode-ws-jsonrpc": "^3.4.0",
- "zod": "^3.25.64",
+ "zod": "^3.25.67",
"zustand": "^5.0.3"
},
"devDependencies": {
diff --git a/src/app/dashboard/data.json b/src/app/dashboard/data.json
new file mode 100644
index 0000000..b62bde6
--- /dev/null
+++ b/src/app/dashboard/data.json
@@ -0,0 +1,122 @@
+[
+ {
+ "id": "1",
+ "name": "张三",
+ "email": "zhangsan@example.com",
+ "createdAt": "2023-10-01T08:00:00Z"
+ },
+ {
+ "id": "2",
+ "name": "李四",
+ "email": "lisi@example.com",
+ "createdAt": "2023-10-02T09:30:00Z"
+ },
+ {
+ "id": "3",
+ "name": "王五",
+ "email": "wangwu@example.com",
+ "createdAt": "2023-10-03T11:45:00Z"
+ },
+ {
+ "id": "4",
+ "name": "赵六",
+ "email": "zhaoliu@example.org",
+ "createdAt": "2023-10-04T14:00:00Z"
+ },
+ {
+ "id": "5",
+ "name": "孙七",
+ "email": "sunqi@example.net",
+ "createdAt": "2023-10-05T16:15:00Z"
+ },
+ {
+ "id": "6",
+ "name": "周八",
+ "email": "zhouba@example.org",
+ "createdAt": "2023-10-06T18:30:00Z"
+ },
+ {
+ "id": "7",
+ "name": "吴九",
+ "email": "wujiu@example.net",
+ "createdAt": "2023-10-07T20:45:00Z"
+ },
+ {
+ "id": "8",
+ "name": "郑十",
+ "email": "zhengshi@example.org",
+ "createdAt": "2023-10-08T23:00:00Z"
+ },
+ {
+ "id": "9",
+ "name": "钱十一",
+ "email": "qian11@example.net",
+ "createdAt": "2023-10-09T01:15:00Z"
+ },
+ {
+ "id": "10",
+ "name": "孙十二",
+ "email": "sun12@example.org",
+ "createdAt": "2023-10-10T03:30:00Z"
+ },
+ {
+ "id": "11",
+ "name": "周十三",
+ "email": "zhou13@example.net",
+ "createdAt": "2023-10-11T05:45:00Z"
+ },
+ {
+ "id": "12",
+ "name": "吴十四",
+ "email": "wushi14@example.org",
+ "createdAt": "2023-10-12T08:00:00Z"
+ },
+ {
+ "id": "13",
+ "name": "郑十五",
+ "email": "zheng15@example.net",
+ "createdAt": "2023-10-13T10:15:00Z"
+ },
+ {
+ "id": "14",
+ "name": "钱十六",
+ "email": "qian16@example.org",
+ "createdAt": "2023-10-14T12:30:00Z"
+ },
+ {
+ "id": "15",
+ "name": "孙十七",
+ "email": "sun17@example.net",
+ "createdAt": "2023-10-15T14:45:00Z"
+ },
+ {
+ "id": "16",
+ "name": "周十八",
+ "email": "zhou18@example.org",
+ "createdAt": "2023-10-16T17:00:00Z"
+ },
+ {
+ "id": "17",
+ "name": "吴十九",
+ "email": "wujiu19@example.net",
+ "createdAt": "2023-10-17T19:15:00Z"
+ },
+ {
+ "id": "18",
+ "name": "郑二十",
+ "email": "zheng20@example.org",
+ "createdAt": "2023-10-18T21:30:00Z"
+ },
+ {
+ "id": "19",
+ "name": "周十九",
+ "email": "zhou19@example.org",
+ "createdAt": "2023-10-19T15:30:00Z"
+ },
+ {
+ "id": "20",
+ "name": "郑二十",
+ "email": "zheng20@example.net",
+ "createdAt": "2023-10-20T17:45:00Z"
+ }
+]
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
new file mode 100644
index 0000000..6128e58
--- /dev/null
+++ b/src/app/dashboard/page.tsx
@@ -0,0 +1,17 @@
+import { DataTable } from "@/components/data-table"
+import { SiteHeader } from "@/components/site-header"
+
+import data from "./data.json"
+
+export default function Page() {
+ return (
+
+ )
+}
diff --git a/src/app/globals.css b/src/app/globals.css
index 26923bb..a257927 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -33,13 +33,13 @@
--chart-5: 213 16% 16%;
--radius: 0.5rem;
--sidebar-background: 0 0% 98%;
- --sidebar-foreground: 213 13% 6%;
- --sidebar-primary: 213 13% 16%;
- --sidebar-primary-foreground: 213 13% 76%;
- --sidebar-accent: 0 0% 85%;
- --sidebar-accent-foreground: 0 0% 25%;
- --sidebar-border: 0 0% 95%;
- --sidebar-ring: 213 13% 16%;
+ --sidebar-foreground: 240 5.3% 26.1%;
+ --sidebar-primary: 240 5.9% 10%;
+ --sidebar-primary-foreground: 0 0% 98%;
+ --sidebar-accent: 240 4.8% 95.9%;
+ --sidebar-accent-foreground: 240 5.9% 10%;
+ --sidebar-border: 220 13% 91%;
+ --sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
@@ -67,14 +67,14 @@
--chart-3: 216 28% 22%;
--chart-4: 210 7% 28%;
--chart-5: 210 20% 82%;
- --sidebar-background: 216 28% 5%;
- --sidebar-foreground: 210 17% 92%;
- --sidebar-primary: 210 17% 82%;
- --sidebar-primary-foreground: 210 17% 22%;
- --sidebar-accent: 216 28% 22%;
- --sidebar-accent-foreground: 216 28% 82%;
- --sidebar-border: 216 18% 12%;
- --sidebar-ring: 210 17% 82%;
+ --sidebar-background: 240 5.9% 10%;
+ --sidebar-foreground: 240 4.8% 95.9%;
+ --sidebar-primary: 224.3 76.3% 48%;
+ --sidebar-primary-foreground: 0 0% 100%;
+ --sidebar-accent: 240 3.7% 15.9%;
+ --sidebar-accent-foreground: 240 4.8% 95.9%;
+ --sidebar-border: 240 3.7% 15.9%;
+ --sidebar-ring: 217.2 91.2% 59.8%;
}
}
@@ -119,3 +119,14 @@ code[data-theme*=" "] span {
color: var(--shiki-dark);
background-color: var(--shiki-dark-bg);
}
+
+
+
+@layer base {
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/src/components/app-sidebar.tsx b/src/components/app-sidebar.tsx
index 526e620..7aa16dc 100644
--- a/src/components/app-sidebar.tsx
+++ b/src/components/app-sidebar.tsx
@@ -1,129 +1,181 @@
-"use client";
+"use client"
+import * as React from "react"
import {
- AudioWaveform,
- Bot,
- Command,
- Frame,
- GalleryVerticalEnd,
- Map,
- PieChart,
- Settings2,
- SquareTerminal,
-} from "lucide-react";
-import * as React from "react";
+ ArrowUpCircleIcon,
+ BarChartIcon,
+ CameraIcon,
+ ClipboardListIcon,
+ DatabaseIcon,
+ FileCodeIcon,
+ FileIcon,
+ FileTextIcon,
+ FolderIcon,
+ HelpCircleIcon,
+ LayoutDashboardIcon,
+ ListIcon,
+ SearchIcon,
+ SettingsIcon,
+ UsersIcon,
+} from "lucide-react"
+
+import { NavDocuments } from "@/components/nav-documents"
+import { NavMain } from "@/components/nav-main"
+import { NavSecondary } from "@/components/nav-secondary"
+import { NavUser } from "@/components/nav-user"
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
- SidebarRail,
-} from "@/components/ui/sidebar";
-import { NavMain } from "@/components/nav-main";
-import { NavProjects } from "@/components/nav-projects";
-import { TeamSwitcher } from "@/components/team-switcher";
-import { NavUser, type NavUserProps } from "@/components/nav-user";
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+} from "@/components/ui/sidebar"
const data = {
- teams: [
- {
- name: "Acme Inc",
- logo: GalleryVerticalEnd,
- plan: "Enterprise",
- },
- {
- name: "Acme Corp.",
- logo: AudioWaveform,
- plan: "Startup",
- },
- {
- name: "Evil Corp.",
- logo: Command,
- plan: "Free",
- },
- ],
+ user: {
+ name: "shadcn",
+ email: "m@example.com",
+ avatar: "/avatars/shadcn.jpg",
+ },
navMain: [
{
- title: "Problemset",
- url: "/dashboard/problemset",
- icon: SquareTerminal,
- isActive: true,
+ title: "Dashboard",
+ url: "#",
+ icon: LayoutDashboardIcon,
},
{
- title: "Models",
+ title: "Lifecycle",
+ url: "#",
+ icon: ListIcon,
+ },
+ {
+ title: "Analytics",
+ url: "#",
+ icon: BarChartIcon,
+ },
+ {
+ title: "Projects",
+ url: "#",
+ icon: FolderIcon,
+ },
+ {
+ title: "Team",
+ url: "#",
+ icon: UsersIcon,
+ },
+ ],
+ navClouds: [
+ {
+ title: "Capture",
+ icon: CameraIcon,
+ isActive: true,
url: "#",
- icon: Bot,
items: [
{
- title: "Genesis",
+ title: "Active Proposals",
url: "#",
},
{
- title: "Explorer",
- url: "#",
- },
- {
- title: "Quantum",
+ title: "Archived",
url: "#",
},
],
},
+ {
+ title: "Proposal",
+ icon: FileTextIcon,
+ url: "#",
+ items: [
+ {
+ title: "Active Proposals",
+ url: "#",
+ },
+ {
+ title: "Archived",
+ url: "#",
+ },
+ ],
+ },
+ {
+ title: "Prompts",
+ icon: FileCodeIcon,
+ url: "#",
+ items: [
+ {
+ title: "Active Proposals",
+ url: "#",
+ },
+ {
+ title: "Archived",
+ url: "#",
+ },
+ ],
+ },
+ ],
+ navSecondary: [
{
title: "Settings",
- url: "/dashboard/settings",
- icon: Settings2,
- items: [
- {
- title: "General",
- url: "/general",
- },
- {
- title: "Language Server",
- url: "/language-server",
- },
- ],
+ url: "#",
+ icon: SettingsIcon,
+ },
+ {
+ title: "Get Help",
+ url: "#",
+ icon: HelpCircleIcon,
+ },
+ {
+ title: "Search",
+ url: "#",
+ icon: SearchIcon,
},
],
- projects: [
+ documents: [
{
- name: "Design Engineering",
+ name: "Data Library",
url: "#",
- icon: Frame,
+ icon: DatabaseIcon,
},
{
- name: "Sales & Marketing",
+ name: "Reports",
url: "#",
- icon: PieChart,
+ icon: ClipboardListIcon,
},
{
- name: "Travel",
+ name: "Word Assistant",
url: "#",
- icon: Map,
+ icon: FileIcon,
},
],
-};
-
-interface AppSidebarProps extends React.ComponentProps {
- user: NavUserProps["user"];
}
-export function AppSidebar({
- user,
- ...props
-}: AppSidebarProps) {
+export function AppSidebar({ ...props }: React.ComponentProps) {
return (
-
+
-
+
+
+
+
+
+ Acme Inc.
+
+
+
+
-
+
+
-
+
-
- );
+ )
}
diff --git a/src/components/chart-area-interactive.tsx b/src/components/chart-area-interactive.tsx
new file mode 100644
index 0000000..294c421
--- /dev/null
+++ b/src/components/chart-area-interactive.tsx
@@ -0,0 +1,292 @@
+"use client"
+
+import * as React from "react"
+import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
+
+import { useIsMobile } from "@/hooks/use-mobile"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card"
+import {
+ ChartConfig,
+ ChartContainer,
+ ChartTooltip,
+ ChartTooltipContent,
+} from "@/components/ui/chart"
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select"
+import {
+ ToggleGroup,
+ ToggleGroupItem,
+} from "@/components/ui/toggle-group"
+const chartData = [
+ { date: "2024-04-01", desktop: 222, mobile: 150 },
+ { date: "2024-04-02", desktop: 97, mobile: 180 },
+ { date: "2024-04-03", desktop: 167, mobile: 120 },
+ { date: "2024-04-04", desktop: 242, mobile: 260 },
+ { date: "2024-04-05", desktop: 373, mobile: 290 },
+ { date: "2024-04-06", desktop: 301, mobile: 340 },
+ { date: "2024-04-07", desktop: 245, mobile: 180 },
+ { date: "2024-04-08", desktop: 409, mobile: 320 },
+ { date: "2024-04-09", desktop: 59, mobile: 110 },
+ { date: "2024-04-10", desktop: 261, mobile: 190 },
+ { date: "2024-04-11", desktop: 327, mobile: 350 },
+ { date: "2024-04-12", desktop: 292, mobile: 210 },
+ { date: "2024-04-13", desktop: 342, mobile: 380 },
+ { date: "2024-04-14", desktop: 137, mobile: 220 },
+ { date: "2024-04-15", desktop: 120, mobile: 170 },
+ { date: "2024-04-16", desktop: 138, mobile: 190 },
+ { date: "2024-04-17", desktop: 446, mobile: 360 },
+ { date: "2024-04-18", desktop: 364, mobile: 410 },
+ { date: "2024-04-19", desktop: 243, mobile: 180 },
+ { date: "2024-04-20", desktop: 89, mobile: 150 },
+ { date: "2024-04-21", desktop: 137, mobile: 200 },
+ { date: "2024-04-22", desktop: 224, mobile: 170 },
+ { date: "2024-04-23", desktop: 138, mobile: 230 },
+ { date: "2024-04-24", desktop: 387, mobile: 290 },
+ { date: "2024-04-25", desktop: 215, mobile: 250 },
+ { date: "2024-04-26", desktop: 75, mobile: 130 },
+ { date: "2024-04-27", desktop: 383, mobile: 420 },
+ { date: "2024-04-28", desktop: 122, mobile: 180 },
+ { date: "2024-04-29", desktop: 315, mobile: 240 },
+ { date: "2024-04-30", desktop: 454, mobile: 380 },
+ { date: "2024-05-01", desktop: 165, mobile: 220 },
+ { date: "2024-05-02", desktop: 293, mobile: 310 },
+ { date: "2024-05-03", desktop: 247, mobile: 190 },
+ { date: "2024-05-04", desktop: 385, mobile: 420 },
+ { date: "2024-05-05", desktop: 481, mobile: 390 },
+ { date: "2024-05-06", desktop: 498, mobile: 520 },
+ { date: "2024-05-07", desktop: 388, mobile: 300 },
+ { date: "2024-05-08", desktop: 149, mobile: 210 },
+ { date: "2024-05-09", desktop: 227, mobile: 180 },
+ { date: "2024-05-10", desktop: 293, mobile: 330 },
+ { date: "2024-05-11", desktop: 335, mobile: 270 },
+ { date: "2024-05-12", desktop: 197, mobile: 240 },
+ { date: "2024-05-13", desktop: 197, mobile: 160 },
+ { date: "2024-05-14", desktop: 448, mobile: 490 },
+ { date: "2024-05-15", desktop: 473, mobile: 380 },
+ { date: "2024-05-16", desktop: 338, mobile: 400 },
+ { date: "2024-05-17", desktop: 499, mobile: 420 },
+ { date: "2024-05-18", desktop: 315, mobile: 350 },
+ { date: "2024-05-19", desktop: 235, mobile: 180 },
+ { date: "2024-05-20", desktop: 177, mobile: 230 },
+ { date: "2024-05-21", desktop: 82, mobile: 140 },
+ { date: "2024-05-22", desktop: 81, mobile: 120 },
+ { date: "2024-05-23", desktop: 252, mobile: 290 },
+ { date: "2024-05-24", desktop: 294, mobile: 220 },
+ { date: "2024-05-25", desktop: 201, mobile: 250 },
+ { date: "2024-05-26", desktop: 213, mobile: 170 },
+ { date: "2024-05-27", desktop: 420, mobile: 460 },
+ { date: "2024-05-28", desktop: 233, mobile: 190 },
+ { date: "2024-05-29", desktop: 78, mobile: 130 },
+ { date: "2024-05-30", desktop: 340, mobile: 280 },
+ { date: "2024-05-31", desktop: 178, mobile: 230 },
+ { date: "2024-06-01", desktop: 178, mobile: 200 },
+ { date: "2024-06-02", desktop: 470, mobile: 410 },
+ { date: "2024-06-03", desktop: 103, mobile: 160 },
+ { date: "2024-06-04", desktop: 439, mobile: 380 },
+ { date: "2024-06-05", desktop: 88, mobile: 140 },
+ { date: "2024-06-06", desktop: 294, mobile: 250 },
+ { date: "2024-06-07", desktop: 323, mobile: 370 },
+ { date: "2024-06-08", desktop: 385, mobile: 320 },
+ { date: "2024-06-09", desktop: 438, mobile: 480 },
+ { date: "2024-06-10", desktop: 155, mobile: 200 },
+ { date: "2024-06-11", desktop: 92, mobile: 150 },
+ { date: "2024-06-12", desktop: 492, mobile: 420 },
+ { date: "2024-06-13", desktop: 81, mobile: 130 },
+ { date: "2024-06-14", desktop: 426, mobile: 380 },
+ { date: "2024-06-15", desktop: 307, mobile: 350 },
+ { date: "2024-06-16", desktop: 371, mobile: 310 },
+ { date: "2024-06-17", desktop: 475, mobile: 520 },
+ { date: "2024-06-18", desktop: 107, mobile: 170 },
+ { date: "2024-06-19", desktop: 341, mobile: 290 },
+ { date: "2024-06-20", desktop: 408, mobile: 450 },
+ { date: "2024-06-21", desktop: 169, mobile: 210 },
+ { date: "2024-06-22", desktop: 317, mobile: 270 },
+ { date: "2024-06-23", desktop: 480, mobile: 530 },
+ { date: "2024-06-24", desktop: 132, mobile: 180 },
+ { date: "2024-06-25", desktop: 141, mobile: 190 },
+ { date: "2024-06-26", desktop: 434, mobile: 380 },
+ { date: "2024-06-27", desktop: 448, mobile: 490 },
+ { date: "2024-06-28", desktop: 149, mobile: 200 },
+ { date: "2024-06-29", desktop: 103, mobile: 160 },
+ { date: "2024-06-30", desktop: 446, mobile: 400 },
+]
+
+const chartConfig = {
+ visitors: {
+ label: "Visitors",
+ },
+ desktop: {
+ label: "Desktop",
+ color: "hsl(var(--chart-1))",
+ },
+ mobile: {
+ label: "Mobile",
+ color: "hsl(var(--chart-2))",
+ },
+} satisfies ChartConfig
+
+export function ChartAreaInteractive() {
+ const isMobile = useIsMobile()
+ const [timeRange, setTimeRange] = React.useState("30d")
+
+ React.useEffect(() => {
+ if (isMobile) {
+ setTimeRange("7d")
+ }
+ }, [isMobile])
+
+ const filteredData = chartData.filter((item) => {
+ const date = new Date(item.date)
+ const referenceDate = new Date("2024-06-30")
+ let daysToSubtract = 90
+ if (timeRange === "30d") {
+ daysToSubtract = 30
+ } else if (timeRange === "7d") {
+ daysToSubtract = 7
+ }
+ const startDate = new Date(referenceDate)
+ startDate.setDate(startDate.getDate() - daysToSubtract)
+ return date >= startDate
+ })
+
+ return (
+
+
+ Total Visitors
+
+
+ Total for the last 3 months
+
+ Last 3 months
+
+
+
+
+ Last 3 months
+
+
+ Last 30 days
+
+
+ Last 7 days
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ const date = new Date(value)
+ return date.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ })
+ }}
+ />
+ {
+ return new Date(value).toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ })
+ }}
+ indicator="dot"
+ />
+ }
+ />
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/data-table.tsx b/src/components/data-table.tsx
new file mode 100644
index 0000000..9252210
--- /dev/null
+++ b/src/components/data-table.tsx
@@ -0,0 +1,548 @@
+"use client"
+
+import * as React from "react"
+import {
+ DndContext,
+ KeyboardSensor,
+ MouseSensor,
+ TouchSensor,
+ closestCenter,
+ useSensor,
+ useSensors,
+ type DragEndEvent,
+ type UniqueIdentifier,
+} from "@dnd-kit/core"
+import { restrictToVerticalAxis } from "@dnd-kit/modifiers"
+import {
+ SortableContext,
+ arrayMove,
+ useSortable,
+ verticalListSortingStrategy,
+} from "@dnd-kit/sortable"
+import { CSS } from "@dnd-kit/utilities"
+import {
+ ColumnDef,
+ ColumnFiltersState,
+ Row,
+ SortingState,
+ VisibilityState,
+ flexRender,
+ getCoreRowModel,
+ getFacetedRowModel,
+ getFacetedUniqueValues,
+ getFilteredRowModel,
+ getPaginationRowModel,
+ getSortedRowModel,
+ useReactTable,
+} from "@tanstack/react-table"
+import {
+ ChevronDownIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+ ChevronsLeftIcon,
+ ChevronsRightIcon,
+ ColumnsIcon,
+ GripVerticalIcon,
+ LoaderIcon,
+ MoreHorizontalIcon,
+ MoreVerticalIcon,
+ PlusIcon,
+ EyeIcon,
+ PencilIcon,
+ TrashIcon,
+} from "lucide-react"
+import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
+import { toast } from "sonner"
+import { z } from "zod"
+
+import { useIsMobile } from "@/hooks/use-mobile"
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import {
+ ChartConfig,
+ ChartContainer,
+ ChartTooltip,
+ ChartTooltipContent,
+} from "@/components/ui/chart"
+import { Checkbox } from "@/components/ui/checkbox"
+import {
+ DropdownMenu,
+ DropdownMenuCheckboxItem,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { Input } from "@/components/ui/input"
+import { Label } from "@/components/ui/label"
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select"
+import { Separator } from "@/components/ui/separator"
+import {
+ Sheet,
+ SheetClose,
+ SheetContent,
+ SheetDescription,
+ SheetFooter,
+ SheetHeader,
+ SheetTitle,
+ SheetTrigger,
+} from "@/components/ui/sheet"
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table"
+import {
+ Tabs,
+ TabsContent,
+ TabsList,
+ TabsTrigger,
+} from "@/components/ui/tabs"
+
+export const schema = z.object({
+ id: z.number(),
+ name: z.string(),
+ email: z.string(),
+ createdAt: z.string().datetime(),
+})
+
+// Create a separate component for the drag handle
+function DragHandle({ id }: { id: number }) {
+ const { attributes, listeners } = useSortable({
+ id,
+ })
+
+ return (
+
+ )
+}
+
+const columns: ColumnDef>[] = [
+ {
+ id: "select",
+ header: ({ table }) => (
+
+ table.toggleAllPageRowsSelected(!!value)}
+ aria-label="Select all"
+ />
+
+ ),
+ cell: ({ row }) => (
+
+ row.toggleSelected(!!value)}
+ aria-label={`Select row ${row.original.id}`}
+ />
+
+ ),
+ enableSorting: false,
+ enableHiding: false,
+ },
+ {
+ accessorKey: "id",
+ header: "ID",
+ cell: ({ row }) => {row.original.id}
,
+ },
+ {
+ accessorKey: "name",
+ header: "姓名",
+ cell: ({ row }) => ,
+ },
+ {
+ accessorKey: "email",
+ header: "邮箱",
+ cell: ({ row }) => {row.original.email}
,
+ },
+ {
+ accessorKey: "createdAt",
+ header: "创建时间",
+ cell: ({ row }) => (
+
+ {new Date(row.original.createdAt).toLocaleDateString()}
+
+ ),
+ },
+ {
+ id: "actions",
+ enableHiding: false,
+ header: () => 操作
,
+ cell: ({ row }) => {
+ const item = row.original
+ return (
+
+
+
+
+
+ )
+ },
+ }
+]
+
+function DraggableRow({ row }: { row: Row> }) {
+ const { transform, transition, setNodeRef, isDragging } = useSortable({
+ id: row.original.id,
+ })
+
+ return (
+
+ {row.getVisibleCells().map((cell) => (
+
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
+
+ ))}
+
+ )
+}
+
+function TableCellViewer({ item }: { item: z.infer }) {
+ const isMobile = useIsMobile()
+
+ return (
+
+
+
+
+
+
+ ID: {item.id}
+ 姓名: {item.name}
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export function DataTable({
+ data: initialData,
+}: {
+ data: z.infer[]
+}) {
+ const [data, setData] = React.useState(() => initialData)
+ const [rowSelection, setRowSelection] = React.useState({})
+ const [columnVisibility, setColumnVisibility] = React.useState({
+ drag: false,
+ // 仅保留必要列可见性控制
+ })
+ const [columnFilters, setColumnFilters] = React.useState([])
+ const [sorting, setSorting] = React.useState([])
+ const [pagination, setPagination] = React.useState({
+ pageIndex: 0,
+ pageSize: 10,
+ })
+ const sortableId = React.useId()
+ const sensors = useSensors(
+ useSensor(MouseSensor, {}),
+ useSensor(TouchSensor, {}),
+ useSensor(KeyboardSensor, {})
+ )
+
+ const dataIds = React.useMemo(
+ () => data?.map(({ id }) => id) || [],
+ [data]
+ )
+
+ const table = useReactTable({
+ data,
+ columns,
+ state: {
+ sorting,
+ columnVisibility,
+ rowSelection,
+ columnFilters,
+ pagination,
+ },
+ getRowId: (row) => row.id.toString(),
+ enableRowSelection: true,
+ onRowSelectionChange: setRowSelection,
+ onSortingChange: setSorting,
+ onColumnFiltersChange: setColumnFilters,
+ onColumnVisibilityChange: setColumnVisibility,
+ onPaginationChange: setPagination,
+ getCoreRowModel: getCoreRowModel(),
+ getFilteredRowModel: getFilteredRowModel(),
+ getPaginationRowModel: getPaginationRowModel(),
+ getSortedRowModel: getSortedRowModel(),
+ getFacetedRowModel: getFacetedRowModel(),
+ getFacetedUniqueValues: getFacetedUniqueValues(),
+ })
+
+ function handleDragEnd(event: DragEndEvent) {
+ const { active, over } = event
+ if (active && over && active.id !== over.id) {
+ setData((data) => {
+ const oldIndex = dataIds.indexOf(active.id)
+ const newIndex = dataIds.indexOf(over.id)
+ return arrayMove(data, oldIndex, newIndex)
+ })
+ }
+ }
+
+ return (
+
+
+ {/* 修改视图标题区域为左侧固定内容 */}
+
+ 管理员列表
+
+
+
+
+
+
+
+
+ {table.getHeaderGroups().map((headerGroup) => (
+
+ {headerGroup.headers.map((header) => {
+ return (
+
+ {header.isPlaceholder
+ ? null
+ : flexRender(
+ header.column.columnDef.header,
+ header.getContext()
+ )}
+
+ )
+ })}
+
+ ))}
+
+
+ {table.getRowModel().rows?.length ? (
+
+ {table.getRowModel().rows.map((row) => (
+
+ ))}
+
+ ) : (
+
+
+ 暂无数据
+
+
+ )}
+
+
+
+
+ {/* 仅调整背景色,保持原有分页结构 */}
+
+
+ {table.getFilteredSelectedRowModel().rows.length} / {table.getFilteredRowModel().rows.length} 行已选择
+
+
+
+
+
+
+
+ 第 {table.getState().pagination.pageIndex + 1} 页
+ 共 {table.getPageCount()} 页
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const chartData = [
+ { month: "January", desktop: 186, mobile: 80 },
+ { month: "February", desktop: 305, mobile: 200 },
+ { month: "March", desktop: 237, mobile: 120 },
+ { month: "April", desktop: 73, mobile: 190 },
+ { month: "May", desktop: 209, mobile: 130 },
+ { month: "June", desktop: 214, mobile: 140 },
+]
+
+const chartConfig = {
+ desktop: {
+ label: "Desktop",
+ color: "var(--primary)",
+ },
+ mobile: {
+ label: "Mobile",
+ color: "var(--primary)",
+ },
+} satisfies ChartConfig
diff --git a/src/components/nav-documents.tsx b/src/components/nav-documents.tsx
new file mode 100644
index 0000000..6f4f182
--- /dev/null
+++ b/src/components/nav-documents.tsx
@@ -0,0 +1,85 @@
+"use client"
+
+import {
+ FolderIcon,
+ MoreHorizontalIcon,
+ ShareIcon,
+ type LucideIcon,
+} from "lucide-react"
+
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import {
+ SidebarGroup,
+ SidebarGroupLabel,
+ SidebarMenu,
+ SidebarMenuAction,
+ SidebarMenuButton,
+ SidebarMenuItem,
+ useSidebar,
+} from "@/components/ui/sidebar"
+
+export function NavDocuments({
+ items,
+}: {
+ items: {
+ name: string
+ url: string
+ icon: LucideIcon
+ }[]
+}) {
+ const { isMobile } = useSidebar()
+
+ return (
+
+ Documents
+
+ {items.map((item) => (
+
+
+
+
+ {item.name}
+
+
+
+
+
+
+ More
+
+
+
+
+
+ Open
+
+
+
+ Share
+
+
+
+
+ ))}
+
+
+
+ More
+
+
+
+
+ )
+}
diff --git a/src/components/nav-main.tsx b/src/components/nav-main.tsx
index 7706335..a7b4716 100644
--- a/src/components/nav-main.tsx
+++ b/src/components/nav-main.tsx
@@ -1,83 +1,58 @@
-"use client";
+"use client"
+import { MailIcon, PlusCircleIcon, type LucideIcon } from "lucide-react"
+
+import { Button } from "@/components/ui/button"
import {
SidebarGroup,
- SidebarGroupLabel,
+ SidebarGroupContent,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
- SidebarMenuSub,
- SidebarMenuSubButton,
- SidebarMenuSubItem,
-} from "@/components/ui/sidebar";
-import {
- Collapsible,
- CollapsibleContent,
- CollapsibleTrigger,
-} from "@/components/ui/collapsible";
-import { ChevronRight, type LucideIcon } from "lucide-react";
+} from "@/components/ui/sidebar"
-export interface NavMainProps {
+export function NavMain({
+ items,
+}: {
items: {
- title: string;
- url: string;
- icon?: LucideIcon;
- isActive?: boolean;
- items?: {
- title: string;
- url: string;
- }[];
- }[];
-}
-
-export function NavMain({ items }: NavMainProps) {
+ title: string
+ url: string
+ icon?: LucideIcon
+ }[]
+}) {
return (
- Platform
-
- {items.map((item) =>
- !item.items ? (
+
+
+
+
+
+ Quick Create
+
+
+
+
+
+ {items.map((item) => (
-
-
- {item.icon && }
- {item.title}
-
+
+ {item.icon && }
+ {item.title}
- ) : (
-
-
-
-
- {item.icon && }
- {item.title}
-
-
-
-
-
- {item.items.map((subItem) => (
-
-
-
- {subItem.title}
-
-
-
- ))}
-
-
-
-
- )
- )}
-
+ ))}
+
+
- );
+ )
}
diff --git a/src/components/nav-secondary.tsx b/src/components/nav-secondary.tsx
new file mode 100644
index 0000000..e3d707e
--- /dev/null
+++ b/src/components/nav-secondary.tsx
@@ -0,0 +1,42 @@
+"use client"
+
+import * as React from "react"
+import { LucideIcon } from "lucide-react"
+
+import {
+ SidebarGroup,
+ SidebarGroupContent,
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+} from "@/components/ui/sidebar"
+
+export function NavSecondary({
+ items,
+ ...props
+}: {
+ items: {
+ title: string
+ url: string
+ icon: LucideIcon
+ }[]
+} & React.ComponentPropsWithoutRef) {
+ return (
+
+
+
+ {items.map((item) => (
+
+
+
+
+ {item.title}
+
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/nav-user.tsx b/src/components/nav-user.tsx
index 66190a5..2eb61f9 100644
--- a/src/components/nav-user.tsx
+++ b/src/components/nav-user.tsx
@@ -1,19 +1,18 @@
-"use client";
+"use client"
import {
- BadgeCheck,
- Bell,
- ChevronsUpDown,
- CreditCard,
- LogOut,
- Sparkles,
-} from "lucide-react";
+ BellIcon,
+ CreditCardIcon,
+ LogOutIcon,
+ MoreVerticalIcon,
+ UserCircleIcon,
+} from "lucide-react"
+
import {
- SidebarMenu,
- SidebarMenuButton,
- SidebarMenuItem,
- useSidebar,
-} from "@/components/ui/sidebar";
+ Avatar,
+ AvatarFallback,
+ AvatarImage,
+} from "@/components/ui/avatar"
import {
DropdownMenu,
DropdownMenuContent,
@@ -22,21 +21,24 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
-import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
-
-export interface NavUserProps {
- user: {
- name: string;
- email: string;
- avatar: string;
- };
-}
+} from "@/components/ui/dropdown-menu"
+import {
+ SidebarMenu,
+ SidebarMenuButton,
+ SidebarMenuItem,
+ useSidebar,
+} from "@/components/ui/sidebar"
export function NavUser({
user,
-}: NavUserProps) {
- const { isMobile } = useSidebar();
+}: {
+ user: {
+ name: string
+ email: string
+ avatar: string
+ }
+}) {
+ const { isMobile } = useSidebar()
return (
@@ -47,15 +49,17 @@ export function NavUser({
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
>
-
+
CN
- {user.name}
- {user.email}
+ {user.name}
+
+ {user.email}
+
-
+
CN
- {user.name}
- {user.email}
+ {user.name}
+
+ {user.email}
+
-
- Upgrade to Pro
-
-
-
-
-
-
+
Account
-
+
Billing
-
+
Notifications
-
+
Log out
- );
+ )
}
diff --git a/src/components/section-cards.tsx b/src/components/section-cards.tsx
new file mode 100644
index 0000000..579f3cc
--- /dev/null
+++ b/src/components/section-cards.tsx
@@ -0,0 +1,101 @@
+import { TrendingDownIcon, TrendingUpIcon } from "lucide-react"
+
+import { Badge } from "@/components/ui/badge"
+import {
+ Card,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card"
+
+export function SectionCards() {
+ return (
+
+
+
+ Total Revenue
+
+ $1,250.00
+
+
+
+
+ +12.5%
+
+
+
+
+
+ Trending up this month
+
+
+ Visitors for the last 6 months
+
+
+
+
+
+ New Customers
+
+ 1,234
+
+
+
+
+ -20%
+
+
+
+
+
+ Down 20% this period
+
+
+ Acquisition needs attention
+
+
+
+
+
+ Active Accounts
+
+ 45,678
+
+
+
+
+ +12.5%
+
+
+
+
+
+ Strong user retention
+
+ Engagement exceed targets
+
+
+
+
+ Growth Rate
+
+ 4.5%
+
+
+
+
+ +4.5%
+
+
+
+
+
+ Steady performance
+
+ Meets growth projections
+
+
+
+ )
+}
diff --git a/src/components/site-header.tsx b/src/components/site-header.tsx
new file mode 100644
index 0000000..0801404
--- /dev/null
+++ b/src/components/site-header.tsx
@@ -0,0 +1,11 @@
+import { Separator } from "@/components/ui/separator"
+
+export function SiteHeader() {
+ return (
+
+ )
+}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 6bb95d9..25ee55d 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -12,87 +12,89 @@ export default {
"./src/lib/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
- extend: {
- colors: {
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- chart: {
- "1": "hsl(var(--chart-1))",
- "2": "hsl(var(--chart-2))",
- "3": "hsl(var(--chart-3))",
- "4": "hsl(var(--chart-4))",
- "5": "hsl(var(--chart-5))",
- },
- sidebar: {
- DEFAULT: "hsl(var(--sidebar-background))",
- foreground: "hsl(var(--sidebar-foreground))",
- primary: "hsl(var(--sidebar-primary))",
- "primary-foreground": "hsl(var(--sidebar-primary-foreground))",
- accent: "hsl(var(--sidebar-accent))",
- "accent-foreground": "hsl(var(--sidebar-accent-foreground))",
- border: "hsl(var(--sidebar-border))",
- ring: "hsl(var(--sidebar-ring))",
- },
- },
- borderRadius: {
- lg: "var(--radius)",
- md: "calc(var(--radius) - 2px)",
- sm: "calc(var(--radius) - 4px)",
- },
- keyframes: {
- "accordion-down": {
- from: {
- height: "0",
- },
- to: {
- height: "var(--radix-accordion-content-height)",
- },
- },
- "accordion-up": {
- from: {
- height: "var(--radix-accordion-content-height)",
- },
- to: {
- height: "0",
- },
- },
- },
- animation: {
- "accordion-down": "accordion-down 0.2s ease-out",
- "accordion-up": "accordion-up 0.2s ease-out",
- },
- },
+ extend: {
+ colors: {
+ background: 'hsl(var(--background))',
+ foreground: 'hsl(var(--foreground))',
+ card: {
+ DEFAULT: 'hsl(var(--card))',
+ foreground: 'hsl(var(--card-foreground))'
+ },
+ popover: {
+ DEFAULT: 'hsl(var(--popover))',
+ foreground: 'hsl(var(--popover-foreground))'
+ },
+ primary: {
+ DEFAULT: 'hsl(var(--primary))',
+ foreground: 'hsl(var(--primary-foreground))'
+ },
+ secondary: {
+ DEFAULT: 'hsl(var(--secondary))',
+ foreground: 'hsl(var(--secondary-foreground))'
+ },
+ muted: {
+ DEFAULT: 'hsl(var(--muted))',
+ foreground: 'hsl(var(--muted-foreground))'
+ },
+ accent: {
+ DEFAULT: 'hsl(var(--accent))',
+ foreground: 'hsl(var(--accent-foreground))'
+ },
+ destructive: {
+ DEFAULT: 'hsl(var(--destructive))',
+ foreground: 'hsl(var(--destructive-foreground))'
+ },
+ border: 'hsl(var(--border))',
+ input: 'hsl(var(--input))',
+ ring: 'hsl(var(--ring))',
+ chart: {
+ '1': 'hsl(var(--chart-1))',
+ '2': 'hsl(var(--chart-2))',
+ '3': 'hsl(var(--chart-3))',
+ '4': 'hsl(var(--chart-4))',
+ '5': 'hsl(var(--chart-5))'
+ },
+ sidebar: {
+ DEFAULT: 'hsl(var(--sidebar-background))',
+ foreground: 'hsl(var(--sidebar-foreground))',
+ primary: 'hsl(var(--sidebar-primary))',
+ 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
+ accent: 'hsl(var(--sidebar-accent))',
+ 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
+ border: 'hsl(var(--sidebar-border))',
+ ring: 'hsl(var(--sidebar-ring))',
+ 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
+ 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))'
+ }
+ },
+ borderRadius: {
+ lg: 'var(--radius)',
+ md: 'calc(var(--radius) - 2px)',
+ sm: 'calc(var(--radius) - 4px)'
+ },
+ keyframes: {
+ 'accordion-down': {
+ from: {
+ height: '0'
+ },
+ to: {
+ height: 'var(--radix-accordion-content-height)'
+ }
+ },
+ 'accordion-up': {
+ from: {
+ height: 'var(--radix-accordion-content-height)'
+ },
+ to: {
+ height: '0'
+ }
+ }
+ },
+ animation: {
+ 'accordion-down': 'accordion-down 0.2s ease-out',
+ 'accordion-up': 'accordion-up 0.2s ease-out'
+ }
+ }
},
plugins: [animate],
} satisfies Config;