Validation first Part

This commit is contained in:
Andreas Knuth 2024-07-30 23:23:25 +02:00
parent 55e800009e
commit 2955c034a0
11 changed files with 206 additions and 354 deletions

View File

@ -277,3 +277,7 @@ export function emailToDirName(email: string): string {
return normalizedEmail;
}
export const LISTINGS_PER_PAGE = 12;
export interface ValidationMessage {
field: string;
message: string;
}

View File

@ -0,0 +1 @@
<p>validated-input works!</p>

View File

@ -0,0 +1,72 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-validated-input',
template: `
<div>
<label [for]="id" class="block text-sm font-medium text-gray-700">
{{ label }}
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
</label>
<input
type="text"
[ngModel]="value"
(input)="onInputChange($event)"
(blur)="onTouched()"
[attr.name]="name"
[required]="required"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
</div>
`,
standalone: true,
imports: [CommonModule, FormsModule],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ValidatedInputComponent),
multi: true,
},
],
})
export class ValidatedInputComponent implements ControlValueAccessor {
@Input() label: string = '';
@Input() id: string = '';
@Input() name: string = '';
@Input() type: string = 'text';
@Input() required: boolean = false;
@Input() validationMessage: string = '';
@Input() value: any = '';
@Output() valueChange = new EventEmitter<any>();
onChange: any = () => {};
onTouched: any = () => {};
writeValue(value: any): void {
if (value !== undefined) {
this.value = value;
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
onInputChange(event: Event): void {
const value = (event.target as HTMLInputElement).value;
this.value = value;
this.onChange(value);
this.valueChange.emit(value);
}
setDisabledState?(isDisabled: boolean): void {
// Implementieren Sie dies, wenn Sie die Deaktivierung des Inputs unterstützen möchten
}
}

View File

@ -0,0 +1 @@
<p>validated-select works!</p>

View File

@ -0,0 +1,77 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-validated-select',
template: `
<div>
<label [for]="id" class="block text-sm font-medium text-gray-700">
{{ label }}
<span class="text-red-500 ml-1">{{ validationMessage }}</span>
</label>
<select
[id]="id"
[name]="name"
[ngModel]="value"
(change)="onSelectChange($event)"
(blur)="onTouched()"
[required]="required"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
>
<option value="" disabled selected>Select an option</option>
<option *ngFor="let option of options" [value]="option.value">
{{ option.label }}
</option>
</select>
</div>
`,
standalone: true,
imports: [CommonModule, FormsModule],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ValidatedSelectComponent),
multi: true,
},
],
})
export class ValidatedSelectComponent implements ControlValueAccessor {
@Input() label: string = '';
@Input() id: string = '';
@Input() name: string = '';
@Input() required: boolean = false;
@Input() validationMessage: string = '';
@Input() options: Array<{ value: any; label: string }> = [];
@Input() value: any = '';
@Output() valueChange = new EventEmitter<any>();
onChange: any = () => {};
onTouched: any = () => {};
writeValue(value: any): void {
if (value !== undefined) {
this.value = value;
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
onSelectChange(event: Event): void {
const value = (event.target as HTMLSelectElement).value;
this.value = value;
this.onChange(value);
this.valueChange.emit(value);
}
setDisabledState?(isDisabled: boolean): void {
// Implementieren Sie dies, wenn Sie die Deaktivierung des Selects unterstützen möchten
}
}

View File

@ -6,7 +6,7 @@
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="md:col-span-2">
<label for="email" class="block text-sm font-medium text-gray-700">E-mail (required)</label>
<input type="email" id="email" name="email" [(ngModel)]="user.email" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" />
<input type="email" id="email" name="email" [(ngModel)]="user.email" disabled class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" />
<p class="text-xs text-gray-500 mt-1">You can only modify your email by contacting us at support&#64;bizwatch.net</p>
</div>
@if (isProfessional){
@ -60,23 +60,26 @@
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label for="firstname" class="block text-sm font-medium text-gray-700">First Name</label>
<input type="text" id="firstname" name="firstname" [(ngModel)]="user.firstname" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" />
</div>
<div>
<label for="lastname" class="block text-sm font-medium text-gray-700">Last Name</label>
<input type="text" id="lastname" name="lastname" [(ngModel)]="user.lastname" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" />
</div>
<app-validated-input label="First Name" name="firstname" [(ngModel)]="user.firstname" [required]="true" [validationMessage]="getValidationMessage('firstname')"></app-validated-input>
<app-validated-input label="Last Name" name="lastname" [(ngModel)]="user.lastname" [required]="true" [validationMessage]="getValidationMessage('lastname')"></app-validated-input>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<!-- <div>
<label for="customerType" class="block text-sm font-medium text-gray-700">Customer Type</label>
<select id="customerType" name="customerType" [(ngModel)]="user.customerType" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
<option *ngFor="let type of customerTypes" [value]="type">{{ type | titlecase }}</option>
</select>
</div>
</div> -->
<app-validated-select
label="Customer Type"
id="customerType"
name="customerType"
[(ngModel)]="user.customerType"
[required]="true"
[validationMessage]="getValidationMessage('customerType')"
[options]="customerTypeOptions"
></app-validated-select>
@if (isProfessional){
<div>
<label for="customerSubType" class="block text-sm font-medium text-gray-700">Professional Type</label>
@ -223,7 +226,6 @@
</div>
</div>
<!-- Responsive version for small screens -->
<div class="mt-8 sm:hidden">
<h3 class="text-lg font-medium text-gray-700 mb-1">Membership Level</h3>
<div class="space-y-2">
@ -264,270 +266,5 @@
</div>
}
</div>
<!-- @if(showModal){ -->
<app-image-crop-and-upload [uploadParams]="uploadParams" (uploadFinished)="uploadFinished($event)"></app-image-crop-and-upload>
<app-confirmation></app-confirmation>
<!-- } -->
<!-- <div class="surface-ground px-4 py-8 md:px-6 lg:px-8">
<div class="p-fluid flex flex-column lg:flex-row">
<menu-account></menu-account>
<p-toast></p-toast>
<div class="surface-card p-5 shadow-2 border-round flex-auto">
<div class="text-900 font-semibold text-lg mt-3">Account Details</div>
<p-divider></p-divider>
<div class="flex gap-5 flex-column-reverse md:flex-row">
<div class="flex-auto p-fluid">
@if (user){
<div class="grid">
<div class="mb-4 col-12 md:col-4">
<label for="state" class="block font-medium text-900 mb-2">E-mail (required)</label>
<input id="state" type="text" [disabled]="true" pInputText [(ngModel)]="user.email" />
<p class="font-italic text-xs line-height-1">You can only modify your email by contacting us at support&#64;bizmatch.net</p>
</div>
<div class="mb-4 col-12 md:col-4">
<label for="customerType" class="block font-medium text-900 mb-2">Customer Type</label>
<p-dropdown id="customerType" [options]="selectOptions?.customerTypes" [(ngModel)]="user.customerType" optionLabel="name" optionValue="value" placeholder="State" [style]="{ width: '100%' }"></p-dropdown>
</div>
<div class="mb-4 col-12 md:col-4">
<label for="customerType" class="block font-medium text-900 mb-2">Professional Role</label>
<p-dropdown
id="customerSubType"
[options]="selectOptions?.customerSubTypes"
[(ngModel)]="user.customerSubType"
optionLabel="name"
optionValue="value"
placeholder="State"
[style]="{ width: '100%' }"
></p-dropdown>
</div>
</div>
<div class="grid">
<div class="mb-4 col-12 md:col-6">
<label for="firstname" class="block font-medium text-900 mb-2">First Name</label>
<input id="firstname" type="text" pInputText [(ngModel)]="user.firstname" />
</div>
<div class="mb-4 col-12 md:col-6">
<label for="lastname" class="block font-medium text-900 mb-2">Last Name</label>
<input id="lastname" type="text" pInputText [(ngModel)]="user.lastname" />
</div>
</div>
@if (isProfessional){
<div class="grid">
<div class="mb-4 col-12 md:col-6">
<label for="firstname" class="block font-medium text-900 mb-2">Company Name</label>
<input id="firstname" type="text" pInputText [(ngModel)]="user.companyName" />
</div>
<div class="mb-4 col-12 md:col-6">
<label for="lastname" class="block font-medium text-900 mb-2">Describe yourself</label>
<input id="lastname" type="text" pInputText [(ngModel)]="user.description" />
</div>
</div>
} @if (isProfessional){
<div class="grid">
<div class="mb-4 col-12 md:col-4">
<label for="phoneNumber" class="block font-medium text-900 mb-2">Your Phone Number</label>
<p-inputMask mask="(999) 999-9999" placeholder="(123) 456-7890" [(ngModel)]="user.phoneNumber"></p-inputMask>
</div>
<div class="mb-4 col-12 md:col-4">
<label for="companyWebsite" class="block font-medium text-900 mb-2">Company Website</label>
<input id="companyWebsite" type="text" pInputText [(ngModel)]="user.companyWebsite" />
</div>
<div class="mb-4 col-12 md:col-4">
<label for="companyLocation" class="block font-medium text-900 mb-2">Company Location</label>
<p-autoComplete [(ngModel)]="user.companyLocation" [suggestions]="suggestions" (completeMethod)="search($event)"></p-autoComplete>
</div>
</div>
} @else {
<div class="grid">
<div class="mb-4 col-12 md:col-6">
<label for="phoneNumber" class="block font-medium text-900 mb-2">Your Phone Number</label>
<p-inputMask mask="(999) 999-9999" placeholder="(123) 456-7890" [(ngModel)]="user.phoneNumber"></p-inputMask>
</div>
</div>
} @if (isProfessional){
<div class="mb-4">
<label for="companyOverview" class="block font-medium text-900 mb-2">Company Overview</label>
<p-editor [(ngModel)]="user.companyOverview" [style]="{ height: '320px' }" [modules]="editorModules">
<ng-template pTemplate="header"></ng-template>
</p-editor>
</div>
<div class="mb-4">
<label for="companyOverview" class="block font-medium text-900 mb-2">Services We offer</label>
<p-editor [(ngModel)]="user.offeredServices" [style]="{ height: '320px' }" [modules]="editorModules">
<ng-template pTemplate="header"></ng-template>
</p-editor>
</div>
<div class="mb-4">
<label for="areasServed" class="block font-medium text-900 mb-2">Areas We Serve</label>
@for (areasServed of user.areasServed; track areasServed){
<div class="grid">
<div class="flex col-12 md:col-6">
<p-dropdown
[filter]="true"
filterBy="name"
id="states"
[options]="selectOptions?.states"
[(ngModel)]="areasServed.state"
optionLabel="name"
optionValue="value"
placeholder="State"
[ngStyle]="{ width: '100%' }"
></p-dropdown>
</div>
<div class="flex col-12 md:col-6">
<input id="county" type="text" pInputText [(ngModel)]="areasServed.county" placeholder="Area/County Served" />
</div>
</div>
}
</div>
<div class="field mb-5 col-12 md:col-6 flex align-items-center">
<p-button class="mr-1" icon="pi pi-plus" severity="success" (click)="addArea()"></p-button>
<p-button icon="pi pi-minus" severity="danger" (click)="removeArea()" [disabled]="user.areasServed?.length < 2"></p-button>
<span class="text-xs">&nbsp;(Add more Areas or remove existing ones.)</span>
</div>
<div>
<label for="companyOverview" class="block font-medium text-900 mb-2">Licensed In</label>
@for (licensedIn of user.licensedIn; track licensedIn){
<div class="grid">
<div class="flex col-12 md:col-6">
<p-dropdown
[filter]="true"
filterBy="name"
id="states"
[options]="selectOptions?.states"
[(ngModel)]="licensedIn.state"
optionLabel="name"
optionValue="value"
placeholder="State"
[ngStyle]="{ width: '100%' }"
></p-dropdown>
</div>
<div class="flex col-12 md:col-6">
<input id="registerNo" type="text" pInputText [(ngModel)]="licensedIn.registerNo" placeholder="Licence Number" />
</div>
</div>
}
</div>
<div class="field mb-5 col-12 md:col-6 flex align-items-center">
<p-button class="mr-1" icon="pi pi-plus" severity="success" (click)="addLicence()"></p-button>
<p-button icon="pi pi-minus" severity="danger" (click)="removeLicence()" [disabled]="user.licensedIn?.length < 2"></p-button>
<span class="text-xs">&nbsp;(Add more licenses or remove existing ones.)</span>
</div>
} }
<div>
<button pButton pRipple label="Update Profile" class="w-auto" (click)="updateProfile(user)"></button>
</div>
</div>
@if (isProfessional){
<div>
<div class="flex flex-column align-items-center flex-or mb-8">
<span class="font-medium text-900 mb-2">Company Logo</span>
<span class="font-medium text-xs mb-2">(is shown in every offer)</span>
@if(user?.hasCompanyLogo){
<div class="image-wrap">
<img src="{{ companyLogoUrl }}" class="rounded-profile" />
<fa-icon [icon]="faTrash" (click)="deleteConfirm('logo')"></fa-icon>
</div>
} @else {
<img src="assets/images/placeholder.png" class="rounded-profile" />
}
<p-fileUpload
#companyUpload
mode="basic"
chooseLabel="Upload"
name="file"
[customUpload]="true"
accept="image/*"
[maxFileSize]="maxFileSize"
(onSelect)="select($event, 'company')"
styleClass="p-button-outlined p-button-plain p-button-rounded mt-4"
></p-fileUpload>
</div>
<p-divider></p-divider>
<div class="flex flex-column align-items-center flex-or">
<span class="font-medium text-900 mb-2">Your Profile Picture</span>
@if(user?.hasProfile){
<div class="image-wrap">
<img src="{{ profileUrl }}" class="rounded-profile" />
<fa-icon [icon]="faTrash" (click)="deleteConfirm('profile')"></fa-icon>
</div>
} @else {
<img src="assets/images/person_placeholder.jpg" class="rounded-profile" />
}
<p-fileUpload
#profileUpload
mode="basic"
chooseLabel="Upload"
name="file"
[customUpload]="true"
accept="image/*"
[maxFileSize]="maxFileSize"
(onSelect)="select($event, 'profile')"
styleClass="p-button-outlined p-button-plain p-button-rounded mt-4"
></p-fileUpload>
</div>
</div>
}
</div>
<div class="text-900 font-semibold text-lg mt-3">Membership Level</div>
<p-divider></p-divider>
<p-table [value]="userSubscriptions" [tableStyle]="{ 'min-width': '50rem' }" dataKey="id">
<ng-template pTemplate="header">
<tr>
<th style="width: 5rem"></th>
<th>ID</th>
<th>Level</th>
<th>Start Date</th>
<th>Date Modified</th>
<th>End Date</th>
<th>Status</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-subscription let-expanded="expanded">
<tr>
<td>
<button type="button" pButton pRipple [pRowToggler]="subscription" class="p-button-text p-button-rounded p-button-plain" [icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
</td>
<td>{{ subscription.id }}</td>
<td>{{ subscription.level }}</td>
<td>{{ subscription.start | date }}</td>
<td>{{ subscription.modified | date }}</td>
<td>{{ subscription.end | date }}</td>
<td>{{ subscription.status }}</td>
</tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-subscription>
<tr>
<td colspan="7">
<div class="p-3">
<p-table [value]="subscription.invoices" dataKey="id">
<ng-template pTemplate="header">
<tr>
<th style="width: 5rem"></th>
<th>ID</th>
<th>Date</th>
<th>Price</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-invoice>
<tr>
<td>
<button pButton pRipple icon="pi pi-print" class="p-button-rounded p-button-success mr-2" (click)="printInvoice(invoice)"></button>
</td>
<td>{{ invoice.id }}</td>
<td>{{ invoice.date | date }}</td>
<td>{{ invoice.price | currency }}</td>
<td></td>
<td></td>
</tr>
</ng-template>
</p-table>
</div>
</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
</div>
<p-confirmDialog></p-confirmDialog> -->

View File

@ -1,3 +1,4 @@
import { TitleCasePipe } from '@angular/common';
import { ChangeDetectorRef, Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
@ -8,13 +9,15 @@ import { ImageCropperComponent } from 'ngx-image-cropper';
import { QuillModule } from 'ngx-quill';
import { lastValueFrom } from 'rxjs';
import { User } from '../../../../../../bizmatch-server/src/models/db.model';
import { AutoCompleteCompleteEvent, Invoice, Subscription, UploadParams, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { AutoCompleteCompleteEvent, Invoice, Subscription, UploadParams, ValidationMessage, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { ConfirmationComponent } from '../../../components/confirmation/confirmation.component';
import { ConfirmationService } from '../../../components/confirmation/confirmation.service';
import { ImageCropAndUploadComponent, UploadReponse } from '../../../components/image-crop-and-upload/image-crop-and-upload.component';
import { MessageComponent } from '../../../components/message/message.component';
import { MessageService } from '../../../components/message/message.service';
import { ValidatedInputComponent } from '../../../components/validated-input/validated-input.component';
import { ValidatedSelectComponent } from '../../../components/validated-select/validated-select.component';
import { GeoService } from '../../../services/geo.service';
import { ImageService } from '../../../services/image.service';
import { LoadingService } from '../../../services/loading.service';
@ -28,8 +31,19 @@ import { TOOLBAR_OPTIONS } from '../../utils/defaults';
@Component({
selector: 'app-account',
standalone: true,
imports: [SharedModule, QuillModule, NgxCurrencyDirective, NgSelectModule, ImageCropperComponent, ConfirmationComponent, ImageCropAndUploadComponent, MessageComponent],
providers: [],
imports: [
SharedModule,
QuillModule,
NgxCurrencyDirective,
NgSelectModule,
ImageCropperComponent,
ConfirmationComponent,
ImageCropAndUploadComponent,
MessageComponent,
ValidatedInputComponent,
ValidatedSelectComponent,
],
providers: [TitleCasePipe],
templateUrl: './account.component.html',
styleUrl: './account.component.scss',
})
@ -51,6 +65,9 @@ export class AccountComponent {
toolbar: [['bold', 'italic', 'underline', 'strike'], [{ list: 'ordered' }, { list: 'bullet' }], [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ color: [] }, { background: [] }], ['clean']],
};
uploadParams: UploadParams;
validationMessages: ValidationMessage[] = [];
customerTypeOptions: Array<{ value: string; label: string }> = [];
customerSubTypeOptions: Array<{ value: string; label: string }> = [];
constructor(
public userService: UserService,
private subscriptionService: SubscriptionsService,
@ -65,6 +82,7 @@ export class AccountComponent {
private confirmationService: ConfirmationService,
private messageService: MessageService,
private sharedService: SharedService,
private titleCasePipe: TitleCasePipe,
) {}
async ngOnInit() {
if (this.id) {
@ -95,6 +113,16 @@ export class AccountComponent {
this.userSubscriptions = await lastValueFrom(this.subscriptionService.getAllSubscriptions(this.user.id));
this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
this.companyLogoUrl = this.user.hasCompanyLogo ? `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
this.customerTypeOptions = this.customerTypes.map(type => ({
value: type,
label: this.titleCasePipe.transform(type),
}));
this.customerSubTypeOptions = this.customerSubTypes.map(type => ({
value: type,
label: this.titleCasePipe.transform(type),
}));
}
printInvoice(invoice: Invoice) {}
@ -182,76 +210,8 @@ export class AccountComponent {
});
}
}
// select(event: any, type: 'company' | 'profile') {
// const imageUrl = URL.createObjectURL(event.files[0]);
// this.type = type;
// const config = { aspectRatio: type === 'company' ? stateOptions[0].value : stateOptions[2].value };
// getImageDimensions(imageUrl).then(dimensions => {
// const dialogWidth = getDialogWidth(dimensions);
// this.dialogRef = this.dialogService.open(ImageCropperComponent, {
// data: {
// imageUrl: imageUrl,
// fileUpload: type === 'company' ? this.companyUpload : this.profileUpload,
// config: config,
// ratioVariable: type === 'company' ? true : false,
// },
// header: 'Edit Image',
// width: dialogWidth,
// modal: true,
// closeOnEscape: true,
// keepInViewport: true,
// closable: false,
// });
// this.dialogRef.onClose.subscribe(cropper => {
// if (cropper) {
// this.loadingService.startLoading('uploadImage');
// cropper.getCroppedCanvas().toBlob(async blob => {
// this.imageUploadService.uploadImage(blob, type === 'company' ? 'uploadCompanyLogo' : 'uploadProfile', emailToDirName(this.user.email)).subscribe(
// async event => {
// if (event.type === HttpEventType.Response) {
// this.loadingService.stopLoading('uploadImage');
// if (this.type === 'company') {
// this.user.hasCompanyLogo = true; //
// this.companyLogoUrl = `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`;
// } else {
// this.user.hasProfile = true;
// this.profileUrl = `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`;
// }
// await this.userService.save(this.user);
// }
// },
// error => console.error('Fehler beim Upload:', error),
// );
// });
// }
// });
// });
// }
// this.confirmationService.showConfirmation({
// target: event.target as EventTarget,
// message: `Do you want to delete your ${type === 'logo' ? 'Logo' : 'Profile'} image`,
// header: 'Delete Confirmation',
// icon: 'pi pi-info-circle',
// acceptButtonStyleClass: 'p-button-danger p-button-text',
// rejectButtonStyleClass: 'p-button-text p-button-text',
// acceptIcon: 'none',
// rejectIcon: 'none',
// accept: async () => {
// if (type === 'profile') {
// this.user.hasProfile = false;
// await Promise.all([this.imageService.deleteProfileImagesById(this.user.email), this.userService.save(this.user)]);
// } else {
// this.user.hasCompanyLogo = false;
// await Promise.all([this.imageService.deleteLogoImagesById(this.user.email), this.userService.save(this.user)]);
// }
// this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Image deleted' });
// this.user = await this.userService.getById(this.user.id);
// },
// reject: () => {
// console.log('deny');
// },
// });
getValidationMessage(fieldName: string): string {
const message = this.validationMessages.find(msg => msg.field === fieldName);
return message ? message.message : '';
}
}

View File

@ -74,7 +74,7 @@ export class EditBusinessListingComponent {
}
});
this.typesOfBusiness = selectOptions.typesOfBusiness.map(e => {
return { name: e.name, value: parseInt(e.value) };
return { name: e.name, value: e.value };
});
}
async ngOnInit() {

View File

@ -113,7 +113,7 @@ export class EditCommercialPropertyListingComponent {
}
});
this.typesOfCommercialProperty = selectOptions.typesOfCommercialProperty.map(e => {
return { name: e.name, value: parseInt(e.value) };
return { name: e.name, value: e.value };
});
}
async ngOnInit() {