feat: echo submitted message back in confirmation email
Task #18 — Send a copy of the submitted message back to the contact in the confirmation email. Changes made to artifacts/api-server/src/routes/contact.ts: - Updated buildConfirmationEmail() signature from (name: string) to ({ name, subject, message }) so it can accept and render the original submission. - Added a visually distinct "Ihre Nachricht" quoted block to the HTML template: - Light gray background (#f8fafc) matching the existing bgField colour - Subtle 3px left border (#e2e8f0) styled as a blockquote - Rounded right corners (border-radius: 0 6px 6px 0) - ALL-CAPS label "IHRE NACHRICHT" in the same style as field labels elsewhere - Optional subject line rendered in semi-bold if provided - Message body with white-space:pre-wrap to preserve line breaks - All user-supplied values (subject, message) passed through the existing escapeHtml() helper — XSS-safe. - Updated the plain-text fallback: adds a "—" delimited quoted section with optional "Betreff:" line before the message body. - Updated the call site to pass { name, subject, message } to buildConfirmationEmail(). No new dependencies. Pre-existing TS error (SendContactMessageBody missing from @workspace/api-zod) is unrelated to this task and unchanged. Replit-Task-Id: 63279220-bb35-4721-bbd6-86182301a697
This commit is contained in:
@@ -67,13 +67,19 @@ router.post("/contact", contactRateLimit, async (req, res) => {
|
||||
"",
|
||||
"vielen Dank für Ihre Nachricht! Ich habe Ihre Anfrage erhalten und melde mich in der Regel innerhalb von 1–2 Werktagen bei Ihnen.",
|
||||
"",
|
||||
"Zur Erinnerung, hier ist Ihre Nachricht:",
|
||||
"—",
|
||||
...(subject ? [`Betreff: ${subject}`, ""] : []),
|
||||
message,
|
||||
"—",
|
||||
"",
|
||||
"Mit freundlichen Grüßen",
|
||||
"Joachim Hummel",
|
||||
"",
|
||||
"—",
|
||||
"jh@unixweb.de",
|
||||
].join("\n"),
|
||||
htmlContent: buildConfirmationEmail(name),
|
||||
htmlContent: buildConfirmationEmail({ name, subject, message }),
|
||||
});
|
||||
|
||||
req.log.info({ to: email }, "Confirmation email sent to sender via Brevo");
|
||||
@@ -255,8 +261,18 @@ function buildNotificationEmail({
|
||||
</html>`;
|
||||
}
|
||||
|
||||
function buildConfirmationEmail(name: string): string {
|
||||
function buildConfirmationEmail({
|
||||
name,
|
||||
subject,
|
||||
message,
|
||||
}: {
|
||||
name: string;
|
||||
subject?: string;
|
||||
message: string;
|
||||
}): string {
|
||||
const safeName = escapeHtml(name);
|
||||
const safeSubject = subject ? escapeHtml(subject) : null;
|
||||
const safeMessage = escapeHtml(message);
|
||||
const brandBlue = "#3f4ff4";
|
||||
const textDark = "#0f172a";
|
||||
const textMid = "#334155";
|
||||
@@ -265,6 +281,7 @@ function buildConfirmationEmail(name: string): string {
|
||||
const borderColor = "#e2e8f0";
|
||||
const bgPage = "#f1f5f9";
|
||||
const bgCard = "#ffffff";
|
||||
const bgQuote = "#f8fafc";
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="de" xmlns="http://www.w3.org/1999/xhtml">
|
||||
@@ -301,7 +318,24 @@ function buildConfirmationEmail(name: string): string {
|
||||
<p style="margin:0 0 6px;font-size:22px;font-weight:700;color:${textDark};line-height:1.3;">Vielen Dank, ${safeName}!</p>
|
||||
<p style="margin:0 0 20px;font-size:13px;font-weight:500;color:${brandBlue};letter-spacing:0.3px;">Ihre Anfrage ist eingegangen.</p>
|
||||
<p style="margin:0 0 16px;font-size:15px;line-height:1.75;color:${textMid};">Schön, dass Sie sich gemeldet haben. Ich habe Ihre Nachricht erhalten und werde mich in der Regel innerhalb von <strong style="color:${textDark};">1–2 Werktagen</strong> bei Ihnen melden.</p>
|
||||
<p style="margin:0 0 32px;font-size:15px;line-height:1.75;color:${textMid};">Bis dahin können Sie gerne mein Portfolio besuchen oder mir direkt eine E-Mail schicken.</p>
|
||||
<p style="margin:0 0 24px;font-size:15px;line-height:1.75;color:${textMid};">Bis dahin können Sie gerne mein Portfolio besuchen oder mir direkt eine E-Mail schicken.</p>
|
||||
|
||||
<!-- ── Quoted message ── -->
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" role="presentation" style="margin-bottom:32px;">
|
||||
<tr>
|
||||
<td style="padding-left:4px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" role="presentation" style="background-color:${bgQuote};border-left:3px solid ${borderColor};border-radius:0 6px 6px 0;">
|
||||
<tr>
|
||||
<td style="padding:16px 20px;">
|
||||
<p style="margin:0 0 10px;font-size:11px;font-weight:600;color:${textLight};letter-spacing:1px;text-transform:uppercase;">Ihre Nachricht</p>
|
||||
${safeSubject ? `<p style="margin:0 0 8px;font-size:13px;font-weight:600;color:${textMuted};">Betreff: ${safeSubject}</p>` : ""}
|
||||
<p style="margin:0;font-size:14px;line-height:1.75;color:${textMid};white-space:pre-wrap;">${safeMessage}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- CTA button -->
|
||||
<table cellpadding="0" cellspacing="0" border="0" role="presentation">
|
||||
|
||||
Reference in New Issue
Block a user