diff --git a/config/routes.rb b/config/routes.rb
index 7af1708..a0cd16e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -22,6 +22,7 @@
collection { patch :reorder }
end
end
+ resources :lightning_talks, only: %i[index]
resources :volunteers, only: %i[index show]
resources :volunteer_slots, only: %i[index show]
resources :volunteer_signups, only: %i[create destroy]
diff --git a/test/controllers/admin/lightning_talks_controller_test.rb b/test/controllers/admin/lightning_talks_controller_test.rb
new file mode 100644
index 0000000..7fd9a8b
--- /dev/null
+++ b/test/controllers/admin/lightning_talks_controller_test.rb
@@ -0,0 +1,45 @@
+require "test_helper"
+
+class Admin::LightningTalksControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @admin = users(:jeremy)
+ @item = ScheduleItem.create!(
+ day: "fri", title: "Lightning Talks", kind: :lightning,
+ sort_time: 1400, time_label: "2:00 PM", is_public: true
+ )
+ end
+
+ test "non-admin gets 404" do
+ sign_in_as users(:attendee_one)
+ get admin_lightning_talks_path
+ assert_response :not_found
+ end
+
+ test "admin sees the index page with lightning blocks" do
+ sign_in_as @admin
+ LightningTalkSignup.claim_next_slot!(user: users(:attendee_one), schedule_item: @item)
+ get admin_lightning_talks_path
+ assert_response :success
+ assert_match @item.title, @response.body
+ assert_match "1", @response.body # at least one speaker count rendered
+ end
+
+ test "admin sees Full badge when block is at capacity" do
+ sign_in_as @admin
+ LightningTalkSignup::MAX_SPEAKERS.times do |i|
+ user = User.create!(email: "filler-#{i}@example.com", role: :attendee)
+ LightningTalkSignup.claim_next_slot!(user: user, schedule_item: @item)
+ end
+ get admin_lightning_talks_path
+ assert_response :success
+ assert_match "Full", @response.body
+ end
+
+ test "admin sees empty state when no lightning items exist" do
+ @item.destroy
+ sign_in_as @admin
+ get admin_lightning_talks_path
+ assert_response :success
+ assert_match "No lightning talk blocks", @response.body
+ end
+end
From 196c4fb9c493a10e2ac23c3f760898adf07b96c4 Mon Sep 17 00:00:00 2001
From: Katya Sarmiento <5871075+Kitkatnik@users.noreply.github.com>
Date: Mon, 27 Apr 2026 00:57:55 -0400
Subject: [PATCH 5/9] Lightning talks UX fixes
- Admin Lightning Talks page now renders the lineup directly (the
speakers panel for the single lightning block) instead of a
table-of-one directory. Empty state covers the "no block scheduled"
case.
- "Edit my lightning talk" link on My Plan now uses
data-turbo-frame="_top" so it escapes the plan_item frame instead
of throwing a "Content Missing" error.
- Save on the edit form now uses data-turbo="false" so the redirect
to /schedule#schedule_item_ reloads the page natively and the
browser scrolls to the lightning row. (Cancel already worked because
it was a GET navigation.)
---
.../admin/lightning_talks_controller.rb | 2 +-
app/views/admin/dashboard/show.html.erb | 2 +-
.../admin/lightning_talks/index.html.erb | 48 ++++---------------
.../lightning_talk_signups/edit.html.erb | 1 +
app/views/plan/_plan_item.html.erb | 4 +-
.../admin/lightning_talks_controller_test.rb | 20 ++------
6 files changed, 20 insertions(+), 57 deletions(-)
diff --git a/app/controllers/admin/lightning_talks_controller.rb b/app/controllers/admin/lightning_talks_controller.rb
index 6b7df27..3784650 100644
--- a/app/controllers/admin/lightning_talks_controller.rb
+++ b/app/controllers/admin/lightning_talks_controller.rb
@@ -1,7 +1,7 @@
module Admin
class LightningTalksController < AdminController
def index
- @lightning_items = ScheduleItem.lightning.ordered.includes(:lightning_talk_signups)
+ @schedule_item = ScheduleItem.lightning.ordered.first
end
end
end
diff --git a/app/views/admin/dashboard/show.html.erb b/app/views/admin/dashboard/show.html.erb
index b82ee18..7b35fcd 100644
--- a/app/views/admin/dashboard/show.html.erb
+++ b/app/views/admin/dashboard/show.html.erb
@@ -44,7 +44,7 @@
<%= link_to admin_lightning_talks_path, class: "action-card" do %>
Lightning Talks
-
See speaker counts per block and manage the lineup — add, remove, reorder.
+
Manage the lineup — add, remove, reorder speakers.
<% end %>
<%= link_to admin_embassy_applications_path, class: "action-card" do %>
diff --git a/app/views/admin/lightning_talks/index.html.erb b/app/views/admin/lightning_talks/index.html.erb
index 6b57472..5aa948b 100644
--- a/app/views/admin/lightning_talks/index.html.erb
+++ b/app/views/admin/lightning_talks/index.html.erb
@@ -2,46 +2,16 @@
Lightning Talks
-<% if @lightning_items.empty? %>
+<% if @schedule_item %>
+
- No lightning talk blocks scheduled yet. Add one from
+ No lightning talk block scheduled yet. Add one from
<%= link_to "Schedule", admin_schedule_items_path, class: "text-blue underline" %>.
-
-<%= render "panel", schedule_item: @schedule_item %>
diff --git a/test/controllers/admin/lightning_talk_signups_controller_test.rb b/test/controllers/admin/lightning_talk_signups_controller_test.rb
index 3946e1c..7a23a34 100644
--- a/test/controllers/admin/lightning_talk_signups_controller_test.rb
+++ b/test/controllers/admin/lightning_talk_signups_controller_test.rb
@@ -15,12 +15,10 @@ class Admin::LightningTalkSignupsControllerTest < ActionDispatch::IntegrationTes
assert_response :not_found
end
- test "admin sees the speakers index page" do
+ test "admin HTML index redirects to top-level Lightning Talks page" do
sign_in_as @admin
- LightningTalkSignup.claim_next_slot!(user: users(:attendee_one), schedule_item: @item)
get admin_schedule_item_lightning_talk_signups_path(@item)
- assert_response :success
- assert_match users(:attendee_one).full_name, @response.body
+ assert_redirected_to admin_lightning_talks_path
end
test "admin can add a speaker" do
@@ -68,13 +66,12 @@ class Admin::LightningTalkSignupsControllerTest < ActionDispatch::IntegrationTes
assert_equal 3, s2.reload.position
end
- test "CSV export returns csv content type" do
+ test "PDF export returns pdf content type" do
sign_in_as @admin
LightningTalkSignup.claim_next_slot!(user: users(:attendee_one), schedule_item: @item)
- get admin_schedule_item_lightning_talk_signups_path(@item, format: :csv)
+ get admin_schedule_item_lightning_talk_signups_path(@item, format: :pdf)
assert_response :success
- assert_match "text/csv", @response.content_type
- assert_match "position,slot_time,first_name", @response.body
- assert_match users(:attendee_one).email, @response.body
+ assert_match "application/pdf", @response.content_type
+ assert @response.body.start_with?("%PDF-"), "expected PDF signature"
end
end
From 1ad0430000178e042137f7073a5616f629c1e599 Mon Sep 17 00:00:00 2001
From: Katya Sarmiento <5871075+Kitkatnik@users.noreply.github.com>
Date: Mon, 27 Apr 2026 01:08:21 -0400
Subject: [PATCH 7/9] Fix Add-speaker button stretching to full flex column
height
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The "Add a speaker" form uses flex+items-end to put the User column
next to the Add button. Rails f.submit renders ,
which browsers stretch unpredictably as a flex item — the result was
a button as tall as the label+select stacked together.
Switching to button_tag (which renders