geo coding, user service, listing for business
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
<div class="grid">
|
||||
<div class="col-12 md:col-6">
|
||||
<ul class="list-none p-0 m-0 border-top-1 border-300">
|
||||
@if (listing && (listing.listingsCategory==='business' || listing.listingsCategory==='professionals_brokers')){
|
||||
<!-- @if (listing && (listing.listingsCategory==='business')){
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
||||
<div class="text-500 w-full md:w-2 font-medium">Summary</div>
|
||||
<div class="w-full md:w-10">
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
} -->
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||
<div class="text-500 w-full md:w-2 font-medium">Description</div>
|
||||
<div class="text-900 w-full md:w-10 line-height-3">{{listing?.description}}</div>
|
||||
@@ -36,7 +36,7 @@
|
||||
</li>
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap ">
|
||||
<div class="text-500 w-full md:w-2 font-medium">Located in</div>
|
||||
<div class="text-900 w-full md:w-10">{{selectOptions.getLocation(listing.location)}}</div>
|
||||
<div class="text-900 w-full md:w-10">{{selectOptions.getState(listing.state)}}</div>
|
||||
</li>
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
||||
<div class="text-500 w-full md:w-2 font-medium">Asking Price</div>
|
||||
@@ -63,7 +63,7 @@
|
||||
<div class="text-900 w-full md:w-10">{{listing.brokerLicencing}}</div>
|
||||
</li>
|
||||
}
|
||||
@if (listing && (listing.listingsCategory==='professionals_brokers')){
|
||||
<!-- @if (listing && (listing.listingsCategory==='professionals_brokers')){
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
||||
<div class="text-500 w-full md:w-2 font-medium">Located in</div>
|
||||
<div class="text-900 w-full md:w-10">{{selectOptions.getLocation(listing.location)}}</div>
|
||||
@@ -84,11 +84,11 @@
|
||||
<div class="text-500 w-full md:w-2 font-medium">Category</div>
|
||||
<div class="text-900 w-full md:w-10">{{listing.category}}</div>
|
||||
</li>
|
||||
}
|
||||
} -->
|
||||
@if (listing && (listing.listingsCategory==='investment')){
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
||||
<div class="text-500 w-full md:w-2 font-medium">Located in</div>
|
||||
<div class="text-900 w-full md:w-10">{{selectOptions.getLocation(listing.location)}}</div>
|
||||
<div class="text-900 w-full md:w-10">{{selectOptions.getState(listing.state)}}</div>
|
||||
</li>
|
||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||
<div class="text-500 w-full md:w-2 font-medium">EMail</div>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
[style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-dropdown [options]="locations" [(ngModel)]="location" optionLabel="criteria.location" optionLabel="name" optionValue="value"
|
||||
[showClear]="true" placeholder="Location" [style]="{ width: '100%'}"></p-dropdown>
|
||||
<p-dropdown [options]="states" [(ngModel)]="state" optionLabel="criteria.location" optionLabel="name" optionValue="value"
|
||||
[showClear]="true" placeholder="State" [style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-dropdown [options]="selectOptions.prices" [(ngModel)]="criteria.minPrice" optionLabel="name"
|
||||
@@ -31,7 +31,7 @@
|
||||
}
|
||||
@if (listingCategory==='investment'){
|
||||
<div class="col-2">
|
||||
<p-dropdown [options]="locations" [(ngModel)]="criteria.location" optionLabel="name" optionValue="value"
|
||||
<p-dropdown [options]="states" [(ngModel)]="criteria.location" optionLabel="name" optionValue="value"
|
||||
[showClear]="true" placeholder="Location" [style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
[style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-dropdown [options]="locations" [(ngModel)]="criteria.location" optionLabel="name" optionValue="value"
|
||||
<p-dropdown [options]="states" [(ngModel)]="criteria.location" optionLabel="name" optionValue="value"
|
||||
[showClear]="true" placeholder="Location" [style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
}
|
||||
@@ -94,17 +94,17 @@
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Asking price: {{listing.price | currency}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Sales revenue: {{listing.salesRevenue | currency}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Net profit: {{listing.cashFlow | currency}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Location: {{selectOptions.getLocation(listing.location)}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Location: {{selectOptions.getState(listing.state)}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Established: {{listing.established}}</p>
|
||||
}
|
||||
@if (listing.listingsCategory==='professionals_brokers'){
|
||||
<!-- <p class="mt-0 mb-1 text-700 line-height-3">Category: {{listing.category}}</p> -->
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Location: {{selectOptions.getLocation(listing.location)}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Location: {{selectOptions.getState(listing.state)}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">EMail: {{listing.email}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Website: {{listing.website}}</p>
|
||||
}
|
||||
@if (listing.listingsCategory==='investment'){
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Location: {{selectOptions.getLocation(listing.location)}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Location: {{selectOptions.getState(listing.state)}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">EMail: {{listing.email}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Website: {{listing.website}}</p>
|
||||
<p class="mt-0 mb-1 text-700 line-height-3">Phone Number: {{listing.phoneNumber}}</p>
|
||||
|
||||
@@ -34,9 +34,9 @@ export class ListingsComponent {
|
||||
maxPrice: string;
|
||||
minPrice: string;
|
||||
type:string;
|
||||
locations = [];
|
||||
locationsSet = new Set();
|
||||
location:string;
|
||||
states = [];
|
||||
statesSet = new Set();
|
||||
state:string;
|
||||
first: number = 0;
|
||||
rows: number = 12;
|
||||
totalRecords:number = 0;
|
||||
@@ -61,25 +61,25 @@ export class ListingsComponent {
|
||||
}
|
||||
async init(){
|
||||
this.listings=await this.listingsService.getListings(this.criteria);
|
||||
this.setLocations();
|
||||
this.setStates();
|
||||
this.filteredListings=[...this.listings];
|
||||
this.totalRecords=this.listings.length
|
||||
this.filteredListings=[...this.listings].splice(this.first,this.rows);
|
||||
this.cdRef.markForCheck();
|
||||
this.cdRef.detectChanges();
|
||||
}
|
||||
setLocations(){
|
||||
this.locationsSet=new Set();
|
||||
setStates(){
|
||||
this.statesSet=new Set();
|
||||
this.listings.forEach(l=>{
|
||||
if (l.location){
|
||||
this.locationsSet.add(l.location)
|
||||
if (l.state){
|
||||
this.statesSet.add(l.state)
|
||||
}
|
||||
})
|
||||
this.locations = [...this.locationsSet].map((ls) =>({name:this.selectOptions.getLocation(ls as string),value:ls}))
|
||||
this.states = [...this.statesSet].map((ls) =>({name:this.selectOptions.getState(ls as string),value:ls}))
|
||||
}
|
||||
async search() {
|
||||
this.listings= await this.listingsService.getListings(this.criteria);
|
||||
this.setLocations();
|
||||
this.setStates();
|
||||
this.totalRecords=this.listings.length
|
||||
this.filteredListings =[...this.listings].splice(this.first,this.rows);
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
@@ -8,41 +8,90 @@
|
||||
<p-divider></p-divider>
|
||||
<div class="flex gap-5 flex-column-reverse md:flex-row">
|
||||
<div class="flex-auto p-fluid">
|
||||
<div class="mb-4">
|
||||
<!-- <div class="mb-4">
|
||||
<label for="email" class="block font-medium text-900 mb-2">Username</label>
|
||||
<input id="email" type="text" [disabled]="true" pInputText [(ngModel)]="user.username">
|
||||
<p class="font-italic text-sm line-height-1">Usernames cannot be changed.</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="state" class="block font-medium text-900 mb-2">First Name</label>
|
||||
<input id="state" type="text" pInputText [(ngModel)]="user.firstname">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="state" class="block font-medium text-900 mb-2">Last Name</label>
|
||||
<input id="state" type="text" pInputText [(ngModel)]="user.lastname">
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="mb-4">
|
||||
<label for="state" class="block font-medium text-900 mb-2">E-mail (required)</label>
|
||||
<input id="state" type="text" pInputText [(ngModel)]="user.email">
|
||||
<input id="state" type="text" [disabled]="true" pInputText [(ngModel)]="user.email">
|
||||
<p class="font-italic text-sm line-height-1">You can only modify your email by contacting us at emailchange@bizmatch.net</p>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="firstname" class="block font-medium text-900 mb-2">First Name</label>
|
||||
<input id="firstname" type="text" pInputText [(ngModel)]="user.firstname">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="lastname" class="block font-medium text-900 mb-2">Last Name</label>
|
||||
<input id="lastname" type="text" pInputText [(ngModel)]="user.lastname">
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-4">
|
||||
<label for="phoneNumber" class="block font-medium text-900 mb-2">Your Phone Number</label>
|
||||
<input id="phoneNumber" type="text" pInputText [(ngModel)]="user.phoneNumber">
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-4">
|
||||
<label for="companyWebsite" class="block font-medium text-900 mb-2">Company Website</label>
|
||||
<input id="companyWebsite" type="text" pInputText [(ngModel)]="user.companyWebsite">
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-4">
|
||||
<label for="companyLocation" class="block font-medium text-900 mb-2">Company Location</label>
|
||||
<p-autoComplete [(ngModel)]="user.companyLocation" [suggestions]="suggestions" (completeMethod)="search($event)"></p-autoComplete>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="companyOverview" class="block font-medium text-900 mb-2">Company Overview</label>
|
||||
<textarea id="companyOverview" type="text" pInputTextarea rows="5" [autoResize]="true" [(ngModel)]="user.companyOverview"></textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="areasServed" class="block font-medium text-900 mb-2">Areas We Serve</label>
|
||||
<textarea id="areasServed" type="text" pInputTextarea rows="5" [autoResize]="true" [(ngModel)]="user.areasServed"></textarea>
|
||||
</div>
|
||||
<div >
|
||||
<label for="companyOverview" class="block font-medium text-900 mb-2">Licensed In</label>
|
||||
@for (licensedIn of user.licensedIn; track licensedIn.value){
|
||||
<div class="grid">
|
||||
<div class="flex col-12 md:col-6">
|
||||
<p-dropdown id="states" [options]="selectOptions?.states" [(ngModel)]="licensedIn.name" optionLabel="name" optionValue="value" [showClear]="true" placeholder="State" [ngStyle]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
<div class="flex col-12 md:col-6">
|
||||
<input id="companyWebsite" type="text" pInputText [(ngModel)]="licensedIn.value" placeholder="Licence Number">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="field mb-5 col-12 md:col-6 flex align-items-center">
|
||||
<p-button class="mr-1" icon="pi pi-plus" severity="success" (click)="addLicence()"></p-button>
|
||||
<p-button icon="pi pi-minus" severity="danger" (click)="removeLicence()" [disabled]="user.licensedIn?.length<2"></p-button>
|
||||
<span class="text-xs"> (Add more licenses or remove existing ones.)</span>
|
||||
<!-- <button pButton pRipple label="Add Licence" class="w-auto" (click)="addLicence()"></button> -->
|
||||
</div>
|
||||
<!-- <div class="mb-4">
|
||||
<label for="state" class="block font-medium text-900 mb-2">New Password</label>
|
||||
<p class="font-italic text-sm line-height-1">If you would like to change the password type a new one. Otherwise leave this blank.</p>
|
||||
<input id="state" type="text" pInputText>
|
||||
<p class="font-italic text-sm line-height-1">Password repetition</p>
|
||||
<input id="state" type="text" pInputText>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div>
|
||||
<button pButton pRipple label="Update Profile" class="w-auto" (click)="updateProfile(user)"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-column align-items-center flex-or">
|
||||
<span class="font-medium text-900 mb-2">Profile Picture</span>
|
||||
<img [src]="imageUrl" (error)="setImageToFallback($event)" class="rounded-image"/>
|
||||
<!-- <p-image src="http://localhost:3000/public/user.png" alt="Image" width="10rem" [preview]="true"></p-image> -->
|
||||
<!-- <button pButton type="button" icon="pi pi-pencil" class="p-button-rounded -mt-4"></button> -->
|
||||
<p-fileUpload mode="basic" chooseLabel="Upload" name="file" [url]="uploadUrl" accept="image/*" [maxFileSize]="maxFileSize" (onUpload)="onUpload($event)" [auto]="true" styleClass="p-button-outlined p-button-plain p-button-rounded mt-4"></p-fileUpload>
|
||||
<div>
|
||||
<div class="flex flex-column align-items-center flex-or mb-8">
|
||||
<span class="font-medium text-900 mb-2">Company Logo</span>
|
||||
<span class="font-medium text-xs mb-2">(is shown in every offer)</span>
|
||||
<img [src]="companyLogoUrl" (error)="setImageToFallback($event)" class="rounded-image"/>
|
||||
<p-fileUpload mode="basic" chooseLabel="Upload" name="file" [url]="uploadUrl" accept="image/*" [maxFileSize]="maxFileSize" (onUpload)="onUploadCompanyLogo($event)" [auto]="true" styleClass="p-button-outlined p-button-plain p-button-rounded mt-4"></p-fileUpload>
|
||||
</div>
|
||||
<p-divider></p-divider>
|
||||
<div class="flex flex-column align-items-center flex-or">
|
||||
<span class="font-medium text-900 mb-2">Your Profile Picture</span>
|
||||
<img [src]="profileUrl" (error)="setImageToFallback($event)" class="rounded-image"/>
|
||||
<p-fileUpload mode="basic" chooseLabel="Upload" name="file" [url]="uploadUrl" accept="image/*" [maxFileSize]="maxFileSize" (onUpload)="onUploadProfilePicture($event)" [auto]="true" styleClass="p-button-outlined p-button-plain p-button-rounded mt-4"></p-fileUpload>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-900 font-semibold text-lg mt-3">Membership Level</div>
|
||||
|
||||
@@ -6,4 +6,7 @@
|
||||
padding: 1px 1px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
|
||||
.wfull{
|
||||
width: 100%;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component } from '@angular/core';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
import { CheckboxModule } from 'primeng/checkbox';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
@@ -23,7 +23,9 @@ import { lastValueFrom } from 'rxjs';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { FileUploadModule } from 'primeng/fileupload';
|
||||
import { Invoice, Subscription, User } from '../../../../../../common-models/src/main.model';
|
||||
import { AutoCompleteCompleteEvent, Invoice, Subscription, User } from '../../../../../../common-models/src/main.model';
|
||||
import { GeoService } from '../../../services/geo.service';
|
||||
import { ChangeDetectionStrategy } from '@angular/compiler';
|
||||
|
||||
|
||||
@Component({
|
||||
@@ -41,24 +43,58 @@ export class AccountComponent {
|
||||
userSubscriptions:Array<Subscription>=[];
|
||||
uploadUrl:string;
|
||||
maxFileSize=1000000;
|
||||
imageUrl:string;
|
||||
constructor(public userService: UserService, private subscriptionService: SubscriptionsService,private messageService: MessageService) {
|
||||
companyLogoUrl:string;
|
||||
profileUrl:string;
|
||||
constructor(public userService: UserService,
|
||||
private subscriptionService: SubscriptionsService,
|
||||
private messageService: MessageService,
|
||||
private geoService:GeoService,
|
||||
public selectOptions:SelectOptionsService,
|
||||
private cdref:ChangeDetectorRef) {
|
||||
this.user=this.userService.getUser()
|
||||
|
||||
}
|
||||
async ngOnInit(){
|
||||
this.imageUrl = `${environment.apiBaseUrl}/profile_${this.user.id}`
|
||||
this.profileUrl = `${environment.apiBaseUrl}/profile_${this.user.id}`
|
||||
this.companyLogoUrl = `${environment.apiBaseUrl}/profile_${this.user.id}`
|
||||
this.userSubscriptions=await lastValueFrom(this.subscriptionService.getAllSubscriptions());
|
||||
this.uploadUrl = `${environment.apiBaseUrl}/bizmatch/account/uploadPhoto/${this.user.id}`;
|
||||
if (!this.user.licensedIn || this.user.licensedIn?.length===0){
|
||||
this.user.licensedIn = [{name:'',value:''}]
|
||||
}
|
||||
this.user=await this.userService.getById(this.user.id);
|
||||
}
|
||||
printInvoice(invoice:Invoice){}
|
||||
updateProfile(user:User){
|
||||
this.messageService.add({ severity: 'warn', summary: 'Information', detail: 'This function is not yet available, please send an email to info@bizmatch.net for changes to your customer data', life: 15000 });
|
||||
|
||||
async updateProfile(user:User){
|
||||
//this.messageService.add({ severity: 'warn', summary: 'Information', detail: 'This function is not yet available, please send an email to info@bizmatch.net for changes to your customer data', life: 15000 });
|
||||
await this.userService.save(this.user);
|
||||
}
|
||||
onUpload(event:any){
|
||||
|
||||
|
||||
onUploadCompanyLogo(event:any){
|
||||
const uniqueSuffix = '?_ts=' + new Date().getTime();
|
||||
this.imageUrl = `${environment.apiBaseUrl}/profile_${this.user.id}${uniqueSuffix}` //`http://IhrServer:Port/${newImagePath}${uniqueSuffix}`;
|
||||
this.companyLogoUrl = `${environment.apiBaseUrl}/company_${this.user.id}${uniqueSuffix}` //`http://IhrServer:Port/${newImagePath}${uniqueSuffix}`;
|
||||
}
|
||||
onUploadProfilePicture(event:any){
|
||||
const uniqueSuffix = '?_ts=' + new Date().getTime();
|
||||
this.profileUrl = `${environment.apiBaseUrl}/profile_${this.user.id}${uniqueSuffix}` //`http://IhrServer:Port/${newImagePath}${uniqueSuffix}`;
|
||||
}
|
||||
setImageToFallback(event: Event) {
|
||||
(event.target as HTMLImageElement).src = `/assets/images/placeholder.png`; // Pfad zum Platzhalterbild
|
||||
}
|
||||
|
||||
|
||||
suggestions: string[] | undefined;
|
||||
|
||||
async search(event: AutoCompleteCompleteEvent) {
|
||||
const result = await lastValueFrom(this.geoService.findCitiesStartingWith(event.query))
|
||||
this.suggestions = result.map(r=>`${r.city} - ${r.state_code}`).slice(0,5);
|
||||
}
|
||||
addLicence(){
|
||||
this.user.licensedIn.push({name:'',value:''});
|
||||
}
|
||||
removeLicence(){
|
||||
this.user.licensedIn.splice(this.user.licensedIn.length-2,1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,6 @@
|
||||
<label for="email" class="block font-medium text-900 mb-2">Title of Listing</label>
|
||||
<input id="email" type="text" pInputText [(ngModel)]="listing.title">
|
||||
</div>
|
||||
@if (listing.listingsCategory==='business' || listing.listingsCategory==='professionals_brokers'){
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<label for="summary" class="block font-medium text-900 mb-2">Summary (Brief description)</label>
|
||||
<textarea id="summary" type="text" pInputTextarea rows="5" [autoResize]="true" [ngModel]="listing.summary | arrayToString:'\n\n'" (ngModelChange)="updateSummary($event)"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<label for="description" class="block font-medium text-900 mb-2">Description</label>
|
||||
@@ -40,21 +32,22 @@
|
||||
[style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
}
|
||||
<div class="mb-4">
|
||||
<label for="listingCategory" class="block font-medium text-900 mb-2">Location</label>
|
||||
<p-dropdown id="listingCategory" [options]="selectOptions?.locations" [(ngModel)]="listing.location" optionLabel="name"
|
||||
optionValue="value" [showClear]="true" placeholder="Location"
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="listingCategory" class="block font-medium text-900 mb-2">State</label>
|
||||
<p-dropdown id="listingCategory" [options]="selectOptions?.states" [(ngModel)]="listing.state" optionLabel="name"
|
||||
optionValue="value" [showClear]="true" placeholder="State"
|
||||
[style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
@if (listing.listingsCategory==='professionals_brokers'){
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<label for="address" class="block font-medium text-900 mb-2">Address</label>
|
||||
<input id="address" type="text" pInputText [(ngModel)]="listing.address">
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="listingCategory" class="block font-medium text-900 mb-2">City</label>
|
||||
<!-- <p-dropdown id="listingCategory" [options]="selectOptions?.states" [(ngModel)]="listing.city" optionLabel="name"
|
||||
optionValue="value" [showClear]="true" placeholder="State"
|
||||
[style]="{ width: '100%'}"></p-dropdown> -->
|
||||
<p-autoComplete [(ngModel)]="listing.city" [suggestions]="suggestions" (completeMethod)="search($event)"></p-autoComplete>
|
||||
</div>
|
||||
}
|
||||
@if (listing.listingsCategory==='professionals_brokers' || listing.listingsCategory==='investment'){
|
||||
</div>
|
||||
<!-- @if (listing.listingsCategory==='investment'){
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<label for="email" class="block font-medium text-900 mb-2">Email</label>
|
||||
@@ -67,23 +60,13 @@
|
||||
<input id="address" type="text" pInputText [(ngModel)]="listing.website">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if (listing.listingsCategory==='professionals_brokers'){
|
||||
<div class="mb-4">
|
||||
<label for="category" class="block font-medium text-900 mb-2">Category</label>
|
||||
<p-dropdown id="category" [options]="selectOptions?.categories" [(ngModel)]="listing.category" optionLabel="name"
|
||||
optionValue="value" [showClear]="true" placeholder="Category"
|
||||
[style]="{ width: '100%'}"></p-dropdown>
|
||||
</div>
|
||||
}
|
||||
@if (listing.listingsCategory==='investment'){
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<label for="phoneNumber" class="block font-medium text-900 mb-2">Phone Number</label>
|
||||
<input id="phoneNumber" type="text" pInputText [(ngModel)]="listing.phoneNumber">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
} -->
|
||||
</div>
|
||||
</div>
|
||||
<p-divider></p-divider>
|
||||
@@ -93,54 +76,76 @@
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="price" class="block font-medium text-900 mb-2">Price</label>
|
||||
<!-- <input id="price" type="text" pInputText [(ngModel)]="listing.price"> -->
|
||||
<p-inputNumber mode="currency" currency="USD" inputId="price" type="text" [(ngModel)]="listing.price"></p-inputNumber>
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-6 flex align-items-end justify-content-center">
|
||||
<p-checkbox [binary]="true" [(ngModel)]="listing.realEstateIncluded"></p-checkbox>
|
||||
<span class="ml-2 text-900">Real Estate Included</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="salesRevenue" class="block font-medium text-900 mb-2">Sales Revenue</label>
|
||||
<!-- <input id="salesRevenue" type="text" pInputText [(ngModel)]="listing.salesRevenue"> -->
|
||||
<p-inputNumber mode="currency" currency="USD" inputId="salesRevenue" type="text" [(ngModel)]="listing.salesRevenue"></p-inputNumber>
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="cashFlow" class="block font-medium text-900 mb-2">Cash Flow</label>
|
||||
<!-- <input id="cashFlow" type="text" pInputText [(ngModel)]="listing.cashFlow"> -->
|
||||
<p-inputNumber mode="currency" currency="USD" inputId="cashFlow" type="text" [(ngModel)]="listing.cashFlow"></p-inputNumber>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="netProfit" class="block font-medium text-900 mb-2">Net Profit</label>
|
||||
<!-- <input id="netProfit" type="text" pInputText [(ngModel)]="listing.netProfit"> -->
|
||||
<p-inputNumber mode="currency" currency="USD" inputId="netProfit" type="text" [(ngModel)]="listing.netProfit"></p-inputNumber>
|
||||
<label for="cashFlow" class="block font-medium text-900 mb-2">Cash Flow</label>
|
||||
<p-inputNumber mode="currency" currency="USD" inputId="cashFlow" type="text" [(ngModel)]="listing.cashFlow"></p-inputNumber>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="employees" class="block font-medium text-900 mb-2">Years Established Since</label>
|
||||
<p-inputNumber mode="employees" mode="decimal" inputId="employees" type="text" [(ngModel)]="listing.established"></p-inputNumber>
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="employees" class="block font-medium text-900 mb-2">Employees</label>
|
||||
<!-- <input id="employees" type="text" pInputText [(ngModel)]="listing.employees"> -->
|
||||
<p-inputNumber mode="employees" mode="decimal" inputId="employees" type="text" [(ngModel)]="listing.employees"></p-inputNumber>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-4 ">
|
||||
<p-checkbox [binary]="true" [(ngModel)]="listing.realEstateIncluded"></p-checkbox>
|
||||
<span class="ml-2 text-900">Real Estate Included</span>
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-4">
|
||||
<p-checkbox [binary]="true" [(ngModel)]="listing.leasedLocation"></p-checkbox>
|
||||
<span class="ml-2 text-900">Leased Location</span>
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-4">
|
||||
<p-checkbox [binary]="true" [(ngModel)]="listing.franchiseResale"></p-checkbox>
|
||||
<span class="ml-2 text-900">Franchise Re-Sale</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="inventory" class="block font-medium text-900 mb-2">Inventory</label>
|
||||
<textarea id="inventory" type="text" pInputTextarea rows="5" [autoResize]="true" [(ngModel)]="listing.inventory"></textarea>
|
||||
<label for="supportAndTraining" class="block font-medium text-900 mb-2">Support & Training</label>
|
||||
<!-- <textarea id="inventory" type="text" pInputTextarea rows="5" [autoResize]="true" [(ngModel)]="listing.supportAndTraining"></textarea> -->
|
||||
<input id="supportAndTraining" type="text" pInputText [(ngModel)]="listing.supportAndTraining">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="reasonForSale" class="block font-medium text-900 mb-2">Reason for Sale</label>
|
||||
<textarea id="reasonForSale" type="text" pInputTextarea rows="5" [autoResize]="true" [(ngModel)]="listing.reasonForSale"></textarea>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="brokerLicensing" class="block font-medium text-900 mb-2">Broker Licensing</label>
|
||||
<input id="brokerLicensing" type="text" pInputText [(ngModel)]="listing.brokerLicencing">
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="brokerLicensing" class="block font-medium text-900 mb-2">Broker Licensing</label>
|
||||
<input id="brokerLicensing" type="text" pInputText [(ngModel)]="listing.brokerLicencing">
|
||||
</div>
|
||||
<div class="mb-4 col-12 md:col-6">
|
||||
<label for="internalListingNumber" class="block font-medium text-900 mb-2">Internal Listing Number</label>
|
||||
<p-inputNumber mode="decimal" inputId="internalListingNumber" type="text" [(ngModel)]="listing.internalListingNumber"></p-inputNumber>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="internalListing" class="block font-medium text-900 mb-2">Internal Listing (Will not be shown on the listing, for your records only.)</label>
|
||||
<label for="internalListing" class="block font-medium text-900 mb-2">Internal Notes (Will not be shown on the listing, for your records only.)</label>
|
||||
<input id="internalListing" type="text" pInputText [(ngModel)]="listing.internals">
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="mb-4 col-12 md:col-6 ">
|
||||
<!-- <p-tag value="New"></p-tag> -->
|
||||
<!-- <p-checkbox [binary]="true" [(ngModel)]="listing.draft"></p-checkbox> -->
|
||||
<p-inputSwitch inputId="draft" [(ngModel)]="listing.draft"></p-inputSwitch>
|
||||
<!-- <span class="ml-2 text-900">Share my data with contacts</span> -->
|
||||
<span class="ml-2 text-900 absolute translate-y-5">Draft Mode (Will not be shown as public listing)</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div>
|
||||
@if (mode==='create'){
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.translate-y-5{
|
||||
transform: translateY(5px);
|
||||
}
|
||||
@@ -25,7 +25,11 @@ import { ArrayToStringPipe } from '../../../pipes/array-to-string.pipe';
|
||||
import { UserService } from '../../../services/user.service';
|
||||
import { SharedModule } from '../../../shared/shared/shared.module';
|
||||
import { MessageService } from 'primeng/api';
|
||||
import { BusinessListing, ListingType, User } from '../../../../../../common-models/src/main.model';
|
||||
import { AutoCompleteCompleteEvent, BusinessListing, ListingType, User } from '../../../../../../common-models/src/main.model';
|
||||
import { GeoResult, GeoService } from '../../../services/geo.service';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'create-listing',
|
||||
standalone: true,
|
||||
@@ -43,7 +47,13 @@ export class EditListingComponent {
|
||||
listing:ListingType = createGenericObject<BusinessListing>();
|
||||
private id: string | undefined = this.activatedRoute.snapshot.params['id'] as string | undefined;
|
||||
user:User;
|
||||
constructor(public selectOptions:SelectOptionsService,private router: Router,private activatedRoute: ActivatedRoute,private listingsService:ListingsService,public userService: UserService,private messageService: MessageService){
|
||||
constructor(public selectOptions:SelectOptionsService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private listingsService:ListingsService,
|
||||
public userService: UserService,
|
||||
private messageService: MessageService,
|
||||
private geoService:GeoService){
|
||||
this.user=this.userService.getUser();
|
||||
// Abonniere Router-Events, um den aktiven Link zu ermitteln
|
||||
this.router.events.subscribe(event => {
|
||||
@@ -62,10 +72,10 @@ export class EditListingComponent {
|
||||
this.listing.listingsCategory='business';
|
||||
}
|
||||
}
|
||||
updateSummary(value: string): void {
|
||||
const lines = value.split('\n');
|
||||
(<BusinessListing>this.listing).summary = lines.filter(l=>l.trim().length>0);
|
||||
}
|
||||
// updateSummary(value: string): void {
|
||||
// const lines = value.split('\n');
|
||||
// (<BusinessListing>this.listing).summary = lines.filter(l=>l.trim().length>0);
|
||||
// }
|
||||
async update(id:string){
|
||||
await this.listingsService.update(this.listing,this.listing.id);
|
||||
this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Listing has been updated', life: 3000 });
|
||||
@@ -74,4 +84,11 @@ export class EditListingComponent {
|
||||
await this.listingsService.create(this.listing);
|
||||
this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Listing has been created', life: 3000 });
|
||||
}
|
||||
|
||||
suggestions: string[] | undefined;
|
||||
|
||||
async search(event: AutoCompleteCompleteEvent) {
|
||||
const result = await lastValueFrom(this.geoService.findCitiesStartingWith(event.query,this.listing.state))//[...Array(5).keys()].map(item => event.query + '-' + item);
|
||||
this.suggestions = result.map(r=>r.city).slice(0,5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<tr>
|
||||
<td class="wide-column line-height-3">{{ listing.title }}</td>
|
||||
<td>{{ selectOptions.getListingsCategory(listing.listingsCategory) }}</td>
|
||||
<td>{{ selectOptions.getLocation(listing.location) }}</td>
|
||||
<td>{{ selectOptions.getState(listing.state) }}</td>
|
||||
<td>
|
||||
<button pButton pRipple icon="pi pi-eye" class="p-button-rounded p-button-success mr-2" [routerLink]="['/details',listing.id]"></button>
|
||||
</td>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<tr>
|
||||
<td class="wide-column line-height-3">{{ listing.title }}</td>
|
||||
<td>{{ selectOptions.getListingsCategory(listing.listingsCategory) }}</td>
|
||||
<td>{{ selectOptions.getLocation(listing.location) }}</td>
|
||||
<td>{{ selectOptions.getState(listing.location) }}</td>
|
||||
<td>
|
||||
<button pButton pRipple icon="pi pi-pencil" class="p-button-rounded p-button-success mr-2" [routerLink]="['/editListing',listing.id]"></button>
|
||||
<button pButton pRipple icon="pi pi-trash" class="p-button-rounded p-button-warning" (click)="confirm($event,listing)"></button>
|
||||
|
||||
Reference in New Issue
Block a user