199 lines
10 KiB
TypeScript
199 lines
10 KiB
TypeScript
import Link from 'next/link'
|
|
import {ReactNode} from 'react'
|
|
|
|
export type AdminLayoutProps = {
|
|
children: ReactNode
|
|
}
|
|
|
|
export default function AdminLayout(props: AdminLayoutProps) {
|
|
return (
|
|
<div className="min-w-[1200px] overflow-auto bg-gray-50 flex">
|
|
|
|
{/* 左侧导航栏 */}
|
|
<aside className="w-64 h-screen overflow-y-auto bg-white border-r border-gray-200">
|
|
{/* Logo区域 */}
|
|
<div className="h-16 flex items-center px-6">
|
|
<svg className="w-8 h-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
|
</svg>
|
|
<h1 className="ml-3 text-xl font-bold text-gray-900">管理系统</h1>
|
|
</div>
|
|
|
|
{/* 导航菜单 */}
|
|
<nav className="mt-4 px-4">
|
|
<div className="space-y-6">
|
|
{/* 概览 */}
|
|
<div>
|
|
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">概览</div>
|
|
<Link
|
|
href="/dashboard"
|
|
className="flex items-center px-3 py-2 text-sm font-medium text-blue-600 bg-blue-50 rounded-md">
|
|
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
|
|
</svg>
|
|
仪表盘
|
|
</Link>
|
|
</div>
|
|
|
|
{/* 用户管理 */}
|
|
<div>
|
|
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">用户管理</div>
|
|
<div className="space-y-1">
|
|
<a
|
|
href="/users"
|
|
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
|
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
|
|
</svg>
|
|
用户列表
|
|
</a>
|
|
<a
|
|
href="/users/roles"
|
|
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
|
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
|
|
</svg>
|
|
角色权限
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 订单管理 */}
|
|
<div>
|
|
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">订单管理</div>
|
|
<div className="space-y-1">
|
|
<a
|
|
href="/orders"
|
|
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
|
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
|
</svg>
|
|
订单列表
|
|
</a>
|
|
<a
|
|
href="/orders/refunds"
|
|
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
|
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M16 15v-1a4 4 0 00-4-4H8m0 0l3 3m-3-3l3-3m9 14V5a2 2 0 00-2-2H6a2 2 0 00-2 2v16l4-2 4 2 4-2 4 2z"/>
|
|
</svg>
|
|
退款管理
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 系统设置 */}
|
|
<div>
|
|
<div className="px-3 mb-2 text-xs font-medium text-gray-500 uppercase tracking-wider">系统设置</div>
|
|
<a
|
|
href="/settings"
|
|
className="flex items-center px-3 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-50">
|
|
<svg className="w-5 h-5 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
|
</svg>
|
|
基本设置
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</aside>
|
|
|
|
{/* 右侧主内容区 */}
|
|
<div className="flex-1 h-screen flex flex-col">
|
|
|
|
{/* 顶部导航栏 */}
|
|
<header className="h-16 bg-white border-b border-gray-200 px-6 flex items-center justify-between">
|
|
|
|
{/* 面包屑导航 */}
|
|
<div className="flex items-center">
|
|
<a href="/dashboard" className="text-gray-600 hover:text-blue-600">首页</a>
|
|
<svg className="w-4 h-4 mx-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7"/>
|
|
</svg>
|
|
<span className="text-gray-400">当前页面</span>
|
|
</div>
|
|
|
|
{/* 右侧工具栏 */}
|
|
<div className="flex items-center space-x-3">
|
|
{/* 搜索框 */}
|
|
<div className="w-56">
|
|
<div className="relative">
|
|
<input
|
|
type="text"
|
|
placeholder="搜索..."
|
|
className="w-full h-10 pl-10 pr-4 text-sm bg-gray-50 border border-gray-200 rounded-lg focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500"
|
|
/>
|
|
<svg
|
|
className="w-5 h-5 text-gray-400 absolute left-3 top-2.5" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 全屏切换 */}
|
|
<button
|
|
className="p-2 text-gray-500 hover:text-gray-600 hover:bg-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/>
|
|
</svg>
|
|
</button>
|
|
|
|
{/* 通知 */}
|
|
<button
|
|
className="relative p-2 text-gray-500 hover:text-gray-600 hover:bg-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path
|
|
strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
|
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
|
</svg>
|
|
<span className="absolute top-2 right-2 w-2 h-2 bg-red-500 rounded-full"></span>
|
|
</button>
|
|
|
|
{/* 用户菜单 */}
|
|
<div className="relative">
|
|
<button
|
|
className="flex items-center space-x-3 p-1.5 rounded-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
<img
|
|
src="/images/avatar.jpg"
|
|
alt="用户头像"
|
|
className="w-9 h-9 rounded-full object-cover border-2 border-gray-200"
|
|
/>
|
|
<div className="text-left">
|
|
<div className="font-medium text-gray-800">管理员</div>
|
|
<div className="text-gray-500 text-xs">超级管理员</div>
|
|
</div>
|
|
<svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
{/* 主内容区域 */}
|
|
<main className={`flex-1 overflow-auto p-6`}>
|
|
{props.children}
|
|
</main>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|