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

48 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
- [x] `GET /RequestDemo` renders; build green.
- [x] Required fields enforced; selects render all options.
- [x] 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).
- [x] 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.