style: atualiza todo design interno da aplicacao
This commit is contained in:
110
app/components/Sidebar.vue
Normal file
110
app/components/Sidebar.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user