This commit is contained in:
2025-04-06 21:49:44 +02:00
parent 7d64ee11bf
commit 466e1dcdce
44 changed files with 1780 additions and 1520 deletions

View File

@@ -1,14 +1,43 @@
:host {
width: 100%;
// Drawer animation styles
.translate-x-0 {
transform: translateX(0);
}
@media (max-width: 1023px) {
.order-2 {
order: 2;
.translate-x-full {
transform: translateX(100%);
}
// Custom scrollbar for drawers
.overflow-y-auto {
&::-webkit-scrollbar {
width: 6px;
}
.order-3 {
order: 3;
&::-webkit-scrollbar-track {
background-color: #f1f1f1;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: #555;
}
}
// Fix for iOS Safari elastic scroll behavior
.fixed {
-webkit-overflow-scrolling: touch;
}
// Focus styles for accessibility
button:focus,
a:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
section p {
display: block;

View File

@@ -1,9 +1,8 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { initFlowbite } from 'flowbite';
@Component({
selector: 'app-footer',
@@ -12,17 +11,62 @@ import { initFlowbite } from 'flowbite';
templateUrl: './footer.component.html',
styleUrl: './footer.component.scss',
})
export class FooterComponent {
export class FooterComponent implements OnInit {
privacyVisible = false;
termsVisible = false;
currentYear: number = new Date().getFullYear();
isHomeRoute = false;
constructor(private router: Router) {}
ngOnInit() {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
initFlowbite();
this.isHomeRoute = event.url === '/home';
}
});
// Listen for escape key to close drawers
document.addEventListener('keydown', event => {
if (event.key === 'Escape') {
this.closeDrawers();
}
});
}
// Toggle privacy drawer
togglePrivacy() {
this.termsVisible = false; // Close other drawer if open
this.privacyVisible = !this.privacyVisible;
this.toggleBodyScroll();
}
// Toggle terms drawer
toggleTerms() {
this.privacyVisible = false; // Close other drawer if open
this.termsVisible = !this.termsVisible;
this.toggleBodyScroll();
}
// Close all drawers
closeDrawers() {
this.privacyVisible = false;
this.termsVisible = false;
this.toggleBodyScroll();
}
// Prevent body scroll when drawer is open
private toggleBodyScroll() {
if (this.privacyVisible || this.termsVisible) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
}
// Clean up event listener on component destroy
ngOnDestroy() {
document.removeEventListener('keydown', () => {});
document.body.style.overflow = ''; // Ensure body scroll is restored
}
}

View File

@@ -1,7 +1,7 @@
<nav class="bg-white border-gray-200 dark:bg-gray-900 print:hidden">
<div class="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">
<img src="assets/images/header-logo.png" class="h-8" alt="Flowbite Logo" />
<img src="assets/images/header-logo.png" class="h-10" alt="Logo" />
</a>
<div class="flex items-center md:order-2 space-x-3 rtl:space-x-reverse">
<!-- Filter button -->
@@ -36,8 +36,7 @@
</ul>
</div>
</div>
}
<!-- Menu Button ohne Flowbite -->
} @if(!isEmailUsUrl()){
<div class="relative">
<button type="button" class="relative inline-flex justify-center items-center w-8 h-8 rounded-full bg-gray-400 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600" id="user-menu-button" aria-expanded="false" (click)="toggleUserMenu()">
<span class="sr-only">Open user menu</span>
@@ -110,6 +109,7 @@
</div>
}
</div>
}
</div>
</div>
<!-- Mobile filter button -->

View File

@@ -12,7 +12,6 @@ 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';
@@ -37,7 +36,6 @@ export class HeaderComponent {
faUserGear = faUserGear;
profileUrl: string;
env = environment;
private filterDropdown: Dropdown | null = null;
isMobile: boolean = false;
private destroy$ = new Subject<void>();
prompt: string;
@@ -158,34 +156,6 @@ 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');
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();

View File

@@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common';
import { Component, forwardRef, Input } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgxMaskDirective, NgxMaskPipe, provideNgxMask } from 'ngx-mask';
import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
import { BaseInputComponent } from '../base-input/base-input.component';
import { TooltipComponent } from '../tooltip/tooltip.component';
import { ValidationMessagesService } from '../validation-messages.service';
@@ -10,7 +10,7 @@ import { ValidationMessagesService } from '../validation-messages.service';
selector: 'app-validated-input',
templateUrl: './validated-input.component.html',
standalone: true,
imports: [CommonModule, FormsModule, TooltipComponent, NgxMaskDirective, NgxMaskPipe],
imports: [CommonModule, FormsModule, TooltipComponent, NgxMaskDirective],
providers: [
{
provide: NG_VALUE_ACCESSOR,

View File

@@ -1,16 +1 @@
<div>
<label for="type" class="block text-sm font-bold text-gray-700 mb-1 relative w-fit"
>{{ label }} @if(validationMessage){
<div
attr.data-tooltip-target="tooltip-{{ name }}"
class="absolute inline-flex items-center justify-center w-6 h-6 text-xs font-bold text-white bg-red-500 border-2 border-white rounded-full -top-2 dark:border-gray-900 hover:cursor-pointer"
(click)="toggleTooltip($event)"
(touchstart)="toggleTooltip($event)"
>
!
</div>
<app-tooltip id="tooltip-{{ name }}" [text]="validationMessage" [isVisible]="isTooltipVisible"></app-tooltip>
}
</label>
<ng-select [items]="items" bindLabel="name" bindValue="value" [(ngModel)]="value" (ngModelChange)="onInputChange($event)" name="type"> </ng-select>
</div>
<ng-select [items]="items" bindLabel="name" bindValue="value" [(ngModel)]="value" (ngModelChange)="onInputChange($event)" name="type"> </ng-select>