Confirmation Email System

Automated registration confirmation emails that welcome fighters, deliver their QR code, and establish the first touchpoint in your fighter engagement pipeline.

Why Confirmation Emails Matter

The confirmation email is the very first message a fighter receives after registering — it sets the tone for their entire experience.

Trust

Instant Confirmation

Fighters immediately know their registration was received and their payment processed. No uncertainty, no follow-up questions to your team.

Check-In

QR Code Delivery

Each fighter gets a unique QR code in their confirmation email for fast check-in at the event. No printed lists, no manual look-ups.

Branding

Custom Branding

Use your own logo, sanctioning branding, rules links, and custom messaging. Make it feel like it came from your organization, not a generic platform.

End-to-End Flow

From creating the template to the fighter's inbox.

A. Sanctioning Level Sanctioning Page → "Confirmation Email"
CustomConfirmationEmails.tsx
Saves to sanctioning_bodies doc
OR
B. Event Level Edit Event Form → "Email Template"
EditEventForm.tsx
Saves to event document
↓ emailConfirmationHTML saved to event data
Fighter Submits Registration RegistrationNew.tsx
Validates form, processes Stripe payment, calls handleRegistrationSubmit()
Save to Roster Fighter added to event roster via API
(PMT, PBSC, or generic)
Add to Database Fighter profile created/updated in Firestore
Generate QR Code Unique fighter QR code for check-in
Email Template Selection sendFighterConfirmationEmail()
Custom HTML? → Use it with placeholder replacement
PMT event? → PMT default template
Otherwise → Generic default template
Placeholder Replacement {{firstName}}, {{lastName}}, {{qrCode}}, {{eventName}}, etc.
+ custom field placeholders from registration form
Send via /api/emails SES email sent to fighter
Source varies by sanctioning body
Fighter Inbox Confirmation + QR code + details
Promoter Notification New registration alert
(if no custom template set)
Admin Notification Success/failure alerts
with full debug data

Two Configuration Paths

Confirmation email templates can be configured at two levels, each serving a different workflow.

Path A

Sanctioning Level

Where: Sanctioning Page → "Confirmation Email" button

Component: CustomConfirmationEmails.tsx

Saves to: sanctioning_bodies/{id}.emailConfirmationHTML

Use case: Set one master template that all events under this sanctioning body inherit. The HTML is written to the sanctioning body document in Firestore. When a new event is created, it can pull this template.

Features:

  • Full HTML code editor
  • Live preview with sample data
  • Click-to-copy placeholder buttons
  • Default template generator
  • Direct save to Firestore
Path B

Event Level

Where: Edit Event Form → "Email Template" section

Component: EditEventForm.tsx → embeds CustomConfirmationEmails

Saves to: events/{id}.emailConfirmationHTML

Use case: Override the sanctioning-level template for a specific event. Useful for events with special messaging, different branding, or unique registration fields.

Features:

  • Same HTML editor as sanctioning level
  • Aware of event's custom registration fields
  • Dynamic placeholder generation based on form config
  • PMT events show a read-only preview of the PMT template
  • Saved as part of the event document on form submit

Priority order: When a fighter registers, the system checks: Does the event have emailConfirmationHTML? Use it. Otherwise, is this a PMT event? Use the PMT template. Otherwise, generate a default template from the fighter data.

Email Anatomy

What the fighter sees in their inbox after registering.

Custom / PMT Template

Default Template (Non-PMT)

Template Placeholders

Use these placeholders in your custom HTML template. They are automatically replaced with actual fighter data when the email is sent.

Placeholder Replaced With Category
{{firstName}}Fighter's first nameEssential
{{lastName}}Fighter's last nameEssential
{{email}}Fighter's email addressEssential
{{eventName}}Event nameEvent
{{eventId}}Event IDEvent
{{fighterId}}Fighter's unique IDEvent
{{qrCode}}QR code image URLEvent
{{gym}}Fighter's gym nameForm
{{gender}}Fighter's genderForm
{{age}}Fighter's ageForm
{{dob}}Date of birthForm
{{weightClass}}Weight classForm
{{heightFoot}}Height (feet)Form
{{heightInch}}Height (inches)Form
{{phone}}Fighter's phoneForm
{{coach}}Coach nameForm
{{coachPhone}}Coach phoneForm
{{city}}Fighter's cityForm
{{state}}Fighter's stateForm
{{customFieldKey}} Any custom field from your registration form Custom

Dynamic custom fields: When you create a custom registration form with CreateRegistrationForm, every field with a fieldKey automatically becomes an available placeholder. The editor detects these and shows them as clickable copy buttons.

Setup Guide: Sanctioning Level

Create a master confirmation email template for all your events.

Navigate to Sanctioning Page

Go to /sanctioning/[sanctioningId]. You must be logged in as an admin or sanctioning body member.

Click "Confirmation Email"

This opens the CustomConfirmationEmails dialog with the HTML editor and preview tabs.

Write or Paste Your HTML Template

Use the HTML editor tab. Insert placeholders from the sidebar. Or click "Use Default Template" to get a starter template with all available fields.

Preview Your Email

Switch to the Preview tab to see the email rendered with sample data (John Doe, Champions MMA, etc.).

Save

Click Save. The HTML is written to sanctioning_bodies/{id}.emailConfirmationHTML in Firestore.

Setup Guide: Event Level

Override the confirmation email for a specific event.

Open Edit Event Form

Navigate to your event page and click Edit to open the EditEventForm.

Find the "Email Template" Section

Scroll to the email section in the form. It shows whether a custom template or default is active.

Click "Edit Email Template"

This embeds the same CustomConfirmationEmails component, but in context="event" mode. It's aware of the event's custom registration fields, so dynamic placeholders are generated.

Write Your Template

Use placeholders. Custom registration fields (select, checkbox-group, text, etc.) automatically appear as available placeholders.

Save the Event

When you save the event form, the emailConfirmationHTML is saved alongside all other event data in a single API call.

PMT events: For PMT-sanctioned events, the email template section shows a read-only preview of the standard PMT template. PMT templates are hardcoded and cannot be customized per-event because they include mandatory elements (rules link, refund policy).

What Happens When a Fighter Registers

The complete sequence inside handleRegistrationSubmit().

1. Fighter Fills Registration Form RegistrationNew.tsx
Name, email, gym, weight, DOB, custom fields, waiver
2. Client-Side Validation Required fields, email format (no spaces), age check, card complete, waiver accepted
3. Payment Processing Free (coupon 100%) → skip payment
Pay Later → skip payment, mark as pay-later
Paid → Stripe PaymentIntent created & confirmed
4. Duplicate Check Check if fighter already registered for this event
If duplicate: alert user, stop process
5. Save to Roster PMT → POST /api/pmt/roster
Generic → POST /api/roster
Fighter added to event roster document
6. Database Operations Check if fighter exists in fighters DB
If new: create fighter profile via addFighterToDatabase()
If exists: update details via updateFighterDetailsInDB()
7a. Fighter Confirmation Email sendFighterConfirmationEmail()
Template selection → placeholder replacement → send via /api/emails
7b. Promoter Notification sendEmailToPromoter()
Only if no custom template
(avoids double email)
7c. Admin Notification sendSuccessRegistrationNotification()
Full debug data, type analysis, PMT info
8. Success "Registration submitted. Check your email: fighter@email.com"
Optional redirect to custom URL

Three Template Strategies

The system selects the right template automatically based on what's configured.

Priority 1

Custom HTML Template

When: emailConfirmationHTML exists on the event document.

Source: Created via the HTML editor in CustomConfirmationEmails.

How: All {{placeholders}} are replaced with actual fighter data, including custom registration fields. Unreplaced placeholders are stripped.

Priority 2

PMT Default Template

When: No custom HTML, but sanctioning is PMT.

Source: Hardcoded in generatePMTConfirmationEmail().

Includes: PMT logo, competition rules link, QR code, registration details, refund policy.

Priority 3

Generic Default Template

When: No custom HTML and not PMT.

Source: generateDefaultConfirmationEmail().

Features: Auto-generated from available fighter data. Only includes fields that have values. Supports English and Spanish (locale).

Sender Identity

The "from" address changes based on the sanctioning body.

SanctioningSender NameSender Email
PMTPoint Muay Thaiinfo@pointmuaythaica.com
PBSCPoint Boxing Sparring Circuitborntowincsc@gmail.com
All OthersTechBoutstechbouts@nakmuay.foundation

Internationalization (i18n)

Built-in Spanish support for the registration flow and confirmation emails.

Registration Form

Bilingual UI

When eventData.locale === 'es', all form labels, validation messages, success/error alerts, and payment instructions switch to Spanish.

Currency also converts to MXN with live exchange rates.

Confirmation Email

Spanish Email Template

The default template auto-generates in Spanish: greeting, intro, field labels, and closing text all switch based on locale.

Custom HTML templates are language-agnostic — whatever you write is what gets sent.

Failure Handling & Safety Nets

What happens when things go wrong — payment taken but registration fails.

Payment Succeeded + Registration Failed The most critical failure scenario
Firestore Log Failure logged to
failed_registrations/{paymentIntentId}
with full debug data
Admin Alert Email Detailed HTML email with:
- Payment intent ID
- Fighter data & undefined fields
- API request/response
- PMT-specific debug info
- Action checklist

Error categorization: The categorizeAndFormatError() function classifies errors into user-friendly messages: payment failed, network error, server error, Stripe error, timeout, or validation error. Each has localized messages in English and Spanish.

Technical Architecture

Files and their roles in the confirmation email system.

app/
  sanctioning/[sanctioningId]/
    PageClient.tsx ← "Confirmation Email" button opens editor dialog

  events/[promoterId]/[eventId]/
    (event page where fighters register)

components/
  sanctioning/
    CustomConfirmationEmails.tsx ← HTML editor + preview + placeholder system

  events/
    EditEventForm.tsx ← embeds CustomConfirmationEmails in event context
    register/
      RegistrationNew.tsx ← registration form UI, Stripe, validation
      FighterFormNew.tsx ← dynamic form fields from config
      CouponCode.tsx ← discount code validation

utils/apiFunctions/
  handleRegistrationSubmit.ts ← orchestrates the entire registration pipeline
    sendFighterConfirmationEmail() ← template selection + placeholder replacement + send
    sendEmailToPromoter() ← promoter new-registration notification
    sendSuccessRegistrationNotification() ← admin success alert with type analysis
    sendFailedRegistrationNotification() ← admin failure alert with debug data
    logFailedRegistration() ← Firestore failed_registrations log
    saveToRoster() ← roster save (PMT or generic)

app/api/
  emails/route.ts ← generic email send endpoint (SES)
  emails/promoterNotificationEmail/route.ts ← promoter notification endpoint

Promoter Notification Email

When a custom template is NOT set, a separate notification is sent to the promoter.

The sendPromoterNotificationEmail flag in RegistrationNew.tsx controls this:

sendPromoterNotificationEmail: !eventData.emailConfirmationHTML

Logic: If the event has a custom email template, the promoter is assumed to have their own notification system. If there's no custom template, the system sends a separate email to all promoterEmails with the fighter's registration details (name, weight, gym, gender, DOB, age, height, phone, coach).

Endpoint: POST /api/emails/promoterNotificationEmail