Bug Fixed: #34,#28,#48,#46,#2,#15
This commit is contained in:
parent
24a3d210f0
commit
044f8efa0f
|
|
@ -18,6 +18,7 @@
|
||||||
<div class="col-12 md:col-3 text-500">
|
<div class="col-12 md:col-3 text-500">
|
||||||
<div class="text-black font-bold line-height-3 mb-3">Actions</div>
|
<div class="text-black font-bold line-height-3 mb-3">Actions</div>
|
||||||
<a *ngIf="!keycloakService.isLoggedIn()" (click)="login()" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline">Login</a>
|
<a *ngIf="!keycloakService.isLoggedIn()" (click)="login()" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline">Login</a>
|
||||||
|
<a *ngIf="!keycloakService.isLoggedIn()" (click)="register()" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline">Register</a>
|
||||||
<a *ngIf="keycloakService.isLoggedIn()" [routerLink]="['/account']" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline">Account</a>
|
<a *ngIf="keycloakService.isLoggedIn()" [routerLink]="['/account']" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline">Account</a>
|
||||||
<a *ngIf="keycloakService.isLoggedIn()" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline" (click)="keycloakService.logout()">Log Out</a>
|
<a *ngIf="keycloakService.isLoggedIn()" class="text-500 line-height-3 block cursor-pointer mb-2 no-underline" (click)="keycloakService.logout()">Log Out</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,7 @@ export class FooterComponent {
|
||||||
redirectUri: window.location.href,
|
redirectUri: window.location.href,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
register() {
|
||||||
|
this.keycloakService.register({ redirectUri: `${window.location.origin}/account` });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,14 +91,17 @@ export class HeaderComponent {
|
||||||
{
|
{
|
||||||
label: 'Businesses for Sale',
|
label: 'Businesses for Sale',
|
||||||
routerLink: '/businessListings',
|
routerLink: '/businessListings',
|
||||||
|
state: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Commercial Property',
|
label: 'Commercial Property',
|
||||||
routerLink: '/commercialPropertyListings',
|
routerLink: '/commercialPropertyListings',
|
||||||
|
state: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Professionals/Brokers Directory',
|
label: 'Professionals/Brokers Directory',
|
||||||
routerLink: '/brokerListings',
|
routerLink: '/brokerListings',
|
||||||
|
state: {},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
this.loginItems = [
|
this.loginItems = [
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
<angular-cropper #cropper [imageUrl]="imageUrl" [cropperOptions]="cropperConfig"></angular-cropper>
|
<angular-cropper #cropper [imageUrl]="imageUrl" [cropperOptions]="cropperConfig"></angular-cropper>
|
||||||
<div class="flex justify-content-between mt-3">
|
<div class="flex justify-content-between mt-3">
|
||||||
@if(ratioVariable){
|
@if(ratioVariable){
|
||||||
<div>
|
<div>
|
||||||
<p-selectButton [options]="stateOptions" [ngModel]="value" (ngModelChange)="changeAspectRation($event)"
|
<p-selectButton [options]="stateOptions" [ngModel]="value" (ngModelChange)="changeAspectRation($event)" optionLabel="label" optionValue="value" class="small"></p-selectButton>
|
||||||
optionLabel="label" optionValue="value"></p-selectButton>
|
</div>
|
||||||
</div>
|
} @else {
|
||||||
} @else {
|
<div></div>
|
||||||
<div></div>
|
}
|
||||||
}
|
<div class="flex justify-content-between">
|
||||||
<div>
|
<p-button icon="pi" (click)="cancelUpload()" label="Cancel" [outlined]="true" size="small" class="mr-2"></p-button>
|
||||||
<p-button icon="pi" (click)="cancelUpload()" label="Cancel" [outlined]="true"></p-button>
|
<p-button icon="pi pi-check" (click)="sendImage()" label="Finish" pAutoFocus [autofocus]="true" size="small"></p-button>
|
||||||
<p-button icon="pi pi-check" (click)="sendImage()" label="Finish" pAutoFocus [autofocus]="true"></p-button>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
::ng-deep p-selectbutton.small .p-button {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
padding: 0.65625rem 1.09375rem;
|
||||||
|
}
|
||||||
|
|
@ -1,67 +1,52 @@
|
||||||
import { Component, ViewChild } from '@angular/core';
|
import { Component, ViewChild } from '@angular/core';
|
||||||
import { AngularCropperjsModule, CropperComponent } from 'angular-cropperjs';
|
import { AngularCropperjsModule, CropperComponent } from 'angular-cropperjs';
|
||||||
import { LoadingService } from '../../services/loading.service';
|
|
||||||
import { ImageService } from '../../services/image.service';
|
|
||||||
import { HttpEventType } from '@angular/common/http';
|
|
||||||
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
|
||||||
import { FileUpload, FileUploadModule } from 'primeng/fileupload';
|
import { FileUpload, FileUploadModule } from 'primeng/fileupload';
|
||||||
import { environment } from '../../../environments/environment';
|
|
||||||
import { User } from '../../../../../bizmatch-server/src/models/db.model';
|
|
||||||
import { SharedModule } from '../../shared/shared/shared.module';
|
|
||||||
import { SelectButtonModule } from 'primeng/selectbutton';
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
||||||
import { KeyValueRatio } from '../../../../../bizmatch-server/src/models/main.model';
|
import { KeyValueRatio } from '../../../../../bizmatch-server/src/models/main.model';
|
||||||
export const stateOptions:KeyValueRatio[]=[
|
import { ImageService } from '../../services/image.service';
|
||||||
{label:'16/9',value:16/9},
|
import { LoadingService } from '../../services/loading.service';
|
||||||
{label:'1/1',value:1},
|
import { SharedModule } from '../../shared/shared/shared.module';
|
||||||
{label:'2/3',value:2/3},
|
export const stateOptions: KeyValueRatio[] = [
|
||||||
]
|
{ label: '16/9', value: 16 / 9 },
|
||||||
|
{ label: '1/1', value: 1 },
|
||||||
|
{ label: 'Free', value: NaN },
|
||||||
|
];
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-image-cropper',
|
selector: 'app-image-cropper',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [SharedModule,FileUploadModule,AngularCropperjsModule,SelectButtonModule],
|
imports: [SharedModule, FileUploadModule, AngularCropperjsModule, SelectButtonModule],
|
||||||
templateUrl: './image-cropper.component.html',
|
templateUrl: './image-cropper.component.html',
|
||||||
styleUrl: './image-cropper.component.scss'
|
styleUrl: './image-cropper.component.scss',
|
||||||
})
|
})
|
||||||
export class ImageCropperComponent {
|
export class ImageCropperComponent {
|
||||||
@ViewChild(CropperComponent) public angularCropper: CropperComponent;
|
@ViewChild(CropperComponent) public angularCropper: CropperComponent;
|
||||||
imageUrl:string; //wird im Template verwendet
|
imageUrl: string; //wird im Template verwendet
|
||||||
fileUpload:FileUpload
|
fileUpload: FileUpload;
|
||||||
value:number = stateOptions[0].value;
|
value: number = stateOptions[0].value;
|
||||||
cropperConfig={aspectRatio: this.value}
|
cropperConfig = { aspectRatio: this.value };
|
||||||
ratioVariable:boolean
|
ratioVariable: boolean;
|
||||||
stateOptions=stateOptions
|
stateOptions = stateOptions;
|
||||||
constructor(
|
constructor(private loadingService: LoadingService, private imageUploadService: ImageService, public config: DynamicDialogConfig, public ref: DynamicDialogRef) {}
|
||||||
private loadingService:LoadingService,
|
|
||||||
private imageUploadService: ImageService,
|
|
||||||
public config: DynamicDialogConfig,
|
|
||||||
public ref: DynamicDialogRef
|
|
||||||
){}
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this.config.data) {
|
if (this.config.data) {
|
||||||
this.imageUrl = this.config.data.imageUrl;
|
this.imageUrl = this.config.data.imageUrl;
|
||||||
this.fileUpload = this.config.data.fileUpload;
|
this.fileUpload = this.config.data.fileUpload;
|
||||||
this.cropperConfig = this.config.data.config ? this.config.data.config: this.cropperConfig;
|
this.cropperConfig = this.config.data.config ? this.config.data.config : this.cropperConfig;
|
||||||
this.ratioVariable = this.config.data.ratioVariable;
|
this.ratioVariable = this.config.data.ratioVariable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendImage(){
|
sendImage() {
|
||||||
// setTimeout(()=>{
|
this.fileUpload.clear();
|
||||||
// this.angularCropper.cropper.getCroppedCanvas().toBlob(async(blob) => {
|
|
||||||
// this.ref.close(blob);
|
|
||||||
// this.fileUpload.clear()
|
|
||||||
// }, 'image/jpg');
|
|
||||||
// },0)
|
|
||||||
|
|
||||||
this.fileUpload.clear()
|
|
||||||
this.ref.close(this.angularCropper.cropper);
|
this.ref.close(this.angularCropper.cropper);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelUpload(){
|
cancelUpload() {
|
||||||
this.fileUpload.clear();
|
this.fileUpload.clear();
|
||||||
this.ref.close();
|
this.ref.close();
|
||||||
}
|
}
|
||||||
changeAspectRation(ratio:number){
|
changeAspectRation(ratio: number) {
|
||||||
this.cropperConfig={aspectRatio: ratio}
|
this.cropperConfig = { aspectRatio: ratio };
|
||||||
this.angularCropper.cropper.setAspectRatio(ratio);
|
this.angularCropper.cropper.setAspectRatio(ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,50 +14,62 @@
|
||||||
<div class="col-12 md:col-6">
|
<div class="col-12 md:col-6">
|
||||||
<ul class="list-none p-0 m-0 border-top-1 border-300">
|
<ul class="list-none p-0 m-0 border-top-1 border-300">
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium flex">Description</div>
|
<div class="text-500 w-full md:w-3 font-medium flex">Description</div>
|
||||||
<div class="text-900 w-full md:w-10 line-height-3 flex flex-column" [innerHTML]="description"></div>
|
<div class="text-900 w-full md:w-9 line-height-3 flex flex-column" [innerHTML]="description"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">Category</div>
|
<div class="text-500 w-full md:w-3 font-medium">Category</div>
|
||||||
<div class="text-900 w-full md:w-10">
|
<div class="text-900 w-full md:w-9">
|
||||||
<p-chip [label]="selectOptions.getBusiness(listing.type)"></p-chip>
|
<p-chip [label]="selectOptions.getBusiness(listing.type)"></p-chip>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<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-500 w-full md:w-3 font-medium">Located in</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ selectOptions.getState(listing.state) }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.city }}, {{ selectOptions.getState(listing.state) }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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>
|
<div class="text-500 w-full md:w-3 font-medium">Asking Price</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.price | currency }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.price | currency }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Real Estate Included</div>
|
<div class="text-500 w-full md:w-3 font-medium">Sales revenue</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.realEstateIncluded ? 'Yes' : 'No' }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.salesRevenue | currency }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">Sales revenue</div>
|
<div class="text-500 w-full md:w-3 font-medium">Cash flow</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.salesRevenue | currency }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.cashFlow | currency }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Cash flow</div>
|
<div class="text-500 w-full md:w-3 font-medium">Type of Real Estate</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.cashFlow | currency }}</div>
|
<div class="text-900 w-full md:w-9">
|
||||||
|
@if (listing.realEstateIncluded){
|
||||||
|
<p-chip label="Real Estate Included"></p-chip>
|
||||||
|
} @if (listing.leasedLocation){
|
||||||
|
<p-chip label="Leased Location"></p-chip>
|
||||||
|
} @if (listing.franchiseResale){
|
||||||
|
<p-chip label="Franchise Re-Sale"></p-chip>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">Employees</div>
|
<div class="text-500 w-full md:w-3 font-medium">Employees</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.employees }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.employees }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Support & Training</div>
|
<div class="text-500 w-full md:w-3 font-medium">Established since</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.supportAndTraining }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.established }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">Reason for Sale</div>
|
<div class="text-500 w-full md:w-3 font-medium">Support & Training</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.reasonForSale }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.supportAndTraining }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Broker licensing</div>
|
<div class="text-500 w-full md:w-3 font-medium">Reason for Sale</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.brokerLicencing }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.reasonForSale }}</div>
|
||||||
|
</li>
|
||||||
|
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
||||||
|
<div class="text-500 w-full md:w-3 font-medium">Broker licensing</div>
|
||||||
|
<div class="text-900 w-full md:w-9">{{ listing.brokerLicencing }}</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@if(listing && listingUser && (listingUser?.email===user?.email || isAdmin())){
|
@if(listing && listingUser && (listingUser?.email===user?.email || isAdmin())){
|
||||||
|
|
@ -79,7 +91,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="field mb-4 col-12 md:col-6">
|
<div class="field mb-4 col-12 md:col-6">
|
||||||
<label for="phoneNumber" class="font-medium text-900">Phone Number</label>
|
<label for="phoneNumber" class="font-medium text-900">Phone Number</label>
|
||||||
<input id="phoneNumber" type="text" pInputText [(ngModel)]="mailinfo.sender.phoneNumber" />
|
<!-- <input id="phoneNumber" type="text" pInputText [(ngModel)]="mailinfo.sender.phoneNumber" /> -->
|
||||||
|
<p-inputMask mask="(999) 999-9999" placeholder="(123) 456-7890" [(ngModel)]="mailinfo.sender.phoneNumber"></p-inputMask>
|
||||||
</div>
|
</div>
|
||||||
<div class="field mb-4 col-12 md:col-6">
|
<div class="field mb-4 col-12 md:col-6">
|
||||||
<label for="state" class="font-medium text-900">Country/State</label>
|
<label for="state" class="font-medium text-900">Country/State</label>
|
||||||
|
|
@ -92,9 +105,9 @@
|
||||||
</div>
|
</div>
|
||||||
@if(listingUser){
|
@if(listingUser){
|
||||||
<div class="surface-border mb-4 col-12 flex align-items-center">
|
<div class="surface-border mb-4 col-12 flex align-items-center">
|
||||||
Listing by <a routerLink="/details-user/{{ listingUser.id }}" class="mr-2">{{ listingUser.firstname }} {{ listingUser.lastname }}</a>
|
Listing by <a routerLink="/details-user/{{ listingUser.id }}" class="mr-2 font-semibold">{{ listingUser.firstname }} {{ listingUser.lastname }}</a>
|
||||||
@if(listingUser.hasCompanyLogo){
|
@if(listingUser.hasCompanyLogo){
|
||||||
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listing.imageName }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="height: 30px; max-width: 100px" />
|
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listing.imageName }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="max-height: 30px; max-width: 100px" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { KeycloakService } from 'keycloak-angular';
|
||||||
import onChange from 'on-change';
|
import onChange from 'on-change';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from 'primeng/api';
|
||||||
import { GalleriaModule } from 'primeng/galleria';
|
import { GalleriaModule } from 'primeng/galleria';
|
||||||
|
import { InputMaskModule } from 'primeng/inputmask';
|
||||||
import { lastValueFrom } from 'rxjs';
|
import { lastValueFrom } from 'rxjs';
|
||||||
import { BusinessListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
|
import { BusinessListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
|
||||||
import { KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
|
import { KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
|
||||||
|
|
@ -16,11 +17,10 @@ import { SelectOptionsService } from '../../../services/select-options.service';
|
||||||
import { UserService } from '../../../services/user.service';
|
import { UserService } from '../../../services/user.service';
|
||||||
import { SharedModule } from '../../../shared/shared/shared.module';
|
import { SharedModule } from '../../../shared/shared/shared.module';
|
||||||
import { getCriteriaStateObject, getSessionStorageHandler, map2User } from '../../../utils/utils';
|
import { getCriteriaStateObject, getSessionStorageHandler, map2User } from '../../../utils/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-details-business-listing',
|
selector: 'app-details-business-listing',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [SharedModule, GalleriaModule],
|
imports: [SharedModule, GalleriaModule, InputMaskModule],
|
||||||
providers: [MessageService],
|
providers: [MessageService],
|
||||||
templateUrl: './details-business-listing.component.html',
|
templateUrl: './details-business-listing.component.html',
|
||||||
styleUrl: './details-business-listing.component.scss',
|
styleUrl: './details-business-listing.component.scss',
|
||||||
|
|
@ -82,7 +82,7 @@ export class DetailsBusinessListingComponent {
|
||||||
this.keycloakUser = map2User(token);
|
this.keycloakUser = map2User(token);
|
||||||
if (this.keycloakUser) {
|
if (this.keycloakUser) {
|
||||||
this.user = await this.userService.getByMail(this.keycloakUser.email);
|
this.user = await this.userService.getByMail(this.keycloakUser.email);
|
||||||
this.mailinfo.sender = { name: `${this.user.firstname} ${this.user.lastname}`, email: this.user.email, phoneNumber: this.user.email, state: this.user.companyLocation };
|
this.mailinfo.sender = { name: `${this.user.firstname} ${this.user.lastname}`, email: this.user.email, phoneNumber: this.user.phoneNumber, state: this.user.companyLocation };
|
||||||
}
|
}
|
||||||
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'business'));
|
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'business'));
|
||||||
this.listingUser = await this.userService.getById(this.listing.userId);
|
this.listingUser = await this.userService.getById(this.listing.userId);
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,32 @@
|
||||||
<div class="col-12 md:col-6">
|
<div class="col-12 md:col-6">
|
||||||
<ul class="list-none p-0 m-0 border-top-1 border-300">
|
<ul class="list-none p-0 m-0 border-top-1 border-300">
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium flex">Description</div>
|
<div class="text-500 w-full md:w-3 font-medium flex">Description</div>
|
||||||
<div class="text-900 w-full md:w-10 line-height-3" [innerHTML]="description"></div>
|
<div class="text-900 w-full md:w-9 line-height-3" [innerHTML]="description"></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">Property Category</div>
|
<div class="text-500 w-full md:w-3 font-medium">Property Category</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ selectOptions.getCommercialProperty(listing.type) }}</div>
|
<div class="text-900 w-full md:w-9">{{ selectOptions.getCommercialProperty(listing.type) }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<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-500 w-full md:w-3 font-medium">Located in</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ selectOptions.getState(listing.state) }}</div>
|
<div class="text-900 w-full md:w-9">{{ selectOptions.getState(listing.state) }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">City</div>
|
<div class="text-500 w-full md:w-3 font-medium">City</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.city }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.city }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Zip Code</div>
|
<div class="text-500 w-full md:w-3 font-medium">Zip Code</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.zipCode }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.zipCode }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">County</div>
|
<div class="text-500 w-full md:w-3 font-medium">County</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.county }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.county }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Asking Price:</div>
|
<div class="text-500 w-full md:w-3 font-medium">Asking Price:</div>
|
||||||
<div class="text-900 w-full md:w-10">{{ listing.price | currency }}</div>
|
<div class="text-900 w-full md:w-9">{{ listing.price | currency }}</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
@ -69,7 +69,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="field mb-4 col-12 md:col-6">
|
<div class="field mb-4 col-12 md:col-6">
|
||||||
<label for="phoneNumber" class="font-medium text-900">Phone Number</label>
|
<label for="phoneNumber" class="font-medium text-900">Phone Number</label>
|
||||||
<input id="phoneNumber" type="text" pInputText [(ngModel)]="mailinfo.sender.phoneNumber" />
|
<!-- <input id="phoneNumber" type="text" pInputText [(ngModel)]="mailinfo.sender.phoneNumber" /> -->
|
||||||
|
<p-inputMask mask="(999) 999-9999" placeholder="(123) 456-7890" [(ngModel)]="mailinfo.sender.phoneNumber"></p-inputMask>
|
||||||
</div>
|
</div>
|
||||||
<div class="field mb-4 col-12 md:col-6">
|
<div class="field mb-4 col-12 md:col-6">
|
||||||
<label for="state" class="font-medium text-900">Country/State</label>
|
<label for="state" class="font-medium text-900">Country/State</label>
|
||||||
|
|
@ -82,9 +83,9 @@
|
||||||
</div>
|
</div>
|
||||||
@if(listingUser){
|
@if(listingUser){
|
||||||
<div class="surface-border mb-4 col-12 flex align-items-center">
|
<div class="surface-border mb-4 col-12 flex align-items-center">
|
||||||
Listing by <a routerLink="/details-user/{{ listingUser.id }}" class="mr-2">{{ listingUser.firstname }} {{ listingUser.lastname }}</a>
|
Listing by <a routerLink="/details-user/{{ listingUser.id }}" class="mr-2 font-semibold">{{ listingUser.firstname }} {{ listingUser.lastname }}</a>
|
||||||
@if(listingUser.hasCompanyLogo){
|
@if(listingUser.hasCompanyLogo){
|
||||||
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listing.imagePath }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="height: 30px; max-width: 100px" />
|
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listing.imagePath }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="max-height: 30px; max-width: 100px" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { KeycloakService } from 'keycloak-angular';
|
||||||
import onChange from 'on-change';
|
import onChange from 'on-change';
|
||||||
import { MessageService } from 'primeng/api';
|
import { MessageService } from 'primeng/api';
|
||||||
import { GalleriaModule } from 'primeng/galleria';
|
import { GalleriaModule } from 'primeng/galleria';
|
||||||
|
import { InputMaskModule } from 'primeng/inputmask';
|
||||||
import { lastValueFrom } from 'rxjs';
|
import { lastValueFrom } from 'rxjs';
|
||||||
import { CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
|
import { CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
|
||||||
import { ErrorResponse, KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
|
import { ErrorResponse, KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
|
||||||
|
|
@ -21,7 +22,7 @@ import { getCriteriaStateObject, getSessionStorageHandler, map2User } from '../.
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-details-commercial-property-listing',
|
selector: 'app-details-commercial-property-listing',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [SharedModule, GalleriaModule],
|
imports: [SharedModule, GalleriaModule, InputMaskModule],
|
||||||
providers: [MessageService],
|
providers: [MessageService],
|
||||||
templateUrl: './details-commercial-property-listing.component.html',
|
templateUrl: './details-commercial-property-listing.component.html',
|
||||||
styleUrl: './details-commercial-property-listing.component.scss',
|
styleUrl: './details-commercial-property-listing.component.scss',
|
||||||
|
|
@ -79,7 +80,7 @@ export class DetailsCommercialPropertyListingComponent {
|
||||||
this.keycloakUser = map2User(token);
|
this.keycloakUser = map2User(token);
|
||||||
if (this.keycloakUser) {
|
if (this.keycloakUser) {
|
||||||
this.user = await this.userService.getByMail(this.keycloakUser.email);
|
this.user = await this.userService.getByMail(this.keycloakUser.email);
|
||||||
this.mailinfo.sender = { name: `${this.user.firstname} ${this.user.lastname}`, email: this.user.email, phoneNumber: this.user.email, state: this.user.companyLocation };
|
this.mailinfo.sender = { name: `${this.user.firstname} ${this.user.lastname}`, email: this.user.email, phoneNumber: this.user.phoneNumber, state: this.user.companyLocation };
|
||||||
}
|
}
|
||||||
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty'));
|
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty'));
|
||||||
this.listingUser = await this.userService.getById(this.listing.userId);
|
this.listingUser = await this.userService.getById(this.listing.userId);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
<!-- <span class="font-medium text-500">Logo</span> -->
|
<!-- <span class="font-medium text-500">Logo</span> -->
|
||||||
<div>
|
<div>
|
||||||
@if(user.hasCompanyLogo){
|
@if(user.hasCompanyLogo){
|
||||||
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ emailToDirName(user.email) }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="height: 60px; max-width: 100px" />
|
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ emailToDirName(user.email) }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="max-height: 60px; max-width: 100px" />
|
||||||
}
|
}
|
||||||
<!-- <img *ngIf="!user.hasCompanyLogo" src="assets/images/placeholder.png"
|
<!-- <img *ngIf="!user.hasCompanyLogo" src="assets/images/placeholder.png"
|
||||||
class="mr-5 lg:mb-0" style="height:60px;max-width:100px" /> -->
|
class="mr-5 lg:mb-0" style="height:60px;max-width:100px" /> -->
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
<li class="flex align-items-center py-3 px-2 flex-wrap">
|
||||||
<div class="text-500 w-full md:w-2 font-medium">Phone Number</div>
|
<div class="text-500 w-full md:w-2 font-medium">Phone Number</div>
|
||||||
<div class="text-900 w-full md:w-10 line-height-3">{{ user.phoneNumber }}</div>
|
<div class="text-900 w-full md:w-10 line-height-3">{{ formatPhoneNumber(user.phoneNumber) }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex align-items-center py-3 px-2 flex-wrap surface-ground">
|
<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">EMail Address</div>
|
<div class="text-500 w-full md:w-2 font-medium">EMail Address</div>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { ListingsService } from '../../../services/listings.service';
|
||||||
import { SelectOptionsService } from '../../../services/select-options.service';
|
import { SelectOptionsService } from '../../../services/select-options.service';
|
||||||
import { UserService } from '../../../services/user.service';
|
import { UserService } from '../../../services/user.service';
|
||||||
import { SharedModule } from '../../../shared/shared/shared.module';
|
import { SharedModule } from '../../../shared/shared/shared.module';
|
||||||
import { map2User } from '../../../utils/utils';
|
import { formatPhoneNumber, map2User } from '../../../utils/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-details-user',
|
selector: 'app-details-user',
|
||||||
|
|
@ -38,6 +38,7 @@ export class DetailsUserComponent {
|
||||||
ts = new Date().getTime();
|
ts = new Date().getTime();
|
||||||
env = environment;
|
env = environment;
|
||||||
emailToDirName = emailToDirName;
|
emailToDirName = emailToDirName;
|
||||||
|
formatPhoneNumber = formatPhoneNumber;
|
||||||
constructor(
|
constructor(
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
#sky-line {
|
#sky-line {
|
||||||
background-image: url(../../../../assets/images/bw-sky.jpg);
|
background-image: url(../../../../assets/images/bw-sky.jpg);
|
||||||
height: 204px;
|
height: 204px;
|
||||||
background-position: bottom;
|
background-position: bottom;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
}
|
}
|
||||||
.search{
|
.search {
|
||||||
background-color: #343F69;
|
background-color: #343f69;
|
||||||
}
|
}
|
||||||
::ng-deep p-paginator div {
|
::ng-deep p-paginator div {
|
||||||
background-color: var(--surface-200) !important;
|
background-color: var(--surface-200) !important;
|
||||||
// background-color: var(--surface-400) !important;
|
// background-color: var(--surface-400) !important;
|
||||||
}
|
}
|
||||||
.rounded-image {
|
.rounded-image {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
// width: 100px;
|
// width: 100px;
|
||||||
max-width: 100px;
|
max-width: 100px;
|
||||||
height: 45px;
|
max-height: 45px;
|
||||||
border: 1px solid rgba(0,0,0,0.2);
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
padding: 1px 1px;
|
padding: 1px 1px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="mb-4 col-12 md:col-4">
|
<div class="mb-4 col-12 md:col-4">
|
||||||
<label for="phoneNumber" class="block font-medium text-900 mb-2">Your Phone Number</label>
|
<label for="phoneNumber" class="block font-medium text-900 mb-2">Your Phone Number</label>
|
||||||
<input id="phoneNumber" type="text" pInputText [(ngModel)]="user.phoneNumber" />
|
<p-inputMask mask="(999) 999-9999" placeholder="(123) 456-7890" [(ngModel)]="user.phoneNumber"></p-inputMask>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 col-12 md:col-4">
|
<div class="mb-4 col-12 md:col-4">
|
||||||
<label for="companyWebsite" class="block font-medium text-900 mb-2">Company Website</label>
|
<label for="companyWebsite" class="block font-medium text-900 mb-2">Company Website</label>
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
/* Stil für das FontAwesome Icon */
|
/* Stil für das FontAwesome Icon */
|
||||||
.image-wrap fa-icon {
|
.image-wrap fa-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px; /* Positioniert das Icon am oberen Rand des Bildes */
|
top: -5px; /* Positioniert das Icon am oberen Rand des Bildes */
|
||||||
right: 5px; /* Positioniert das Icon am rechten Rand des Bildes */
|
right: -18px; /* Positioniert das Icon am rechten Rand des Bildes */
|
||||||
color: #fff; /* Weiße Farbe für das Icon */
|
color: #fff; /* Weiße Farbe für das Icon */
|
||||||
background-color: rgba(0, 0, 0, 0.5); /* Halbtransparenter Hintergrund für bessere Sichtbarkeit */
|
background-color: rgba(0, 0, 0, 0.5); /* Halbtransparenter Hintergrund für bessere Sichtbarkeit */
|
||||||
padding: 5px; /* Ein wenig Platz um das Icon */
|
padding: 5px; /* Ein wenig Platz um das Icon */
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { DialogModule } from 'primeng/dialog';
|
||||||
import { DialogService, DynamicDialogModule, DynamicDialogRef } from 'primeng/dynamicdialog';
|
import { DialogService, DynamicDialogModule, DynamicDialogRef } from 'primeng/dynamicdialog';
|
||||||
import { EditorModule } from 'primeng/editor';
|
import { EditorModule } from 'primeng/editor';
|
||||||
import { FileUpload, FileUploadModule } from 'primeng/fileupload';
|
import { FileUpload, FileUploadModule } from 'primeng/fileupload';
|
||||||
|
import { InputMaskModule } from 'primeng/inputmask';
|
||||||
import { SelectButtonModule } from 'primeng/selectbutton';
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
||||||
import { lastValueFrom } from 'rxjs';
|
import { lastValueFrom } from 'rxjs';
|
||||||
import { User } from '../../../../../../bizmatch-server/src/models/db.model';
|
import { User } from '../../../../../../bizmatch-server/src/models/db.model';
|
||||||
|
|
@ -23,12 +24,12 @@ import { SelectOptionsService } from '../../../services/select-options.service';
|
||||||
import { SubscriptionsService } from '../../../services/subscriptions.service';
|
import { SubscriptionsService } from '../../../services/subscriptions.service';
|
||||||
import { UserService } from '../../../services/user.service';
|
import { UserService } from '../../../services/user.service';
|
||||||
import { SharedModule } from '../../../shared/shared/shared.module';
|
import { SharedModule } from '../../../shared/shared/shared.module';
|
||||||
import { map2User } from '../../../utils/utils';
|
import { getDialogWidth, getImageDimensions, map2User } from '../../../utils/utils';
|
||||||
import { TOOLBAR_OPTIONS } from '../../utils/defaults';
|
import { TOOLBAR_OPTIONS } from '../../utils/defaults';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-account',
|
selector: 'app-account',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [SharedModule, FileUploadModule, EditorModule, AngularCropperjsModule, DialogModule, SelectButtonModule, DynamicDialogModule, ConfirmDialogModule],
|
imports: [SharedModule, FileUploadModule, EditorModule, AngularCropperjsModule, DialogModule, SelectButtonModule, DynamicDialogModule, ConfirmDialogModule, InputMaskModule],
|
||||||
providers: [MessageService, DialogService, ConfirmationService],
|
providers: [MessageService, DialogService, ConfirmationService],
|
||||||
templateUrl: './account.component.html',
|
templateUrl: './account.component.html',
|
||||||
styleUrl: './account.component.scss',
|
styleUrl: './account.component.scss',
|
||||||
|
|
@ -124,46 +125,46 @@ export class AccountComponent {
|
||||||
const imageUrl = URL.createObjectURL(event.files[0]);
|
const imageUrl = URL.createObjectURL(event.files[0]);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
const config = { aspectRatio: type === 'company' ? stateOptions[0].value : stateOptions[2].value };
|
const config = { aspectRatio: type === 'company' ? stateOptions[0].value : stateOptions[2].value };
|
||||||
this.dialogRef = this.dialogService.open(ImageCropperComponent, {
|
getImageDimensions(imageUrl).then(dimensions => {
|
||||||
data: {
|
const dialogWidth = getDialogWidth(dimensions);
|
||||||
imageUrl: imageUrl,
|
|
||||||
fileUpload: type === 'company' ? this.companyUpload : this.profileUpload,
|
this.dialogRef = this.dialogService.open(ImageCropperComponent, {
|
||||||
config: config,
|
data: {
|
||||||
ratioVariable: type === 'company' ? true : false,
|
imageUrl: imageUrl,
|
||||||
},
|
fileUpload: type === 'company' ? this.companyUpload : this.profileUpload,
|
||||||
header: 'Edit Image',
|
config: config,
|
||||||
width: '30vw',
|
ratioVariable: type === 'company' ? true : false,
|
||||||
modal: true,
|
},
|
||||||
closeOnEscape: true,
|
header: 'Edit Image',
|
||||||
keepInViewport: true,
|
width: dialogWidth,
|
||||||
closable: false,
|
modal: true,
|
||||||
// breakpoints: {
|
closeOnEscape: true,
|
||||||
// '960px': '75vw',
|
keepInViewport: true,
|
||||||
// '640px': '90vw',
|
closable: false,
|
||||||
// },
|
});
|
||||||
});
|
this.dialogRef.onClose.subscribe(cropper => {
|
||||||
this.dialogRef.onClose.subscribe(cropper => {
|
if (cropper) {
|
||||||
if (cropper) {
|
this.loadingService.startLoading('uploadImage');
|
||||||
this.loadingService.startLoading('uploadImage');
|
cropper.getCroppedCanvas().toBlob(async blob => {
|
||||||
cropper.getCroppedCanvas().toBlob(async blob => {
|
this.imageUploadService.uploadImage(blob, type === 'company' ? 'uploadCompanyLogo' : 'uploadProfile', emailToDirName(this.user.email)).subscribe(
|
||||||
this.imageUploadService.uploadImage(blob, type === 'company' ? 'uploadCompanyLogo' : 'uploadProfile', emailToDirName(this.user.email)).subscribe(
|
async event => {
|
||||||
async event => {
|
if (event.type === HttpEventType.Response) {
|
||||||
if (event.type === HttpEventType.Response) {
|
this.loadingService.stopLoading('uploadImage');
|
||||||
this.loadingService.stopLoading('uploadImage');
|
if (this.type === 'company') {
|
||||||
if (this.type === 'company') {
|
this.user.hasCompanyLogo = true; //
|
||||||
this.user.hasCompanyLogo = true; //
|
this.companyLogoUrl = `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`;
|
||||||
this.companyLogoUrl = `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`;
|
} else {
|
||||||
} else {
|
this.user.hasProfile = true;
|
||||||
this.user.hasProfile = true;
|
this.profileUrl = `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`;
|
||||||
this.profileUrl = `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`;
|
}
|
||||||
|
await this.userService.save(this.user);
|
||||||
}
|
}
|
||||||
await this.userService.save(this.user);
|
},
|
||||||
}
|
error => console.error('Fehler beim Upload:', error),
|
||||||
},
|
);
|
||||||
error => console.error('Fehler beim Upload:', error),
|
});
|
||||||
);
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
deleteConfirm(type: 'profile' | 'logo') {
|
deleteConfirm(type: 'profile' | 'logo') {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||||
import { lastValueFrom } from 'rxjs';
|
import { lastValueFrom } from 'rxjs';
|
||||||
import { ListingsService } from '../../../services/listings.service';
|
import { ListingsService } from '../../../services/listings.service';
|
||||||
import { SelectOptionsService } from '../../../services/select-options.service';
|
import { SelectOptionsService } from '../../../services/select-options.service';
|
||||||
import { createDefaultCommercialPropertyListing, map2User, routeListingWithState } from '../../../utils/utils';
|
import { createDefaultCommercialPropertyListing, getDialogWidth, getImageDimensions, map2User, routeListingWithState } from '../../../utils/utils';
|
||||||
|
|
||||||
import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
|
import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||||
import { HttpEventType } from '@angular/common/http';
|
import { HttpEventType } from '@angular/common/http';
|
||||||
|
|
@ -151,41 +151,44 @@ export class EditCommercialPropertyListingComponent {
|
||||||
|
|
||||||
select(event: any) {
|
select(event: any) {
|
||||||
const imageUrl = URL.createObjectURL(event.files[0]);
|
const imageUrl = URL.createObjectURL(event.files[0]);
|
||||||
this.dialogRef = this.dialogService.open(ImageCropperComponent, {
|
getImageDimensions(imageUrl).then(dimensions => {
|
||||||
data: {
|
const dialogWidth = getDialogWidth(dimensions);
|
||||||
imageUrl: imageUrl,
|
this.dialogRef = this.dialogService.open(ImageCropperComponent, {
|
||||||
fileUpload: this.fileUpload,
|
data: {
|
||||||
ratioVariable: false,
|
imageUrl: imageUrl,
|
||||||
},
|
fileUpload: this.fileUpload,
|
||||||
header: 'Edit Image',
|
ratioVariable: false,
|
||||||
width: '50vw',
|
},
|
||||||
modal: true,
|
header: 'Edit Image',
|
||||||
closeOnEscape: true,
|
width: dialogWidth,
|
||||||
keepInViewport: true,
|
modal: true,
|
||||||
closable: false,
|
closeOnEscape: true,
|
||||||
breakpoints: {
|
keepInViewport: true,
|
||||||
'960px': '75vw',
|
closable: false,
|
||||||
'640px': '90vw',
|
breakpoints: {
|
||||||
},
|
'960px': '75vw',
|
||||||
});
|
'640px': '90vw',
|
||||||
this.dialogRef.onClose.subscribe(cropper => {
|
},
|
||||||
if (cropper) {
|
});
|
||||||
this.loadingService.startLoading('uploadImage');
|
this.dialogRef.onClose.subscribe(cropper => {
|
||||||
cropper.getCroppedCanvas().toBlob(async blob => {
|
if (cropper) {
|
||||||
this.imageService.uploadImage(blob, 'uploadPropertyPicture', this.listing.imagePath, this.listing.serialId).subscribe(
|
this.loadingService.startLoading('uploadImage');
|
||||||
async event => {
|
cropper.getCroppedCanvas().toBlob(async blob => {
|
||||||
if (event.type === HttpEventType.Response) {
|
this.imageService.uploadImage(blob, 'uploadPropertyPicture', this.listing.imagePath, this.listing.serialId).subscribe(
|
||||||
this.ts = new Date().getTime();
|
async event => {
|
||||||
console.log('Upload abgeschlossen', event.body);
|
if (event.type === HttpEventType.Response) {
|
||||||
this.loadingService.stopLoading('uploadImage');
|
this.ts = new Date().getTime();
|
||||||
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty'));
|
console.log('Upload abgeschlossen', event.body);
|
||||||
}
|
this.loadingService.stopLoading('uploadImage');
|
||||||
},
|
this.listing = await lastValueFrom(this.listingsService.getListingById(this.id, 'commercialProperty'));
|
||||||
error => console.error('Fehler beim Upload:', error),
|
}
|
||||||
);
|
},
|
||||||
}, 'image/jpg');
|
error => console.error('Fehler beim Upload:', error),
|
||||||
cropper.destroy();
|
);
|
||||||
}
|
}, 'image/jpg');
|
||||||
|
cropper.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,14 @@ export function createLogger(name: string, level: number = INFO, options: any =
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
export function formatPhoneNumber(phone: string): string {
|
||||||
|
const cleaned = ('' + phone).replace(/\D/g, '');
|
||||||
|
const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
|
||||||
|
if (match) {
|
||||||
|
return '(' + match[1] + ') ' + match[2] + '-' + match[3];
|
||||||
|
}
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
export const getSessionStorageHandler = function (path, value, previous, applyData) {
|
export const getSessionStorageHandler = function (path, value, previous, applyData) {
|
||||||
sessionStorage.setItem('criteria', JSON.stringify(this));
|
sessionStorage.setItem('criteria', JSON.stringify(this));
|
||||||
};
|
};
|
||||||
|
|
@ -130,3 +137,25 @@ export function map2User(jwt: string): KeycloakUser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export function getImageDimensions(imageUrl: string): Promise<{ width: number; height: number }> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
resolve({ width: img.width, height: img.height });
|
||||||
|
};
|
||||||
|
img.src = imageUrl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDialogWidth(dimensions): string {
|
||||||
|
const aspectRatio = dimensions.width / dimensions.height;
|
||||||
|
let dialogWidth = '50vw'; // Standardbreite
|
||||||
|
|
||||||
|
// Passen Sie die Breite basierend auf dem Seitenverhältnis an
|
||||||
|
if (aspectRatio < 1) {
|
||||||
|
dialogWidth = '30vw'; // Hochformat
|
||||||
|
} else if (aspectRatio > 1) {
|
||||||
|
dialogWidth = '50vw'; // Querformat
|
||||||
|
}
|
||||||
|
return dialogWidth;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue