Paginator & SQL Querries where clauses & city search

This commit is contained in:
2024-07-18 19:02:32 +02:00
parent f88eebe8d3
commit abcde3991d
30 changed files with 850 additions and 421 deletions

View File

@@ -11,9 +11,10 @@ import { filter, Observable, Subject, Subscription } from 'rxjs';
import { User } from '../../../../../bizmatch-server/src/models/db.model';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, emailToDirName, KeycloakUser, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../environments/environment';
import { SearchService } from '../../services/search.service';
import { SharedService } from '../../services/shared.service';
import { UserService } from '../../services/user.service';
import { createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaStateObject, getSessionStorageHandlerWrapper, map2User } from '../../utils/utils';
import { getCriteriaStateObject, getSessionStorageHandlerWrapper, map2User } from '../../utils/utils';
import { DropdownComponent } from '../dropdown/dropdown.component';
import { ModalService } from '../search-modal/modal.service';
@Component({
@@ -46,9 +47,8 @@ export class HeaderComponent {
private sharedService: SharedService,
private breakpointObserver: BreakpointObserver,
private modalService: ModalService,
) {
//this.criteria = onChange(getCriteriaStateObject('business'), getSessionStorageHandlerWrapper(this.activeTabAction));
}
private searchService: SearchService,
) {}
async ngOnInit() {
const token = await this.keycloakService.getToken();
@@ -89,14 +89,18 @@ export class HeaderComponent {
}
ngAfterViewInit() {}
openModal() {
if (this.isActive('/businessListings')) {
this.modalService.showModal(createEmptyBusinessListingCriteria());
} else if (this.isActive('/commercialPropertyListings')) {
this.modalService.showModal(createEmptyCommercialPropertyListingCriteria());
} else if (this.isActive('/brokerListings')) {
this.modalService.showModal(createEmptyUserListingCriteria());
async openModal() {
const accepted = await this.modalService.showModal(this.criteria);
if (accepted) {
this.searchService.search(this.criteria);
}
// if (this.isActive('/businessListings')) {
// this.modalService.showModal(createEmptyBusinessListingCriteria());
// } else if (this.isActive('/commercialPropertyListings')) {
// this.modalService.showModal(createEmptyCommercialPropertyListingCriteria());
// } else if (this.isActive('/brokerListings')) {
// this.modalService.showModal(createEmptyUserListingCriteria());
// }
}
navigateWithState(dest: string, state: any) {
this.router.navigate([dest], { state: state });

View File

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

View File

@@ -0,0 +1,98 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-paginator',
standalone: true,
imports: [CommonModule],
template: `
<nav class="my-2" aria-label="Page navigation">
<ul class="flex justify-center items-center -space-x-px h-8 text-sm">
<li>
<a
(click)="onPageChange(currentPage - 1)"
[class.pointer-events-none]="currentPage === 1"
class="flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
>
<span class="sr-only">Previous</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" />
</svg>
</a>
</li>
<ng-container *ngFor="let page of visiblePages">
<li *ngIf="page !== '...'">
<a
(click)="onPageChange(page)"
[ngClass]="
page === currentPage
? 'z-10 flex items-center justify-center px-3 h-8 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white'
: 'flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white'
"
>
{{ page }}
</a>
</li>
<li *ngIf="page === '...'">
<span class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400">...</span>
</li>
</ng-container>
<li>
<a
(click)="onPageChange(currentPage + 1)"
[class.pointer-events-none]="currentPage === pageCount"
class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
>
<span class="sr-only">Next</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" />
</svg>
</a>
</li>
</ul>
</nav>
`,
})
export class PaginatorComponent implements OnChanges {
@Input() page = 1;
@Input() pageCount = 1;
@Output() pageChange = new EventEmitter<number>();
currentPage = 1;
visiblePages: (number | string)[] = [];
ngOnChanges(changes: SimpleChanges): void {
if (changes['page'] || changes['pageCount']) {
this.currentPage = this.page;
this.updateVisiblePages();
}
}
updateVisiblePages(): void {
const totalPages = this.pageCount;
const current = this.currentPage;
if (totalPages <= 6) {
this.visiblePages = Array.from({ length: totalPages }, (_, i) => i + 1);
} else {
if (current <= 3) {
this.visiblePages = [1, 2, 3, 4, '...', totalPages];
} else if (current >= totalPages - 2) {
this.visiblePages = [1, '...', totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
} else {
this.visiblePages = [1, '...', current - 1, current, current + 1, '...', totalPages];
}
}
}
onPageChange(page: number | string): void {
if (typeof page === 'string') {
return;
}
if (page >= 1 && page <= this.pageCount && page !== this.currentPage) {
this.currentPage = page;
this.pageChange.emit(page);
this.updateVisiblePages();
}
}
}

View File

@@ -28,13 +28,28 @@
</div>
<div>
<label for="city" class="block mb-2 text-sm font-medium text-gray-900">Location - City</label>
<input
<!-- <input
type="text"
id="city"
[(ngModel)]="criteria.city"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="e.g. Houston"
/>
/> -->
<ng-select
class="custom"
[multiple]="false"
[hideSelected]="true"
[trackByFn]="trackByFn"
[minTermLength]="2"
[loading]="cityLoading"
typeToSearchText="Please enter 2 or more characters"
[typeahead]="cityInput$"
[(ngModel)]="criteria.city"
>
@for (city of cities$ | async; track city.id) {
<ng-option [value]="city.city">{{ city.city }} - {{ selectOptions.getStateInitials(city.state) }}</ng-option>
}
</ng-select>
</div>
<div>
@@ -205,13 +220,28 @@
</div>
<div>
<label for="city" class="block mb-2 text-sm font-medium text-gray-900">Location - City</label>
<input
<!-- <input
type="text"
id="city"
[(ngModel)]="criteria.city"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="e.g. Houston"
/>
/> -->
<ng-select
class="custom"
[multiple]="false"
[hideSelected]="true"
[trackByFn]="trackByFn"
[minTermLength]="2"
[loading]="cityLoading"
typeToSearchText="Please enter 2 or more characters"
[typeahead]="cityInput$"
[(ngModel)]="criteria.city"
>
@for (city of cities$ | async; track city.id) {
<ng-option [value]="city.city">{{ city.city }} - {{ selectOptions.getStateInitials(city.state) }}</ng-option>
}
</ng-select>
</div>
<div>
<label for="price" class="block mb-2 text-sm font-medium text-gray-900">Price</label>
@@ -265,7 +295,7 @@
</div>
</div>
</div>
} @if(criteria.criteriaType==='user'){
} @if(criteria.criteriaType==='broker'){
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-4">
<div>
@@ -280,13 +310,28 @@
</div>
<div>
<label for="city" class="block mb-2 text-sm font-medium text-gray-900">Location - City</label>
<input
<!-- <input
type="text"
id="city"
[(ngModel)]="criteria.city"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
placeholder="e.g. Houston"
/>
/> -->
<ng-select
class="custom"
[multiple]="false"
[hideSelected]="true"
[trackByFn]="trackByFn"
[minTermLength]="2"
[loading]="cityLoading"
typeToSearchText="Please enter 2 or more characters"
[typeahead]="cityInput$"
[(ngModel)]="criteria.city"
>
@for (city of cities$ | async; track city.id) {
<ng-option [value]="city.city">{{ city.city }} - {{ selectOptions.getStateInitials(city.state) }}</ng-option>
}
</ng-select>
</div>
</div>
<div class="space-y-4">

View File

@@ -3,4 +3,7 @@
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
height: 46px;
border-radius: 0.5rem;
.ng-value-container .ng-input {
top: 10px;
}
}

View File

@@ -1,7 +1,9 @@
import { AsyncPipe, NgIf } from '@angular/common';
import { Component } from '@angular/core';
import { NgSelectModule } from '@ng-select/ng-select';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, KeyValue, KeyValueStyle, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { catchError, concat, distinctUntilChanged, Observable, of, Subject, switchMap, tap } from 'rxjs';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, GeoResult, KeyValue, KeyValueStyle, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { GeoService } from '../../services/geo.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { SharedModule } from '../../shared/shared/shared.module';
import { ModalService } from './modal.service';
@@ -14,11 +16,15 @@ import { ModalService } from './modal.service';
styleUrl: './search-modal.component.scss',
})
export class SearchModalComponent {
constructor(public selectOptions: SelectOptionsService, public modalService: ModalService) {}
cities$: Observable<GeoResult[]>;
cityLoading = false;
cityInput$ = new Subject<string>();
constructor(public selectOptions: SelectOptionsService, public modalService: ModalService, private geoService: GeoService) {}
ngOnInit() {
this.modalService.message$.subscribe(msg => {
this.criteria = msg;
});
this.loadCities();
}
public criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
@@ -32,6 +38,25 @@ export class SearchModalComponent {
}
}
}
private loadCities() {
this.cities$ = concat(
of([]), // default items
this.cityInput$.pipe(
distinctUntilChanged(),
tap(() => (this.cityLoading = true)),
switchMap(term =>
this.geoService.findCitiesStartingWith(term).pipe(
catchError(() => of([])), // empty list on error
// map(cities => cities.map(city => city.city)), // transform the list of objects to a list of city names
tap(() => (this.cityLoading = false)),
),
),
),
);
}
trackByFn(item: GeoResult) {
return item.id;
}
search() {
console.log('Search criteria:', this.criteria);
}

View File

@@ -2,15 +2,15 @@ import { CommonModule, NgOptimizedImage } from '@angular/common';
import { ChangeDetectorRef, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import onChange from 'on-change';
import { BusinessListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
import { ListingType, UserListingCriteria, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { ImageService } from '../../../services/image.service';
import { ListingsService } from '../../../services/listings.service';
import { SearchService } from '../../../services/search.service';
import { SelectOptionsService } from '../../../services/select-options.service';
import { UserService } from '../../../services/user.service';
import { getCriteriaStateObject, getSessionStorageHandlerWrapper } from '../../../utils/utils';
import { getCriteriaStateObject } from '../../../utils/utils';
@Component({
selector: 'app-broker-listings',
@@ -48,15 +48,23 @@ export class BrokerListingsComponent {
private cdRef: ChangeDetectorRef,
private imageService: ImageService,
private route: ActivatedRoute,
private searchService: SearchService,
) {
this.criteria = onChange(getCriteriaStateObject('broker'), getSessionStorageHandlerWrapper('broker'));
this.route.data.subscribe(async () => {
if (this.router.getCurrentNavigation().extras.state) {
} else {
this.first = this.criteria.page * this.criteria.length;
this.rows = this.criteria.length;
this.criteria = getCriteriaStateObject('broker');
// this.route.data.subscribe(async () => {
// if (this.router.getCurrentNavigation().extras.state) {
// } else {
// this.first = this.criteria.page * this.criteria.length;
// this.rows = this.criteria.length;
// }
// this.init();
// });
this.init();
this.searchService.currentCriteria.subscribe(criteria => {
if (criteria && criteria.criteriaType === 'broker') {
this.criteria = criteria as UserListingCriteria;
this.search();
}
this.init();
});
}
async ngOnInit() {
@@ -73,8 +81,8 @@ export class BrokerListingsComponent {
}
async search() {
const usersReponse = await this.userService.search(this.criteria);
this.users = usersReponse.data;
this.totalRecords = usersReponse.total;
this.users = usersReponse.results;
this.totalRecords = usersReponse.totalCount;
this.cdRef.markForCheck();
this.cdRef.detectChanges();
}

View File

@@ -112,6 +112,7 @@
}
</div>
</div>
<app-paginator [page]="page" [pageCount]="pageCount" (pageChange)="onPageChange($event)"></app-paginator>
<!-- <div class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">

View File

@@ -2,19 +2,20 @@ import { CommonModule } from '@angular/common';
import { ChangeDetectorRef, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import onChange from 'on-change';
import { BusinessListing } from '../../../../../../bizmatch-server/src/models/db.model';
import { BusinessListingCriteria, ListingType, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { BusinessListingCriteria, LISTINGS_PER_PAGE, ListingType, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { PaginatorComponent } from '../../../components/paginator/paginator.component';
import { ImageService } from '../../../services/image.service';
import { ListingsService } from '../../../services/listings.service';
import { SearchService } from '../../../services/search.service';
import { SelectOptionsService } from '../../../services/select-options.service';
import { getCriteriaStateObject, getSessionStorageHandlerWrapper } from '../../../utils/utils';
import { getCriteriaStateObject } from '../../../utils/utils';
@Component({
selector: 'app-business-listings',
standalone: true,
imports: [CommonModule, FormsModule, RouterModule],
imports: [CommonModule, FormsModule, RouterModule, PaginatorComponent],
templateUrl: './business-listings.component.html',
styleUrls: ['./business-listings.component.scss', '../../pages.scss'],
})
@@ -35,6 +36,8 @@ export class BusinessListingsComponent {
rows: number = 12;
env = environment;
public category: 'business' | 'commercialProperty' | 'professionals_brokers' | undefined;
page = 1;
pageCount = 1;
emailToDirName = emailToDirName;
constructor(
public selectOptions: SelectOptionsService,
@@ -44,15 +47,23 @@ export class BusinessListingsComponent {
private cdRef: ChangeDetectorRef,
private imageService: ImageService,
private route: ActivatedRoute,
private searchService: SearchService,
) {
this.criteria = onChange(getCriteriaStateObject('business'), getSessionStorageHandlerWrapper('business'));
this.route.data.subscribe(async () => {
if (this.router.getCurrentNavigation().extras.state) {
} else {
this.first = this.criteria.page * this.criteria.length;
this.rows = this.criteria.length;
this.criteria = getCriteriaStateObject('business');
// this.route.data.subscribe(async () => {
// if (this.router.getCurrentNavigation().extras.state) {
// } else {
// this.first = this.criteria.page * this.criteria.length;
// this.rows = this.criteria.length;
// }
// this.init();
// });
this.init();
this.searchService.currentCriteria.subscribe(criteria => {
if (criteria && criteria.criteriaType === 'business') {
this.criteria = criteria as BusinessListingCriteria;
this.search();
}
this.init();
});
}
async ngOnInit() {
@@ -64,24 +75,25 @@ export class BusinessListingsComponent {
this.states = statesResult.map(ls => ({ name: this.selectOptions.getState(ls.state as string), value: ls.state, count: ls.count }));
this.search();
}
refine() {
this.criteria.start = 0;
this.criteria.page = 0;
this.search();
}
// refine() {
// this.criteria.start = 0;
// this.criteria.page = 0;
// this.search();
// }
async search() {
//this.listings = await this.listingsService.getListingsByPrompt(this.criteria);
const listingReponse = await this.listingsService.getListings(this.criteria, 'business');
this.listings = listingReponse.data;
this.totalRecords = listingReponse.total;
this.listings = listingReponse.results;
this.totalRecords = listingReponse.totalCount;
this.pageCount = this.totalRecords % LISTINGS_PER_PAGE === 0 ? this.totalRecords / LISTINGS_PER_PAGE : Math.floor(this.totalRecords / LISTINGS_PER_PAGE) + 1;
this.cdRef.markForCheck();
this.cdRef.detectChanges();
}
onPageChange(event: any) {
this.criteria.start = event.first;
this.criteria.length = event.rows;
this.criteria.page = event.page;
this.criteria.pageCount = event.pageCount;
onPageChange(page: any) {
this.criteria.start = (page - 1) * LISTINGS_PER_PAGE + 1;
this.criteria.length = LISTINGS_PER_PAGE;
this.criteria.page = page;
// this.criteria.pageCount = event.pageCount;
this.search();
}
imageErrorHandler(listing: ListingType) {

View File

@@ -2,14 +2,14 @@ import { CommonModule } from '@angular/common';
import { ChangeDetectorRef, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import onChange from 'on-change';
import { CommercialPropertyListing } from '../../../../../../bizmatch-server/src/models/db.model';
import { CommercialPropertyListingCriteria } from '../../../../../../bizmatch-server/src/models/main.model';
import { CommercialPropertyListingCriteria, ResponseCommercialPropertyListingArray } from '../../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../../environments/environment';
import { ImageService } from '../../../services/image.service';
import { ListingsService } from '../../../services/listings.service';
import { SearchService } from '../../../services/search.service';
import { SelectOptionsService } from '../../../services/select-options.service';
import { getCriteriaStateObject, getSessionStorageHandlerWrapper } from '../../../utils/utils';
import { getCriteriaStateObject } from '../../../utils/utils';
@Component({
selector: 'app-commercial-property-listings',
@@ -43,15 +43,23 @@ export class CommercialPropertyListingsComponent {
private cdRef: ChangeDetectorRef,
private imageService: ImageService,
private route: ActivatedRoute,
private searchService: SearchService,
) {
this.criteria = onChange(getCriteriaStateObject('commercialProperty'), getSessionStorageHandlerWrapper('commercialProperty'));
this.route.data.subscribe(async () => {
if (this.router.getCurrentNavigation().extras.state) {
} else {
this.first = this.criteria.page * this.criteria.length;
this.rows = this.criteria.length;
this.criteria = getCriteriaStateObject('commercialProperty');
// this.route.data.subscribe(async () => {
// if (this.router.getCurrentNavigation().extras.state) {
// } else {
// this.first = this.criteria.page * this.criteria.length;
// this.rows = this.criteria.length;
// }
// this.init();
// });
this.init();
this.searchService.currentCriteria.subscribe(criteria => {
if (criteria && criteria.criteriaType === 'commercialProperty') {
this.criteria = criteria as CommercialPropertyListingCriteria;
this.search();
}
this.init();
});
}
async ngOnInit() {}
@@ -67,8 +75,8 @@ export class CommercialPropertyListingsComponent {
}
async search() {
const listingReponse = await this.listingsService.getListings(this.criteria, 'commercialProperty');
this.listings = listingReponse.data;
this.totalRecords = listingReponse.total;
this.listings = (<ResponseCommercialPropertyListingArray>listingReponse).results;
this.totalRecords = (<ResponseCommercialPropertyListingArray>listingReponse).totalCount;
this.cdRef.markForCheck();
this.cdRef.detectChanges();
}

View File

@@ -1,18 +1,18 @@
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
export interface GeoResult { city: string; state: string; state_code: string }
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { GeoResult } from '../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class GeoService {
private apiBaseUrl = environment.apiBaseUrl;
constructor(private http: HttpClient) { }
constructor(private http: HttpClient) {}
findCitiesStartingWith(prefix:string, state?:string):Observable<GeoResult[]>{
const stateString = state?`/${state}`:''
findCitiesStartingWith(prefix: string, state?: string): Observable<GeoResult[]> {
const stateString = state ? `/${state}` : '';
return this.http.get<GeoResult[]>(`${this.apiBaseUrl}/bizmatch/geo/${prefix}${stateString}`);
}
}

View File

@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, UserListingCriteria } from '../../../../bizmatch-server/src/models/main.model';
@Injectable({
providedIn: 'root',
})
export class SearchService {
private criteriaSource = new BehaviorSubject<BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria>(null);
currentCriteria = this.criteriaSource.asObservable();
constructor() {}
search(criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria): void {
this.criteriaSource.next(criteria);
}
}

View File

@@ -39,6 +39,9 @@ export class SelectOptionsService {
getState(value: string): string {
return this.states.find(l => l.value === value)?.name;
}
getStateInitials(name: string): string {
return this.states.find(l => l.name === name?.toUpperCase())?.value;
}
getBusiness(value: string): string {
return this.typesOfBusiness.find(t => t.value === value)?.name;
}

View File

@@ -124,8 +124,8 @@ export function createEmptyCommercialPropertyListingCriteria(): CommercialProper
prompt: '',
criteriaType: 'commercialProperty',
county: '',
minPrice: 0,
maxPrice: 0,
minPrice: null,
maxPrice: null,
title: '',
};
}
@@ -139,7 +139,7 @@ export function createEmptyUserListingCriteria(): UserListingCriteria {
city: '',
types: [],
prompt: '',
criteriaType: 'user',
criteriaType: 'broker',
firstname: '',
lastname: '',
companyName: '',