Files
bizmatch-project/bizmatch/src/app/components/header/header.component.ts
2024-07-24 16:16:25 +02:00

185 lines
7.7 KiB
TypeScript

import { BreakpointObserver } from '@angular/cdk/layout';
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { faUserGear } from '@fortawesome/free-solid-svg-icons';
import { Collapse, Dropdown, initFlowbite } from 'flowbite';
import { KeycloakService } from 'keycloak-angular';
import onChange from 'on-change';
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 { CriteriaChangeService } from '../../services/criteria-change.service';
import { SearchService } from '../../services/search.service';
import { SharedService } from '../../services/shared.service';
import { UserService } from '../../services/user.service';
import { compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaStateObject, map2User } from '../../utils/utils';
import { DropdownComponent } from '../dropdown/dropdown.component';
import { ModalService } from '../search-modal/modal.service';
@Component({
selector: 'header',
standalone: true,
imports: [CommonModule, RouterModule, DropdownComponent, FormsModule],
templateUrl: './header.component.html',
styleUrl: './header.component.scss',
})
export class HeaderComponent {
public buildVersion = environment.buildVersion;
user$: Observable<KeycloakUser>;
keycloakUser: KeycloakUser;
user: User;
activeItem;
faUserGear = faUserGear;
profileUrl: string;
env = environment;
private filterDropdown: Dropdown | null = null;
isMobile: boolean = false;
private destroy$ = new Subject<void>();
prompt: string;
private subscription: Subscription;
criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
private routerSubscription: Subscription | undefined;
baseRoute: string;
constructor(
public keycloakService: KeycloakService,
private router: Router,
private userService: UserService,
private sharedService: SharedService,
private breakpointObserver: BreakpointObserver,
private modalService: ModalService,
private searchService: SearchService,
private criteriaChangeService: CriteriaChangeService,
) {}
async ngOnInit() {
const token = await this.keycloakService.getToken();
this.keycloakUser = map2User(token);
if (this.keycloakUser) {
this.user = await this.userService.getByMail(this.keycloakUser?.email);
this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
}
setTimeout(() => {
initFlowbite();
}, 10);
this.sharedService.currentProfilePhoto.subscribe(photoUrl => {
if (photoUrl) {
this.profileUrl = photoUrl;
}
});
this.checkCurrentRoute(this.router.url);
this.routerSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: any) => {
this.checkCurrentRoute(event.urlAfterRedirects);
});
}
private checkCurrentRoute(url: string): void {
this.baseRoute = url.split('/')[1]; // Nimmt den ersten Teil der Route nach dem ersten '/'
const specialRoutes = [, '', ''];
if ('businessListings' === this.baseRoute) {
//this.criteria = onChange(getCriteriaStateObject('business'), getSessionStorageHandlerWrapper('business'));
//this.criteria = onChange(getCriteriaStateObject('business'), this.getSessionStorageHandler);
this.criteria = this.createEnhancedProxy(getCriteriaStateObject('business'));
} else if ('commercialPropertyListings' === this.baseRoute) {
// this.criteria = onChange(getCriteriaStateObject('commercialProperty'), getSessionStorageHandlerWrapper('commercialProperty'));
this.criteria = this.createEnhancedProxy(getCriteriaStateObject('commercialProperty'));
} else if ('brokerListings' === this.baseRoute) {
// this.criteria = onChange(getCriteriaStateObject('broker'), getSessionStorageHandlerWrapper('broker'));
this.criteria = this.createEnhancedProxy(getCriteriaStateObject('broker'));
} else {
this.criteria = undefined;
}
}
private createEnhancedProxy(obj: any) {
const component = this;
const sessionStorageHandler = function (path, value, previous, applyData) {
let criteriaType = '';
if ('/businessListings' === window.location.pathname) {
criteriaType = 'business';
} else if ('/commercialPropertyListings' === window.location.pathname) {
criteriaType = 'commercialProperty';
} else if ('/brokerListings' === window.location.pathname) {
criteriaType = 'broker';
}
sessionStorage.setItem(`${criteriaType}_criteria`, JSON.stringify(this));
};
return onChange(obj, function (path, value, previous, applyData) {
// Call the original sessionStorageHandler
sessionStorageHandler.call(this, path, value, previous, applyData);
// Notify about the criteria change using the component's context
component.criteriaChangeService.notifyCriteriaChange();
});
}
ngAfterViewInit() {}
async openModal() {
const accepted = await this.modalService.showModal(this.criteria);
if (accepted) {
this.searchService.search(this.criteria);
}
}
navigateWithState(dest: string, state: any) {
this.router.navigate([dest], { state: state });
}
login() {
this.keycloakService.login({
redirectUri: window.location.href,
});
}
register() {
this.keycloakService.register({ redirectUri: `${window.location.origin}/account` });
}
isActive(route: string): boolean {
return this.router.url === route;
}
isListingUrl(): boolean {
return ['/businessListings', '/commercialPropertyListings', '/brokerListings'].includes(this.router.url);
}
closeDropdown() {
const dropdownButton = document.getElementById('user-menu-button');
const dropdownMenu = this.user ? document.getElementById('user-login') : document.getElementById('user-unknown');
if (dropdownButton && dropdownMenu) {
const dropdown = new Dropdown(dropdownMenu, dropdownButton);
dropdown.hide();
}
}
closeMobileMenu() {
const targetElement = document.getElementById('navbar-user');
const triggerElement = document.querySelector('[data-collapse-toggle="navbar-user"]');
if (targetElement instanceof HTMLElement && triggerElement instanceof HTMLElement) {
const collapse = new Collapse(targetElement, triggerElement);
collapse.collapse();
}
}
closeMenus() {
this.closeDropdown();
this.closeMobileMenu();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
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;
}
}
}