first validation
This commit is contained in:
parent
782c254a33
commit
747435bfba
|
|
@ -1,13 +1,12 @@
|
|||
import { Body, Controller, Post } from '@nestjs/common';
|
||||
import { User } from 'src/models/db.model.js';
|
||||
import { MailInfo } from 'src/models/main.model.js';
|
||||
import { ErrorResponse, MailInfo } from 'src/models/main.model.js';
|
||||
import { MailService } from './mail.service.js';
|
||||
|
||||
@Controller('mail')
|
||||
export class MailController {
|
||||
constructor(private mailService: MailService) {}
|
||||
@Post()
|
||||
sendEMail(@Body() mailInfo: MailInfo): Promise<User> {
|
||||
sendEMail(@Body() mailInfo: MailInfo): Promise<void | ErrorResponse> {
|
||||
return this.mailService.sendInquiry(mailInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import { MailerService } from '@nestjs-modules/mailer';
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import path, { join } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { User } from '../models/db.model.js';
|
||||
import { MailInfo } from '../models/main.model.js';
|
||||
import { ErrorResponse, MailInfo, isEmpty } from '../models/main.model.js';
|
||||
import { UserService } from '../user/user.service.js';
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
|
@ -15,10 +14,13 @@ export class MailService {
|
|||
private userService: UserService,
|
||||
) {}
|
||||
|
||||
async sendInquiry(mailInfo: MailInfo): Promise<User> {
|
||||
async sendInquiry(mailInfo: MailInfo): Promise<void | ErrorResponse> {
|
||||
//const user = await this.authService.getUser(mailInfo.userId) as KeycloakUser;
|
||||
const user = await this.userService.getUserByMail(mailInfo.email);
|
||||
console.log(JSON.stringify(user));
|
||||
if (isEmpty(mailInfo.sender.name)) {
|
||||
return { fields: [{ fieldname: 'name', message: 'Required' }] };
|
||||
}
|
||||
await this.mailerService.sendMail({
|
||||
to: user.email,
|
||||
from: '"Bizmatch Team" <info@bizmatch.net>', // override default from
|
||||
|
|
@ -38,6 +40,5 @@ export class MailService {
|
|||
url: mailInfo.url,
|
||||
},
|
||||
});
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,3 +165,42 @@ export interface ImageProperty {
|
|||
code: string;
|
||||
name: string;
|
||||
}
|
||||
export interface ErrorResponse {
|
||||
fields?: FieldError[];
|
||||
general?: string[];
|
||||
}
|
||||
export interface FieldError {
|
||||
fieldname: string;
|
||||
message: string;
|
||||
}
|
||||
export function isEmpty(value: any): boolean {
|
||||
// Check for undefined or null
|
||||
if (value === undefined || value === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for empty string or string with only whitespace
|
||||
if (typeof value === 'string') {
|
||||
return value.trim().length === 0;
|
||||
}
|
||||
|
||||
// Check for number and NaN
|
||||
if (typeof value === 'number') {
|
||||
return isNaN(value);
|
||||
}
|
||||
|
||||
// If it's not a string or number, it's not considered empty by this function
|
||||
return false;
|
||||
}
|
||||
export function emailToDirName(email: string): string {
|
||||
// Entferne ungültige Zeichen und ersetze sie durch Unterstriche
|
||||
const sanitizedEmail = email.replace(/[^a-zA-Z0-9_-]/g, '_');
|
||||
|
||||
// Entferne führende und nachfolgende Unterstriche
|
||||
const trimmedEmail = sanitizedEmail.replace(/^_+|_+$/g, '');
|
||||
|
||||
// Ersetze mehrfache aufeinanderfolgende Unterstriche durch einen einzelnen Unterstrich
|
||||
const normalizedEmail = trimmedEmail.replace(/_+/g, '_');
|
||||
|
||||
return normalizedEmail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,12 +90,14 @@
|
|||
<label for="notes" class="font-medium text-900">Questions/Comments</label>
|
||||
<textarea id="notes" pInputTextarea [autoResize]="true" [rows]="5" [(ngModel)]="mailinfo.sender.comments"></textarea>
|
||||
</div>
|
||||
@if(listingUser){
|
||||
<div class="surface-border mb-4 col-12 flex align-items-center">
|
||||
Listing by <a routerLink="/details-user/{{ listingUser.id }}" class="mr-2">{{ listingUser.firstname }} {{ listingUser.lastname }}</a>
|
||||
@if(listingUser.hasCompanyLogo){
|
||||
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listingUser.id }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="height: 30px; max-width: 100px" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<button pButton pRipple label="Submit" icon="pi pi-file" class="w-auto" (click)="mail()"></button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
<div class="grid formgrid p-fluid">
|
||||
<div class="field mb-4 col-12 md:col-6">
|
||||
<label for="name" class="font-medium text-900">Your Name</label>
|
||||
<input id="name" type="text" pInputText [(ngModel)]="mailinfo.sender.name" />
|
||||
<input [ngClass]="{ 'ng-invalid': containsError('name'), 'ng-dirty': containsError('name') }" id="name" type="text" pInputText [(ngModel)]="mailinfo.sender.name" />
|
||||
</div>
|
||||
<div class="field mb-4 col-12 md:col-6">
|
||||
<label for="email" class="font-medium text-900">Your Email</label>
|
||||
|
|
@ -80,12 +80,14 @@
|
|||
<label for="notes" class="font-medium text-900">Questions/Comments</label>
|
||||
<textarea id="notes" pInputTextarea [autoResize]="true" [rows]="5" [(ngModel)]="mailinfo.sender.comments"></textarea>
|
||||
</div>
|
||||
@if(listingUser){
|
||||
<div class="surface-border mb-4 col-12 flex align-items-center">
|
||||
Listing by <a routerLink="/details-user/{{ listingUser.id }}" class="mr-2">{{ listingUser.firstname }} {{ listingUser.lastname }}</a>
|
||||
@if(listingUser.hasCompanyLogo){
|
||||
<img src="{{ env.imageBaseUrl }}/pictures/logo/{{ listingUser.id }}.avif?_ts={{ ts }}" class="mr-5 lg:mb-0" style="height: 30px; max-width: 100px" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<button pButton pRipple label="Submit" icon="pi pi-file" class="w-auto" (click)="mail()"></button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { MessageService } from 'primeng/api';
|
|||
import { GalleriaModule } from 'primeng/galleria';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model';
|
||||
import { KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
|
||||
import { ErrorResponse, KeycloakUser, ListingCriteria, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { HistoryService } from '../../../services/history.service';
|
||||
import { ListingsService } from '../../../services/listings.service';
|
||||
|
|
@ -54,6 +54,7 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
description: SafeHtml;
|
||||
ts = new Date().getTime();
|
||||
env = environment;
|
||||
errorResponse: ErrorResponse;
|
||||
constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private listingsService: ListingsService,
|
||||
|
|
@ -85,7 +86,15 @@ export class DetailsCommercialPropertyListingComponent {
|
|||
this.mailinfo.email = this.listingUser.email;
|
||||
this.mailinfo.userId = this.listing.userId;
|
||||
this.mailinfo.listing = this.listing;
|
||||
await this.mailService.mail(this.mailinfo);
|
||||
this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Your message has been sent to the creator of the listing', life: 3000 });
|
||||
const result = await this.mailService.mail(this.mailinfo);
|
||||
if (result) {
|
||||
this.errorResponse = result as ErrorResponse;
|
||||
} else {
|
||||
this.errorResponse = null;
|
||||
this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Your message has been sent to the creator of the listing', life: 3000 });
|
||||
}
|
||||
}
|
||||
containsError(fieldname: string) {
|
||||
return this.errorResponse?.fields.map(f => f.fieldname).includes(fieldname);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { MailInfo } from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { ErrorResponse, MailInfo } from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class MailService {
|
||||
|
||||
private apiBaseUrl = environment.apiBaseUrl;
|
||||
constructor(private http: HttpClient) { }
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
async mail(mailinfo:MailInfo):Promise<void>{
|
||||
await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/mail`,mailinfo));
|
||||
async mail(mailinfo: MailInfo): Promise<void | ErrorResponse> {
|
||||
return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/mail`, mailinfo));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue