Umbau: header & businessListing

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

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;