add phone & company name
This commit is contained in:
parent
e7cadb6df8
commit
fcdd98c9ca
|
|
@ -10,7 +10,13 @@ export class AppController {
|
||||||
return { message: 'API is alive' };
|
return { message: 'API is alive' };
|
||||||
}
|
}
|
||||||
@Post()
|
@Post()
|
||||||
async sendEMail(@Body() mailInfo: {name:string,email:string,message:string}): Promise<void> {
|
async sendEMail(@Body() mailInfo: {
|
||||||
|
name: string,
|
||||||
|
email: string,
|
||||||
|
phone?: string,
|
||||||
|
company?: string,
|
||||||
|
message: string
|
||||||
|
}): Promise<void> {
|
||||||
return await this.appService.sendMail(mailInfo);
|
return await this.appService.sendMail(mailInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,18 +1,38 @@
|
||||||
|
|
||||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
import { MailerService } from '@nestjs-modules/mailer';
|
import { MailerService } from '@nestjs-modules/mailer';
|
||||||
import { z,ZodError } from 'zod';
|
import { z, ZodError } from 'zod';
|
||||||
|
|
||||||
export const SenderSchema = z.object({
|
export const SenderSchema = z.object({
|
||||||
name: z.string().min(6, { message: 'Name must be at least 6 characters long' }),
|
name: z.string().min(6, { message: 'Name must be at least 6 characters long' }),
|
||||||
email: z.string().email({ message: 'Invalid email address' }),
|
email: z.string().email({ message: 'Invalid email address' }),
|
||||||
|
phone: z.string()
|
||||||
|
.optional()
|
||||||
|
.refine(
|
||||||
|
(val) => {
|
||||||
|
if (!val) return true; // If no phone number provided, validation passes
|
||||||
|
// Validate US phone number format (various formats supported)
|
||||||
|
const usPhoneRegex = /^(\+?1\s?)?(\(\d{3}\)|\d{3})[\s.-]?\d{3}[\s.-]?\d{4}$/;
|
||||||
|
return usPhoneRegex.test(val);
|
||||||
|
},
|
||||||
|
{ message: 'Please enter a valid US phone number' }
|
||||||
|
),
|
||||||
|
company: z.string().optional(), // Company is optional
|
||||||
message: z.string().min(10, { message: 'Comments must be at least 10 characters long' }),
|
message: z.string().min(10, { message: 'Comments must be at least 10 characters long' }),
|
||||||
});
|
});
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService {
|
||||||
constructor(
|
constructor(
|
||||||
private mailerService: MailerService,
|
private mailerService: MailerService,
|
||||||
) {}
|
) {}
|
||||||
async sendMail(mailInfo: {name:string,email:string,message:string}): Promise<void> {
|
|
||||||
|
async sendMail(mailInfo: {
|
||||||
|
name: string,
|
||||||
|
email: string,
|
||||||
|
phone?: string, // Mark as optional with ?
|
||||||
|
company?: string, // Mark as optional with ?
|
||||||
|
message: string
|
||||||
|
}): Promise<void> {
|
||||||
try {
|
try {
|
||||||
SenderSchema.parse(mailInfo);
|
SenderSchema.parse(mailInfo);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -25,6 +45,7 @@ export class AppService {
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.mailerService.sendMail({
|
await this.mailerService.sendMail({
|
||||||
to: 'andreas.knuth@gmail.com',
|
to: 'andreas.knuth@gmail.com',
|
||||||
from: `"Bay Area Affiliates, Inc." <bayarea@bizmatch.net>`,
|
from: `"Bay Area Affiliates, Inc." <bayarea@bizmatch.net>`,
|
||||||
|
|
@ -33,6 +54,8 @@ export class AppService {
|
||||||
context: {
|
context: {
|
||||||
name: mailInfo.name,
|
name: mailInfo.name,
|
||||||
email: mailInfo.email,
|
email: mailInfo.email,
|
||||||
|
phone: mailInfo.phone || 'Not provided',
|
||||||
|
company: mailInfo.company || 'Not provided',
|
||||||
message: mailInfo.message
|
message: mailInfo.message
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Neue Nachricht von {{name}}</title>
|
<title>New message from {{name}}</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
|
|
@ -41,6 +41,8 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p><strong>Name:</strong> {{name}}</p>
|
<p><strong>Name:</strong> {{name}}</p>
|
||||||
<p><strong>Email:</strong> {{email}}</p>
|
<p><strong>Email:</strong> {{email}}</p>
|
||||||
|
<p><strong>Phone:</strong> {{phone}}</p>
|
||||||
|
<p><strong>Company:</strong> {{company}}</p>
|
||||||
<p><strong>Message:</strong></p>
|
<p><strong>Message:</strong></p>
|
||||||
<p>{{message}}</p>
|
<p>{{message}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,10 @@ interface ErrorResponse {
|
||||||
<p class="mt-4 text-center text-gray-600">We're here to help you with all your IT needs.</p>
|
<p class="mt-4 text-center text-gray-600">We're here to help you with all your IT needs.</p>
|
||||||
<div class="mt-12 max-w-lg mx-auto">
|
<div class="mt-12 max-w-lg mx-auto">
|
||||||
<form (ngSubmit)="onSubmit()" class="bg-white p-8 rounded-lg shadow" data-aos="fade-up">
|
<form (ngSubmit)="onSubmit()" class="bg-white p-8 rounded-lg shadow" data-aos="fade-up">
|
||||||
|
<p class="text-sm text-gray-500 mb-4">Fields marked with <span class="text-red-600">*</span> are required</p>
|
||||||
<div class="mb-4 relative">
|
<div class="mb-4 relative">
|
||||||
<label class="block text-gray-700 flex items-center">
|
<label class="block text-gray-700 flex items-center">
|
||||||
Name
|
Name <span class="text-red-600 ml-1">*</span>
|
||||||
<span *ngIf="errors.name" class="ml-2 text-red-600 cursor-pointer"
|
<span *ngIf="errors.name" class="ml-2 text-red-600 cursor-pointer"
|
||||||
[title]="errors.name"
|
[title]="errors.name"
|
||||||
data-tooltip-target="tooltip-name">
|
data-tooltip-target="tooltip-name">
|
||||||
|
|
@ -46,7 +47,7 @@ interface ErrorResponse {
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 relative">
|
<div class="mb-4 relative">
|
||||||
<label class="block text-gray-700 flex items-center">
|
<label class="block text-gray-700 flex items-center">
|
||||||
Email
|
Email <span class="text-red-600 ml-1">*</span>
|
||||||
<span *ngIf="errors.email" class="ml-2 text-red-600 cursor-pointer"
|
<span *ngIf="errors.email" class="ml-2 text-red-600 cursor-pointer"
|
||||||
[title]="errors.email"
|
[title]="errors.email"
|
||||||
data-tooltip-target="tooltip-email">
|
data-tooltip-target="tooltip-email">
|
||||||
|
|
@ -63,7 +64,39 @@ interface ErrorResponse {
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 relative">
|
<div class="mb-4 relative">
|
||||||
<label class="block text-gray-700 flex items-center">
|
<label class="block text-gray-700 flex items-center">
|
||||||
Message
|
Phone <span class="text-gray-400 text-sm ml-1">(optional)</span>
|
||||||
|
<span *ngIf="errors.phone" class="ml-2 text-red-600 cursor-pointer"
|
||||||
|
[title]="errors.phone"
|
||||||
|
data-tooltip-target="tooltip-phone">
|
||||||
|
ℹ
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
name="phone"
|
||||||
|
[(ngModel)]="formData.phone"
|
||||||
|
class="w-full mt-2 p-3 border rounded"
|
||||||
|
placeholder="Your Phone Number">
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 relative">
|
||||||
|
<label class="block text-gray-700 flex items-center">
|
||||||
|
Company <span class="text-gray-400 text-sm ml-1">(optional)</span>
|
||||||
|
<span *ngIf="errors.company" class="ml-2 text-red-600 cursor-pointer"
|
||||||
|
[title]="errors.company"
|
||||||
|
data-tooltip-target="tooltip-company">
|
||||||
|
ℹ
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="company"
|
||||||
|
[(ngModel)]="formData.company"
|
||||||
|
class="w-full mt-2 p-3 border rounded"
|
||||||
|
placeholder="Your Company Name">
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 relative">
|
||||||
|
<label class="block text-gray-700 flex items-center">
|
||||||
|
Message <span class="text-red-600 ml-1">*</span>
|
||||||
<span *ngIf="errors.message" class="ml-2 text-red-600 cursor-pointer"
|
<span *ngIf="errors.message" class="ml-2 text-red-600 cursor-pointer"
|
||||||
[title]="errors.message"
|
[title]="errors.message"
|
||||||
data-tooltip-target="tooltip-message">
|
data-tooltip-target="tooltip-message">
|
||||||
|
|
@ -95,10 +128,12 @@ export class ContactComponent {
|
||||||
formData = {
|
formData = {
|
||||||
name: '',
|
name: '',
|
||||||
email: '',
|
email: '',
|
||||||
|
phone: '',
|
||||||
|
company: '',
|
||||||
message: '',
|
message: '',
|
||||||
};
|
};
|
||||||
//errors: { [key: string]: string } = {};
|
// Update the errors type to include the new fields
|
||||||
errors: { name?: string, email?:string, message?:string } = {};
|
errors: { name?: string, email?: string, phone?: string, company?: string, message?: string } = {};
|
||||||
|
|
||||||
constructor(private http: HttpClient, private overlayService: OverlayService) {}
|
constructor(private http: HttpClient, private overlayService: OverlayService) {}
|
||||||
|
|
||||||
|
|
@ -108,7 +143,7 @@ export class ContactComponent {
|
||||||
try {
|
try {
|
||||||
await lastValueFrom(this.http.post(`${this.apiBaseUrl}/api`, this.formData));
|
await lastValueFrom(this.http.post(`${this.apiBaseUrl}/api`, this.formData));
|
||||||
this.overlayService.showSuccess();
|
this.overlayService.showSuccess();
|
||||||
this.formData = { name: '', email: '', message: '' }; // Formular zurücksetzen
|
this.formData = { name: '', email: '', phone: '', company: '', message: '' }; // Reset form
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof HttpErrorResponse && error.status === 400) {
|
if (error instanceof HttpErrorResponse && error.status === 400) {
|
||||||
const errorResponse = error.error as ErrorResponse;
|
const errorResponse = error.error as ErrorResponse;
|
||||||
|
|
@ -116,8 +151,8 @@ export class ContactComponent {
|
||||||
this.errors[err.field] = err.message;
|
this.errors[err.field] = err.message;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Allgemeine Fehlerbehandlung
|
// General error handling
|
||||||
console.error('Ein unerwarteter Fehler ist aufgetreten:', error);
|
console.error('An unexpected error occurred:', error);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.overlayService.hideLoading();
|
this.overlayService.hideLoading();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue