diff --git a/appview/pages/pages.go b/appview/pages/pages.go index d0988ee2..15dff888 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -523,6 +523,18 @@ func (p *Pages) UpgradeBanner(w io.Writer, params UpgradeBannerParams) error { return p.executePlain("banner", w, params) } +type NewsletterResponseParams struct { + // Id identifies the calling form instance; the response span's id will + // be "newsletter-msg-" so it round-trips with the form's hx-target. + Id string + // Error, when non-empty, switches the template to the error variant. + Error string +} + +func (p *Pages) NewsletterResponse(w io.Writer, params NewsletterResponseParams) error { + return p.executePlain("timeline/fragments/newsletterResponse", w, params) +} + type KnotsParams struct { LoggedInUser *oauth.MultiAccountUser Registrations []models.Registration diff --git a/appview/pages/templates/layouts/base.html b/appview/pages/templates/layouts/base.html index e8538b25..bad39985 100644 --- a/appview/pages/templates/layouts/base.html +++ b/appview/pages/templates/layouts/base.html @@ -61,7 +61,6 @@ {{ template "fragments/posthog" . }} - {{ block "topbarLayout" . }}
diff --git a/appview/pages/templates/timeline/fragments/newsletter.html b/appview/pages/templates/timeline/fragments/newsletter.html deleted file mode 100644 index 3e05d912..00000000 --- a/appview/pages/templates/timeline/fragments/newsletter.html +++ /dev/null @@ -1,16 +0,0 @@ -{{ define "timeline/fragments/newsletter" }} -
-
-

We've got a newsletter! Punch in your email to get our updates sent straight to your inbox.

- - - - - -
-
- -{{ end }} diff --git a/appview/pages/templates/timeline/fragments/newsletterForm.html b/appview/pages/templates/timeline/fragments/newsletterForm.html new file mode 100644 index 00000000..11a4630d --- /dev/null +++ b/appview/pages/templates/timeline/fragments/newsletterForm.html @@ -0,0 +1,55 @@ +{{/* + Shared newsletter signup form. Variants style the form differently, but the + POST target, response-target id and request plumbing stay identical. + + Params (dict): + Id string - unique id suffix (e.g. "widget", "home"); used to build + the response span's id so multiple signup forms can + coexist on one page without colliding. + Variant string - "card" (compact sidebar card) | "hero" (large CTA) +*/}} +{{ define "timeline/fragments/newsletterForm" }} + {{ $id := .Id }} + {{ $variant := .Variant }} + {{ if eq $variant "hero" }} +
+ + + + +
+ {{ else }} +
+ + + + +
+ {{ end }} +{{ end }} diff --git a/appview/pages/templates/timeline/fragments/newsletterResponse.html b/appview/pages/templates/timeline/fragments/newsletterResponse.html new file mode 100644 index 00000000..a122689c --- /dev/null +++ b/appview/pages/templates/timeline/fragments/newsletterResponse.html @@ -0,0 +1,16 @@ +{{/* + Response fragment swapped into place by htmx after a /newsletter/signup + submission. Returns a whose id matches the form's hx-target so the + swap is clean and no hard-coded id leaks into Go. + + Params: + Id string - matches the Id used in newsletterForm (e.g. "widget", "home") + Error string - if non-empty, renders the error variant +*/}} +{{ define "timeline/fragments/newsletterResponse" }} + {{ if .Error }} + {{ .Error }} + {{ else }} + You're signed up! + {{ end }} +{{ end }} diff --git a/appview/pages/templates/timeline/fragments/newsletterWidget.html b/appview/pages/templates/timeline/fragments/newsletterWidget.html index afa81307..6098aaf2 100644 --- a/appview/pages/templates/timeline/fragments/newsletterWidget.html +++ b/appview/pages/templates/timeline/fragments/newsletterWidget.html @@ -1,13 +1,10 @@ {{ define "timeline/fragments/newsletterWidget" }}
+ class="relative border border-green-800/15 dark:border-green-700 rounded bg-green-50 dark:bg-green-950 p-4"> - - + {{ template "timeline/fragments/newsletterForm" (dict "Id" "widget" "Variant" "card") }}
- {{ end }} diff --git a/appview/pages/templates/timeline/home.html b/appview/pages/templates/timeline/home.html index d1804d16..a0ca103b 100644 --- a/appview/pages/templates/timeline/home.html +++ b/appview/pages/templates/timeline/home.html @@ -507,25 +507,11 @@ {{ define "newsletter" }}
-

Stay in the loop

-

- We've got a newsletter! Punch in your email to stay updated on what we're shipping at Tangled. -

-
- - - - -
+

Stay in the loop

+

+ We've got a newsletter! Punch in your email to stay updated on what we're shipping at Tangled. +

+ {{ template "timeline/fragments/newsletterForm" (dict "Id" "home" "Variant" "hero") }} +
{{ end }} diff --git a/appview/pages/templates/timeline/timeline.html b/appview/pages/templates/timeline/timeline.html index a0286385..e2d6f344 100644 --- a/appview/pages/templates/timeline/timeline.html +++ b/appview/pages/templates/timeline/timeline.html @@ -16,62 +16,74 @@ {{ end }} {{ define "content" }} -
- {{ template "timeline/fragments/newsletter" . }} - {{ template "timeline/fragments/goodfirstissues" . }} - {{ template "timeline/fragments/trending" . }} - {{ template "timeline/fragments/timeline" . }} -
+{{/* + Single responsive grid. Every fragment is rendered once, with CSS alone + handling the mobile → desktop reflow. Only trending has two variants + (horizontal scroll for mobile, vertical sidebar for desktop); both are + present in the DOM and toggled via utility classes. -