Files
nuxt-frontend/app/components/Sidebar.vue

111 lines
3.3 KiB
Vue

<template>
<aside
class="sticky top-0 z-50 border-b border-[#e7e5e4] bg-white/90 backdrop-blur lg:h-screen lg:w-[280px] lg:shrink-0 lg:border-b-0 lg:border-r">
<div class="flex h-full min-h-0 flex-col gap-4 px-4 py-3 lg:px-5 lg:py-6">
<NuxtLink to="/home"
class="flex items-center gap-3 rounded-2xl px-1 text-base font-semibold tracking-[0.16px] text-[#0c0a09] lg:px-0">
<span class="inline-flex h-11 w-11 items-center justify-center rounded-xl bg-[#292524] text-white">
<Icon name="mdi:gamepad-variant" class="text-xl" />
</span>
<span>GameVerse</span>
</NuxtLink>
<nav
class="flex min-w-0 gap-2 overflow-x-auto pb-1 lg:min-h-0 lg:flex-1 lg:flex-col lg:overflow-y-auto lg:overflow-x-visible lg:pb-0"
aria-label="Rotas internas">
<NuxtLink v-for="item in navigationItems" :key="item.to" :to="item.to"
:aria-current="isActive(item.to) ? 'page' : undefined" :class="[
'inline-flex h-10 shrink-0 items-center gap-2 rounded-full border px-4 text-[14px] font-medium leading-none transition lg:w-full lg:justify-start',
isActive(item.to)
? 'border-[#292524] bg-[#292524] text-white'
: 'border-[#d6d3d1] bg-transparent text-[#0c0a09] hover:border-[#0c0a09]'
]">
<Icon :name="item.icon" class="text-base" />
<span>{{ item.label }}</span>
</NuxtLink>
</nav>
<button type="button" :disabled="isLeaving" @click="sair"
class="inline-flex h-10 shrink-0 items-center justify-center gap-2 rounded-full bg-[#292524] px-4 text-[14px] font-medium leading-none text-white transition hover:bg-[#0c0a09] disabled:cursor-not-allowed disabled:opacity-70 lg:w-full">
<Icon v-if="isLeaving" name="mdi:loading" class="animate-spin text-base" />
<Icon v-else name="mdi:logout" class="text-base" />
<span>{{ isLeaving ? 'Saindo...' : 'Sair' }}</span>
</button>
</div>
</aside>
</template>
<script setup>
const route = useRoute()
const { $toast } = useNuxtApp()
const token = useCookie('token', {
secure: true,
sameSite: 'lax',
maxAge: 900
})
const isLeaving = ref(false)
const navigationItems = [
{
label: 'Home',
to: '/home',
icon: 'mdi:view-dashboard-outline'
},
{
label: 'Dados da conta',
to: '/dados-conta',
icon: 'mdi:account-circle-outline'
},
{
label: 'Rankings',
to: '/ranking-jogos',
icon: 'mdi:trophy-outline'
},
{
label: 'Perfil gamer',
to: '/perfil-gamer',
icon: 'mdi:account-star-outline'
},
{
label: 'Gift card',
to: '/gift-card',
icon: 'mdi:gift-outline'
},
{
label: 'Favoritos',
to: '/favoritos',
icon: 'mdi:heart-outline'
},
{
label: 'Catálogo',
to: '/catalogo',
icon: 'mdi:controller-classic-outline'
},
{
label: 'Novo jogo',
to: '/catalogo/criar',
icon: 'mdi:plus'
}
]
const isActive = (path) => {
if (path === '/catalogo') {
return (
route.path === '/catalogo' ||
(route.path.startsWith('/catalogo/') && route.path !== '/catalogo/criar')
)
}
return route.path === path
}
async function sair() {
isLeaving.value = true
token.value = null
$toast.success('Sessão encerrada com sucesso.', { duration: 8000 })
await navigateTo('/login')
}
</script>