From fe1466025e9ba001d943a4dce626752b5f259dd9 Mon Sep 17 00:00:00 2001 From: majiti606 <2771637854@qq.com> Date: Thu, 19 Jun 2025 10:39:48 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=B8=AA=E4=BA=BA=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E4=B8=8E=E4=BE=A7=E8=BE=B9=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(app)/management/change-password/page.tsx | 113 ++++++++++++++++++ src/app/(app)/management/page.tsx | 91 ++++++++++++++ src/app/(app)/management/profile/page.tsx | 56 +++++++++ src/components/app-sidebar.tsx | 109 +++-------------- src/components/manage-form.tsx | 28 +++++ src/components/manage-sidebar.tsx | 97 +++++++++++++++ src/components/manage-switcher.tsx | 64 ++++++++++ 7 files changed, 464 insertions(+), 94 deletions(-) create mode 100644 src/app/(app)/management/change-password/page.tsx create mode 100644 src/app/(app)/management/page.tsx create mode 100644 src/app/(app)/management/profile/page.tsx create mode 100644 src/components/manage-form.tsx create mode 100644 src/components/manage-sidebar.tsx create mode 100644 src/components/manage-switcher.tsx diff --git a/src/app/(app)/management/change-password/page.tsx b/src/app/(app)/management/change-password/page.tsx new file mode 100644 index 0000000..7e70e26 --- /dev/null +++ b/src/app/(app)/management/change-password/page.tsx @@ -0,0 +1,113 @@ +"use client" +import { useState } from "react"; + +export default function ChangePasswordPage() { + const [oldPassword, setOldPassword] = useState(""); + const [newPassword, setNewPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [showSuccess, setShowSuccess] = useState(false); + + const getPasswordStrength = (password: string) => { + if (password.length < 6) return "weak"; + if (/[A-Za-z]/.test(password) && /\d/.test(password)) return "medium"; + return "strong"; + }; + + const strengthText = getPasswordStrength(newPassword); + let strengthColor = ""; + let strengthLabel = ""; + + switch (strengthText) { + case "weak": + strengthColor = "bg-red-500"; + strengthLabel = "弱"; + break; + case "medium": + strengthColor = "bg-yellow-500"; + strengthLabel = "中等"; + break; + case "strong": + strengthColor = "bg-green-500"; + strengthLabel = "强"; + break; + } + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (newPassword !== confirmPassword) { + alert("两次输入的密码不一致!"); + return; + } + setShowSuccess(true); + setTimeout(() => setShowSuccess(false), 3000); + console.log("提交修改密码", { oldPassword, newPassword }); + }; + + return ( +
+
+

修改密码

+
+
+ + setOldPassword(e.target.value)} + className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" + required + /> +
+ +
+ + setNewPassword(e.target.value)} + className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" + required + /> + {newPassword && ( +

+ 密码强度: + +   + {strengthLabel} +

+ )} +
+ +
+ + setConfirmPassword(e.target.value)} + className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" + required + /> + {newPassword && confirmPassword && newPassword !== confirmPassword && ( +

密码不一致

+ )} +
+ +
+ +
+
+
+ + {showSuccess && ( +
+ ✅ 密码修改成功! +
+ )} +
+ ); +} \ No newline at end of file diff --git a/src/app/(app)/management/page.tsx b/src/app/(app)/management/page.tsx new file mode 100644 index 0000000..bf146b7 --- /dev/null +++ b/src/app/(app)/management/page.tsx @@ -0,0 +1,91 @@ +"use client" +import React, { useState } from "react" +import { AppSidebar } from "@/components/manage-sidebar" +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb" +import { Separator } from "@/components/ui/separator" +import { + SidebarInset, + SidebarProvider, + SidebarTrigger, +} from "@/components/ui/sidebar" +import ProfilePage from "./profile/page" +import ChangePasswordPage from "./change-password/page" + +// 模拟菜单数据 +const menuItems = [ + { title: "登录信息", key: "profile" }, + { title: "修改密码", key: "change-password" }, +] + +export default function ManagementDefaultPage() { + const [activePage, setActivePage] = useState("profile") + const [isCollapsed, setIsCollapsed] = useState(false) + + const renderContent = () => { + switch (activePage) { + case "profile": + return + case "change-password": + return + default: + return + } + } + + const toggleSidebar = () => { + setIsCollapsed((prev) => !prev) + } + + return ( + +
+ {/* 左侧侧边栏 */} + {!isCollapsed && ( +
+ +
+ )} + + {/* 右侧主内容区域 */} + +
+ {/* 折叠按钮 */} + + + + {/* 面包屑导航 */} + + + + 管理面板 + + + + + {menuItems.find((item) => item.key === activePage)?.title} + + + + +
+ + {/* 主体内容:根据 isCollapsed 切换样式 */} +
+ {renderContent()} +
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/(app)/management/profile/page.tsx b/src/app/(app)/management/profile/page.tsx new file mode 100644 index 0000000..c656b21 --- /dev/null +++ b/src/app/(app)/management/profile/page.tsx @@ -0,0 +1,56 @@ +"use client" +export default function ProfilePage() { + return ( +
+
+

登录信息

+ +
+
+
+ 👤 +
+
+
+

张三

+

角色:管理员

+

最后登录时间:2025-04-05 14:30

+
+
+ +
+ +
+
+ +

zhangsan123

+
+ +
+ +

zhangsan@example.com

+
+ +
+ +

2022-03-12

+
+ +
+ +

已激活

+
+
+ +
+ +
+
+
+ ); +} \ No newline at end of file diff --git a/src/components/app-sidebar.tsx b/src/components/app-sidebar.tsx index 2aee537..28e4700 100644 --- a/src/components/app-sidebar.tsx +++ b/src/components/app-sidebar.tsx @@ -26,140 +26,61 @@ const data = { versions: ["1.0.1", "1.1.0-alpha", "2.0.0-beta1"], navMain: [ { - title: "Getting Started", + title: "学生", url: "#", items: [ { - title: "Installation", + title: "学生列表", url: "#", }, { - title: "Project Structure", + title: "学生详情", + url: "#", + }, + { + title: "学生仪表盘", url: "#", }, ], }, { - title: "Building Your Application", + title: "教师", url: "#", items: [ { - title: "Routing", + title: "教师列表", url: "#", }, { - title: "Data Fetching", + title: "教师详情", url: "#", isActive: true, }, { - title: "Rendering", - url: "#", - }, - { - title: "Caching", - url: "#", - }, - { - title: "Styling", - url: "#", - }, - { - title: "Optimizing", - url: "#", - }, - { - title: "Configuring", - url: "#", - }, - { - title: "Testing", - url: "#", - }, - { - title: "Authentication", - url: "#", - }, - { - title: "Deploying", - url: "#", - }, - { - title: "Upgrading", - url: "#", - }, - { - title: "Examples", + title: "教师仪表盘", url: "#", }, ], }, { - title: "API Reference", + title: "管理员", url: "#", items: [ { - title: "Components", + title: "管理员列表", url: "#", }, { - title: "File Conventions", + title: "管理员详情", url: "#", }, { title: "Functions", url: "#", }, - { - title: "next.config.js Options", - url: "#", - }, - { - title: "CLI", - url: "#", - }, - { - title: "Edge Runtime", - url: "#", - }, - ], - }, - { - title: "Architecture", - url: "#", - items: [ - { - title: "Accessibility", - url: "#", - }, - { - title: "Fast Refresh", - url: "#", - }, - { - title: "Next.js Compiler", - url: "#", - }, - { - title: "Supported Browsers", - url: "#", - }, - { - title: "Turbopack", - url: "#", - }, - ], - }, - { - title: "Community", - url: "#", - items: [ - { - title: "Contribution Guide", - url: "#", - }, ], }, + ], } diff --git a/src/components/manage-form.tsx b/src/components/manage-form.tsx new file mode 100644 index 0000000..a120602 --- /dev/null +++ b/src/components/manage-form.tsx @@ -0,0 +1,28 @@ +import { Search } from "lucide-react" + +import { Label } from "@/components/ui/label" +import { + SidebarGroup, + SidebarGroupContent, + SidebarInput, +} from "@/components/ui/sidebar" + +export function SearchForm({ ...props }: React.ComponentProps<"form">) { + return ( +
+ + + + + + + +
+ ) +} \ No newline at end of file diff --git a/src/components/manage-sidebar.tsx b/src/components/manage-sidebar.tsx new file mode 100644 index 0000000..c7de169 --- /dev/null +++ b/src/components/manage-sidebar.tsx @@ -0,0 +1,97 @@ +import * as React from "react"; +import { ChevronRight } from "lucide-react"; + +import { VersionSwitcher } from "@/components/manage-switcher"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; +import { + Sidebar, + SidebarContent, + SidebarGroup, + SidebarGroupContent, + SidebarGroupLabel, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarRail, +} from "@/components/ui/sidebar"; + +// 自定义数据:包含用户相关菜单项 +const data = { + versions: ["1.0.1", "1.1.0-alpha", "2.0.0-beta1"], + navUser: [ + { + title: "个人中心", + url: "#", + items: [ + { title: "登录信息", url: "#", key: "profile" }, + { title: "修改密码", url: "#", key: "change-password" }, + ], + }, + ], +}; + +// 显式定义 props 类型 +interface AppSidebarProps { + onItemClick?: (key: string) => void; +} + +export function AppSidebar({ onItemClick = (key: string) => {}, ...props }: AppSidebarProps) { + return ( + + + + + + {/* 渲染用户相关的侧边栏菜单 */} + {data.navUser.map((item) => ( + + + + + {item.title} + + + + + + + {item.items.map((subItem) => ( + + { + e.preventDefault(); + onItemClick(subItem.key); + }} + > + {subItem.title} + + + ))} + + + + + + ))} + + + + ); +} \ No newline at end of file diff --git a/src/components/manage-switcher.tsx b/src/components/manage-switcher.tsx new file mode 100644 index 0000000..054995b --- /dev/null +++ b/src/components/manage-switcher.tsx @@ -0,0 +1,64 @@ +"use client" + +import * as React from "react" +import { Check, ChevronsUpDown, GalleryVerticalEnd } from "lucide-react" + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/components/ui/sidebar" + +export function VersionSwitcher({ + versions, + defaultVersion, +}: { + versions: string[] + defaultVersion: string +}) { + const [selectedVersion, setSelectedVersion] = React.useState(defaultVersion) + + return ( + + + + + +
+ +
+
+ Documentation + v{selectedVersion} +
+ +
+
+ + {versions.map((version) => ( + setSelectedVersion(version)} + > + v{version}{" "} + {version === selectedVersion && } + + ))} + +
+
+
+ ) +} \ No newline at end of file