new Landing page, stripped app
This commit is contained in:
200
bizmatch-client/src/app/components/header/header.component.ts
Normal file
200
bizmatch-client/src/app/components/header/header.component.ts
Normal file
@@ -0,0 +1,200 @@
|
||||
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, HostListener } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NavigationEnd, Router, RouterModule } from '@angular/router';
|
||||
import { faUserGear } from '@fortawesome/free-solid-svg-icons';
|
||||
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
|
||||
import { debounceTime, filter, Observable, Subject, Subscription } from 'rxjs';
|
||||
import { SortByOptions, User } from '../../../../../bizmatch-server/src/models/db.model';
|
||||
import { BusinessListingCriteria, emailToDirName, KeycloakUser, KeyValueAsSortBy } from '../../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../../environments/environment';
|
||||
|
||||
import { SharedService } from '../../services/shared.service';
|
||||
|
||||
import { Collapse, Dropdown } from 'flowbite';
|
||||
import { AuthService } from '../../services/auth.service';
|
||||
import { CriteriaChangeService } from '../../services/criteria-change.service';
|
||||
import { ListingsService } from '../../services/listings.service';
|
||||
import { ModalService } from '../../services/modal.service';
|
||||
import { SearchService } from '../../services/search.service';
|
||||
import { SelectOptionsService } from '../../services/select-options.service';
|
||||
import { UserService } from '../../services/user.service';
|
||||
import { assignProperties, compareObjects, createEmptyBusinessListingCriteria, getCriteriaProxy, map2User } from '../../utils/utils';
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
selector: 'header',
|
||||
imports: [CommonModule, RouterModule, 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;
|
||||
private routerSubscription: Subscription | undefined;
|
||||
baseRoute: string;
|
||||
sortDropdownVisible: boolean;
|
||||
sortByOptions: KeyValueAsSortBy[] = [];
|
||||
numberOfBroker$: Observable<number>;
|
||||
numberOfCommercial$: Observable<number>;
|
||||
constructor(
|
||||
private router: Router,
|
||||
private userService: UserService,
|
||||
private sharedService: SharedService,
|
||||
private breakpointObserver: BreakpointObserver,
|
||||
private modalService: ModalService,
|
||||
private searchService: SearchService,
|
||||
private criteriaChangeService: CriteriaChangeService,
|
||||
public selectOptions: SelectOptionsService,
|
||||
public authService: AuthService,
|
||||
private listingService: ListingsService,
|
||||
) {}
|
||||
@HostListener('document:click', ['$event'])
|
||||
handleGlobalClick(event: Event) {
|
||||
const target = event.target as HTMLElement;
|
||||
if (target.id !== 'sortDropdownButton' && target.id !== 'sortDropdownMobileButton') {
|
||||
this.sortDropdownVisible = false;
|
||||
}
|
||||
}
|
||||
async ngOnInit() {
|
||||
const token = await this.authService.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`;
|
||||
}
|
||||
|
||||
this.sharedService.currentProfilePhoto.subscribe(photoUrl => {
|
||||
this.profileUrl = photoUrl;
|
||||
});
|
||||
|
||||
this.checkCurrentRoute(this.router.url);
|
||||
this.setupSortByOptions();
|
||||
|
||||
this.routerSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: any) => {
|
||||
this.checkCurrentRoute(event.urlAfterRedirects);
|
||||
this.setupSortByOptions();
|
||||
});
|
||||
this.subscription = this.criteriaChangeService.criteriaChange$.pipe(debounceTime(400)).subscribe(() => {
|
||||
this.criteria = getCriteriaProxy(this.baseRoute, this);
|
||||
});
|
||||
this.userService.currentUser.pipe(untilDestroyed(this)).subscribe(u => {
|
||||
this.user = u;
|
||||
});
|
||||
}
|
||||
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 = [];
|
||||
if (this.isProfessionalListing()) {
|
||||
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'professional')];
|
||||
}
|
||||
if (this.isBusinessListing()) {
|
||||
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'business' || s.type === 'listing')];
|
||||
}
|
||||
if (this.isCommercialPropertyListing()) {
|
||||
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => s.type === 'commercial' || s.type === 'listing')];
|
||||
}
|
||||
this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => !s.type)];
|
||||
}
|
||||
ngAfterViewInit() {}
|
||||
|
||||
async openModal() {
|
||||
const modalResult = await this.modalService.showModal(this.criteria);
|
||||
if (modalResult.accepted) {
|
||||
this.searchService.search(this.criteria);
|
||||
} else {
|
||||
this.criteria = assignProperties(this.criteria, modalResult.criteria);
|
||||
}
|
||||
}
|
||||
navigateWithState(dest: string, state: any) {
|
||||
this.router.navigate([dest], { state: state });
|
||||
}
|
||||
|
||||
isActive(route: string): boolean {
|
||||
return this.router.url === route;
|
||||
}
|
||||
isEmailUsUrl(): boolean {
|
||||
return ['/emailUs'].includes(this.router.url);
|
||||
}
|
||||
isFilterUrl(): boolean {
|
||||
return ['/businessListings', '/commercialPropertyListings', '/brokerListings'].includes(this.router.url);
|
||||
}
|
||||
isBusinessListing(): boolean {
|
||||
return ['/businessListings'].includes(this.router.url);
|
||||
}
|
||||
isCommercialPropertyListing(): boolean {
|
||||
return ['/commercialPropertyListings'].includes(this.router.url);
|
||||
}
|
||||
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');
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
closeMenusAndSetCriteria(path: string) {
|
||||
this.closeDropdown();
|
||||
this.closeMobileMenu();
|
||||
const criteria = getCriteriaProxy(path, this);
|
||||
criteria.page = 1;
|
||||
criteria.start = 0;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
getNumberOfFiltersSet() {
|
||||
if (this.criteria?.criteriaType === 'businessListings') {
|
||||
return compareObjects(createEmptyBusinessListingCriteria(), 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;
|
||||
}
|
||||
get isProfessional() {
|
||||
return this.user?.customerType === 'professional';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user