diff --git a/bizmatch/src/app/components/footer/footer.component.html b/bizmatch/src/app/components/footer/footer.component.html index ac0fe58..61d7fae 100644 --- a/bizmatch/src/app/components/footer/footer.component.html +++ b/bizmatch/src/app/components/footer/footer.component.html @@ -18,6 +18,7 @@
Actions
Login + Register Account Log Out
diff --git a/bizmatch/src/app/components/footer/footer.component.ts b/bizmatch/src/app/components/footer/footer.component.ts index 705d8d5..0beebcb 100644 --- a/bizmatch/src/app/components/footer/footer.component.ts +++ b/bizmatch/src/app/components/footer/footer.component.ts @@ -18,4 +18,7 @@ export class FooterComponent { redirectUri: window.location.href, }); } + register() { + this.keycloakService.register({ redirectUri: `${window.location.origin}/account` }); + } } diff --git a/bizmatch/src/app/components/header/header.component.ts b/bizmatch/src/app/components/header/header.component.ts index c216e1f..c6bf306 100644 --- a/bizmatch/src/app/components/header/header.component.ts +++ b/bizmatch/src/app/components/header/header.component.ts @@ -91,14 +91,17 @@ export class HeaderComponent { { label: 'Businesses for Sale', routerLink: '/businessListings', + state: {}, }, { label: 'Commercial Property', routerLink: '/commercialPropertyListings', + state: {}, }, { label: 'Professionals/Brokers Directory', routerLink: '/brokerListings', + state: {}, }, ]; this.loginItems = [ diff --git a/bizmatch/src/app/components/image-cropper/image-cropper.component.html b/bizmatch/src/app/components/image-cropper/image-cropper.component.html index 1585625..3371953 100644 --- a/bizmatch/src/app/components/image-cropper/image-cropper.component.html +++ b/bizmatch/src/app/components/image-cropper/image-cropper.component.html @@ -1,15 +1,14 @@
- @if(ratioVariable){ -
- -
- } @else { -
- } -
- - -
-
\ No newline at end of file + @if(ratioVariable){ +
+ +
+ } @else { +
+ } +
+ + +
+ diff --git a/bizmatch/src/app/components/image-cropper/image-cropper.component.scss b/bizmatch/src/app/components/image-cropper/image-cropper.component.scss index e69de29..6363bda 100644 --- a/bizmatch/src/app/components/image-cropper/image-cropper.component.scss +++ b/bizmatch/src/app/components/image-cropper/image-cropper.component.scss @@ -0,0 +1,4 @@ +::ng-deep p-selectbutton.small .p-button { + font-size: 0.875rem; + padding: 0.65625rem 1.09375rem; +} diff --git a/bizmatch/src/app/components/image-cropper/image-cropper.component.ts b/bizmatch/src/app/components/image-cropper/image-cropper.component.ts index cf517d2..e30c17c 100644 --- a/bizmatch/src/app/components/image-cropper/image-cropper.component.ts +++ b/bizmatch/src/app/components/image-cropper/image-cropper.component.ts @@ -1,67 +1,52 @@ import { Component, ViewChild } from '@angular/core'; 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 { 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 { KeyValueRatio } from '../../../../../bizmatch-server/src/models/main.model'; -export const stateOptions:KeyValueRatio[]=[ - {label:'16/9',value:16/9}, - {label:'1/1',value:1}, - {label:'2/3',value:2/3}, -] +import { ImageService } from '../../services/image.service'; +import { LoadingService } from '../../services/loading.service'; +import { SharedModule } from '../../shared/shared/shared.module'; +export const stateOptions: KeyValueRatio[] = [ + { label: '16/9', value: 16 / 9 }, + { label: '1/1', value: 1 }, + { label: 'Free', value: NaN }, +]; @Component({ selector: 'app-image-cropper', standalone: true, - imports: [SharedModule,FileUploadModule,AngularCropperjsModule,SelectButtonModule], + imports: [SharedModule, FileUploadModule, AngularCropperjsModule, SelectButtonModule], templateUrl: './image-cropper.component.html', - styleUrl: './image-cropper.component.scss' + styleUrl: './image-cropper.component.scss', }) export class ImageCropperComponent { @ViewChild(CropperComponent) public angularCropper: CropperComponent; - imageUrl:string; //wird im Template verwendet - fileUpload:FileUpload - value:number = stateOptions[0].value; - cropperConfig={aspectRatio: this.value} - ratioVariable:boolean - stateOptions=stateOptions - constructor( - private loadingService:LoadingService, - private imageUploadService: ImageService, - public config: DynamicDialogConfig, - public ref: DynamicDialogRef - ){} + imageUrl: string; //wird im Template verwendet + fileUpload: FileUpload; + value: number = stateOptions[0].value; + cropperConfig = { aspectRatio: this.value }; + ratioVariable: boolean; + stateOptions = stateOptions; + constructor(private loadingService: LoadingService, private imageUploadService: ImageService, public config: DynamicDialogConfig, public ref: DynamicDialogRef) {} ngOnInit(): void { if (this.config.data) { - this.imageUrl = this.config.data.imageUrl; - this.fileUpload = this.config.data.fileUpload; - this.cropperConfig = this.config.data.config ? this.config.data.config: this.cropperConfig; - this.ratioVariable = this.config.data.ratioVariable; + this.imageUrl = this.config.data.imageUrl; + this.fileUpload = this.config.data.fileUpload; + this.cropperConfig = this.config.data.config ? this.config.data.config : this.cropperConfig; + this.ratioVariable = this.config.data.ratioVariable; } } - sendImage(){ - // setTimeout(()=>{ - // this.angularCropper.cropper.getCroppedCanvas().toBlob(async(blob) => { - // this.ref.close(blob); - // this.fileUpload.clear() - // }, 'image/jpg'); - // },0) - - this.fileUpload.clear() + sendImage() { + this.fileUpload.clear(); this.ref.close(this.angularCropper.cropper); - } + } - cancelUpload(){ + cancelUpload() { this.fileUpload.clear(); this.ref.close(); } - changeAspectRation(ratio:number){ - this.cropperConfig={aspectRatio: ratio} + changeAspectRation(ratio: number) { + this.cropperConfig = { aspectRatio: ratio }; this.angularCropper.cropper.setAspectRatio(ratio); } } diff --git a/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.html b/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.html index 73934ed..7324ef1 100644 --- a/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.html +++ b/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.html @@ -14,50 +14,62 @@
@if(listing && listingUser && (listingUser?.email===user?.email || isAdmin())){ @@ -79,7 +91,8 @@
- + +
@@ -92,9 +105,9 @@
@if(listingUser){
- Listing by  {{ listingUser.firstname }} {{ listingUser.lastname }} + Listing by  {{ listingUser.firstname }} {{ listingUser.lastname }} @if(listingUser.hasCompanyLogo){ - + }
} diff --git a/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts b/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts index b0c2336..7b62618 100644 --- a/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts +++ b/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts @@ -5,6 +5,7 @@ import { KeycloakService } from 'keycloak-angular'; import onChange from 'on-change'; import { MessageService } from 'primeng/api'; import { GalleriaModule } from 'primeng/galleria'; +import { InputMaskModule } from 'primeng/inputmask'; import { lastValueFrom } from 'rxjs'; import { BusinessListing, User } from '../../../../../../bizmatch-server/src/models/db.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 { SharedModule } from '../../../shared/shared/shared.module'; import { getCriteriaStateObject, getSessionStorageHandler, map2User } from '../../../utils/utils'; - @Component({ selector: 'app-details-business-listing', standalone: true, - imports: [SharedModule, GalleriaModule], + imports: [SharedModule, GalleriaModule, InputMaskModule], providers: [MessageService], templateUrl: './details-business-listing.component.html', styleUrl: './details-business-listing.component.scss', @@ -82,7 +82,7 @@ export class DetailsBusinessListingComponent { this.keycloakUser = map2User(token); if (this.keycloakUser) { 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.listingUser = await this.userService.getById(this.listing.userId); diff --git a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html index c4fcb8b..e3f0764 100644 --- a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html +++ b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.html @@ -14,32 +14,32 @@
@@ -69,7 +69,8 @@
- + +
@@ -82,9 +83,9 @@
@if(listingUser){
- Listing by  {{ listingUser.firstname }} {{ listingUser.lastname }} + Listing by  {{ listingUser.firstname }} {{ listingUser.lastname }} @if(listingUser.hasCompanyLogo){ - + }
} diff --git a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts index 175c909..13bd740 100644 --- a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts +++ b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts @@ -5,6 +5,7 @@ import { KeycloakService } from 'keycloak-angular'; import onChange from 'on-change'; import { MessageService } from 'primeng/api'; import { GalleriaModule } from 'primeng/galleria'; +import { InputMaskModule } from 'primeng/inputmask'; import { lastValueFrom } from 'rxjs'; import { CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model'; import { ErrorResponse, KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model'; @@ -21,7 +22,7 @@ import { getCriteriaStateObject, getSessionStorageHandler, map2User } from '../. @Component({ selector: 'app-details-commercial-property-listing', standalone: true, - imports: [SharedModule, GalleriaModule], + imports: [SharedModule, GalleriaModule, InputMaskModule], providers: [MessageService], templateUrl: './details-commercial-property-listing.component.html', styleUrl: './details-commercial-property-listing.component.scss', @@ -79,7 +80,7 @@ export class DetailsCommercialPropertyListingComponent { this.keycloakUser = map2User(token); if (this.keycloakUser) { 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.listingUser = await this.userService.getById(this.listing.userId); diff --git a/bizmatch/src/app/pages/details/details-user/details-user.component.html b/bizmatch/src/app/pages/details/details-user/details-user.component.html index 23e5628..4b51810 100644 --- a/bizmatch/src/app/pages/details/details-user/details-user.component.html +++ b/bizmatch/src/app/pages/details/details-user/details-user.component.html @@ -30,7 +30,7 @@
@if(user.hasCompanyLogo){ - + } @@ -57,7 +57,7 @@
  • Phone Number
    -
    {{ user.phoneNumber }}
    +
    {{ formatPhoneNumber(user.phoneNumber) }}
  • EMail Address
    diff --git a/bizmatch/src/app/pages/details/details-user/details-user.component.ts b/bizmatch/src/app/pages/details/details-user/details-user.component.ts index 6d9a0e1..c3bebfb 100644 --- a/bizmatch/src/app/pages/details/details-user/details-user.component.ts +++ b/bizmatch/src/app/pages/details/details-user/details-user.component.ts @@ -14,7 +14,7 @@ import { ListingsService } from '../../../services/listings.service'; import { SelectOptionsService } from '../../../services/select-options.service'; import { UserService } from '../../../services/user.service'; import { SharedModule } from '../../../shared/shared/shared.module'; -import { map2User } from '../../../utils/utils'; +import { formatPhoneNumber, map2User } from '../../../utils/utils'; @Component({ selector: 'app-details-user', @@ -38,6 +38,7 @@ export class DetailsUserComponent { ts = new Date().getTime(); env = environment; emailToDirName = emailToDirName; + formatPhoneNumber = formatPhoneNumber; constructor( private activatedRoute: ActivatedRoute, private router: Router, diff --git a/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.scss b/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.scss index 57253e1..fab7e02 100644 --- a/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.scss +++ b/bizmatch/src/app/pages/listings/broker-listings/broker-listings.component.scss @@ -1,23 +1,23 @@ #sky-line { - background-image: url(../../../../assets/images/bw-sky.jpg); - height: 204px; - background-position: bottom; - background-size: cover; - margin-bottom: -1px; + background-image: url(../../../../assets/images/bw-sky.jpg); + height: 204px; + background-position: bottom; + background-size: cover; + margin-bottom: -1px; } -.search{ - background-color: #343F69; +.search { + background-color: #343f69; } ::ng-deep p-paginator div { - background-color: var(--surface-200) !important; - // background-color: var(--surface-400) !important; + background-color: var(--surface-200) !important; + // background-color: var(--surface-400) !important; } .rounded-image { - border-radius: 6px; - // width: 100px; - max-width: 100px; - height: 45px; - border: 1px solid rgba(0,0,0,0.2); - padding: 1px 1px; - object-fit: contain; -} \ No newline at end of file + border-radius: 6px; + // width: 100px; + max-width: 100px; + max-height: 45px; + border: 1px solid rgba(0, 0, 0, 0.2); + padding: 1px 1px; + object-fit: contain; +} diff --git a/bizmatch/src/app/pages/subscription/account/account.component.html b/bizmatch/src/app/pages/subscription/account/account.component.html index 3f3ccf6..9ebecba 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.html +++ b/bizmatch/src/app/pages/subscription/account/account.component.html @@ -36,7 +36,7 @@
    - +
    diff --git a/bizmatch/src/app/pages/subscription/account/account.component.scss b/bizmatch/src/app/pages/subscription/account/account.component.scss index e7f8f3d..05e3422 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.scss +++ b/bizmatch/src/app/pages/subscription/account/account.component.scss @@ -25,8 +25,8 @@ /* Stil für das FontAwesome Icon */ .image-wrap fa-icon { position: absolute; - top: 5px; /* Positioniert das Icon am oberen Rand des Bildes */ - right: 5px; /* Positioniert das Icon am rechten Rand des Bildes */ + top: -5px; /* Positioniert das Icon am oberen Rand des Bildes */ + right: -18px; /* Positioniert das Icon am rechten Rand des Bildes */ color: #fff; /* Weiße Farbe für das Icon */ background-color: rgba(0, 0, 0, 0.5); /* Halbtransparenter Hintergrund für bessere Sichtbarkeit */ padding: 5px; /* Ein wenig Platz um das Icon */ diff --git a/bizmatch/src/app/pages/subscription/account/account.component.ts b/bizmatch/src/app/pages/subscription/account/account.component.ts index 67a3f91..4d6559f 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.ts +++ b/bizmatch/src/app/pages/subscription/account/account.component.ts @@ -10,6 +10,7 @@ import { DialogModule } from 'primeng/dialog'; import { DialogService, DynamicDialogModule, DynamicDialogRef } from 'primeng/dynamicdialog'; import { EditorModule } from 'primeng/editor'; import { FileUpload, FileUploadModule } from 'primeng/fileupload'; +import { InputMaskModule } from 'primeng/inputmask'; import { SelectButtonModule } from 'primeng/selectbutton'; import { lastValueFrom } from 'rxjs'; 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 { UserService } from '../../../services/user.service'; 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'; @Component({ selector: 'app-account', 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], templateUrl: './account.component.html', styleUrl: './account.component.scss', @@ -124,46 +125,46 @@ export class AccountComponent { const imageUrl = URL.createObjectURL(event.files[0]); this.type = type; const config = { aspectRatio: type === 'company' ? stateOptions[0].value : stateOptions[2].value }; - this.dialogRef = this.dialogService.open(ImageCropperComponent, { - data: { - imageUrl: imageUrl, - fileUpload: type === 'company' ? this.companyUpload : this.profileUpload, - config: config, - ratioVariable: type === 'company' ? true : false, - }, - header: 'Edit Image', - width: '30vw', - modal: true, - closeOnEscape: true, - keepInViewport: true, - closable: false, - // breakpoints: { - // '960px': '75vw', - // '640px': '90vw', - // }, - }); - this.dialogRef.onClose.subscribe(cropper => { - if (cropper) { - this.loadingService.startLoading('uploadImage'); - cropper.getCroppedCanvas().toBlob(async blob => { - this.imageUploadService.uploadImage(blob, type === 'company' ? 'uploadCompanyLogo' : 'uploadProfile', emailToDirName(this.user.email)).subscribe( - async event => { - if (event.type === HttpEventType.Response) { - this.loadingService.stopLoading('uploadImage'); - if (this.type === 'company') { - this.user.hasCompanyLogo = true; // - this.companyLogoUrl = `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`; - } else { - this.user.hasProfile = true; - this.profileUrl = `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`; + getImageDimensions(imageUrl).then(dimensions => { + const dialogWidth = getDialogWidth(dimensions); + + this.dialogRef = this.dialogService.open(ImageCropperComponent, { + data: { + imageUrl: imageUrl, + fileUpload: type === 'company' ? this.companyUpload : this.profileUpload, + config: config, + ratioVariable: type === 'company' ? true : false, + }, + header: 'Edit Image', + width: dialogWidth, + modal: true, + closeOnEscape: true, + keepInViewport: true, + closable: false, + }); + this.dialogRef.onClose.subscribe(cropper => { + if (cropper) { + this.loadingService.startLoading('uploadImage'); + cropper.getCroppedCanvas().toBlob(async blob => { + this.imageUploadService.uploadImage(blob, type === 'company' ? 'uploadCompanyLogo' : 'uploadProfile', emailToDirName(this.user.email)).subscribe( + async event => { + if (event.type === HttpEventType.Response) { + this.loadingService.stopLoading('uploadImage'); + if (this.type === 'company') { + this.user.hasCompanyLogo = true; // + this.companyLogoUrl = `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}`; + } else { + this.user.hasProfile = true; + 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') { diff --git a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts index 5b66b9d..424fa8b 100644 --- a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts +++ b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { lastValueFrom } from 'rxjs'; import { ListingsService } from '../../../services/listings.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 { HttpEventType } from '@angular/common/http'; @@ -151,41 +151,44 @@ export class EditCommercialPropertyListingComponent { select(event: any) { const imageUrl = URL.createObjectURL(event.files[0]); - this.dialogRef = this.dialogService.open(ImageCropperComponent, { - data: { - imageUrl: imageUrl, - fileUpload: this.fileUpload, - ratioVariable: false, - }, - header: 'Edit Image', - width: '50vw', - modal: true, - closeOnEscape: true, - keepInViewport: true, - closable: false, - breakpoints: { - '960px': '75vw', - '640px': '90vw', - }, - }); - this.dialogRef.onClose.subscribe(cropper => { - if (cropper) { - this.loadingService.startLoading('uploadImage'); - cropper.getCroppedCanvas().toBlob(async blob => { - this.imageService.uploadImage(blob, 'uploadPropertyPicture', this.listing.imagePath, this.listing.serialId).subscribe( - async event => { - if (event.type === HttpEventType.Response) { - this.ts = new Date().getTime(); - 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'); - cropper.destroy(); - } + getImageDimensions(imageUrl).then(dimensions => { + const dialogWidth = getDialogWidth(dimensions); + this.dialogRef = this.dialogService.open(ImageCropperComponent, { + data: { + imageUrl: imageUrl, + fileUpload: this.fileUpload, + ratioVariable: false, + }, + header: 'Edit Image', + width: dialogWidth, + modal: true, + closeOnEscape: true, + keepInViewport: true, + closable: false, + breakpoints: { + '960px': '75vw', + '640px': '90vw', + }, + }); + this.dialogRef.onClose.subscribe(cropper => { + if (cropper) { + this.loadingService.startLoading('uploadImage'); + cropper.getCroppedCanvas().toBlob(async blob => { + this.imageService.uploadImage(blob, 'uploadPropertyPicture', this.listing.imagePath, this.listing.serialId).subscribe( + async event => { + if (event.type === HttpEventType.Response) { + this.ts = new Date().getTime(); + 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'); + cropper.destroy(); + } + }); }); } diff --git a/bizmatch/src/app/utils/utils.ts b/bizmatch/src/app/utils/utils.ts index 7ac9e4d..bebf392 100644 --- a/bizmatch/src/app/utils/utils.ts +++ b/bizmatch/src/app/utils/utils.ts @@ -87,7 +87,14 @@ export function createLogger(name: string, level: number = INFO, options: any = ...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) { sessionStorage.setItem('criteria', JSON.stringify(this)); }; @@ -130,3 +137,25 @@ export function map2User(jwt: string): KeycloakUser { 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; +}