Files
Plushealthtech/task/03-request-demo-page.md
T
Clive e5d1446791
Gitea CI/CD / build (push) Successful in 1m40s
Site pages and AI tasks.
2026-08-20 14:58:52 +10:00

3.0 KiB
Raw Blame History

Task 03 — Request Demo page with MailPit form

  • Status: Done — 2026-08-20
  • Depends on: 01
  • Size: M

Goal

Create the Request Demo page at /RequestDemo with a form that emails its submission to MailPit (tools.host.domain:1025, recipient [email protected]) via the existing MailSender. Same send/success/error pattern as the Contact page (Task 02).

Files

  • Create: plushealthtech/Pages/RequestDemo.cshtml
  • Create: plushealthtech/Pages/RequestDemo.cshtml.cs

Steps

  1. PageModel (RequestDemoModel : PageModel)

    • Inject MailSender (+ logger).
    • [BindProperty] fields with DataAnnotations:
      • Name — [Required], [StringLength(200)]
      • Email — [Required], [EmailAddress], [StringLength(320)]
      • Organization — [Required], [StringLength(200)]
      • PracticeType — select: Healthcare system, Hospital, Clinic, Veterinary practice, Other (optional)
      • ProductsOfInterest — select: Clinical Decision Support, Patient Management, Veterinary Solutions, Multiple / not sure (optional)
      • Message — [StringLength(5000)] (optional)
    • Success / Error flags, OnGet reset.
    • OnPost() same contract as Task 02: validate → build plain-text Field: value body → SendAsync($"New demo request — {Organization}", body) → success flag; SMTP failure → generic error banner + log.
  2. View (RequestDemo.cshtml)

    • @page, @model RequestDemoModel, ViewData["Title"] = "Request Demo".
    • Marketing-flavored hero (one-line value prop, 2–3 trust bullets like "FHIR®-ready" / "24/7 clinical support" — reuse Index hero metrics) + the form card, Tailwind styling consistent with the site.
    • @Html.AntiforgeryToken(), per-field validation spans, success/error rendering identical in behavior to Contact.
    • Close with a secondary CTA: "Prefer to talk? Visit the Contact page." → /Contact.

Acceptance criteria

  • GET /RequestDemo renders; build green.
  • Required fields enforced; selects render all options.
  • Valid submit → success panel shown; MailPit shows the message from [email protected] to [email protected] with subject New demo request — {Organization} (e2e verified 2026-08-20, ahead of Task 13).
  • With MailPit down → friendly error banner, exception in app log, no stack trace in the browser.

Notes

  • Antiforgery: the form uses asp-page="/RequestDemo", which auto-injects __RequestVerificationToken — the explicit @Html.AntiforgeryToken() from the spec is unnecessary and would duplicate the field (same approach as the Contact page).
  • SMTP-down path verified by running the app with Smtp__Host=127.0.0.1 Smtp__Port=1 (env override, no config change): banner rendered, SmtpException (SocketException 10061) logged with sender context, response body clean.
  • Validation confirmed over HTTP: empty POST → "required" messages on Name/Email/Organization only; bad email → "not a valid e-mail address"; both selects render their full option lists with a placeholder.