Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/controllers/concerns/event_registration_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module EventRegistrationSession
extend ActiveSupport::Concern

private

def store_event_reg_slug(event_id, slug)
session[:event_reg_slugs] ||= {}
session[:event_reg_slugs][event_id.to_s] = slug
end

def clear_event_reg_slug(event_id)
return unless session[:event_reg_slugs]
session[:event_reg_slugs].delete(event_id.to_s)
end

def event_reg_slug_for(event_id)
session.dig(:event_reg_slugs, event_id.to_s)
end
end
2 changes: 2 additions & 0 deletions app/controllers/events/public_registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Events
class PublicRegistrationsController < ApplicationController
include EventRegistrationSession
skip_before_action :authenticate_user!, only: [ :new, :create, :show ]
before_action :set_event
before_action :ensure_registerable, only: [ :new, :create ]
Expand Down Expand Up @@ -53,6 +54,7 @@ def create
)

if result.success?
store_event_reg_slug(@event.id, result.event_registration.slug)
redirect_to registration_ticket_path(result.event_registration.slug),
notice: "You have been successfully registered!"
else
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/events/registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
module Events
class RegistrationsController < ApplicationController
include EventRegistrationSession
before_action :authenticate_user!, only: [ :create, :destroy ]
before_action :set_event, only: [ :create, :destroy ]
before_action :set_registrant, only: [ :create, :destroy ]
before_action :set_event_registration, only: [ :show, :resend_confirmation, :cancel, :reactivate ]

def show
authorize! @event_registration, to: :show_public?
store_event_reg_slug(@event_registration.event_id, @event_registration.slug) if @event_registration.active?
end

def resend_confirmation
Expand All @@ -20,6 +22,7 @@ def cancel

if @event_registration.active?
@event_registration.update!(status: "cancelled")
clear_event_reg_slug(@event_registration.event_id)
redirect_to registration_ticket_path(@event_registration.slug), notice: "Your registration has been cancelled."
else
redirect_to registration_ticket_path(@event_registration.slug), alert: "Registration is already cancelled."
Expand All @@ -31,6 +34,7 @@ def reactivate

if @event_registration.status == "cancelled"
@event_registration.update!(status: "registered")
store_event_reg_slug(@event_registration.event_id, @event_registration.slug)
redirect_to registration_ticket_path(@event_registration.slug), notice: "Your registration has been reactivated."
else
redirect_to registration_ticket_path(@event_registration.slug), alert: "Registration is not cancelled."
Expand All @@ -43,6 +47,7 @@ def create
if existing&.status == "cancelled"
authorize! existing
existing.update!(status: "registered")
store_event_reg_slug(@event.id, existing.slug)
success = "Your registration has been reactivated."
respond_to do |format|
format.turbo_stream { flash.now[:notice] = success }
Expand All @@ -55,6 +60,7 @@ def create
authorize! @event_registration

if @event_registration.save
store_event_reg_slug(@event.id, @event_registration.slug)
success = "You have successfully registered for this event."
respond_to do |format|
format.turbo_stream { flash.now[:notice] = success }
Expand Down
10 changes: 9 additions & 1 deletion app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class EventsController < ApplicationController
include AhoyTracking, TagAssignable
include AhoyTracking, TagAssignable, EventRegistrationSession
skip_before_action :authenticate_user!, only: [ :index, :show ]
skip_before_action :verify_authenticity_token, only: [ :preview ]
before_action :set_event, only: %i[ show edit update destroy preview manage copy_registration_form ]
Expand All @@ -8,12 +8,14 @@ def index
authorize!
base_scope = authorized_scope(Event.all)
@events = base_scope.search_by_params(params).order(start_date: :desc)
persist_reg_slug_from_params
end

def show
authorize! @event
@event = @event.decorate
track_view(@event)
persist_reg_slug_from_params
end

def new
Expand Down Expand Up @@ -228,6 +230,12 @@ def set_event
@event = Event.find(params[:id])
end

def persist_reg_slug_from_params
return unless params[:reg].present?
reg = EventRegistration.find_by(slug: params[:reg])
store_event_reg_slug(reg.event_id, reg.slug) if reg&.active?
end

def event_params
params.require(:event).permit(:cost,
:created_by_id,
Expand Down
10 changes: 10 additions & 0 deletions app/views/events/_card.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@

<!-- Location + Times + Buttons (bottom-aligned group) -->
<% registered = current_user && event.actively_registered?(current_user.person) %>
<% unless registered
reg_slug = session.dig(:event_reg_slugs, event.id.to_s)
slug_registration = reg_slug ? EventRegistration.find_by(slug: reg_slug, event_id: event.id) : nil
slug_registered = slug_registration&.active?
end %>
<div class="mt-auto flex flex-col gap-4">
<div class="text-sm text-gray-700 leading-none">
<% if event.location.present? %>
Expand All @@ -55,6 +60,11 @@
data: { turbo_frame: "_top" },
class: "btn px-3 py-2 text-xs uppercase leading-tight text-white hover:bg-white event-view-registration-btn",
style: "font-family: 'Telefon Bold', sans-serif; background-color: rgb(22, 101, 52); border: 2px solid rgb(22, 101, 52);" %>
<% elsif slug_registered %>
<%= link_to "View registration", registration_ticket_path(slug_registration.slug),
data: { turbo_frame: "_top" },
class: "btn px-3 py-2 text-xs uppercase leading-tight text-white hover:bg-white event-view-registration-btn",
style: "font-family: 'Telefon Bold', sans-serif; background-color: rgb(22, 101, 52); border: 2px solid rgb(22, 101, 52);" %>
<% elsif event.ended? %>
<span class="text-sm text-gray-500 italic">Event ended</span>
<% if allowed_to?(:manage?, event) %>
Expand Down
3 changes: 2 additions & 1 deletion app/views/events/_registration_section.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<% instance ||= 1 %>
<% button_text ||= "Register" %>
<% registered = event.actively_registered?(current_user&.person) %>
<% slug_registration = params[:reg].present? ? EventRegistration.find_by(slug: params[:reg], event_id: event.id) : nil %>
<% reg_slug = params[:reg].presence || session.dig(:event_reg_slugs, event.id.to_s) %>
<% slug_registration = reg_slug ? EventRegistration.find_by(slug: reg_slug, event_id: event.id) : nil %>
<% slug_registered = slug_registration&.active? %>
<% slug_cancelled = slug_registration.present? && slug_registration.status == "cancelled" %>
<%= tag.div id: dom_id(event.object, "registration_section_#{instance}"), class: "registration-section flex flex-col items-center gap-4 mb-6" do %>
Expand Down
5 changes: 3 additions & 2 deletions app/views/events/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
<% else %>
<!-- Top Right Actions -->
<div class="flex flex-wrap items-center gap-2 mb-4">
<%= link_to "← Back to Events", events_path, class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
<% reg_slug = params[:reg].presence || session.dig(:event_reg_slugs, @event.id.to_s) %>
<%= link_to "← Back to Events", events_path(reg: reg_slug), class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
<div class="ml-auto flex flex-wrap gap-2">
<%= link_to "Home", root_path, class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
<%= link_to "Events", events_path, class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
<%= link_to "Events", events_path(reg: reg_slug), class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
<% if allowed_to?(:manage?, @event) && @event.object.event_forms.registration.exists? %>
<%= link_to "Register (as visitor)", new_event_public_registration_path(@event), class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1 admin-only bg-blue-100" %>
<% end %>
Expand Down
39 changes: 39 additions & 0 deletions spec/requests/events/registrations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@
get registration_ticket_path(registration.slug)
expect(response).to have_http_status(:success)
end

it "stores the slug in session for active registrations" do
get registration_ticket_path(registration.slug)
expect(session[:event_reg_slugs]).to eq({ event.id.to_s => registration.slug })
end
end

context "when the registration is cancelled" do
before { registration.update!(status: "cancelled") }

it "does not store the slug in session" do
get registration_ticket_path(registration.slug)
expect(session[:event_reg_slugs]).to be_nil
end
end

context "as an admin" do
Expand Down Expand Up @@ -91,6 +105,15 @@
expect(flash[:notice]).to eq("Your registration has been cancelled.")
end

it "clears the slug from session" do
# First store the slug via show
get registration_ticket_path(registration.slug)
expect(session[:event_reg_slugs][event.id.to_s]).to eq(registration.slug)

post registration_cancel_path(registration.slug)
expect(session[:event_reg_slugs][event.id.to_s]).to be_nil
end

it "does not cancel an already cancelled registration" do
registration.update!(status: "cancelled")

Expand Down Expand Up @@ -123,6 +146,11 @@
expect(flash[:notice]).to eq("Your registration has been reactivated.")
end

it "stores the slug in session after reactivation" do
post registration_reactivate_path(registration.slug)
expect(session[:event_reg_slugs]).to eq({ event.id.to_s => registration.slug })
end

it "does not reactivate an already active registration" do
registration.update!(status: "registered")

Expand Down Expand Up @@ -193,6 +221,12 @@
expect(response.media_type).to eq("text/vnd.turbo-stream.html")
expect(flash.now[:notice]).to eq("You have successfully registered for this event.")
end

it "stores the slug in session" do
post event_registrant_registration_path(event_id: event.id)
reg = EventRegistration.last
expect(session[:event_reg_slugs]).to eq({ event.id.to_s => reg.slug })
end
end

context "when a cancelled registration exists" do
Expand All @@ -218,6 +252,11 @@
expect(response).to redirect_to(registration_ticket_path(cancelled_registration.slug))
expect(flash[:notice]).to eq("Your registration has been reactivated.")
end

it "stores the slug in session on reactivation" do
post event_registrant_registration_path(event_id: event.id)
expect(session[:event_reg_slugs]).to eq({ event.id.to_s => cancelled_registration.slug })
end
end

context "when creation fails" do
Expand Down
23 changes: 23 additions & 0 deletions spec/requests/events_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
expect(response).to have_http_status(:ok)
end

it "stores reg slug in session when reg param is present" do
sign_in user
registration = create(:event_registration, event: event, registrant: create(:person))
get events_path(reg: registration.slug)
expect(session[:event_reg_slugs]).to eq({ event.id.to_s => registration.slug })
end

context "when user time_zone is set" do
# 19:00 UTC = 12:00 noon PT = 15:00 (3 pm) ET (June 15, 2025 with DST)
let(:utc_start) { Time.utc(2025, 6, 15, 19, 0, 0) }
Expand Down Expand Up @@ -63,6 +70,22 @@
end
end

describe "GET /show" do
it "stores reg slug in session when reg param is present" do
sign_in user
registration = create(:event_registration, event: event, registrant: create(:person))
get event_path(event, reg: registration.slug)
expect(session[:event_reg_slugs]).to eq({ event.id.to_s => registration.slug })
end

it "does not store slug for cancelled registrations" do
sign_in user
registration = create(:event_registration, event: event, registrant: create(:person), status: "cancelled")
get event_path(event, reg: registration.slug)
expect(session[:event_reg_slugs]).to be_nil
end
end

describe "GET /new" do
context "as admin" do
it "renders successfully" do
Expand Down