From 3eb8e7599ef3e3e493c9b800a9a04141fbf3d0fd Mon Sep 17 00:00:00 2001
From: Teal Bauer <teal@starsong.eu>
Date: Sun, 9 Mar 2025 23:49:00 +0100
Subject: [PATCH] Redesign conference form with improved UI organization

- Group form into logical sections with background color and headers
- Add labels and placeholder text
---
 app/views/admin/conferences/_form.html.erb | 180 +++++++++++----------
 1 file changed, 98 insertions(+), 82 deletions(-)

diff --git a/app/views/admin/conferences/_form.html.erb b/app/views/admin/conferences/_form.html.erb
index 63b52d4..a439f29 100644
--- a/app/views/admin/conferences/_form.html.erb
+++ b/app/views/admin/conferences/_form.html.erb
@@ -12,106 +12,122 @@
     <% end %>
 
     <div class="space-y-4">
-      <div>
-        <%= form.label :name, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-        <%= form.text_field :name, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
-      </div>
+      <div class="bg-gray-50 dark:bg-gray-700/30 p-4 rounded-md">
+        <h3 class="text-lg font-medium text-gray-700 dark:text-gray-300 mb-4">Basic Information</h3>
+        <div class="grid grid-cols-1 gap-4 md:grid-cols-3">
+          <div>
+            <%= form.label :name, "Conference Name", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+            <%= form.text_field :name, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white", placeholder: "e.g. Tech Conference 2025" %>
+            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">The official name of the conference</p>
+          </div>
 
-      <div>
-        <%= form.label :slug, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-        <%= form.text_field :slug, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
-        <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Used in URLs. Should contain only lowercase letters, numbers, and hyphens.</p>
-      </div>
+          <div>
+            <%= form.label :url, "Official Website URL", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+            <%= form.url_field :url, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white", placeholder: "https://example.com" %>
+            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">The official website of the conference</p>
+          </div>
 
-      <div>
-        <%= form.label :url, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-        <%= form.url_field :url, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
+          <div>
+            <%= form.label :slug, "URL Slug", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+            <%= form.text_field :slug, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white", placeholder: "e.g. tech-conf-2025" %>
+            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Used in URLs (e.g., /conferences/tech-conf-2025). Use only lowercase letters, numbers, and hyphens.</p>
+          </div>
+        </div>
       </div>
 
-      <div>
-        <%= form.label :time_zone, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-        <%= form.time_zone_select :time_zone, nil, { include_blank: "Select Time Zone" }, { class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" } %>
-      </div>
+      <div class="bg-gray-50 dark:bg-gray-700/30 p-4 rounded-md">
+        <h3 class="text-lg font-medium text-gray-700 dark:text-gray-300 mb-4">Timing & Location</h3>
+        <div class="grid grid-cols-1 gap-4 md:grid-cols-3">
+          <div>
+            <%= form.label :time_zone, "Conference Time Zone", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+            <%= form.time_zone_select :time_zone, nil, { include_blank: "Select Time Zone" }, { class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" } %>
+            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">The local time zone where the conference takes place</p>
+          </div>
 
-      <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
-        <div>
-          <%= form.label :starts_at, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-          <%= form.datetime_local_field :starts_at, value: conference.starts_at&.strftime('%Y-%m-%dT%H:%M'), class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
-        </div>
+          <div>
+            <%= form.label :starts_at, "Start Date & Time", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+            <%= form.datetime_local_field :starts_at, value: conference.starts_at&.strftime('%Y-%m-%dT%H:%M'), class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
+            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">When the conference officially begins</p>
+          </div>
 
-        <div>
-          <%= form.label :ends_at, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-          <%= form.datetime_local_field :ends_at, value: conference.ends_at&.strftime('%Y-%m-%dT%H:%M'), class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
+          <div>
+            <%= form.label :ends_at, "End Date & Time", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+            <%= form.datetime_local_field :ends_at, value: conference.ends_at&.strftime('%Y-%m-%dT%H:%M'), class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" %>
+            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">When the conference officially ends</p>
+          </div>
         </div>
       </div>
 
-      <div>
-        <%= form.label :import_job_class, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
-        <%= form.select :import_job_class, 
-                      [["Select Import Job Class", ""]] + 
-                      ConferencesController.available_import_job_classes.map { |class_name, display_name| [display_name, class_name] },
-                      {}, 
-                      { class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white",
-                        data: { conference_form_target: "importJobClass", action: "change->conference-form#importJobClassChanged" } } %>
-        <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Select the import job class to see required data fields</p>
-      </div>
+      <div class="bg-gray-50 dark:bg-gray-700/30 p-4 rounded-md">
+        <h3 class="text-lg font-medium text-gray-700 dark:text-gray-300 mb-4">Import Configuration</h3>
+        
+        <div>
+          <%= form.label :import_job_class, "Data Import Method", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
+          <%= form.select :import_job_class, 
+                        [["Select Import Job Class", ""]] + 
+                        ConferencesController.available_import_job_classes.map { |class_name, display_name| [display_name, class_name] },
+                        {}, 
+                        { class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white",
+                          data: { conference_form_target: "importJobClass", action: "change->conference-form#importJobClassChanged" } } %>
+          <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Select the method used to import conference data (sessions, speakers, etc.). Each method requires specific data fields below.</p>
+        </div>
 
-      <!-- Add hidden inputs to preserve all data values -->
-      <% if conference.data.present? %>
-        <% conference.data.each do |key, value| %>
-          <input type="hidden" name="data[<%= key %>]" value="<%= value %>" id="hidden_data_<%= key %>">
+        <!-- Add hidden inputs to preserve all data values -->
+        <% if conference.data.present? %>
+          <% conference.data.each do |key, value| %>
+            <input type="hidden" name="data[<%= key %>]" value="<%= value %>" id="hidden_data_<%= key %>">
+          <% end %>
         <% end %>
-      <% end %>
 
-      <fieldset class="mt-6 border border-gray-300 rounded-md p-4 dark:border-gray-600">
-        <legend class="px-2 text-sm font-medium text-gray-700 dark:text-gray-300">Required Data Fields</legend>
-        
-        <div class="space-y-4" data-conference-form-target="requiredFields">
-          <% if conference.import_job_class.present? %>
-            <% begin %>
-              <% klass = conference.import_job_class.constantize %>
-              <% conference.required_data_fields.each do |field| %>
-                <% metadata = klass.respond_to?(:field_metadata) ? (klass.field_metadata[field] || {}) : {} %>
-                <div class="mb-4">
-                  <label for="data_<%= field %>" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
-                    <%= metadata[:title] || field.humanize %><%= metadata[:required] ? ' <span class="text-red-500">*</span>'.html_safe : '' %>
-                  </label>
-                  <% if metadata[:description].present? %>
-                    <p class="mt-1 text-xs text-gray-500 dark:text-gray-400"><%= metadata[:description] %></p>
-                  <% end %>
-                  <input 
-                    type="text" 
-                    id="data_<%= field %>"
-                    name="data[<%= field %>]" 
-                    value="<%= conference.data&.dig(field) %>"
-                    placeholder="<%= metadata[:placeholder] %>"
-                    <%= 'required' if metadata[:required] %>
-                    class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
-                </div>
+        <div class="mt-6">
+          <h4 class="text-md font-medium text-gray-700 dark:text-gray-300 mb-3">Required Data Fields for Import</h4>
+          
+          <div class="space-y-4" data-conference-form-target="requiredFields">
+            <% if conference.import_job_class.present? %>
+              <% begin %>
+                <% klass = conference.import_job_class.constantize %>
+                <% conference.required_data_fields.each do |field| %>
+                  <% metadata = klass.respond_to?(:field_metadata) ? (klass.field_metadata[field] || {}) : {} %>
+                  <div class="mb-4">
+                    <label for="data_<%= field %>" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
+                      <%= metadata[:title] || field.humanize %><%= metadata[:required] ? ' <span class="text-red-500">*</span>'.html_safe : '' %>
+                    </label>
+                    <% if metadata[:description].present? %>
+                      <p class="mt-1 text-xs text-gray-500 dark:text-gray-400"><%= metadata[:description] %></p>
+                    <% end %>
+                    <input 
+                      type="text" 
+                      id="data_<%= field %>"
+                      name="data[<%= field %>]" 
+                      value="<%= conference.data&.dig(field) %>"
+                      placeholder="<%= metadata[:placeholder] %>"
+                      <%= 'required' if metadata[:required] %>
+                      class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
+                  </div>
+                <% end %>
+              <% rescue => e %>
+                <div class="text-red-500">Error loading field metadata: <%= e.message %></div>
               <% end %>
-            <% rescue => e %>
-              <div class="text-red-500">Error loading field metadata: <%= e.message %></div>
+            <% else %>
+              <p class="text-sm text-gray-500 dark:text-gray-400">Select an import job class to see required fields</p>
             <% end %>
-          <% else %>
-            <p class="text-sm text-gray-500 dark:text-gray-400">Select an import job class to see required fields</p>
-          <% end %>
+          </div>
         </div>
-      </fieldset>
 
-      <fieldset class="mt-6 border border-gray-300 rounded-md p-4 dark:border-gray-600">
-        <legend class="px-2 text-sm font-medium text-gray-700 dark:text-gray-300">Custom Data Fields</legend>
+        <div class="mt-6 pt-6 border-t border-gray-200 dark:border-gray-600">
+          <h4 class="text-md font-medium text-gray-700 dark:text-gray-300 mb-3">Additional Custom Data Fields</h4>
         
         <div class="space-y-4" data-conference-form-target="customFields">
           <% if conference.data.present? %>
             <% conference.data.except(*conference.required_data_fields).each do |key, value| %>
               <div class="flex items-center space-x-2 custom-field-row">
                 <div class="flex-1">
-                  <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label>
-                  <input type="text" name="custom_field_keys[]" value="<%= key %>" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
+                  <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Field Name</label>
+                  <input type="text" name="custom_field_keys[]" value="<%= key %>" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" placeholder="e.g. venue_address">
                 </div>
                 <div class="flex-1">
-                  <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Value</label>
-                  <input type="text" name="custom_field_values[]" value="<%= value %>" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
+                  <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Field Value</label>
+                  <input type="text" name="custom_field_values[]" value="<%= value %>" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" placeholder="The field's value">
                 </div>
                 <div class="flex items-end">
                   <button type="button" data-action="click->conference-form#removeCustomField" class="mt-1 p-2 text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300">
@@ -128,12 +144,12 @@
         <template data-conference-form-target="customTemplate">
           <div class="flex items-center space-x-2 custom-field-row">
             <div class="flex-1">
-              <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label>
-              <input type="text" name="custom_field_keys[]" value="KEY_PLACEHOLDER" placeholder="Enter key" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
+              <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Field Name</label>
+              <input type="text" name="custom_field_keys[]" value="KEY_PLACEHOLDER" placeholder="e.g. venue_address" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
             </div>
             <div class="flex-1">
-              <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Value</label>
-              <input type="text" name="custom_field_values[]" value="VALUE_PLACEHOLDER" placeholder="Enter value" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
+              <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Field Value</label>
+              <input type="text" name="custom_field_values[]" value="VALUE_PLACEHOLDER" placeholder="The field's value" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
             </div>
             <div class="flex items-end">
               <button type="button" data-action="click->conference-form#removeCustomField" class="mt-1 p-2 text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300">
@@ -150,10 +166,10 @@
             <svg xmlns="http://www.w3.org/2000/svg" class="-ml-0.5 mr-2 h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
               <path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd" />
             </svg>
-            Add Custom Field
+            Add Additional Field
           </button>
         </div>
-      </fieldset>
+      </div>
     </div>
 
   </div>
-- 
GitLab