+ @if (criteria.radius){
+
-
-
-
+ }
+
+ @if(getNumberOfFiltersSet()>0 && numberOfResults$){
+
+ }@else {
+
+ }
}
diff --git a/bizmatch/src/app/pages/home/home.component.scss b/bizmatch/src/app/pages/home/home.component.scss
index 0f99c9e..7d4bd35 100644
--- a/bizmatch/src/app/pages/home/home.component.scss
+++ b/bizmatch/src/app/pages/home/home.component.scss
@@ -35,7 +35,8 @@ select {
}
:host ::ng-deep .ng-select.ng-select-single .ng-select-container {
height: 48px;
- border: unset;
+ border: none;
+ background-color: transparent;
.ng-value-container .ng-input {
top: 10px;
}
@@ -43,13 +44,6 @@ select {
display: none;
}
}
-.flex-1-1-2 {
- flex: 1 1 2%;
-}
-// .light {
-// color: #999;
-// }
-// component.css
select {
color: #000; /* Standard-Textfarbe für das Dropdown */
// background-color: #fff; /* Hintergrundfarbe für das Dropdown */
diff --git a/bizmatch/src/app/pages/home/home.component.ts b/bizmatch/src/app/pages/home/home.component.ts
index 7578826..1f36c36 100644
--- a/bizmatch/src/app/pages/home/home.component.ts
+++ b/bizmatch/src/app/pages/home/home.component.ts
@@ -3,17 +3,20 @@ import { ChangeDetectorRef, Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { NgSelectModule } from '@ng-select/ng-select';
+import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { KeycloakService } from 'keycloak-angular';
import onChange from 'on-change';
-import { catchError, concat, distinctUntilChanged, Observable, of, Subject, switchMap, tap } from 'rxjs';
-import { BusinessListingCriteria, CommercialPropertyListingCriteria, GeoResult, KeycloakUser, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
+import { catchError, concat, debounceTime, distinctUntilChanged, Observable, of, Subject, Subscription, switchMap, tap } from 'rxjs';
+import { BusinessListingCriteria, CityAndStateResult, CommercialPropertyListingCriteria, GeoResult, KeycloakUser, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { ModalService } from '../../components/search-modal/modal.service';
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 { getCriteriaStateObject, map2User } from '../../utils/utils';
+import { UserService } from '../../services/user.service';
+import { compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaStateObject, map2User } from '../../utils/utils';
+@UntilDestroy()
@Component({
selector: 'app-home',
standalone: true,
@@ -31,10 +34,12 @@ export class HomeComponent {
isMenuOpen = false;
user: KeycloakUser;
prompt: string;
- cities$: Observable
;
+ cities$: Observable;
cityLoading = false;
cityInput$ = new Subject();
cityOrState = undefined;
+ private criteriaChangeSubscription: Subscription;
+ numberOfResults$: Observable;
public constructor(
private router: Router,
private modalService: ModalService,
@@ -42,10 +47,11 @@ export class HomeComponent {
private activatedRoute: ActivatedRoute,
public selectOptions: SelectOptionsService,
public keycloakService: KeycloakService,
- private listingsService: ListingsService,
private criteriaChangeService: CriteriaChangeService,
private geoService: GeoService,
public cdRef: ChangeDetectorRef,
+ private listingService: ListingsService,
+ private userService: UserService,
) {}
async ngOnInit() {
const token = await this.keycloakService.getToken();
@@ -55,6 +61,7 @@ export class HomeComponent {
this.criteria = this.createEnhancedProxy(getCriteriaStateObject('business'));
this.user = map2User(token);
this.loadCities();
+ this.setupCriteriaChangeListener();
}
async changeTab(tabname: 'business' | 'commercialProperty' | 'broker') {
this.activeTabAction = tabname;
@@ -85,10 +92,11 @@ export class HomeComponent {
});
}
search() {
- const data = { keep: true };
this.router.navigate([`${this.activeTabAction}Listings`]);
}
-
+ private setupCriteriaChangeListener() {
+ this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(untilDestroyed(this), debounceTime(400)).subscribe(() => this.setTotalNumberOfResults());
+ }
login() {
this.keycloakService.login({
redirectUri: window.location.href,
@@ -113,7 +121,7 @@ export class HomeComponent {
// Wenn keine Option ausgewählt ist, setzen Sie types zurück auf ein leeres Array
this.criteria.radius = null;
} else {
- this.criteria.radius = value;
+ this.criteria.radius = parseInt(value);
}
}
async openModal() {
@@ -130,7 +138,8 @@ export class HomeComponent {
distinctUntilChanged(),
tap(() => (this.cityLoading = true)),
switchMap(term =>
- this.geoService.findCitiesStartingWith(term).pipe(
+ //this.geoService.findCitiesStartingWith(term).pipe(
+ this.geoService.findCitiesAndStatesStartingWith(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)),
@@ -142,14 +151,61 @@ export class HomeComponent {
trackByFn(item: GeoResult) {
return item.id;
}
- setCity(city) {
- if (city) {
- this.criteria.city = city.city;
- this.criteria.state = city.state_code;
+ setCityOrState(cityOrState: CityAndStateResult) {
+ if (cityOrState) {
+ if (cityOrState.type === 'state') {
+ this.criteria.state = cityOrState.state_code;
+ } else {
+ this.criteria.city = cityOrState.name;
+ this.criteria.state = cityOrState.state_code;
+ this.criteria.searchType = 'radius';
+ this.criteria.radius = 20;
+ }
} else {
this.criteria.city = null;
this.criteria.radius = null;
this.criteria.searchType = 'exact';
}
}
+ getTypes() {
+ if (this.criteria.criteriaType === 'business') {
+ return this.selectOptions.typesOfBusiness;
+ } else if (this.criteria.criteriaType === 'commercialProperty') {
+ return this.selectOptions.typesOfCommercialProperty;
+ } else {
+ return this.selectOptions.customerSubTypes;
+ }
+ }
+ getPlaceholderLabel() {
+ if (this.criteria.criteriaType === 'business') {
+ return 'Business Type';
+ } else if (this.criteria.criteriaType === 'commercialProperty') {
+ return 'Property Type';
+ } else {
+ return 'Professional Type';
+ }
+ }
+ setTotalNumberOfResults() {
+ if (this.criteria) {
+ console.log(`Getting total number of results for ${this.criteria.criteriaType}`);
+ if (this.criteria.criteriaType === 'business' || this.criteria.criteriaType === 'commercialProperty') {
+ this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria, this.criteria.criteriaType);
+ } else if (this.criteria.criteriaType === 'broker') {
+ this.numberOfResults$ = this.userService.getNumberOfBroker(this.criteria);
+ } else {
+ this.numberOfResults$ = of();
+ }
+ }
+ }
+ getNumberOfFiltersSet() {
+ if (this.criteria?.criteriaType === 'broker') {
+ return compareObjects(createEmptyUserListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius']);
+ } else if (this.criteria?.criteriaType === 'business') {
+ return compareObjects(createEmptyBusinessListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius']);
+ } else if (this.criteria?.criteriaType === 'commercialProperty') {
+ return compareObjects(createEmptyCommercialPropertyListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius']);
+ } else {
+ return 0;
+ }
+ }
}
diff --git a/bizmatch/src/app/services/geo.service.ts b/bizmatch/src/app/services/geo.service.ts
index 61dc069..050cb61 100644
--- a/bizmatch/src/app/services/geo.service.ts
+++ b/bizmatch/src/app/services/geo.service.ts
@@ -1,7 +1,7 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
-import { CountyResult, GeoResult } from '../../../../bizmatch-server/src/models/main.model';
+import { CityAndStateResult, CountyResult, GeoResult } from '../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../environments/environment';
@Injectable({
@@ -15,6 +15,9 @@ export class GeoService {
const stateString = state ? `/${state}` : '';
return this.http.get(`${this.apiBaseUrl}/bizmatch/geo/${prefix}${stateString}`);
}
+ findCitiesAndStatesStartingWith(prefix: string): Observable {
+ return this.http.get(`${this.apiBaseUrl}/bizmatch/geo/citiesandstates/${prefix}`);
+ }
findCountiesStartingWith(prefix: string, states?: string[]): Observable {
return this.http.post(`${this.apiBaseUrl}/bizmatch/geo/counties`, { prefix, states });
}