# Email Templates The Email Templates feature provides a complete email template management system with variable substitution, versioning, and rich text editing. Create reusable email templates for campaigns, notifications, and communications. ## Overview The Email Templates system consists of four integrated components: 1. **[Template System](template-system.md)** - Template CRUD and management 2. **[Editor](editor.md)** - Rich text editor with variable insertion 3. **[Variables](variables.md)** - Dynamic content placeholders 4. **[Versioning](versioning.md)** - Template version history ## Features ### Template Management - Create/edit/delete templates - Category organization - Template types (campaign, notification, system) - Published/draft status - Search and filtering - Clone templates ### Rich Text Editor - WYSIWYG HTML editor - Variable insertion menu - Preview mode - HTML source view - Image upload (future) - Link management ### Variable System Dynamic placeholders: - **User variables** - `{{user.name}}`, `{{user.email}}` - **Campaign variables** - `{{campaign.name}}`, `{{campaign.description}}` - **Representative variables** - `{{rep.name}}`, `{{rep.title}}`, `{{rep.email}}` - **Custom variables** - Template-specific placeholders - **System variables** - `{{site.name}}`, `{{current.date}}` ### Version History - Auto-save on changes - Version diff viewer - Restore previous versions - Change log ## User Flow ### Admin Experience 1. **Create Template** (`/app/email-templates`) - Click "New Template" - Enter name and category - Set template type - Save draft 2. **Edit Template** (`/app/email-templates/:id/edit`) - Full-screen rich text editor - Insert variables from dropdown - Preview with sample data - Save changes 3. **Use Template** - Select template in campaign form - Variables auto-populated from context - Send email with processed template 4. **Manage Versions** (`/app/email-templates/:id/versions`) - View version history - Compare versions - Restore previous version ## Architecture ### Backend Components **Module:** - `api/src/modules/email-templates/email-templates.routes.ts` - Template CRUD - `api/src/modules/email-templates/email-templates.service.ts` - Business logic - `api/src/modules/email-templates/email-templates.schemas.ts` - Zod validation **Database Models:** - `EmailTemplate` - Template definitions (name, content, variables) - `EmailTemplateVersion` - Version history (future) **Email Processing:** - Variable substitution in `email.service.ts` - Mustache-style templating: `{{variable}}` - HTML escaping for security ### Frontend Components **Admin Pages:** - `admin/src/pages/EmailTemplatesPage.tsx` - Template management table - `admin/src/pages/EmailTemplateEditorPage.tsx` - Full-screen editor **Editor Components:** - `admin/src/components/email-templates/TemplateEditor.tsx` - Rich text editor - `admin/src/components/email-templates/VariableInserter.tsx` - Variable dropdown ## Configuration ### Template Types - **campaign** - Campaign email templates - **notification** - User notifications - **system** - System emails (verification, password reset) - **custom** - Custom templates ### Template Categories - **Influence** - Campaign-related templates - **Map** - Shift/canvass notifications - **User** - User account emails - **System** - Automated system emails ## Variable System ### Available Variables **User Context:** ``` {{user.id}} # User ID {{user.email}} # Email address {{user.name}} # Full name {{user.role}} # User role ``` **Campaign Context:** ``` {{campaign.id}} # Campaign ID {{campaign.name}} # Campaign name {{campaign.description}} # Description {{campaign.emailTemplate}} # Email body ``` **Representative Context:** ``` {{rep.name}} # Representative name {{rep.title}} # Title (MP, MLA, etc.) {{rep.email}} # Email address {{rep.phone}} # Phone number {{rep.district}} # District name ``` **System Context:** ``` {{site.name}} # Site name {{site.url}} # Site URL {{current.date}} # Current date {{current.year}} # Current year ``` ### Variable Insertion ```typescript // Insert variable at cursor position editor.insertContent('{{user.name}}'); // Variable dropdown menu ``` ### Variable Processing Server-side processing in `email.service.ts`: ```typescript function processTemplate( template: string, variables: Record ): string { let processed = template; for (const [key, value] of Object.entries(variables)) { const placeholder = `{{${key}}}`; processed = processed.replace( new RegExp(placeholder, 'g'), escapeHtml(String(value)) ); } return processed; } ``` ## Database Schema ### EmailTemplate Model ```prisma model EmailTemplate { id Int @id @default(autoincrement()) name String subject String body String @db.Text category String? type String @default("custom") variables Json? # Available variables published Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` ## API Endpoints ### Admin Endpoints ``` GET /api/email-templates # List templates POST /api/email-templates # Create template GET /api/email-templates/:id # Get template PATCH /api/email-templates/:id # Update template DELETE /api/email-templates/:id # Delete template POST /api/email-templates/:id/clone # Clone template GET /api/email-templates/:id/preview # Preview with sample data ``` ## Security ### HTML Escaping All variable values are HTML-escaped to prevent XSS: ```typescript import { escapeHtml } from '../utils/sanitize'; const safe = escapeHtml(userInput); // Converts: < > & " ' to HTML entities ``` ### Template Validation - Subject line: 1-200 characters - Body: Required, max 50,000 characters - Variables: Valid JSON object - Category: Predefined list ## Best Practices ### Template Design - Clear subject lines (50-60 chars) - Personalize with variables - Mobile-responsive HTML - Plain text alternative - Unsubscribe link - Branding consistency ### Variable Usage - Document available variables - Provide defaults for missing values - Test with sample data - Validate variable names ### Version Management - Meaningful version names - Document changes - Test before publishing - Keep version history ## Desktop-Only Editor Email template editor requires desktop browser: ```typescript const screens = Grid.useBreakpoint(); const isMobile = !screens.md; if (isMobile) { return ( ); } ``` ## Integration Points ### Campaign Emails Campaign emails use templates: ```typescript // Select template in campaign form // Process template with campaign data const emailBody = processTemplate(template.body, { 'user.name': user.name, 'campaign.name': campaign.name, 'rep.name': representative.name, }); ``` ### System Emails System emails (verification, password reset): ```typescript // Load system template const template = await getTemplateByType('email-verification'); // Process with user data const emailBody = processTemplate(template.body, { 'user.name': user.name, 'verify.link': verificationUrl, }); // Send email await emailService.sendEmail({ to: user.email, subject: template.subject, html: emailBody, }); ``` ## Related Documentation - [Template System](template-system.md) - [Editor](editor.md) - [Variables](variables.md) - [Versioning](versioning.md) - [Email Templates Page](../../frontend/pages/admin/email-templates-page.md) - [Email Template Editor Page](../../frontend/pages/admin/email-template-editor-page.md) - [Email Service](../../backend/services/index.md) - [Campaign Manager Guide](../../user-guides/campaign-manager-guide.md)