Skip to content

feat(dashboard): a registrations section for an event - #357

Closed
harshtandiya wants to merge 9 commits into
developfrom
version-2-dashboard-events-registrations
Closed

feat(dashboard): a registrations section for an event#357
harshtandiya wants to merge 9 commits into
developfrom
version-2-dashboard-events-registrations

Conversation

@harshtandiya

Copy link
Copy Markdown
Collaborator

Stacked on version-2-dashboard-events-guests.

Adds a Registrations section to the event workspace: two status tiles that
gate signup, and the ticket tiers the event sells.

Registration has no boolean behind it. Buzz Event only has
registrations_close_at, and are_registrations_closed() already derives
open/closed from it for the booking flow. So the toggle writes the cutoff:
off is now in the event's own timezone, on clears it. Consequence worth
knowing: an event that has already ended still reads Closed after
reopening — same answer the public page gives, so it is honest, not a bug.
If we want a real flag later, that is a doctype change plus booking-flow
work, not this PR.

Guest registration carries guest_verification_method in the same
dialog, since neither field means much without the other.

Ticket tiers read and insert straight through useList — they inherit
their event's team scope from the permission hooks, so no endpoint. Creation
only. Edit, delete and publish stay in Desk for now, and tickets_sold /
remaining_tickets are Python properties a list call cannot fetch, so rows
show title and price and nothing else.

No new endpoint anywhere. get_event grew four fields; writes go through
the frappe.client.set_value resource the details page already uses.

Also here: nowInZone in utils/timeZones.ts (Frappe's naive datetime, in
the event's zone) and the first Switch usage in this dashboard.

Checked: 40 buzz.api.events tests, 18 timeZones unit tests, typecheck,
pre-commit, and the chromium e2e project. One pre-existing failure there,
auth.spec.ts › should login via UI, which fails on a stashed tree too.

🤖 Generated with Claude Code

@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds an event registrations management section with registration and guest-booking controls plus ticket-tier creation.

  • Extends event details with registration and guest-booking state.
  • Adds registration settings dialogs and ticket-type listing and creation.
  • Adds the management route, navigation entry, timezone utility, and end-to-end coverage.

Confidence Score: 3/5

The PR does not appear safe to merge until registration closing uses the same timezone fallback semantics as backend enforcement.

Timezone-less events still persist the organizer browser’s wall clock while the backend evaluates the cutoff in the server timezone, and unresolvable event zones still silently persist the browser wall clock, so registration can remain open or close earlier than requested.

Files Needing Attention: dashboard/src/utils/timeZones.ts, dashboard/src/components/dashboard/events/EventRegistrationDialog.vue

Important Files Changed

Filename Overview
dashboard/src/utils/timeZones.ts Adds event-zone wall-clock formatting, but its null and error fallbacks still produce cutoffs in the browser timezone rather than the timezone used by backend registration enforcement.
dashboard/src/components/dashboard/events/EventRegistrationDialog.vue Adds registration open/close persistence and directly stores the timezone utility’s naive datetime result.
dashboard/src/pages/manage/events/EventRegistrations.vue Adds the registrations workspace, status controls, and ticket-tier list while forwarding the event’s nullable timezone to the cutoff dialog.
buzz/api/events/services.py Extends managed-event details with registration and guest-booking fields and derives the current registration status.
dashboard/src/components/dashboard/events/GuestRegistrationDialog.vue Adds coordinated controls for guest booking and its optional verification method.
dashboard/src/components/dashboard/events/TicketTypeDialog.vue Adds validated creation of event ticket tiers with price, currency, and optional capacity.
dashboard/src/data/tickets.ts Adds scoped ticket-type and enabled-currency list resources.
dashboard/src/router.ts Registers the static event registrations route before the dynamic management fallback.

Reviews (11): Last reviewed commit: "test(e2e): drive the registrations secti..." | Re-trigger Greptile

Comment thread dashboard/src/utils/timeZones.ts
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from dca02a6 to bf146a1 Compare August 17, 2026 10:44
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch 2 times, most recently from 4a99d7a to 9bf0e09 Compare August 17, 2026 13:30
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from bf146a1 to 262bade Compare August 17, 2026 13:30
Comment on lines +52 to +56
try {
return format(zone ?? undefined)
} catch {
// An event carrying a zone this runtime cannot resolve falls back to the browser's.
return format()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Fallback shifts registration cutoff

When an event contains an invalid, obsolete, or browser-unsupported timezone, nowInZone falls back to the organizer's browser timezone. The backend then interprets that naive timestamp in the event timezone, causing registration to close earlier or later than requested.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: dashboard/src/utils/timeZones.ts
Line: 52-56

Comment:
**Fallback shifts registration cutoff**

When an event contains an invalid, obsolete, or browser-unsupported timezone, `nowInZone` falls back to the organizer's browser timezone. The backend then interprets that naive timestamp in the event timezone, causing registration to close earlier or later than requested.

**Knowledge Base Used:**
- [Events domain](https://app.greptile.com/bwh-tech/-/custom-context/knowledge-base/bwhtech/buzz/-/docs/events-domain.md)
- [Public booking flow](https://app.greptile.com/bwh-tech/-/custom-context/knowledge-base/bwhtech/buzz/-/docs/booking-flow.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from 262bade to eef8f42 Compare August 19, 2026 06:14
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from 9bf0e09 to d4e6c72 Compare August 19, 2026 06:14
@github-actions

Copy link
Copy Markdown
Contributor

❌ UI Demo Check failed

This pull request changes the UI (11 file(s) under dashboard/src/),
but the description has no screenshot or demo. Reviewers should be able to see the
change without checking out the branch.

🛠️ How to fix

  • Edit the description and drag a screenshot or a short screen recording into it.
    Before/after images are ideal for visual tweaks.
  • Or apply the skip-demo label if a visual makes no sense here
    (pure refactor, copy change, dependency bump).

Either one re-runs this check automatically.

@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from d4e6c72 to abf8c38 Compare August 19, 2026 07:20
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from eef8f42 to 1ab6f08 Compare August 19, 2026 07:20
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from abf8c38 to 7463e7e Compare August 21, 2026 08:14
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from 1ab6f08 to 5f7cb40 Compare August 25, 2026 17:49
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from 7463e7e to 14b0dd6 Compare August 25, 2026 17:49
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from 5f7cb40 to d54e43e Compare August 25, 2026 20:36
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from 14b0dd6 to 53eecac Compare August 25, 2026 20:36
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from d54e43e to b15748b Compare August 25, 2026 20:47
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from 53eecac to 3353f4d Compare August 25, 2026 20:47
harshtandiya and others added 4 commits August 27, 2026 00:59
Attendees becomes Guests in the event sidebar, and the destination is now
a page rather than the placeholder: everyone holding a ticket, listed by
name.

Only submitted tickets count — a draft is a booking still being paid for,
not somebody coming. The team permission hooks already scope Event Ticket,
so the list is a plain query with no endpoint behind it.

The page header both event pages share moves into EventPageHeader, with
the section name as a prop and a slot for whatever the page puts on the
right.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A count of registrations sits above the list, and a row now carries the
person rather than just their name: avatar, name, email, the add-ons they
picked as badges, and the ticket type they hold.

Add-ons live in a child table, which a plain list query cannot reach, so
the page moves onto get_event_guests. Both the ticket type and the add-ons
are named rather than numbered — Event Ticket Type and Ticket Add-on are
autonamed, so the link value on its own is a docname nobody recognises.
Their titles are looked up in one query each, keyed by string, since an
autonamed doctype returns integer names while every link to it travels as
a string.

Read access is the bar, not write: the list shows the team what the
doctype already shows it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The border was packaging around a number that reads fine without it, and
the box stretched the full column to hold two short lines.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The page opens on how the event is doing — the number registered, and
whether registrations are still open — then the list itself, searchable by
name or email. Filtering happens over the list already loaded, so a
keystroke costs nothing.

Whether registrations are closed is the booking flow's own rule, reused
rather than restated: an explicit cutoff if the event sets one, otherwise
the end of the event.

A guest row now reads as a line rather than a stack, with the email beside
the name — it is what tells two people of the same name apart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from 3353f4d to 23d20d0 Compare August 26, 2026 19:37
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-guests branch from b15748b to 21ebcd6 Compare August 26, 2026 19:37
harshtandiya and others added 4 commits August 27, 2026 01:16
The page labelled its header from `get_event`, which is gated on write because
it backs the edit form. A member with read access could load the guest list but
not the name of the event it belonged to, so the header fell back to "Event".

The guest payload already fetches the event to work out whether registrations
have closed, so the title comes off a document that was loaded anyway — and the
page drops a request rather than gaining one.
The manage page needs three things the detail payload did not carry: when
registrations close, whether they are closed right now, and how guests are
let in.

`registrations_closed` is derived rather than stored — `Buzz Event` has no
accept-registrations flag, so an event with no cutoff still closes once it
has ended. `are_registrations_closed` already answers that for the booking
flow and reads only the fields DETAIL_FIELDS carries, so it takes the row
as-is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closing registration means "closed as of right now", and Frappe stores
Datetime without an offset, so the value written has to be the event's local
time rather than the browser's. The Swedish locale already formats in
Frappe's shape, which saves assembling it part by part.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Everything that decides whether people can sign up, in one place: two status
tiles above the ticket tiers the event sells.

Registration has no boolean behind it, so its dialog writes the cutoff —
off is now in the event's timezone, on clears it. An event that has already
ended still reads Closed after reopening, which is the same answer the
public page gives. Guest registration carries its verification method in
the same dialog, since neither field means much without the other.

Ticket tiers are read and inserted straight through `useList`: the tiers
inherit their event's team scope from the permission hooks, so no endpoint
of their own. Only creation for now — edit, delete and publish are still
Desk work, and the sold counters are Python properties a list call cannot
carry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Each toggle test reads the shared event's current state and puts it back,
rather than assuming how a previous run left it. Two things the tree makes
awkward: an open dialog hides the tile behind it, so the state has to be
read before clicking, and the select is a custom listbox rather than a
native one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-registrations branch from 23d20d0 to e13531d Compare August 26, 2026 19:46
Base automatically changed from version-2-dashboard-events-guests to develop August 26, 2026 19:53
@harshtandiya
harshtandiya deleted the version-2-dashboard-events-registrations branch August 26, 2026 19:55
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