feat: free-form salutation (Anrede) — replace 'an wen', drop the 'für' prefix #26

Closed
opened 2026-06-17 13:24:30 +00:00 by mAi · 2 comments
Collaborator

What (m, PWA)

m: „lass uns das ‚für' in der Adresszeile der Karten entfernen … Vielleicht machen wir die gesamte Anrede customized? … Keine Auswahl — wir ändern einfach das ‚an wen' zu Anrede.“

Two linked changes:

  1. Drop the „für“ prefix on the rendered card. Today the recipient renders as something like „für “ — remove the hardcoded „für“.
  2. Turn the recipient field into a free-form „Anrede“. Rename the „An wen“ / recipient field label to „Anrede“, a single free-text field the sender fully controls (e.g. „Liebe Oma Erika“, „Hallo zusammen“, „Für meinen Schatz“). No dropdown / no selection — just a relabeled free-text field. The card renders the Anrede as-is (no „für“/„An:“ prefix, no transformation).

Details / interactions to handle

  • It's the same underlying field as today's recipient_name (rename label + placeholder/hint, e.g. „z. B. Liebe Oma Erika“; keep the column, just repurpose semantics — no migration needed). Render the stored value verbatim as the salutation line.
  • Broadcast mode (#4, „zum Teilen“): there's no specific addressee. The Anrede should stay optional there (a general greeting like „Hallo ihr Lieben“ is fine, or empty → no salutation line). Make sure broadcast still works (no „für“, no empty „An:“ artifact).
  • An/von grouping (#12): the „An“ side becomes „Anrede“; the „von“ (sender) field stays. Keep them adjacent + equal styling.
  • Live preview (#15) + admin (#19): show the Anrede verbatim (admin can label the column „Anrede“). No „für“ anywhere.
  • Empty Anrede → just render no salutation line (don't show a stray label).

Constraints

Mobile-first, German + Umlaute. No regression to broadcast (#4), occasions (#10), An/von layout (#12), preview (#15), admin (#19). Verbatim render — don't escape-mangle Umlaute.

Sequencing

Compose + render + preview + admin → same single-worker compose track, after the in-flight styling block (#23/#24/#25). otto-head assigns when that merges.

DoD

  • Recipient field is a free-form „Anrede“ (no dropdown); card renders it verbatim with NO „für“/„An:“ prefix; empty → no salutation line.
  • Broadcast, occasions, An/von layout, preview, admin all still correct.
  • build/vet/test green; e2e (custom Anrede renders verbatim; broadcast w/o Anrede clean); test data cleaned. Commit references this issue.
## What (m, PWA) m: *„lass uns das ‚für' in der Adresszeile der Karten entfernen … Vielleicht machen wir die gesamte Anrede customized? … Keine Auswahl — wir ändern einfach das ‚an wen' zu Anrede.“* Two linked changes: 1. **Drop the „für“ prefix** on the rendered card. Today the recipient renders as something like „für <Name>“ — remove the hardcoded „für“. 2. **Turn the recipient field into a free-form „Anrede“.** Rename the „An wen“ / recipient field label to **„Anrede“**, a single free-text field the sender fully controls (e.g. „Liebe Oma Erika“, „Hallo zusammen“, „Für meinen Schatz“). **No dropdown / no selection** — just a relabeled free-text field. The card renders the Anrede **as-is** (no „für“/„An:“ prefix, no transformation). ## Details / interactions to handle - It's the same underlying field as today's `recipient_name` (rename label + placeholder/hint, e.g. „z. B. Liebe Oma Erika“; keep the column, just repurpose semantics — no migration needed). Render the stored value verbatim as the salutation line. - **Broadcast mode (#4, „zum Teilen“):** there's no specific addressee. The Anrede should stay optional there (a general greeting like „Hallo ihr Lieben“ is fine, or empty → no salutation line). Make sure broadcast still works (no „für“, no empty „An:“ artifact). - **An/von grouping (#12):** the „An“ side becomes „Anrede“; the „von“ (sender) field stays. Keep them adjacent + equal styling. - **Live preview (#15) + admin (#19):** show the Anrede verbatim (admin can label the column „Anrede“). No „für“ anywhere. - Empty Anrede → just render no salutation line (don't show a stray label). ## Constraints Mobile-first, German + Umlaute. No regression to broadcast (#4), occasions (#10), An/von layout (#12), preview (#15), admin (#19). Verbatim render — don't escape-mangle Umlaute. ## Sequencing Compose + render + preview + admin → same single-worker compose track, **after the in-flight styling block (#23/#24/#25)**. otto-head assigns when that merges. ## DoD - Recipient field is a free-form „Anrede“ (no dropdown); card renders it verbatim with NO „für“/„An:“ prefix; empty → no salutation line. - Broadcast, occasions, An/von layout, preview, admin all still correct. - build/vet/test green; e2e (custom Anrede renders verbatim; broadcast w/o Anrede clean); test data cleaned. Commit references this issue.
mAi self-assigned this 2026-06-17 13:35:39 +00:00
Author
Collaborator

#26 free-form „Anrede“ + #27 collapsible field hints — done

otto-head bundled #27 into this shift (same compose UI), so both ship in one commit.

#26 — free-form salutation

  • Drop the „für“ prefix: the rendered card no longer prefixes the recipient. The to-line now renders the stored value verbatim — no „Für“/„An:“ prefix and no added comma. Page <title> also drops „Für“.
  • „An wen“ → „Anrede“: the recipient field is relabelled „Anrede (optional)“ with placeholder „z. B. Liebe Oma Erika“. No dropdown — same free-text field, same recipient_name column (no migration).
  • Decoupled from audience: the Anrede is now optional in every mode, broadcast included (a general greeting like „Hallo ihr Lieben“ works). The handler no longer clears it for broadcast and the compose JS no longer hides the field. Empty Anrede → no salutation line.
  • An/von layout (#12): both fields stay adjacent + equal styling; the pair no longer collapses to a lone „Von“.
  • Live preview (#15): renders the Anrede verbatim (no „Für“), broadcast included.
  • Admin (#19): list + delete-confirm relabel the column „Anrede:“ and surface the Anrede for broadcast cards too (e.g. 📢 An alle · Anrede: Hallo ihr Lieben).

#27 — collapse verbose hints behind „ⓘ“

  • Each verbose hint (Fotos & Video, Wunsch-Adresse, Gültig bis, Max. Aufrufe, Passwort) now hides behind a small „ⓘ“ disclosure beside its label, collapsed by default.
  • Built on native <details>/<summary>: works with no JS (tap toggles), keyboard- and screen-reader-accessible (aria-label on the toggle, aria-describedby on the input). Hint content is preserved, not deleted. The popover is absolutely positioned, so revealing it never reflows the form.

Verification

  • go build / go vet / go test -race ./... all green. New tests: TestRenderSalutationVerbatim, TestComposeAnredeFieldAndCollapsedHints.
  • e2e on a throwaway Postgres + local storage (torn down, no prod touch):
    • single + Anrede → to-line = Liebe Oma Erika (no „Für“, no comma), Umlaute intact;
    • broadcast without Anrede → no to-line, no stray „für“;
    • broadcast with Anrede → Hallo ihr Lieben rendered verbatim;
    • admin shows „Anrede:“ for both, old „An:“ label gone.

Branch mai/hermes/issue-26-feat-free-form (not merged — otto-head merges/deploys).
Commit: 057fb9a3b0

## #26 free-form „Anrede“ + #27 collapsible field hints — done otto-head bundled #27 into this shift (same compose UI), so both ship in one commit. ### #26 — free-form salutation - **Drop the „für“ prefix:** the rendered card no longer prefixes the recipient. The `to-line` now renders the stored value **verbatim** — no „Für“/„An:“ prefix and no added comma. Page `<title>` also drops „Für“. - **„An wen“ → „Anrede“:** the recipient field is relabelled **„Anrede (optional)“** with placeholder **„z. B. Liebe Oma Erika“**. No dropdown — same free-text field, same `recipient_name` column (no migration). - **Decoupled from audience:** the Anrede is now optional in **every** mode, broadcast included (a general greeting like „Hallo ihr Lieben“ works). The handler no longer clears it for broadcast and the compose JS no longer hides the field. Empty Anrede → no salutation line. - **An/von layout (#12):** both fields stay adjacent + equal styling; the pair no longer collapses to a lone „Von“. - **Live preview (#15):** renders the Anrede verbatim (no „Für“), broadcast included. - **Admin (#19):** list + delete-confirm relabel the column **„Anrede:“** and surface the Anrede for broadcast cards too (e.g. `📢 An alle · Anrede: Hallo ihr Lieben`). ### #27 — collapse verbose hints behind „ⓘ“ - Each verbose hint (Fotos & Video, Wunsch-Adresse, Gültig bis, Max. Aufrufe, Passwort) now hides behind a small **„ⓘ“** disclosure beside its label, collapsed by default. - Built on native `<details>`/`<summary>`: **works with no JS** (tap toggles), keyboard- and screen-reader-accessible (`aria-label` on the toggle, `aria-describedby` on the input). Hint **content is preserved**, not deleted. The popover is absolutely positioned, so revealing it never reflows the form. ### Verification - `go build` / `go vet` / `go test -race ./...` all green. New tests: `TestRenderSalutationVerbatim`, `TestComposeAnredeFieldAndCollapsedHints`. - **e2e** on a throwaway Postgres + local storage (torn down, no prod touch): - single + Anrede → `to-line` = `Liebe Oma Erika` (no „Für“, no comma), Umlaute intact; - broadcast **without** Anrede → no `to-line`, no stray „für“; - broadcast **with** Anrede → `Hallo ihr Lieben` rendered verbatim; - admin shows „Anrede:“ for both, old „An:“ label gone. Branch `mai/hermes/issue-26-feat-free-form` (not merged — otto-head merges/deploys). Commit: https://mgit.msbls.de/m/postcards/commit/057fb9a3b0d618b86f07467f338f6cf19bb9d139
Author
Collaborator

Merged & deployed (merge f281b85)

Verified live on sendmy.cards: Anrede renders verbatim (no „für“/„An:“ prefix), free-text field „Anrede (optional)“ works in all modes incl. broadcast; verbose field hints collapsed behind ⓘ

(no-JS + accessible, content preserved). build/vet/test green. Not closing — m closes.

## ✅ Merged & deployed (merge `f281b85`) Verified live on sendmy.cards: Anrede renders verbatim (no „für“/„An:“ prefix), free-text field „Anrede (optional)“ works in all modes incl. broadcast; verbose field hints collapsed behind ⓘ <details> (no-JS + accessible, content preserved). build/vet/test green. Not closing — m closes.
mAi closed this issue 2026-06-23 15:48:04 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/postcards#26
No description provided.