add phone & company name

This commit is contained in:
Andreas Knuth 2025-03-19 12:56:34 +01:00
parent e7cadb6df8
commit fcdd98c9ca
4 changed files with 83 additions and 17 deletions

View File

@ -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);
} }
} }

View File

@ -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
}, },
}); });

View File

@ -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>

View File

@ -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">
&#8505;
</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">
&#8505;
</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();