Add board-specific welcome email template and logic
Build And Push Image / docker (push) Successful in 1m43s
Details
Build And Push Image / docker (push) Successful in 1m43s
Details
- Create separate welcome email template for board members - Add conditional logic to use board template based on membership tier - Update email service to support sendWelcomeBoardEmail method - Include board-specific subject line and template preloading
This commit is contained in:
parent
1ab45cf503
commit
400f9cdd52
|
|
@ -135,7 +135,7 @@ export default defineEventHandler(async (event) => {
|
|||
const config = useRuntimeConfig();
|
||||
const verificationLink = `https://portal.monacousa.org/auth/verify?token=${verificationToken}`;
|
||||
|
||||
await emailService.sendWelcomeEmail(member.email, {
|
||||
const emailData = {
|
||||
firstName: member.first_name,
|
||||
lastName: member.last_name,
|
||||
verificationLink,
|
||||
|
|
@ -145,10 +145,19 @@ export default defineEventHandler(async (event) => {
|
|||
month: 'long',
|
||||
day: 'numeric'
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
// Use appropriate email template based on membership tier
|
||||
if (membershipTier === 'board') {
|
||||
console.log('[api/members/[id]/create-portal-account.post] Sending board-specific welcome email');
|
||||
await emailService.sendWelcomeBoardEmail(member.email, emailData);
|
||||
} else {
|
||||
console.log('[api/members/[id]/create-portal-account.post] Sending standard welcome email');
|
||||
await emailService.sendWelcomeEmail(member.email, emailData);
|
||||
}
|
||||
|
||||
emailSent = true;
|
||||
console.log('[api/members/[id]/create-portal-account.post] Welcome email sent successfully');
|
||||
console.log(`[api/members/[id]/create-portal-account.post] Welcome email sent successfully (${membershipTier} template)`);
|
||||
} catch (error: any) {
|
||||
emailError = error.message || 'Unknown email error';
|
||||
console.error('[api/members/[id]/create-portal-account.post] Failed to send welcome email:', emailError);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,311 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Welcome to the MonacoUSA Board Portal</title>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;">
|
||||
<!-- Main Container -->
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color: #f4f4f4; padding: 20px 0;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<!-- Email Container -->
|
||||
<table width="600" cellpadding="0" cellspacing="0" border="0" style="background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.1);">
|
||||
|
||||
<!-- Header with Monaco Red Background -->
|
||||
<tr>
|
||||
<td style="background-color: #a31515; padding: 30px; text-align: center;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="{{logoUrl}}" alt="MonacoUSA" width="80" height="80" style="border-radius: 8px; margin-bottom: 15px;">
|
||||
<h1 style="color: #ffffff; font-size: 28px; font-weight: bold; margin: 0 0 8px 0;">Welcome to the Board Portal</h1>
|
||||
<p style="color: #ffffff; font-size: 16px; margin: 0; opacity: 0.9;">Monaco - United States Association</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Main Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 30px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
|
||||
<!-- Greeting -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 20px;">
|
||||
<h2 style="color: #a31515; font-size: 20px; font-weight: bold; margin: 0;">Dear Board Member {{firstName}} {{lastName}},</h2>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Welcome Message -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 30px;">
|
||||
<p style="color: #333333; font-size: 16px; line-height: 1.6; margin: 0;">
|
||||
Your <strong>MonacoUSA Board Portal</strong> account has been successfully created!
|
||||
Welcome to the board management system where you have special access to oversee association operations, manage members, and coordinate board activities.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Board Access Success Box -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 30px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color: #f8f9fa; border: 1px solid #e9ecef; border-radius: 6px;">
|
||||
<tr>
|
||||
<td style="padding: 25px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td style="text-align: center; padding-bottom: 15px;">
|
||||
<span style="background-color: #6f42c1; color: #ffffff; padding: 8px 16px; border-radius: 20px; font-weight: bold; font-size: 14px;">👑 Board Access Granted</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="50%" style="vertical-align: top; padding-right: 10px;">
|
||||
<p style="margin: 0 0 8px 0; color: #333333; font-weight: bold;">Member ID:</p>
|
||||
<p style="margin: 0; color: #a31515; font-weight: bold; font-size: 18px;">{{memberId}}</p>
|
||||
</td>
|
||||
<td width="50%" style="vertical-align: top; padding-left: 10px;">
|
||||
<p style="margin: 0 0 8px 0; color: #333333; font-weight: bold;">Portal Access Level:</p>
|
||||
<p style="margin: 0; color: #6f42c1; font-size: 16px; font-weight: bold;">Board Member</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-top: 15px;">
|
||||
<p style="margin: 0; color: #666666; font-size: 14px;">
|
||||
You have access to board-specific tools including member management, event oversight, and administrative functions.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Next Step: Verify Email -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 30px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td style="background-color: #e3f2fd; border-left: 4px solid #2196f3; padding: 20px; border-radius: 4px;">
|
||||
<h3 style="color: #1976d2; font-size: 18px; font-weight: bold; margin: 0 0 10px 0;">📧 Next Step: Verify Your Email</h3>
|
||||
<p style="color: #333333; font-size: 16px; line-height: 1.6; margin: 0 0 15px 0;">
|
||||
To activate your board portal access and secure your account, please verify your email address by clicking the button below:
|
||||
</p>
|
||||
<table cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td style="text-align: center; padding: 15px 0;">
|
||||
<a href="{{verificationLink}}" style="background-color: #a31515; color: #ffffff; text-decoration: none; padding: 15px 30px; border-radius: 6px; font-weight: bold; font-size: 16px; display: inline-block;">
|
||||
✉️ Verify Email Address
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="color: #666666; font-size: 14px; font-style: italic; margin: 15px 0 0 0;">
|
||||
This verification link will expire in 24 hours for security purposes.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Board-Specific Features -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 30px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td style="background-color: #f3e5f5; border-left: 4px solid #9c27b0; padding: 20px; border-radius: 4px;">
|
||||
<h3 style="color: #7b1fa2; font-size: 18px; font-weight: bold; margin: 0 0 10px 0;">🛡️ Your Board Access Includes</h3>
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="50%" style="vertical-align: top; padding-right: 15px;">
|
||||
<p style="margin: 0 0 8px 0; color: #333333; font-weight: bold;">👥 Member Management</p>
|
||||
<p style="margin: 0 0 15px 0; color: #333333; font-size: 14px;">View, edit, and manage all association members</p>
|
||||
|
||||
<p style="margin: 0 0 8px 0; color: #333333; font-weight: bold;">📅 Event Management</p>
|
||||
<p style="margin: 0 0 15px 0; color: #333333; font-size: 14px;">Create, edit, and manage association events</p>
|
||||
</td>
|
||||
<td width="50%" style="vertical-align: top; padding-left: 15px;">
|
||||
<p style="margin: 0 0 8px 0; color: #333333; font-weight: bold;">📊 Board Dashboard</p>
|
||||
<p style="margin: 0 0 15px 0; color: #333333; font-size: 14px;">Access board-specific statistics and insights</p>
|
||||
|
||||
<p style="margin: 0 0 8px 0; color: #333333; font-weight: bold;">💼 Portal Accounts</p>
|
||||
<p style="margin: 0 0 15px 0; color: #333333; font-size: 14px;">Create and manage member portal accounts</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="color: #666666; font-size: 14px; font-style: italic; margin: 15px 0 0 0;">
|
||||
These features will be available immediately after email verification.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- What's Next for Board Members -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 30px;">
|
||||
<h3 style="color: #a31515; font-size: 18px; font-weight: bold; margin: 0 0 15px 0;">⭐ Board Member Next Steps</h3>
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td style="padding: 5px 0; border-bottom: 1px solid #eeeeee;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="30" style="vertical-align: top; padding-right: 10px;">
|
||||
<span style="background-color: #a31515; color: #ffffff; border-radius: 50%; width: 24px; height: 24px; display: inline-block; text-align: center; line-height: 24px; font-weight: bold; font-size: 14px;">1</span>
|
||||
</td>
|
||||
<td>
|
||||
<p style="margin: 0; color: #333333; font-size: 16px;">
|
||||
<strong>Verify your email</strong> using the button above
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px 0; border-bottom: 1px solid #eeeeee;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="30" style="vertical-align: top; padding-right: 10px;">
|
||||
<span style="background-color: #a31515; color: #ffffff; border-radius: 50%; width: 24px; height: 24px; display: inline-block; text-align: center; line-height: 24px; font-weight: bold; font-size: 14px;">2</span>
|
||||
</td>
|
||||
<td>
|
||||
<p style="margin: 0; color: #333333; font-size: 16px;">
|
||||
<strong>Access the board portal</strong> at portal.monacousa.org/dashboard/board
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px 0; border-bottom: 1px solid #eeeeee;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="30" style="vertical-align: top; padding-right: 10px;">
|
||||
<span style="background-color: #a31515; color: #ffffff; border-radius: 50%; width: 24px; height: 24px; display: inline-block; text-align: center; line-height: 24px; font-weight: bold; font-size: 14px;">3</span>
|
||||
</td>
|
||||
<td>
|
||||
<p style="margin: 0; color: #333333; font-size: 16px;">
|
||||
<strong>Review board dashboard</strong> and familiarize yourself with your tools
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px 0;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td width="30" style="vertical-align: top; padding-right: 10px;">
|
||||
<span style="background-color: #a31515; color: #ffffff; border-radius: 50%; width: 24px; height: 24px; display: inline-block; text-align: center; line-height: 24px; font-weight: bold; font-size: 14px;">4</span>
|
||||
</td>
|
||||
<td>
|
||||
<p style="margin: 0; color: #333333; font-size: 16px;">
|
||||
<strong>Begin managing</strong> members, events, and association operations
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Board Support Information -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 30px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td style="background-color: #e8f5e8; border-left: 4px solid #4caf50; padding: 20px; border-radius: 4px;">
|
||||
<h3 style="color: #2e7d32; font-size: 18px; font-weight: bold; margin: 0 0 10px 0;">📞 Board Member Support</h3>
|
||||
<p style="color: #333333; font-size: 16px; line-height: 1.6; margin: 0 0 15px 0;">
|
||||
As a board member, you have priority support for any technical questions or assistance needed with the portal.
|
||||
</p>
|
||||
<p style="color: #333333; font-size: 16px; line-height: 1.6; margin: 0;">
|
||||
For board-specific support, please contact: <strong>board@monacousa.org</strong>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Help Message -->
|
||||
<tr>
|
||||
<td style="padding-bottom: 20px;">
|
||||
<p style="color: #333333; font-size: 16px; line-height: 1.6; margin: 0;">
|
||||
Thank you for your service to the MonacoUSA Association. Your board access enables you to help guide our community and manage our operations effectively.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td style="background-color: #f8f9fa; padding: 30px; text-align: center; border-top: 1px solid #e9ecef;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<h4 style="color: #333333; font-size: 18px; font-weight: bold; margin: 0 0 8px 0;">MonacoUSA Association</h4>
|
||||
<p style="color: #666666; font-size: 14px; margin: 0 0 15px 0;">Board Portal Access</p>
|
||||
|
||||
<!-- Links -->
|
||||
<table cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td style="padding: 0 10px;">
|
||||
<a href="https://portal.monacousa.org/dashboard/board" style="color: #a31515; text-decoration: none; font-size: 14px;">Board Portal</a>
|
||||
</td>
|
||||
<td style="padding: 0 10px; color: #cccccc;">|</td>
|
||||
<td style="padding: 0 10px;">
|
||||
<a href="mailto:board@monacousa.org" style="color: #a31515; text-decoration: none; font-size: 14px;">Board Support</a>
|
||||
</td>
|
||||
<td style="padding: 0 10px; color: #cccccc;">|</td>
|
||||
<td style="padding: 0 10px;">
|
||||
<a href="https://monacousa.org" style="color: #a31515; text-decoration: none; font-size: 14px;">Website</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Email Info -->
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin-top: 20px;">
|
||||
<tr>
|
||||
<td style="padding-top: 15px; border-top: 1px solid #dddddd;">
|
||||
<p style="color: #999999; font-size: 12px; margin: 0;">
|
||||
This email was sent to <strong>{{email}}</strong> regarding your MonacoUSA Board Portal access.<br>
|
||||
If you did not expect this email, please contact board@monacousa.org immediately.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -152,7 +152,7 @@ export class EmailService {
|
|||
* Preload and compile email templates
|
||||
*/
|
||||
private preloadTemplates(): void {
|
||||
const templateNames = ['welcome', 'verification', 'password-reset', 'dues-reminder', 'test'];
|
||||
const templateNames = ['welcome', 'welcome-board', 'verification', 'password-reset', 'dues-reminder', 'test'];
|
||||
|
||||
templateNames.forEach(templateName => {
|
||||
try {
|
||||
|
|
@ -263,6 +263,39 @@ export class EmailService {
|
|||
console.log(`[EmailService] ✅ Welcome email sent to ${to}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send welcome/verification email to new board members
|
||||
*/
|
||||
async sendWelcomeBoardEmail(to: string, data: WelcomeEmailData): Promise<void> {
|
||||
const template = this.getTemplate('welcome-board');
|
||||
if (!template) {
|
||||
console.error('[EmailService] ❌ Board welcome email template not found! Available templates:', Array.from(this.templates.keys()));
|
||||
throw new Error('Board welcome email template not found');
|
||||
}
|
||||
|
||||
const config = useRuntimeConfig();
|
||||
const templateData = {
|
||||
...data,
|
||||
logoUrl: data.logoUrl || 'https://portal.monacousa.org/MONACOUSA-Flags_376x376.png',
|
||||
baseUrl: config.public.domain || 'https://portal.monacousa.org',
|
||||
email: data.email || to
|
||||
};
|
||||
|
||||
console.log('[EmailService] Board template data:', templateData);
|
||||
|
||||
const html = template(templateData);
|
||||
console.log('[EmailService] Generated board HTML length:', html.length);
|
||||
console.log('[EmailService] Board HTML preview (first 200 chars):', html.substring(0, 200));
|
||||
|
||||
await this.sendEmail({
|
||||
to,
|
||||
subject: 'Welcome to the MonacoUSA Board Portal - Please Verify Your Email',
|
||||
html
|
||||
});
|
||||
|
||||
console.log(`[EmailService] ✅ Board welcome email sent to ${to}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email verification email
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue