فهرست منبع

✨ feat(admin): 实现响应式侧边栏布局

- 拆分侧边栏为桌面端和移动端独立组件
- 桌面端侧边栏保留标题和搜索功能
- 移动端侧边栏仅保留菜单导航,优化移动端使用体验
- 调整侧边栏样式和布局,确保在不同设备上显示正常
yourname 3 ماه پیش
والد
کامیت
f90e1f6e30
1فایلهای تغییر یافته به همراه61 افزوده شده و 9 حذف شده
  1. 61 9
      web/src/client/admin/layouts/MainLayout.tsx

+ 61 - 9
web/src/client/admin/layouts/MainLayout.tsx

@@ -78,8 +78,8 @@ export const MainLayout = () => {
   const appName = getGlobalConfig('APP_NAME') || '应用Starter';
   
 
-  // 侧边栏内容
-  const SidebarContent = () => (
+  // 侧边栏内容 - 桌面端(包含标题和搜索)
+  const DesktopSidebarContent = () => (
     <div className="flex h-full flex-col">
       <div className="p-4 border-b">
         <h2 className="text-lg font-semibold truncate">
@@ -94,7 +94,7 @@ export const MainLayout = () => {
           </div>
         )}
       </div>
-      
+
       <ScrollArea className="flex-1">
         <nav className="p-2">
           {menuItems.map((item) => (
@@ -113,7 +113,7 @@ export const MainLayout = () => {
                 {item.icon}
                 {!collapsed && <span className="ml-2">{item.label}</span>}
               </Button>
-              
+
               {item.children && !collapsed && (
                 <div className="ml-4">
                   {item.children.map((child) => (
@@ -142,23 +142,75 @@ export const MainLayout = () => {
     </div>
   );
 
+  // 侧边栏内容 - 移动端(仅菜单,不包含标题)
+  const MobileSidebarContent = () => (
+    <div className="flex h-full flex-col">
+      <ScrollArea className="flex-1">
+        <nav className="p-2">
+          {menuItems.map((item) => (
+            <div key={item.key}>
+              <Button
+                variant={selectedKey === item.key ? "default" : "ghost"}
+                className={cn(
+                  "w-full justify-start mb-1",
+                  selectedKey === item.key && "bg-primary text-primary-foreground"
+                )}
+                onClick={() => {
+                  handleMenuClick(item);
+                  setIsMobileMenuOpen(false);
+                }}
+              >
+                {item.icon}
+                <span className="ml-2">{item.label}</span>
+              </Button>
+
+              {item.children && (
+                <div className="ml-4">
+                  {item.children.map((child) => (
+                    <Button
+                      key={child.key}
+                      variant={selectedKey === child.key ? "default" : "ghost"}
+                      className={cn(
+                        "w-full justify-start mb-1 text-sm",
+                        selectedKey === child.key && "bg-primary text-primary-foreground"
+                      )}
+                      onClick={() => {
+                        handleMenuClick(child);
+                        setIsMobileMenuOpen(false);
+                      }}
+                    >
+                      {child.icon && <span className="ml-2">{child.icon}</span>}
+                      <span className={child.icon ? "ml-2" : "ml-6"}>{child.label}</span>
+                    </Button>
+                  ))}
+                </div>
+              )}
+            </div>
+          ))}
+        </nav>
+      </ScrollArea>
+    </div>
+  );
+
   return (
     <div className="flex h-screen bg-background">
       {/* Desktop Sidebar */}
       <aside className={cn(
-        "hidden md:block border-r bg-background transition-all duration-200",
+        "hidden md:block border-r bg-background transition-all duration-200 flex flex-col",
         collapsed ? "w-16" : "w-64"
       )}>
-        <SidebarContent />
+        <DesktopSidebarContent />
       </aside>
 
       {/* Mobile Sidebar */}
       <Sheet open={isMobileMenuOpen} onOpenChange={setIsMobileMenuOpen}>
-        <SheetContent side="left" className="w-64 p-0">
-          <SheetHeader className="p-4">
+        <SheetContent side="left" className="w-64 p-0 flex flex-col h-full">
+          <SheetHeader className="p-4 border-b">
             <SheetTitle>{appName}</SheetTitle>
           </SheetHeader>
-          <SidebarContent />
+          <div className="flex-1 overflow-hidden">
+            <MobileSidebarContent />
+          </div>
         </SheetContent>
       </Sheet>