93 lines
4.5 KiB
Vue
93 lines
4.5 KiB
Vue
<script setup>
|
|
const auth = useAuthStore()
|
|
const ui = useUiStore()
|
|
const router = useRouter()
|
|
|
|
const creditsBadgeClass = computed(() => {
|
|
const bal = auth.creditsBalance
|
|
if (bal === 0 && auth.freeUsed) return 'bg-red-50 text-red-500'
|
|
if (bal <= 1 && auth.freeUsed) return 'bg-amber-50 text-amber-600'
|
|
return 'bg-blue-50 text-[#1a56db]'
|
|
})
|
|
|
|
async function handleLogout() {
|
|
await auth.logout()
|
|
router.push('/')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<nav class="bg-white border-b border-gray-200 h-[60px] flex items-center px-6 sticky top-0 z-50">
|
|
<div class="max-w-6xl mx-auto w-full flex items-center justify-between">
|
|
|
|
<!-- Logo -->
|
|
<NuxtLink to="/" class="text-xl font-bold text-[#1a56db]">IDconvert</NuxtLink>
|
|
|
|
<!-- Desktop -->
|
|
<div class="hidden md:flex items-center gap-3">
|
|
<NuxtLink to="/pricing" class="text-sm text-gray-600 hover:text-gray-900 px-3 py-1.5 rounded hover:bg-gray-100 transition-colors">Pricing</NuxtLink>
|
|
|
|
<!-- Logged out -->
|
|
<template v-if="!auth.isLoggedIn">
|
|
<button @click="ui.openAuthModal('login')" class="text-sm text-gray-800 border border-gray-200 px-4 py-1.5 rounded-md hover:bg-gray-100 transition-colors">
|
|
Login
|
|
</button>
|
|
<button @click="ui.openAuthModal('register')" class="text-sm bg-[#1a56db] text-white px-4 py-1.5 rounded-md hover:bg-[#1648c0] transition-colors">
|
|
Sign up
|
|
</button>
|
|
</template>
|
|
|
|
<!-- Logged in -->
|
|
<template v-else>
|
|
<span :class="['text-sm font-medium px-3 py-1 rounded-full', creditsBadgeClass]">
|
|
<template v-if="!auth.freeUsed">1 free conversion</template>
|
|
<template v-else-if="auth.creditsBalance === 0">No credits</template>
|
|
<template v-else>{{ auth.creditsBalance }} credit{{ auth.creditsBalance !== 1 ? 's' : '' }}</template>
|
|
</span>
|
|
<button @click="ui.openPurchaseModal()" class="text-sm bg-[#1a56db] text-white px-4 py-1.5 rounded-md hover:bg-[#1648c0] transition-colors">
|
|
Buy credits
|
|
</button>
|
|
<!-- Avatar dropdown -->
|
|
<div class="relative group">
|
|
<button class="w-8 h-8 rounded-full bg-blue-50 text-[#1a56db] text-sm font-bold flex items-center justify-center border border-blue-100">
|
|
{{ auth.user?.name?.[0]?.toUpperCase() || 'U' }}
|
|
</button>
|
|
<div class="absolute right-0 top-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg py-1 w-44 invisible group-hover:visible opacity-0 group-hover:opacity-100 transition-all">
|
|
<div class="px-3 py-2 text-xs text-gray-400 border-b border-gray-100 truncate">{{ auth.user?.email }}</div>
|
|
<NuxtLink to="/dashboard" class="block px-3 py-2 text-sm text-gray-700 hover:bg-gray-50">Dashboard</NuxtLink>
|
|
<button @click="handleLogout" class="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-gray-50">Log out</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<!-- Mobile hamburger -->
|
|
<button class="md:hidden p-2 text-gray-600" @click="ui.toggleMobileMenu()">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Mobile menu -->
|
|
<Transition name="slide-down">
|
|
<div v-if="ui.mobileMenuOpen" class="absolute top-[60px] left-0 right-0 bg-white border-b border-gray-200 px-6 py-4 flex flex-col gap-2 md:hidden shadow-sm">
|
|
<NuxtLink to="/pricing" @click="ui.closeMobileMenu()" class="text-sm text-gray-700 py-2">Pricing</NuxtLink>
|
|
<template v-if="!auth.isLoggedIn">
|
|
<button @click="ui.openAuthModal('login'); ui.closeMobileMenu()" class="text-sm text-gray-700 text-left py-2">Login</button>
|
|
<button @click="ui.openAuthModal('register'); ui.closeMobileMenu()" class="text-sm text-[#1a56db] text-left py-2 font-medium">Sign up</button>
|
|
</template>
|
|
<template v-else>
|
|
<NuxtLink to="/dashboard" @click="ui.closeMobileMenu()" class="text-sm text-gray-700 py-2">Dashboard</NuxtLink>
|
|
<button @click="handleLogout; ui.closeMobileMenu()" class="text-sm text-gray-700 text-left py-2">Log out</button>
|
|
</template>
|
|
</div>
|
|
</Transition>
|
|
</nav>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.slide-down-enter-active, .slide-down-leave-active { transition: all 0.15s ease; }
|
|
.slide-down-enter-from, .slide-down-leave-to { opacity: 0; transform: translateY(-8px); }
|
|
</style>
|