From c79441c06da496dff74f2193e7da77de3384a526 Mon Sep 17 00:00:00 2001
From: Felix Eckhofer <felix@eckhofer.com>
Date: Mon, 23 Dec 2024 02:35:24 +0100
Subject: [PATCH] Add notes field to sessions

---
 app/controllers/sessions_controller.rb        | 35 +++++++++++++++++++
 .../controllers/session_controller.js         |  4 +--
 app/views/sessions/_session.html.erb          | 12 +++++++
 config/routes.rb                              |  3 ++
 .../20241223004818_add_notes_to_sessions.rb   |  5 +++
 db/schema.rb                                  |  3 +-
 6 files changed, 59 insertions(+), 3 deletions(-)
 create mode 100644 db/migrate/20241223004818_add_notes_to_sessions.rb

diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index e857065..5c13c86 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -1,4 +1,6 @@
 class SessionsController < ApplicationController
+  before_action :authorize_shiftcoordinator, except: [:index, :show]
+
   def index
     @conference = Conference.find_by(slug: params[:conference_slug])
     @sessions = @conference.sessions.includes(:stage).order(:starts_at)
@@ -22,4 +24,37 @@ class SessionsController < ApplicationController
     @session = Session.includes(:stage).find_by(conference: @conference, ref_id: params[:ref_id])
     @users = User.all
   end
+
+  def update_notes
+    conference = Conference.find_by!(slug: params[:conference_slug])
+    session = Session.find_by!(conference:, ref_id: params[:ref_id])
+    session.notes = params[:note]
+
+    if session.save
+      Rails.logger.debug("Updated notes on session #{session.ref_id} to: #{session.notes}")
+      Turbo::StreamsChannel.broadcast_replace_to(
+        session.conference,
+        target: helpers.dom_id(session),
+        partial: "sessions/session",
+        locals: { session: }
+      )
+      flash.now[:success] = 'Notes saved successfully.'
+      respond_to do |format|
+        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(session), partial: "sessions/session", locals: { session: }) }
+        format.html { redirect_to conference_session_path(session.conference, session), success: 'Notes saved successfully.' }
+      end
+    else
+      flash.now[:alert] = 'Failed to save notes.'
+      respond_to do |format|
+        format.turbo_stream { render turbo_stream: turbo_stream.replace(helpers.dom_id(session), partial: "sessions/session", locals: { session: }), status: :unprocessable_entity }
+        format.html { render :show, status: :unprocessable_entity }
+      end
+    end
+  end
+
+  private
+
+  def notes_params
+    params.require(:session).permit(:notes)
+  end
 end
diff --git a/app/javascript/controllers/session_controller.js b/app/javascript/controllers/session_controller.js
index ffc5dfd..3694c69 100644
--- a/app/javascript/controllers/session_controller.js
+++ b/app/javascript/controllers/session_controller.js
@@ -53,8 +53,8 @@ export default class extends Controller {
   submitWithPrompt(event) {
     event.preventDefault();
 
-    const reason = prompt(event.target.dataset.prompt);
-    if (reason !== null && reason.trim() !== "") {
+    const reason = prompt(event.target.dataset.prompt, event.target.dataset?.prefill);
+    if (reason !== null && event.target.dataset?.submitempty || reason.trim() !== "") {
       const input = document.createElement("input");
       input.type = "hidden";
       input.name = "note";
diff --git a/app/views/sessions/_session.html.erb b/app/views/sessions/_session.html.erb
index 5d0c016..90be7e6 100644
--- a/app/views/sessions/_session.html.erb
+++ b/app/views/sessions/_session.html.erb
@@ -21,6 +21,11 @@
         <%= session.stage.name %>
       </span>
       <span class="absolute top-0 right-0 text-3xl only-loggedin hidden">
+        <%= form_with url: update_notes_conference_session_path(session.conference, session), method: :patch, class: "inline", data: { turbo_frame: dom_id(session) } do |form| %>
+          <%= link_to update_notes_conference_session_path(session.conference, session), class: "pr-1 only-shiftcoordinator hidden", title: "Edit Note", aria_label: "Edit Note", data: { action: "session#submitWithPrompt", prompt: "Please enter the note", prefill: session.notes, submitempty: true, turbo_prefetch:"false" } do %>
+              📝
+          <% end %>
+        <% end %>
         <%= link_to conference_session_candidates_path(session.conference, session), class: "pr-1 only-candidate hidden", title: "Withdraw", aria_label: "Withdraw", data: { turbo_method: :delete, turbo_frame: dom_id(session) }, method: :delete do %>
           🙅
         <% end %>
@@ -50,6 +55,13 @@
       <% end %>
     <% end %>
 
+    <% unless session.notes.blank? %>
+    <div class="flex items-center bg-blue-100 bg-opacity-50 border border-blue-500 text-blue-700 p-2 my-2 rounded-md" role="alert">
+      <span class="text-xl mr-2" aria-label="Notes" title="Notes">ℹ️</span>
+      <span><%= session.notes %></span>
+    </div>
+    <% end %>
+
     <small>assigned (<%= session.assignments.length %>)</small>
     <ul class="inline-flex flex-wrap gap-1 my-1">
       <% session.assignments.each do |assignment| %>
diff --git a/config/routes.rb b/config/routes.rb
index cd2292f..cce0b9b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -17,6 +17,9 @@ Rails.application.routes.draw do
     get 'stats', on: :member
     get ':date', action: :show, on: :member, as: :date, date: /\d{4}-\d{2}-\d{2}/
     resources :sessions, param: :ref_id do
+      member do
+        patch :update_notes
+      end
       resources :assignments, only: [:create, :destroy]
       resources :candidates, only: [:create, :destroy]
       delete 'candidates', to: 'candidates#destroy_self'
diff --git a/db/migrate/20241223004818_add_notes_to_sessions.rb b/db/migrate/20241223004818_add_notes_to_sessions.rb
new file mode 100644
index 0000000..720888b
--- /dev/null
+++ b/db/migrate/20241223004818_add_notes_to_sessions.rb
@@ -0,0 +1,5 @@
+class AddNotesToSessions < ActiveRecord::Migration[7.1]
+  def change
+    add_column :sessions, :notes, :string
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d3627a4..2347d52 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.1].define(version: 2024_12_22_215716) do
+ActiveRecord::Schema[7.1].define(version: 2024_12_23_004818) do
   create_table "assignments", force: :cascade do |t|
     t.integer "user_id", null: false
     t.integer "session_id", null: false
@@ -136,6 +136,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_12_22_215716) do
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.string "ref_id"
+    t.string "notes"
     t.index ["conference_id"], name: "index_sessions_on_conference_id"
     t.index ["ref_id", "conference_id"], name: "index_sessions_on_ref_id_and_conference_id", unique: true
     t.index ["stage_id"], name: "index_sessions_on_stage_id"
-- 
GitLab