fix further bugs

This commit is contained in:
Andreas Knuth 2024-05-16 15:57:39 -05:00
parent 327aef0f21
commit e0ecea5af2
12 changed files with 135 additions and 101 deletions

View File

@ -1,13 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { fstat, readFileSync } from 'fs';
import { join } from 'path';
import { fileURLToPath } from 'url';
import path from 'path';
import { readFileSync } from 'fs';
import fs from 'fs-extra';
import { ImageProperty } from '../models/main.model.js';
import sharp from 'sharp';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import path, { join } from 'path';
import sharp from 'sharp';
import { fileURLToPath } from 'url';
import { Logger } from 'winston';
import { ImageProperty } from '../models/main.model.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@ -27,7 +26,7 @@ export class FileService {
this.subscriptions = JSON.parse(rawData);
}
getSubscriptions() {
return this.subscriptions
return this.subscriptions;
}
async storeProfilePicture(file: Express.Multer.File, userId: string) {
let quality = 50;
@ -38,8 +37,8 @@ export class FileService {
.toBuffer();
await sharp(output).toFile(`./pictures/profile/${userId}.avif`);
}
hasProfile(userId: string){
return fs.existsSync(`./pictures/profile/${userId}.avif`)
hasProfile(userId: string) {
return fs.existsSync(`./pictures/profile/${userId}.avif`);
}
async storeCompanyLogo(file: Express.Multer.File, userId: string) {
@ -52,41 +51,41 @@ export class FileService {
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}.avif`)?true:false
hasCompanyLogo(userId: string) {
return fs.existsSync(`./pictures/logo/${userId}.avif`) ? true : false;
}
async getPropertyImages(listingId: string): Promise<string[]> {
const result: string[] = []
const directory = `./pictures/property/${listingId}`
const result: string[] = [];
const directory = `./pictures/property/${listingId}`;
if (fs.existsSync(directory)) {
const files = await fs.readdir(directory);
files.forEach(f => {
result.push(f)
})
result.push(f);
});
return result;
} else {
return []
return [];
}
}
async hasPropertyImages(listingId: string): Promise<boolean> {
const result: ImageProperty[] = []
const directory = `./pictures/property/${listingId}`
const result: ImageProperty[] = [];
const directory = `./pictures/property/${listingId}`;
if (fs.existsSync(directory)) {
const files = await fs.readdir(directory);
return files.length>0
return files.length > 0;
} else {
return false
return false;
}
}
async storePropertyPicture(file: Express.Multer.File, listingId: string) : Promise<string> {
const suffix = file.mimetype.includes('png') ? 'png' : 'jpg'
const directory = `./pictures/property/${listingId}`
async storePropertyPicture(file: Express.Multer.File, listingId: string): Promise<string> {
const suffix = file.mimetype.includes('png') ? 'png' : 'jpg';
const directory = `./pictures/property/${listingId}`;
fs.ensureDirSync(`${directory}`);
const imageName = await this.getNextImageName(directory);
//await fs.outputFile(`${directory}/${imageName}`, file.buffer);
await this.resizeImageToAVIF(file.buffer,150 * 1024,imageName,directory);
return `${imageName}.avif`
await this.resizeImageToAVIF(file.buffer, 150 * 1024, imageName, directory);
return `${imageName}.avif`;
}
async getNextImageName(directory) {
try {
@ -103,7 +102,7 @@ export class FileService {
return null;
}
}
async resizeImageToAVIF(buffer: Buffer, maxSize: number,imageName:string,directory:string) {
async resizeImageToAVIF(buffer: Buffer, maxSize: number, imageName: string, directory: string) {
let quality = 50; // AVIF kann mit niedrigeren Qualitätsstufen gute Ergebnisse erzielen
let output;
let start = Date.now();
@ -114,26 +113,40 @@ export class FileService {
.toBuffer();
await sharp(output).toFile(`${directory}/${imageName}.avif`); // Ersetze Dateierweiterung
let timeTaken = Date.now() - start;
this.logger.info(`Quality: ${quality} - Time: ${timeTaken} milliseconds`)
this.logger.info(`Quality: ${quality} - Time: ${timeTaken} milliseconds`);
}
getProfileImagesForUsers(userids:string){
getProfileImagesForUsers(userids: string) {
const ids = userids.split(',');
let result = {};
for (const id of ids){
result = {...result,[id]:fs.existsSync(`./pictures/profile/${id}.avif`)}
for (const id of ids) {
result = { ...result, [id]: fs.existsSync(`./pictures/profile/${id}.avif`) };
}
return result;
}
getCompanyLogosForUsers(userids:string){
getCompanyLogosForUsers(userids: string) {
const ids = userids.split(',');
let result = {};
for (const id of ids){
result = {...result,[id]:fs.existsSync(`./pictures/logo/${id}.avif`)}
for (const id of ids) {
result = { ...result, [id]: fs.existsSync(`./pictures/logo/${id}.avif`) };
}
return result;
}
deleteImage(path:string){
deleteImage(path: string) {
fs.unlinkSync(path);
}
deleteDirectoryIfExists(imagePath) {
const dirPath = `pictures/property/${imagePath}`;
try {
const exists = fs.pathExistsSync();
if (exists) {
fs.removeSync(dirPath);
console.log(`Directory ${dirPath} was deleted.`);
} else {
console.log(`Directory ${dirPath} does not exist.`);
}
} catch (error) {
console.error(`Error while deleting ${dirPath}:`, error);
}
}
}

View File

@ -40,9 +40,10 @@ export class CommercialPropertyListingsController {
this.logger.info(`Save Listing`);
return await this.listingsService.updateListing(listing.id, listing, commercials);
}
@Delete(':id')
deleteById(@Param('id') id: string) {
@Delete(':id/:imagePath')
deleteById(@Param('id') id: string, @Param('imagePath') imagePath: string) {
this.listingsService.deleteListing(id, commercials);
this.fileService.deleteDirectoryIfExists(imagePath);
}
@Put('imageOrder/:id')

View File

@ -60,7 +60,7 @@
<div class="text-900 w-full md:w-10">{{ listing.brokerLicencing }}</div>
</li>
</ul>
@if(listing && listingUser && (listingUser.id===listing?.userId || isAdmin())){
@if(listing && listingUser && (listingUser?.email===user?.email || isAdmin())){
<button pButton pRipple label="Edit" icon="pi pi-file-edit" class="w-auto" [routerLink]="['/editBusinessListing', listing.id]"></button>
}
</div>

View File

@ -43,7 +43,7 @@
</li>
</ul>
@if(listing && listingUser && (listingUser.id===listing?.userId || isAdmin())){
@if(listing && listingUser && (listingUser?.email===user?.email || isAdmin())){
<button pButton pRipple label="Edit" icon="pi pi-file-edit" class="w-auto" [routerLink]="['/editCommercialPropertyListing', listing.id]"></button>
}
</div>

View File

@ -138,7 +138,7 @@
</ul>
</div>
</div>
@if( user?.id===(user$| async)?.id || isAdmin()){
@if( user?.email===(user$| async)?.email || isAdmin()){
<button pButton pRipple label="Edit" icon="pi pi-file-edit" class="w-auto" [routerLink]="['/account', user.id]"></button>
}
</div>

View File

@ -48,7 +48,7 @@ export class DetailsUserComponent {
async ngOnInit() {
this.user = await this.userService.getById(this.id);
this.user.email;
const results = await Promise.all([await this.listingsService.getListingByUserId(this.id, 'business'), await this.listingsService.getListingByUserId(this.id, 'commercialProperty')]);
// Zuweisen der Ergebnisse zu den Member-Variablen der Klasse
this.businessListings = results[0];

View File

@ -1,6 +1,6 @@
import { ChangeDetectorRef, Component } from '@angular/core';
import { ConfirmationService, MessageService } from 'primeng/api';
import { User } from '../../../../../../bizmatch-server/src/models/db.model';
import { CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
import { ListingType } from '../../../../../../bizmatch-server/src/models/main.model';
import { ListingsService } from '../../../services/listings.service';
import { SelectOptionsService } from '../../../services/select-options.service';
@ -36,7 +36,11 @@ export class MyListingComponent {
}
async deleteListing(listing: ListingType) {
await this.listingsService.deleteListing(listing.id, listing.listingsCategory);
if (listing.listingsCategory === 'business') {
await this.listingsService.deleteBusinessListing(listing.id);
} else {
await this.listingsService.deleteCommercialPropertyListing(listing.id, (<CommercialPropertyListing>listing).imagePath);
}
const result = await Promise.all([await this.listingsService.getListingByUserId(this.user.id, 'business'), await this.listingsService.getListingByUserId(this.user.id, 'commercialProperty')]);
this.myListings = [...result[0], ...result[1]];
}

View File

@ -22,7 +22,7 @@ export class HistoryService {
}
get canGoBack(): boolean {
return !!this.previousUrl;
return !!this.previousUrl || window.history.length > 2;
}
goBack(): void {

View File

@ -31,12 +31,16 @@ export class ListingsService {
}
}
async getAllStates(listingsCategory?: 'business' | 'commercialProperty'): Promise<StatesResult[]> {
const result = lastValueFrom(this.http.get<StatesResult[]>(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/states/all`));
const result = lastValueFrom(this.http.get<StatesResult[]>(`${this.apiBaseUrl}/bizmatch/listings/business/states/all`));
return result;
}
async deleteListing(id: string, listingsCategory: 'business' | 'professionals_brokers' | 'commercialProperty') {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/${id}`));
async deleteBusinessListing(id: string) {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/business/${id}`));
}
async deleteCommercialPropertyListing(id: string, imagePath: string) {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/commercialProperty/${id}/${imagePath}`));
}
async getPropertyImages(id: string): Promise<string[]> {
return await lastValueFrom(this.http.get<string[]>(`${this.apiBaseUrl}/bizmatch/image/${id}`));
}

View File

@ -1,6 +1,6 @@
// Build information, automatically generated by `the_build_script` :zwinkern:
const build = {
timestamp: 'NA',
timestamp: "GER: 16.05.2024 22:55 | TX: 05/16/2024 3:55 PM"
};
export default build;

View File

@ -1,18 +1,18 @@
@import "primeng/resources/primeng.css";
@import 'primeng/resources/primeng.css';
@import 'primeicons/primeicons.css';
// @import 'primeflex/primeflex.scss';
@import "primeflex/primeflex.css";
@import 'primeflex/primeflex.css';
@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');
@import "primeng/resources/themes/lara-light-blue/theme.css";
@import "@fortawesome/fontawesome-free/css/all.min.css";
@import 'primeng/resources/themes/lara-light-blue/theme.css';
@import '@fortawesome/fontawesome-free/css/all.min.css';
:root {
--text-color-secondary:rgba(255, 255, 255);
--wrapper-width:1491px;
--text-color-secondary: rgba(255, 255, 255);
--wrapper-width: 1491px;
// --secondary-color: #ffffff; /* Setzt die secondary Farbe auf weiß */
}
.p-button.p-button-secondary.p-button-outlined{
color: #ffffff;;
.p-button.p-button-secondary.p-button-outlined {
color: #ffffff;
}
html,
body,
@ -35,7 +35,11 @@ h6 {
margin: 0;
}
body, input, button, select, textarea {
body,
input,
button,
select,
textarea {
// font-family: 'Open Sans', sans-serif;
font-family: var(--font-family);
-webkit-font-smoothing: antialiased;
@ -71,8 +75,11 @@ p-menubarsub ul {
height: 100%;
margin: auto;
}
.p-editor-container .ql-toolbar{
.p-editor-container .ql-toolbar {
background: #f9fafb;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
}
.p-dropdown-panel .p-dropdown-header .p-dropdown-filter {
margin-right: 0 !important;
}

View File

@ -3,9 +3,11 @@ const fs = require('fs');
const dayjs = require('dayjs');
const timezone = require('dayjs/plugin/timezone');
const utc = require('dayjs/plugin/utc');
var localizedFormat = require('dayjs/plugin/localizedFormat');
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(localizedFormat);
const write = (content, path) => {
const writePath = path || `${process.cwd()}/src/build.ts`;
@ -23,7 +25,10 @@ const package = require(`${process.cwd()}/package.json`);
console.log('start build.js script ...');
// Generate `build` object
const build = {};
build.timestamp = dayjs(new Date()).utc().format('DD.MM.YYYY HH:mm') + ' UTC';
const acDate = new Date();
const german = dayjs(acDate).tz('Europe/Berlin').format('DD.MM.YYYY HH:mm');
const texan = dayjs(acDate).tz('America/Chicago').format('L LT');
build.timestamp = `GER: ${german} | TX: ${texan}`;
// Write Build information to file
write(build);
console.log('build.js script finished ...');