Files
quyun-v2/frontend/portal/src/components/TopNavbar.vue

193 lines
6.3 KiB
Vue

<script setup>
import { ref, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { tenantPath } from "../utils/tenant";
const isLoggedIn = ref(false);
const user = ref({});
const router = useRouter();
const route = useRoute();
const tenantRoute = (path) => tenantPath(path, route);
const checkAuth = () => {
const token = localStorage.getItem("token");
const userStr = localStorage.getItem("user");
if (token && userStr) {
isLoggedIn.value = true;
try {
user.value = JSON.parse(userStr);
} catch (e) {
isLoggedIn.value = false;
}
} else {
isLoggedIn.value = false;
}
};
onMounted(() => {
checkAuth();
});
const logout = () => {
localStorage.removeItem("token");
localStorage.removeItem("user");
isLoggedIn.value = false;
user.value = {};
router.push(tenantRoute("/"));
};
</script>
<template>
<nav
class="fixed top-0 w-full z-50 bg-surface border-b border-line h-16 text-content"
>
<div
class="mx-auto max-w-screen-xl h-full flex items-center justify-between"
>
<!-- Left: Logo -->
<router-link :to="tenantRoute('/')" class="flex items-center gap-2">
<div
class="w-8 h-8 bg-primary-600 rounded-lg flex items-center justify-center text-white font-bold text-xl"
>
Q
</div>
<span class="text-xl font-bold text-content hidden sm:block"
>Quyun</span
>
</router-link>
<!-- Center-Left: Nav Links (Desktop) -->
<div class="hidden md:flex items-center space-x-8">
<router-link
:to="tenantRoute('/')"
class="text-muted font-medium hover:text-primary-600"
active-class="text-primary-600"
>首页</router-link
>
<router-link
:to="tenantRoute('/explore')"
class="text-muted font-medium hover:text-primary-600"
active-class="text-primary-600"
>发现</router-link
>
<router-link
:to="tenantRoute('/topics')"
class="text-muted font-medium hover:text-primary-600"
active-class="text-primary-600"
>专题</router-link
>
<router-link
:to="tenantRoute('/channel')"
class="text-muted font-medium hover:text-primary-600"
active-class="text-primary-600"
>频道</router-link
>
</div>
<!-- Center-Right: Global Search -->
<div class="hidden sm:flex flex-1 max-w-md mx-8">
<div class="relative w-full">
<i
class="pi pi-search absolute left-3 top-1/2 -translate-y-1/2 text-muted"
></i>
<input
type="text"
placeholder="搜索感兴趣的内容..."
class="w-full h-10 pl-10 pr-4 rounded-full bg-surface-highlight border border-transparent focus:border-primary-300 focus:bg-surface focus:ring-2 focus:ring-primary-100 text-sm transition-all text-content placeholder:text-muted"
/>
</div>
</div>
<!-- Right: User Actions -->
<div class="flex items-center gap-4">
<template v-if="isLoggedIn">
<!-- Notification -->
<router-link
:to="tenantRoute('/me/notifications')"
class="relative w-10 h-10 flex items-center justify-center rounded-full hover:bg-surface-highlight text-muted"
>
<i class="pi pi-bell text-xl"></i>
<span
class="absolute top-2 right-2 w-2 h-2 bg-red-600 rounded-full border border-surface"
></span>
</router-link>
<!-- Creator Entry -->
<router-link
:to="tenantRoute('/creator/apply')"
class="hidden sm:flex items-center gap-1 px-3 py-1.5 text-sm font-medium text-muted hover:bg-surface-highlight rounded-lg border border-line"
>
<i class="pi pi-pencil"></i>
<span>创作</span>
</router-link>
<!-- Avatar Dropdown -->
<div class="relative group h-full flex items-center">
<button
class="w-9 h-9 rounded-full overflow-hidden border border-line focus:ring-2 ring-primary-100"
>
<img
:src="
user.avatar ||
`https://api.dicebear.com/7.x/avataaars/svg?seed=${user.id}`
"
alt="User"
class="w-full h-full object-cover"
/>
</button>
<!-- Dropdown Menu -->
<div
class="absolute right-0 top-full pt-2 w-48 hidden group-hover:block"
>
<div
class="bg-surface rounded-xl shadow-lg border border-line py-1"
>
<div class="px-4 py-3 border-b border-line">
<p class="text-sm font-bold text-content">
{{ user.nickname }}
</p>
<p class="text-xs text-muted truncate">
{{ user.phone }}
</p>
</div>
<router-link
:to="tenantRoute('/me')"
class="block px-4 py-2 text-sm text-content hover:bg-surface-highlight"
>个人中心</router-link
>
<router-link
:to="tenantRoute('/creator')"
class="block px-4 py-2 text-sm text-content hover:bg-surface-highlight"
>创作者中心</router-link
>
<div class="border-t border-line mt-1"></div>
<button
@click="logout"
class="block w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-red-50"
>
退出登录
</button>
</div>
</div>
</div>
</template>
<template v-else>
<router-link
:to="'/auth/login'"
class="bg-primary-600 text-white px-6 py-2 rounded-full font-medium hover:bg-primary-700 transition-all shadow-sm shadow-primary-100 active:scale-95"
>登录 / 注册</router-link
>
</template>
<!-- Mobile Menu Button -->
<button
class="md:hidden w-10 h-10 flex items-center justify-center text-muted"
>
<i class="pi pi-bars text-xl"></i>
</button>
</div>
</div>
</nav>
</template>