- Added methods to normalize permissions and roles from API responses. - Implemented a centralized error handling method for authentication errors. - Updated API endpoints for login, registration, and user profile management. - Introduced session refresh functionality to retrieve user roles and permissions. feat(catalog): improve companies and units management with permissions and filters - Integrated permission checks for creating, updating, and deleting companies. - Added user role and permission checks to the Companies component. - Enhanced the Units component with search and status filters. - Refactored unit creation and update logic to handle validation errors. fix(catalog): update unit measure services and mapping logic - Improved API service methods for fetching, creating, and updating units of measure. - Added mapping functions to convert API responses to internal data structures. - Enhanced error handling in unit measure services. chore(auth): refactor authentication storage utilities - Created utility functions for managing authentication tokens and user data in local storage. - Updated API interceptor to use new storage utility functions for session management. style: clean up code formatting and improve readability across components and services
181 lines
7.3 KiB
Vue
181 lines
7.3 KiB
Vue
<script setup lang="ts">
|
|
import { ref, computed } from 'vue';
|
|
import { useAuth } from '../composables/useAuth';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
const { login, isLoading } = useAuth();
|
|
|
|
const email = ref('');
|
|
const password = ref('');
|
|
const showPassword = ref(false);
|
|
const errorMessage = ref('');
|
|
|
|
const isFormValid = computed(() => {
|
|
return email.value.trim() !== '' && password.value.trim() !== '';
|
|
});
|
|
|
|
const handleLogin = async () => {
|
|
errorMessage.value = '';
|
|
|
|
const result = await login({
|
|
email: email.value,
|
|
password: password.value
|
|
});
|
|
|
|
if (result.success) {
|
|
const requestedRedirect = typeof route.query.redirect === 'string' ? route.query.redirect : '/';
|
|
const redirect = requestedRedirect.startsWith('/') ? requestedRedirect : '/';
|
|
router.push(redirect);
|
|
} else {
|
|
errorMessage.value = result.error || 'Error al iniciar sesión';
|
|
}
|
|
};
|
|
|
|
const handleKeyPress = (event: KeyboardEvent) => {
|
|
if (event.key === 'Enter' && isFormValid.value) {
|
|
handleLogin();
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex min-h-screen bg-surface-50 dark:bg-surface-950">
|
|
<!-- Left Column: Image Panel -->
|
|
<div
|
|
class="relative hidden lg:flex lg:w-1/2 flex-col justify-between p-8 text-white bg-cover bg-center bg-no-repeat"
|
|
style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuBTdTKvMQYppS4BwZhrgylD8oKxLJa13js2PIRUwAQF5XbEqqNU2VCYyvJEQTWdKdoCTYHiAm_RGoobkJ3Rt4xd-XJUcshYKfCBrF0fZcBJOFR9UJ0Vh2WuLIA8g_xmKA8Fn7hdh4KPqJC7X_IOg5UPi5RRzqxB-Xn2tMbaEk-n1h8mYXfnKSIV7C0up-YreeZdP9GeznZN6DCzjy8TLyxw03gXdmhHziZC6hzahwWemMrtS8W5sX028-G1tnxivu1v2o8oETFyh5Wi')"
|
|
>
|
|
<!-- Overlay oscuro -->
|
|
<div class="absolute inset-0 bg-black/50"></div>
|
|
|
|
<!-- Logo y nombre -->
|
|
<div class="relative z-10 flex items-center gap-3">
|
|
<i class="pi pi-box text-4xl"></i>
|
|
<span class="text-xl font-bold">Golscontrols ERP</span>
|
|
</div>
|
|
|
|
<!-- Texto principal -->
|
|
<div class="relative z-10">
|
|
<h1 class="text-4xl font-black leading-tight tracking-tight">
|
|
Sistema Integral de Gestión Empresarial
|
|
</h1>
|
|
<p class="mt-2 max-w-md text-lg text-white/80">
|
|
Optimiza tus operaciones, gestiona inventarios y aumenta la eficiencia desde un solo panel.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Column: Form Panel -->
|
|
<div class="flex w-full lg:w-1/2 flex-col items-center justify-center px-4 py-12">
|
|
<div class="w-full max-w-md space-y-8">
|
|
<!-- Header -->
|
|
<div>
|
|
<h1 class="text-3xl font-bold tracking-tight text-surface-900 dark:text-white">
|
|
Bienvenido de nuevo
|
|
</h1>
|
|
<p class="mt-2 text-base text-surface-600 dark:text-surface-300">
|
|
Ingresa tus credenciales para acceder a tu cuenta.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Mensaje de error -->
|
|
<Message
|
|
v-if="errorMessage"
|
|
severity="error"
|
|
:closable="true"
|
|
@close="errorMessage = ''"
|
|
>
|
|
{{ errorMessage }}
|
|
</Message>
|
|
|
|
<!-- Info de prueba (solo para desarrollo) -->
|
|
<Message severity="info" :closable="false">
|
|
<div class="text-sm">
|
|
<p class="font-semibold mb-1">Credenciales de prueba:</p>
|
|
<p><strong>Email:</strong> admin@golsystems.com.mx</p>
|
|
<p><strong>Password:</strong> P8YeFQggR06r</p>
|
|
</div>
|
|
</Message>
|
|
|
|
<!-- Formulario -->
|
|
<form @submit.prevent="handleLogin" class="space-y-6">
|
|
<!-- Email -->
|
|
<div class="flex flex-col gap-2">
|
|
<label for="email" class="text-sm font-medium text-surface-900 dark:text-surface-200">
|
|
Correo Electrónico
|
|
</label>
|
|
<IconField>
|
|
<InputIcon class="pi pi-user" />
|
|
<InputText
|
|
id="email"
|
|
v-model="email"
|
|
type="email"
|
|
placeholder="you@example.com"
|
|
:disabled="isLoading"
|
|
@keypress="handleKeyPress"
|
|
class="w-full"
|
|
autocomplete="email"
|
|
size="large"
|
|
/>
|
|
</IconField>
|
|
</div>
|
|
|
|
<!-- Password -->
|
|
<div class="flex flex-col gap-2">
|
|
<label for="password" class="text-sm font-medium text-surface-900 dark:text-surface-200">
|
|
Contraseña
|
|
</label>
|
|
<IconField>
|
|
<InputIcon class="pi pi-lock" />
|
|
<InputText
|
|
id="password"
|
|
v-model="password"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
placeholder="Ingresa tu contraseña"
|
|
:disabled="isLoading"
|
|
@keypress="handleKeyPress"
|
|
class="w-full pr-10"
|
|
autocomplete="current-password"
|
|
size="large"
|
|
/>
|
|
<button
|
|
type="button"
|
|
@click="showPassword = !showPassword"
|
|
class="absolute right-3 top-1/2 -translate-y-1/2 text-surface-400 hover:text-surface-600 dark:hover:text-surface-200"
|
|
tabindex="-1"
|
|
>
|
|
<i :class="showPassword ? 'pi pi-eye-slash' : 'pi pi-eye'"></i>
|
|
</button>
|
|
</IconField>
|
|
</div>
|
|
|
|
<!-- Botón de Login -->
|
|
<Button
|
|
type="submit"
|
|
label="Iniciar Sesión"
|
|
:loading="isLoading"
|
|
:disabled="!isFormValid || isLoading"
|
|
class="w-full"
|
|
size="large"
|
|
severity="primary"
|
|
/>
|
|
</form>
|
|
|
|
<!-- Copyright -->
|
|
<p class="text-center text-sm text-surface-500 dark:text-surface-400">
|
|
© 2025 Grupo Golsystems, Todos los derechos reservados.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* Ajuste para el botón de toggle password */
|
|
.p-iconfield {
|
|
position: relative;
|
|
}
|
|
</style>
|