Umbau commercial-details, Anfang Umbau user-details
This commit is contained in:
parent
1534c14a68
commit
677b95c21c
|
|
@ -96,3 +96,120 @@
|
|||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="container mx-auto p-4">
|
||||
<div class="bg-white shadow-md rounded-lg overflow-hidden">
|
||||
<div class="p-6 relative">
|
||||
<h1 class="text-3xl font-bold mb-4">{{ listing?.title }}</h1>
|
||||
<button class="absolute top-4 right-4 text-gray-500 hover:text-gray-700" (click)="historyService.goBack()">
|
||||
<fa-icon [icon]="faTimes" size="2x"></fa-icon>
|
||||
</button>
|
||||
<div class="lg:hidden">
|
||||
@if (listing && listing.imageOrder.length > 0) {
|
||||
<div id="gallery" class="relative w-full" data-carousel="slide">
|
||||
<div class="relative h-56 overflow-hidden rounded-lg md:h-96">
|
||||
@for (image of listing.imageOrder; track $index) {
|
||||
<div class="hidden duration-700 ease-in-out" data-carousel-item>
|
||||
<img src="{{ env.imageBaseUrl }}/pictures/property/{{ listing.imagePath }}/{{ listing.serialId }}/{{ image }}" class="absolute block max-w-full h-auto -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2" />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="absolute z-30 flex space-x-3 -translate-x-1/2 bottom-5 left-1/2">
|
||||
<button type="button" class="w-3 h-3 rounded-full bg-white dark:bg-gray-800" aria-current="true" aria-label="Slide 1" data-carousel-slide-to="0"></button>
|
||||
@for (i of getImageIndices(); track i) {
|
||||
<button
|
||||
type="button"
|
||||
class="w-3 h-3 rounded-full bg-white/50 dark:bg-gray-800/50 hover:bg-white dark:hover:bg-gray-800"
|
||||
aria-current="false"
|
||||
attr.aria-label="Slide {{ i }}"
|
||||
attr.data-carousel-slide-to="{{ i }}"
|
||||
></button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-col lg:flex-row">
|
||||
<div class="w-full lg:w-1/2 pr-0 lg:pr-4">
|
||||
<p class="mb-4" [innerHTML]="description"></p>
|
||||
|
||||
<div class="space-y-2">
|
||||
<div *ngFor="let detail of propertyDetails; let i = index" class="flex flex-col sm:flex-row" [ngClass]="{ 'bg-gray-100': i % 2 === 0 }">
|
||||
<div class="w-full sm:w-1/3 font-semibold p-2">{{ detail.label }}</div>
|
||||
<div class="w-full sm:w-2/3 p-2">{{ detail.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@if(listing && listingUser && (listingUser?.email===user?.email || isAdmin())){
|
||||
<button class="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600" [routerLink]="['/editCommercialPropertyListing', listing.id]">Edit</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="w-full lg:w-1/2 mt-6 lg:mt-0">
|
||||
<div class="hidden lg:block">
|
||||
@if (listing && listing.imageOrder.length > 0) {
|
||||
<div id="gallery" class="relative w-full" data-carousel="slide">
|
||||
<div class="relative h-56 overflow-hidden rounded-lg md:h-96">
|
||||
@for (image of listing.imageOrder; track $index) {
|
||||
<div class="hidden duration-700 ease-in-out" data-carousel-item>
|
||||
<img
|
||||
src="{{ env.imageBaseUrl }}/pictures/property/{{ listing.imagePath }}/{{ listing.serialId }}/{{ image }}"
|
||||
class="absolute block max-w-full h-auto -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="absolute z-30 flex space-x-3 -translate-x-1/2 bottom-5 left-1/2">
|
||||
<button type="button" class="w-3 h-3 rounded-full bg-white dark:bg-gray-800" aria-current="true" aria-label="Slide 1" data-carousel-slide-to="0"></button>
|
||||
@for (i of getImageIndices(); track i) {
|
||||
<button
|
||||
type="button"
|
||||
class="w-3 h-3 rounded-full bg-white/50 dark:bg-gray-800/50 hover:bg-white dark:hover:bg-gray-800"
|
||||
aria-current="false"
|
||||
attr.aria-label="Slide {{ i }}"
|
||||
attr.data-carousel-slide-to="{{ i }}"
|
||||
></button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<h2 class="text-xl font-semibold mb-4">Contact the Author of this Listing</h2>
|
||||
<p class="text-sm text-gray-600 mb-4">Please include your contact info below</p>
|
||||
<form>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">Your Name</label>
|
||||
<input type="text" id="name" name="name" [(ngModel)]="mailinfo.sender.name" class="w-full px-3 py-2 border border-gray-300 rounded-md" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Your Email</label>
|
||||
<input type="email" id="email" name="email" [(ngModel)]="mailinfo.sender.email" class="w-full px-3 py-2 border border-gray-300 rounded-md" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="phone" class="block text-sm font-medium text-gray-700 mb-1">Phone Number</label>
|
||||
<input type="tel" id="phone" name="phone" [(ngModel)]="mailinfo.sender.phoneNumber" class="w-full px-3 py-2 border border-gray-300 rounded-md" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="location" class="block text-sm font-medium text-gray-700 mb-1">Country/State</label>
|
||||
<input type="text" id="location" name="location" [(ngModel)]="mailinfo.sender.state" class="w-full px-3 py-2 border border-gray-300 rounded-md" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="message" class="block text-sm font-medium text-gray-700 mb-1">Questions/Comments</label>
|
||||
<textarea id="message" name="message" [(ngModel)]="mailinfo.sender.comments" rows="4" class="w-full px-3 py-2 border border-gray-300 rounded-md"></textarea>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-sm">
|
||||
Listing by <span class="font-semibold">Mia Hernandez</span>
|
||||
<img src="https://placehold.co/30x30" alt="Realtor logo" class="inline-block ml-1 w-6 h-6" />
|
||||
</div>
|
||||
<button (click)="mail()" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
::ng-deep p {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-size: 1rem; /* oder 1rem, abhängig vom Browser und den Standardeinstellungen */
|
||||
line-height: 1.5;
|
||||
}
|
||||
::ng-deep h1 {
|
||||
display: block;
|
||||
font-size: 2em; /* etwa 32px */
|
||||
margin-top: 0.67em;
|
||||
margin-bottom: 0.67em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
::ng-deep h2 {
|
||||
display: block;
|
||||
font-size: 1.5em; /* etwa 24px */
|
||||
margin-top: 0.83em;
|
||||
margin-bottom: 0.83em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
::ng-deep h3 {
|
||||
display: block;
|
||||
font-size: 1.17em; /* etwa 18.72px */
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import onChange from 'on-change';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
|
|
@ -54,6 +55,9 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
ts = new Date().getTime();
|
||||
env = environment;
|
||||
errorResponse: ErrorResponse;
|
||||
faTimes = faTimes;
|
||||
propertyDetails = [];
|
||||
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private listingsService: ListingsService,
|
||||
|
|
@ -65,6 +69,7 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
public historyService: HistoryService,
|
||||
public keycloakService: KeycloakService,
|
||||
private imageService: ImageService,
|
||||
private ngZone: NgZone,
|
||||
) {
|
||||
this.mailinfo = { sender: {}, userId: '', email: '', url: environment.mailinfoUrl };
|
||||
|
||||
|
|
@ -81,6 +86,27 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty'));
|
||||
this.listingUser = await this.userService.getById(this.listing.userId);
|
||||
this.description = this.sanitizer.bypassSecurityTrustHtml(this.listing.description);
|
||||
import('flowbite').then(flowbite => {
|
||||
flowbite.initCarousels();
|
||||
});
|
||||
this.propertyDetails = [
|
||||
{ label: 'Property Category', value: this.selectOptions.getCommercialProperty(this.listing.type) },
|
||||
{ label: 'Located in', value: this.selectOptions.getState(this.listing.state) },
|
||||
{ label: 'City', value: this.listing.city },
|
||||
{ label: 'Zip Code', value: this.listing.zipCode },
|
||||
{ label: 'County', value: this.listing.county },
|
||||
{ label: 'Asking Price:', value: `$${this.listing.price?.toLocaleString()}` },
|
||||
];
|
||||
//this.initFlowbite();
|
||||
}
|
||||
private initFlowbite() {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
import('flowbite')
|
||||
.then(flowbite => {
|
||||
flowbite.initCarousels();
|
||||
})
|
||||
.catch(error => console.error('Error initializing Flowbite:', error));
|
||||
});
|
||||
}
|
||||
isAdmin() {
|
||||
return this.keycloakService.getUserRoles(true).includes('ADMIN');
|
||||
|
|
@ -100,4 +126,7 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
containsError(fieldname: string) {
|
||||
return this.errorResponse?.fields.map(f => f.fieldname).includes(fieldname);
|
||||
}
|
||||
getImageIndices(): number[] {
|
||||
return this.listing && this.listing.imageOrder ? this.listing.imageOrder.slice(1).map((e, i) => i + 1) : [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,3 +134,177 @@
|
|||
}
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="container mx-auto p-4">
|
||||
<div class="bg-white shadow-md rounded-lg overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between p-4 border-b">
|
||||
<div class="flex items-center space-x-4">
|
||||
<img src="https://placehold.co/80x80" alt="Profile picture of Avery Brown smiling" class="w-20 h-20 rounded-full" />
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold flex items-center">
|
||||
Avery Brown
|
||||
<span class="text-yellow-400 ml-2">★</span>
|
||||
</h1>
|
||||
<p class="text-gray-600">
|
||||
Company
|
||||
<span class="mx-1">-</span>
|
||||
New Mexico Business Sales
|
||||
<span class="mx-2">|</span>
|
||||
For Sale
|
||||
<span class="mx-1">-</span>
|
||||
<!-- <i class="fas fa-building text-red-500"></i> -->
|
||||
<span>9</span>
|
||||
</p>
|
||||
</div>
|
||||
<img src="https://placehold.co/45x60" class="w-11 h-14" />
|
||||
</div>
|
||||
<button class="text-red-500 text-2xl">×</button>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<p class="p-4 text-gray-700">Helping business owners in southern New Mexico sell their businesses and assisting buyers in finding the perfect opportunity.</p>
|
||||
|
||||
<!-- Company Profile -->
|
||||
<div class="p-4">
|
||||
<h2 class="text-xl font-semibold mb-4">Company Profile</h2>
|
||||
<p class="text-gray-700 mb-4">
|
||||
New Mexico Business Sales is a trusted business brokerage firm serving the southern New Mexico market. Our team of experienced brokers is committed to providing personalized service and expert guidance to ensure
|
||||
a smooth and successful transaction for our clients.
|
||||
</p>
|
||||
|
||||
<!-- Profile Details -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center bg-gray-100">
|
||||
<span class="font-semibold w-40 p-2">Name</span>
|
||||
<span class="p-2 flex-grow">Avery Brown</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center">
|
||||
<span class="font-semibold w-40 p-2">Phone Number</span>
|
||||
<span class="p-2 flex-grow">(575) 555-7890</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center bg-gray-100">
|
||||
<span class="font-semibold w-40 p-2">EMail Address</span>
|
||||
<span class="p-2 flex-grow">avery.brown@nmbizsales.com</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center">
|
||||
<span class="font-semibold w-40 p-2">Company Location</span>
|
||||
<span class="p-2 flex-grow">Las Cruces - NM</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Services -->
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold mb-2">Services we offer</h3>
|
||||
<h4 class="font-medium">What We Offer</h4>
|
||||
<ul class="list-disc pl-5 text-gray-700">
|
||||
<li>Business listings</li>
|
||||
<li>Buyer search and qualification</li>
|
||||
<li>Due diligence support</li>
|
||||
<li>Financing assistance</li>
|
||||
<li>Closing coordination</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Areas Served -->
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold mb-2">Areas (Counties) we serve</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-sm">Doña Ana County-NM</span>
|
||||
<span class="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-sm">Otero County-NM</span>
|
||||
<span class="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-sm">Luna County-NM</span>
|
||||
<span class="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-sm">Sierra County-NM</span>
|
||||
<span class="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-sm">Grant County-NM</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Licensed In -->
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold mb-2">Licensed In</h3>
|
||||
<span class="bg-green-100 text-green-800 px-2 py-1 rounded-full text-sm">4.2700P-NM</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Business Listings -->
|
||||
<div class="p-4">
|
||||
<h2 class="text-xl font-semibold mb-4">My Business Listings For Sale</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<i class="fas fa-utensils text-blue-500 mr-2"></i>
|
||||
<span class="font-medium">Food and Restaurant</span>
|
||||
</div>
|
||||
<p class="text-gray-700">Successful Coffee Shop in The Colony</p>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<i class="fas fa-utensils text-blue-500 mr-2"></i>
|
||||
<span class="font-medium">Food and Restaurant</span>
|
||||
</div>
|
||||
<p class="text-gray-700">Established Craft Beer Bar in Wylie</p>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<i class="fas fa-industry text-yellow-500 mr-2"></i>
|
||||
<span class="font-medium">Industrial Services</span>
|
||||
</div>
|
||||
<p class="text-gray-700">Profitable Electrical Contracting Business in New Braunfels</p>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<i class="fas fa-dumbbell text-green-500 mr-2"></i>
|
||||
<span class="font-medium">Service</span>
|
||||
</div>
|
||||
<p class="text-gray-700">Successful Fitness Center in Coppell</p>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<i class="fas fa-building text-purple-500 mr-2"></i>
|
||||
<span class="font-medium">Mixed Use</span>
|
||||
</div>
|
||||
<p class="text-gray-700">Mixed-Use Development Opportunity</p>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center mb-2">
|
||||
<i class="fas fa-tree text-green-500 mr-2"></i>
|
||||
<span class="font-medium">Land</span>
|
||||
</div>
|
||||
<p class="text-gray-700">Upscale Golf Course</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Commercial Property Listings -->
|
||||
<div class="p-4">
|
||||
<h2 class="text-xl font-semibold mb-4">My Commercial Property Listings For Sale</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center space-x-4">
|
||||
<img src="https://placehold.co/45x45" alt="Car Dealership and Service Center" class="w-12 h-12 object-cover rounded" />
|
||||
<div>
|
||||
<p class="font-medium">Mixed Use</p>
|
||||
<p class="text-gray-700">Car Dealership and Service Center</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center space-x-4">
|
||||
<img src="https://placehold.co/45x45" alt="Cold Storage Warehouse" class="w-12 h-12 object-cover rounded" />
|
||||
<div>
|
||||
<p class="font-medium">Industrial</p>
|
||||
<p class="text-gray-700">Cold Storage Warehouse</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border rounded-lg p-4">
|
||||
<div class="flex items-center space-x-4">
|
||||
<img src="https://placehold.co/45x45" alt="Retail Strip Center in Round Rock" class="w-12 h-12 object-cover rounded" />
|
||||
<div>
|
||||
<p class="font-medium">Retail</p>
|
||||
<p class="text-gray-700">Retail Strip Center in Round Rock</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
} @else {
|
||||
<img src="assets/images/placeholder.png" class="w-8 h-10 object-contain" />
|
||||
}
|
||||
<button class="bg-green-500 hover:bg-green-600 text-white font-medium py-2 px-4 rounded-full flex items-center">
|
||||
<button class="bg-green-500 hover:bg-green-600 text-white font-medium py-2 px-4 rounded-full flex items-center" [routerLink]="['/details-user', user.id]">
|
||||
View Full profile
|
||||
<i class="fas fa-arrow-right ml-2"></i>
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Reference in New Issue