Skip to content
Snippets Groups Projects

Redesign conference form with improved UI organization

Merged Teal requested to merge conference-form-ui into main
1 file
+ 98
82
Compare changes
  • Side-by-side
  • Inline
@@ -12,106 +12,122 @@
@@ -12,106 +12,122 @@
<% end %>
<% end %>
<div class="space-y-4">
<div class="space-y-4">
<div>
<div class="bg-gray-50 dark:bg-gray-700/30 p-4 rounded-md">
<%= form.label :name, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<h3 class="text-lg font-medium text-gray-700 dark:text-gray-300 mb-4">Basic Information</h3>
<%= 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 class="grid grid-cols-1 gap-4 md:grid-cols-3">
</div>
<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>
<div>
<%= form.label :slug, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<%= form.label :url, "Official Website URL", 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" %>
<%= 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">Used in URLs. Should contain only lowercase letters, numbers, and hyphens.</p>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">The official website of the conference</p>
</div>
</div>
<div>
<div>
<%= form.label :url, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<%= form.label :slug, "URL Slug", 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" %>
<%= 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>
<div>
<div class="bg-gray-50 dark:bg-gray-700/30 p-4 rounded-md">
<%= form.label :time_zone, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<h3 class="text-lg font-medium text-gray-700 dark:text-gray-300 mb-4">Timing & Location</h3>
<%= 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 class="grid grid-cols-1 gap-4 md:grid-cols-3">
</div>
<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>
<div>
<%= form.label :starts_at, "Start Date & Time", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<%= 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" %>
<%= 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>
<div>
<div>
<%= form.label :ends_at, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<%= 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" %>
<%= 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>
</div>
<div>
<div class="bg-gray-50 dark:bg-gray-700/30 p-4 rounded-md">
<%= form.label :import_job_class, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<h3 class="text-lg font-medium text-gray-700 dark:text-gray-300 mb-4">Import Configuration</h3>
<%= form.select :import_job_class,
[["Select Import Job Class", ""]] +
<div>
ConferencesController.available_import_job_classes.map { |class_name, display_name| [display_name, class_name] },
<%= 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,
{ 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",
[["Select Import Job Class", ""]] +
data: { conference_form_target: "importJobClass", action: "change->conference-form#importJobClassChanged" } } %>
ConferencesController.available_import_job_classes.map { |class_name, display_name| [display_name, class_name] },
<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>
{ 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 -->
<!-- Add hidden inputs to preserve all data values -->
<% if conference.data.present? %>
<% if conference.data.present? %>
<% conference.data.each do |key, value| %>
<% conference.data.each do |key, value| %>
<input type="hidden" name="data[<%= key %>]" value="<%= value %>" id="hidden_data_<%= key %>">
<input type="hidden" name="data[<%= key %>]" value="<%= value %>" id="hidden_data_<%= key %>">
 
<% end %>
<% end %>
<% end %>
<% end %>
<fieldset class="mt-6 border border-gray-300 rounded-md p-4 dark:border-gray-600">
<div class="mt-6">
<legend class="px-2 text-sm font-medium text-gray-700 dark:text-gray-300">Required Data Fields</legend>
<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">
<div class="space-y-4" data-conference-form-target="requiredFields">
<% if conference.import_job_class.present? %>
<% if conference.import_job_class.present? %>
<% begin %>
<% begin %>
<% klass = conference.import_job_class.constantize %>
<% klass = conference.import_job_class.constantize %>
<% conference.required_data_fields.each do |field| %>
<% conference.required_data_fields.each do |field| %>
<% metadata = klass.respond_to?(:field_metadata) ? (klass.field_metadata[field] || {}) : {} %>
<% metadata = klass.respond_to?(:field_metadata) ? (klass.field_metadata[field] || {}) : {} %>
<div class="mb-4">
<div class="mb-4">
<label for="data_<%= field %>" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
<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 : '' %>
<%= metadata[:title] || field.humanize %><%= metadata[:required] ? ' <span class="text-red-500">*</span>'.html_safe : '' %>
</label>
</label>
<% if metadata[:description].present? %>
<% if metadata[:description].present? %>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400"><%= metadata[:description] %></p>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400"><%= metadata[:description] %></p>
<% end %>
<% end %>
<input
<input
type="text"
type="text"
id="data_<%= field %>"
id="data_<%= field %>"
name="data[<%= field %>]"
name="data[<%= field %>]"
value="<%= conference.data&.dig(field) %>"
value="<%= conference.data&.dig(field) %>"
placeholder="<%= metadata[:placeholder] %>"
placeholder="<%= metadata[:placeholder] %>"
<%= 'required' if metadata[:required] %>
<%= '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">
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>
 
<% end %>
 
<% rescue => e %>
 
<div class="text-red-500">Error loading field metadata: <%= e.message %></div>
<% end %>
<% end %>
<% rescue => e %>
<% else %>
<div class="text-red-500">Error loading field metadata: <%= e.message %></div>
<p class="text-sm text-gray-500 dark:text-gray-400">Select an import job class to see required fields</p>
<% end %>
<% end %>
<% else %>
</div>
<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">
<div class="mt-6 pt-6 border-t border-gray-200 dark:border-gray-600">
<legend class="px-2 text-sm font-medium text-gray-700 dark:text-gray-300">Custom Data Fields</legend>
<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">
<div class="space-y-4" data-conference-form-target="customFields">
<% if conference.data.present? %>
<% if conference.data.present? %>
<% conference.data.except(*conference.required_data_fields).each do |key, value| %>
<% 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 items-center space-x-2 custom-field-row">
<div class="flex-1">
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label>
<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">
<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>
<div class="flex-1">
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Value</label>
<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">
<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>
<div class="flex items-end">
<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">
<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 @@
@@ -128,12 +144,12 @@
<template data-conference-form-target="customTemplate">
<template data-conference-form-target="customTemplate">
<div class="flex items-center space-x-2 custom-field-row">
<div class="flex items-center space-x-2 custom-field-row">
<div class="flex-1">
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label>
<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="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">
<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>
<div class="flex-1">
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Value</label>
<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="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">
<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>
<div class="flex items-end">
<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">
<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 @@
@@ -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">
<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" />
<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>
</svg>
Add Custom Field
Add Additional Field
</button>
</button>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</div>
</div>
Loading