|
|
@ -29,16 +29,78 @@ async function handleLogout() { |
|
|
<template> |
|
|
<template> |
|
|
<div> |
|
|
<div> |
|
|
<header class="app-header"> |
|
|
<header class="app-header"> |
|
|
<router-link to="/" class="brand">Mach-CMS</router-link> |
|
|
|
|
|
|
|
|
<router-link to="/" class="brand" aria-label="Mach-CMS 首页"> |
|
|
|
|
|
<svg class="brand-logo" viewBox="0 0 116 30" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Mach"> |
|
|
|
|
|
<defs> |
|
|
|
|
|
<filter id="brand-glow" x="-40%" y="-80%" width="180%" height="260%"> |
|
|
|
|
|
<feGaussianBlur stdDeviation="1.6" result="blur" /> |
|
|
|
|
|
<feMerge> |
|
|
|
|
|
<feMergeNode in="blur" /> |
|
|
|
|
|
<feMergeNode in="blur" /> |
|
|
|
|
|
<feMergeNode in="SourceGraphic" /> |
|
|
|
|
|
</feMerge> |
|
|
|
|
|
</filter> |
|
|
|
|
|
</defs> |
|
|
|
|
|
<text |
|
|
|
|
|
x="1" y="24" |
|
|
|
|
|
fill="#ffffff" |
|
|
|
|
|
font-family="'Noto Sans SC','Source Code Pro',monospace" |
|
|
|
|
|
font-size="21" |
|
|
|
|
|
font-weight="700" |
|
|
|
|
|
letter-spacing="5" |
|
|
|
|
|
filter="url(#brand-glow)" |
|
|
|
|
|
>Mach</text> |
|
|
|
|
|
<line x1="2" y1="28" x2="100" y2="28" stroke="#7ff0ff" stroke-width="1.2" opacity="0.9" stroke-linecap="round" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
</router-link> |
|
|
<span v-if="pageTitle" class="header-page-title"><span class="header-title-sep">×</span>{{ pageTitle }}</span> |
|
|
<span v-if="pageTitle" class="header-page-title"><span class="header-title-sep">×</span>{{ pageTitle }}</span> |
|
|
<nav class="nav-links"> |
|
|
<nav class="nav-links"> |
|
|
<router-link to="/">首页</router-link> |
|
|
|
|
|
<router-link to="/search">搜索</router-link> |
|
|
|
|
|
<router-link v-if="auth.isLoggedIn" to="/admin">管理后台</router-link> |
|
|
|
|
|
<router-link v-if="auth.isAdmin" to="/admin/comments">评论审核</router-link> |
|
|
|
|
|
|
|
|
<router-link to="/" title="首页"> |
|
|
|
|
|
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
|
|
|
|
|
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /> |
|
|
|
|
|
<polyline points="9 22 9 12 15 12 15 22" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
<span class="nav-text">首页</span> |
|
|
|
|
|
</router-link> |
|
|
|
|
|
<router-link to="/search" title="搜索"> |
|
|
|
|
|
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
|
|
|
|
|
<circle cx="11" cy="11" r="7" /> |
|
|
|
|
|
<line x1="21" y1="21" x2="16.65" y2="16.65" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
<span class="nav-text">搜索</span> |
|
|
|
|
|
</router-link> |
|
|
|
|
|
<router-link v-if="auth.isLoggedIn" to="/admin" title="管理后台"> |
|
|
|
|
|
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
|
|
|
|
|
<rect x="3" y="3" width="7" height="7" /> |
|
|
|
|
|
<rect x="14" y="3" width="7" height="7" /> |
|
|
|
|
|
<rect x="14" y="14" width="7" height="7" /> |
|
|
|
|
|
<rect x="3" y="14" width="7" height="7" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
<span class="nav-text">管理后台</span> |
|
|
|
|
|
</router-link> |
|
|
|
|
|
<router-link v-if="auth.isAdmin" to="/admin/comments" title="评论审核"> |
|
|
|
|
|
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
|
|
|
|
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
<span class="nav-text">评论审核</span> |
|
|
|
|
|
</router-link> |
|
|
<span v-if="auth.username" class="username">{{ auth.username }}</span> |
|
|
<span v-if="auth.username" class="username">{{ auth.username }}</span> |
|
|
<a v-if="auth.isLoggedIn" href="#" @click.prevent="handleLogout">退出</a> |
|
|
|
|
|
<router-link v-else to="/login">登录</router-link> |
|
|
|
|
|
|
|
|
<a v-if="auth.isLoggedIn" href="#" title="退出" @click.prevent="handleLogout"> |
|
|
|
|
|
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
|
|
|
|
|
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /> |
|
|
|
|
|
<polyline points="16 17 21 12 16 7" /> |
|
|
|
|
|
<line x1="21" y1="12" x2="9" y2="12" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
<span class="nav-text">退出</span> |
|
|
|
|
|
</a> |
|
|
|
|
|
<router-link v-else to="/login" title="登录"> |
|
|
|
|
|
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> |
|
|
|
|
|
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" /> |
|
|
|
|
|
<polyline points="10 17 15 12 10 7" /> |
|
|
|
|
|
<line x1="15" y1="12" x2="3" y2="12" /> |
|
|
|
|
|
</svg> |
|
|
|
|
|
<span class="nav-text">登录</span> |
|
|
|
|
|
</router-link> |
|
|
</nav> |
|
|
</nav> |
|
|
<button |
|
|
<button |
|
|
class="theme-toggle" |
|
|
class="theme-toggle" |
|
|
@ -99,14 +161,16 @@ async function handleLogout() { |
|
|
display: flex; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
color: var(--ac-header-text); |
|
|
|
|
|
font-family: var(--song-font-display); |
|
|
|
|
|
font-size: 18px; |
|
|
|
|
|
font-weight: 400; |
|
|
|
|
|
letter-spacing: 0.06em; |
|
|
|
|
|
|
|
|
flex-shrink: 0; |
|
|
text-decoration: none; |
|
|
text-decoration: none; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.brand-logo { |
|
|
|
|
|
display: block; |
|
|
|
|
|
width: auto; |
|
|
|
|
|
height: 30px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
.nav-links { |
|
|
.nav-links { |
|
|
display: flex; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
@ -125,11 +189,22 @@ async function handleLogout() { |
|
|
.nav-links a { |
|
|
.nav-links a { |
|
|
display: inline-flex; |
|
|
display: inline-flex; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
|
|
|
gap: 5px; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
padding: 0 12px; |
|
|
padding: 0 12px; |
|
|
color: var(--ac-header-muted); |
|
|
color: var(--ac-header-muted); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.nav-icon { |
|
|
|
|
|
width: 16px; |
|
|
|
|
|
height: 16px; |
|
|
|
|
|
flex-shrink: 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.nav-text { |
|
|
|
|
|
font-size: 14px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
.nav-links a:hover { |
|
|
.nav-links a:hover { |
|
|
color: var(--ac-header-text); |
|
|
color: var(--ac-header-text); |
|
|
} |
|
|
} |
|
|
@ -166,8 +241,8 @@ async function handleLogout() { |
|
|
|
|
|
|
|
|
@media (max-width: 640px) { |
|
|
@media (max-width: 640px) { |
|
|
.app-header { |
|
|
.app-header { |
|
|
padding: 0 12px; |
|
|
|
|
|
gap: 10px; |
|
|
|
|
|
|
|
|
padding: 0 10px; |
|
|
|
|
|
gap: 8px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.header-page-title { |
|
|
.header-page-title { |
|
|
@ -187,8 +262,16 @@ async function handleLogout() { |
|
|
|
|
|
|
|
|
.nav-links a { |
|
|
.nav-links a { |
|
|
padding: 0 10px; |
|
|
padding: 0 10px; |
|
|
|
|
|
gap: 0; |
|
|
|
|
|
min-width: 38px; |
|
|
|
|
|
justify-content: center; |
|
|
white-space: nowrap; |
|
|
white-space: nowrap; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.nav-text, |
|
|
|
|
|
.nav-links .username { |
|
|
|
|
|
display: none; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.app-main { |
|
|
.app-main { |
|
|
|