From c263f2057ddbb0fc40d96372a9916b837bcfa334 Mon Sep 17 00:00:00 2001 From: maebeale Date: Wed, 17 Jun 2026 14:25:55 -0400 Subject: [PATCH 1/3] Add a CE hours detail section to the registration ticket CE requirements (CAMFT approval, license-number and payment rules, sign-in, post-training evaluation) used to live in a long confirmation email. Surface them per event the same way "Before you attend" works: a ticket call-out linking to a sanitized-HTML details page, so admins can keep the embedded links instead of re-sending an email each time. Co-Authored-By: Claude Opus 4.8 --- app/controllers/events_controller.rb | 18 ++++++++- app/models/event.rb | 7 ++++ app/policies/event_policy.rb | 3 ++ .../event_registrations/_ticket.html.erb | 15 ++++++++ app/views/events/_form.html.erb | 37 +++++++++++++++++++ app/views/events/ce_hours.html.erb | 33 +++++++++++++++++ config/routes.rb | 1 + ...17120000_add_ce_hours_details_to_events.rb | 11 ++++++ db/schema.rb | 2 + spec/requests/events_spec.rb | 24 ++++++++++++ 10 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 app/views/events/ce_hours.html.erb create mode 100644 db/migrate/20260617120000_add_ce_hours_details_to_events.rb diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index b799c202b..599801e12 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -1,8 +1,8 @@ class EventsController < ApplicationController include AhoyTracking, TagAssignable - skip_before_action :authenticate_user!, only: [ :index, :show, :staff, :details ] + skip_before_action :authenticate_user!, only: [ :index, :show, :staff, :details, :ce_hours ] skip_before_action :verify_authenticity_token, only: [ :preview ] - before_action :set_event, only: %i[ show edit update destroy preview dashboard background registrants details staff edit_staff update_staff recipients bulk_payments preview_reminder send_reminder copy_registration_form allocate_bulk_payment create_bulk_payment ] + before_action :set_event, only: %i[ show edit update destroy preview dashboard background registrants details ce_hours staff edit_staff update_staff recipients bulk_payments preview_reminder send_reminder copy_registration_form allocate_bulk_payment create_bulk_payment ] def index authorize! @@ -104,6 +104,20 @@ def details @event = @event.decorate end + # Public CE hours page (continuing education requirements, payment, sign-in + # rules). Linked from the registration ticket. When no details are set there + # is nothing to show, so fall back to the event page. + def ce_hours + authorize! @event, to: :ce_hours? + + if @event.ce_hours_details.blank? + redirect_to event_path(@event, reg: params[:reg].presence) + return + end + + @event = @event.decorate + end + def staff authorize! @event, to: :staff? @event = @event.decorate diff --git a/app/models/event.rb b/app/models/event.rb index 7e644f9b7..8bd22545e 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -156,6 +156,13 @@ def event_details_label super.presence || "Before you attend" end + # Heading shown on the CE hours ticket call-out and its details page. Falls + # back to the default even when an admin clears it, so the section never + # renders unlabelled. + def ce_hours_details_label + super.presence || "CE hours" + end + # Virtual attributes for date/time inputs (Firefox datetime-local compat) attr_writer :start_date_date, :start_date_time, :end_date_date, :end_date_time, diff --git a/app/policies/event_policy.rb b/app/policies/event_policy.rb index 88a6de687..4eaea918f 100644 --- a/app/policies/event_policy.rb +++ b/app/policies/event_policy.rb @@ -112,6 +112,8 @@ def google_analytics? :rhino_description, :event_details, :event_details_label, + :ce_hours_details, + :ce_hours_details_label, :autoshow_cost, :autoshow_date, :autoshow_location, @@ -150,6 +152,7 @@ def google_analytics? alias_rule :preview?, to: :edit? alias_rule :details?, to: :show? + alias_rule :ce_hours?, to: :show? private diff --git a/app/views/event_registrations/_ticket.html.erb b/app/views/event_registrations/_ticket.html.erb index 5e97d2e13..b9bc84b5e 100644 --- a/app/views/event_registrations/_ticket.html.erb +++ b/app/views/event_registrations/_ticket.html.erb @@ -109,6 +109,21 @@ <% end %> <% end %> + + <% if event_registration.event.ce_hours_details.present? %> + <%= link_to ce_hours_event_path(event_registration.event, reg: event_registration.slug), + class: "flex items-center gap-3 rounded-xl border-2 border-indigo-300 bg-indigo-50 px-4 py-3 hover:bg-indigo-100 transition-colors" do %> + + +
+

<%= event_registration.event.ce_hours_details_label %>

+

Continuing education hours — requirements & next steps

+
+ + + <% end %> + <% end %> + <% if event_registration.w9_requested? %> <%= link_to "/documents/awbw-w9.pdf", diff --git a/app/views/events/_form.html.erb b/app/views/events/_form.html.erb index 6e9e0b35d..1dda4f6b9 100644 --- a/app/views/events/_form.html.erb +++ b/app/views/events/_form.html.erb @@ -454,6 +454,43 @@ + <%# ---- CE HOURS (ticket call-out + details page) ---- %> +
+ + + +
+