diff --git a/bizmatch-server/src/drizzle/migrations/0001_wet_mephistopheles.sql b/bizmatch-server/src/drizzle/migrations/0001_wet_mephistopheles.sql new file mode 100644 index 0000000..c6cbcab --- /dev/null +++ b/bizmatch-server/src/drizzle/migrations/0001_wet_mephistopheles.sql @@ -0,0 +1,7 @@ +DO $$ BEGIN + CREATE TYPE "customerType" AS ENUM('buyer', 'broker', 'professional'); +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +ALTER TABLE "users" ADD COLUMN "customerType" "customerType"; \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/migrations/meta/0001_snapshot.json b/bizmatch-server/src/drizzle/migrations/meta/0001_snapshot.json new file mode 100644 index 0000000..46667c5 --- /dev/null +++ b/bizmatch-server/src/drizzle/migrations/meta/0001_snapshot.json @@ -0,0 +1,518 @@ +{ + "id": "0bc02618-4414-4e90-8c44-808737611da7", + "prevId": "fc58c59b-ac5c-406e-8fdb-b05de40aed17", + "version": "5", + "dialect": "pg", + "tables": { + "businesses": { + "name": "businesses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "char(2)", + "primaryKey": false, + "notNull": false + }, + "price": { + "name": "price", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "favoritesForUser": { + "name": "favoritesForUser", + "type": "varchar(30)[]", + "primaryKey": false, + "notNull": false + }, + "draft": { + "name": "draft", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "listingsCategory": { + "name": "listingsCategory", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "realEstateIncluded": { + "name": "realEstateIncluded", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "leasedLocation": { + "name": "leasedLocation", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "franchiseResale": { + "name": "franchiseResale", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "salesRevenue": { + "name": "salesRevenue", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "cashFlow": { + "name": "cashFlow", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "supportAndTraining": { + "name": "supportAndTraining", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "employees": { + "name": "employees", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "established": { + "name": "established", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "internalListingNumber": { + "name": "internalListingNumber", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reasonForSale": { + "name": "reasonForSale", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "brokerLicencing": { + "name": "brokerLicencing", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "internals": { + "name": "internals", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "imagePath": { + "name": "imagePath", + "type": "varchar(200)", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated": { + "name": "updated", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "visits": { + "name": "visits", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastVisit": { + "name": "lastVisit", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "businesses_userId_users_id_fk": { + "name": "businesses_userId_users_id_fk", + "tableFrom": "businesses", + "tableTo": "users", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "commercials": { + "name": "commercials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "serial_id": { + "name": "serial_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "char(2)", + "primaryKey": false, + "notNull": false + }, + "price": { + "name": "price", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "favoritesForUser": { + "name": "favoritesForUser", + "type": "varchar(30)[]", + "primaryKey": false, + "notNull": false + }, + "listingsCategory": { + "name": "listingsCategory", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "hideImage": { + "name": "hideImage", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "draft": { + "name": "draft", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "zipCode": { + "name": "zipCode", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "county": { + "name": "county", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "phoneNumber": { + "name": "phoneNumber", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "imageOrder": { + "name": "imageOrder", + "type": "varchar(200)[]", + "primaryKey": false, + "notNull": false + }, + "imagePath": { + "name": "imagePath", + "type": "varchar(200)", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated": { + "name": "updated", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "visits": { + "name": "visits", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastVisit": { + "name": "lastVisit", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "commercials_userId_users_id_fk": { + "name": "commercials_userId_users_id_fk", + "tableFrom": "commercials", + "tableTo": "users", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "firstname": { + "name": "firstname", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "lastname": { + "name": "lastname", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phoneNumber": { + "name": "phoneNumber", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "companyName": { + "name": "companyName", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "companyOverview": { + "name": "companyOverview", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "companyWebsite": { + "name": "companyWebsite", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "companyLocation": { + "name": "companyLocation", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "offeredServices": { + "name": "offeredServices", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "areasServed": { + "name": "areasServed", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hasProfile": { + "name": "hasProfile", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "hasCompanyLogo": { + "name": "hasCompanyLogo", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "licensedIn": { + "name": "licensedIn", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "gender": { + "name": "gender", + "type": "gender", + "primaryKey": false, + "notNull": false + }, + "customerType": { + "name": "customerType", + "type": "customerType", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated": { + "name": "updated", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "customerType": { + "name": "customerType", + "values": { + "buyer": "buyer", + "broker": "broker", + "professional": "professional" + } + }, + "gender": { + "name": "gender", + "values": { + "male": "male", + "female": "female" + } + } + }, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/migrations/meta/_journal.json b/bizmatch-server/src/drizzle/migrations/meta/_journal.json index c61103a..e2ba672 100644 --- a/bizmatch-server/src/drizzle/migrations/meta/_journal.json +++ b/bizmatch-server/src/drizzle/migrations/meta/_journal.json @@ -8,6 +8,13 @@ "when": 1716495198537, "tag": "0000_burly_bruce_banner", "breakpoints": true + }, + { + "idx": 1, + "version": "5", + "when": 1717085220861, + "tag": "0001_wet_mephistopheles", + "breakpoints": true } ] } \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/schema.ts b/bizmatch-server/src/drizzle/schema.ts index f929b43..b2f640a 100644 --- a/bizmatch-server/src/drizzle/schema.ts +++ b/bizmatch-server/src/drizzle/schema.ts @@ -3,6 +3,7 @@ import { AreasServed, LicensedIn } from 'src/models/db.model'; export const PG_CONNECTION = 'PG_CONNECTION'; export const genderEnum = pgEnum('gender', ['male', 'female']); +export const customerTypeEnum = pgEnum('customerType', ['buyer', 'broker', 'professional']); export const users = pgTable('users', { id: uuid('id').primaryKey().defaultRandom(), @@ -21,6 +22,7 @@ export const users = pgTable('users', { hasCompanyLogo: boolean('hasCompanyLogo'), licensedIn: jsonb('licensedIn').$type(), gender: genderEnum('gender'), + customerType: customerTypeEnum('customerType'), created: timestamp('created'), updated: timestamp('updated'), }); diff --git a/bizmatch-server/src/models/db.model.ts b/bizmatch-server/src/models/db.model.ts index 3ff474b..1ce3a18 100644 --- a/bizmatch-server/src/models/db.model.ts +++ b/bizmatch-server/src/models/db.model.ts @@ -15,6 +15,7 @@ export interface User { hasCompanyLogo?: boolean; licensedIn?: LicensedIn[]; gender?: 'male' | 'female'; + customerType?: 'buyer' | 'broker' | 'professional'; created?: Date; updated?: Date; } @@ -35,6 +36,7 @@ export interface UserData { hasCompanyLogo?: boolean; licensedIn?: string[]; gender?: 'male' | 'female'; + customerType?: 'buyer' | 'broker' | 'professional'; created?: Date; updated?: Date; } diff --git a/bizmatch-server/src/select-options/select-options.controller.ts b/bizmatch-server/src/select-options/select-options.controller.ts index f37d8d3..bf35719 100644 --- a/bizmatch-server/src/select-options/select-options.controller.ts +++ b/bizmatch-server/src/select-options/select-options.controller.ts @@ -3,16 +3,16 @@ import { SelectOptionsService } from './select-options.service.js'; @Controller('select-options') export class SelectOptionsController { - constructor(private selectOptionsService:SelectOptionsService){} - @Get() - getSelectOption():any{ - return { - typesOfBusiness:this.selectOptionsService.typesOfBusiness, - prices:this.selectOptionsService.prices, - listingCategories:this.selectOptionsService.listingCategories, - categories:this.selectOptionsService.categories, - locations:this.selectOptionsService.locations, - typesOfCommercialProperty:this.selectOptionsService.typesOfCommercialProperty, - } - } + constructor(private selectOptionsService: SelectOptionsService) {} + @Get() + getSelectOption(): any { + return { + typesOfBusiness: this.selectOptionsService.typesOfBusiness, + prices: this.selectOptionsService.prices, + listingCategories: this.selectOptionsService.listingCategories, + customerTypes: this.selectOptionsService.customerTypes, + locations: this.selectOptionsService.locations, + typesOfCommercialProperty: this.selectOptionsService.typesOfCommercialProperty, + }; + } } diff --git a/bizmatch-server/src/select-options/select-options.service.ts b/bizmatch-server/src/select-options/select-options.service.ts index c74d2e7..3e78b39 100644 --- a/bizmatch-server/src/select-options/select-options.service.ts +++ b/bizmatch-server/src/select-options/select-options.service.ts @@ -39,9 +39,14 @@ export class SelectOptionsService { { name: 'Business', value: 'business' }, { name: 'Commercial Property', value: 'commercialProperty' }, ]; - public categories: Array = [ - { name: 'Broker', value: 'broker', icon: 'pi-image', bgColorClass: 'bg-green-100', textColorClass: 'text-green-600' }, - { name: 'Professional', value: 'professional', icon: 'pi-globe', bgColorClass: 'bg-yellow-100', textColorClass: 'text-yellow-600' }, + public customerTypes: Array = [ + { name: 'Buyer', value: 'buyer' }, + { name: 'Broker', value: 'broker' }, + { name: 'Professional', value: 'professional' }, + ]; + public gender: Array = [ + { name: 'Male', value: 'male' }, + { name: 'Female', value: 'female' }, ]; public imageTypes: ImageType[] = [ { name: 'propertyPicture', upload: 'uploadPropertyPicture', delete: 'propertyPicture' }, diff --git a/bizmatch/src/app/pages/subscription/account/account.component.html b/bizmatch/src/app/pages/subscription/account/account.component.html index 9ebecba..69bc855 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.html +++ b/bizmatch/src/app/pages/subscription/account/account.component.html @@ -8,10 +8,16 @@
@if (user){ -
- - -

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

+
+
+ + +

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

+
+
+ + +
@@ -23,6 +29,7 @@
+ @if (isProfessional){
@@ -33,6 +40,7 @@
+ } @if (isProfessional){
@@ -47,6 +55,14 @@
+ } @else { +
+
+ + +
+
+ } @if (isProfessional){
@@ -59,7 +75,6 @@
-
@for (areasServed of user.areasServed; track areasServed){ @@ -118,11 +133,12 @@  (Add more licenses or remove existing ones.)
- } + } }
+ @if (isProfessional){
Company Logo @@ -172,6 +188,7 @@ >
+ }
Membership Level
diff --git a/bizmatch/src/app/pages/subscription/account/account.component.ts b/bizmatch/src/app/pages/subscription/account/account.component.ts index 4d6559f..70a44d6 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.ts +++ b/bizmatch/src/app/pages/subscription/account/account.component.ts @@ -75,7 +75,7 @@ export class AccountComponent { try { this.user = await this.userService.getByMail(email); } catch (e) { - this.user = { email, firstname: keycloakUser.firstName, lastname: keycloakUser.lastName, areasServed: [], licensedIn: [], companyOverview: '', offeredServices: '' }; + this.user = { email, firstname: keycloakUser.firstName, lastname: keycloakUser.lastName, areasServed: [], licensedIn: [], companyOverview: '', offeredServices: '', customerType: 'broker' }; this.user = await this.userService.save(this.user); } } @@ -121,6 +121,9 @@ export class AccountComponent { removeArea() { this.user.areasServed.splice(this.user.areasServed.length - 1, 1); } + get isProfessional() { + return this.user.customerType === 'broker' || this.user.customerType === 'professional'; + } select(event: any, type: 'company' | 'profile') { const imageUrl = URL.createObjectURL(event.files[0]); this.type = type; diff --git a/bizmatch/src/app/services/select-options.service.ts b/bizmatch/src/app/services/select-options.service.ts index e519c92..c4a9a02 100644 --- a/bizmatch/src/app/services/select-options.service.ts +++ b/bizmatch/src/app/services/select-options.service.ts @@ -1,9 +1,8 @@ -import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { InitEditableRow } from 'primeng/table'; +import { Injectable } from '@angular/core'; import { lastValueFrom } from 'rxjs'; -import { environment } from '../../environments/environment'; import { KeyValue, KeyValueStyle } from '../../../../bizmatch-server/src/models/main.model'; +import { environment } from '../../environments/environment'; @Injectable({ providedIn: 'root', @@ -13,67 +12,58 @@ export class SelectOptionsService { constructor(private http: HttpClient) {} async init() { - const allSelectOptions = await lastValueFrom( - this.http.get(`${this.apiBaseUrl}/bizmatch/select-options`) - ); + const allSelectOptions = await lastValueFrom(this.http.get(`${this.apiBaseUrl}/bizmatch/select-options`)); this.typesOfBusiness = allSelectOptions.typesOfBusiness; this.prices = allSelectOptions.prices; this.listingCategories = allSelectOptions.listingCategories; - this.categories = allSelectOptions.categories; + this.customerTypes = allSelectOptions.customerTypes; this.states = allSelectOptions.locations; - this.typesOfCommercialProperty = allSelectOptions.typesOfCommercialProperty + this.gender = allSelectOptions.gender; + this.typesOfCommercialProperty = allSelectOptions.typesOfCommercialProperty; } public typesOfBusiness: Array; - + public typesOfCommercialProperty: Array; - + public prices: Array; public listingCategories: Array; - public categories: Array; + public customerTypes: Array; + + public gender: Array; public states: Array; - getState(value:string):string{ - return this.states.find(l=>l.value===value)?.name + getState(value: string): string { + return this.states.find(l => l.value === value)?.name; } - getBusiness(value:number):string{ - return this.typesOfBusiness.find(t=>t.value===String(value))?.name + getBusiness(value: number): string { + return this.typesOfBusiness.find(t => t.value === String(value))?.name; } - getCommercialProperty(value:number):string{ - return this.typesOfCommercialProperty.find(t=>t.value===String(value))?.name + getCommercialProperty(value: number): string { + return this.typesOfCommercialProperty.find(t => t.value === String(value))?.name; } - getListingsCategory(value:string):string{ - return this.listingCategories.find(l=>l.value===value)?.name + getListingsCategory(value: string): string { + return this.listingCategories.find(l => l.value === value)?.name; } - getCategory(value:string):string{ - return this.categories.find(c=>c.value===value)?.name + getCustomerType(value: string): string { + return this.customerTypes.find(c => c.value === value)?.name; } - getIcon(value:string):string{ - return this.categories.find(c=>c.value===value)?.icon + getGender(value: string): string { + return this.gender.find(c => c.value === value)?.name; } - getTextColor(value:string):string{ - return this.categories.find(c=>c.value===value)?.textColorClass + getIconType(value: string): string { + return this.typesOfBusiness.find(c => c.value === value)?.icon; } - getBgColor(value:string):string{ - return this.categories.find(c=>c.value===value)?.bgColorClass + getTextColorType(value: string): string { + return this.typesOfBusiness.find(c => c.value === value)?.textColorClass; } - getIconAndTextColor(value:string):string{ - const category = this.categories.find(c=>c.value===value) - return `${category?.icon} ${category?.textColorClass}` + getBgColorType(value: number): string { + return this.typesOfBusiness.find(c => c.value === String(value))?.bgColorClass; } - getIconType(value:string):string{ - return this.typesOfBusiness.find(c=>c.value===value)?.icon - } - getTextColorType(value:string):string{ - return this.typesOfBusiness.find(c=>c.value===value)?.textColorClass - } - getBgColorType(value:number):string{ - return this.typesOfBusiness.find(c=>c.value===String(value))?.bgColorClass - } - getIconAndTextColorType(value:number):string{ - const category = this.typesOfBusiness.find(c=>c.value===String(value)) - return `${category?.icon} ${category?.textColorClass}` + getIconAndTextColorType(value: number): string { + const category = this.typesOfBusiness.find(c => c.value === String(value)); + return `${category?.icon} ${category?.textColorClass}`; } }