"""Self-contained HTML pages for the no-login CSAT magic link. Mirrors provisioning's ``quick-complete`` pattern: the GET landing page is side-effect-free (mail-client prefetch safe) and shows three POST buttons; the POST consumes the action token's jti once. Works in the Feishu in-app browser and any external browser, no SPA, no SSO. """ from __future__ import annotations import html from fastapi.responses import HTMLResponse # (score, emoji, zh, en) — 3-point caliber aligned with the Feishu mirror. RATE_CHOICES = ( (3, "😊", "满意", "Satisfied"), (2, "😐", "一般", "Neutral"), (1, "🙁", "不满意", "Unsatisfied"), ) def rate_page( *, title: str, heading: str, body_html: str, tone: str = "info", icon: str | None = None, ) -> HTMLResponse: """Tiny bilingual result/landing page (visual language matches the provisioning quick-complete pages so all magic links feel like one product).""" accents = { "ok": ("#1a7f37", "#e7f6ec", "✓"), "err": ("#cf222e", "#fdecec", "!"), "info": ("#0969da", "#eaf2fb", "★"), } accent, badge_bg, default_icon = accents.get(tone, accents["info"]) badge_glyph = icon if icon is not None else default_icon doc = ( "" "" "" f"{html.escape(title)}
" f"{badge_glyph}" f"

{html.escape(heading)}

" f"{body_html}" "
" ) # Page-level CSP: the global SecurityHeadersMiddleware default # (``default-src 'none'``) makes the browser ignore the inline