Skip to content

Add custom RSVP questions to events - #256

Merged
lowercasename merged 5 commits into
mainfrom
feature/custom-rsvp-questions
Aug 13, 2026
Merged

Add custom RSVP questions to events#256
lowercasename merged 5 commits into
mainfrom
feature/custom-rsvp-questions

Conversation

@lowercasename

@lowercasename lowercasename commented Aug 12, 2026

Copy link
Copy Markdown
Owner

End-to-end feature to handle custom questions for events. I've also updated the styling of the event options section to make it a bit friendlier. Works for the ActivityPub route as well, and I've added email sending for all RSVPs, not just ones on approval-only events.

This should close up #196.

New options cards:

Screenshot 2026-08-12 at 15 26 18

Custom questions!

Screenshot 2026-08-12 at 15 27 08

Answering custom questions:

Screenshot 2026-08-12 at 15 27 52

Admin sees the answers, attendees don't:

Screenshot 2026-08-12 at 15 28 20

ActivityPub attendees get a DM with a secret link to fill in their answers post hoc:

Screenshot 2026-08-12 at 15 30 21

...and can only do it once.

Screenshot 2026-08-12 at 15 31 10

Hosts can ask attendees up to six questions (short text or multiple
choice with up to ten options) when they RSVP. Closes #196.

- Questions are stored on the event with stable IDs, and answers on the
  attendee with a snapshot of the prompt, so answers survive edits to
  the questions and outlive deleted ones
- Web attendees answer in the RSVP modal; answers are shown only to the
  host, with 'No answer' placeholders for unanswered questions
- Fediverse attendees are DMed a link to a standalone answers form,
  keyed on a hash of their (newly generated) removal password
- Answers are echoed in the attendee confirmation email and sent to the
  host via the attendeeAwaitingApproval email, a new attendeeJoined
  email on every plain RSVP, and a new attendeeAnswered email when the
  standalone form is submitted; delivery failures are logged
- Multiple choice answers are re-validated server-side against the
  stored options, and validation failures on the plain-HTML forms
  redirect with a flash message instead of serving raw JSON
The nested-checkbox options list is now a stack of feature cards
(public listing, event group, comments, RSVPs), each with a
description and a toggle switch, the whole header row clickable.
RSVP settings - attendance requests, the attendee limit, and custom
questions - live inside the expanded RSVPs card.

- Attendance requests is a nested card with human-friendly copy
  explaining that the location stays hidden until the host approves
- The attendee limit checkbox and number field are merged into a
  single field whose empty state ('No limit') means no limit; the
  legacy checkbox value is derived at submit time
- The custom question builder gets stable client-side keys so Alpine
  doesn't leave stale inputs behind on mid-list removal
- Restores the semibold label styling that was lost at some point,
  with checkbox labels and host-authored question prompts kept at
  regular weight
- The first-load welcome banner (with its 'do not share this link'
  warning) was shown to whoever loaded the event or group page first,
  and that first view consumed the one-shot flag - so a visitor could
  both see the host-only message and prevent the host from ever seeing
  it. It is now gated on holding the edit token.
- The event group edit token field's label rendered its help text
  ('You can find this long string of characters...') because the label
  and the help text shared an i18n key; the label now has its own key.
The host's answer listing sized its question column to the longest
unwrapped prompt, so a long question (they can be 200 characters)
would overflow the attendee card. The column is now capped at half
the card width with wrapping, and on narrow screens each answer
stacks under its question instead of sharing a row.
Rewording a question can change what an existing answer means - 'Are
you vegan or vegetarian?' answered 'No', then reworded to 'Do you have
any dietary restrictions?', must not present that 'No' as answering
the new question. The host's answer listing now uses the prompt
snapshot stored with each answer (as deleted questions already did),
while unanswered questions show the current wording.
@lowercasename
lowercasename merged commit 8aa9136 into main Aug 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant