diff --git a/web/src/padelnomics/admin/routes.py b/web/src/padelnomics/admin/routes.py
index 32bf36d..b60d27f 100644
--- a/web/src/padelnomics/admin/routes.py
+++ b/web/src/padelnomics/admin/routes.py
@@ -33,6 +33,7 @@ from ..core import (
utcnow,
utcnow_iso,
)
+from ..email_templates import EMAIL_TEMPLATE_REGISTRY, render_email_template
logger = logging.getLogger(__name__)
@@ -1398,10 +1399,16 @@ async def email_compose():
email_addresses=EMAIL_ADDRESSES,
)
- html = f"
{body.replace(chr(10), '
')}
"
+ body_html = f"{body.replace(chr(10), '
')}
"
if wrap:
- from ..worker import _email_wrap
- html = _email_wrap(html)
+ html = render_email_template(
+ "emails/admin_compose.html",
+ lang="en",
+ body_html=body_html,
+ preheader="",
+ )
+ else:
+ html = body_html
result = await send_email(
to=to, subject=subject, html=html,
@@ -1424,6 +1431,36 @@ async def email_compose():
)
+@bp.route("/emails/compose/preview", methods=["POST"])
+@role_required("admin")
+async def compose_preview():
+ """HTMX endpoint: render live preview for compose textarea (no CSRF — read-only)."""
+ form = await request.form
+ body = form.get("body", "").strip()
+ wrap = form.get("wrap", "") == "1"
+
+ body_html = f"{body.replace(chr(10), '
')}
" if body else ""
+
+ if wrap and body_html:
+ try:
+ rendered_html = render_email_template(
+ "emails/admin_compose.html",
+ lang="en",
+ body_html=body_html,
+ preheader="",
+ )
+ except Exception:
+ logger.exception("compose_preview: template render failed")
+ rendered_html = body_html
+ else:
+ rendered_html = body_html
+
+ return await render_template(
+ "admin/partials/email_preview_frame.html",
+ rendered_html=rendered_html,
+ )
+
+
# --- Audiences ---
@bp.route("/emails/audiences")
diff --git a/web/src/padelnomics/admin/templates/admin/email_compose.html b/web/src/padelnomics/admin/templates/admin/email_compose.html
index dfd5a7a..1ab8846 100644
--- a/web/src/padelnomics/admin/templates/admin/email_compose.html
+++ b/web/src/padelnomics/admin/templates/admin/email_compose.html
@@ -2,51 +2,91 @@
{% set admin_page = "compose" %}
{% block title %}Compose Email - Admin - {{ config.APP_NAME }}{% endblock %}
+{% block admin_head %}
+
+{% endblock %}
+
{% block admin_content %}
-