update message component, bugfixes

This commit is contained in:
2024-08-05 13:31:32 +02:00
parent 4c1b1fbc87
commit 8b71b073be
15 changed files with 1332 additions and 756 deletions

View File

@@ -8,12 +8,12 @@
<app-footer></app-footer>
</div>
<!-- @if (loadingService.isLoading$ | async) {
@if (loadingService.isLoading$ | async) {
<div class="spinner-overlay">
<div class="spinner-container">
<div class="spinner-text" *ngIf="loadingService.loadingText$ | async as loadingText">{{ loadingText }}</div>
</div>
</div>
} -->
}
<app-message-container></app-message-container>
<app-search-modal></app-search-modal>

View File

@@ -1,3 +1,4 @@
import { animate, style, transition, trigger } from '@angular/animations';
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Message } from './message.service';
@@ -7,20 +8,9 @@ import { Message } from './message.service';
standalone: true,
imports: [CommonModule],
template: `
<div [ngClass]="getClasses()" role="alert">
<div [ngClass]="getIconClasses()">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<path [attr.d]="getIconPath()" />
</svg>
<span class="sr-only">{{ getSrText() }}</span>
</div>
<div class="ms-3 text-sm font-normal">{{ message.text }}</div>
<button
type="button"
(click)="onClose()"
class="ms-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex items-center justify-center h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700"
aria-label="Close"
>
<div [@toastAnimation]="'in'" [ngClass]="getClasses()" role="alert">
<div class="ms-3 text-sm font-medium">{{ message.text }}</div>
<button type="button" (click)="onClose()" class="ms-auto -mx-1.5 -my-1.5 rounded-lg p-1.5 inline-flex items-center justify-center h-8 w-8" [ngClass]="getCloseButtonClasses()" aria-label="Close">
<span class="sr-only">Close</span>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
@@ -28,6 +18,12 @@ import { Message } from './message.service';
</button>
</div>
`,
animations: [
trigger('toastAnimation', [
transition(':enter', [style({ transform: 'translateY(100%)', opacity: 0 }), animate('300ms ease-out', style({ transform: 'translateY(0)', opacity: 1 }))]),
transition(':leave', [animate('300ms ease-in', style({ transform: 'translateY(100%)', opacity: 0 }))]),
]),
],
})
export class MessageComponent {
@Input() message!: Message;
@@ -38,51 +34,32 @@ export class MessageComponent {
}
getClasses(): string {
return `flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800 ${this.getSeverityClasses()}`;
return `flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 rounded-lg shadow ${this.getSeverityClasses()}`;
}
getIconClasses(): string {
const baseClasses = 'inline-flex items-center justify-center flex-shrink-0 w-8 h-8 rounded-lg';
getCloseButtonClasses(): string {
switch (this.message.severity) {
case 'success':
return `${baseClasses} text-green-500 bg-green-100 dark:bg-green-800 dark:text-green-200`;
return 'text-green-600 hover:bg-green-200 focus:ring-green-400';
case 'danger':
return `${baseClasses} text-red-500 bg-red-100 dark:bg-red-800 dark:text-red-200`;
return 'text-red-600 hover:bg-red-200 focus:ring-red-400';
case 'warning':
return `${baseClasses} text-orange-500 bg-orange-100 dark:bg-orange-700 dark:text-orange-200`;
}
}
getIconPath(): string {
switch (this.message.severity) {
case 'success':
return 'M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z';
case 'danger':
return 'M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 11.793a1 1 0 1 1-1.414 1.414L10 11.414l-2.293 2.293a1 1 0 0 1-1.414-1.414L8.586 10 6.293 7.707a1 1 0 0 1 1.414-1.414L10 8.586l2.293-2.293a1 1 0 0 1 1.414 1.414L11.414 10l2.293 2.293Z';
case 'warning':
return 'M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM10 15a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-4a1 1 0 0 1-2 0V6a1 1 0 0 1 2 0v5Z';
}
}
getSrText(): string {
switch (this.message.severity) {
case 'success':
return 'Check icon';
case 'danger':
return 'Error icon';
case 'warning':
return 'Warning icon';
return 'text-yellow-600 hover:bg-yellow-200 focus:ring-yellow-400';
default:
return 'text-blue-600 hover:bg-blue-200 focus:ring-blue-400';
}
}
private getSeverityClasses(): string {
switch (this.message.severity) {
case 'success':
return 'border-green-500';
return 'bg-green-100 text-green-700';
case 'danger':
return 'border-red-500';
return 'bg-red-100 text-red-700';
case 'warning':
return 'border-orange-500';
return 'bg-yellow-100 text-yellow-700';
default:
return 'bg-blue-100 text-blue-700';
}
}
}

View File

@@ -15,7 +15,7 @@
type="text"
[id]="name"
[ngModel]="value"
(input)="onInputChange($event)"
(ngModelChange)="onInputChange($event)"
(blur)="onTouched()"
[attr.name]="name"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"

View File

@@ -58,7 +58,7 @@
@for (listing of listings; track listing.id) {
<div class="bg-white rounded-lg shadow-md overflow-hidden">
@if (listing.imageOrder?.length>0){
<img src="{{ env.imageBaseUrl }}/pictures/property/{{ listing.imagePath }}/{{ listing.serialId }}/{{ listing.imageOrder[0] }}?_ts={{ ts }}" alt="Image" class="w-full h-48 object-cover" />
<img src="{{ env.imageBaseUrl }}/pictures/property/{{ listing.imagePath }}/{{ listing.serialId }}/{{ listing.imageOrder[0] }}?_ts={{ getTS() }}" alt="Image" class="w-full h-48 object-cover" />
} @else {
<img src="assets/images/placeholder_properties.jpg" alt="Image" class="w-full h-48 object-cover" />
}

View File

@@ -34,7 +34,6 @@ export class CommercialPropertyListingsComponent {
statesSet = new Set();
state: string;
totalRecords: number = 0;
ts = new Date().getTime();
env = environment;
page = 1;
pageCount = 1;
@@ -85,4 +84,7 @@ export class CommercialPropertyListingsComponent {
reset() {
this.criteria.title = null;
}
getTS() {
return new Date().getTime();
}
}

View File

@@ -9,7 +9,7 @@
<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){
@if (isProfessional || isAdmin()){
<div class="flex flex-row items-center justify-around md:space-x-4">
<div class="flex h-full justify-between flex-col">
<p class="text-sm font-medium text-gray-700 mb-1">Company Logo</p>
@@ -71,8 +71,14 @@
<option *ngFor="let type of customerTypes" [value]="type">{{ type | titlecase }}</option>
</select>
</div> -->
@if (!isAdmin()){
<app-validated-select label="Customer Type" name="customerType" [(ngModel)]="user.customerType" [options]="customerTypeOptions"></app-validated-select>
@if (isProfessional){
}@else{
<div>
<label for="customerType" class="block text-sm font-medium text-gray-700">User Type</label>
<span class="bg-blue-100 text-blue-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300">ADMIN</span>
</div>
} @if (isProfessional){
<!-- <div>
<label for="customerSubType" class="block text-sm font-medium text-gray-700">Professional Type</label>
<select id="customerSubType" name="customerSubType" [(ngModel)]="user.customerSubType" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">

View File

@@ -226,7 +226,7 @@ export class AccountComponent {
const message = this.validationMessages.find(msg => msg.field === fieldName);
return message ? message.message : '';
}
test(value) {
console.log(`--->${value}`);
isAdmin() {
return this.keycloakService.getUserRoles(true).includes('ADMIN');
}
}

View File

@@ -130,6 +130,7 @@
<app-drag-drop-mixed [listing]="listing" (imageOrderChanged)="imageOrderChanged($event)" (imageToDelete)="deleteConfirm($event)"></app-drag-drop-mixed>
<!-- </div> -->
</div>
@if (mode!=='create'){
<div class="bg-white p-4 rounded-lg shadow">
<h2 class="text-lg font-semibold mb-2">Property Pictures</h2>
<p class="text-sm text-gray-500 mb-4">(Pictures can be uploaded once the listing is posted initially)</p>
@@ -144,7 +145,7 @@
</button>
<input type="file" #fileInput style="display: none" (change)="fileChangeEvent($event)" accept="image/*" />
</div>
@if (mode==='create'){
} @if (mode==='create'){
<button (click)="save()" class="bg-blue-500 text-white px-4 py-2 mt-3 rounded-md hover:bg-blue-600">Post Listing</button>
} @else {
<button (click)="save()" class="bg-blue-500 text-white px-4 py-2 mt-3 rounded-md hover:bg-blue-600">Update Listing</button>

View File

@@ -54,7 +54,7 @@ export class EmailUsComponent {
this.messageService.addMessage({
severity: 'danger',
text: 'An error occurred',
duration: 5000,
duration: 50000,
});
if (error.error && Array.isArray(error.error?.message)) {
this.validationMessagesService.updateMessages(error.error.message);