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

feat: finished maintenace of agents

parent 3a4d7bcd
<div class="custom-input"> <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> <label for="custom-input">{{ placeholder }}</label>
<p *ngIf="maxLength">{{ myInput.value.length }} / {{ maxLength }}</p> <p *ngIf="maxLength">{{ myInput.value.length }} / {{ maxLength }}</p>
</div> </div>
......
...@@ -30,4 +30,15 @@ ...@@ -30,4 +30,15 @@
padding: 15px; padding: 15px;
background-color: #f3f3f4; background-color: #f3f3f4;
min-height: calc(100vh - 202.8px) 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="container-content">
<div class="bg-white mail-box-header"> <div class="bg-white mail-box-header d-flex justify-content-between align-items-start">
<div class="d-flex align-items-center mail-box-header-title"> <div>
<i [class]="['bi', icon]"></i> <div class="d-flex align-items-center mail-box-header-title">
<span>{{ title }}</span> <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> </div>
<span class="mail-box-header-description">{{ message }}</span>
</div> </div>
<div class="bg-white mail-box-content"> <div class="bg-white mail-box-content">
<ng-content></ng-content> <ng-content></ng-content>
......
import { Location } from '@angular/common';
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
@Component({ @Component({
...@@ -15,4 +16,13 @@ export class MailBoxComponent { ...@@ -15,4 +16,13 @@ export class MailBoxComponent {
@Input() @Input()
public message: string = ''; public message: string = '';
@Input()
public btnBack: boolean = false;
constructor(private location: Location) { }
goBack(): void {
this.location.back();
}
} }
...@@ -7,3 +7,60 @@ ...@@ -7,3 +7,60 @@
.btn-save:disabled { .btn-save:disabled {
color: #00000042; 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 @@ ...@@ -2,26 +2,68 @@
<shared-mail-box <shared-mail-box
title="Agentes" title="Agentes"
message="Este mantenimiento permite gestionar los agentes dentro de la agencia" message="Este mantenimiento permite gestionar los agentes dentro de la agencia"
icon="bi-people"> icon="bi-people"
<form class="px-3"> [btnBack]="true">
<form [formGroup]="myForm" (ngSubmit)="onSave()" autocomplete="off" class="px-3">
<p class="mb-0 mt-2 fw-medium">Información personal</p> <p class="mb-0 mt-2 fw-medium">Información personal</p>
<hr class="mt-0"> <hr class="mt-0">
<div class="d-flex flex-column gap-3 mt-4"> <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> <div class="custom-input">
<shared-input [value]="agent.detail" placeholder="Detalles *" [maxLength]="100"></shared-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> </div>
<p class="mb-0 mt-4 fw-medium">Credenciales</p> <p class="mb-0 mt-4 fw-medium">Credenciales</p>
<hr class="mt-0"> <hr class="mt-0">
<div class="d-flex flex-column gap-3 mt-4"> <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> </div>
<hr> <hr>
<div class="d-flex justify-content-end mb-2"> <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> <i class="bi bi-floppy me-1"></i>
<span>Guardar</span> <span>Guardar</span>
</button> </button>
......
...@@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core'; ...@@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core';
import { AgentsService } from '../../services/agent.service'; import { AgentsService } from '../../services/agent.service';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Agent } from '../../interfaces/agent.interface'; import { Agent } from '../../interfaces/agent.interface';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Location } from '@angular/common';
@Component({ @Component({
selector: 'app-agent-add', selector: 'app-agent-add',
...@@ -10,30 +12,118 @@ import { Agent } from '../../interfaces/agent.interface'; ...@@ -10,30 +12,118 @@ import { Agent } from '../../interfaces/agent.interface';
}) })
export class AgentAddComponent implements OnInit { 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 { ngOnInit(): void {
this._activatedRoute.params.subscribe(param => { this._activatedRoute.params.subscribe(param => {
if (param['id']) { if (param['id']) {
const id: number = param['id']; const id: number = param['id'];
const agent = this._supervisorService.getAgentById(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 { } else {
this.agent = this.getEmptyAgent(); this.buildForm();
} }
}) })
} }
getEmptyAgent(): Agent { isValidField(field: string): boolean | undefined {
return { const fieldForm = this.myForm.get(field);
id: 0, return fieldForm?.invalid && fieldForm?.touched;
name: '', }
lastname: '',
detail: '', getErrorMessage(field: string): string | null {
email: '', if (!this.myForm.controls[field]) return null;
password: ''
}; 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 { ...@@ -14,7 +14,7 @@ export class AgentsService {
lastname: 'Doe', lastname: 'Doe',
detail: 'Detail', detail: 'Detail',
email: 'jodoe@gmail.com', email: 'jodoe@gmail.com',
password: '' password: 'password1234'
}, },
{ {
id: 2, id: 2,
...@@ -22,7 +22,7 @@ export class AgentsService { ...@@ -22,7 +22,7 @@ export class AgentsService {
lastname: 'Doe', lastname: 'Doe',
detail: 'Detail', detail: 'Detail',
email: 'jdoe@gmail.com', email: 'jdoe@gmail.com',
password: '' password: 'password1234'
}, },
{ {
id: 3, id: 3,
...@@ -30,7 +30,7 @@ export class AgentsService { ...@@ -30,7 +30,7 @@ export class AgentsService {
lastname: 'Smith', lastname: 'Smith',
detail: 'Detail', detail: 'Detail',
email: 'jsmith@gmail.com', email: 'jsmith@gmail.com',
password: '' password: 'password1234'
}, },
{ {
id: 4, id: 4,
...@@ -38,7 +38,7 @@ export class AgentsService { ...@@ -38,7 +38,7 @@ export class AgentsService {
lastname: 'Smith', lastname: 'Smith',
detail: 'Detail', detail: 'Detail',
email: 'jasmith@gmail.com', email: 'jasmith@gmail.com',
password: '' password: 'password1234'
}, },
{ {
id: 5, id: 5,
...@@ -46,7 +46,7 @@ export class AgentsService { ...@@ -46,7 +46,7 @@ export class AgentsService {
lastname: 'Smith', lastname: 'Smith',
detail: 'Detail', detail: 'Detail',
email: 'jasmith@gmail.com', email: 'jasmith@gmail.com',
password: '' password: 'password1234'
}, },
{ {
id: 6, id: 6,
...@@ -54,7 +54,7 @@ export class AgentsService { ...@@ -54,7 +54,7 @@ export class AgentsService {
lastname: 'Smith', lastname: 'Smith',
detail: 'Detail', detail: 'Detail',
email: 'jasmith@gmail.com', email: 'jasmith@gmail.com',
password: '' password: 'password1234'
} }
]; ];
...@@ -70,6 +70,7 @@ export class AgentsService { ...@@ -70,6 +70,7 @@ export class AgentsService {
} }
saveAgent(agent: Agent): Agent { saveAgent(agent: Agent): Agent {
agent.id = this._agents.length + 1;
this._agents = [...this._agents, agent]; this._agents = [...this._agents, agent];
return agent; return agent;
} }
...@@ -78,13 +79,15 @@ export class AgentsService { ...@@ -78,13 +79,15 @@ export class AgentsService {
let edited: boolean = false; let edited: boolean = false;
this._agents.filter(item => { agent.id = id;
if (item.id === id) {
item.name = agent.name; // Edit agent
item.lastname = agent.lastname; this._agents = this._agents.map(item => {
item.detail = agent.detail; if (item.id == id) {
edited = true; edited = true;
return agent;
} }
return item;
}); });
return edited? agent : null; return edited? agent : null;
......
...@@ -7,6 +7,7 @@ import { AgentsComponent } from './pages/agents/agents.component'; ...@@ -7,6 +7,7 @@ import { AgentsComponent } from './pages/agents/agents.component';
import { HomePageComponent } from './pages/home-page/home-page.component'; import { HomePageComponent } from './pages/home-page/home-page.component';
import { AgentAddComponent } from './pages/agent-add/agent-add.component'; import { AgentAddComponent } from './pages/agent-add/agent-add.component';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
...@@ -21,7 +22,9 @@ import { HttpClientModule } from '@angular/common/http'; ...@@ -21,7 +22,9 @@ import { HttpClientModule } from '@angular/common/http';
CommonModule, CommonModule,
SharedModule, SharedModule,
SupervisorRoutingModule, SupervisorRoutingModule,
HttpClientModule HttpClientModule,
ReactiveFormsModule,
FormsModule
], ],
exports:[ exports:[
SupervisorRoutingModule 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