From 840d7a63b109ff1c77fccea5c0626844447a4526 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Mon, 25 Mar 2024 20:17:49 +0100 Subject: [PATCH] broker direcrtory renewed, imageservice updated, demo data --- bizmatch-server/src/file/file.service.ts | 49 ++++-- bizmatch-server/src/image/image.controller.ts | 17 +- bizmatch-server/src/user/user.controller.ts | 40 +++-- bizmatch-server/src/user/user.service.ts | 2 +- bizmatch/angular.json | 3 +- bizmatch/package.json | 1 + bizmatch/src/app/app.routes.ts | 2 +- .../components/footer/footer.component.html | 3 +- .../app/components/header/header.component.ts | 110 ++++++------ .../details-user/details-user.component.html | 35 ++-- .../details-user/details-user.component.scss | 3 + .../details-user/details-user.component.ts | 11 +- .../src/app/pages/home/home.component.html | 28 +-- bizmatch/src/app/pages/home/home.component.ts | 15 +- .../pages/listings/listings.component.html | 16 +- .../pages/listings/listings.component.scss | 5 +- .../app/pages/listings/listings.component.ts | 10 +- .../account/account.component.html | 159 +++++++++++++----- .../subscription/account/account.component.ts | 106 ++++++++++-- .../edit-listing/edit-listing.component.ts | 2 +- bizmatch/src/app/services/image.service.ts | 27 ++- bizmatch/src/app/services/loading.service.ts | 2 +- .../src/assets/images/person_placeholder.jpg | Bin 0 -> 71263 bytes .../person_placeholder.jpg:Zone.Identifier | 3 + common-models/src/main.model.ts | 4 + crawler/{import.ts => importListing.ts} | 0 crawler/importUser.ts | 13 ++ crawler/index.ts | 2 +- crawler/updateFields.ts | 4 +- crawler/users.json | 156 +++++++++++++++++ 30 files changed, 616 insertions(+), 212 deletions(-) create mode 100644 bizmatch/src/assets/images/person_placeholder.jpg create mode 100644 bizmatch/src/assets/images/person_placeholder.jpg:Zone.Identifier rename crawler/{import.ts => importListing.ts} (100%) create mode 100644 crawler/importUser.ts create mode 100644 crawler/users.json diff --git a/bizmatch-server/src/file/file.service.ts b/bizmatch-server/src/file/file.service.ts index 609e7f8..4d18558 100644 --- a/bizmatch-server/src/file/file.service.ts +++ b/bizmatch-server/src/file/file.service.ts @@ -30,19 +30,33 @@ export class FileService { return this.subscriptions } async storeProfilePicture(file: Express.Multer.File, userId: string) { - const suffix = file.mimetype.includes('png') ? 'png' : 'jpg' - await fs.outputFile(`./pictures/profile/${userId}`, file.buffer); + // const suffix = file.mimetype.includes('png') ? 'png' : 'jpg' + // await fs.outputFile(`./pictures/profile/${userId}`, file.buffer); + let quality = 50; + const output = await sharp(file.buffer) + .resize({ width: 300 }) + .avif({ quality }) // Verwende AVIF + //.webp({ quality }) // Verwende Webp + .toBuffer(); + await sharp(output).toFile(`./pictures/profile/${userId}.avif`); } hasProfile(userId: string){ - return fs.existsSync(`./pictures/profile/${userId}`) + return fs.existsSync(`./pictures/profile/${userId}.avif`) } async storeCompanyLogo(file: Express.Multer.File, userId: string) { - const suffix = file.mimetype.includes('png') ? 'png' : 'jpg' - await fs.outputFile(`./pictures/logo/${userId}`, file.buffer); + // const suffix = file.mimetype.includes('png') ? 'png' : 'jpg' + let quality = 50; + const output = await sharp(file.buffer) + .resize({ width: 300 }) + .avif({ quality }) // Verwende AVIF + //.webp({ quality }) // Verwende Webp + .toBuffer(); + await sharp(output).toFile(`./pictures/logo/${userId}.avif`); // Ersetze Dateierweiterung + // await fs.outputFile(`./pictures/logo/${userId}`, file.buffer); } hasCompanyLogo(userId: string){ - return fs.existsSync(`./pictures/logo/${userId}`) + return fs.existsSync(`./pictures/logo/${userId}.avif`) } async getPropertyImages(listingId: string): Promise { @@ -103,13 +117,28 @@ export class FileService { //.webp({ quality }) // Verwende Webp .toBuffer(); - if (output.byteLength > maxSize) { - quality -= 5; // Justiere Qualität in feineren Schritten - } + // if (output.byteLength > maxSize) { + // quality -= 5; // Justiere Qualität in feineren Schritten + // } // } while (output.byteLength > maxSize && quality > 0); await sharp(output).toFile(`${directory}/${imageName}.avif`); // Ersetze Dateierweiterung let timeTaken = Date.now() - start; this.logger.info(`Quality: ${quality} - Time: ${timeTaken} milliseconds`) } - + getProfileImagesForUsers(userids:string){ + const ids = userids.split(','); + let result = {}; + for (const id of ids){ + result = {...result,[id]:fs.existsSync(`./pictures/profile/${id}.avif`)} + } + return result; + } + getCompanyLogosForUsers(userids:string){ + const ids = userids.split(','); + let result = {}; + for (const id of ids){ + result = {...result,[id]:fs.existsSync(`./pictures/logo/${id}.avif`)} + } + return result; + } } diff --git a/bizmatch-server/src/image/image.controller.ts b/bizmatch-server/src/image/image.controller.ts index 4cfeba1..55bb6cb 100644 --- a/bizmatch-server/src/image/image.controller.ts +++ b/bizmatch-server/src/image/image.controller.ts @@ -23,13 +23,22 @@ export class ImageController { @Post('uploadProfile/:id') @UseInterceptors(FileInterceptor('file'),) - uploadProfile(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) { - this.fileService.storeProfilePicture(file,id); + async uploadProfile(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) { + await this.fileService.storeProfilePicture(file,id); } @Post('uploadCompanyLogo/:id') @UseInterceptors(FileInterceptor('file'),) - uploadCompanyLogo(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) { - this.fileService.storeCompanyLogo(file,id); + async uploadCompanyLogo(@UploadedFile() file: Express.Multer.File,@Param('id') id:string) { + await this.fileService.storeCompanyLogo(file,id); + } + + @Get('profileImages/:userids') + async getProfileImagesForUsers(@Param('userids') userids:string): Promise { + return await this.fileService.getProfileImagesForUsers(userids); + } + @Get('companyLogos/:userids') + async getCompanyLogosForUsers(@Param('userids') userids:string): Promise { + return await this.fileService.getCompanyLogosForUsers(userids); } } diff --git a/bizmatch-server/src/user/user.controller.ts b/bizmatch-server/src/user/user.controller.ts index 46c8d58..d67c6bc 100644 --- a/bizmatch-server/src/user/user.controller.ts +++ b/bizmatch-server/src/user/user.controller.ts @@ -7,22 +7,30 @@ import { UserEntity } from 'src/models/server.model.js'; @Controller('user') export class UserController { - constructor(private userService:UserService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger){} - - @Get(':id') - findById(@Param('id') id:string): any { - return this.userService.getUserById(id); - } + constructor(private userService: UserService, @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {} - @Post() - save(@Body() user: any):Promise{ - this.logger.info(`User persisted: `); - return this.userService.saveUser(user); - } - - @Post('search') - find(@Body() criteria: any): any { - return this.userService.findUser(criteria); - } + @Get(':id') + findById(@Param('id') id: string): any { + this.logger.info(`Searching for user with ID: ${id}`); + const user = this.userService.getUserById(id); + this.logger.info(`Found user: ${JSON.stringify(user)}`); + return user; + } + + @Post() + save(@Body() user: any): Promise { + this.logger.info(`Saving user: ${JSON.stringify(user)}`); + const savedUser = this.userService.saveUser(user); + this.logger.info(`User persisted: ${JSON.stringify(savedUser)}`); + return savedUser; + } + + @Post('search') + find(@Body() criteria: any): any { + this.logger.info(`Searching for users with criteria: ${JSON.stringify(criteria)}`); + const foundUsers = this.userService.findUser(criteria); + this.logger.info(`Found users: ${JSON.stringify(foundUsers)}`); + return foundUsers; + } } diff --git a/bizmatch-server/src/user/user.service.ts b/bizmatch-server/src/user/user.service.ts index 7d7cf30..2cda06f 100644 --- a/bizmatch-server/src/user/user.service.ts +++ b/bizmatch-server/src/user/user.service.ts @@ -19,7 +19,7 @@ export class UserService { companyWebsite:{ type: 'string' }, companyLocation:{ type: 'string' }, offeredServices:{ type: 'string' }, - areasServed:{ type: 'string' }, + areasServed:{ type: 'string[]' }, names:{ type: 'string[]', path:'$.licensedIn.name' }, values:{ type: 'string[]', path:'$.licensedIn.value' } }, { diff --git a/bizmatch/angular.json b/bizmatch/angular.json index 908d580..dd766d1 100644 --- a/bizmatch/angular.json +++ b/bizmatch/angular.json @@ -31,7 +31,8 @@ "src/assets" ], "styles": [ - "src/styles.scss" + "src/styles.scss", + "node_modules/quill/dist/quill.snow.css" ] }, "configurations": { diff --git a/bizmatch/package.json b/bizmatch/package.json index 625da45..0977085 100644 --- a/bizmatch/package.json +++ b/bizmatch/package.json @@ -39,6 +39,7 @@ "primeflex": "^3.3.1", "primeicons": "^6.0.1", "primeng": "^17.10.0", + "quill": "^1.3.7", "rxjs": "~7.8.1", "tslib": "^2.3.0", "urlcat": "^3.1.0", diff --git a/bizmatch/src/app/app.routes.ts b/bizmatch/src/app/app.routes.ts index a538ba5..2134fec 100644 --- a/bizmatch/src/app/app.routes.ts +++ b/bizmatch/src/app/app.routes.ts @@ -42,7 +42,7 @@ export const routes: Routes = [ component: DetailsUserComponent, }, { - path: 'account', + path: 'account/:id', component: AccountComponent, canActivate: [authGuard], }, diff --git a/bizmatch/src/app/components/footer/footer.component.html b/bizmatch/src/app/components/footer/footer.component.html index fce6111..5c7b0ce 100644 --- a/bizmatch/src/app/components/footer/footer.component.html +++ b/bizmatch/src/app/components/footer/footer.component.html @@ -4,7 +4,6 @@
footer sections
© 2024 Bizmatch All rights reserved.
-
BizMatch, Inc., 1001 Blucher Street, Corpus Christi, Texas 78401
@@ -19,7 +18,7 @@
diff --git a/bizmatch/src/app/components/header/header.component.ts b/bizmatch/src/app/components/header/header.component.ts index ef47ee0..f927703 100644 --- a/bizmatch/src/app/components/header/header.component.ts +++ b/bizmatch/src/app/components/header/header.component.ts @@ -21,8 +21,8 @@ import { User } from '../../../../../common-models/src/main.model'; }) export class HeaderComponent { public buildVersion = environment.buildVersion; - user:User; user$:Observable + user:User; public tabItems: MenuItem[]; public menuItems: MenuItem[]; activeItem @@ -33,6 +33,60 @@ export class HeaderComponent { ngOnInit(){ this.user$=this.userService.getUserObservable(); + this.user$.subscribe(u=>{ + this.user=u; + this.menuItems = [ + { + label: 'User Actions', + icon: 'fas fa-cog', + items: [ + { + label: 'Account', + icon: 'pi pi-user', + routerLink: `/account/${this.user.id}`, + visible: this.isUserLogedIn() + }, + { + label: 'Create Listing', + icon: 'pi pi-plus-circle', + routerLink: "/createListing", + visible: this.isUserLogedIn() + }, + { + label: 'My Listings', + icon: 'pi pi-list', + routerLink:"/myListings", + visible: this.isUserLogedIn() + }, + { + label: 'My Favorites', + icon: 'pi pi-star', + routerLink:"/myFavorites", + visible: this.isUserLogedIn() + }, + { + label: 'EMail Us', + icon: 'fa-regular fa-envelope', + routerLink:"/emailUs", + visible: this.isUserLogedIn() + }, + { + label: 'Logout', + icon: 'fa-solid fa-right-from-bracket', + routerLink:"/logout", + visible: this.isUserLogedIn() + }, + { + label: 'Login', + icon: 'fa-solid fa-right-from-bracket', + //routerLink:"/account", + command: () => this.login(), + visible: !this.isUserLogedIn() + }, + ] + } + ] + }); this.tabItems = [ { label: 'Businesses for Sale', @@ -50,63 +104,13 @@ export class HeaderComponent { fragment:'' } ]; - this.menuItems = [ - { - label: 'User Actions', - icon: 'fas fa-cog', - items: [ - { - label: 'Account', - icon: 'pi pi-user', - routerLink: '/account', - visible: this.isUserLoogedIn() - }, - { - label: 'Create Listing', - icon: 'pi pi-plus-circle', - routerLink: "/createListing", - visible: this.isUserLoogedIn() - }, - { - label: 'My Listings', - icon: 'pi pi-list', - routerLink:"/myListings", - visible: this.isUserLoogedIn() - }, - { - label: 'My Favorites', - icon: 'pi pi-star', - routerLink:"/myFavorites", - visible: this.isUserLoogedIn() - }, - { - label: 'EMail Us', - icon: 'fa-regular fa-envelope', - routerLink:"/emailUs", - visible: this.isUserLoogedIn() - }, - { - label: 'Logout', - icon: 'fa-solid fa-right-from-bracket', - routerLink:"/logout", - visible: this.isUserLoogedIn() - }, - { - label: 'Login', - icon: 'fa-solid fa-right-from-bracket', - //routerLink:"/account", - command: () => this.login(), - visible: !this.isUserLoogedIn() - }, - ] - } - ] + this.activeItem=this.tabItems[0]; } navigateWithState(dest: string, state: any) { this.router.navigate([dest], { state: state }); } - isUserLoogedIn(){ + isUserLogedIn(){ return this.userService?.isLoggedIn(); } login(){ 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 769abfc..5a1d4bd 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 @@ -8,8 +8,12 @@
- + @if(user.hasProfile){ + + } @else { + + }
{{user.firstname}} {{user.lastname}} @@ -28,8 +32,14 @@
-
+
+ @if(user.hasCompanyLogo){ + + } + +
@@ -37,18 +47,13 @@
-

{{user.description}}

Company Profile
-
{{user.companyOverview}}
+
  • Name
    @@ -67,14 +72,10 @@
    {{user.companyLocation}}
  • -
    Company Overview
    -
    {{user.companyOverview}}
    +
    Services we offer
    +
  • -
    Services we offer
    -
    {{user.offeredServices}}
    -
  • -
  • Areas we serve
    @for (area of user.areasServed; track area) { @@ -123,7 +124,7 @@
    @if( user?.id===(user$| async)?.id || isAdmin()){ + [routerLink]="['/account',user.id]"> }
diff --git a/bizmatch/src/app/pages/details/details-user/details-user.component.scss b/bizmatch/src/app/pages/details/details-user/details-user.component.scss index e69de29..2980734 100644 --- a/bizmatch/src/app/pages/details/details-user/details-user.component.scss +++ b/bizmatch/src/app/pages/details/details-user/details-user.component.scss @@ -0,0 +1,3 @@ +:host ::ng-deep p { + margin:3px 0; +} \ No newline at end of file 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 741cf2a..7e5d194 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 @@ -9,6 +9,8 @@ import { UserService } from '../../../services/user.service'; import { Observable } from 'rxjs'; import { ListingsService } from '../../../services/listings.service'; import { SelectOptionsService } from '../../../services/select-options.service'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; +import { ImageService } from '../../../services/image.service'; @Component({ selector: 'app-details-user', @@ -25,18 +27,25 @@ export class DetailsUserComponent { environment = environment; criteria:ListingCriteria; userListings:BusinessListing[] + companyOverview:SafeHtml; + offeredServices:SafeHtml; constructor(private activatedRoute: ActivatedRoute, private router: Router, private userService: UserService, private listingsService:ListingsService, private messageService: MessageService, - public selectOptions: SelectOptionsService) { + public selectOptions: SelectOptionsService, + private sanitizer: DomSanitizer, + private imageService:ImageService) { } async ngOnInit() { this.user = await this.userService.getById(this.id); + this.userListings = await this.listingsService.getListingByUserId(this.id); this.user$ = this.userService.getUserObservable(); + this.companyOverview=this.sanitizer.bypassSecurityTrustHtml(this.user.companyOverview); + this.offeredServices=this.sanitizer.bypassSecurityTrustHtml(this.user.offeredServices); } back() { this.router.navigate(['listings', this.criteria.listingsCategory]) diff --git a/bizmatch/src/app/pages/home/home.component.html b/bizmatch/src/app/pages/home/home.component.html index af00958..9a120e7 100644 --- a/bizmatch/src/app/pages/home/home.component.html +++ b/bizmatch/src/app/pages/home/home.component.html @@ -5,31 +5,13 @@
diff --git a/bizmatch/src/app/pages/home/home.component.ts b/bizmatch/src/app/pages/home/home.component.ts index 2439ac1..e74f759 100644 --- a/bizmatch/src/app/pages/home/home.component.ts +++ b/bizmatch/src/app/pages/home/home.component.ts @@ -12,7 +12,8 @@ import { SelectOptionsService } from '../../services/select-options.service'; import { UserService } from '../../services/user.service'; import onChange from 'on-change'; import { getCriteriaStateObject, getSessionStorageHandler } from '../../utils/utils'; -import { ListingCriteria } from '../../../../../common-models/src/main.model'; +import { ListingCriteria, User } from '../../../../../common-models/src/main.model'; +import { Observable } from 'rxjs'; @Component({ selector: 'app-home', standalone: true, @@ -26,20 +27,20 @@ export class HomeComponent { maxPrice:string; minPrice:string; criteria:ListingCriteria + user$:Observable public constructor(private router: Router,private activatedRoute: ActivatedRoute, public selectOptions:SelectOptionsService, public userService:UserService) { this.criteria = onChange(getCriteriaStateObject(),getSessionStorageHandler); } ngOnInit(){ - + this.user$=this.userService.getUserObservable(); } search(){ this.router.navigate([`listings/${this.activeTabAction}`]) } - account(){ - setTimeout(()=>{ - this.router.navigate([`account`]) - },10); - } + + login(){ + this.userService.login(window.location.href); + } } \ No newline at end of file diff --git a/bizmatch/src/app/pages/listings/listings.component.html b/bizmatch/src/app/pages/listings/listings.component.html index 3813700..9bc1a14 100644 --- a/bizmatch/src/app/pages/listings/listings.component.html +++ b/bizmatch/src/app/pages/listings/listings.component.html @@ -121,11 +121,15 @@ } @for (user of users; track user.id) { -
-
+
+
- + @if(user.hasProfile){ + + } @else { + + }

{{user.description}}

@@ -134,7 +138,11 @@
- + @if(user.hasCompanyLogo){ + + } @else { + + } diff --git a/bizmatch/src/app/pages/listings/listings.component.scss b/bizmatch/src/app/pages/listings/listings.component.scss index 248f146..af0a00b 100644 --- a/bizmatch/src/app/pages/listings/listings.component.scss +++ b/bizmatch/src/app/pages/listings/listings.component.scss @@ -14,8 +14,9 @@ } .rounded-image { border-radius: 6px; - width: 100px; - height: 25px; + // width: 100px; + max-width: 100px; + height: 45px; border: 1px solid rgba(0,0,0,0.2); padding: 1px 1px; object-fit: contain; diff --git a/bizmatch/src/app/pages/listings/listings.component.ts b/bizmatch/src/app/pages/listings/listings.component.ts index 098d2eb..bcb2307 100644 --- a/bizmatch/src/app/pages/listings/listings.component.ts +++ b/bizmatch/src/app/pages/listings/listings.component.ts @@ -18,6 +18,7 @@ import { InitEditableRow } from 'primeng/table'; import { environment } from '../../../environments/environment'; import { ListingCriteria, ListingType, User } from '../../../../../common-models/src/main.model'; import { UserService } from '../../services/user.service'; +import { ImageService } from '../../services/image.service'; @Component({ selector: 'app-listings', standalone: true, @@ -49,7 +50,8 @@ export class ListingsComponent { private userService:UserService, private activatedRoute: ActivatedRoute, private router:Router, - private cdRef:ChangeDetectorRef) { + private cdRef:ChangeDetectorRef, + private imageService:ImageService) { this.criteria = onChange(getCriteriaStateObject(),getSessionStorageHandler); this.router.getCurrentNavigation() this.activatedRoute.snapshot @@ -80,6 +82,12 @@ export class ListingsComponent { this.listings=[] this.filteredListings=[]; this.users=await this.userService.search(this.criteria); + const profiles = await this.imageService.getProfileImagesForUsers(this.users.map(u=>u.id)); + const logos = await this.imageService.getCompanyLogosForUsers(this.users.map(u=>u.id)); + this.users.forEach(u=>{ + u.hasProfile=profiles[u.id] + u.hasCompanyLogo=logos[u.id] + }) this.cdRef.markForCheck(); this.cdRef.detectChanges(); } diff --git a/bizmatch/src/app/pages/subscription/account/account.component.html b/bizmatch/src/app/pages/subscription/account/account.component.html index 2df31a5..cc856a6 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.html +++ b/bizmatch/src/app/pages/subscription/account/account.component.html @@ -1,4 +1,3 @@ -
@@ -16,7 +15,8 @@
-

You can only modify your email by contacting us at emailchange@bizmatch.net

+

You can only modify your email by contacting us at + emailchange@bizmatch.net

@@ -48,60 +48,109 @@
- - + +
- -
+ + + + + + + + + + + +
+
+ + + + + + + + + + + + +
+
- -
-
+ +
+
@for (licensedIn of user.licensedIn; track licensedIn.value){
- +
- +
} -
+
- +  (Add more licenses or remove existing ones.) -
- +
+
- +
Company Logo (is shown in every offer) - - + @if(user.hasCompanyLogo){ + + } @else { + + } +
Your Profile Picture - - + @if(user.hasProfile){ + + } @else { + + } +
Membership Level
- + @@ -116,7 +165,9 @@ - + {{ subscription.id }} {{ subscription.level }} @@ -132,31 +183,51 @@
- - - ID - Date - Price - - - - - - - - {{ invoice.id }} - {{ invoice.date | date}} - {{ invoice.price | currency}} - - - - - -
+ + + ID + Date + Price + +
+ + + + + {{ invoice.id }} + {{ invoice.date | date}} + {{ invoice.price | currency}} + +
+ + + +
- \ No newline at end of file + + + + + + +
+ @if(type==='company'){ +
+ +
+ } @else { +
+ } +
+ + +
+
+
+
\ No newline at end of file diff --git a/bizmatch/src/app/pages/subscription/account/account.component.ts b/bizmatch/src/app/pages/subscription/account/account.component.ts index 8c3eec8..cb87c63 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.ts +++ b/bizmatch/src/app/pages/subscription/account/account.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component } from '@angular/core'; +import { ChangeDetectorRef, Component, ViewChild } from '@angular/core'; import { ButtonModule } from 'primeng/button'; import { CheckboxModule } from 'primeng/checkbox'; import { InputTextModule } from 'primeng/inputtext'; @@ -15,56 +15,72 @@ import { ChipModule } from 'primeng/chip'; import { MenuAccountComponent } from '../../menu-account/menu-account.component'; import { DividerModule } from 'primeng/divider'; import { TableModule } from 'primeng/table'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpEventType } from '@angular/common/http'; import { UserService } from '../../../services/user.service'; import { SharedModule } from '../../../shared/shared/shared.module'; import { SubscriptionsService } from '../../../services/subscriptions.service'; import { lastValueFrom } from 'rxjs'; import { MessageService } from 'primeng/api'; import { environment } from '../../../../environments/environment'; -import { FileUploadModule } from 'primeng/fileupload'; -import { AutoCompleteCompleteEvent, Invoice, Subscription, User } from '../../../../../../common-models/src/main.model'; +import { FileUpload, FileUploadModule } from 'primeng/fileupload'; +import { AutoCompleteCompleteEvent, Invoice, KeyValue, KeyValueRatio, Subscription, User } from '../../../../../../common-models/src/main.model'; import { GeoService } from '../../../services/geo.service'; import { ChangeDetectionStrategy } from '@angular/compiler'; - - +import { EditorModule } from 'primeng/editor'; +import { LoadingService } from '../../../services/loading.service'; +import { AngularCropperjsModule, CropperComponent } from 'angular-cropperjs'; +import { ImageService } from '../../../services/image.service'; +import { DialogModule } from 'primeng/dialog'; +import { SelectButtonModule } from 'primeng/selectbutton'; @Component({ selector: 'app-account', standalone: true, - // imports: [CommonModule, StyleClassModule, MenuAccountComponent, DividerModule,ButtonModule, TableModule, InputTextModule, DropdownModule, FormsModule, ChipModule,InputTextareaModule ], - imports: [SharedModule,FileUploadModule], + imports: [SharedModule,FileUploadModule,EditorModule,AngularCropperjsModule,DialogModule,SelectButtonModule], providers:[MessageService], templateUrl: './account.component.html', styleUrl: './account.component.scss' }) export class AccountComponent { + @ViewChild(CropperComponent) public angularCropper: CropperComponent; + @ViewChild('companyUpload') public companyUpload: FileUpload; + @ViewChild('profileUpload') public profileUpload: FileUpload; + private id: string | undefined = this.activatedRoute.snapshot.params['id'] as string | undefined; user:User; subscriptions:Array; userSubscriptions:Array=[]; - uploadProfileUrl:string; - uploadCompanyUrl:string; maxFileSize=1000000; companyLogoUrl:string; profileUrl:string; + imageUrl; + type:'company'|'profile' + stateOptions:KeyValueRatio[]=[ + {label:'16/9',value:16/9}, + {label:'1/1',value:1}, + {label:'2/3',value:2/3}, + ] + value:number = this.stateOptions[0].value; + config={aspectRatio: this.value} + environment=environment constructor(public userService: UserService, private subscriptionService: SubscriptionsService, private messageService: MessageService, private geoService:GeoService, public selectOptions:SelectOptionsService, - private cdref:ChangeDetectorRef) { - this.user=this.userService.getUser() + private cdref:ChangeDetectorRef, + private activatedRoute: ActivatedRoute, + private loadingService:LoadingService, + private imageUploadService: ImageService) { + } async ngOnInit(){ - + this.user=await this.userService.getById(this.id); this.userSubscriptions=await lastValueFrom(this.subscriptionService.getAllSubscriptions()); - this.uploadProfileUrl = `${environment.apiBaseUrl}/bizmatch/image/uploadProfile/${this.user.id}`; - this.uploadCompanyUrl = `${environment.apiBaseUrl}/bizmatch/image/uploadCompanyLogo/${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); - this.profileUrl = this.user.hasProfile?`${environment.apiBaseUrl}/profile/${this.user.id}`:`/assets/images/placeholder.png` - this.companyLogoUrl = this.user.hasCompanyLogo?`${environment.apiBaseUrl}/logo/${this.user.id}`:`/assets/images/placeholder.png` + this.profileUrl = this.user.hasProfile?`${environment.apiBaseUrl}/profile/${this.user.id}.avif`:`/assets/images/placeholder.png` + this.companyLogoUrl = this.user.hasCompanyLogo?`${environment.apiBaseUrl}/logo/${this.user.id}.avif`:`/assets/images/placeholder.png` } printInvoice(invoice:Invoice){} @@ -99,4 +115,60 @@ export class AccountComponent { removeLicence(){ this.user.licensedIn.splice(this.user.licensedIn.length-2,1); } + + select(event:any,type:'company'|'profile'){ + this.imageUrl = URL.createObjectURL(event.files[0]); + this.type=type + this.config={aspectRatio: type==='company'?this.stateOptions[0].value:this.stateOptions[2].value} + } + sendImage(){ + this.imageUrl=null + this.loadingService.startLoading('uploadImage'); + this.angularCropper.cropper.getCroppedCanvas().toBlob(async(blob) => { + if (this.type==='company'){ + this.imageUploadService.uploadCompanyLogo(blob,this.user.id).subscribe(async(event) => { + if (event.type === HttpEventType.UploadProgress) { + // Berechne und zeige den Fortschritt basierend auf event.loaded und event.total + const progress = event.total ? event.loaded / event.total : 0; + console.log(`Upload-Fortschritt: ${progress * 100}%`); + // Hier könntest du beispielsweise eine Fortschrittsanzeige aktualisieren + } else if (event.type === HttpEventType.Response) { + console.log('Upload abgeschlossen', event.body); + this.companyUpload.clear(); + this.loadingService.stopLoading('uploadImage'); + this.companyLogoUrl=`${environment.apiBaseUrl}/logo/${this.user.id}.avif?_ts=${new Date().getTime()}` + } + }, error => console.error('Fehler beim Upload:', error)); + } else { + this.imageUploadService.uploadProfileImage(blob,this.user.id).subscribe(async(event) => { + if (event.type === HttpEventType.UploadProgress) { + // Berechne und zeige den Fortschritt basierend auf event.loaded und event.total + const progress = event.total ? event.loaded / event.total : 0; + console.log(`Upload-Fortschritt: ${progress * 100}%`); + // Hier könntest du beispielsweise eine Fortschrittsanzeige aktualisieren + } else if (event.type === HttpEventType.Response) { + console.log('Upload abgeschlossen', event.body); + this.profileUpload.clear(); + this.loadingService.stopLoading('uploadImage'); + this.profileUrl=`${environment.apiBaseUrl}/profile/${this.user.id}.avif?_ts=${new Date().getTime()}` + } + }, error => console.error('Fehler beim Upload:', error)); + } + + + // this.fileUpload.upload(); + }, 'image/png'); + } + cancelUpload(){ + this.imageUrl=null + if (this.type==='company'){ + this.companyUpload.clear(); + } else { + this.profileUpload.clear(); + } + } + changeAspectRation(ratio:number){ + this.config={aspectRatio: ratio} + this.angularCropper.cropper.setAspectRatio(ratio); + } } diff --git a/bizmatch/src/app/pages/subscription/edit-listing/edit-listing.component.ts b/bizmatch/src/app/pages/subscription/edit-listing/edit-listing.component.ts index 7bf9edd..dafc117 100644 --- a/bizmatch/src/app/pages/subscription/edit-listing/edit-listing.component.ts +++ b/bizmatch/src/app/pages/subscription/edit-listing/edit-listing.component.ts @@ -134,7 +134,7 @@ export class EditListingComponent { this.loadingService.startLoading('uploadImage'); this.angularCropper.cropper.getCroppedCanvas().toBlob(async(blob) => { - this.imageUploadService.uploadImage(blob).subscribe(async(event) => { + this.imageUploadService.uploadPropertyImage(blob,this.listing.id).subscribe(async(event) => { if (event.type === HttpEventType.UploadProgress) { // Berechne und zeige den Fortschritt basierend auf event.loaded und event.total const progress = event.total ? event.loaded / event.total : 0; diff --git a/bizmatch/src/app/services/image.service.ts b/bizmatch/src/app/services/image.service.ts index 2bf4817..c584c43 100644 --- a/bizmatch/src/app/services/image.service.ts +++ b/bizmatch/src/app/services/image.service.ts @@ -1,23 +1,44 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { environment } from '../../environments/environment'; +import { lastValueFrom } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ImageService { - private uploadUrl = 'http://localhost:3000/bizmatch/image/uploadPropertyPicture/1a4b800e-793c-4c47-b987-7bf634060a4e'; + private apiBaseUrl = environment.apiBaseUrl; constructor(private http: HttpClient) { } - uploadImage(imageBlob: Blob) { + uploadPropertyImage(imageBlob: Blob,listingId:string) { + const uploadUrl = `${this.apiBaseUrl}/bizmatch/image/uploadPropertyPicture/${listingId}`; + return this.uploadImage(imageBlob,uploadUrl); + } + uploadCompanyLogo(imageBlob: Blob,userId:string) { + const uploadUrl = `${this.apiBaseUrl}/bizmatch/image/uploadCompanyLogo/${userId}`; + return this.uploadImage(imageBlob,uploadUrl); + } + uploadProfileImage(imageBlob: Blob,userId:string) { + const uploadUrl = `${this.apiBaseUrl}/bizmatch/image/uploadProfile/${userId}`; + return this.uploadImage(imageBlob,uploadUrl); + } + uploadImage(imageBlob: Blob,uploadUrl:string) { const formData = new FormData(); formData.append('file', imageBlob, 'image.png'); - return this.http.post(this.uploadUrl, formData,{ + return this.http.post(uploadUrl, formData,{ // headers: this.headers, reportProgress: true, observe: 'events', }); } + + async getProfileImagesForUsers(userids:string[]){ + return await lastValueFrom(this.http.get<[]>(`${this.apiBaseUrl}/bizmatch/image/profileImages/${userids.join(',')}`)); + } + async getCompanyLogosForUsers(userids:string[]){ + return await lastValueFrom(this.http.get<[]>(`${this.apiBaseUrl}/bizmatch/image/companyLogos/${userids.join(',')}`)); + } } diff --git a/bizmatch/src/app/services/loading.service.ts b/bizmatch/src/app/services/loading.service.ts index 2f823ff..a5b7cf6 100644 --- a/bizmatch/src/app/services/loading.service.ts +++ b/bizmatch/src/app/services/loading.service.ts @@ -20,7 +20,7 @@ export class LoadingService { public startLoading(type: string,request?:string): void { if (!this.loading$.value.includes(type)) { this.loading$.next(this.loading$.value.concat(type)); - if (type==='uploadImage' || request?.includes('uploadPropertyPicture')) { + if (type==='uploadImage' || request?.includes('uploadPropertyPicture')|| request?.includes('uploadProfile')|| request?.includes('uploadCompanyLogo')) { this.loadingTextSubject.next("Please wait - we're processing your image..."); } else { this.loadingTextSubject.next(null); diff --git a/bizmatch/src/assets/images/person_placeholder.jpg b/bizmatch/src/assets/images/person_placeholder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5e2b51ee8044494299d3cb7f4be499e22c0780a7 GIT binary patch literal 71263 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 { + const listings = await fs.readJson('./users.json'); + //listings.forEach(element => { + for (const listing of listings) { + const response = await fetch('http://localhost:3000/bizmatch/user', { + method: 'POST', + body: JSON.stringify(listing), + headers: { 'Content-Type': 'application/json' }, + }); + } +})(); diff --git a/crawler/index.ts b/crawler/index.ts index 77adc67..5dbb98e 100644 --- a/crawler/index.ts +++ b/crawler/index.ts @@ -106,7 +106,7 @@ async function extractListingData(page: Page): Promise { employees: content[labels.employeesLabel], reasonForSale: content[labels.reasonLabel], internals: '', - } as BusinessListing; + } as any; return listing; } catch (error) { console.log(`Fehler bei ${title}`); diff --git a/crawler/updateFields.ts b/crawler/updateFields.ts index 2c451c4..0560e9e 100644 --- a/crawler/updateFields.ts +++ b/crawler/updateFields.ts @@ -21,9 +21,9 @@ import { BusinessListing } from "../common-models/src/main.model" }) const listings:Array = await response.json(); for (const listing of listings) { - const option = selectOptions.locations.find(l=>l.name.toLowerCase()===listing.location.toLowerCase()); + const option = selectOptions.locations.find(l=>l.name.toLowerCase()===listing.state.toLowerCase()); if (option){ - listing.location=option.value + listing.state=option.value } const response = await fetch(`http://localhost:3000/bizmatch/listings/${listing.id}`, { method: 'PUT', diff --git a/crawler/users.json b/crawler/users.json new file mode 100644 index 0000000..a9574ba --- /dev/null +++ b/crawler/users.json @@ -0,0 +1,156 @@ +[ + { + "id": "8a2b1c5d-7e6f-4g3h-9i1j-2k3l4m5n6o7p", + "firstname": "Sarah", + "lastname": "Thompson", + "email": "sarah.thompson@businessbrokers.com", + "licensedIn": [ + { + "name": "California", + "value": "123456" + }, + { + "name": "Nevada", + "value": "789012" + } + ], + "phoneNumber": "(310) 555-1234", + "companyLocation": "Los Angeles - CA", + "hasCompanyLogo": true, + "hasProfile": true, + "companyName": "Business Brokers Inc.", + "companyWebsite": "https://www.businessbrokers.com", + "description": "Experienced business brokers helping clients buy and sell businesses in California and Nevada.", + "companyOverview": "

Business Brokers Inc. is a team of experienced professionals dedicated to helping clients navigate the complex process of buying and selling businesses. With a strong focus on client satisfaction and a deep understanding of the local markets in California and Nevada, we strive to deliver exceptional results for our clients.

", + "areasServed": [ + "Los Angeles County, CA", + "Orange County, CA", + "San Diego County, CA", + "Clark County, NV", + "Washoe County, NV" + ], + "offeredServices": "

Services Offered

  • Business valuation
  • Market analysis
  • Buyer and seller representation
  • Due diligence assistance
  • Negotiations and closing support
" + }, + { + "id": "4q5r6s7t-8u9v-0w1x-2y3z-4a5b6c7d8e9f", + "firstname": "Michael", + "lastname": "Johnson", + "email": "michael@bizbrokers.net", + "licensedIn": [ + { + "name": "Florida", + "value": "654321" + } + ], + "phoneNumber": "(407) 555-9876", + "companyLocation": "Orlando - FL", + "hasCompanyLogo": false, + "hasProfile": true, + "companyName": "BizBrokers", + "companyWebsite": "https://www.bizbrokers.net", + "description": "Helping business owners in Florida sell their businesses and assisting buyers in finding the perfect opportunity.", + "companyOverview": "

At BizBrokers, we understand the unique challenges of buying and selling businesses in the Florida market. Our team of experienced brokers is committed to providing personalized service and expert guidance to ensure a smooth and successful transaction for our clients.

", + "areasServed": [ + "Orange County, FL", + "Seminole County, FL", + "Osceola County, FL", + "Brevard County, FL", + "Volusia County, FL" + ], + "offeredServices": "

Services Offered

  • Business listings
  • Buyer search and qualification
  • Due diligence support
  • Financing assistance
  • Closing coordination
" + }, + { + "id": "1g2h3i4j-5k6l-7m8n-9o0p-1q2r3s4t5u6v", + "firstname": "Emily", + "lastname": "Davis", + "email": "emily.davis@bizsaleexperts.com", + "licensedIn": [ + { + "name": "New York", + "value": "987654" + }, + { + "name": "New Jersey", + "value": "210987" + } + ], + "phoneNumber": "(212) 555-4321", + "companyLocation": "New York City - NY", + "hasCompanyLogo": true, + "hasProfile": true, + "companyName": "Business Sale Experts", + "companyWebsite": "https://www.bizsaleexperts.com", + "description": "Experienced business brokers specializing in the sale of businesses in the New York and New Jersey area.", + "companyOverview": "

Business Sale Experts is a leading business brokerage firm serving the New York and New Jersey markets. With a team of seasoned professionals and a proven track record of success, we are dedicated to helping our clients achieve their goals in the sale or acquisition of businesses.

", + "areasServed": [ + "New York County, NY", + "Kings County, NY", + "Queens County, NY", + "Bronx County, NY", + "Hudson County, NJ", + "Bergen County, NJ", + "Essex County, NJ" + ], + "offeredServices": "

Services Offered

  • Business valuation
  • Marketing and advertising
  • Buyer screening and qualification
  • Negotiations and deal structuring
  • Due diligence coordination
  • Closing support
" + }, + { + "id": "7w8x9y0z-1a2b-3c4d-5e6f-7g8h9i0j1k2l", + "firstname": "David", + "lastname": "Wilson", + "email": "david.wilson@bizacquisitions.com", + "licensedIn": [ + { + "name": "Texas", + "value": "543210" + } + ], + "phoneNumber": "(713) 555-8765", + "companyLocation": "Houston - TX", + "hasCompanyLogo": true, + "hasProfile": true, + "companyName": "Business Acquisitions Ltd.", + "companyWebsite": "https://www.bizacquisitions.com", + "description": "Helping business owners in Texas sell their businesses and assisting buyers in finding the perfect acquisition opportunity.", + "companyOverview": "

Business Acquisitions Ltd. is a leading business brokerage firm serving the Texas market. Our team of experienced brokers is dedicated to providing expert guidance and personalized service to help our clients achieve their goals in the sale or acquisition of businesses.

", + "areasServed": [ + "Harris County, TX", + "Dallas County, TX", + "Tarrant County, TX", + "Bexar County, TX", + "Travis County, TX" + ], + "offeredServices": "

Services Offered

  • Business valuation
  • Market analysis
  • Buyer search and qualification
  • Due diligence coordination
  • Financing assistance
  • Closing support
" + }, + { + "id": "3m4n5o6p-7q8r-9s0t-1u2v-3w4x5y6z7a8b", + "firstname": "Jessica", + "lastname": "Brown", + "email": "jessica@bizbrokerexperts.com", + "licensedIn": [ + { + "name": "Illinois", + "value": "876543" + }, + { + "name": "Wisconsin", + "value": "109876" + } + ], + "phoneNumber": "(312) 555-2109", + "companyLocation": "Chicago - IL", + "hasCompanyLogo": true, + "hasProfile": true, + "companyName": "Business Broker Experts", + "companyWebsite": "https://www.bizbrokerexperts.com", + "description": "Experienced business brokers helping clients buy and sell businesses in Illinois and Wisconsin.", + "companyOverview": "

Business Broker Experts is a leading business brokerage firm serving the Illinois and Wisconsin markets. With a team of seasoned professionals and a commitment to client satisfaction, we strive to deliver exceptional results for our clients in the sale or acquisition of businesses.

", + "areasServed": [ + "Cook County, IL", + "DuPage County, IL", + "Lake County, IL", + "Milwaukee County, WI", + "Dane County, WI" + ], + "offeredServices": "

Services Offered

  • Business valuation
  • Market analysis
  • Buyer and seller representation
  • Due diligence assistance
  • Negotiations and closing support
" + } + ] \ No newline at end of file