feat: 实现前端管理看板与移动端扫码视图组件
This commit is contained in:
87
frontend/src/components/layout/AdminLayout.tsx
Normal file
87
frontend/src/components/layout/AdminLayout.tsx
Normal file
@ -0,0 +1,87 @@
|
||||
import { NavLink, Outlet, useLocation } from "react-router-dom";
|
||||
import { QrCode, Package, ArrowLeft, LayoutDashboard, Smartphone } from "lucide-react";
|
||||
|
||||
const MENU = [
|
||||
{
|
||||
title: "全局概览",
|
||||
path: "/admin/dashboard",
|
||||
icon: LayoutDashboard,
|
||||
description: "生产数据总览 · 产品 + 任务统计",
|
||||
},
|
||||
{
|
||||
title: "产品管理",
|
||||
path: "/admin/products",
|
||||
icon: Package,
|
||||
description: "创建产品 · 生成二维码 · 打印标签",
|
||||
},
|
||||
];
|
||||
|
||||
export default function AdminLayout() {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen bg-gray-50">
|
||||
{/* 侧边栏 */}
|
||||
<aside className="fixed left-0 top-0 z-40 flex h-screen w-56 flex-col border-r border-gray-200 bg-white">
|
||||
<div className="flex items-center gap-2 border-b border-gray-100 px-5 py-4">
|
||||
<QrCode className="h-5 w-5 text-blue-600" />
|
||||
<span className="text-sm font-bold text-gray-800">生产流转 · 管理端</span>
|
||||
</div>
|
||||
|
||||
<nav className="flex-1 space-y-0.5 px-3 py-4">
|
||||
{MENU.map((item) => {
|
||||
const isActive = location.pathname.startsWith(item.path);
|
||||
return (
|
||||
<NavLink
|
||||
key={item.path}
|
||||
to={item.path}
|
||||
className={`flex items-start gap-3 rounded-lg px-3 py-2.5 transition-colors ${
|
||||
isActive ? "bg-blue-50 text-blue-700" : "text-gray-600 hover:bg-gray-100"
|
||||
}`}
|
||||
>
|
||||
<item.icon className={`mt-0.5 h-4 w-4 shrink-0 ${isActive ? "text-blue-600" : "text-gray-400"}`} />
|
||||
<div>
|
||||
<p className="text-sm font-medium">{item.title}</p>
|
||||
<p className="text-xs text-gray-400">{item.description}</p>
|
||||
</div>
|
||||
</NavLink>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
<div className="space-y-1 border-t border-gray-100 px-5 py-3">
|
||||
<a
|
||||
href="/scan"
|
||||
className="flex items-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium text-green-600 transition-colors hover:bg-green-50"
|
||||
>
|
||||
<Smartphone className="h-3.5 w-3.5" />
|
||||
模拟手机扫码
|
||||
</a>
|
||||
<a
|
||||
href="/"
|
||||
className="flex items-center gap-1.5 rounded-md px-2 py-1.5 text-xs text-gray-400 transition-colors hover:text-gray-600"
|
||||
>
|
||||
<ArrowLeft className="h-3.5 w-3.5" />
|
||||
移动端首页
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main className="ml-56 flex-1">
|
||||
<div className="sticky top-0 z-30 border-b border-gray-200 bg-white px-6 py-3">
|
||||
<div className="flex items-center gap-2 text-xs text-gray-400">
|
||||
<LayoutDashboard className="h-3 w-3" />
|
||||
<span>管理端</span>
|
||||
<span>/</span>
|
||||
<span className="font-medium text-gray-600">
|
||||
{MENU.find((m) => location.pathname.startsWith(m.path))?.title ?? "页面"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<Outlet />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user