Skip to content

The CSV export sits in the signup header, away from the responses it downloads #559

Closed

Description

@richshaw

Before you start: read the design

This issue came out of a design session with the owner. The issue below is the full brief, but the design is drawn out on a canvas. Look at it before building:

  • The canvas: https://claude.ai/artifact/KRD1hJm8zADfXsxUJ5Wyxm (private to the owner's account, which pipeline sessions run under). Read it with the Artifact tool's read action, with paths. The boards that were agreed on:
    • project/Summary.dc.html: desktop, the version to build
    • project/PhoneSummary.dc.html: phone, the version to build
    • project/Empty.dc.html: the tab with no sign-ups
    • project/Before.dc.html: today's page, for comparison
    • project/Main.dc.html and project/Phone.dc.html are an earlier version without the summary line. Don't build those.
  • The session: https://claude.ai/code/session_01N9Vk9ngRY59GhUGDUKVoe4. Read its conversation with the claude-code-remote list_events tool (session_id: session_01N9Vk9ngRY59GhUGDUKVoe4, kinds: ["user", "assistant"]) to see why each choice was made. That session started from a screenshot of a real instance: don't copy any names, emails or slugs from it into code, tests or the PR.

What happens

An organizer on the Responses tab who wants the list as a spreadsheet looks for a download there, and there isn't one. The button is up in the signup header (SignupHeader in src/components/signup/SignupHeader.tsx), labelled Export, next to Preview and Publish / Close signup. On a phone it's inside the ⋯ menu as Export responses (MobileMoreMenuSheet). The Responses tab (src/app/app/(chrome)/signups/[id]/responses/page.tsx) has to point at it: "Everyone who's signed up so far. Export to CSV from the header."

  • Wrong place. The header holds actions on the whole signup. Export is about the responses, so people look for it next to the table.
  • Vague label. "Export" next to Preview and Publish doesn't say it downloads a spreadsheet of who signed up.
  • Shows where it means nothing. It sits on the Build and Settings tabs, and on drafts nobody can sign up to yet.

Fix, in outline

  • Move the download onto the Responses tab. Put a bar above the table: a summary line on the left, a Download CSV button on the right (outlined, download icon, not brand blue: blue stays for Publish / Close). It links to the existing /api/signups/[id]/export.csv. Use a plain <a href>, not next/link: it's a file download, not a page, so the router has nothing to do. The route already sends content-disposition: attachment.
  • On a phone, two rows. The summary on its own line, then Download CSV full width underneath, at least 44px tall. Don't squeeze them onto one row.
  • The summary line reads e.g. "5 sign-ups · 1 cancelled · 1 removed":
    • Sign-ups is the same number as the tab's badge: active commitments (ACTIVE_COMMITMENT_STATUSES). Say "sign-ups", not "people" or "signed up": one person can hold several. "1 sign-up" in the singular. The number is semibold in ink, the rest muted.
    • Cancelled counts rows whose status is cancelled that howCommitmentsEnded doesn't mark. Removed counts the ones it marks removed. These match the status pills in the table.
    • Moves are left out. The old half of a move (moved) isn't someone dropping out: their new sign-up is already counted.
    • Zero parts are left out. No "· 0 cancelled".
    • Work it out from the commitments and ended the page already loads. No new query.
  • No sign-ups at all: no bar. The existing "No signups yet. Share the public link to start collecting." box is enough. If every row is cancelled or removed, the table shows, so the bar and download show too ("0 sign-ups · 2 cancelled").
  • Drop the sentence "Everyone who's signed up so far. Export to CSV from the header."
  • Take Export out of the header (SignupHeader). Its grid goes to Preview plus Publish or Close, or Preview alone when there's neither. Take Export responses out of MobileMoreMenuSheet.

Watch for

  • The ⋯ menu can end up empty. With Export gone, MobileMoreMenuSheet holds only Publish (draft) or Close signup (open). For a closed or archived signup it would open an empty sheet. Hide the ⋯ button in MobileSignupHeader when the status is neither draft nor open.
  • The phone layout of the table is a careful mix of table roles and grid (see the comment in the Responses page). Put the bar outside the table's box and leave the table markup alone.
  • Help pages. No article mentions Export today. take-someone-off-a-slot and create-and-publish-a-signup walk through the Responses tab. Run the help-pages skill's affected-articles.mjs on your branch, and if a screenshot of the Responses tab changes, re-take it with pnpm help:screenshots.
  • CHANGELOG. Add a line under Unreleased › Changed.
  • Budgets. The Responses page is a server component and this adds no client JavaScript. Run pnpm build && pnpm budgets to confirm the header's page budget doesn't go up, and lower it if it comes in under.
  • Overlapping PRs. Move the signup tabs into a (tabs) route group #527 moves the signup tab pages into a (tabs) route group, so whichever lands second has a small merge in the Responses page's path.
  • Tests that hit the export. tests/e2e/response-headers.spec.ts fetches export.csv directly and doesn't need to change.

Done when

  • The Responses tab shows the summary and Download CSV as in Summary.dc.html (desktop) and PhoneSummary.dc.html (phone). Clicking it downloads <slug>-responses.csv.
  • With no sign-ups there's no bar, only the empty-state box.
  • The header and the ⋯ menu no longer offer Export, and the ⋯ button doesn't open an empty sheet for a closed or archived signup.
  • A unit test pins the summary text: singular and plural, zero parts left out, moves not counted. Pull it into a small pure function so it can be tested.
  • A Playwright check on the Responses tab finds the Download CSV link with the export href.
  • pnpm lint && pnpm typecheck && pnpm knip && pnpm test pass.

From the owner, in a design session with Claude (the session and canvas linked at the top). Checked against main at a0b3f49: SignupHeader, MobileMoreMenuSheet, MobileSignupHeader, the Responses page, and howCommitmentsEnded / countActiveCommitmentsForSignup in src/services/commitments.ts. https://claude.ai/code/session_01N9Vk9ngRY59GhUGDUKVoe4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions