Adds the public Workshops page and keeps every sign-up on this site. The form is built once to the settled field set, so the same fields show at every width. A valid send is saved before anyone is emailed. The page names no price, and the member count never sets one.
Changes
/workshops in the marketing layout and the sitemap: hero, overview, circle, who runs it, quote, signup, then the existing Ask Organizer section.
Quote Block gains a citation layout for the lavender quote.
Signup is a normal form. With JavaScript it sends JSON. Without it, the same route accepts the POST, keeps the answers, and returns the confirmation or the form with errors.
New WorkshopInquiry table. The server checks every field, ignores a filled honeypot and a too-fast submit, and limits how often one address can send.
Organizations of 1,000 members or more are flagged large and see “Choose a time.” Smaller ones see “Download the kit.”
The team can read the latest inquiries and export a CSV at /workshop-inquiries. That page stays hidden until its token is set.
A purge route retries mail that did not go out, then deletes inquiries older than twelve months.
Screenshots
How to Test
Apply the new migration, then open /workshops.
Check the page at a phone width, around 800px, and at 1024px and wider. Every “Talk to a facilitator” button should land on the form.
Submit empty. Each required field should show its own message, and anything you typed should still be there.
Tick “Something else” and confirm the extra line appears. Send a complete form for an organization under 1,000 members, then one for 1,000 or more. The first confirmation offers the kit. The second offers a time.
With JavaScript off, submit once empty and once complete. You should come back to the same page with the errors or the confirmation.
Set WORKSHOP_INQUIRY_ADMIN_TOKEN, open /workshop-inquiries, and export the CSV. Unset, that page should 404.
Notes
Quote wording, the line under Send, and the note that links to /kit are the current frames and are still pending approval. /kit is not live yet.
Leave WORKSHOP_INQUIRY_TO empty until the inbox address is approved. The row still saves, and the inbox email waits.
NEXT_PUBLIC_WORKSHOP_SCHEDULING_URL is the “Choose a time” link. Unset, those words are text, not an empty link.
WORKSHOP_INQUIRY_ADMIN_TOKEN and WORKSHOP_INQUIRY_PURGE_TOKEN gate the team page and the purge job.
Twelve months is the proposed retention. Who reads the inquiries is still open.
## Overview
Adds the public Workshops page and keeps every sign-up on this site. The form is built once to the settled field set, so the same fields show at every width. A valid send is saved before anyone is emailed. The page names no price, and the member count never sets one.
## Changes
- `/workshops` in the marketing layout and the sitemap: hero, overview, circle, who runs it, quote, signup, then the existing Ask Organizer section.
- Quote Block gains a citation layout for the lavender quote.
- Signup is a normal form. With JavaScript it sends JSON. Without it, the same route accepts the POST, keeps the answers, and returns the confirmation or the form with errors.
- New `WorkshopInquiry` table. The server checks every field, ignores a filled honeypot and a too-fast submit, and limits how often one address can send.
- Organizations of 1,000 members or more are flagged large and see “Choose a time.” Smaller ones see “Download the kit.”
- The team can read the latest inquiries and export a CSV at `/workshop-inquiries`. That page stays hidden until its token is set.
- A purge route retries mail that did not go out, then deletes inquiries older than twelve months.
## Screenshots

## How to Test
1. Apply the new migration, then open `/workshops`.
2. Check the page at a phone width, around 800px, and at 1024px and wider. Every “Talk to a facilitator” button should land on the form.
3. Submit empty. Each required field should show its own message, and anything you typed should still be there.
4. Tick “Something else” and confirm the extra line appears. Send a complete form for an organization under 1,000 members, then one for 1,000 or more. The first confirmation offers the kit. The second offers a time.
5. With JavaScript off, submit once empty and once complete. You should come back to the same page with the errors or the confirmation.
6. Set `WORKSHOP_INQUIRY_ADMIN_TOKEN`, open `/workshop-inquiries`, and export the CSV. Unset, that page should 404.
## Notes
- Quote wording, the line under Send, and the note that links to `/kit` are the current frames and are still pending approval. `/kit` is not live yet.
- Leave `WORKSHOP_INQUIRY_TO` empty until the inbox address is approved. The row still saves, and the inbox email waits.
- `NEXT_PUBLIC_WORKSHOP_SCHEDULING_URL` is the “Choose a time” link. Unset, those words are text, not an empty link.
- `WORKSHOP_INQUIRY_ADMIN_TOKEN` and `WORKSHOP_INQUIRY_PURGE_TOKEN` gate the team page and the purge job.
- Twelve months is the proposed retention. Who reads the inquiries is still open.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Overview
Adds the public Workshops page and keeps every sign-up on this site. The form is built once to the settled field set, so the same fields show at every width. A valid send is saved before anyone is emailed. The page names no price, and the member count never sets one.
Changes
/workshopsin the marketing layout and the sitemap: hero, overview, circle, who runs it, quote, signup, then the existing Ask Organizer section.WorkshopInquirytable. The server checks every field, ignores a filled honeypot and a too-fast submit, and limits how often one address can send./workshop-inquiries. That page stays hidden until its token is set.Screenshots
How to Test
/workshops.WORKSHOP_INQUIRY_ADMIN_TOKEN, open/workshop-inquiries, and export the CSV. Unset, that page should 404.Notes
/kitare the current frames and are still pending approval./kitis not live yet.WORKSHOP_INQUIRY_TOempty until the inbox address is approved. The row still saves, and the inbox email waits.NEXT_PUBLIC_WORKSHOP_SCHEDULING_URLis the “Choose a time” link. Unset, those words are text, not an empty link.WORKSHOP_INQUIRY_ADMIN_TOKENandWORKSHOP_INQUIRY_PURGE_TOKENgate the team page and the purge job.