207 lines
7.6 KiB
Vue
207 lines
7.6 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import { useRouter } from 'vue-router';
|
|
import { useLayout } from "../../composables/useLayout";
|
|
import { useAuth } from "../../modules/auth/composables/useAuth";
|
|
|
|
const router = useRouter();
|
|
const { isDarkMode, toggleDarkMode } = useLayout();
|
|
const { user, logout } = useAuth();
|
|
|
|
// Referencia al menú de usuario
|
|
const userMenu = ref();
|
|
|
|
// Función para toggle del menú
|
|
const toggleUserMenu = (event: Event) => {
|
|
userMenu.value.toggle(event);
|
|
};
|
|
|
|
// Función de logout
|
|
const handleLogout = async () => {
|
|
await logout();
|
|
router.push('/login');
|
|
};
|
|
|
|
// Opciones del menú de usuario
|
|
const userMenuItems = ref([
|
|
{
|
|
label: 'Mi Perfil',
|
|
icon: 'pi pi-user',
|
|
command: () => {
|
|
router.push('/profile');
|
|
}
|
|
},
|
|
{
|
|
label: 'Configuración',
|
|
icon: 'pi pi-cog',
|
|
command: () => {
|
|
router.push('/settings');
|
|
}
|
|
},
|
|
{
|
|
separator: true
|
|
},
|
|
{
|
|
label: 'Cerrar Sesión',
|
|
icon: 'pi pi-sign-out',
|
|
command: () => {
|
|
handleLogout();
|
|
}
|
|
}
|
|
]);
|
|
</script>
|
|
|
|
<template>
|
|
<header class="bg-surface-0 dark:bg-surface-900 border-b border-surface-200 dark:border-surface-700 px-6 py-4">
|
|
<div class="flex items-center justify-between">
|
|
<!-- Left Section: Branding -->
|
|
<div class="flex items-center gap-3">
|
|
<!-- <i class="pi pi-box text-2xl text-primary"></i>
|
|
<div class="flex flex-col">
|
|
<span class="text-lg font-bold text-surface-900 dark:text-surface-0">
|
|
GOLS Control
|
|
</span>
|
|
<span class="text-xs text-surface-500 dark:text-surface-400">
|
|
Sistema de Gestión
|
|
</span>
|
|
</div> -->
|
|
</div>
|
|
|
|
<!-- Right Section: Actions -->
|
|
<div class="flex items-center gap-2">
|
|
<!-- Search Button (opcional) -->
|
|
<!-- <button
|
|
type="button"
|
|
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-surface-100 dark:hover:bg-surface-800 transition-all text-surface-700 dark:text-surface-200"
|
|
title="Buscar"
|
|
>
|
|
<i class="pi pi-search"></i>
|
|
</button> -->
|
|
|
|
<!-- Notifications Button (opcional) -->
|
|
<!-- <button
|
|
type="button"
|
|
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-surface-100 dark:hover:bg-surface-800 transition-all text-surface-700 dark:text-surface-200 relative"
|
|
title="Notificaciones"
|
|
>
|
|
<i class="pi pi-bell"></i>
|
|
<span class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full"></span>
|
|
</button> -->
|
|
|
|
<!-- Dark Mode Toggle -->
|
|
<button
|
|
type="button"
|
|
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-surface-100 dark:hover:bg-surface-800 transition-all text-surface-900 dark:text-surface-0"
|
|
@click="toggleDarkMode"
|
|
:title="isDarkMode ? 'Modo claro' : 'Modo oscuro'"
|
|
>
|
|
<i :class="['pi', isDarkMode ? 'pi-sun' : 'pi-moon']" />
|
|
</button>
|
|
|
|
<!-- Settings/Config Button -->
|
|
<!-- <div class="relative">
|
|
<button
|
|
v-styleclass="{
|
|
selector: '@next',
|
|
enterFromClass: 'hidden',
|
|
enterActiveClass: 'animate-scalein',
|
|
leaveToClass: 'hidden',
|
|
leaveActiveClass: 'animate-fadeout',
|
|
hideOnOutsideClick: true,
|
|
}"
|
|
type="button"
|
|
class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-surface-100 dark:hover:bg-surface-800 transition-all text-surface-700 dark:text-surface-200"
|
|
title="Configuración"
|
|
>
|
|
<i class="pi pi-cog" />
|
|
</button>
|
|
<AppConfig />
|
|
</div> -->
|
|
|
|
<!-- User Profile Button with Menu -->
|
|
<div class="relative">
|
|
<button
|
|
type="button"
|
|
class="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-surface-100 dark:hover:bg-surface-800 transition-all"
|
|
title="Perfil"
|
|
@click="toggleUserMenu"
|
|
aria-haspopup="true"
|
|
aria-controls="user_menu"
|
|
>
|
|
<div class="w-8 h-8 rounded-full bg-primary flex items-center justify-center text-white text-sm font-semibold">
|
|
{{ user?.name?.charAt(0).toUpperCase() || 'U' }}
|
|
</div>
|
|
<span class="text-sm font-medium text-surface-900 dark:text-surface-0 hidden md:block">
|
|
{{ user?.full_name || user?.name || 'Usuario' }}
|
|
</span>
|
|
<i class="pi pi-angle-down text-sm text-surface-500 hidden md:block"></i>
|
|
</button>
|
|
|
|
<!-- Menu de Usuario -->
|
|
<Menu
|
|
ref="userMenu"
|
|
id="user_menu"
|
|
:model="userMenuItems"
|
|
:popup="true"
|
|
class="w-56"
|
|
>
|
|
<template #start>
|
|
<div class="px-4 py-3 border-b border-surface-200 dark:border-surface-700">
|
|
<p class="text-sm font-semibold text-surface-900 dark:text-surface-0">{{ user?.full_name || user?.name }}</p>
|
|
<p class="text-xs text-surface-500 dark:text-surface-400">{{ user?.email }}</p>
|
|
</div>
|
|
</template>
|
|
<template #item="{ item, props }">
|
|
<a
|
|
v-bind="props.action"
|
|
class="flex items-center gap-3 px-4 py-3 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors"
|
|
:class="{ 'text-red-600 dark:text-red-400': item.label === 'Cerrar Sesión' }"
|
|
>
|
|
<i :class="item.icon"></i>
|
|
<span class="text-sm font-medium">{{ item.label }}</span>
|
|
</a>
|
|
</template>
|
|
<template #end>
|
|
<div class="px-4 py-2 border-t border-surface-200 dark:border-surface-700">
|
|
<p class="text-xs text-surface-400 dark:text-surface-500">Versión 1.0.0</p>
|
|
</div>
|
|
</template>
|
|
</Menu>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.animate-scalein {
|
|
animation: scalein 0.15s ease-in;
|
|
}
|
|
|
|
.animate-fadeout {
|
|
animation: fadeout 0.15s ease-out;
|
|
}
|
|
|
|
@keyframes scalein {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.9);
|
|
}
|
|
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes fadeout {
|
|
from {
|
|
opacity: 1;
|
|
}
|
|
|
|
to {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
</style>
|