Filter for commercial properties
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgSelectModule } from '@ng-select/ng-select';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { catchError, concat, debounceTime, distinctUntilChanged, map, Observable, of, Subject, Subscription, switchMap, tap } from 'rxjs';
|
||||
import { CommercialPropertyListingCriteria, CountyResult, GeoResult } from '../../../../../bizmatch-server/src/models/main.model';
|
||||
import { CriteriaChangeService } from '../../services/criteria-change.service';
|
||||
import { GeoService } from '../../services/geo.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, resetCommercialPropertyListingCriteria } from '../../utils/utils';
|
||||
import { ValidatedCityComponent } from '../validated-city/validated-city.component';
|
||||
import { ValidatedPriceComponent } from '../validated-price/validated-price.component';
|
||||
import { ModalService } from './modal.service';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'app-search-modal-commercial',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, NgSelectModule, ValidatedCityComponent, ValidatedPriceComponent],
|
||||
templateUrl: './search-modal-commercial.component.html',
|
||||
styleUrls: ['./search-modal.component.scss'],
|
||||
})
|
||||
export class SearchModalCommercialComponent {
|
||||
@Input()
|
||||
isModal: boolean = true;
|
||||
// cities$: Observable<GeoResult[]>;
|
||||
counties$: Observable<CountyResult[]>;
|
||||
// cityLoading = false;
|
||||
countyLoading = false;
|
||||
// cityInput$ = new Subject<string>();
|
||||
countyInput$ = new Subject<string>();
|
||||
private criteriaChangeSubscription: Subscription;
|
||||
public criteria: CommercialPropertyListingCriteria;
|
||||
private debounceTimeout: any;
|
||||
public backupCriteria: CommercialPropertyListingCriteria = getCriteriaStateObject('businessListings');
|
||||
numberOfResults$: Observable<number>;
|
||||
cancelDisable = false;
|
||||
constructor(
|
||||
public selectOptions: SelectOptionsService,
|
||||
public modalService: ModalService,
|
||||
private geoService: GeoService,
|
||||
private criteriaChangeService: CriteriaChangeService,
|
||||
private listingService: ListingsService,
|
||||
private userService: UserService,
|
||||
private searchService: SearchService,
|
||||
) {}
|
||||
// Define property type options
|
||||
|
||||
selectedPropertyType: string | null = null;
|
||||
selectedPropertyTypeName: string | null = null;
|
||||
ngOnInit() {
|
||||
this.setupCriteriaChangeListener();
|
||||
|
||||
this.modalService.message$.pipe(untilDestroyed(this)).subscribe(msg => {
|
||||
this.criteria = msg as CommercialPropertyListingCriteria;
|
||||
this.backupCriteria = JSON.parse(JSON.stringify(msg));
|
||||
this.setTotalNumberOfResults();
|
||||
});
|
||||
this.modalService.modalVisible$.pipe(untilDestroyed(this)).subscribe(val => {
|
||||
if (val.visible) {
|
||||
this.criteria.page = 1;
|
||||
this.criteria.start = 0;
|
||||
}
|
||||
});
|
||||
// this.loadCities();
|
||||
this.loadCounties();
|
||||
this.modalService.sendCriteria(this.criteria);
|
||||
}
|
||||
hasActiveFilters(): boolean {
|
||||
return !!(this.criteria.state || this.criteria.city || this.criteria.minPrice || this.criteria.maxPrice || this.criteria.types.length || this.criteria.title);
|
||||
}
|
||||
removeFilter(filterType: string) {
|
||||
switch (filterType) {
|
||||
case 'state':
|
||||
this.criteria.state = null;
|
||||
this.setCity(null);
|
||||
break;
|
||||
case 'city':
|
||||
this.criteria.city = null;
|
||||
this.criteria.radius = null;
|
||||
this.criteria.searchType = 'exact';
|
||||
break;
|
||||
case 'price':
|
||||
this.criteria.minPrice = null;
|
||||
this.criteria.maxPrice = null;
|
||||
break;
|
||||
case 'types':
|
||||
this.criteria.types = [];
|
||||
break;
|
||||
case 'title':
|
||||
this.criteria.title = null;
|
||||
break;
|
||||
}
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
clearFilter() {
|
||||
resetCommercialPropertyListingCriteria(this.criteria);
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
// Handle category change
|
||||
onCategoryChange(event: any[]) {
|
||||
this.criteria.types = event;
|
||||
this.onCriteriaChange();
|
||||
}
|
||||
|
||||
categoryClicked(checked: boolean, value: string) {
|
||||
if (checked) {
|
||||
this.criteria.types.push(value);
|
||||
} else {
|
||||
const index = this.criteria.types.findIndex(t => t === value);
|
||||
if (index > -1) {
|
||||
this.criteria.types.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
private loadCounties() {
|
||||
this.counties$ = concat(
|
||||
of([]), // default items
|
||||
this.countyInput$.pipe(
|
||||
distinctUntilChanged(),
|
||||
tap(() => (this.countyLoading = true)),
|
||||
switchMap(term =>
|
||||
this.geoService.findCountiesStartingWith(term).pipe(
|
||||
catchError(() => of([])), // empty list on error
|
||||
map(counties => counties.map(county => county.name)), // transform the list of objects to a list of city names
|
||||
tap(() => (this.countyLoading = false)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
onCriteriaChange() {
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
setCity(city) {
|
||||
if (city) {
|
||||
this.criteria.city = city;
|
||||
this.criteria.state = city.state;
|
||||
} else {
|
||||
this.criteria.city = null;
|
||||
this.criteria.radius = null;
|
||||
this.criteria.searchType = 'exact';
|
||||
}
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
setState(state: string) {
|
||||
if (state) {
|
||||
this.criteria.state = state;
|
||||
} else {
|
||||
this.criteria.state = null;
|
||||
this.setCity(null);
|
||||
}
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
setRadius(radius: number) {
|
||||
this.criteria.radius = radius;
|
||||
this.searchService.search(this.criteria);
|
||||
}
|
||||
private setupCriteriaChangeListener() {
|
||||
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
|
||||
this.setTotalNumberOfResults();
|
||||
this.cancelDisable = true;
|
||||
});
|
||||
}
|
||||
trackByFn(item: GeoResult) {
|
||||
return item.id;
|
||||
}
|
||||
search() {
|
||||
console.log('Search criteria:', this.criteria);
|
||||
}
|
||||
getCounties() {
|
||||
this.geoService.findCountiesStartingWith('');
|
||||
}
|
||||
closeModal() {
|
||||
console.log('Closing modal');
|
||||
}
|
||||
closeAndSearch() {
|
||||
this.modalService.accept();
|
||||
this.searchService.search(this.criteria);
|
||||
this.close();
|
||||
}
|
||||
setTotalNumberOfResults() {
|
||||
if (this.criteria) {
|
||||
console.log(`Getting total number of results for ${this.criteria.criteriaType}`);
|
||||
if (this.criteria.criteriaType === 'commercialPropertyListings') {
|
||||
this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria, 'commercialProperty');
|
||||
} else {
|
||||
this.numberOfResults$ = of();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.modalService.reject(this.backupCriteria);
|
||||
}
|
||||
|
||||
debouncedSearch() {
|
||||
clearTimeout(this.debounceTimeout);
|
||||
this.debounceTimeout = setTimeout(() => {
|
||||
this.searchService.search(this.criteria);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user