Fehler Hamburger Menu, Backend requests

This commit is contained in:
Timo Knuth 2025-12-08 00:55:01 +01:00
parent 30ecc292cd
commit 0ac17ef155
9 changed files with 87 additions and 19 deletions

View File

@ -46,6 +46,11 @@ export class AppComponent implements AfterViewInit {
} }
// Hier haben Sie Zugriff auf den aktuellen Route-Pfad // Hier haben Sie Zugriff auf den aktuellen Route-Pfad
this.actualRoute = currentRoute.snapshot.url[0].path; this.actualRoute = currentRoute.snapshot.url[0].path;
// Re-initialize Flowbite after navigation to ensure all components are ready
setTimeout(() => {
initFlowbite();
}, 50);
}); });
} }
ngOnInit() { ngOnInit() {
@ -53,8 +58,9 @@ export class AppComponent implements AfterViewInit {
} }
ngAfterViewInit() { ngAfterViewInit() {
// Flowbite wird nicht mehr zentral initialisiert // Initialize Flowbite for dropdowns, modals, and other interactive components
// Drawers funktionieren automatisch durch data-drawer-target Attribute // Note: Drawers work automatically with data-drawer-target attributes
initFlowbite();
} }
@HostListener('window:keydown', ['$event']) @HostListener('window:keydown', ['$event'])

View File

@ -1,7 +1,7 @@
<nav class="bg-white border-neutral-200 dark:bg-neutral-900 print:hidden"> <nav class="bg-white border-neutral-200 dark:bg-neutral-900 print:hidden">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4"> <div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
<a routerLink="/home" class="flex items-center space-x-3 rtl:space-x-reverse"> <a routerLink="/home" class="flex items-center space-x-3 rtl:space-x-reverse">
<img src="assets/images/header-logo.png" class="h-10" alt="BizMatch - Business Marketplace for Buying and Selling Businesses" width="150" height="40" /> <img src="assets/images/header-logo.png" class="h-10 w-auto" alt="BizMatch - Business Marketplace for Buying and Selling Businesses" />
</a> </a>
<div class="flex items-center md:order-2 space-x-3 rtl:space-x-reverse"> <div class="flex items-center md:order-2 space-x-3 rtl:space-x-reverse">
<!-- Filter button --> <!-- Filter button -->

View File

@ -1,10 +1,10 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, HostListener, OnDestroy, OnInit } from '@angular/core'; import { Component, HostListener, OnDestroy, OnInit, AfterViewInit } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { NavigationEnd, Router, RouterModule } from '@angular/router'; import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { faUserGear } from '@fortawesome/free-solid-svg-icons'; import { faUserGear } from '@fortawesome/free-solid-svg-icons';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { Collapse, Dropdown } from 'flowbite'; import { Collapse, Dropdown, initFlowbite } from 'flowbite';
import { filter, Observable, Subject, takeUntil } from 'rxjs'; import { filter, Observable, Subject, takeUntil } from 'rxjs';
import { SortByOptions, User } from '../../../../../bizmatch-server/src/models/db.model'; import { SortByOptions, User } from '../../../../../bizmatch-server/src/models/db.model';
@ -29,7 +29,7 @@ import { ModalService } from '../search-modal/modal.service';
templateUrl: './header.component.html', templateUrl: './header.component.html',
styleUrl: './header.component.scss', styleUrl: './header.component.scss',
}) })
export class HeaderComponent implements OnInit, OnDestroy { export class HeaderComponent implements OnInit, OnDestroy, AfterViewInit {
public buildVersion = environment.buildVersion; public buildVersion = environment.buildVersion;
user$: Observable<KeycloakUser>; user$: Observable<KeycloakUser>;
keycloakUser: KeycloakUser; keycloakUser: KeycloakUser;
@ -285,6 +285,14 @@ export class HeaderComponent implements OnInit, OnDestroy {
}; };
} }
ngAfterViewInit(): void {
// Initialize Flowbite after header DOM is fully rendered
// This ensures all dropdown elements exist before initialization
setTimeout(() => {
initFlowbite();
}, 0);
}
ngOnDestroy() { ngOnDestroy() {
this.destroy$.next(); this.destroy$.next();
this.destroy$.complete(); this.destroy$.complete();

View File

@ -1,7 +1,9 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, forwardRef, Input } from '@angular/core'; import { Component, forwardRef, Input, OnInit, OnDestroy } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgxCurrencyDirective } from 'ngx-currency'; import { NgxCurrencyDirective } from 'ngx-currency';
import { Subject } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { BaseInputComponent } from '../base-input/base-input.component'; import { BaseInputComponent } from '../base-input/base-input.component';
import { TooltipComponent } from '../tooltip/tooltip.component'; import { TooltipComponent } from '../tooltip/tooltip.component';
import { ValidationMessagesService } from '../validation-messages.service'; import { ValidationMessagesService } from '../validation-messages.service';
@ -20,15 +22,39 @@ import { ValidationMessagesService } from '../validation-messages.service';
templateUrl: './validated-price.component.html', templateUrl: './validated-price.component.html',
styles: `:host{width:100%}`, styles: `:host{width:100%}`,
}) })
export class ValidatedPriceComponent extends BaseInputComponent { export class ValidatedPriceComponent extends BaseInputComponent implements OnInit, OnDestroy {
@Input() inputClasses: string; @Input() inputClasses: string;
@Input() placeholder: string = ''; @Input() placeholder: string = '';
@Input() debounceTimeMs: number = 400; // Configurable debounce time in milliseconds
private inputChange$ = new Subject<any>();
private destroy$ = new Subject<void>();
constructor(validationMessagesService: ValidationMessagesService) { constructor(validationMessagesService: ValidationMessagesService) {
super(validationMessagesService); super(validationMessagesService);
} }
override ngOnInit(): void {
// Setup debounced onChange
this.inputChange$
.pipe(
debounceTime(this.debounceTimeMs),
takeUntil(this.destroy$)
)
.subscribe(value => {
this.value = value;
this.onChange(this.value);
});
}
override ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
onInputChange(event: Event): void { onInputChange(event: Event): void {
this.value = !event ? null : event; const newValue = !event ? null : event;
this.onChange(this.value); // Send signal to Subject instead of calling onChange directly
this.inputChange$.next(newValue);
} }
} }

View File

@ -1,5 +1,5 @@
<header class="w-full flex justify-between items-center p-4 bg-white top-0 z-10 h-16 md:h-20"> <header class="w-full flex justify-between items-center p-4 bg-white top-0 z-10 h-16 md:h-20">
<img src="assets/images/header-logo.png" alt="Logo" class="h-8 md:h-10" width="150" height="40" /> <img src="assets/images/header-logo.png" alt="Logo" class="h-8 md:h-10 w-auto" />
<div class="hidden md:flex items-center space-x-4"> <div class="hidden md:flex items-center space-x-4">
@if(user){ @if(user){
<a routerLink="/account" class="text-primary-600 border border-primary-600 px-3 py-2 rounded">Account</a> <a routerLink="/account" class="text-primary-600 border border-primary-600 px-3 py-2 rounded">Account</a>

View File

@ -1,6 +1,13 @@
<div class="container mx-auto px-4 py-8 max-w-4xl"> <div class="container mx-auto px-4 py-8 max-w-4xl">
<div class="bg-white rounded-lg drop-shadow-custom-bg p-6 md:p-8"> <div class="bg-white rounded-lg drop-shadow-custom-bg p-6 md:p-8 relative">
<h1 class="text-3xl font-bold text-neutral-900 mb-6">Privacy Statement</h1> <button
(click)="goBack()"
class="absolute top-4 right-4 md:top-6 md:right-6 w-10 h-10 flex items-center justify-center rounded-full bg-red-600 hover:bg-red-700 text-white transition-colors duration-200"
aria-label="Go back"
>
<i class="fas fa-arrow-left text-lg"></i>
</button>
<h1 class="text-3xl font-bold text-neutral-900 mb-6 pr-14">Privacy Statement</h1>
<section id="content" role="main"> <section id="content" role="main">
<article class="post page"> <article class="post page">

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule, Location } from '@angular/common';
import { SeoService } from '../../services/seo.service'; import { SeoService } from '../../services/seo.service';
@Component({ @Component({
@ -10,7 +10,10 @@ import { SeoService } from '../../services/seo.service';
styleUrls: ['./privacy-statement.component.scss'] styleUrls: ['./privacy-statement.component.scss']
}) })
export class PrivacyStatementComponent implements OnInit { export class PrivacyStatementComponent implements OnInit {
constructor(private seoService: SeoService) {} constructor(
private seoService: SeoService,
private location: Location
) {}
ngOnInit(): void { ngOnInit(): void {
// Set SEO meta tags for Privacy Statement page // Set SEO meta tags for Privacy Statement page
@ -20,4 +23,8 @@ export class PrivacyStatementComponent implements OnInit {
type: 'website' type: 'website'
}); });
} }
goBack(): void {
this.location.back();
}
} }

View File

@ -1,6 +1,13 @@
<div class="container mx-auto px-4 py-8 max-w-4xl"> <div class="container mx-auto px-4 py-8 max-w-4xl">
<div class="bg-white rounded-lg drop-shadow-custom-bg p-6 md:p-8"> <div class="bg-white rounded-lg drop-shadow-custom-bg p-6 md:p-8 relative">
<h1 class="text-3xl font-bold text-neutral-900 mb-6">Terms of Use</h1> <button
(click)="goBack()"
class="absolute top-4 right-4 md:top-6 md:right-6 w-10 h-10 flex items-center justify-center rounded-full bg-red-600 hover:bg-red-700 text-white transition-colors duration-200"
aria-label="Go back"
>
<i class="fas fa-arrow-left text-lg"></i>
</button>
<h1 class="text-3xl font-bold text-neutral-900 mb-6 pr-14">Terms of Use</h1>
<section id="content" role="main"> <section id="content" role="main">
<article class="post page"> <article class="post page">

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule, Location } from '@angular/common';
import { SeoService } from '../../services/seo.service'; import { SeoService } from '../../services/seo.service';
@Component({ @Component({
@ -10,7 +10,10 @@ import { SeoService } from '../../services/seo.service';
styleUrls: ['./terms-of-use.component.scss'] styleUrls: ['./terms-of-use.component.scss']
}) })
export class TermsOfUseComponent implements OnInit { export class TermsOfUseComponent implements OnInit {
constructor(private seoService: SeoService) {} constructor(
private seoService: SeoService,
private location: Location
) {}
ngOnInit(): void { ngOnInit(): void {
// Set SEO meta tags for Terms of Use page // Set SEO meta tags for Terms of Use page
@ -20,4 +23,8 @@ export class TermsOfUseComponent implements OnInit {
type: 'website' type: 'website'
}); });
} }
goBack(): void {
this.location.back();
}
} }