UIAngular/Server/src/routes/api/vbs.js

327 lines
11 KiB
JavaScript

var express = require('express');
var router = express.Router();
const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
host: 'smtp.ionos.com',
port: 587,
secure: false,
auth:{
user: 'mail@ofbbutte.com',
pass: '@2014OfbPwd'
}
});
router.get("/",function(req,res){
res.status(200).json({"message":"Hello World"});
return;
});
router.post("/", function(req,res){
console.log(req.body);
//This is the honeypot field
//If it has something in it then we know it was filled out by a bot
if (!req.body.hp || req.body.hp != '.'){
res.status(200).json({"status":200,"message":"Success!"});
return;
}
let mailOptions = {
from: 'donotreply@ofbbutte.com',
to: 'djabsher@gmail.com',
subject: 'OFB - VBS Registration - ' + req.body.firstName,
html: generateRegistrationEmailHTML(req.body)
};
let mailOptions2 = {
from: 'donotreply@ofbbutte.com',
to: req.body.parentEmail,
subject: 'OFB - Vaction Bible School Registration',
html: generateVbsConfirmationEmail(req.body.firstName, req.body.parentFirstName)
}
transporter.sendMail(mailOptions,(error, info) =>{
if (error){
console.log(error);
res.status(400).json({"status":400,"message":"There was an error","error":error.response});
} else {
transporter.sendMail(mailOptions2, (error, into) => {
res.status(200).json({"status":200,"message":"Success"});
});
}
});
});
/**
* Generates a sectioned HTML email string for the registration form.
* Displays all fields even if they are empty.
* @param {Object} data - The value object from this.form.value
* @returns {string} Ready-to-send HTML string
*/
function generateRegistrationEmailHTML(data) {
// Helper to cleanly format boolean true/false fields
const formatBool = (val) => {
if (val === true || val === 'true') return 'Yes';
if (val === false || val === 'false') return 'No';
return val;
};
// Helper to ensure we don't render literal 'null' or 'undefined' text
const sanitizeValue = (val) => {
if (val === null || val === undefined) return '';
return String(val).trim();
};
const formatDate = (dateString) => {
try {
if (!dateString || typeof dateString !== "string") {
throw new Error("Invalid date string.");
}
const [date] = dateString.split("T");
const [year, month, day] = date.split("-");
if (!year || !month || !day) {
throw new Error("Invalid date format.");
}
return `${month}/${day}/${year}`;
} catch (error) {
console.error("Error formatting date:", error.message);
return dateString;
}
}
// Define the layout sections and human-readable labels
const sections = [
{
title: "Student Information",
fields: [
{ label: "Student Name", value: `${sanitizeValue(data.firstName)} ${sanitizeValue(data.lastName)}`.trim() },
{ label: "Grade", value: sanitizeValue(data.grade) },
{ label: "Date of Birth", value: formatDate(sanitizeValue(data.dob)) },
{ label: "Has Allergies?", value: sanitizeValue(formatBool(data.hasAllergies)) },
{ label: "Allergies", value: sanitizeValue(data.allergies) },
{ label: "Has Dietary Restrictions?", value: sanitizeValue(formatBool(data.hasDietaryRestrictions)) },
{ label: "Dietary Restrictions", value: sanitizeValue(data.dietaryRestrictions) },
{ label: "Attended in Past?", value: sanitizeValue(formatBool(data.attendedInPast)) },
{ label: "Rides Bus?", value: sanitizeValue(formatBool(data.ridesBus)) }
]
},
{
title: "Parent / Guardian Information",
fields: [
{ label: "Parent Name", value: `${sanitizeValue(data.parentFirstName)} ${sanitizeValue(data.parentLastName)}`.trim() },
{ label: "Email", value: sanitizeValue(data.parentEmail) },
{ label: "Mobile Phone", value: sanitizeValue(data.parentMobilePhone) },
{ label: "Home Phone", value: sanitizeValue(data.parentHomePhone) },
{ label: "Work Phone", value: sanitizeValue(data.parentWorkPhone) },
{ label: "Address", value: `${sanitizeValue(data.address1)}${data.address2 ? ', ' + sanitizeValue(data.address2) : ''}, ${sanitizeValue(data.city)}, ${sanitizeValue(data.state)} ${sanitizeValue(data.zip)}`.trim().replace(/^,|,$/g, '') }
]
},
{
title: "Emergency Contact",
fields: [
{ label: "Same as Parent?", value: sanitizeValue(formatBool(data.emergencySameAsParent)) },
{ label: "Emergency Name", value: `${sanitizeValue(data.emergencyFirstName)} ${sanitizeValue(data.emergencyLastName)}`.trim() },
{ label: "Emergency Phone", value: sanitizeValue(data.emergencyPhone) },
{ label: "Notes", value: sanitizeValue(data.notes) }
]
}
];
// Map the sections array into HTML tables (No filtering out fields!)
const htmlContent = sections.map(section => {
const rows = section.fields.map(field => `
<tr>
<td style="padding: 10px 12px; border-bottom: 1px solid #edf2f7; font-weight: 600; color: #4a5568; width: 35%; font-size: 14px;">
${field.label}
</td>
<td style="padding: 10px 12px; border-bottom: 1px solid #edf2f7; color: #2d3748; font-size: 14px;">
${field.value}
</td>
</tr>
`).join('');
return `
<h3 style="color: #4f46e5; font-size: 16px; margin-top: 24px; margin-bottom: 10px; border-bottom: 2px solid #e2e8f0; padding-bottom: 6px; font-weight: 600;">
${section.title}
</h3>
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; margin-bottom: 15px;">
<tbody>
${rows}
</tbody>
</table>
`;
}).join('');
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vacation Bible School Registration</title>
</head>
<body style="margin: 0; padding: 0; background-color: #f7fafc; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f7fafc; padding: 24px 0;">
<tr>
<td align="center">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 650px; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 6px rgba(0,0,0,0.05); border: 1px solid #e2e8f0;">
<!-- Header Banner -->
<tr>
<td style="background-color: rgb(0, 188, 212); padding: 24px; text-align: center;">
<h1 style="color: #ffffff; margin: 0; font-size: 20px; font-weight: 600; letter-spacing: 0.5px;">
Vacation Bible School Registration
</h1>
</td>
</tr>
<!-- Content Body -->
<tr>
<td style="padding: 24px 32px;">
<p style="margin-top: 0; margin-bottom: 16px; font-size: 15px; color: #718096; line-height: 1.5;">
</p>
${htmlContent}
</td>
</tr>
<!-- Footer -->
<tr>
<td style="background-color: #f8fafc; padding: 20px; text-align: center; font-size: 12px; color: #a0aec0; border-top: 1px solid #edf2f7;">
Old Fashion Baptist Church Vacation Bible School Registration
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
`;
}
function generateVbsConfirmationEmail(studentName, parentName) {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
color: #333;
}
.container {
max-width: 650px;
margin: auto;
background: #ffffff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,.1);
}
.header {
background-color: rgb(0, 188, 212);
color: white;
text-align: center;
padding: 25px;
}
.content {
padding: 30px;
}
.info-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.info-table td {
padding: 10px;
border-bottom: 1px solid #ddd;
vertical-align: top;
}
.label {
font-weight: bold;
width: 140px;
color: #2c5aa0;
}
.footer {
text-align: center;
background: #f8f8f8;
padding: 20px;
font-size: 14px;
color: #666;
}
.highlight {
color: #2c5aa0;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Vacation Bible School Registration</h1>
</div>
<div class="content">
<p>
<span class="highlight">${studentName}</span>
has been registered for
<strong>Vacation Bible School!</strong>
</p>
<p>We look forward to having ${studentName} join us for Bible lessons, games, snacks, and prizes!</p>
<h2>Vacation Bible School Information</h2>
<table class="info-table">
<tr>
<td class="label">Ages</td>
<td>4 - 12 years old</td>
</tr>
<tr>
<td class="label">Dates</td>
<td>August 10 - 13</td>
</tr>
<tr>
<td class="label">Time</td>
<td>6:30 PM - 8:00 PM</td>
</tr>
<tr>
<td class="label">Location</td>
<td>
Old Fashion Baptist Church<br>
5003 Wynne Ave<br>
Butte, MT
</td>
</tr>
<tr>
<td class="label">Contact</td>
<td>(406) 494-5028</td>
</tr>
</table>
<p style="margin-top:25px;">
If you have any questions, please don't hesitate to contact us.
</p>
</div>
<div class="footer">
Old Fashion Baptist Church<br>
</div>
</div>
</body>
</html>
`;
}
module.exports = router;