Skip to content

Commit ebf53db

Browse files
committed
feat(REC): modifica listado de auditoria de usuarios/recetas
1 parent 8decdec commit ebf53db

26 files changed

Lines changed: 2915 additions & 391 deletions

src/app/audit/audit.module.ts

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,80 @@
1-
import { BrowserModule } from '@angular/platform-browser';
2-
import { NgModule } from '@angular/core';
31
import { CommonModule } from '@angular/common';
4-
import { ReactiveFormsModule } from '@angular/forms';
52
import { HttpClientModule } from '@angular/common/http';
6-
import { FormsModule } from '@angular/forms';
3+
import { NgModule } from '@angular/core';
4+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
5+
import { BrowserModule } from '@angular/platform-browser';
76

87
import { AuditRoutingModule, routingComponent } from './audit-routing.module';
98
// flex-layout
109
import { FlexLayoutModule } from '@angular/flex-layout';
1110
// material
11+
import { MatAutocompleteModule } from '@angular/material/autocomplete';
12+
import { MatButtonModule } from '@angular/material/button';
1213
import { MatCardModule } from '@angular/material/card';
14+
import { MatCheckboxModule } from '@angular/material/checkbox';
15+
import { MatChipsModule } from '@angular/material/chips';
16+
import { MatNativeDateModule } from '@angular/material/core';
17+
import { MatDatepickerModule } from '@angular/material/datepicker';
18+
import { MatDialogModule } from '@angular/material/dialog';
1319
import { MatFormFieldModule } from '@angular/material/form-field';
20+
import { MatIconModule } from '@angular/material/icon';
1421
import { MatInputModule } from '@angular/material/input';
15-
import { MatButtonModule } from '@angular/material/button';
16-
import { MatSelectModule } from '@angular/material/select';
17-
import { MatAutocompleteModule } from '@angular/material/autocomplete';
18-
import { MatMenuModule } from '@angular/material/menu';
19-
import { MatDatepickerModule } from '@angular/material/datepicker';
20-
import { MatNativeDateModule } from '@angular/material/core';
2122
import { MatListModule } from '@angular/material/list';
22-
import { MatTableModule } from '@angular/material/table';
23-
import { MatIconModule } from '@angular/material/icon';
23+
import { MatMenuModule } from '@angular/material/menu';
2424
import { MatPaginatorModule } from '@angular/material/paginator';
25+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
26+
import { MatRadioModule } from '@angular/material/radio';
27+
import { MatSelectModule } from '@angular/material/select';
28+
import { MatSnackBarModule } from '@angular/material/snack-bar';
2529
import { MatSortModule } from '@angular/material/sort';
30+
import { MatTableModule } from '@angular/material/table';
2631
import { MatTooltipModule } from '@angular/material/tooltip';
27-
import { MatChipsModule } from '@angular/material/chips';
28-
import { MatSnackBarModule } from '@angular/material/snack-bar';
29-
import { MatDialogModule } from '@angular/material/dialog';
30-
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
31-
import { UsersListComponent } from './components/user-list/users-list.component';
32+
import { PatientNamePipe } from '@shared/pipes/patient-name.pipe';
33+
import { DialogReportComponent } from './components/dialog-report/dialog-report.component';
3234
import { PrescriptionListComponent } from './components/prescription-list/prescription-list.component';
35+
import { UserCreateComponent } from './components/user-create/user-create.component';
36+
import { UsersListComponent } from './components/user-list/users-list.component';
3337
import { FormatTimePipe } from './pipes/format-time.pipe';
34-
import { DialogReportComponent } from './components/dialog-report/dialog-report.component';
35-
import { PatientNamePipe } from '@shared/pipes/patient-name.pipe';
3638

3739
@NgModule({
38-
declarations: [
39-
routingComponent,
40-
UsersListComponent,
41-
PrescriptionListComponent,
42-
FormatTimePipe,
43-
DialogReportComponent,
44-
],
45-
imports: [
46-
BrowserModule,
47-
CommonModule,
48-
AuditRoutingModule,
49-
ReactiveFormsModule,
50-
FormsModule,
51-
HttpClientModule,
52-
FlexLayoutModule,
53-
MatCardModule,
54-
MatFormFieldModule,
55-
MatInputModule,
56-
MatButtonModule,
57-
MatSelectModule,
58-
MatAutocompleteModule,
59-
MatMenuModule,
60-
MatDatepickerModule,
61-
MatNativeDateModule,
62-
MatListModule,
63-
MatTableModule,
64-
MatIconModule,
65-
MatTooltipModule,
66-
MatChipsModule,
67-
MatSnackBarModule,
68-
MatDialogModule,
69-
MatProgressSpinnerModule,
70-
MatSortModule,
71-
MatPaginatorModule
72-
],
73-
providers: [PatientNamePipe]
40+
declarations: [
41+
routingComponent,
42+
UsersListComponent,
43+
UserCreateComponent,
44+
PrescriptionListComponent,
45+
FormatTimePipe,
46+
DialogReportComponent,
47+
],
48+
imports: [
49+
BrowserModule,
50+
CommonModule,
51+
AuditRoutingModule,
52+
ReactiveFormsModule,
53+
FormsModule,
54+
HttpClientModule,
55+
FlexLayoutModule,
56+
MatCardModule,
57+
MatFormFieldModule,
58+
MatInputModule,
59+
MatButtonModule,
60+
MatSelectModule,
61+
MatAutocompleteModule,
62+
MatMenuModule,
63+
MatDatepickerModule,
64+
MatNativeDateModule,
65+
MatListModule,
66+
MatTableModule,
67+
MatIconModule,
68+
MatTooltipModule,
69+
MatChipsModule,
70+
MatSnackBarModule,
71+
MatDialogModule,
72+
MatProgressSpinnerModule,
73+
MatSortModule,
74+
MatPaginatorModule,
75+
MatCheckboxModule,
76+
MatRadioModule
77+
],
78+
providers: [PatientNamePipe]
7479
})
7580
export class AuditModule { }
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
<div class="user-create-container">
2+
<mat-card class="create-user-card">
3+
<mat-card-header class="card-header">
4+
<div mat-card-avatar class="header-avatar">
5+
<mat-icon>person_add</mat-icon>
6+
</div>
7+
<mat-card-title class="header-title">Crear Nuevo Usuario</mat-card-title>
8+
<mat-card-subtitle class="header-subtitle">Complete la información del nuevo usuario</mat-card-subtitle>
9+
</mat-card-header>
10+
11+
<mat-divider></mat-divider>
12+
13+
<mat-card-content class="card-content">
14+
<form [formGroup]="userForm" (ngSubmit)="onSave()" class="user-form" autocomplete="off">
15+
16+
<div class="form-section">
17+
<h3 class="section-title">
18+
Tipo de Usuario
19+
</h3>
20+
21+
<div class="form-row">
22+
<mat-form-field appearance="outline" class="full-width">
23+
<mat-label>Roles</mat-label>
24+
<mat-icon matPrefix>admin_panel_settings</mat-icon>
25+
<mat-select formControlName="roles" multiple (selectionChange)="onRoleSelectionChange($event)">
26+
<mat-option *ngFor="let role of getAvailableRoleOptions()" [value]="role.role"
27+
[disabled]="isRoleDisabled(role)" (click)="onRoleOptionClick($event, role)">
28+
<div class="role-option">
29+
<span class="role-indicator" [style.background-color]="role.color"></span>
30+
<span>{{ role.displayName || role.name || role.role }}</span>
31+
</div>
32+
</mat-option>
33+
</mat-select>
34+
<mat-hint>Seleccione el tipo de usuario primero</mat-hint>
35+
<mat-error *ngIf="isFieldInvalid('roles')">
36+
{{ getFieldError('roles') }}
37+
</mat-error>
38+
</mat-form-field>
39+
</div>
40+
</div>
41+
42+
<div class="form-section" *ngIf="hasSelectedRoles()">
43+
<!-- Campo Username -->
44+
<div class="form-row" *ngIf="hasProfessionalRole() || hasOnlyAuditorRole()">
45+
<mat-form-field appearance="outline" class="full-width">
46+
<mat-label>{{ hasOnlyAuditorRole() ? 'Nombre de usuario' : 'Documento (Username)' }}</mat-label>
47+
<mat-icon matPrefix>badge</mat-icon>
48+
<input matInput formControlName="username"
49+
[placeholder]="hasOnlyAuditorRole() ? 'Ingrese el nombre de usuario' : 'Ingrese el número de documento'"
50+
(input)="onUsernameChange($event)">
51+
<mat-icon matSuffix *ngIf="isValidatingUsername" class="validation-icon">
52+
<mat-spinner diameter="20"></mat-spinner>
53+
</mat-icon>
54+
<mat-icon matSuffix *ngIf="!isValidatingUsername && isUsernameValid && hasProfessionalRole()"
55+
class="validation-icon success">check_circle</mat-icon>
56+
<mat-icon matSuffix
57+
*ngIf="!isValidatingUsername && !isUsernameValid && usernameValidationMessage && hasProfessionalRole()"
58+
class="validation-icon error">error</mat-icon>
59+
<mat-hint *ngIf="usernameValidationMessage && hasProfessionalRole()"
60+
[class.success-hint]="isUsernameValid" [class.error-hint]="!isUsernameValid">
61+
{{ usernameValidationMessage }}
62+
</mat-hint>
63+
<mat-error *ngIf="isFieldInvalid('username')">
64+
{{ getFieldError('username') }}
65+
</mat-error>
66+
</mat-form-field>
67+
</div>
68+
69+
<!-- Campo CUIL para farmacias -->
70+
<div class="form-row" *ngIf="hasPharmacyRole()">
71+
<mat-form-field appearance="outline" class="full-width">
72+
<mat-label>CUIL</mat-label>
73+
<mat-icon matPrefix>fingerprint</mat-icon>
74+
<input matInput formControlName="cuil" placeholder="12345678901" maxlength="11"
75+
(input)="onCuilChange($event)">
76+
<mat-icon matSuffix *ngIf="isValidatingCuil" class="validation-icon">
77+
<mat-spinner diameter="20"></mat-spinner>
78+
</mat-icon>
79+
<mat-icon matSuffix *ngIf="!isValidatingCuil && isCuilValid"
80+
class="validation-icon success">check_circle</mat-icon>
81+
<mat-icon matSuffix *ngIf="!isValidatingCuil && !isCuilValid && cuilValidationMessage"
82+
class="validation-icon error">error</mat-icon>
83+
<mat-hint *ngIf="cuilValidationMessage" [class.success-hint]="isCuilValid"
84+
[class.error-hint]="!isCuilValid">
85+
{{ cuilValidationMessage }}
86+
</mat-hint>
87+
<mat-error *ngIf="isFieldInvalid('cuil')">
88+
{{ getFieldError('cuil') }}
89+
</mat-error>
90+
</mat-form-field>
91+
</div>
92+
</div>
93+
94+
<!-- Información del profesional encontrado -->
95+
<div class="form-section" *ngIf="hasProfessionalData()">
96+
<h3 class="section-title">
97+
<mat-icon>person_search</mat-icon>
98+
Profesional Encontrado en Andes
99+
</h3>
100+
101+
<div class="found-data-card">
102+
<div class="professional-info">
103+
<div class="info-row">
104+
<strong>Nombre:</strong> {{ foundProfessionalData.nombre }} {{ foundProfessionalData.apellido }}
105+
</div>
106+
<div class="info-row" *ngIf="foundProfessionalData.cuit">
107+
<strong>CUIL:</strong> {{ foundProfessionalData.cuit }}
108+
</div>
109+
<div class="info-row" *ngIf="foundProfessionalData.documento">
110+
<strong>Documento:</strong> {{ foundProfessionalData.documento }}
111+
</div>
112+
<div class="info-row" *ngIf="foundProfessionalData.sexo">
113+
<strong>Sexo:</strong> {{ foundProfessionalData.sexo }}
114+
</div>
115+
<div class="info-row"
116+
*ngIf="foundProfessionalData.profesiones && foundProfessionalData.profesiones.length">
117+
<strong>Profesiones:</strong>
118+
<span>
119+
<ng-container *ngFor="let profession of foundProfessionalData.profesiones; let last = last">
120+
{{ profession.profesion?.nombre }} (Mat. {{ getProfessionMatricula(profession) }})<span
121+
*ngIf="!last">, </span>
122+
</ng-container>
123+
</span>
124+
</div>
125+
</div>
126+
127+
<button mat-icon-button type="button" (click)="clearFoundData()" class="clear-data-button"
128+
aria-label="Buscar otro profesional">
129+
<mat-icon>clear</mat-icon>
130+
</button>
131+
</div>
132+
</div>
133+
134+
<!-- Información de farmacia encontrada -->
135+
<div class="form-section" *ngIf="hasPharmacyData()">
136+
<h3 class="section-title">
137+
<mat-icon>local_pharmacy</mat-icon>
138+
Farmacia Encontrada en Andes
139+
</h3>
140+
141+
<div class="found-data-card">
142+
<div class="pharmacy-info">
143+
<div class="info-row">
144+
<strong>Denominación:</strong> {{ foundPharmacyData.denominacion || foundPharmacyData.razonSocial }}
145+
</div>
146+
<div class="info-row" *ngIf="foundPharmacyData.cuit">
147+
<strong>CUIT:</strong> {{ foundPharmacyData.cuit }}
148+
</div>
149+
<div class="info-row" *ngIf="foundPharmacyData.DTResponsable">
150+
<strong>Responsable:</strong> {{ foundPharmacyData.DTResponsable }}
151+
</div>
152+
<div class="info-row" *ngIf="foundPharmacyData.matriculaDTResponsable">
153+
<strong>Matrícula:</strong> {{ foundPharmacyData.matriculaDTResponsable }}
154+
</div>
155+
<div class="info-row" *ngIf="foundPharmacyData.domicilio">
156+
<strong>Dirección:</strong>
157+
{{ foundPharmacyData.domicilio.valor }}
158+
<span *ngIf="foundPharmacyData.domicilio.ubicacion">
159+
, {{ foundPharmacyData.domicilio.ubicacion.localidad.nombre }}
160+
<span *ngIf="foundPharmacyData.domicilio.ubicacion.provincia">
161+
, {{ foundPharmacyData.domicilio.ubicacion.provincia.nombre }}
162+
</span>
163+
</span>
164+
</div>
165+
<div class="info-row">
166+
<strong>Estado:</strong>
167+
<span [class.activo]="foundPharmacyData.activo" [class.inactivo]="!foundPharmacyData.activo">
168+
{{ foundPharmacyData.activo ? 'Activa' : 'Inactiva' }}
169+
</span>
170+
</div>
171+
<div class="info-row" *ngIf="foundPharmacyData.telefono">
172+
<strong>Teléfono:</strong> {{ foundPharmacyData.telefono }}
173+
</div>
174+
<div class="info-row" *ngIf="foundPharmacyData.email">
175+
<strong>Email:</strong> {{ foundPharmacyData.email }}
176+
</div>
177+
</div>
178+
179+
<button mat-icon-button type="button" (click)="clearFoundData()" class="clear-data-button"
180+
aria-label="Buscar otra farmacia">
181+
<mat-icon>clear</mat-icon>
182+
</button>
183+
</div>
184+
</div>
185+
186+
<div class="form-section">
187+
<div class="form-row" *ngIf="!hasProfessionalRole() && !hasPharmacyRole() && !hasOnlyAuditorRole()">
188+
<mat-form-field appearance="outline" class="full-width">
189+
<mat-label>Nombre</mat-label>
190+
<mat-icon matPrefix>store</mat-icon>
191+
<input matInput formControlName="businessName" placeholder="Ingrese el nombre del negocio">
192+
<mat-error *ngIf="isFieldInvalid('businessName')">
193+
{{ getFieldError('businessName') }}
194+
</mat-error>
195+
</mat-form-field>
196+
</div>
197+
</div>
198+
<div class="form-section">
199+
<h3 class="section-title">
200+
Información del usuario
201+
</h3>
202+
<div class="form-row">
203+
<mat-form-field appearance="outline" class="full-width">
204+
<mat-label>Email</mat-label>
205+
<mat-icon matPrefix>email</mat-icon>
206+
<input matInput type="email" formControlName="email" placeholder="usuario@ejemplo.com" autocomplete="off"
207+
autocapitalize="none" spellcheck="false" name="no-autocomplete-email">
208+
<mat-error *ngIf="isFieldInvalid('email')">
209+
{{ getFieldError('email') }}
210+
</mat-error>
211+
</mat-form-field>
212+
</div>
213+
214+
<div class="form-row">
215+
<mat-form-field appearance="outline" class="full-width">
216+
<mat-label>Contraseña</mat-label>
217+
<mat-icon matPrefix>lock</mat-icon>
218+
<input matInput type="password" formControlName="password" placeholder="Ingrese la contraseña"
219+
autocomplete="new-password" name="no-autocomplete-password">
220+
<mat-hint>Mínimo 6 caracteres</mat-hint>
221+
<mat-error *ngIf="isFieldInvalid('password')">
222+
{{ getFieldError('password') }}
223+
</mat-error>
224+
</mat-form-field>
225+
</div>
226+
</div>
227+
228+
229+
230+
</form>
231+
</mat-card-content>
232+
233+
<mat-divider></mat-divider>
234+
235+
<mat-card-actions class="card-actions">
236+
<div class="actions-container">
237+
<button mat-stroked-button type="button" (click)="onCancel()" [disabled]="isLoading" class="cancel-button">
238+
<mat-icon>close</mat-icon>
239+
Cancelar
240+
</button>
241+
242+
<button mat-icon-button type="button" (click)="onSave()" [disabled]="isLoading || userForm.invalid"
243+
class="save-button" [style.background-color]="(isLoading || userForm.invalid) ? '#969696' : '#3f51b5'"
244+
[style.color]="'white'">
245+
<div class="button">
246+
<mat-icon *ngIf="!isLoading">save</mat-icon>
247+
<mat-spinner *ngIf="isLoading" diameter="20"></mat-spinner>
248+
{{ isLoading ? 'Guardando...' : 'Crear Usuario' }}
249+
</div>
250+
</button>
251+
</div>
252+
</mat-card-actions>
253+
</mat-card>
254+
</div>

0 commit comments

Comments
 (0)