Skip to content

feature: Admin UI for creating and updating RsvpEvent(s) - #492

Merged
leesheppard merged 10 commits into
rubyaustralia:mainfrom
sidbhatt11:feature/admin-events-ui
Jul 25, 2026
Merged

feature: Admin UI for creating and updating RsvpEvent(s)#492
leesheppard merged 10 commits into
rubyaustralia:mainfrom
sidbhatt11:feature/admin-events-ui

Conversation

@sidbhatt11

Copy link
Copy Markdown
Contributor

[feature: Admin UI for RsvpEvent]

[extra goodies]

  • Adds a test helper for "time travelling" (similar to timecop)
    This was necessary because of a validation rule I added on RsvpEvent#happens_at which prevents creating events in the past from the UI. Some tests were using hard-coded timestamps to create RsvpEvent models. This helper allows them to remain frozen in time.
  • Added eslint.config.js > ignores because it was trying to lint everything

[screenshots]

admin-events-form admin-events-index admin-side-menu-bar

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an Admin interface for managing RsvpEvent records (listing, creating, and editing) in the Rails app, including clearer time rendering (UTC + viewer-local) and supporting test infrastructure to keep time-dependent specs stable.

Changes:

  • Added Admin::RsvpEventsController, routes, navigation entry, and admin views (index/new/edit + shared form) for RsvpEvent management.
  • Updated RsvpEvent to resolve a submitted “wall clock + selected zone” into a stored UTC instant, and added a “not in the past” validation on create.
  • Added a time_travel_to: RSpec helper and updated existing specs; added a new feature spec covering the admin flows.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
spec/support/time_travel.rb Adds time_travel_to: metadata to freeze time in specs via travel_to.
spec/lib/campaigns/event_spec.rb Pins spec time to avoid date-dependent failures.
spec/helpers/campaigns_helper_spec.rb Pins spec time to avoid date-dependent failures.
spec/features/admin_event_management_spec.rb Adds feature coverage for new admin event create/edit flows.
eslint.config.js Adds ignore globs to prevent linting non-source directories.
config/routes.rb Exposes admin routes for rsvp_events (index/new/create/edit/update).
app/views/shared/_navigation.html.erb Adds “Events” link to the committee-only nav.
app/views/admin/rsvp_events/new.html.erb New-event page wrapper rendering the shared form.
app/views/admin/rsvp_events/index.html.erb Events listing with UTC + local-time rendering and edit action.
app/views/admin/rsvp_events/edit.html.erb Edit-event page wrapper rendering the shared form.
app/views/admin/rsvp_events/_form.html.erb Shared form for create/update (title, happens_at, time zone).
app/models/rsvp_event.rb Adds time zone resolution logic and new validations/scope behavior.
app/frontend/controllers/local_time_controller.js Stimulus controller to render viewer-local time from <time datetime="...">.
app/controllers/admin/rsvp_events_controller.rb CRUD endpoints (index/new/create/edit/update) with strong params and not-found handling.
Comments suppressed due to low confidence (3)

app/views/admin/rsvp_events/_form.html.erb:36

  • datetime_select is constrained to start_year: Time.current.year, which can exclude an existing event’s year when editing older events (making the selected value unavailable in the dropdown). Include the event’s year in the selectable range.
    <%= form.datetime_select :happens_at,
                            { selected: event.happens_at&.utc || Time.current.in_time_zone("Australia/Sydney"), start_year: Time.current.year },
                            {

app/views/admin/rsvp_events/_form.html.erb:43

  • The time zone dropdown options are limited to country_zones("AU"), but the default is set to "UTC" when editing (event.happens_at.present?). Since "UTC" isn’t in that list, the default/selected value won’t actually be applied.
    <%= form.time_zone_select :time_zone,
                              ActiveSupport::TimeZone.country_zones("AU"),
                              { required: true, default: event.happens_at.present? ? "UTC" : "Sydney" },
                              { class: "px-1 py-0.5 rounded-sm border-gray-300 shadow-sm focus:border-ruby-red focus:ring focus:ring-ruby-red focus:ring-opacity-50 text-sm sm:text-base" } %>

app/views/admin/rsvp_events/index.html.erb:54

  • The empty-state row uses colspan="4", but the table only has 3 columns (Title / Happens At / Actions). This can render misaligned table layout in some browsers.
              <td colspan="4" class="px-4 sm:px-6 py-8 text-center text-sm text-gray-500">

Comment thread app/views/admin/rsvp_events/_form.html.erb Outdated
Comment thread app/models/rsvp_event.rb
Comment thread spec/features/admin_event_management_spec.rb Outdated
Comment thread app/views/admin/rsvp_events/index.html.erb Outdated
@sidbhatt11

Copy link
Copy Markdown
Contributor Author

the copilot review is very useful! I will update the PR soon 👍

add routes, controller methods for index and create,
:index and :new views, a reusable _form partial,
convenience methods and validations on the rsvp_event model
to build out listing and creation journeys.
as there is nothing to show in an event.
the index page already shows everything (title + timestamps)
in the admin/rsvp_events/index page.

we do not store the event timestamp's timezone in any column
so this is the compromise until we decide to add a column
There was a bug with event.happens_at where the Time.use_zone block
was not having any effect on correcting the "happens_at" timezone (e.g.
Perth -> UTC).

Fixed this by moving the TZ -> UTC transaltion logic to before_validation
hook inside RsvpEvent model. This keeps the controller small too.

Also redirect to the events index after create — the show route was removed, so
the previous redirect_to admin_rsvp_event_path 404'd on success.
in the :new view "happens_at" field defaults to current time
in Sydney, while in the :edit view it defaults to the time in
UTC as we do not have the original timezone stored anywhere.
because eslint was looking at things it didn't need to
one for presence (always on)
one for making sure that when creating new events,
admins can't use a date in the past
Some specs use hard-coded timestamps for RsvpEvent#happens_at.
This doesn't work since we have added a validation rule that
prevents creation of RsvpEvents in the past.

This change adds a timecop-like wrapper for those tests
so that they continue passing correctly without relying on
relative future time or other tricks.
- prefer happens_at.utc.iso8601 instead of happens_at.iso8601 in <time>
  in the rsvp_event/index view
- correct error message copy to say "saved" instead of "created"
  as the rsvp_event/_form is reused for both :new and :edit views
- use "time_travel_to" helper in "Admin Event Management" spec
  otherwise the tests will fail due to model validations kicking in
  past the hard-coded dates
@leesheppard
leesheppard force-pushed the feature/admin-events-ui branch from 852ae76 to 2968797 Compare July 25, 2026 03:28
@github-project-automation github-project-automation Bot moved this from Todo to Done in RubyAU Community PM Jul 25, 2026
@leesheppard
leesheppard merged commit 89e6732 into rubyaustralia:main Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants