Skip to content

Commit 4519e17

Browse files
committed
feat: enhance admin components and update terminology for private access
1 parent b3bc0f9 commit 4519e17

16 files changed

Lines changed: 48 additions & 41 deletions

app/components/DarkToggle.vue

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
<script setup lang="ts">
22
const mode = useColorMode()
33
const state = mode.state
4+
const consecutiveClicks = shallowRef(0)
5+
let resetClicksTimer: number | undefined
6+
7+
const SECRET_CLICK_COUNT = 5
8+
const CLICK_SEQUENCE_TIMEOUT_MS = 1_500
49
510
function toggleDark() {
611
mode.value = state.value === 'dark' ? 'light' : 'dark'
12+
13+
consecutiveClicks.value += 1
14+
if (resetClicksTimer) window.clearTimeout(resetClicksTimer)
15+
16+
if (consecutiveClicks.value === SECRET_CLICK_COUNT) {
17+
consecutiveClicks.value = 0
18+
void navigateTo('/admin')
19+
return
20+
}
21+
22+
resetClicksTimer = window.setTimeout(() => {
23+
consecutiveClicks.value = 0
24+
}, CLICK_SEQUENCE_TIMEOUT_MS)
725
}
826
27+
onBeforeUnmount(() => {
28+
if (resetClicksTimer) window.clearTimeout(resetClicksTimer)
29+
})
30+
931
watchEffect(() => {
1032
if (typeof document !== 'undefined') {
1133
document

app/components/admin/AdminLogin.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ function submit() {
1515
<div class="login-copy">
1616
<span class="login-index">PRIVATE / 01</span>
1717
<h1 id="admin-login-title">Site<br />control.</h1>
18-
<p>一个只属于站点维护者的入口。登录后,管理操作会出现在对应内容页面。</p>
18+
<p>一个只属于站点维护者的私密空间。验证后,维护操作会出现在对应内容页面。</p>
1919
</div>
2020

2121
<form class="login-form" @submit.prevent="submit">
2222
<div class="login-form__heading">
2323
<span aria-hidden="true"><i /> SECURE SESSION</span>
24-
<p>使用 NUXT_ADMIN_PASSWORD 继续</p>
24+
<p>验证访问密钥后继续</p>
2525
</div>
2626

27-
<label for="admin-password">管理密码</label>
27+
<label for="admin-password">访问密钥</label>
2828
<div class="login-control">
2929
<input
3030
id="admin-password"
@@ -55,7 +55,7 @@ function submit() {
5555
</p>
5656

5757
<button class="login-submit" type="submit" :disabled="loading || !password">
58-
<span>{{ loading ? '正在验证' : '进入管理模式' }}</span>
58+
<span>{{ loading ? '正在验证' : '进入私密空间' }}</span>
5959
<i class="i-hugeicons:arrow-up-right-01" aria-hidden="true" />
6060
</button>
6161
</form>

app/components/admin/AdminPortal.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ async function handleLogout() {
2727
<section class="portal-shell" aria-labelledby="admin-portal-title">
2828
<header class="portal-header">
2929
<div>
30-
<span class="portal-index">ADMIN / ACTIVE</span>
30+
<span class="portal-index">PRIVATE / ACTIVE</span>
3131
<h1 id="admin-portal-title">Control<br />room.</h1>
3232
</div>
3333
<div class="portal-session">
34-
<span><i aria-hidden="true" /> 管理会话已启用</span>
34+
<span><i aria-hidden="true" /> 私密会话已启用</span>
3535
<button type="button" :disabled="mutating" @click="handleLogout">
36-
{{ mutating ? '正在退出' : '退出登录' }}
36+
{{ mutating ? '正在退出' : '结束会话' }}
3737
</button>
3838
</div>
3939
</header>
@@ -53,7 +53,7 @@ async function handleLogout() {
5353
</div>
5454

5555
<footer class="portal-footer">
56-
<p>登录态同时作用于站点内容页;只有管理员会看到编辑、删除和私密内容控制。</p>
56+
<p>私密会话同时作用于站点内容页;维护工具不会对普通访客显示。</p>
5757
<NuxtLink to="/">返回站点</NuxtLink>
5858
</footer>
5959
</section>

app/components/admin/PhotoAdmin.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ onMounted(() => loadPhotos(1))
6969
</div>
7070
<div class="workspace-status">
7171
<span><i aria-hidden="true" /> D1 + R2 已连接</span>
72-
<NuxtLink to="/admin">管理首页</NuxtLink>
72+
<NuxtLink to="/admin">私密首页</NuxtLink>
7373
</div>
7474
</header>
7575

app/components/bookmarks/BookmarkCollection.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const looseBookmarks = computed(() => props.items.filter((item) => item.kind ===
5050
<i class="i-hugeicons:folder-02" aria-hidden="true" />
5151
<h2>{{ folder.title }}</h2>
5252
<span>{{ folder.children.length }}</span>
53-
<span v-if="isAdmin && folder.private" class="collection__private" title="仅管理员可见">
53+
<span v-if="isAdmin && folder.private" class="collection__private" title="仅维护者可见">
5454
<i class="i-hugeicons:square-lock-02" aria-hidden="true" /> 私密
5555
</span>
5656
</div>

app/components/bookmarks/BookmarkEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ function submit() {
164164
<label class="editor__visibility">
165165
<input v-model="form.private" type="checkbox" />
166166
<span>
167-
<strong>仅管理员可见</strong>
167+
<strong>仅维护者可见</strong>
168168
<small>访客看不到此项目;私密文件夹也会隐藏其内容。</small>
169169
</span>
170170
</label>

app/components/bookmarks/BookmarkItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const host = computed(() => bookmarkHost(props.item.url))
4343
<span v-for="tag in item.tags.slice(0, 3)" :key="tag">{{ tag }}</span>
4444
</div>
4545

46-
<span v-if="isAdmin && item.private" class="bookmark-item__private" title="仅管理员可见">
46+
<span v-if="isAdmin && item.private" class="bookmark-item__private" title="仅维护者可见">
4747
<i class="i-hugeicons:square-lock-02" aria-hidden="true" />
4848
<span>私密</span>
4949
</span>

app/components/bookmarks/BookmarksPage.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ onMounted(loadBookmarks)
135135
</p>
136136

137137
<div v-if="isAdmin" class="admin-notice">
138-
<span><i class="i-hugeicons:square-lock-02" aria-hidden="true" /> 管理模式</span>
139-
<p>你已登录,可以直接维护这页的公开与私密书签。</p>
138+
<span><i class="i-hugeicons:square-lock-02" aria-hidden="true" /> 私密模式</span>
139+
<p>私密会话已启用,可以直接维护这页的公开与私密书签。</p>
140140
</div>
141141

142142
<BookmarkToolbar

app/components/icons/IconsUnoCSS.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from-unocss-from
2020
via-unocss-via
2121
to-unocss-to
22-
>admin</sub
22+
>lab</sub
2323
>
2424
</a>
2525
</div>

app/components/nav/NavHeader.vue

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<script setup lang="ts">
22
const route = useRoute()
3-
const { authenticated } = useAdminSession()
43
5-
const publicNavigation = [
4+
const navigation = [
65
{ label: 'Home', to: '/', icon: null },
76
{ label: 'Photos', to: '/photos', icon: 'i-hugeicons:image-03' },
87
{ label: 'Projects', to: '/projects', icon: 'i-hugeicons:package-search' },
@@ -11,15 +10,6 @@ const publicNavigation = [
1110
{ label: 'About', to: '/about', icon: 'i-hugeicons:user-circle' },
1211
] as const
1312
14-
const navigation = computed(() => [
15-
...publicNavigation,
16-
{
17-
label: authenticated.value ? 'Admin' : 'Login',
18-
to: '/admin',
19-
icon: authenticated.value ? 'i-hugeicons:dashboard-square-01' : 'i-hugeicons:square-lock-02',
20-
},
21-
])
22-
2313
const isHome = computed(() => route.path === '/')
2414
const { mode: photosViewMode, togglePhotosView } = usePhotosViewMode()
2515
@@ -90,11 +80,6 @@ function isActive(path: string) {
9080
<MeAvatar v-else-if="item.to === '/'" navigation shared />
9181
<i v-else class="color-inherit" :class="item.icon" aria-hidden="true" />
9282
<span v-if="!isHome" class="sr-only">{{ item.label }}</span>
93-
<span
94-
v-if="authenticated && item.to === '/admin'"
95-
class="absolute right-[0.32rem] top-[0.32rem] size-[0.3rem] rounded-full bg-[#568c68]"
96-
aria-hidden="true"
97-
/>
9883
</NuxtLink>
9984
</template>
10085
</div>

0 commit comments

Comments
 (0)