2026-01-15 13:51:44 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="admin-layout">
|
|
|
|
|
<!-- Sidebar Navigation -->
|
2026-01-16 09:08:07 +08:00
|
|
|
<aside class="admin-sidebar" :class="{ 'collapsed': !isSidebarOpen }">
|
2026-01-15 13:51:44 +08:00
|
|
|
<div class="sidebar-header">
|
|
|
|
|
<h1 class="sidebar-title">管理后台</h1>
|
|
|
|
|
</div>
|
|
|
|
|
<nav class="sidebar-nav">
|
|
|
|
|
<ul>
|
2026-01-16 09:08:07 +08:00
|
|
|
<li v-for="(item, index) in menuItems" :key="index">
|
|
|
|
|
<!-- Parent Menu Item -->
|
|
|
|
|
<div
|
|
|
|
|
v-if="item.children"
|
|
|
|
|
class="nav-item-parent"
|
|
|
|
|
:class="{ 'expanded': item.isOpen }"
|
|
|
|
|
@click="toggleMenu(index)"
|
|
|
|
|
>
|
|
|
|
|
<div class="nav-link-content">
|
|
|
|
|
<span class="nav-icon">{{ item.icon }}</span>
|
|
|
|
|
<span class="nav-text">{{ item.title }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="nav-arrow">▼</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Single Menu Item -->
|
|
|
|
|
<router-link
|
|
|
|
|
v-else
|
|
|
|
|
:to="item.path || ''"
|
|
|
|
|
class="nav-link"
|
|
|
|
|
active-class="active"
|
|
|
|
|
>
|
|
|
|
|
<span class="nav-icon">{{ item.icon }}</span>
|
|
|
|
|
<span class="nav-text">{{ item.title }}</span>
|
2026-01-15 13:51:44 +08:00
|
|
|
</router-link>
|
2026-01-16 09:08:07 +08:00
|
|
|
|
|
|
|
|
<!-- Submenu -->
|
|
|
|
|
<ul v-if="item.children" class="submenu" :style="{ maxHeight: item.isOpen ? (item.children.length * 50) + 'px' : '0px' }">
|
|
|
|
|
<li v-for="(child, childIndex) in item.children" :key="childIndex">
|
|
|
|
|
<router-link :to="child.path" class="nav-link sub-link" active-class="active">
|
|
|
|
|
<span class="nav-icon">{{ child.icon }}</span>
|
|
|
|
|
<span class="nav-text">{{ child.title }}</span>
|
|
|
|
|
</router-link>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
2026-01-15 13:51:44 +08:00
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</nav>
|
2026-01-16 09:32:46 +08:00
|
|
|
<!-- Sidebar Footer removed as per request -->
|
2026-01-15 13:51:44 +08:00
|
|
|
</aside>
|
|
|
|
|
|
|
|
|
|
<!-- Main Content Area -->
|
|
|
|
|
<main class="admin-main">
|
|
|
|
|
<!-- Top Navigation Bar -->
|
|
|
|
|
<header class="admin-header">
|
|
|
|
|
<div class="header-left">
|
|
|
|
|
<button class="toggle-btn" @click="toggleSidebar">
|
|
|
|
|
☰
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="header-right">
|
2026-01-16 09:32:46 +08:00
|
|
|
<div class="user-dropdown relative" ref="dropdownRef">
|
|
|
|
|
<button class="user-info-btn" @click="toggleUserDropdown">
|
|
|
|
|
<span class="username">{{ currentUser.username }}</span>
|
|
|
|
|
<span class="role">({{ currentUser.role }})</span>
|
|
|
|
|
<span class="arrow" :class="{ 'rotated': isUserDropdownOpen }">▼</span>
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<div v-if="isUserDropdownOpen" class="dropdown-menu">
|
|
|
|
|
<div class="dropdown-header">
|
|
|
|
|
<span class="user-email">管理员</span>
|
|
|
|
|
</div>
|
|
|
|
|
<ul class="dropdown-list">
|
|
|
|
|
<li>
|
|
|
|
|
<button @click="handleChangePassword" class="dropdown-item">
|
|
|
|
|
<span class="icon">🔒</span>
|
|
|
|
|
修改密码
|
|
|
|
|
</button>
|
|
|
|
|
</li>
|
|
|
|
|
<li class="divider"></li>
|
|
|
|
|
<li>
|
|
|
|
|
<button @click="handleLogout" class="dropdown-item text-red-400">
|
|
|
|
|
<span class="icon">🚪</span>
|
|
|
|
|
退出登录
|
|
|
|
|
</button>
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
2026-01-15 13:51:44 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<!-- Content Container -->
|
|
|
|
|
<div class="admin-content">
|
|
|
|
|
<router-view />
|
|
|
|
|
</div>
|
|
|
|
|
</main>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2026-01-16 09:32:46 +08:00
|
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
2026-01-15 13:51:44 +08:00
|
|
|
import { useRouter } from 'vue-router'
|
|
|
|
|
import { useToast } from '../../composables/useToast'
|
|
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const toast = useToast()
|
|
|
|
|
const isSidebarOpen = ref(true)
|
|
|
|
|
const currentUser = ref(JSON.parse(localStorage.getItem('user') || '{}'))
|
|
|
|
|
|
2026-01-16 09:32:46 +08:00
|
|
|
// Dropdown logic
|
|
|
|
|
const isUserDropdownOpen = ref(false)
|
|
|
|
|
const dropdownRef = ref<HTMLElement | null>(null)
|
|
|
|
|
|
|
|
|
|
const toggleUserDropdown = () => {
|
|
|
|
|
isUserDropdownOpen.value = !isUserDropdownOpen.value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const closeDropdown = (e: MouseEvent) => {
|
|
|
|
|
if (dropdownRef.value && !dropdownRef.value.contains(e.target as Node)) {
|
|
|
|
|
isUserDropdownOpen.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleChangePassword = () => {
|
|
|
|
|
// Implement change password logic or navigate to page
|
|
|
|
|
toast.showToast('功能开发中...', 'info')
|
|
|
|
|
isUserDropdownOpen.value = false
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 09:08:07 +08:00
|
|
|
interface MenuItem {
|
|
|
|
|
title: string
|
|
|
|
|
icon: string
|
|
|
|
|
path?: string
|
|
|
|
|
children?: { title: string; path: string; icon: string }[]
|
|
|
|
|
isOpen?: boolean
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const menuItems = ref<MenuItem[]>([
|
|
|
|
|
{
|
|
|
|
|
title: '概览',
|
|
|
|
|
icon: '📊',
|
|
|
|
|
path: '/admin/dashboard'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '内容管理',
|
|
|
|
|
icon: '📚',
|
|
|
|
|
isOpen: true,
|
|
|
|
|
children: [
|
|
|
|
|
{ title: '文章管理', path: '/admin/posts', icon: '📝' },
|
|
|
|
|
{ title: '作品管理', path: '/admin/works', icon: '🎨' },
|
|
|
|
|
{ title: '代码片段', path: '/admin/snippets', icon: '💻' },
|
|
|
|
|
{ title: '标签管理', path: '/admin/tags', icon: '🏷️' }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '页面配置',
|
|
|
|
|
icon: '🔧',
|
|
|
|
|
isOpen: false,
|
|
|
|
|
children: [
|
|
|
|
|
{ title: '关于页面', path: '/admin/about', icon: '👤' },
|
|
|
|
|
{ title: '客户评价', path: '/admin/testimonials', icon: '💬' },
|
|
|
|
|
{ title: '合作伙伴', path: '/admin/partners', icon: '🤝' }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '业务中心',
|
|
|
|
|
icon: '💼',
|
|
|
|
|
isOpen: false,
|
|
|
|
|
children: [
|
|
|
|
|
{ title: '合作咨询', path: '/admin/inquiries', icon: '📩' },
|
|
|
|
|
{ title: '邮箱配置', path: '/admin/email-suffixes', icon: '📧' }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '用户权限',
|
|
|
|
|
icon: '🛡️',
|
|
|
|
|
isOpen: false,
|
|
|
|
|
children: [
|
|
|
|
|
{ title: '用户管理', path: '/admin/users', icon: '👥' },
|
|
|
|
|
{ title: '角色管理', path: '/admin/roles', icon: '🔒' }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '系统设置',
|
|
|
|
|
icon: '⚙️',
|
|
|
|
|
isOpen: false,
|
|
|
|
|
children: [
|
|
|
|
|
{ title: '全局配置', path: '/admin/settings', icon: '🛠️' },
|
|
|
|
|
{ title: '操作日志', path: '/admin/logs', icon: '📋' }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
const toggleMenu = (index: number) => {
|
|
|
|
|
menuItems.value[index].isOpen = !menuItems.value[index].isOpen
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 13:51:44 +08:00
|
|
|
const toggleSidebar = () => {
|
|
|
|
|
isSidebarOpen.value = !isSidebarOpen.value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleLogout = () => {
|
|
|
|
|
localStorage.removeItem('token')
|
|
|
|
|
localStorage.removeItem('user')
|
|
|
|
|
toast.showToast('退出登录成功', 'success')
|
|
|
|
|
router.push('/login')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if user is authenticated
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
const token = localStorage.getItem('token')
|
|
|
|
|
if (!token) {
|
|
|
|
|
router.push('/login')
|
|
|
|
|
}
|
2026-01-16 09:32:46 +08:00
|
|
|
document.addEventListener('click', closeDropdown)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
document.removeEventListener('click', closeDropdown)
|
2026-01-15 13:51:44 +08:00
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.admin-layout {
|
|
|
|
|
display: flex;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
background-color: #050505;
|
|
|
|
|
color: #ececec;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 09:32:46 +08:00
|
|
|
/* User Dropdown Styles */
|
|
|
|
|
.user-dropdown {
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.user-info-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 0.75rem;
|
|
|
|
|
background: transparent;
|
|
|
|
|
border: none;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
padding: 0.5rem;
|
|
|
|
|
border-radius: 0.375rem;
|
|
|
|
|
transition: background-color 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.user-info-btn:hover {
|
|
|
|
|
background-color: rgba(255, 255, 255, 0.05);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.arrow {
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
color: rgba(255, 255, 255, 0.5);
|
|
|
|
|
transition: transform 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.arrow.rotated {
|
|
|
|
|
transform: rotate(180deg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-menu {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 100%;
|
|
|
|
|
right: 0;
|
|
|
|
|
margin-top: 0.5rem;
|
|
|
|
|
width: 200px;
|
|
|
|
|
background: #1a1a1a;
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
|
|
|
border-radius: 0.5rem;
|
|
|
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
|
|
|
|
z-index: 100;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
animation: slideIn 0.2s ease-out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes slideIn {
|
|
|
|
|
from { opacity: 0; transform: translateY(-10px); }
|
|
|
|
|
to { opacity: 1; transform: translateY(0); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-header {
|
|
|
|
|
padding: 1rem;
|
|
|
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
|
|
|
background: rgba(255, 255, 255, 0.02);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.user-email {
|
|
|
|
|
font-size: 0.85rem;
|
|
|
|
|
color: rgba(255, 255, 255, 0.5);
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-list {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0.5rem 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 0.75rem;
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding: 0.75rem 1rem;
|
|
|
|
|
background: transparent;
|
|
|
|
|
border: none;
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
font-size: 0.9rem;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
text-align: left;
|
|
|
|
|
transition: background-color 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-item:hover {
|
|
|
|
|
background-color: rgba(212, 179, 131, 0.1);
|
|
|
|
|
color: #d4b383;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-item .icon {
|
|
|
|
|
font-size: 1.1rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.divider {
|
|
|
|
|
height: 1px;
|
|
|
|
|
background-color: rgba(255, 255, 255, 0.05);
|
|
|
|
|
margin: 0.5rem 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 13:51:44 +08:00
|
|
|
/* Sidebar Styles */
|
|
|
|
|
.admin-sidebar {
|
|
|
|
|
width: 250px;
|
|
|
|
|
background: rgba(5, 5, 5, 0.7);
|
|
|
|
|
backdrop-filter: blur(20px);
|
|
|
|
|
-webkit-backdrop-filter: blur(20px);
|
|
|
|
|
border-right: 1px solid rgba(255, 255, 255, 0.03);
|
|
|
|
|
color: white;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
2026-01-16 09:08:07 +08:00
|
|
|
overflow-y: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-sidebar::-webkit-scrollbar {
|
|
|
|
|
width: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-sidebar::-webkit-scrollbar-thumb {
|
|
|
|
|
background: rgba(255, 255, 255, 0.1);
|
|
|
|
|
border-radius: 2px;
|
2026-01-15 13:51:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sidebar-header {
|
|
|
|
|
padding: 1.5rem;
|
|
|
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sidebar-title {
|
|
|
|
|
font-size: 1.5rem;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
margin: 0;
|
|
|
|
|
color: #d4b383;
|
|
|
|
|
font-family: 'Playfair Display', serif;
|
|
|
|
|
font-style: italic;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sidebar-nav {
|
|
|
|
|
flex: 1;
|
|
|
|
|
padding: 1rem 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sidebar-nav ul {
|
|
|
|
|
list-style: none;
|
|
|
|
|
padding: 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 09:08:07 +08:00
|
|
|
.nav-link, .nav-item-parent {
|
2026-01-15 13:51:44 +08:00
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 0.75rem 1.5rem;
|
|
|
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
|
|
|
border-left: 3px solid transparent;
|
|
|
|
|
position: relative;
|
2026-01-16 09:08:07 +08:00
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-item-parent {
|
|
|
|
|
justify-content: space-between;
|
2026-01-15 13:51:44 +08:00
|
|
|
}
|
|
|
|
|
|
2026-01-16 09:08:07 +08:00
|
|
|
.nav-link-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-link:hover, .nav-item-parent:hover {
|
2026-01-15 13:51:44 +08:00
|
|
|
background-color: rgba(212, 179, 131, 0.1);
|
|
|
|
|
color: white;
|
|
|
|
|
border-left-color: rgba(212, 179, 131, 0.3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-link.active {
|
|
|
|
|
background-color: rgba(212, 179, 131, 0.15);
|
|
|
|
|
color: #d4b383;
|
|
|
|
|
border-left-color: #d4b383;
|
|
|
|
|
box-shadow: 0 0 15px rgba(212, 179, 131, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-icon {
|
|
|
|
|
margin-right: 0.75rem;
|
|
|
|
|
font-size: 1.1rem;
|
2026-01-16 09:08:07 +08:00
|
|
|
min-width: 1.5rem;
|
|
|
|
|
text-align: center;
|
2026-01-15 13:51:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-text {
|
|
|
|
|
font-size: 0.95rem;
|
|
|
|
|
font-family: 'Inter', sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 09:08:07 +08:00
|
|
|
.nav-arrow {
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
transition: transform 0.3s ease;
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nav-item-parent.expanded .nav-arrow {
|
|
|
|
|
transform: rotate(180deg);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Submenu Styles */
|
|
|
|
|
.submenu {
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.2);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
transition: max-height 0.3s ease-out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sub-link {
|
|
|
|
|
padding-left: 2.5rem;
|
|
|
|
|
font-size: 0.9rem;
|
|
|
|
|
border-left: 3px solid transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sub-link .nav-icon {
|
|
|
|
|
font-size: 1rem;
|
|
|
|
|
margin-right: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-15 13:51:44 +08:00
|
|
|
.sidebar-footer {
|
|
|
|
|
padding: 1rem;
|
|
|
|
|
border-top: 1px solid rgba(255, 255, 255, 0.03);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.logout-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding: 0.75rem 1.5rem;
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
color: #d4b383;
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 0.375rem;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
|
|
|
font-size: 0.95rem;
|
|
|
|
|
font-family: 'Inter', sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.logout-btn:hover {
|
|
|
|
|
background-color: rgba(212, 179, 131, 0.1);
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
box-shadow: 0 5px 15px rgba(212, 179, 131, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Main Content Styles */
|
|
|
|
|
.admin-main {
|
|
|
|
|
flex: 1;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Header Styles */
|
|
|
|
|
.admin-header {
|
|
|
|
|
background: rgba(5, 5, 5, 0.7);
|
|
|
|
|
backdrop-filter: blur(20px);
|
|
|
|
|
-webkit-backdrop-filter: blur(20px);
|
|
|
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
|
|
|
|
padding: 0 1.5rem;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
height: 60px;
|
|
|
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
|
|
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toggle-btn {
|
|
|
|
|
background: none;
|
|
|
|
|
border: none;
|
|
|
|
|
font-size: 1.5rem;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
padding: 0.5rem;
|
|
|
|
|
border-radius: 0.375rem;
|
|
|
|
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toggle-btn:hover {
|
|
|
|
|
background-color: rgba(212, 179, 131, 0.1);
|
|
|
|
|
color: #d4b383;
|
|
|
|
|
transform: scale(1.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.user-info {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 0.5rem;
|
|
|
|
|
font-size: 0.95rem;
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
font-family: 'Inter', sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.username {
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #d4b383;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.role {
|
|
|
|
|
color: rgba(255, 255, 255, 0.6);
|
|
|
|
|
font-size: 0.85rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Content Area */
|
|
|
|
|
.admin-content {
|
|
|
|
|
flex: 1;
|
|
|
|
|
padding: 1.5rem;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Scrollbar Styles */
|
|
|
|
|
.admin-content::-webkit-scrollbar {
|
|
|
|
|
width: 6px;
|
|
|
|
|
height: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-content::-webkit-scrollbar-track {
|
|
|
|
|
background: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-content::-webkit-scrollbar-thumb {
|
|
|
|
|
background: rgba(255, 255, 255, 0.1);
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-content::-webkit-scrollbar-thumb:hover {
|
|
|
|
|
background: #d4b383;
|
|
|
|
|
box-shadow: 0 0 10px rgba(212, 179, 131, 0.4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-content::-webkit-scrollbar-corner {
|
|
|
|
|
background: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Responsive Design */
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
.admin-sidebar {
|
|
|
|
|
position: fixed;
|
|
|
|
|
left: 0;
|
|
|
|
|
top: 0;
|
|
|
|
|
height: 100vh;
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
transform: translateX(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-sidebar.collapsed {
|
|
|
|
|
transform: translateX(-100%);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-16 09:08:07 +08:00
|
|
|
</style>
|