feat: add admin console and account settings
Implement the admin dashboard with review, user, and image management workflows. Add profile settings, password reset, pending upload defaults, community placeholder routing, Vercel SPA rewrites, refreshed header styling, and the OpenCloud color-system skill.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import { NButton, NSpace, NTag } from 'naive-ui'
|
||||
import { NButton, NSpace } from 'naive-ui'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { RouterLink, useRoute } from 'vue-router'
|
||||
|
||||
@@ -10,6 +10,8 @@ const isMapRoute = computed(() => route.name === 'map')
|
||||
|
||||
const headerHidden = ref(false)
|
||||
const headerPinnedOpen = ref(false)
|
||||
const activeNavClass = 'bg-teal-100 text-teal-800 ring-1 ring-teal-200'
|
||||
const inactiveNavClass = 'text-slate-600 hover:bg-teal-50 hover:text-teal-800'
|
||||
|
||||
let lastScrollY = 0
|
||||
const HIDE_HEADER_EVENT = 'opencloud:hide-header'
|
||||
@@ -111,24 +113,31 @@ onMounted(() => {
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'map' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'map' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
地图
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/encyclopedia"
|
||||
to="/community"
|
||||
class="px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'encyclopedia' || route.name === 'cloud-type' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'community' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
图鉴
|
||||
社区
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/gallery"
|
||||
class="px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'gallery' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'gallery' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
画廊
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/encyclopedia"
|
||||
class="px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'encyclopedia' || route.name === 'cloud-type' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
图鉴
|
||||
</RouterLink>
|
||||
</nav>
|
||||
|
||||
<NSpace align="center" :size="8" class="shrink-0 md:[&_.n-button]:px-4">
|
||||
@@ -137,9 +146,12 @@ onMounted(() => {
|
||||
to="/upload"
|
||||
class="no-underline"
|
||||
>
|
||||
<NButton type="primary" strong size="small" class="md:!h-10 md:!px-4 md:!text-sm">
|
||||
<span
|
||||
class="inline-flex h-8 items-center border border-sky-200 bg-sky-100 px-3 text-sm font-medium uppercase tracking-[0.12em] text-sky-800 shadow-[4px_4px_0_0_rgba(14,165,233,0.14)] transition-colors hover:bg-sky-50 hover:text-sky-900 md:h-10 md:px-4"
|
||||
:class="route.name === 'upload' ? 'ring-1 ring-sky-300' : ''"
|
||||
>
|
||||
上传
|
||||
</NButton>
|
||||
</span>
|
||||
</RouterLink>
|
||||
|
||||
<template v-if="authStore.isLoggedIn">
|
||||
@@ -147,9 +159,12 @@ onMounted(() => {
|
||||
to="/profile"
|
||||
class="no-underline"
|
||||
>
|
||||
<NTag type="success" bordered size="small" class="max-w-[7rem] truncate md:max-w-none">
|
||||
{{ authStore.profile?.username }}
|
||||
</NTag>
|
||||
<span
|
||||
class="inline-flex h-8 max-w-[7.5rem] items-center border border-teal-100 bg-white/80 px-3 text-sm font-medium text-teal-800 shadow-[3px_3px_0_0_rgba(20,184,166,0.08)] transition-colors hover:border-teal-200 hover:bg-teal-50 md:h-10 md:max-w-none"
|
||||
:class="route.name === 'profile' || route.name === 'profile-settings' ? 'bg-teal-50 ring-1 ring-teal-200' : ''"
|
||||
>
|
||||
<span class="truncate">@{{ authStore.profile?.username }}</span>
|
||||
</span>
|
||||
</RouterLink>
|
||||
<NButton
|
||||
quaternary
|
||||
@@ -182,29 +197,36 @@ onMounted(() => {
|
||||
<RouterLink
|
||||
to="/"
|
||||
class="shrink-0 px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'map' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'map' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
地图
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/encyclopedia"
|
||||
to="/community"
|
||||
class="shrink-0 px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'encyclopedia' || route.name === 'cloud-type' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'community' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
图鉴
|
||||
社区
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/gallery"
|
||||
class="shrink-0 px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'gallery' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'gallery' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
画廊
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/encyclopedia"
|
||||
class="shrink-0 px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'encyclopedia' || route.name === 'cloud-type' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
图鉴
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
v-if="authStore.isLoggedIn"
|
||||
to="/profile"
|
||||
class="shrink-0 px-3 py-2 text-sm font-medium tracking-[0.12em] uppercase transition-colors"
|
||||
:class="route.name === 'profile' ? 'bg-slate-900 text-white' : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900'"
|
||||
:class="route.name === 'profile' ? activeNavClass : inactiveNavClass"
|
||||
>
|
||||
主页
|
||||
</RouterLink>
|
||||
|
||||
Reference in New Issue
Block a user