This commit is contained in:
2024-05-15 17:35:04 -05:00
parent 474d7c63d5
commit f51a298227
39 changed files with 333 additions and 260 deletions

View File

@@ -18,11 +18,11 @@ export class ImageController {
private selectOptions: SelectOptionsService,
) {}
@Post('uploadPropertyPicture/:id')
@Post('uploadPropertyPicture/:imagePath')
@UseInterceptors(FileInterceptor('file'))
async uploadPropertyPicture(@UploadedFile() file: Express.Multer.File, @Param('id') id: string) {
const imagename = await this.fileService.storePropertyPicture(file, id);
await this.listingService.addImage(id, imagename);
async uploadPropertyPicture(@UploadedFile() file: Express.Multer.File, @Param('imagePath') imagePath: string) {
const imagename = await this.fileService.storePropertyPicture(file, imagePath);
await this.listingService.addImage(imagePath, imagename);
}
@Post('uploadProfile/:id')

View File

@@ -68,7 +68,13 @@ export class ListingsService {
.where(sql`${table.id} = ${id}`);
return result[0] as BusinessListing | CommercialPropertyListing;
}
async findByImagePath(imagePath: string): Promise<CommercialPropertyListing> {
const result = await this.conn
.select()
.from(commercials)
.where(sql`${commercials.imagePath} = ${imagePath}`);
return result[0] as CommercialPropertyListing;
}
async findByUserId(userId: string, table: typeof businesses | typeof commercials): Promise<BusinessListing[] | CommercialPropertyListing[]> {
return (await this.conn.select().from(table).where(eq(table.userId, userId))) as BusinessListing[] | CommercialPropertyListing[];
}
@@ -76,8 +82,6 @@ export class ListingsService {
async createListing(data: BusinessListing | CommercialPropertyListing, table: typeof businesses | typeof commercials): Promise<BusinessListing | CommercialPropertyListing> {
data.created = new Date();
data.updated = new Date();
data.visits = 0;
data.lastVisit = null;
const [createdListing] = await this.conn.insert(table).values(data).returning();
return createdListing as BusinessListing | CommercialPropertyListing;
}
@@ -116,10 +120,9 @@ export class ListingsService {
await this.updateListing(listing.id, listing, commercials);
}
}
async addImage(id: string, imagename: string) {
const listing = (await this.findById(id, commercials)) as unknown as CommercialPropertyListing;
async addImage(imagePath: string, imagename: string) {
const listing = (await this.findByImagePath(imagePath)) as unknown as CommercialPropertyListing;
listing.imageOrder.push(imagename);
listing.imagePath = listing.id;
await this.updateListing(listing.id, listing, commercials);
}
}

View File

@@ -35,7 +35,7 @@ export class MailService {
phone: mailInfo.sender.phoneNumber,
email: mailInfo.sender.email,
id: mailInfo.listing.id,
url: 'http://localhost:4200',
url: mailInfo.url,
},
});
return user;

View File

@@ -65,7 +65,7 @@ export interface BusinessListing {
updated?: Date;
visits?: number;
lastVisit?: Date;
listingsCategory?: string;
listingsCategory?: 'commercialProperty' | 'business';
}
export interface CommercialPropertyListing {
@@ -91,7 +91,7 @@ export interface CommercialPropertyListing {
updated?: Date;
visits?: number;
lastVisit?: Date;
listingsCategory?: string;
listingsCategory?: 'commercialProperty' | 'business';
}
export interface AreasServed {
county: string;

View File

@@ -64,24 +64,24 @@ export interface ListingCriteria {
maxPrice: number;
realEstateChecked: boolean;
title: string;
category: 'professional|broker';
category: 'professional' | 'broker';
name: string;
}
export interface KeycloakUser {
id: string;
createdTimestamp: number;
username: string;
enabled: boolean;
totp: boolean;
emailVerified: boolean;
createdTimestamp?: number;
username?: string;
enabled?: boolean;
totp?: boolean;
emailVerified?: boolean;
firstName: string;
lastName: string;
email: string;
disableableCredentialTypes: any[];
requiredActions: any[];
notBefore: number;
access: Access;
disableableCredentialTypes?: any[];
requiredActions?: any[];
notBefore?: number;
access?: Access;
}
export interface Access {
manageGroupMembership: boolean;
@@ -150,6 +150,7 @@ export interface MailInfo {
sender: Sender;
userId: string;
email: string;
url: string;
listing?: BusinessListing;
}
export interface Sender {

View File

@@ -1,13 +1,15 @@
import { Body, Controller, Get, Inject, Param, Post, Put, Query, Req } from '@nestjs/common';
import { UserService } from './user.service.js';
import { Body, Controller, Get, Inject, Param, Post, Query } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { User } from 'src/models/db.model.js';
import { Logger } from 'winston';
import { UserService } from './user.service.js';
@Controller('user')
export class UserController {
constructor(private userService: UserService, @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {}
constructor(
private userService: UserService,
@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
) {}
@Get()
findByMail(@Query('mail') mail: string): any {
@@ -30,7 +32,7 @@ export class UserController {
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)}`);
@@ -38,5 +40,11 @@ export class UserController {
this.logger.info(`Found users: ${JSON.stringify(foundUsers)}`);
return foundUsers;
}
@Get('states/all')
async getStates(): Promise<any[]> {
this.logger.info(`Getting all states for users`);
const result = await this.userService.getStates();
this.logger.info(`Found ${result.length} entries`);
return result;
}
}

View File

@@ -19,7 +19,8 @@ export class UserService {
private getConditions(criteria: ListingCriteria): any[] {
const conditions = [];
if (criteria.state) {
conditions.push(sql`EXISTS (SELECT 1 FROM unnest(users."areasServed") AS area WHERE area LIKE '%' || ${criteria.state} || '%')`);
//conditions.push(sql`EXISTS (SELECT 1 FROM unnest(users."areasServed") AS area WHERE area LIKE '%' || ${criteria.state} || '%')`);
conditions.push(sql`${schema.users.areasServed} @> ${JSON.stringify([{ state: criteria.state }])}`);
}
if (criteria.name) {
conditions.push(or(ilike(schema.users.firstname, `%${criteria.name}%`), ilike(schema.users.lastname, `%${criteria.name}%`)));
@@ -78,4 +79,9 @@ export class UserService {
]);
return { total, data };
}
async getStates(): Promise<any[]> {
const query = sql`SELECT jsonb_array_elements(${schema.users.areasServed}) ->> 'state' AS state, COUNT(DISTINCT ${schema.users.id}) AS count FROM ${schema.users} GROUP BY state ORDER BY count DESC`;
const result = await this.conn.execute(query);
return result.rows;
}
}