Umbau: header & businessListing

This commit is contained in:
Andreas Knuth 2024-07-03 18:51:01 +02:00
parent 958f0afd9b
commit 1ccd1d174c
19 changed files with 246 additions and 304 deletions

View File

@ -43,6 +43,9 @@ export interface UserData {
updated?: Date;
}
export interface BusinessListing {
icon?: string;
iconColor?: string;
logo?: string;
id: string;
userId?: string;
type?: number;

View File

@ -17,7 +17,6 @@ export interface KeyValueStyle {
name: string;
value: string;
icon: string;
bgColorClass: string;
textColorClass: string;
}
export type SelectOption<T = number> = {

View File

@ -5,28 +5,28 @@ import { ImageType, KeyValue, KeyValueStyle } from '../models/main.model.js';
export class SelectOptionsService {
constructor() {}
public typesOfBusiness: Array<KeyValueStyle> = [
{ name: 'Automotive', value: '1', icon: 'fa-solid fa-car', bgColorClass: 'bg-green-100', textColorClass: 'text-green-600' },
{ name: 'Industrial Services', value: '2', icon: 'fa-solid fa-industry', bgColorClass: 'bg-yellow-100', textColorClass: 'text-yellow-600' },
{ name: 'Real Estate', value: '3', icon: 'pi pi-building', bgColorClass: 'bg-blue-100', textColorClass: 'text-blue-600' },
{ name: 'Uncategorized', value: '4', icon: 'pi pi-question', bgColorClass: 'bg-cyan-100', textColorClass: 'text-cyan-600' },
{ name: 'Retail', value: '5', icon: 'fa-solid fa-money-bill-wave', bgColorClass: 'bg-pink-100', textColorClass: 'text-pink-600' },
{ name: 'Oilfield SVE and MFG.', value: '6', icon: 'fa-solid fa-oil-well', bgColorClass: 'bg-indigo-100', textColorClass: 'text-indigo-600' },
{ name: 'Service', value: '7', icon: 'fa-solid fa-umbrella', bgColorClass: 'bg-teal-100', textColorClass: 'text-teal-600' },
{ name: 'Advertising', value: '8', icon: 'fa-solid fa-rectangle-ad', bgColorClass: 'bg-orange-100', textColorClass: 'text-orange-600' },
{ name: 'Agriculture', value: '9', icon: 'fa-solid fa-wheat-awn', bgColorClass: 'bg-bluegray-100', textColorClass: 'text-bluegray-600' },
{ name: 'Franchise', value: '10', icon: 'pi pi-star', bgColorClass: 'bg-purple-100', textColorClass: 'text-purple-600' },
{ name: 'Professional', value: '11', icon: 'fa-solid fa-user-gear', bgColorClass: 'bg-gray-100', textColorClass: 'text-gray-600' },
{ name: 'Manufacturing', value: '12', icon: 'fa-solid fa-industry', bgColorClass: 'bg-red-100', textColorClass: 'text-red-600' },
{ name: 'Food and Restaurant', value: '13', icon: 'fa-solid fa-utensils', bgColorClass: 'bg-primary-100', textColorClass: 'text-primary-600' },
{ name: 'Automotive', value: '1', icon: 'fa-solid fa-car', textColorClass: 'text-green-400' },
{ name: 'Industrial Services', value: '2', icon: 'fa-solid fa-industry', textColorClass: 'text-yellow-400' },
{ name: 'Real Estate', value: '3', icon: 'fa-solid fa-building', textColorClass: 'text-blue-400' },
{ name: 'Uncategorized', value: '4', icon: 'fa-solid fa-question', textColorClass: 'text-cyan-400' },
{ name: 'Retail', value: '5', icon: 'fa-solid fa-money-bill-wave', textColorClass: 'text-pink-400' },
{ name: 'Oilfield SVE and MFG.', value: '6', icon: 'fa-solid fa-oil-well', textColorClass: 'text-indigo-400' },
{ name: 'Service', value: '7', icon: 'fa-solid fa-umbrella', textColorClass: 'text-teal-400' },
{ name: 'Advertising', value: '8', icon: 'fa-solid fa-rectangle-ad', textColorClass: 'text-orange-400' },
{ name: 'Agriculture', value: '9', icon: 'fa-solid fa-wheat-awn', textColorClass: 'text-sky-400' },
{ name: 'Franchise', value: '10', icon: 'fa-solid fa-star', textColorClass: 'text-purple-400' },
{ name: 'Professional', value: '11', icon: 'fa-solid fa-user-gear', textColorClass: 'text-gray-400' },
{ name: 'Manufacturing', value: '12', icon: 'fa-solid fa-industry', textColorClass: 'text-red-400' },
{ name: 'Food and Restaurant', value: '13', icon: 'fa-solid fa-utensils', textColorClass: 'text-amber-700' },
];
public typesOfCommercialProperty: Array<KeyValueStyle> = [
{ name: 'Retail', value: '100', icon: 'fa-solid fa-money-bill-wave', bgColorClass: 'bg-pink-100', textColorClass: 'text-pink-600' },
{ name: 'Land', value: '101', icon: 'pi pi-building', bgColorClass: 'bg-blue-100', textColorClass: 'text-blue-600' },
{ name: 'Industrial', value: '102', icon: 'fa-solid fa-industry', bgColorClass: 'bg-yellow-100', textColorClass: 'text-yellow-600' },
{ name: 'Office', value: '103', icon: 'fa-solid fa-umbrella', bgColorClass: 'bg-teal-100', textColorClass: 'text-teal-600' },
{ name: 'Mixed Use', value: '104', icon: 'fa-solid fa-rectangle-ad', bgColorClass: 'bg-orange-100', textColorClass: 'text-orange-600' },
{ name: 'Multifamily', value: '105', icon: 'pi pi-star', bgColorClass: 'bg-purple-100', textColorClass: 'text-purple-600' },
{ name: 'Uncategorized', value: '106', icon: 'pi pi-question', bgColorClass: 'bg-cyan-100', textColorClass: 'text-cyan-600' },
{ name: 'Retail', value: '100', icon: 'fa-solid fa-money-bill-wave', textColorClass: 'text-pink-400' },
{ name: 'Land', value: '101', icon: 'pi pi-building', textColorClass: 'text-blue-400' },
{ name: 'Industrial', value: '102', icon: 'fa-solid fa-industry', textColorClass: 'text-yellow-400' },
{ name: 'Office', value: '103', icon: 'fa-solid fa-umbrella', textColorClass: 'text-teal-400' },
{ name: 'Mixed Use', value: '104', icon: 'fa-solid fa-rectangle-ad', textColorClass: 'text-orange-400' },
{ name: 'Multifamily', value: '105', icon: 'pi pi-star', textColorClass: 'text-purple-400' },
{ name: 'Uncategorized', value: '106', icon: 'pi pi-question', textColorClass: 'text-cyan-400' },
];
public prices: Array<KeyValue> = [
{ name: '$100K', value: '100000' },

View File

@ -1,11 +1,12 @@
<!-- <div class="container"> -->
<div class="content">
<div [ngClass]="{ 'bg-slate-100': actualRoute !== 'home' }">
@if (actualRoute !=='home' && actualRoute !=='pricing'){
<header></header>
}
<router-outlet></router-outlet>
<app-footer></app-footer>
</div>
<app-footer></app-footer>
<!-- <p-confirmDialog #cd>
<ng-template pTemplate="headless" let-message>
<div class="flex flex-column align-items-center p-5 surface-overlay border-round">

View File

@ -1,13 +1,3 @@
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
flex: 1;
/* Optional: Padding für den Inhalt, um sicherzustellen, dass er nicht direkt am Footer klebt */
// padding-bottom: 20px;
}
.progress-spinner {
position: fixed;
z-index: 999;

View File

@ -25,7 +25,8 @@
</div>
</div>
</div> -->
<footer class="bg-white py-6 px-4 md:px-6 mt-auto">
<footer class="bg-white px-4 py-2 md:px-6 mt-auto w-full">
<div class="container mx-auto flex flex-col lg:flex-row justify-between items-center">
<div class="flex flex-col lg:flex-row items-center mb-4 lg:mb-0">
<img src="assets/images/header-logo.png" alt="BizMatch Logo" class="h-8 mb-2 lg:mb-0 lg:mr-4" />

View File

@ -1,5 +1,7 @@
:host {
height: 192px;
// position: absolute;
// bottom: 0px;
width: 100%;
}
div {
font-size: small;
@ -12,7 +14,7 @@ div {
order: 3;
}
}
p {
section p {
display: block;
margin-block-start: 1em;
margin-block-end: 1em;

View File

@ -16,13 +16,4 @@ export class FooterComponent {
ngOnInit() {
initFlowbite();
}
// constructor(public keycloakService: KeycloakService) {}
// login() {
// this.keycloakService.login({
// redirectUri: window.location.href,
// });
// }
// register() {
// this.keycloakService.register({ redirectUri: `${window.location.origin}/account` });
// }
}

View File

@ -1,4 +1,4 @@
<div class="wrapper">
<!-- <div class="wrapper">
<div class="pl-3 flex align-items-center gap-2">
<a routerLink="/home"><img src="assets/images/header-logo.png" height="40" alt="bizmatch" /></a>
<p-tabMenu [model]="tabItems" ariaLabelledBy="label" styleClass="flex" [activeItem]="activeItem"> </p-tabMenu>
@ -9,4 +9,100 @@
}
<ng-template #empty> </ng-template>
</div>
</div>
</div> -->
<nav class="bg-white border-gray-200 dark:bg-gray-900">
<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">
<img src="assets/images/header-logo.png" class="h-8" alt="Flowbite Logo" />
</a>
<div class="flex items-center md:order-2 space-x-3 md:space-x-0 rtl:space-x-reverse">
<button
type="button"
class="flex text-sm bg-gray-800 rounded-full md:me-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
id="user-menu-button"
aria-expanded="false"
[attr.data-dropdown-toggle]="user ? 'user-login' : 'user-unknown'"
data-dropdown-placement="bottom"
>
<span class="sr-only">Open user menu</span>
@if(user){
<img class="w-8 h-8 rounded-full" src="/docs/images/people/profile-picture-3.jpg" alt="user photo" />
} @else {
<i class="flex justify-center items-center text-stone-50 w-8 h-8 rounded-full fa-solid fa-bars"></i>
}
</button>
<!-- Dropdown menu -->
@if(user){
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600" id="user-login">
<div class="px-4 py-3">
<span class="block text-sm text-gray-900 dark:text-white">Welcome, {{ user.firstName }} </span>
<span class="block text-sm text-gray-500 truncate dark:text-gray-400">{{ user.email }}</span>
</div>
<ul class="py-2" aria-labelledby="user-menu-button">
<li>
<a routerLink="/account" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Account</a>
</li>
<li>
<a routerLink="/createBusinessListing" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Create Listing</a>
</li>
<li>
<a routerLink="/myListings" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Listings</a>
</li>
<li>
<a routerLink="/emailUs" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">EMail Us</a>
</li>
<li>
<a routerLink="/logout" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Logout</a>
</li>
</ul>
</div>
} @else {
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded-lg shadow dark:bg-gray-700 dark:divide-gray-600" id="user-unknown">
<ul class="py-2" aria-labelledby="user-menu-button">
<li>
<a (click)="login()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Log In</a>
</li>
<li>
<a (click)="register()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">Register</a>
</li>
</ul>
</div>
}
<button
data-collapse-toggle="navbar-user"
type="button"
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
aria-controls="navbar-user"
aria-expanded="false"
>
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15" />
</svg>
</button>
</div>
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="navbar-user">
<ul
class="flex flex-col font-medium p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:space-x-8 rtl:space-x-reverse md:flex-row md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700"
>
<li>
<a class="block py-2 px-3 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500" aria-current="page">Businesses</a>
</li>
<li>
<a
class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
>Properties</a
>
</li>
<li>
<a
href="#"
class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700"
>Professionals</a
>
</li>
</ul>
</div>
</div>
</nav>

View File

@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { faUserGear } from '@fortawesome/free-solid-svg-icons';
import { initFlowbite } from 'flowbite';
import { KeycloakService } from 'keycloak-angular';
import { MenuItem } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
@ -33,92 +34,13 @@ export class HeaderComponent {
async ngOnInit() {
const token = await this.keycloakService.getToken();
this.user = map2User(token);
//this.user$ = this.keycloakService
// this.user$.subscribe(u => {
// this.user = u;
this.menuItems = [
{
label: 'User Actions',
icon: 'fas fa-cog',
items: [
{
label: 'Account',
icon: 'pi pi-user',
routerLink: `/account`,
visible: this.keycloakService.isLoggedIn(),
},
{
label: 'Create Listing',
icon: 'pi pi-plus-circle',
routerLink: '/createBusinessListing',
visible: this.keycloakService.isLoggedIn(),
},
{
label: 'My Listings',
icon: 'pi pi-list',
routerLink: '/myListings',
visible: this.keycloakService.isLoggedIn(),
},
{
label: 'My Favorites',
icon: 'pi pi-star',
routerLink: '/myFavorites',
visible: this.keycloakService.isLoggedIn(),
},
{
label: 'EMail Us',
icon: 'fa-regular fa-envelope',
routerLink: '/emailUs',
visible: this.keycloakService.isLoggedIn(),
},
{
label: 'Logout',
icon: 'fa-solid fa-right-from-bracket',
routerLink: '/logout',
visible: this.keycloakService.isLoggedIn(),
},
{
label: 'Login',
icon: 'fa-solid fa-right-from-bracket',
command: () => this.login(),
visible: !this.keycloakService.isLoggedIn(),
},
],
},
];
// });
this.tabItems = [
{
label: 'Businesses for Sale',
routerLink: '/businessListings',
state: {},
},
{
label: 'Commercial Property',
routerLink: '/commercialPropertyListings',
state: {},
},
{
label: 'Professionals/Brokers Directory',
routerLink: '/brokerListings',
state: {},
},
];
this.loginItems = [
{
label: 'Login',
command: () => this.login(),
visible: !this.keycloakService.isLoggedIn(),
},
{
label: 'Register',
command: () => this.register(),
visible: !this.keycloakService.isLoggedIn(),
},
];
this.activeItem = this.tabItems[0];
setTimeout(() => {
initFlowbite();
});
}
ngAfterViewInit() {}
navigateWithState(dest: string, state: any) {
this.router.navigate([dest], { state: state });
}

View File

@ -99,7 +99,7 @@
<div class="col-12 md:col-6 cursor-pointer" [routerLink]="['/details-business-listing', listing.id]">
<div class="p-3 border-1 surface-border border-round surface-card">
<div class="text-900 mb-2">
<span [class]="selectOptions.getBgColorType(listing.type)" class="inline-flex border-circle align-items-center justify-content-center mr-3" style="width: 38px; height: 38px">
<span class="inline-flex border-circle align-items-center justify-content-center mr-3" style="width: 38px; height: 38px">
<i [class]="selectOptions.getIconAndTextColorType(listing.type)" class="pi text-xl"></i>
</span>
<span class="font-medium">{{ selectOptions.getBusiness(listing.type) }}</span>

View File

@ -1,112 +1,13 @@
<!-- <div class="container">
<div class="wrapper">
<div class="py-3 px-6 flex align-items-center justify-content-between relative">
<a routerLink="/home"><img src="../../../assets/images/header-logo.png" alt="Image" height="50" /></a>
<div class="align-items-center flex-grow-1 justify-content-between hidden lg:flex absolute lg:static w-full left-0 top-100 px-6 lg:px-0 shadow-2 lg:shadow-none z-2">
<section></section>
<div class="flex justify-content-between lg:block border-top-1 lg:border-top-none border-gray-800 py-3 lg:py-0 mt-3 lg:mt-0">
@if(keycloakService.isLoggedIn()){
<p-button label="Account" class="ml-3 font-bold" [outlined]="true" severity="secondary" [routerLink]="['/account']"></p-button>
} @else {
<p-button label="Log In" class="ml-3 font-bold" [outlined]="true" severity="secondary" (click)="login()"></p-button>
<p-button label="Register" class="ml-3 font-bold" [outlined]="true" severity="secondary" (click)="register()"></p-button>
}
</div>
</div>
</div>
<div class="px-4 py-8 md:px-6 lg:px-8">
<div class="flex flex-wrap">
<div class="w-12 lg:w-6 p-4">
<h1 class="text-6xl font-bold text-blue-900 mt-0 mb-3">Find businesses for sale</h1>
<p class="text-3xl text-blue-600 mt-0 mb-5">Unlocking Exclusive Opportunities, Empowering Entrepreneurial Dreams</p>
<ul class="list-none p-0 m-0">
<li class="mb-3 flex align-items-center"><i class="pi pi-compass text-yellow-500 text-xl mr-2"></i><span class="text-blue-600 line-height-3">Texas expertise and nationwide presence</span></li>
<li class="mb-3 flex align-items-center"><i class="pi pi-map text-yellow-500 text-xl mr-2"></i><span class="text-blue-600 line-height-3">Industry diversity</span></li>
<li class="mb-3 flex align-items-center"><i class="pi pi-calendar text-yellow-500 text-xl mr-2"></i><span class="text-blue-600 line-height-3">Support throughout the entire process</span></li>
</ul>
</div>
<div class="w-12 lg:w-6 text-center lg:text-right flex">
<div class="mt-5">
<ul class="flex flex-column align-items-left gap-3 px-2 py-3 list-none surface-border">
<li><button pButton pRipple icon="pi pi-user" (click)="changeTab('business')" label="Businesses" [ngClass]="{ 'p-button-text text-700': activeTabAction !== 'business' }"></button></li>
<li>
<button
pButton
pRipple
icon="pi pi-shield"
(click)="changeTab('commercialProperty')"
label="Commercial Property"
[ngClass]="{ 'p-button-text text-700': activeTabAction != 'commercialProperty' }"
></button>
</li>
<li>
<button pButton pRipple icon="pi pi-globe" (click)="changeTab('broker')" label="Professionals/Brokers Directory" [ngClass]="{ 'p-button-text text-700': activeTabAction != 'broker' }"></button>
</li>
</ul>
</div>
<div [ngClass]="{ 'mt-5': activeTabAction === 'business', 'mt-11': activeTabAction === 'commercialProperty', 'mt-22': activeTabAction === 'broker' }">
<div class="flex flex-column align-items-right gap-3 px-2 py-3 my-3 surface-border">
<p-dropdown
[filter]="true"
filterBy="name"
[options]="states"
[(ngModel)]="criteria.state"
optionLabel="name"
optionValue="value"
[showClear]="true"
placeholder="State"
[style]="{ width: '200px' }"
></p-dropdown>
@if(activeTabAction === 'business'){
<p-dropdown
[filter]="true"
filterBy="name"
[options]="selectOptions.typesOfBusiness"
[(ngModel)]="criteria.type"
optionLabel="name"
optionValue="value"
[showClear]="true"
placeholder="Category"
[style]="{ width: '200px' }"
></p-dropdown>
} @if(activeTabAction === 'commercialProperty'){
<p-dropdown
[options]="selectOptions.typesOfCommercialProperty"
[(ngModel)]="criteria.type"
optionLabel="name"
optionValue="value"
[showClear]="true"
placeholder="Category"
[style]="{ width: '200px' }"
></p-dropdown>
} @if(activeTabAction === 'business' || activeTabAction === 'commercialProperty'){
<p-dropdown [options]="selectOptions.prices" [(ngModel)]="criteria.minPrice" optionLabel="name" optionValue="value" [showClear]="true" placeholder="Min Price" [style]="{ width: '200px' }"></p-dropdown>
<p-dropdown [options]="selectOptions.prices" [(ngModel)]="criteria.maxPrice" optionLabel="name" optionValue="value" [showClear]="true" placeholder="Max Price" [style]="{ width: '200px' }"></p-dropdown>
}
<button pButton pRipple label="Find" class="ml-3 font-bold" [style]="{ width: '200px' }" (click)="search()"></button>
</div>
</div>
</div>
<div class="w-12 flex justify-content-center">
<button
type="button"
pButton
pRipple
label="Create Your Listing"
class="block mt-7 mb-7 lg:mb-0 p-button-rounded p-button-success p-button-lg font-medium"
[routerLink]="keycloakService.isLoggedIn() ? '/createBusinessListing' : '/pricing'"
></button>
</div>
</div>
</div>
</div>
</div> -->
<header class="w-full flex justify-between items-center p-4 bg-white fixed top-0 z-10 h-16 md:h-20">
<img src="assets/images/header-logo.png" alt="Logo" class="h-8 md:h-10" />
<div class="hidden md:flex items-center space-x-4">
<a href="#" class="text-gray-800">Pricing</a>
<a href="#" class="text-blue-600 border border-blue-600 px-3 py-2 rounded">Log In</a>
<a href="#" class="text-white bg-blue-600 px-4 py-2 rounded">Register</a>
@if(user){
<a routerLink="/account" class="text-blue-600 border border-blue-600 px-3 py-2 rounded">Account</a>
} @else {
<a routerLink="/pricing" class="text-gray-800">Pricing</a>
<a (click)="login()" class="text-blue-600 border border-blue-600 px-3 py-2 rounded">Log In</a>
<a (click)="register()" class="text-white bg-blue-600 px-4 py-2 rounded">Register</a>
}
</div>
<button (click)="toggleMenu()" class="md:hidden text-gray-600">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@ -135,22 +36,6 @@
<h1 class="text-3xl md:text-4xl lg:text-5xl font-bold text-blue-900 mb-4 text-center">Find businesses for sale.</h1>
<p class="text-base md:text-lg lg:text-xl text-blue-600 mb-8 text-center">Unlocking Exclusive Opportunities - Empowering Entrepreneurial Dreams</p>
<div class="bg-white bg-opacity-80 p-2 rounded-lg shadow-lg w-full">
<!-- <div class="flex flex-wrap justify-center space-x-2 space-y-2 md:space-x-4 md:space-y-0 mb-4">
<button class="text-white bg-blue-600 font-semibold px-3 py-2 rounded text-sm md:text-base">Businesses</button>
<button class="text-gray-600 px-3 py-2 text-sm md:text-base">Commercial Property</button>
<button class="text-gray-600 px-3 py-2 text-sm md:text-base">Professionals/Broker Directory</button>
</div> -->
<!-- <ul class="flex flex-wrap text-sm font-medium text-center text-gray-500 border-b border-gray-200 dark:border-gray-700 dark:text-gray-400">
<li class="me-2">
<a href="#" aria-current="page" class="inline-block p-4 text-blue-600 bg-gray-100 rounded-t-lg active dark:bg-gray-800 dark:text-blue-500">Businesses</a>
</li>
<li class="me-2">
<a href="#" class="inline-block p-4 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300">Properties</a>
</li>
<li class="me-2">
<a href="#" class="inline-block p-4 rounded-t-lg hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300">Professionals</a>
</li>
</ul> -->
<div class="text-sm lg:text-base text-center text-gray-500 border-b border-gray-200 dark:text-gray-400 dark:border-gray-700 flex justify-center">
<ul class="flex flex-wrap -mb-px">
<li class="me-2">
@ -193,7 +78,7 @@
</div>
<div class="flex items-center border border-gray-300 rounded-full p-2">
<input type="text" placeholder="AI Search" class="flex-grow px-4 py-2 outline-none rounded-full text-sm md:text-base" />
<button class="bg-blue-600 text-white p-2 rounded-full">
<button class="bg-blue-600 text-white p-2 rounded-full" (click)="search()">
<svg class="h-5 w-5 md:h-6 md:w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-4.35-4.35M10.5 18.5A7.5 7.5 0 1018 10.5 7.5 7.5 0 0010.5 18.5z"></path>
</svg>

View File

@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { initFlowbite } from 'flowbite';
import { KeycloakService } from 'keycloak-angular';
import onChange from 'on-change';
import { ButtonModule } from 'primeng/button';
@ -9,10 +10,10 @@ import { CheckboxModule } from 'primeng/checkbox';
import { DropdownModule } from 'primeng/dropdown';
import { InputTextModule } from 'primeng/inputtext';
import { StyleClassModule } from 'primeng/styleclass';
import { ListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { KeycloakUser, ListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { ListingsService } from '../../services/listings.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { getCriteriaStateObject, getSessionStorageHandler, resetCriteria } from '../../utils/utils';
import { getCriteriaStateObject, getSessionStorageHandler, map2User, resetCriteria } from '../../utils/utils';
@Component({
selector: 'app-home',
standalone: true,
@ -28,17 +29,18 @@ export class HomeComponent {
criteria: ListingCriteria;
states = [];
isMenuOpen = false;
user: KeycloakUser;
public constructor(private router: Router, private activatedRoute: ActivatedRoute, public selectOptions: SelectOptionsService, public keycloakService: KeycloakService, private listingsService: ListingsService) {
this.criteria = onChange(getCriteriaStateObject(), getSessionStorageHandler);
resetCriteria(this.criteria);
}
async ngOnInit() {
// if (this.activeTabAction === 'business' || this.activeTabAction === 'commercialProperty') {
// const statesResult = await this.listingsService.getAllStates(this.activeTabAction);
// this.states = statesResult.map(s => s.state).map(ls => ({ name: this.selectOptions.getState(ls as string), value: ls }));
// } else {
// this.states = [];
// }
const token = await this.keycloakService.getToken();
this.user = map2User(token);
setTimeout(() => {
initFlowbite();
});
}
async changeTab(tabname: 'business' | 'commercialProperty' | 'broker') {
this.activeTabAction = tabname;

View File

@ -1,4 +1,4 @@
<div id="sky-line" class="hidden-lg-down"></div>
<!-- <div id="sky-line" class="hidden-lg-down"></div>
<div class="search">
<div class="wrapper">
<div class="grid p-4 align-items-center">
@ -82,4 +82,33 @@
<p-paginator (onPageChange)="onPageChange($event)" [first]="first" [rows]="rows" [totalRecords]="totalRecords" [rowsPerPageOptions]="[12, 24, 48]"></p-paginator>
</div>
</div>
</div> -->
<!-- business-listing.component.html -->
<!-- <div class="w-full bg-slate-100"> -->
<div class="container mx-auto p-4">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
@for (listing of listings; track listing.id) {
<div class="bg-white rounded-lg shadow-md overflow-hidden">
<div class="p-4 flex flex-col h-full relative">
<div class="flex items-center mb-2">
<i [class]="selectOptions.getIconAndTextColorType(listing.type)" class="mr-2"></i>
<span [class]="selectOptions.getTextColorType(listing.type)" class="font-semibold">{{ selectOptions.getBusiness(listing.type) }}</span>
</div>
<h2 class="text-lg font-semibold mb-2">{{ listing.title }}</h2>
<p class="text-sm text-gray-600 mb-1">Asking price: {{ listing.price | currency }}</p>
<p class="text-sm text-gray-600 mb-1">Sales revenue: {{ listing.salesRevenue | currency }}</p>
<p class="text-sm text-gray-600 mb-1">Net profit: {{ listing.cashFlow | currency }}</p>
<p class="text-sm text-gray-600 mb-1">Location: {{ selectOptions.getState(listing.state) }}</p>
<p class="text-sm text-gray-600 mb-1">Established: {{ listing.established }}</p>
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listing.imageName }}.avif?_ts={{ ts }}" alt="Company logo" class="absolute bottom-[70px] right-[30px] h-[35px] w-auto" />
<div class="flex-grow"></div>
<button class="bg-green-500 text-white px-4 py-2 rounded-md w-full flex items-center justify-center mt-2" [routerLink]="['/details-business-listing', listing.id]">
View Full Listing
<i class="fas fa-arrow-right ml-2"></i>
</button>
</div>
</div>
}
</div>
</div>
<!-- </div> -->

View File

@ -1,30 +1,32 @@
#sky-line {
background-image: url(../../../../assets/images/bw-sky.jpg);
height: 204px;
background-position: bottom;
background-size: cover;
margin-bottom: -1px;
}
.search {
background-color: #343f69;
}
::ng-deep p-paginator div {
background-color: var(--surface-200) !important;
}
.icon-pos {
position: absolute;
bottom: 1.5rem; /* Gleich dem Padding des Containers */
right: 1.5rem; /* Gleich dem Padding des Containers */
}
.rounded-image {
border-radius: 6px;
// width: 100px;
max-width: 100px;
height: 35px;
border: 1px solid rgba(0, 0, 0, 0.2);
padding: 1px 1px;
object-fit: contain;
}
::ng-deep span.p-button-label {
font-weight: 500;
// #sky-line {
// background-image: url(../../../../assets/images/bw-sky.jpg);
// height: 204px;
// background-position: bottom;
// background-size: cover;
// margin-bottom: -1px;
// }
// .search {
// background-color: #343f69;
// }
// ::ng-deep p-paginator div {
// background-color: var(--surface-200) !important;
// }
// .icon-pos {
// position: absolute;
// bottom: 1.5rem;
// right: 1.5rem;
// }
// .rounded-image {
// border-radius: 6px;
// max-width: 100px;
// height: 35px;
// border: 1px solid rgba(0, 0, 0, 0.2);
// padding: 1px 1px;
// object-fit: contain;
// }
// ::ng-deep span.p-button-label {
// font-weight: 500;
// }
:host {
width: 100%;
}

View File

@ -79,7 +79,9 @@ export class BusinessListingsComponent {
this.init();
});
}
async ngOnInit() {}
async ngOnInit() {
//initFlowbite();
}
async init() {
const statesResult = await this.listingsService.getAllStates('business');
this.states = statesResult.map(ls => ({ name: this.selectOptions.getState(ls.state as string), value: ls.state, count: ls.count }));
@ -94,8 +96,8 @@ export class BusinessListingsComponent {
const listingReponse = await this.listingsService.getListings(this.criteria, 'business');
this.listings = listingReponse.data;
this.totalRecords = listingReponse.total;
this.cdRef.markForCheck();
this.cdRef.detectChanges();
// this.cdRef.markForCheck();
// this.cdRef.detectChanges();
}
onPageChange(event: any) {
this.criteria.start = event.first;

View File

@ -57,11 +57,8 @@ export class SelectOptionsService {
getIconType(value: string): string {
return this.typesOfBusiness.find(c => c.value === value)?.icon;
}
getTextColorType(value: string): string {
return this.typesOfBusiness.find(c => c.value === value)?.textColorClass;
}
getBgColorType(value: number): string {
return this.typesOfBusiness.find(c => c.value === String(value))?.bgColorClass;
getTextColorType(value: number): string {
return this.typesOfBusiness.find(c => c.value === String(value))?.textColorClass;
}
getIconAndTextColorType(value: number): string {
const category = this.typesOfBusiness.find(c => c.value === String(value));

View File

@ -1,9 +1,9 @@
@import 'primeng/resources/primeng.css';
@import 'primeicons/primeicons.css';
// @import 'primeng/resources/primeng.css';
// @import 'primeicons/primeicons.css';
// @import 'primeflex/primeflex.css';
@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');
@import 'primeng/resources/themes/lara-light-blue/theme.css';
// @import 'primeng/resources/themes/lara-light-blue/theme.css';
@import '@fortawesome/fontawesome-free/css/all.min.css';
// In Ihrer src/styles.css Datei:
@ -23,6 +23,9 @@ body,
app-root {
margin: 0;
height: 100%;
&:hover a {
cursor: pointer;
}
}
app-root {

View File

@ -1,5 +1,22 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
safelist: [
'text-red-400',
'text-purple-400',
'text-pink-400',
'text-teal-400',
'text-green-400',
'text-yellow-400',
'text-blue-400',
'text-cyan-400',
'text-gray-400',
'text-sky-400',
'text-orange-400',
'text-violet-400',
'text-indigo-400',
'text-amber-700'
// Fügen Sie hier alle möglichen Farbklassen hinzu, die dynamisch geladen werden könnten
],
content: [
"./src/**/*.{html,ts}",
"./node_modules/flowbite/**/*.js" // add this line