Toolhub / Views /Shared /_AdminLayout.cshtml
unifare
Initial commit: ToolHub ASP.NET Core app
5fc700d
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - ToolHub 管理后台</title>
<!-- 外部字体和图标 -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet" />
<!-- 样式文件 -->
<link rel="stylesheet" href="~/css/toolhub.css" asp-append-version="true" />
<style>
.admin-sidebar {
width: 250px;
background: white;
box-shadow: var(--shadow);
position: fixed;
top: 0;
left: 0;
height: 100vh;
z-index: 1000;
overflow-y: auto;
}
.admin-main {
margin-left: 250px;
min-height: 100vh;
background: #fafafa;
}
.admin-header {
background: white;
padding: 1rem 2rem;
box-shadow: var(--shadow-sm);
display: flex;
justify-content: space-between;
align-items: center;
}
.admin-content {
padding: 2rem;
}
.sidebar-brand {
padding: 1.5rem;
border-bottom: 1px solid var(--light-2);
text-align: center;
}
.sidebar-nav {
padding: 1rem 0;
}
.sidebar-nav-item {
display: block;
padding: 0.75rem 1.5rem;
color: var(--dark-2);
text-decoration: none;
transition: var(--transition);
border-left: 3px solid transparent;
}
.sidebar-nav-item:hover,
.sidebar-nav-item.active {
background: var(--light-1);
color: var(--primary);
border-left-color: var(--primary);
text-decoration: none;
}
.sidebar-nav-item i {
width: 1.5rem;
margin-right: 0.75rem;
}
.stats-card {
background: white;
padding: 1.5rem;
border-radius: var(--border-radius);
box-shadow: var(--shadow-sm);
transition: var(--transition);
}
.stats-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow);
}
.stats-number {
font-size: 2rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.stats-label {
color: var(--dark-2);
font-size: 0.875rem;
}
.data-table {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow-sm);
overflow: hidden;
}
.data-table table {
width: 100%;
border-collapse: collapse;
}
.data-table th,
.data-table td {
padding: 0.75rem 1rem;
text-align: left;
border-bottom: 1px solid var(--light-2);
}
.data-table th {
background: var(--light-1);
font-weight: 600;
color: var(--dark);
}
.data-table tbody tr:hover {
background: var(--light-1);
}
.badge {
display: inline-block;
padding: 0.25rem 0.75rem;
font-size: 0.75rem;
font-weight: 500;
border-radius: 50px;
color: white;
}
.badge-primary { background: var(--primary); }
.badge-success { background: var(--success); }
.badge-warning { background: var(--warning); }
.badge-danger { background: var(--danger); }
.badge-secondary { background: var(--dark-2); }
@@media (max-width: 768px) {
.admin-sidebar {
transform: translateX(-100%);
transition: transform 0.3s ease;
}
.admin-sidebar.show {
transform: translateX(0);
}
.admin-main {
margin-left: 0;
}
}
</style>
@await RenderSectionAsync("Styles", required: false)
</head>
<body class="admin-page">
<!-- 侧边栏 -->
<div class="admin-sidebar">
<div class="sidebar-brand">
<div class="brand-icon" style="margin-bottom: 0.5rem;">
<i class="fas fa-wrench"></i>
</div>
<h5 style="margin: 0; font-weight: 700;">
<span class="text-gradient">ToolHub</span>
</h5>
<p style="font-size: 0.75rem; color: var(--dark-2); margin: 0.25rem 0 0;">管理后台</p>
</div>
<nav class="sidebar-nav">
<a href="@Url.Action("Index", "Admin")" class="sidebar-nav-item @(ViewContext.RouteData.Values["action"]?.ToString() == "Index" ? "active" : "")">
<i class="fas fa-chart-line"></i>
仪表板
</a>
<a href="@Url.Action("Index", "Category")" class="sidebar-nav-item @(ViewContext.RouteData.Values["controller"]?.ToString() == "Category" ? "active" : "")">
<i class="fas fa-tags"></i>
工具分类
</a>
<a href="@Url.Action("Index", "Tag")" class="sidebar-nav-item @(ViewContext.RouteData.Values["controller"]?.ToString() == "Tag" ? "active" : "")">
<i class="fas fa-tags"></i>
标签管理
</a>
<a href="@Url.Action("Index", "Tool")" class="sidebar-nav-item @(ViewContext.RouteData.Values["controller"]?.ToString() == "Tool" ? "active" : "")">
<i class="fas fa-tools"></i>
工具管理
</a>
<a href="@Url.Action("Index", "ToolStatistics")" class="sidebar-nav-item @(ViewContext.RouteData.Values["controller"]?.ToString() == "ToolStatistics" ? "active" : "")">
<i class="fas fa-chart-bar"></i>
工具统计
</a>
<a href="@Url.Action("Users", "Admin")" class="sidebar-nav-item @(ViewContext.RouteData.Values["action"]?.ToString() == "Users" ? "active" : "")">
<i class="fas fa-users"></i>
用户管理
</a>
<a href="@Url.Action("Index", "Home")" class="sidebar-nav-item" target="_blank">
<i class="fas fa-external-link-alt"></i>
查看网站
</a>
</nav>
</div>
<!-- 主内容区 -->
<div class="admin-main">
<!-- 顶部导航 -->
<header class="admin-header">
<div style="display: flex; align-items: center;">
<button class="btn btn-outline btn-sm mobile-sidebar-toggle" style="display: none; margin-right: 1rem;">
<i class="fas fa-bars"></i>
</button>
<h1 style="font-size: 1.25rem; font-weight: 600; margin: 0; color: var(--dark);">
@ViewData["Title"]
</h1>
</div>
<div style="display: flex; align-items: center; gap: 1rem;">
<span style="font-size: 0.875rem; color: var(--dark-2);">
欢迎,<strong>@User.Identity?.Name</strong>
</span>
<form method="post" action="@Url.Action("Logout", "Admin")" style="margin: 0;">
<button type="submit" class="btn btn-outline btn-sm">
<i class="fas fa-sign-out-alt"></i>
退出
</button>
</form>
</div>
</header>
<!-- 内容区 -->
<main class="admin-content">
@RenderBody()
</main>
</div>
<!-- JavaScript -->
<script src="~/js/toolhub.js" asp-append-version="true"></script>
<script>
// 移动端侧边栏切换
document.addEventListener('DOMContentLoaded', function() {
const toggleBtn = document.querySelector('.mobile-sidebar-toggle');
const sidebar = document.querySelector('.admin-sidebar');
if (toggleBtn && sidebar) {
// 显示移动端按钮
if (window.innerWidth <= 768) {
toggleBtn.style.display = 'inline-flex';
}
// 切换侧边栏
toggleBtn.addEventListener('click', function() {
sidebar.classList.toggle('show');
});
// 点击外部关闭
document.addEventListener('click', function(e) {
if (window.innerWidth <= 768 &&
!sidebar.contains(e.target) &&
!toggleBtn.contains(e.target)) {
sidebar.classList.remove('show');
}
});
// 响应式处理
window.addEventListener('resize', function() {
if (window.innerWidth <= 768) {
toggleBtn.style.display = 'inline-flex';
} else {
toggleBtn.style.display = 'none';
sidebar.classList.remove('show');
}
});
}
});
</script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>