Commit 440544e3 authored by Heber Cordova's avatar Heber Cordova

feat: finished maintenace of agents

parent 3a4d7bcd
<div class="custom-input">
<input [type]="type" [value]="value" (keyup)="onChangeInput(myInput)" id="custom-input" required #myInput>
<input formControlName="name" [type]="type" [value]="value" (keyup)="onChangeInput(myInput)" id="custom-input" required #myInput>
<label for="custom-input">{{ placeholder }}</label>
<p *ngIf="maxLength">{{ myInput.value.length }} / {{ maxLength }}</p>
</div>
......
......@@ -30,4 +30,15 @@
padding: 15px;
background-color: #f3f3f4;
min-height: calc(100vh - 202.8px)
}
\ No newline at end of file
}
.btn-back {
font-size: 10px;
color: #676a6c;
border: 1px solid #e4e5e6;
padding: 4px 6px;
}
.btn-back i {
margin-right: 5px;
}
<div class="container-content">
<div class="bg-white mail-box-header">
<div class="d-flex align-items-center mail-box-header-title">
<i [class]="['bi', icon]"></i>
<span>{{ title }}</span>
<div class="bg-white mail-box-header d-flex justify-content-between align-items-start">
<div>
<div class="d-flex align-items-center mail-box-header-title">
<i [class]="['bi', icon]"></i>
<span>{{ title }}</span>
</div>
<span class="mail-box-header-description">{{ message }}</span>
</div>
<div>
<button *ngIf="btnBack" (click)="goBack()" class="btn btn-back">
<i class="bi bi-arrow-return-left"></i>
<span>Regresar</span>
</button>
</div>
<span class="mail-box-header-description">{{ message }}</span>
</div>
<div class="bg-white mail-box-content">
<ng-content></ng-content>
......
import { Location } from '@angular/common';
import { Component, Input } from '@angular/core';
@Component({
......@@ -15,4 +16,13 @@ export class MailBoxComponent {
@Input()
public message: string = '';
@Input()
public btnBack: boolean = false;
constructor(private location: Location) { }
goBack(): void {
this.location.back();
}
}
......@@ -7,3 +7,60 @@
.btn-save:disabled {
color: #00000042;
}
/* Forms */
.custom-input {
position: relative;
}
.custom-input input {
width: 100%;
border: none;
border-bottom: 1px solid #ccc;
border-radius: 0;
font-size: 12px;
outline: none;
color: #8f8e8e;
}
.custom-input input:focus {
margin-bottom: -2px;
border-bottom: 2px solid #3f51b5;
}
.custom-input label {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
transition: 0.2s;
font-size: 14px;
}
.custom-input p {
margin: 0;
font-size: 12px;
text-align: end;
}
.custom-input input:focus + label {
top: -12px;
left: 1px;
font-size: 12px;
color: #3f51b5;
}
.custom-input input + label {
top: -12px;
left: 1px;
font-size: 12px;
color: #ccc;
}
.custom-input-detail {
font-size: 12px;
}
......@@ -2,26 +2,68 @@
<shared-mail-box
title="Agentes"
message="Este mantenimiento permite gestionar los agentes dentro de la agencia"
icon="bi-people">
<form class="px-3">
icon="bi-people"
[btnBack]="true">
<form [formGroup]="myForm" (ngSubmit)="onSave()" autocomplete="off" class="px-3">
<p class="mb-0 mt-2 fw-medium">Información personal</p>
<hr class="mt-0">
<div class="d-flex flex-column gap-3 mt-4">
<shared-input [value]="agent.name" placeholder="Nombres *" [maxLength]="30"></shared-input>
<shared-input [value]="agent.lastname" placeholder="Apellidos *" [maxLength]="50"></shared-input>
<shared-input [value]="agent.detail" placeholder="Detalles *" [maxLength]="100"></shared-input>
<div class="custom-input">
<input type="text" formControlName="name" id="custom-input">
<label for="custom-input">Nombre *</label>
<div class="d-flex custom-input-detail" [ngClass]="isValidField('name')? 'justify-content-between' : 'justify-content-end'">
<span *ngIf="isValidField('name')" class="text-danger">{{ getErrorMessage('name') }}</span>
<span>{{ myForm.controls['name'].value.length }} / {{ dataLengths['name'].max }}</span>
</div>
</div>
<div class="custom-input">
<input type="text" formControlName="lastname" id="custom-input">
<label for="custom-input">Apellidos *</label>
<div class="d-flex custom-input-detail" [ngClass]="isValidField('lastname')? 'justify-content-between' : 'justify-content-end'">
<span *ngIf="isValidField('lastname')" class="text-danger">{{ getErrorMessage('lastname') }}</span>
<span>{{ myForm.controls['lastname'].value.length }} / {{ dataLengths['lastname'].max }}</span>
</div>
</div>
<div class="custom-input">
<input type="text" formControlName="detail" id="custom-input">
<label for="custom-input">Detalle *</label>
<div class="d-flex custom-input-detail" [ngClass]="isValidField('detail')? 'justify-content-between' : 'justify-content-end'">
<span *ngIf="isValidField('detail')" class="text-danger">{{ getErrorMessage('detail') }}</span>
<span>{{ myForm.controls['detail'].value.length }} / {{ dataLengths['detail'].max }}</span>
</div>
</div>
</div>
<p class="mb-0 mt-4 fw-medium">Credenciales</p>
<hr class="mt-0">
<div class="d-flex flex-column gap-3 mt-4">
<shared-input [value]="agent.email" placeholder="Correo *" [maxLength]="100"></shared-input>
<shared-input-password></shared-input-password>
<div class="custom-input">
<input type="text" formControlName="email" id="custom-input">
<label for="custom-input">Correo *</label>
<div class="d-flex custom-input-detail" [ngClass]="isValidField('email')? 'justify-content-between' : 'justify-content-end'">
<span *ngIf="isValidField('email')" class="text-danger">{{ getErrorMessage('email') }}</span>
<span>{{ myForm.controls['email'].value.length }} / {{ dataLengths['email'].max }}</span>
</div>
</div>
<div class="custom-input">
<input type="password" formControlName="password" id="custom-input">
<label for="custom-input">Contraseña *</label>
<div class="d-flex custom-input-detail" [ngClass]="isValidField('password')? 'justify-content-between' : 'justify-content-end'">
<span *ngIf="isValidField('password')" class="text-danger">{{ getErrorMessage('password') }}</span>
<span>{{ myForm.controls['password'].value.length }} / {{ dataLengths['password'].max }}</span>
</div>
</div>
</div>
<hr>
<div class="d-flex justify-content-end mb-2">
<button type="submit" class="btn btn-save">
<button [disabled]="!myForm.valid" type="submit" class="btn btn-save">
<i class="bi bi-floppy me-1"></i>
<span>Guardar</span>
</button>
......
......@@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core';
import { AgentsService } from '../../services/agent.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Agent } from '../../interfaces/agent.interface';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Location } from '@angular/common';
@Component({
selector: 'app-agent-add',
......@@ -10,30 +12,118 @@ import { Agent } from '../../interfaces/agent.interface';
})
export class AgentAddComponent implements OnInit {
public agent!: Agent;
public myForm!: FormGroup;
private isNew: boolean = false;
constructor(private _supervisorService: AgentsService, private _activatedRoute: ActivatedRoute, private _router: Router) {}
constructor(
private _supervisorService:
AgentsService, private _activatedRoute:
ActivatedRoute, private _router: Router,
private fb: FormBuilder,
private location: Location) {}
ngOnInit(): void {
this._activatedRoute.params.subscribe(param => {
if (param['id']) {
const id: number = param['id'];
const agent = this._supervisorService.getAgentById(id);
agent? this.agent = agent : this._router.navigate(['/supervisors']);
if (agent) {
this.buildForm(agent);
} else {
this._router.navigate(['/supervisors']);
}
} else {
this.agent = this.getEmptyAgent();
this.buildForm();
}
})
}
getEmptyAgent(): Agent {
return {
id: 0,
name: '',
lastname: '',
detail: '',
email: '',
password: ''
};
isValidField(field: string): boolean | undefined {
const fieldForm = this.myForm.get(field);
return fieldForm?.invalid && fieldForm?.touched;
}
getErrorMessage(field: string): string | null {
if (!this.myForm.controls[field]) return null;
const errors = this.myForm.controls[field].errors || {};
console.log(errors);
for (const key of Object.keys(errors)) {
switch (key) {
case 'required':
return 'Este campo es requerido';
case 'minlength':
return `Este campo debe tener al menos ${errors[key].requiredLength} caracteres`;
case 'maxlength':
return `Este campo debe tener como máximo ${errors[key].requiredLength} caracteres`;
case 'email':
return 'El email no es válido';
}
}
return null;
}
dataLengths = {
name: {
min: 3,
max: 20
},
lastname: {
min: 3,
max: 30
},
detail: {
min: 3,
max: 100
},
email: {
min: 3,
max: 30
},
password: {
min: 3,
max: 30
}
};
buildForm(agent?: Agent):void {
if (agent) {
this.myForm = this.fb.group({
name: [agent.name, [Validators.required, Validators.minLength(3), Validators.maxLength(this.dataLengths['name'].max)]],
lastname: [agent.lastname, [Validators.required, Validators.minLength(3), Validators.maxLength(this.dataLengths['lastname'].max)]],
detail: [agent.detail, [Validators.required, Validators.minLength(3), Validators.maxLength(this.dataLengths['detail'].max)]],
email: [agent.email, [Validators.required, Validators.minLength(3), Validators.maxLength(this.dataLengths['email'].max)]],
password: [agent.password, [Validators.required, Validators.minLength(3), Validators.maxLength(this.dataLengths['password'].max)]]
})
} else {
this.myForm = this.fb.group({
name: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(20)]],
lastname: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(30)]],
detail: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(100)]],
email: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(30)]],
password: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(30)]]
});
this.isNew = true;
console.log(this.myForm);
}
}
onSave() {
this.myForm.markAllAsTouched();
if (this.myForm.valid) {
if (this.isNew) {
this._supervisorService.saveAgent(this.myForm.value);
} else {
const id: number = this._activatedRoute.snapshot.params['id'];
this._supervisorService.editAgent(id, this.myForm.value);
}
this.myForm.reset({name: '', lastname: '', detail: '', email: '', password: ''});
this.location.back();
}
}
}
......@@ -14,7 +14,7 @@ export class AgentsService {
lastname: 'Doe',
detail: 'Detail',
email: 'jodoe@gmail.com',
password: ''
password: 'password1234'
},
{
id: 2,
......@@ -22,7 +22,7 @@ export class AgentsService {
lastname: 'Doe',
detail: 'Detail',
email: 'jdoe@gmail.com',
password: ''
password: 'password1234'
},
{
id: 3,
......@@ -30,7 +30,7 @@ export class AgentsService {
lastname: 'Smith',
detail: 'Detail',
email: 'jsmith@gmail.com',
password: ''
password: 'password1234'
},
{
id: 4,
......@@ -38,7 +38,7 @@ export class AgentsService {
lastname: 'Smith',
detail: 'Detail',
email: 'jasmith@gmail.com',
password: ''
password: 'password1234'
},
{
id: 5,
......@@ -46,7 +46,7 @@ export class AgentsService {
lastname: 'Smith',
detail: 'Detail',
email: 'jasmith@gmail.com',
password: ''
password: 'password1234'
},
{
id: 6,
......@@ -54,7 +54,7 @@ export class AgentsService {
lastname: 'Smith',
detail: 'Detail',
email: 'jasmith@gmail.com',
password: ''
password: 'password1234'
}
];
......@@ -70,6 +70,7 @@ export class AgentsService {
}
saveAgent(agent: Agent): Agent {
agent.id = this._agents.length + 1;
this._agents = [...this._agents, agent];
return agent;
}
......@@ -78,13 +79,15 @@ export class AgentsService {
let edited: boolean = false;
this._agents.filter(item => {
if (item.id === id) {
item.name = agent.name;
item.lastname = agent.lastname;
item.detail = agent.detail;
agent.id = id;
// Edit agent
this._agents = this._agents.map(item => {
if (item.id == id) {
edited = true;
return agent;
}
return item;
});
return edited? agent : null;
......
......@@ -7,6 +7,7 @@ import { AgentsComponent } from './pages/agents/agents.component';
import { HomePageComponent } from './pages/home-page/home-page.component';
import { AgentAddComponent } from './pages/agent-add/agent-add.component';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
......@@ -21,7 +22,9 @@ import { HttpClientModule } from '@angular/common/http';
CommonModule,
SharedModule,
SupervisorRoutingModule,
HttpClientModule
HttpClientModule,
ReactiveFormsModule,
FormsModule
],
exports:[
SupervisorRoutingModule
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment