BugFix: ERROR [ExceptionsHandler] column "users.areasServed" must appear in the GROUP BY clause or be used in an aggregate function resolved
This commit is contained in:
parent
7807afbad3
commit
9ecc0c2429
|
|
@ -70,13 +70,6 @@ export class UserController {
|
|||
findTotal(@Body() criteria: UserListingCriteria): Promise<number> {
|
||||
return this.userService.getUserListingsCount(criteria);
|
||||
}
|
||||
@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;
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get('subscriptions/:id')
|
||||
|
|
|
|||
|
|
@ -140,10 +140,4 @@ export class UserService {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,66 +1,3 @@
|
|||
<!-- <div id="sky-line" class="hidden-lg-down"></div>
|
||||
<div class="search">
|
||||
<div class="wrapper">
|
||||
<div class="grid p-4 align-items-center">
|
||||
<div class="col-2">
|
||||
<p-dropdown [filter]="true" filterBy="name" [options]="states" [(ngModel)]="criteria.state" optionLabel="name" optionValue="value" [showClear]="true" placeholder="Location" [style]="{ width: '100%' }">
|
||||
<ng-template let-state pTemplate="item">
|
||||
<div class="flex align-items-center gap-2">
|
||||
<div>{{ state.name }} ({{ state.count }})</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</p-dropdown>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<p-inputGroup>
|
||||
<input id="name" type="text" pInputText [(ngModel)]="criteria.name" placeholder="Name" />
|
||||
<button type="button" pButton icon="pi pi-times" class="p-button-secondary" (click)="reset()"></button>
|
||||
</p-inputGroup>
|
||||
</div>
|
||||
<div class="col-1 col-offset-7">
|
||||
<p-button label="Refine" (click)="refine()"></p-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="surface-200 h-full">
|
||||
<div class="wrapper">
|
||||
<div class="grid">
|
||||
@for (user of users; track user) {
|
||||
<div class="col-12 lg:col-6 xl:col-4 p-4 flex flex-column">
|
||||
<div class="surface-card shadow-2 p-2 flex flex-column flex-grow-1 justify-content-between" style="border-radius: 10px">
|
||||
<div class="surface-card p-4 flex flex-column align-items-center md:flex-row md:align-items-stretch h-full">
|
||||
<span>
|
||||
@if(user.hasProfile){
|
||||
<img src="{{ env.imageBaseUrl }}/pictures/profile/{{ emailToDirName(user.email) }}.avif?_ts={{ ts }}" class="w-5rem" />
|
||||
} @else {
|
||||
<img src="assets/images/person_placeholder.jpg" class="w-5rem" />
|
||||
}
|
||||
</span>
|
||||
<div class="flex flex-column align-items-center md:align-items-stretch ml-4 mt-4 md:mt-0">
|
||||
<p class="mt-0 mb-3 line-height-3 text-center md:text-left">{{ user.description }}</p>
|
||||
<span class="text-900 font-medium mb-1 mt-auto">{{ user.firstname }} {{ user.lastname }}</span>
|
||||
<div class="text-600 text-sm">{{ user.companyName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4 py-3 text-right flex justify-content-between align-items-center">
|
||||
@if(user.hasCompanyLogo){
|
||||
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ emailToDirName(user.email) }}.avif?_ts={{ ts }}" class="rounded-image" />
|
||||
} @else {
|
||||
<img src="assets/images/placeholder.png" class="rounded-image" />
|
||||
}
|
||||
<button pButton pRipple icon="pi pi-arrow-right" iconPos="right" label="View Full profile" class="p-button-rounded p-button-success" [routerLink]="['/details-user', user.id]"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="mb-2 surface-200 flex align-items-center justify-content-center paginator-bar">
|
||||
<div class="mx-1 text-color">Total number of Professionals/Brokers: {{ totalRecords }}</div>
|
||||
<p-paginator (onPageChange)="onPageChange($event)" [first]="first" [rows]="rows" [totalRecords]="totalRecords" [rowsPerPageOptions]="[12, 24, 48]"></p-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<!-- Amanda Taylor -->
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ export class BrokerListingsComponent {
|
|||
maxPrice: string;
|
||||
minPrice: string;
|
||||
type: string;
|
||||
states = [];
|
||||
statesSet = new Set();
|
||||
state: string;
|
||||
first: number = 0;
|
||||
|
|
@ -63,10 +62,7 @@ export class BrokerListingsComponent {
|
|||
}
|
||||
});
|
||||
}
|
||||
async ngOnInit() {
|
||||
const statesResult = await this.userService.getAllStates();
|
||||
this.states = statesResult.map(ls => ({ name: this.selectOptions.getState(ls.state as string), value: ls.state, count: ls.count }));
|
||||
}
|
||||
async ngOnInit() {}
|
||||
async init() {
|
||||
this.search();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ export class BusinessListingsComponent {
|
|||
maxPrice: string;
|
||||
minPrice: string;
|
||||
type: string;
|
||||
states = [];
|
||||
state: string;
|
||||
totalRecords: number = 0;
|
||||
ts = new Date().getTime();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ export class CommercialPropertyListingsComponent {
|
|||
maxPrice: string;
|
||||
minPrice: string;
|
||||
type: string;
|
||||
states = [];
|
||||
statesSet = new Set();
|
||||
state: string;
|
||||
totalRecords: number = 0;
|
||||
|
|
@ -59,8 +58,6 @@ export class CommercialPropertyListingsComponent {
|
|||
}
|
||||
async ngOnInit() {}
|
||||
async init() {
|
||||
const statesResult = await this.listingsService.getAllStates('commercialProperty');
|
||||
this.states = statesResult.map(ls => ({ name: this.selectOptions.getState(ls.state as string), value: ls.state, count: ls.count }));
|
||||
this.search();
|
||||
}
|
||||
async search() {
|
||||
|
|
|
|||
|
|
@ -2,14 +2,7 @@ import { HttpClient } from '@angular/common/http';
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Observable, lastValueFrom } from 'rxjs';
|
||||
import { BusinessListing, CommercialPropertyListing } from '../../../../bizmatch-server/src/models/db.model';
|
||||
import {
|
||||
BusinessListingCriteria,
|
||||
CommercialPropertyListingCriteria,
|
||||
ListingType,
|
||||
ResponseBusinessListingArray,
|
||||
ResponseCommercialPropertyListingArray,
|
||||
StatesResult,
|
||||
} from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { BusinessListingCriteria, CommercialPropertyListingCriteria, ListingType, ResponseBusinessListingArray, ResponseCommercialPropertyListingArray } from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
|
|
@ -50,10 +43,6 @@ export class ListingsService {
|
|||
return await lastValueFrom(this.http.post<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}`, listing));
|
||||
}
|
||||
}
|
||||
async getAllStates(listingsCategory?: 'business' | 'commercialProperty'): Promise<StatesResult[]> {
|
||||
const result = lastValueFrom(this.http.get<StatesResult[]>(`${this.apiBaseUrl}/bizmatch/listings/business/states/all`));
|
||||
return result;
|
||||
}
|
||||
async deleteBusinessListing(id: string) {
|
||||
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/business/${id}`));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue