Cal.comdesign-system

Seat Confirmation Roster

Host drawer lists for a class that needs a yes for each person.

Use this inside the existing booking drawer when an event type has both Requires confirmation and Seats. The Unconfirmed list stays one row per session and does not say how many people are waiting. Opening that row is the drawer.

A normal meeting that needs confirmation stays booking-level Confirm / Reject. A class that does not need confirmation keeps today's attendees list and Remove seats.

Ownership

Feature โ€” not @coss/ui/shared. It knows about accepted seats, waiting people, and the seat limit. Shared pieces stay generic: SelectionList, Checkbox, Button, Badge, Alert.

The roster does not decide booking status. Once anyone has been accepted, the booking stays confirmed even if the room is later emptied. That rule stays in the caller. Waiting is everyone who is not confirmed: pending and rejected.

When to use it

Two in the room and three waiting. Accept on a waiting person sends that one id. Check several waiting people, then Accept or Reject that selection from the footer. The row Accept hides once anyone is checked, so the footer is the only commit. Remove on a person in the room sends that one id. The footer appears only once someone waiting is checked, and it shows how many are selected. Rejected people show a Rejected badge next to their name. A full room hides the checkboxes and the row Accept. A line under In the room says to remove someone to free a seat. Search filters the waiting list only, so the room stays visible.

Two in the room, three waiting

2 of 4 seats taken

In the room

Waiting

Everyone waiting, with none of the four seats taken.

Everyone waiting

0 of 4 seats taken

Waiting

Each person can carry a disclosure under their row. The drawer puts that seat's booking responses there, in both lists, so a host reads a waiting applicant's answers before accepting or rejecting them. A person with no answers gets no disclosure.

Answers readable before accepting

2 of 4 seats taken

In the room

Waiting

The room is full. Waiting people stay visible, without checkboxes, until someone in the room is removed.

Room already full

4 of 4 seats taken

In the room

Remove someone to free a seat.

Waiting

Twelve people already in the room, sixteen waiting, and no seats left. Search sits above both lists and filters the waiting list only. Each list stops at a fixed height and scrolls on its own. The waiting list stays read-only until a seat is free.

12 in the room, 16 waiting, no seats left

12 of 12 seats taken

In the room

Remove someone to free a seat.

Waiting

Copy into the drawer

Lists go in the drawer body, in place of the single attendees list. Buttons go in the existing DrawerFooter. The product fills labels with t(). The design-system app has no i18n provider, so the demos above use the English defaults.

apps/web/modules/bookings/components/booking-details-drawer.tsx

people is { id, name, email, group: "accepted" | "pending" | "rejected" }. id is the seat id the later mutation will send. Pending and rejected people share the waiting list. Pass the same labels to SeatConfirmationRosterActions. The actions render nothing until a waiting person is checked.

API

Selection rules live in packages/features/bookings/lib/seat-confirmation-selection.ts. Checking another person when none are left does not add them.

The lists scroll. There is no Previous / Next.

Internationalization

The component does not call t(). Demos use the English defaults. Add these keys to packages/i18n/locales/en/common.json when the drawer is wired, and pass them through labels. Accept, Reject, and Remove reuse accept, reject, and remove.

Call sites

Example URLs

Not in the product yet. The live demos on this page are the component.

Source