feat: implementar lógica de autenticación en rutas y redirección al cerrar sesión

This commit is contained in:
Juan Felipe Zapata Moreno 2026-01-28 15:54:13 -06:00
parent 5b7b6f2343
commit eb7fc0de14
4 changed files with 31 additions and 25 deletions

View File

@ -1,33 +1,12 @@
<script setup> <script setup>
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import useLoader from '@Stores/Loader'; import useLoader from '@Stores/Loader';
import { hasToken } from '@Services/Api';
/** Definidores */ /** Definidores */
const router = useRouter();
const route = useRoute();
const loader = useLoader(); const loader = useLoader();
/** Rutas públicas que no requieren autenticación */
const publicRoutes = [
'facturacion.index',
'auth.index',
'auth.forgot-password',
'auth.reset-password'
];
/** Ciclos */ /** Ciclos */
onMounted(() => { onMounted(() => {
// No redirigir si estamos en una ruta pública
if (publicRoutes.includes(route.name)) {
return;
}
if(!hasToken()) {
return router.push({ name: 'auth.index' })
}
loader.boot() loader.boot()
}) })
</script> </script>

View File

@ -126,7 +126,7 @@ onMounted(() => {
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary dark:bg-primary-d mb-4"> <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary dark:bg-primary-d mb-4">
<GoogleIcon name="receipt_long" class="text-3xl text-white" /> <GoogleIcon name="receipt_long" class="text-3xl text-white" />
</div> </div>
<h1 class="text-2xl font-bold text-gray-900 dark:text-white"> <h1 class="text-xl md:text-2xl font-bold text-gray-900 dark:text-white">
Solicitud de Factura Solicitud de Factura
</h1> </h1>
<p class="text-gray-600 dark:text-gray-400 mt-2"> <p class="text-gray-600 dark:text-gray-400 mt-2">
@ -140,7 +140,7 @@ onMounted(() => {
</div> </div>
<!-- Error --> <!-- Error -->
<div v-else-if="error" class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-8 text-center"> <div v-else-if="error" class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4 md:p-8 text-center">
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-red-100 dark:bg-red-900/30 mb-4"> <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-red-100 dark:bg-red-900/30 mb-4">
<GoogleIcon name="error" class="text-3xl text-red-500" /> <GoogleIcon name="error" class="text-3xl text-red-500" />
</div> </div>
@ -153,7 +153,7 @@ onMounted(() => {
</div> </div>
<!-- Submitted Success --> <!-- Submitted Success -->
<div v-else-if="submitted" class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-8 text-center"> <div v-else-if="submitted" class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4 md:p-8 text-center">
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-100 dark:bg-green-900/30 mb-4"> <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-100 dark:bg-green-900/30 mb-4">
<GoogleIcon name="check_circle" class="text-3xl text-green-500" /> <GoogleIcon name="check_circle" class="text-3xl text-green-500" />
</div> </div>
@ -176,7 +176,7 @@ onMounted(() => {
<GoogleIcon name="shopping_cart" class="text-xl" /> <GoogleIcon name="shopping_cart" class="text-xl" />
Datos de la Venta Datos de la Venta
</h2> </h2>
<div class="grid grid-cols-2 gap-4 text-sm"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm">
<div> <div>
<span class="text-gray-500 dark:text-gray-400">Folio:</span> <span class="text-gray-500 dark:text-gray-400">Folio:</span>
<span class="ml-2 font-semibold text-gray-900 dark:text-white">{{ saleData.invoice_number }}</span> <span class="ml-2 font-semibold text-gray-900 dark:text-white">{{ saleData.invoice_number }}</span>

View File

@ -1,5 +1,6 @@
import { createRouter, createWebHashHistory } from 'vue-router' import { createRouter, createWebHashHistory } from 'vue-router'
import { hasPermission } from '@Plugins/RolePermission'; import { hasPermission } from '@Plugins/RolePermission';
import { hasToken } from '@Services/Api';
import examples from './Examples'; import examples from './Examples';
@ -237,4 +238,26 @@ const router = createRouter({
] ]
}) })
router.beforeEach((to, from, next) => {
const publicRoutes = [
'facturacion.index',
'auth.index',
'auth.forgot-password',
'auth.reset-password'
];
// Si es una ruta pública, permitir acceso
if (publicRoutes.includes(to.name)) {
return next();
}
// Si no es pública y no hay token, redirigir a login
if (!hasToken()) {
return next({ name: 'auth.index' });
}
// Si hay token, permitir acceso
next();
});
export default router export default router

View File

@ -73,6 +73,10 @@ const closeSession = () => {
resetCsrfToken() resetCsrfToken()
Notify.info(Lang('session.closed')) Notify.info(Lang('session.closed'))
setTimeout(() => {
window.location.hash = '#/auth'
}, 500)
} }
/** /**