This commit is contained in:
2025-08-07 16:57:51 -05:00
parent 4efa6c9d77
commit 4dcff1d883
12 changed files with 158 additions and 161 deletions

View File

@@ -6,32 +6,23 @@
<div class="flex items-center md:order-2 space-x-3 rtl:space-x-reverse">
<!-- Filter button -->
@if(isFilterUrl()){
<!-- <button
type="button"
#triggerButton
(click)="openModal()"
id="filterDropdownButton"
class="max-sm:hidden px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-lg hover:bg-gray-100 hover:text-blue-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
>
<i class="fas fa-filter mr-2"></i>Filter ({{ getNumberOfFiltersSet() }})
</button> -->
<!-- Sort button -->
<div class="relative">
<button
type="button"
id="sortDropdownButton"
class="max-sm:hidden px-4 py-2 text-sm font-medium bg-white border border-gray-200 rounded-lg hover:bg-gray-100 hover:text-blue-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
(click)="toggleSortDropdown()"
[ngClass]="{ 'text-blue-500': selectOptions.getSortByOption(criteria?.sortBy) !== 'Sort', 'text-gray-900': selectOptions.getSortByOption(criteria?.sortBy) === 'Sort' }"
[ngClass]="{ 'text-blue-500': selectOptions.getSortByOption(sortBy) !== 'Sort', 'text-gray-900': selectOptions.getSortByOption(sortBy) === 'Sort' }"
>
<i class="fas fa-sort mr-2"></i>{{ selectOptions.getSortByOption(criteria?.sortBy) }}
<i class="fas fa-sort mr-2"></i>{{ selectOptions.getSortByOption(sortBy) }}
</button>
<!-- Sort options dropdown -->
<div *ngIf="sortDropdownVisible" class="absolute right-0 z-50 w-48 md:mt-2 max-md:mt-20 max-md:mr-[-2.5rem] bg-white border border-gray-200 rounded-lg drop-shadow-custom-bg dark:bg-gray-800 dark:border-gray-600">
<ul class="py-1 text-sm text-gray-700 dark:text-gray-200">
@for(item of sortByOptions; track item){
<li (click)="sortBy(item.value)" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer">{{ item.selectName ? item.selectName : item.name }}</li>
<li (click)="sortByFct(item.value)" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer">{{ item.selectName ? item.selectName : item.name }}</li>
}
</ul>
</div>
@@ -217,23 +208,14 @@
</div>
<!-- Mobile filter button -->
<div class="md:hidden flex justify-center pb-4">
<!-- <button
(click)="openModal()"
type="button"
id="filterDropdownMobileButton"
class="w-full mx-4 px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-lg hover:bg-gray-100 hover:text-blue-700 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
>
<i class="fas fa-filter mr-2"></i>Filter ({{ getNumberOfFiltersSet() }})
</button> -->
<!-- Sorting -->
<button
(click)="toggleSortDropdown()"
type="button"
id="sortDropdownMobileButton"
class="mx-4 w-1/2 px-4 py-2 text-sm font-medium bg-white border border-gray-200 rounded-lg hover:bg-gray-100 hover:text-blue-700 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
[ngClass]="{ 'text-blue-500': selectOptions.getSortByOption(criteria?.sortBy) !== 'Sort', 'text-gray-900': selectOptions.getSortByOption(criteria?.sortBy) === 'Sort' }"
[ngClass]="{ 'text-blue-500': selectOptions.getSortByOption(sortBy) !== 'Sort', 'text-gray-900': selectOptions.getSortByOption(sortBy) === 'Sort' }"
>
<i class="fas fa-sort mr-2"></i>{{ selectOptions.getSortByOption(criteria?.sortBy) }}
<i class="fas fa-sort mr-2"></i>{{ selectOptions.getSortByOption(sortBy) }}
</button>
</div>
</nav>

View File

@@ -17,7 +17,7 @@ import { SearchService } from '../../services/search.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { SharedService } from '../../services/shared.service';
import { UserService } from '../../services/user.service';
import { assignProperties, compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
import { assignProperties, createEmptyUserListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
import { DropdownComponent } from '../dropdown/dropdown.component';
import { ModalService } from '../search-modal/modal.service';
@UntilDestroy()
@@ -49,6 +49,7 @@ export class HeaderComponent {
sortByOptions: KeyValueAsSortBy[] = [];
numberOfBroker$: Observable<number>;
numberOfCommercial$: Observable<number>;
sortBy: SortByOptions = null; // Neu: Separate Property
constructor(
private router: Router,
private userService: UserService,
@@ -76,7 +77,7 @@ export class HeaderComponent {
this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
}
this.numberOfBroker$ = this.userService.getNumberOfBroker(createEmptyUserListingCriteria());
this.numberOfCommercial$ = this.listingService.getNumberOfListings(createEmptyCommercialPropertyListingCriteria(), 'commercialProperty');
this.numberOfCommercial$ = this.listingService.getNumberOfListings('commercialProperty');
setTimeout(() => {
initFlowbite();
}, 10);
@@ -87,7 +88,7 @@ export class HeaderComponent {
this.checkCurrentRoute(this.router.url);
this.setupSortByOptions();
this.loadSortBy(); // Neu
this.routerSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: any) => {
this.checkCurrentRoute(event.urlAfterRedirects);
this.setupSortByOptions();
@@ -99,31 +100,56 @@ export class HeaderComponent {
this.user = u;
});
}
private loadSortBy() {
const storedSortBy = sessionStorage.getItem(this.getSortByKey());
this.sortBy = storedSortBy ? (storedSortBy as SortByOptions) : null;
}
private saveSortBy() {
sessionStorage.setItem(this.getSortByKey(), this.sortBy);
}
private getSortByKey(): string {
// Basierend auf Route (für Business/Commercial unterscheiden)
if (this.isBusinessListing()) return 'businessSortBy';
if (this.isCommercialPropertyListing()) return 'commercialSortBy';
if (this.isProfessionalListing()) return 'professionalsSortBy';
return 'defaultSortBy'; // Fallback
}
sortByFct(selectedSortBy: SortByOptions) {
this.sortBy = selectedSortBy;
this.saveSortBy(); // Speichere separat
this.sortDropdownVisible = false;
this.searchService.search(this.criteria.criteriaType); // Neu: Übergebe sortBy separat
}
private checkCurrentRoute(url: string): void {
this.baseRoute = url.split('/')[1]; // Nimmt den ersten Teil der Route nach dem ersten '/'
const specialRoutes = [, '', ''];
this.criteria = getCriteriaProxy(this.baseRoute, this);
// this.searchService.search(this.criteria);
}
setupSortByOptions() {
this.sortByOptions = [];
let storedSortBy = null;
if (this.isProfessionalListing()) {
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'professional')];
storedSortBy = sessionStorage.getItem('professionalsSortBy');
}
if (this.isBusinessListing()) {
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'business' || s.type === 'listing')];
storedSortBy = sessionStorage.getItem('businessSortBy');
}
if (this.isCommercialPropertyListing()) {
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'commercial' || s.type === 'listing')];
storedSortBy = sessionStorage.getItem('commercialSortBy');
}
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => !s.type)];
this.sortBy = storedSortBy && storedSortBy !== 'null' ? (storedSortBy as SortByOptions) : null;
}
ngAfterViewInit() {}
async openModal() {
const modalResult = await this.modalService.showModal(this.criteria);
if (modalResult.accepted) {
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
} else {
this.criteria = assignProperties(this.criteria, modalResult.criteria);
}
@@ -147,9 +173,7 @@ export class HeaderComponent {
isProfessionalListing(): boolean {
return ['/brokerListings'].includes(this.router.url);
}
// isSortingUrl(): boolean {
// return ['/businessListings', '/commercialPropertyListings'].includes(this.router.url);
// }
closeDropdown() {
const dropdownButton = document.getElementById('user-menu-button');
const dropdownMenu = this.user ? document.getElementById('user-login') : document.getElementById('user-unknown');
@@ -180,23 +204,7 @@ export class HeaderComponent {
this.destroy$.next();
this.destroy$.complete();
}
getNumberOfFiltersSet() {
if (this.criteria?.criteriaType === 'brokerListings') {
return compareObjects(createEmptyUserListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius', 'sortBy']);
} else if (this.criteria?.criteriaType === 'businessListings') {
return compareObjects(createEmptyBusinessListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius', 'sortBy']);
} else if (this.criteria?.criteriaType === 'commercialPropertyListings') {
return compareObjects(createEmptyCommercialPropertyListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius', 'sortBy']);
} else {
return 0;
}
}
sortBy(sortBy: SortByOptions) {
this.criteria.sortBy = sortBy;
this.sortDropdownVisible = false;
this.searchService.search(this.criteria);
}
toggleSortDropdown() {
this.sortDropdownVisible = !this.sortDropdownVisible;
}

View File

@@ -95,11 +95,11 @@ export class SearchModalCommercialComponent {
this.criteria.title = null;
break;
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
clearFilter() {
resetCommercialPropertyListingCriteria(this.criteria);
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
// Handle category change
onCategoryChange(event: any[]) {
@@ -116,7 +116,7 @@ export class SearchModalCommercialComponent {
this.criteria.types.splice(index, 1);
}
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
private loadCounties() {
this.counties$ = concat(
@@ -135,7 +135,7 @@ export class SearchModalCommercialComponent {
);
}
onCriteriaChange() {
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
setCity(city) {
if (city) {
@@ -146,7 +146,7 @@ export class SearchModalCommercialComponent {
this.criteria.radius = null;
this.criteria.searchType = 'exact';
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
setState(state: string) {
if (state) {
@@ -155,11 +155,11 @@ export class SearchModalCommercialComponent {
this.criteria.state = null;
this.setCity(null);
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
setRadius(radius: number) {
this.criteria.radius = radius;
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
private setupCriteriaChangeListener() {
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
@@ -181,14 +181,14 @@ export class SearchModalCommercialComponent {
}
closeAndSearch() {
this.modalService.accept();
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
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');
this.numberOfResults$ = this.listingService.getNumberOfListings('commercialProperty');
} else {
this.numberOfResults$ = of();
}
@@ -202,7 +202,7 @@ export class SearchModalCommercialComponent {
debouncedSearch() {
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}, 1000);
}
}

View File

@@ -140,12 +140,12 @@ export class SearchModalComponent {
this.criteria.title = null;
break;
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
// Handle category change
onCategoryChange(selectedCategories: string[]) {
this.criteria.types = selectedCategories;
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
// Handle property type change
@@ -159,7 +159,7 @@ export class SearchModalComponent {
this.criteria[value] = true;
}
this.selectedPropertyType = value;
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
// Update selected property type based on current criteria
@@ -181,7 +181,7 @@ export class SearchModalComponent {
this.criteria.types.splice(index, 1);
}
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
private loadCounties() {
this.counties$ = concat(
@@ -200,7 +200,7 @@ export class SearchModalComponent {
);
}
onCriteriaChange() {
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
setCity(city) {
if (city) {
@@ -211,7 +211,7 @@ export class SearchModalComponent {
this.criteria.radius = null;
this.criteria.searchType = 'exact';
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
setState(state: string) {
if (state) {
@@ -220,11 +220,11 @@ export class SearchModalComponent {
this.criteria.state = null;
this.setCity(null);
}
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
setRadius(radius: number) {
this.criteria.radius = radius;
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
private setupCriteriaChangeListener() {
this.criteriaChangeSubscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
@@ -246,7 +246,7 @@ export class SearchModalComponent {
}
closeAndSearch() {
this.modalService.accept();
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
this.close();
}
isTypeOfBusinessClicked(v: KeyValueStyle) {
@@ -259,7 +259,7 @@ export class SearchModalComponent {
if (this.criteria) {
console.log(`Getting total number of results for ${this.criteria.criteriaType}`);
if (this.criteria.criteriaType === 'businessListings' || this.criteria.criteriaType === 'commercialPropertyListings') {
this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria, this.criteria.criteriaType === 'businessListings' ? 'business' : 'commercialProperty');
this.numberOfResults$ = this.listingService.getNumberOfListings(this.criteria.criteriaType === 'businessListings' ? 'business' : 'commercialProperty');
} else if (this.criteria.criteriaType === 'brokerListings') {
//this.numberOfResults$ = this.userService.getNumberOfBroker(this.criteria);
} else {
@@ -270,7 +270,7 @@ export class SearchModalComponent {
clearFilter() {
resetBusinessListingCriteria(this.criteria);
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
close() {
this.modalService.reject(this.backupCriteria);
@@ -282,12 +282,12 @@ export class SearchModalComponent {
// Aktivieren Sie nur die aktuell ausgewählte Checkbox
this.criteria[checkbox] = value;
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}
debouncedSearch() {
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.searchService.search(this.criteria);
this.searchService.search(this.criteria.criteriaType);
}, 1000);
}
}