Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
module Events
class PublicRegistrationsController < ApplicationController
class PublicFormsController < ApplicationController
HEADINGS = {
"registration" => "Registration",
"scholarship" => "Scholarship application",
"bulk_payment" => "Bulk payment",
"ce_credit" => "Continuing education credit"
}.freeze

skip_before_action :authenticate_user!, only: [ :new, :create, :show ]
before_action :set_event
before_action :ensure_registerable, only: [ :new, :create ]

rescue_from ActionController::InvalidAuthenticityToken do
flash[:alert] = "Your session has expired. Please try submitting the form again."
redirect_to new_event_public_registration_path(@event)
redirect_to public_form_new_path
end

def new
authorize! :public_registration, to: :new?
authorize! :public_form, to: :new?

@form = registration_form
unless @form
Expand All @@ -25,10 +32,10 @@ def new
end

def create
authorize! :public_registration, to: :create?
authorize! :public_form, to: :create?

if params[:public_registration][:website_url].present?
redirect_to new_event_public_registration_path(@event)
redirect_to public_form_new_path
return
end

Expand Down Expand Up @@ -76,7 +83,7 @@ def create
end

def show
authorize! :public_registration, to: :show?
authorize! :public_form, to: :show?

if params[:reg].present?
registration = EventRegistration.find_by!(slug: params[:reg], event_id: @event.id)
Expand Down Expand Up @@ -148,9 +155,31 @@ def registration_form
@event.registration_form
end

def form_role
EventForm::ROLES.include?(params[:form_role]) ? params[:form_role] : "registration"
end

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: form_variant is whitelisted against VARIANTS and falls back to "registration", so an unknown variant in the URL degrades to the default flow rather than blowing up the path helpers below.

helper_method :form_role

def scholarship_mode?
params[:scholarship_requested] == "true"
if form_role == "scholarship"
params[:scholarship_requested] != "false"
else
params[:scholarship_requested] == "true"
end

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Scholarship default differs by variant: the scholarship_form flow opts in unless scholarship_requested=false, while other flows opt in only when explicitly =true. This preserves the existing query-param behavior for the registration flow.

end

def public_form_new_path
send("new_event_#{form_role}_form_path", @event)
end

def public_form_submit_path
send("event_#{form_role}_form_path", @event)
end

def public_form_heading
HEADINGS.fetch(form_role)
end
helper_method :public_form_new_path, :public_form_submit_path, :public_form_heading

def split_form_params(all_params)
reg_field_ids = @form.form_fields.pluck(:id).map(&:to_s)
Expand Down
8 changes: 4 additions & 4 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ def self.search_by_params(params)
stories
end

def registration_form
forms.find_by(event_forms: { role: "registration" })
def form_for_role(role)
forms.find_by(event_forms: { role: role.to_s })
end

def scholarship_form
forms.find_by(event_forms: { role: "scholarship" })
EventForm::ROLES.each do |role_name|
define_method("#{role_name}_form") { form_for_role(role_name) }
end

def active_registration_for(person)
Expand Down
7 changes: 4 additions & 3 deletions app/models/event_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ class EventForm < ApplicationRecord
belongs_to :event
belongs_to :form

ROLES = %w[registration scholarship].freeze
ROLES = %w[registration scholarship bulk_payment ce_credit].freeze

validates :role, presence: true, inclusion: { in: ROLES }
validates :form_id, uniqueness: { scope: [ :event_id, :role ] }

scope :registration, -> { where(role: "registration") }
scope :scholarship, -> { where(role: "scholarship") }
ROLES.each do |role_name|
scope role_name, -> { where(role: role_name) }
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class Events::PublicRegistrationPolicy < ApplicationPolicy
class Events::PublicFormPolicy < ApplicationPolicy
def new?
true
end
Expand Down
2 changes: 1 addition & 1 deletion app/views/event_registrations/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
<% end %>

<% submissions.each_with_index do |(form_name, ts), i| %>
<%= link_to event_public_registration_path(f.object.event, **form_show_params),
<%= link_to event_registration_form_path(f.object.event, **form_show_params),
class: "group inline-flex items-center gap-1.5 font-medium #{DomainTheme.text_class_for(:event_registrations, intensity: 600)} hover:underline",
target: "_blank",
title: "#{form_name} — submitted #{ts.strftime('%b %-d, %Y')}",
Expand Down
2 changes: 1 addition & 1 deletion app/views/event_registrations/_ticket.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<% registration_form = event_registration.event.registration_form %>
<% if registration_form && registration_form.form_submissions.exists?(person: event_registration.registrant) %>
<%= link_to "View registration details",
event_public_registration_path(event_registration.event, reg: event_registration.slug),
event_registration_form_path(event_registration.event, reg: event_registration.slug),
class: "text-xs text-gray-400 hover:text-blue-600 underline" %>
<% end %>
<%= button_to "Resend confirmation email",
Expand Down
4 changes: 2 additions & 2 deletions app/views/events/_card.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<% if user_signed_in? %>
<% if event.object.registration_form&.form_fields&.any? %>
<%= link_to "Register",
new_event_public_registration_path(event),
new_event_registration_form_path(event),
data: { turbo_frame: "_top" },
class: "btn px-3 py-2 text-xs uppercase leading-tight font-telefon text-accent border-2 border-accent hover:text-white hover:bg-orange-700" %>
<% else %>
Expand All @@ -88,7 +88,7 @@
<% end %>
<% elsif event.object.public_registration_enabled? && event.object.event_forms.registration.exists? %>
<%= link_to "Register",
new_event_public_registration_path(event),
new_event_registration_form_path(event),
data: { turbo_frame: "_top" },
class: "btn px-3 py-2 text-xs uppercase leading-tight font-telefon text-accent border-2 border-accent hover:text-white hover:bg-orange-700" %>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/events/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@
</p>
<% if @event.event_forms.registration.exists? %>
<%= link_to "View public registration page",
new_event_public_registration_path(@event),
new_event_registration_form_path(@event),
class: "text-sm text-blue-700 hover:text-blue-900 underline",
target: "_blank" %>
<% end %>
Expand Down
5 changes: 3 additions & 2 deletions app/views/events/_form_actions_menu.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
class="hidden absolute right-0 z-10 mt-1 bg-white border border-gray-200 rounded-md shadow-lg py-1 min-w-[180px]">
<% if @event.event_forms.registration.exists? || @event.scholarship_form %>
<% if @event.event_forms.registration.exists? %>
<%= link_to "Public registration", new_event_public_registration_path(@event, as_visitor: true), class: item_class, target: "_blank", rel: "noopener noreferrer" %>
<%= link_to "Public registration", new_event_registration_form_path(@event, as_visitor: true), class: item_class, target: "_blank", rel: "noopener noreferrer" %>
<%= link_to "Bulk payment", new_event_bulk_payment_form_path(@event, as_visitor: true), class: item_class, target: "_blank", rel: "noopener noreferrer" %>
<% end %>
<% if @event.scholarship_form %>
<%= link_to "Scholarship version", new_event_public_registration_path(@event, scholarship_requested: true, as_visitor: true), class: item_class, target: "_blank", rel: "noopener noreferrer" %>
<%= link_to "Scholarship version", new_event_scholarship_form_path(@event, as_visitor: true), class: item_class, target: "_blank", rel: "noopener noreferrer" %>
<% end %>
<div class="my-1 border-t border-gray-100"></div>
<%= link_to "Change base form", edit_event_path(@event, anchor: "registration_form_section"), class: item_class %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/events/_registrants_results.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<% form_show_params = registration.slug.present? ? { reg: registration.slug } : { person_id: person.id } %>
<% tooltip_parts = submissions.map { |name, ts| "#{name} — Submitted #{ts.strftime('%B %d, %Y at %l:%M %P')}" } %>
<% tooltip_parts << "Scholarship requested" if registration.scholarship_requested? %>
<%= link_to event_public_registration_path(@event, **form_show_params),
<%= link_to event_registration_form_path(@event, **form_show_params),
class: "text-green-600 hover:text-green-800",
title: tooltip_parts.join("\n"),
target: "_blank",
Expand Down
4 changes: 2 additions & 2 deletions app/views/events/_registration_section.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<% if user_signed_in? %>
<% if event.object.registration_form&.form_fields&.any? %>
<%= link_to button_text,
new_event_public_registration_path(event),
new_event_registration_form_path(event),
class: "btn px-10 py-2 text-2xl uppercase text-white hover:bg-white event-register-btn",
style: "font-family: 'Telefon Bold', sans-serif; background-color: rgb(170, 46, 0); border: 3px solid rgb(170, 46, 0);" %>
<% else %>
Expand All @@ -35,7 +35,7 @@
<% end %>
<% elsif event.object.public_registration_enabled? && event.object.event_forms.registration.exists? %>
<%= link_to button_text,
new_event_public_registration_path(event),
new_event_registration_form_path(event),
class: "btn px-10 py-2 text-2xl uppercase text-white hover:bg-white event-register-btn",
style: "font-family: 'Telefon Bold', sans-serif; background-color: rgb(170, 46, 0); border: 3px solid rgb(170, 46, 0);" %>
<% end %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<%= image_tag("logo.png", alt: "Organization logo", class: "h-9 w-auto") %>
</div>
<div>
<h2 class="text-xl font-semibold tracking-wide leading-tight">Registration</h2>
<h2 class="text-xl font-semibold tracking-wide leading-tight"><%= public_form_heading %></h2>
<p class="text-sm text-blue-200">Reserve your spot — it only takes a minute.</p>
</div>
</div>
Expand All @@ -69,7 +69,7 @@
</div>
<% end %>

<%= form_with url: event_public_registration_path(@event), method: :post, local: true, class: "space-y-2", data: { turbo: !@event.cost_cents.to_i.positive? } do |f| %>
<%= form_with url: public_form_submit_path, method: :post, local: true, class: "space-y-2", data: { turbo: !@event.cost_cents.to_i.positive? } do |f| %>

<% if @scholarship %>
<input type="hidden" name="scholarship_requested" value="true">
Expand Down Expand Up @@ -145,16 +145,16 @@
<% label_override = email_label_overrides[key] %>
<% if span %>
<div class="<%= span %>">
<%= render "events/public_registrations/form_field", field: row_field, value: submitted_value, label: label_override %>
<%= render "events/public_forms/form_field", field: row_field, value: submitted_value, label: label_override %>
</div>
<% else %>
<%= render "events/public_registrations/form_field", field: row_field, value: submitted_value, label: label_override %>
<%= render "events/public_forms/form_field", field: row_field, value: submitted_value, label: label_override %>
<% end %>
<% end %>
</div>
<% else %>
<% submitted_value = params.dig(:public_registration, :form_fields, field.id.to_s) %>
<%= render "events/public_registrations/form_field", field: field, value: submitted_value %>
<%= render "events/public_forms/form_field", field: field, value: submitted_value %>
<% end %>
<% end %>

Expand All @@ -167,7 +167,7 @@
<% @scholarship_form.form_fields.reorder(position: :asc).each do |field| %>
<% next if field.group_header? %>
<% submitted_value = params.dig(:public_registration, :form_fields, field.id.to_s) %>
<%= render "events/public_registrations/form_field", field: field, value: submitted_value %>
<%= render "events/public_forms/form_field", field: field, value: submitted_value %>
<% end %>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/views/forms/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@
<% label_override = email_label_overrides[key] %>
<% if span %>
<div class="<%= span %>">
<%= render "events/public_registrations/form_field", field: row_field, value: nil, label: label_override %>
<%= render "events/public_forms/form_field", field: row_field, value: nil, label: label_override %>
</div>
<% else %>
<%= render "events/public_registrations/form_field", field: row_field, value: nil, label: label_override %>
<%= render "events/public_forms/form_field", field: row_field, value: nil, label: label_override %>
<% end %>
<% end %>
</div>
<% else %>
<%= render "events/public_registrations/form_field", field: field, value: nil %>
<%= render "events/public_forms/form_field", field: field, value: nil %>
<% end %>
<% end %>
</fieldset>
Expand Down
2 changes: 1 addition & 1 deletion app/views/scholarships/_form_submission.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</span>
<h2 class="text-sm font-semibold text-gray-700">Form submission</h2>
<% if @form_submission %>
<%= link_to event_public_registration_path(@event, **submission_params),
<%= link_to event_registration_form_path(@event, **submission_params),
class: "ml-auto inline-flex items-center gap-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:underline",
target: "_blank", rel: "noopener" do %>
View full submission
Expand Down
7 changes: 6 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@
post :send_reminder
end
resource :registrations, only: %i[ create destroy ], module: :events, as: :registrant_registration

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: The registrant_registration resource stays separate from the three new public *_form resources — the routing spec asserts POST /events/:id/registrations still hits events/registrations#create and does not collide.

resource :public_registration, only: [ :new, :create, :show ], module: :events
EventForm::ROLES.each do |form_role|
actions = form_role == "registration" ? %i[ new create show ] : %i[ new create ]
resource :"#{form_role}_form", only: actions,
controller: "public_forms", module: :events,
defaults: { form_role: form_role }
end
end
resources :people do
collection do
Expand Down
8 changes: 8 additions & 0 deletions spec/factories/event_forms.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@
trait :scholarship do
role { "scholarship" }
end

trait :bulk_payment do
role { "bulk_payment" }
end

trait :ce_credit do
role { "ce_credit" }
end
end
end
10 changes: 10 additions & 0 deletions spec/models/event_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
describe "scopes" do
let!(:registration) { create(:event_form, role: "registration") }
let!(:scholarship) { create(:event_form, role: "scholarship") }
let!(:bulk_payment) { create(:event_form, role: "bulk_payment") }
let!(:ce_credit) { create(:event_form, role: "ce_credit") }

it ".registration returns only registration records" do
expect(EventForm.registration).to contain_exactly(registration)
Expand All @@ -43,5 +45,13 @@
it ".scholarship returns only scholarship records" do
expect(EventForm.scholarship).to contain_exactly(scholarship)
end

it ".bulk_payment returns only bulk_payment records" do
expect(EventForm.bulk_payment).to contain_exactly(bulk_payment)
end

it ".ce_credit returns only ce_credit records" do
expect(EventForm.ce_credit).to contain_exactly(ce_credit)
end
end
end
10 changes: 5 additions & 5 deletions spec/requests/events/registrations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
end
end

describe "GET /events/:event_id/public_registration (show)" do
describe "GET /events/:event_id/registration_form (show)" do
let!(:registration) { create(:event_registration, event: event, registrant: user.person) }

before do
Expand All @@ -161,28 +161,28 @@
end

it "allows access with a valid slug" do
get event_public_registration_path(event, reg: registration.slug)
get event_registration_form_path(event, reg: registration.slug)
expect(response).to have_http_status(:success)
end

it "returns 404 with an invalid slug" do
get event_public_registration_path(event, reg: "bogus-slug")
get event_registration_form_path(event, reg: "bogus-slug")
expect(response).to have_http_status(:not_found)
end

it "returns 404 with a slug from a different event" do
other_event = create(:event)
other_registration = create(:event_registration, event: other_event, registrant: user.person)

get event_public_registration_path(event, reg: other_registration.slug)
get event_registration_form_path(event, reg: other_registration.slug)
expect(response).to have_http_status(:not_found)
end

context "as a guest" do
before { sign_out user }

it "allows access with a valid slug" do
get event_public_registration_path(event, reg: registration.slug)
get event_registration_form_path(event, reg: registration.slug)
expect(response).to have_http_status(:success)
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/requests/scholarships_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
expect(response.body).to include("Why do you need a scholarship?")
expect(response.body).to include("Limited budget")
expect(response.body).to include("View full submission")
expect(response.body).to include(event_public_registration_path(event, reg: registration.slug))
expect(response.body).to include(event_registration_form_path(event, reg: registration.slug))
end

it "renders the shared event header: event link, training date, and a profile-linked recipient" do
Expand Down
Loading