feat(deps): adopt react-email for portal-auth template

Migrates the activation + reset email templates from hand-strung HTML
strings to React components rendered via @react-email/components.

Concrete wins this lands:
- React auto-escapes interpolation — drops the hand-rolled escapeHtml()
  helper. Eliminates the entire class of "I forgot to escape" XSS bugs.
- @react-email primitives (Button, Hr, Link, Text) render to
  Outlook/Gmail/AppleMail-safe inline-styled HTML.
- JSX over template strings makes the templates editable / reviewable.
- Sets the pattern for the remaining 7 templates (crm-invite,
  document-signing, inquiry-*, notification-digest, admin-email-change,
  residential-inquiry). Migrate opportunistically when those files are
  next touched.

The shell (logo, blurred background, table-based wrapper) stays via
renderShell so this is a strictly inner-body migration — visual parity
preserved.

Vitest config: added @vitejs/plugin-react so .tsx files imported by
tests (transitively via the service that uses the template) transform
correctly under Next's tsconfig `jsx: 'preserve'` setting.

Verified: tsc clean, vitest 1293/1293 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-12 18:43:14 +02:00
parent 9455ff9981
commit ff0667ce52
6 changed files with 938 additions and 148 deletions

View File

@@ -1,9 +1,16 @@
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import path from 'path';
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { loadEnv } = require('vite');
export default defineConfig({
// Next.js tsconfig sets jsx: 'preserve' so .tsx files imported by
// tests (e.g. react-email templates) aren't transformed by vite's
// default loader. The official react plugin handles the JSX
// transform in test-time only — Next's runtime keeps its preserve
// setting for the prod build.
plugins: [react()],
test: {
globals: true,
environment: 'node',