810 lines
18 KiB
Vue
810 lines
18 KiB
Vue
<template>
|
|
<header class="app-header" :class="headerClasses">
|
|
<!-- 移动端汉堡菜单按钮 -->
|
|
<button
|
|
v-if="isMobile"
|
|
class="mobile-menu-button"
|
|
@click="$emit('toggle-sidebar')"
|
|
:aria-label="t('header.toggleSidebar')"
|
|
>
|
|
<MenuIcon :class="{ 'icon-active': sidebarVisible }" />
|
|
</button>
|
|
<!-- 品牌标识区域 -->
|
|
<div class="brand-section">
|
|
<router-link to="/" class="brand-link">
|
|
<div class="brand-logo">
|
|
<div class="logo-icon">
|
|
<img src="@/assets/logo.png" alt="Logo" class="logo-image" />
|
|
</div>
|
|
<span class="brand-name">{{ t('app.title') }}</span>
|
|
</div>
|
|
</router-link>
|
|
</div>
|
|
<!-- 功能区域 -->
|
|
<div class="actions-section">
|
|
<!-- 移动端隐藏的操作按钮 -->
|
|
<div class="header-actions" v-if="!isMobile">
|
|
<!-- 搜索按钮 -->
|
|
<!-- <button
|
|
class="action-button search-button"
|
|
@click="toggleSearch"
|
|
:aria-label="t('header.search')"
|
|
>
|
|
<SearchIcon />
|
|
</button> -->
|
|
<!-- 通知按钮 -->
|
|
<!-- <button
|
|
class="action-button notification-button"
|
|
:aria-label="t('header.notifications')"
|
|
@click="toggleNotifications"
|
|
>
|
|
<NotificationIcon />
|
|
<span v-if="notificationCount > 0" class="notification-badge">
|
|
{{ notificationCount }}
|
|
</span>
|
|
</button> -->
|
|
<!-- 用户菜单 -->
|
|
<div class="user-menu" v-if="currentUser">
|
|
<el-dropdown trigger="click" @command="handleUserCommand">
|
|
<div class="user-avatar">
|
|
<el-avatar :size="32" :src="currentUser.avatarUrl">
|
|
<el-icon><UserIcon /></el-icon>
|
|
</el-avatar>
|
|
<span class="user-name">{{ currentUser.nickname || currentUser.email }}</span>
|
|
<ChevronDownIcon class="dropdown-icon" />
|
|
</div>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<!-- <el-dropdown-item command="profile">
|
|
<UserIcon class="dropdown-item-icon" />
|
|
{{ t('header.profile') }}
|
|
</el-dropdown-item>
|
|
<el-dropdown-item command="settings">
|
|
{{ t('header.settings') }}
|
|
</el-dropdown-item> -->
|
|
<el-dropdown-item divided command="logout">
|
|
<LogoutIcon class="dropdown-item-icon" />
|
|
{{ t('header.logout') }}
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 主题切换 -->
|
|
<ThemeToggle />
|
|
|
|
<!-- 语言切换 -->
|
|
<LanguageToggle />
|
|
|
|
<!-- 移动端用户操作 -->
|
|
<div v-if="isMobile && currentUser" class="mobile-user-menu">
|
|
<el-dropdown trigger="click" @command="handleUserCommand">
|
|
<el-avatar :size="32" :src="currentUser.avatarUrl" class="mobile-avatar">
|
|
<el-icon><UserIcon /></el-icon>
|
|
</el-avatar>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="profile">
|
|
<UserIcon class="dropdown-item-icon" />
|
|
{{ t('header.profile') }}
|
|
</el-dropdown-item>
|
|
<el-dropdown-item command="settings">
|
|
{{ t('header.settings') }}
|
|
</el-dropdown-item>
|
|
<el-dropdown-item divided command="logout">
|
|
{{ t('header.logout') }}
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 搜索下拉框 -->
|
|
<div v-if="searchVisible" class="search-dropdown" @click.stop>
|
|
<div class="search-input-container">
|
|
<SearchIcon class="search-icon" />
|
|
<input
|
|
ref="searchInput"
|
|
v-model="searchQuery"
|
|
type="text"
|
|
:placeholder="t('header.searchPlaceholder')"
|
|
class="search-input"
|
|
@keyup.enter="performSearch"
|
|
@keyup.esc="closeSearch"
|
|
/>
|
|
<button v-if="searchQuery" @click="clearSearch" class="clear-search-button">
|
|
<XIcon />
|
|
</button>
|
|
</div>
|
|
<div class="search-suggestions" v-if="searchSuggestions.length > 0">
|
|
<div
|
|
v-for="suggestion in searchSuggestions"
|
|
:key="suggestion.id"
|
|
class="search-suggestion"
|
|
@click="selectSuggestion(suggestion)"
|
|
>
|
|
<component :is="suggestion.icon" class="suggestion-icon" />
|
|
<span class="suggestion-text">{{ suggestion.text }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 通知面板 -->
|
|
<div v-if="notificationsVisible" class="notifications-panel" @click.stop>
|
|
<div class="notifications-header">
|
|
<h3>{{ t('header.notifications') }}</h3>
|
|
<button @click="markAllAsRead" class="mark-all-read">
|
|
{{ t('header.markAllRead') }}
|
|
</button>
|
|
</div>
|
|
<div class="notifications-list">
|
|
<div
|
|
v-for="notification in notifications"
|
|
:key="notification.id"
|
|
:class="['notification-item', { 'unread': !notification.read }]"
|
|
@click="markAsRead(notification.id)"
|
|
>
|
|
<div class="notification-icon">
|
|
<component :is="notification.icon" />
|
|
</div>
|
|
<div class="notification-content">
|
|
<p class="notification-text">{{ notification.text }}</p>
|
|
<span class="notification-time">{{ formatTime(notification.time) }}</span>
|
|
</div>
|
|
</div>
|
|
<div v-if="notifications.length === 0" class="no-notifications">
|
|
{{ t('header.noNotifications') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import ThemeToggle from '@/components/ui/ThemeToggle.vue'
|
|
import LanguageToggle from '@/components/ui/LanguageToggle.vue'
|
|
|
|
// 图标组件
|
|
import {
|
|
Menu as MenuIcon,
|
|
Search as SearchIcon,
|
|
Bell as NotificationIcon,
|
|
User as UserIcon,
|
|
Right as LogoutIcon,
|
|
ArrowDown as ChevronDownIcon,
|
|
Close as XIcon,
|
|
Cpu as BrainIcon
|
|
} from '@element-plus/icons-vue'
|
|
|
|
export default {
|
|
name: 'AppHeader',
|
|
components: {
|
|
ThemeToggle,
|
|
LanguageToggle,
|
|
MenuIcon,
|
|
SearchIcon,
|
|
NotificationIcon,
|
|
UserIcon,
|
|
LogoutIcon,
|
|
ChevronDownIcon,
|
|
XIcon,
|
|
BrainIcon
|
|
},
|
|
props: {
|
|
sidebarVisible: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
emits: ['toggle-sidebar'],
|
|
setup(props, { emit }) {
|
|
const { t } = useI18n()
|
|
const router = useRouter()
|
|
const authStore = useAuthStore()
|
|
|
|
// 响应式状态
|
|
const isMobile = ref(window.innerWidth < 768)
|
|
const searchVisible = ref(false)
|
|
const notificationsVisible = ref(false)
|
|
const searchQuery = ref('')
|
|
const searchInput = ref(null)
|
|
|
|
// 计算属性
|
|
const currentUser = computed(() => authStore.user)
|
|
const notificationCount = ref(3) // 模拟通知数量
|
|
|
|
const headerClasses = computed(() => ({
|
|
'mobile-header': isMobile.value,
|
|
'desktop-header': !isMobile.value
|
|
}))
|
|
|
|
// 模拟搜索建议
|
|
const searchSuggestions = ref([
|
|
{ id: 1, text: 'Dashboard', icon: 'UserIcon' },
|
|
{ id: 2, text: 'Projects', icon: 'UserIcon' },
|
|
{ id: 3, text: 'Settings', icon: 'UserIcon' }
|
|
])
|
|
|
|
// 模拟通知数据
|
|
const notifications = ref([
|
|
{
|
|
id: 1,
|
|
text: '新项目已创建完成',
|
|
time: new Date(),
|
|
icon: 'UserIcon',
|
|
read: false
|
|
},
|
|
{
|
|
id: 2,
|
|
text: '您的作品获得了新的点赞',
|
|
time: new Date(Date.now() - 1000 * 60 * 30),
|
|
icon: 'UserIcon',
|
|
read: false
|
|
}
|
|
])
|
|
|
|
// 窗口大小变化处理
|
|
const handleResize = () => {
|
|
isMobile.value = window.innerWidth < 768
|
|
}
|
|
|
|
// 切换搜索
|
|
const toggleSearch = async () => {
|
|
searchVisible.value = !searchVisible.value
|
|
if (searchVisible.value) {
|
|
await nextTick()
|
|
searchInput.value?.focus()
|
|
}
|
|
}
|
|
|
|
const closeSearch = () => {
|
|
searchVisible.value = false
|
|
searchQuery.value = ''
|
|
}
|
|
|
|
const clearSearch = () => {
|
|
searchQuery.value = ''
|
|
searchInput.value?.focus()
|
|
}
|
|
|
|
// 搜索操作
|
|
const performSearch = () => {
|
|
if (searchQuery.value.trim()) {
|
|
console.log('搜索:', searchQuery.value)
|
|
router.push(`/search?q=${encodeURIComponent(searchQuery.value)}`)
|
|
closeSearch()
|
|
}
|
|
}
|
|
|
|
const selectSuggestion = (suggestion) => {
|
|
searchQuery.value = suggestion.text
|
|
performSearch()
|
|
}
|
|
|
|
// 通知操作
|
|
const toggleNotifications = () => {
|
|
notificationsVisible.value = !notificationsVisible.value
|
|
}
|
|
|
|
const markAsRead = (id) => {
|
|
const notification = notifications.value.find(n => n.id === id)
|
|
if (notification) {
|
|
notification.read = true
|
|
notificationCount.value = Math.max(0, notificationCount.value - 1)
|
|
}
|
|
}
|
|
|
|
const markAllAsRead = () => {
|
|
notifications.value.forEach(n => n.read = true)
|
|
notificationCount.value = 0
|
|
}
|
|
|
|
// 用户菜单操作
|
|
const handleUserCommand = async (command) => {
|
|
switch (command) {
|
|
case 'profile':
|
|
router.push('/profile')
|
|
break
|
|
case 'settings':
|
|
router.push('/settings')
|
|
break
|
|
case 'logout':
|
|
try {
|
|
await authStore.logout(()=>{
|
|
router.push('/login')
|
|
})
|
|
} catch (error) {
|
|
console.error('登出失败:', error)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
// 时间格式化
|
|
const formatTime = (time) => {
|
|
const now = new Date()
|
|
const diff = now - time
|
|
const minutes = Math.floor(diff / (1000 * 60))
|
|
const hours = Math.floor(diff / (1000 * 60 * 60))
|
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24))
|
|
|
|
if (minutes < 1) return '刚刚'
|
|
if (minutes < 60) return `${minutes}分钟前`
|
|
if (hours < 24) return `${hours}小时前`
|
|
return `${days}天前`
|
|
}
|
|
|
|
// 点击外部关闭下拉菜单
|
|
const handleClickOutside = (event) => {
|
|
if (!event.target.closest('.app-header')) {
|
|
searchVisible.value = false
|
|
notificationsVisible.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
window.addEventListener('resize', handleResize)
|
|
document.addEventListener('click', handleClickOutside)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', handleResize)
|
|
document.removeEventListener('click', handleClickOutside)
|
|
})
|
|
|
|
return {
|
|
t,
|
|
isMobile,
|
|
searchVisible,
|
|
notificationsVisible,
|
|
searchQuery,
|
|
searchInput,
|
|
searchSuggestions,
|
|
notifications,
|
|
notificationCount,
|
|
currentUser,
|
|
headerClasses,
|
|
toggleSearch,
|
|
closeSearch,
|
|
clearSearch,
|
|
performSearch,
|
|
selectSuggestion,
|
|
toggleNotifications,
|
|
markAsRead,
|
|
markAllAsRead,
|
|
handleUserCommand,
|
|
formatTime
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.app-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
height: 64px;
|
|
padding: 0 24px;
|
|
background: var(--header-bg, #ffffff);
|
|
border-bottom: 1px solid var(--border-color, #e5e7eb);
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
|
|
position: relative;
|
|
z-index: 200;
|
|
}
|
|
|
|
/* 移动端汉堡菜单按钮 */
|
|
.mobile-menu-button {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 40px;
|
|
height: 40px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-primary, #1f2937);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.mobile-menu-button:hover {
|
|
background: var(--hover-bg, #f3f4f6);
|
|
}
|
|
|
|
.mobile-menu-button .icon-active {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
/* 品牌标识区域 */
|
|
.brand-section {
|
|
flex: 1;
|
|
}
|
|
|
|
.brand-link {
|
|
display: flex;
|
|
align-items: center;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
}
|
|
|
|
.brand-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.logo-icon {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: white;
|
|
box-shadow: 0 4px 12px rgba(167, 139, 250, 0.4);
|
|
}
|
|
|
|
.logo-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.brand-name {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
background: linear-gradient(135deg, #6B46C1 0%, #A78BFA 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
letter-spacing: -0.025em;
|
|
}
|
|
|
|
/* 功能区域 */
|
|
.actions-section {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
}
|
|
|
|
.header-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
/* 操作按钮 */
|
|
.action-button {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 40px;
|
|
height: 40px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-secondary, #6b7280);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.action-button:hover {
|
|
background: var(--hover-bg, #f3f4f6);
|
|
color: var(--text-primary, #1f2937);
|
|
}
|
|
|
|
/* 通知徽章 */
|
|
.notification-badge {
|
|
position: absolute;
|
|
top: 6px;
|
|
right: 6px;
|
|
min-width: 16px;
|
|
height: 16px;
|
|
background: #ef4444;
|
|
color: white;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
line-height: 1;
|
|
}
|
|
|
|
/* 用户菜单 */
|
|
.user-menu {
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.user-avatar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 4px 8px;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.user-avatar:hover {
|
|
background: var(--hover-bg, #f3f4f6);
|
|
}
|
|
|
|
.user-name {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text-primary, #1f2937);
|
|
max-width: 100px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.dropdown-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
color: var(--text-secondary, #6b7280);
|
|
}
|
|
|
|
/* 移动端用户菜单 */
|
|
.mobile-user-menu {
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.mobile-avatar {
|
|
cursor: pointer;
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
.mobile-avatar:hover {
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
/* 下拉菜单图标 */
|
|
.dropdown-item-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
margin-right: 8px;
|
|
}
|
|
|
|
/* 搜索下拉框 */
|
|
.search-dropdown {
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 24px;
|
|
right: 24px;
|
|
background: var(--header-bg, #ffffff);
|
|
border: 1px solid var(--border-color, #e5e7eb);
|
|
border-radius: 12px;
|
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
|
padding: 16px;
|
|
margin-top: 8px;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.search-input-container {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.search-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
color: var(--text-secondary, #6b7280);
|
|
}
|
|
|
|
.search-input {
|
|
flex: 1;
|
|
border: none;
|
|
outline: none;
|
|
font-size: 14px;
|
|
color: var(--text-primary, #1f2937);
|
|
background: transparent;
|
|
}
|
|
|
|
.clear-search-button {
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-secondary, #6b7280);
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
border-radius: 4px;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.clear-search-button:hover {
|
|
background: var(--hover-bg, #f3f4f6);
|
|
}
|
|
|
|
/* 搜索建议 */
|
|
.search-suggestions {
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.search-suggestion {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 8px 12px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.search-suggestion:hover {
|
|
background: var(--hover-bg, #f3f4f6);
|
|
}
|
|
|
|
.suggestion-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
color: var(--text-secondary, #6b7280);
|
|
}
|
|
|
|
.suggestion-text {
|
|
font-size: 14px;
|
|
color: var(--text-primary, #1f2937);
|
|
}
|
|
|
|
/* 通知面板 */
|
|
.notifications-panel {
|
|
position: absolute;
|
|
top: 100%;
|
|
right: 24px;
|
|
width: 320px;
|
|
background: var(--header-bg, #ffffff);
|
|
border: 1px solid var(--border-color, #e5e7eb);
|
|
border-radius: 12px;
|
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
|
margin-top: 8px;
|
|
z-index: 1000;
|
|
max-height: 400px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.notifications-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 16px;
|
|
border-bottom: 1px solid var(--border-color, #e5e7eb);
|
|
}
|
|
|
|
.notifications-header h3 {
|
|
margin: 0;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: var(--text-primary, #1f2937);
|
|
}
|
|
|
|
.mark-all-read {
|
|
font-size: 12px;
|
|
color: #6B46C1;
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
.mark-all-read:hover {
|
|
background: rgba(107, 70, 193, 0.1);
|
|
}
|
|
|
|
.notifications-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.notification-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 12px;
|
|
padding: 12px 16px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease;
|
|
border-bottom: 1px solid var(--border-color, #e5e7eb);
|
|
}
|
|
|
|
.notification-item:hover {
|
|
background: var(--hover-bg, #f3f4f6);
|
|
}
|
|
|
|
.notification-item.unread {
|
|
background: rgba(107, 70, 193, 0.05);
|
|
}
|
|
|
|
.notification-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.notification-icon {
|
|
width: 32px;
|
|
height: 32px;
|
|
background: linear-gradient(135deg, #7C3AED, #6B46C1);
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: white;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.notification-content {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.notification-text {
|
|
margin: 0 0 4px 0;
|
|
font-size: 14px;
|
|
color: var(--text-primary, #1f2937);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.notification-time {
|
|
font-size: 12px;
|
|
color: var(--text-secondary, #6b7280);
|
|
}
|
|
|
|
.no-notifications {
|
|
padding: 24px;
|
|
text-align: center;
|
|
color: var(--text-secondary, #6b7280);
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* 移动端样式 */
|
|
@media (max-width: 767px) {
|
|
.app-header {
|
|
padding: 0 16px;
|
|
}
|
|
|
|
.brand-name {
|
|
display: none;
|
|
}
|
|
|
|
.header-actions {
|
|
display: none;
|
|
}
|
|
|
|
.search-dropdown {
|
|
left: 16px;
|
|
right: 16px;
|
|
}
|
|
|
|
.notifications-panel {
|
|
left: 16px;
|
|
right: 16px;
|
|
width: auto;
|
|
}
|
|
}
|
|
|
|
/* 深色主题 */
|
|
.dark .app-header {
|
|
--header-bg: #1f2937;
|
|
--text-primary: #f9fafb;
|
|
--text-secondary: #d1d5db;
|
|
--border-color: #374151;
|
|
--hover-bg: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.dark .logo-icon {
|
|
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.4);
|
|
}
|
|
</style> |