Scope flash rendering to Dashboard only
Move flash bar rendering from Layout into Dashboard since undo
completion is only relevant on the dashboard. Revert the flash/csrf
plumbing from Layout, Series::Show, Series::New, and User::Show.
Only the root route consumes the flash from the session now.

https://claude.ai/code/session_01NLGBcJgbiyWGDBGFh8DRas
change
commit 21299caace85310e2279dcede287a0b20acbfd2f
author Claude <noreply@anthropic.com>
date
parent 1b68d1bb
diff --git a/lib/ketchup/views/dashboard.rb b/lib/ketchup/views/dashboard.rb
index 8d47e36..4f3ebdf 100644
--- a/lib/ketchup/views/dashboard.rb
+++ b/lib/ketchup/views/dashboard.rb
@@ -21,7 +21,8 @@ module Views
       overdue = @current_user.overdue_tasks.all.sort_by { |t| -t.urgency }
       upcoming = @current_user.upcoming_tasks.all
 
-      render Layout.new(current_user: @current_user, flash: @flash, csrf: @csrf) do
+      render Layout.new(current_user: @current_user) do
+        render_flash
         div(class: "dashboard") do
           div(class: "column-overdue") do
             render_focus(overdue)
@@ -36,6 +37,22 @@ module Views
 
     private
 
+    def render_flash
+      return unless @flash
+
+      undo_path = @flash["undo_path"]
+
+      div(class: "flash-bar") do
+        span(class: "flash-message") { @flash["message"] }
+        if undo_path
+          form(method: "post", action: undo_path, class: "flash-undo-form") do
+            input(type: "hidden", name: "_csrf", value: @csrf.call(undo_path))
+            button(type: "submit", class: "flash-undo-btn") { "Undo" }
+          end
+        end
+      end
+    end
+
     def render_focus(overdue)
       if overdue.empty?
         section(class: "section section--focus") do
diff --git a/lib/ketchup/views/layout.rb b/lib/ketchup/views/layout.rb
index 22cb9c9..134c379 100644
--- a/lib/ketchup/views/layout.rb
+++ b/lib/ketchup/views/layout.rb
@@ -17,12 +17,10 @@ module Views
       }.freeze
     end
 
-    def initialize(current_user:, title: "Ketchup", active_view: nil, flash: nil, csrf: nil)
+    def initialize(current_user:, title: "Ketchup", active_view: nil)
       @current_user = current_user
       @title = title
       @active_view = active_view
-      @flash = flash
-      @csrf = csrf
     end
 
     def view_template(&)
@@ -62,7 +60,6 @@ module Views
             end
             a(href: "/users/#{@current_user[:id]}", class: "header-user") { @current_user[:login] }
           end
-          render_flash
           yield
           render_footer
         end
@@ -71,22 +68,6 @@ module Views
 
     private
 
-    def render_flash
-      return unless @flash
-
-      undo_path = @flash["undo_path"]
-
-      div(class: "flash-bar") do
-        span(class: "flash-message") { @flash["message"] }
-        if undo_path && @csrf
-          form(method: "post", action: undo_path, class: "flash-undo-form") do
-            input(type: "hidden", name: "_csrf", value: @csrf.call(undo_path))
-            button(type: "submit", class: "flash-undo-btn") { "Undo" }
-          end
-        end
-      end
-    end
-
     def asset_path(path)
       version = ASSET_VERSIONS[path]
       version ? "#{path}?v=#{version}" : path
diff --git a/lib/ketchup/views/series/new.rb b/lib/ketchup/views/series/new.rb
index 7b74bc1..a5611dc 100644
--- a/lib/ketchup/views/series/new.rb
+++ b/lib/ketchup/views/series/new.rb
@@ -7,14 +7,13 @@ require_relative "../layout"
 module Views
   module Series
     class New < Phlex::HTML
-      def initialize(current_user:, csrf:, flash: nil)
+      def initialize(current_user:, csrf:)
         @current_user = current_user
         @csrf = csrf
-        @flash = flash
       end
 
       def view_template
-        render Layout.new(current_user: @current_user, title: "New Series — Ketchup", active_view: :new, flash: @flash, csrf: @csrf) do
+        render Layout.new(current_user: @current_user, title: "New Series — Ketchup", active_view: :new) do
           div(class: "dashboard") do
             div(class: "main-column") do
               section(class: "section") do
diff --git a/lib/ketchup/views/series/show.rb b/lib/ketchup/views/series/show.rb
index a888494..e1d6794 100644
--- a/lib/ketchup/views/series/show.rb
+++ b/lib/ketchup/views/series/show.rb
@@ -7,17 +7,16 @@ require_relative "../layout"
 module Views
   module Series
     class Show < Phlex::HTML
-      def initialize(series:, current_user:, csrf:, flash: nil)
+      def initialize(series:, current_user:, csrf:)
         @series = series
         @current_user = current_user
         @csrf = csrf
-        @flash = flash
       end
 
       def view_template
         active_task = @series.active_task
 
-        render Layout.new(current_user: @current_user, title: "#{note_title} — Ketchup", active_view: nil, flash: @flash, csrf: @csrf) do
+        render Layout.new(current_user: @current_user, title: "#{note_title} — Ketchup", active_view: nil) do
           div(class: "dashboard") do
             div(class: "main-column") do
               section(class: "section", "x-data": "{ editing: false }") do
diff --git a/lib/ketchup/views/user/show.rb b/lib/ketchup/views/user/show.rb
index 169f960..564d06d 100644
--- a/lib/ketchup/views/user/show.rb
+++ b/lib/ketchup/views/user/show.rb
@@ -7,17 +7,16 @@ require_relative "../layout"
 module Views
   module User
     class Show < Phlex::HTML
-      def initialize(current_user:, csrf:, flash: nil)
+      def initialize(current_user:, csrf:)
         @current_user = current_user
         @csrf = csrf
-        @flash = flash
       end
 
       def view_template
         email_path = "/users/#{@current_user[:id]}/email"
         email = @current_user[:email]
 
-        render Layout.new(current_user: @current_user, title: "Settings — Ketchup", active_view: nil, flash: @flash, csrf: @csrf) do
+        render Layout.new(current_user: @current_user, title: "Settings — Ketchup", active_view: nil) do
           div(class: "dashboard") do
             div(class: "main-column") do
               section(class: "section", "x-data": "{ editing: false }") do
diff --git a/lib/ketchup/web.rb b/lib/ketchup/web.rb
index 68ad391..d03a61d 100644
--- a/lib/ketchup/web.rb
+++ b/lib/ketchup/web.rb
@@ -48,8 +48,7 @@ class Web < Roda
       r.halt 404 unless @user.id == user_id
 
       r.get do
-        flash = session.delete("flash")
-        Views::User::Show.new(current_user: @user, csrf: method(:csrf_token), flash: flash).call
+        Views::User::Show.new(current_user: @user, csrf: method(:csrf_token)).call
       end
 
       r.post "email" do
@@ -61,8 +60,7 @@ class Web < Roda
 
     r.on "series" do
       r.get "new" do
-        flash = session.delete("flash")
-        Views::Series::New.new(current_user: @user, csrf: method(:csrf_token), flash: flash).call
+        Views::Series::New.new(current_user: @user, csrf: method(:csrf_token)).call
       end
 
       r.is do
@@ -99,8 +97,7 @@ class Web < Roda
 
         r.is do
           r.get do
-            flash = session.delete("flash")
-            Views::Series::Show.new(series: @series, current_user: @user, csrf: method(:csrf_token), flash: flash).call
+            Views::Series::Show.new(series: @series, current_user: @user, csrf: method(:csrf_token)).call
           end
 
           r.patch do