recuperar contraseña y boton exportar a excel

This commit is contained in:
luis cespedes 2025-05-06 12:34:07 -04:00
parent b30722bf68
commit 0288e80b9d
5 changed files with 236 additions and 85 deletions

View File

@ -126,19 +126,4 @@
</tr>
</ng-template>
</p-table>
<!-- Botón de exportar debajo de la tabla -->
<div class="flex justify-content-end mt-3">
<button
pButton
type="button"
icon="pi pi-file-excel"
(click)="exportExcelWithStyles(dt)"
class="p-button-success"
label="Exportar a Excel"
pTooltip="Descargar planilla Excel"
tooltipPosition="top"
[tooltipOptions]="{showDelay: 100, appendTo: 'body'}"
></button>
</div>
</div>

View File

@ -29,6 +29,22 @@
</div>
<!-- Tabla1 -->
<!-- <div class="font-bold text-black-alpha-90 my-2">T&iacute;tulo de la tabla:</div> -->
<!-- Botón de exportar a Excel (movido arriba) -->
<div class="flex justify-content-end align-items-center my-2 py-2">
<button
pButton
type="button"
(click)="exportExcelWithStyles(dt)"
icon="pi pi-file-excel"
class="p-button-success"
label="Exportar"
pTooltip="Descargar planilla Excel"
tooltipPosition="top"
[tooltipOptions]="{showDelay: 100, appendTo: 'body'}"
></button>
</div>
<p-table
#dt
id="azul"
@ -119,17 +135,5 @@
</tr>
</ng-template>
</p-table>
<div class="flex justify-content-end mt-3">
<button
pButton
type="button"
(click)="exportExcelWithStyles(dt)"
icon="pi pi-file-excel"
class="p-button-success"
label="Exportar a Excel"
pTooltip="Descargar planilla Excel"
tooltipPosition="top"
[tooltipOptions]="{showDelay: 100, appendTo: 'body'}"
></button>
</div>
</div>
<!-- Se eliminó el botón que estaba aquí abajo -->
</div>

View File

@ -19,69 +19,124 @@
<main class="main-content">
<div class="login-container">
<div class="login-box">
<div class="login-card">
<div class="login-header">
<h2>Iniciar Sesión</h2>
</div>
<div class="flip-container" [ngClass]="{'flip': showRecovery}">
<div class="flipper">
<!-- LADO FRONTAL: LOGIN -->
<div class="front">
<div class="login-card">
<div class="login-header">
<h2>Iniciar Sesión</h2>
</div>
<form (ngSubmit)="onLogin()">
<form (ngSubmit)="onLogin()">
<!-- Email -->
<input
type="email"
pInputText
[(ngModel)]="email"
name="email"
placeholder="Email"
class="input-with-icon w-full mb-3"
style="background-color: white; color: black;"
required
/>
<!-- Email -->
<input
type="email"
pInputText
[(ngModel)]="email"
name="email"
placeholder="Email"
class="input-with-icon w-full mb-3"
style="background-color: white; color: black;"
required
/>
<!-- Password -->
<input
type="password"
pInputText
[(ngModel)]="password"
name="password"
placeholder="Password"
class="input-with-lock w-full"
style="background-color: white; color: black;"
required
/>
<!-- Password -->
<input
type="password"
pInputText
[(ngModel)]="password"
name="password"
placeholder="Password"
class="input-with-lock w-full"
style="background-color: white; color: black;"
required
/>
<!-- Mensaje de error -->
<div *ngIf="errorMessage" class="error-message mt-2">
<p-message severity="error" [text]="errorMessage"></p-message>
</div>
<!-- Mensaje de error -->
<div *ngIf="errorMessage" class="error-message mt-2">
<p-message severity="error" [text]="errorMessage"></p-message>
<!-- Botón -->
<div class="login-actions">
<button
pButton
type="submit"
[label]="loading ? 'Autenticando...' : 'Autenticar'"
class="p-button-primary w-full"
style="color: white"
[disabled]="loading || !email || !password">
<i *ngIf="loading" class="pi pi-spin pi-spinner mr-2"></i>
</button>
</div>
</form>
<!-- Recuperar contraseña -->
<div class="password-recovery">
<a href="#" (click)="toggleRecovery($event)">Recuperar Contraseña</a>
</div>
<!-- Credenciales de prueba -->
<div class="test-credentials mt-3 p-2" style="background-color: #f8f9fa; border-radius: 4px;">
<p class="mb-1"><strong>Credenciales de prueba:</strong></p>
<p class="mb-1">Email: admin&#64;example.com</p>
<p>Password: admin123</p>
</div>
</div>
</div>
<!-- Botón -->
<div class="login-actions">
<button
pButton
type="submit"
[label]="loading ? 'Autenticando...' : 'Autenticar'"
class="p-button-primary w-full"
style="color: white"
[disabled]="loading || !email || !password">
<i *ngIf="loading" class="pi pi-spin pi-spinner mr-2"></i>
</button>
<!-- LADO TRASERO: RECUPERACIÓN DE CONTRASEÑA -->
<div class="back">
<div class="login-card">
<div class="login-header">
<h2>Recuperar Contraseña</h2>
</div>
<form (ngSubmit)="onRecoverPassword()">
<!-- Email para recuperación -->
<input
type="email"
pInputText
[(ngModel)]="recoveryEmail"
name="recoveryEmail"
placeholder="Ingresa tu email"
class="input-with-icon w-full mb-3"
style="background-color: white; color: black;"
required
/>
<!-- Mensaje informativo -->
<div class="info-message mb-3">
<p class="text-sm">Te enviaremos un enlace para restablecer tu contraseña.</p>
</div>
<!-- Mensaje de estado de recuperación -->
<div *ngIf="recoveryMessage" class="recovery-message mt-2 mb-3">
<p-message [severity]="recoveryStatus" [text]="recoveryMessage"></p-message>
</div>
<!-- Botón de enviar -->
<div class="login-actions">
<button
pButton
type="submit"
[label]="recoveryLoading ? 'Enviando...' : 'Enviar Enlace'"
class="p-button-primary w-full"
style="color: white"
[disabled]="recoveryLoading || !recoveryEmail">
<i *ngIf="recoveryLoading" class="pi pi-spin pi-spinner mr-2"></i>
</button>
</div>
</form>
<!-- Volver al login -->
<div class="password-recovery">
<a href="#" (click)="toggleRecovery($event)">Volver al Login</a>
</div>
</div>
</div>
</form>
<!-- Recuperar contraseña -->
<div class="password-recovery">
<a href="#">Recuperar Contraseña</a>
</div>
<!-- Credenciales de prueba -->
<div class="test-credentials mt-3 p-2" style="background-color: #f8f9fa; border-radius: 4px;">
<p class="mb-1"><strong>Credenciales de prueba:</strong></p>
<p class="mb-1">Email: admin&#64;example.com</p>
<p>Password: admin123</p>
</div>
</div>
</div>
</div>

View File

@ -61,7 +61,8 @@
flex: 1;
display: flex;
justify-content: center;
align-items: center;
align-items: flex-start; /* Cambiado de center a flex-start */
padding-top: 40px; /* Añadido padding superior */
background-color: #f0f0f0;
background-size: cover;
background-position: center;
@ -86,6 +87,8 @@
.login-box {
width: 360px;
max-width: 100%;
margin-top: 2rem;
margin-bottom: 2rem;
}
.login-card {
@ -93,6 +96,56 @@
border-radius: 4px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
width: 100%;
}
/* Estilos para el efecto de flip de tarjeta */
.flip-container {
perspective: 1000px;
width: 100%;
min-height: 410px; /* Aumentamos altura para evitar saltos */
position: relative;
}
.flip-container.flip .flipper {
transform: rotateY(180deg);
}
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
width: 100%;
height: 100%;
}
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden; /* Asegura compatibilidad con Safari */
backface-visibility: hidden;
}
.front {
z-index: 2;
transform: rotateY(0deg);
}
.back {
transform: rotateY(180deg);
}
/* Ajuste para los contenedores de recuperación */
.info-message {
padding: 0 0.5rem;
}
.recovery-message {
min-height: 30px;
}
.login-header {

View File

@ -35,10 +35,20 @@ import { AuthService } from '../../services/auth.service';
styleUrl: './login.component.scss'
})
export class LoginComponent {
// Login form
email: string = '';
password: string = '';
loading: boolean = false;
errorMessage: string = '';
// Password recovery form
recoveryEmail: string = '';
recoveryLoading: boolean = false;
recoveryMessage: string = '';
recoveryStatus: string = 'info';
// Control de formularios
showRecovery: boolean = false;
constructor(
private router: Router,
@ -46,6 +56,24 @@ export class LoginComponent {
private messageService: MessageService
) { }
/**
* Cambia entre el formulario de login y recuperación
*/
toggleRecovery(event: Event) {
event.preventDefault();
this.showRecovery = !this.showRecovery;
this.errorMessage = '';
this.recoveryMessage = '';
// Si estamos cambiando al formulario de recuperación, copiar el email actual
if (this.showRecovery && this.email) {
this.recoveryEmail = this.email;
}
}
/**
* Proceso de login
*/
onLogin() {
this.loading = true;
this.errorMessage = '';
@ -71,4 +99,30 @@ export class LoginComponent {
});
}
/**
* Proceso de recuperación de contraseña
*/
onRecoverPassword() {
if (!this.recoveryEmail) {
this.recoveryMessage = 'Debes ingresar un email';
this.recoveryStatus = 'error';
return;
}
this.recoveryLoading = true;
this.recoveryMessage = '';
// Simulamos la recuperación (en producción, esto llamaría a un servicio real)
setTimeout(() => {
this.recoveryLoading = false;
this.recoveryMessage = 'Hemos enviado un enlace de recuperación a tu email';
this.recoveryStatus = 'success';
this.messageService.add({
severity: 'success',
summary: 'Email enviado',
detail: 'Se ha enviado un enlace de recuperación a tu correo'
});
}, 1500);
}
}