diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index d62e63b3d904921c0e048bf6c3dddc731ccc3e65..e7d3fbcff9dcb41c36870e9c655fc6b73bd2e5e6 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -1,44 +1,13 @@ class ConferencesController < ApplicationController before_action :authenticate_user!, except: [ :index, :show, :stats ] - before_action :authorize_permission, only: [ :new, :create, :edit, :update, :destroy ] - before_action :set_conference, only: [ :show, :edit, :update, :destroy, :stats ] + before_action :set_conference, only: [ :show, :stats ] private - def authorize_permission - super("manage_conferences") - end - def set_conference @conference = Conference.find_by(slug: params[:slug]) end - def conference_params - all_params = params.require(:conference).permit(:name, :slug, :starts_at, :ends_at, :url, :time_zone, :import_job_class, data: {}).to_h - - data_hash = @conference&.data&.dup || {} - - if params[:data].present? - params[:data].each do |key, value| - data_hash[key] = value.presence - end - end - - if params[:custom_field_keys].present? && params[:custom_field_values].present? - keys = params[:custom_field_keys] - values = params[:custom_field_values] - - keys.each_with_index do |key, index| - next if key.blank? - data_hash[key] = values[index].presence - end - end - - all_params[:data] = data_hash - - all_params - end - public def self.available_import_job_classes @@ -107,37 +76,6 @@ class ConferencesController < ApplicationController @users = User.all end - def new - @conference = Conference.new - end - - def create - @conference = Conference.new(conference_params) - - if @conference.save - redirect_to conference_path(slug: @conference.slug), notice: "Conference was successfully created." - else - render :new, status: :unprocessable_entity - end - end - - def edit - # @conference is set by the before_action - end - - def update - if @conference.update(conference_params) - redirect_to conference_path(slug: @conference.slug), notice: "Conference was successfully updated." - else - render :edit, status: :unprocessable_entity - end - end - - def destroy - @conference.destroy - redirect_to conferences_path, notice: "Conference was successfully deleted." - end - def stats @conference = Conference.find_by(slug: params[:slug]) @relevant_stages = @conference.relevant_stages diff --git a/app/javascript/application.js b/app/javascript/application.js index 9a7c38e3c09de067a5b333670776a0adfcc2d9e5..d8e00596a5508f2c25fee17794ef5bfde6bdfc54 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,10 +1,9 @@ // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails +import "channels" import "controllers" import "@hotwired/turbo-rails" document.addEventListener("turbo:load", function() { - console.log('turbo:load'); - applyDarkmode(); const flashMessages = document.querySelectorAll(".flash"); flashMessages.forEach(flashMessage => { @@ -16,4 +15,4 @@ document.addEventListener("turbo:load", function() { flashMessage.parentNode.removeChild(flashMessage); }, 5000); }); -});import "channels" +}); diff --git a/app/models/user.rb b/app/models/user.rb index 4940c1406855194c9bad0ab78b8cc5bcee24ef83..d32f397dbc1ccaa7a4112027040a4a29b64537bf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -102,6 +102,11 @@ class User < ApplicationRecord roles.joins(:permissions).exists?(permissions: { name: permission_name }) end + # Alias for has_permission? with a more standard Rails name + def can?(permission_name) + has_permission?(permission_name) + end + def shiftcoordinator? has_role?("shift_coordinator") end diff --git a/app/views/assignments/by_user.html.erb b/app/views/assignments/by_user.html.erb index d74bc9c4d6de954c78c5f4c1b759286ed6d11fbe..8edfbb194003ac106d23d4cf588ce7b8479640b5 100644 --- a/app/views/assignments/by_user.html.erb +++ b/app/views/assignments/by_user.html.erb @@ -1,4 +1,5 @@ -<div class="max-w-full"> +<div class="container mx-auto px-4 py-8"> + <div class="max-w-full"> <h1 class="text-xl my-4 dark:text-red-500"> Assignments for <%= link_to @user.name, user_assignments_path(@user) %> diff --git a/app/views/assignments/index.html.erb b/app/views/assignments/index.html.erb index ff94edb93b091f8d9c45ccd4997e55606bcdd09d..06d829ff23810ce10a9c43b94a712c60c23549fd 100644 --- a/app/views/assignments/index.html.erb +++ b/app/views/assignments/index.html.erb @@ -1,5 +1,6 @@ -<% now = Time.now %> -<div class="scroll-smooth"> +<div class="container mx-auto px-4 py-8"> + <% now = Time.now %> + <div class="scroll-smooth"> <h1 class="text-xl my-4 dark:text-red-500">Assignments for all users</h1> <p> Jump to: diff --git a/app/views/conferences/edit.html.erb b/app/views/conferences/edit.html.erb deleted file mode 100644 index 4acecd24ed85cde7d154db364386be791d81bfd2..0000000000000000000000000000000000000000 --- a/app/views/conferences/edit.html.erb +++ /dev/null @@ -1,158 +0,0 @@ -<div class="container mx-auto px-4 py-8"> - <h1 class="text-2xl font-bold mb-6 dark:text-gray-200">Edit Conference: <%= @conference.name %></h1> - - <%= form_with(model: @conference, url: conference_path(slug: @conference.slug), method: :patch, class: "space-y-6") do |form| %> - <% if @conference.errors.any? %> - <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> - <h2 class="font-bold"><%= pluralize(@conference.errors.count, "error") %> prohibited this conference from being saved:</h2> - <ul class="list-disc list-inside mt-2"> - <% @conference.errors.full_messages.each do |message| %> - <li><%= message %></li> - <% end %> - </ul> - </div> - <% 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> - <%= 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, 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> - - <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, {}, { 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="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 :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> - </div> - - <div data-controller="dynamic-fields"> - <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: { dynamic_fields_target: "importJobClass", action: "change->dynamic-fields#updateRequiredFields" } } %> - <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> - - <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-dynamic-fields-target="requiredFields"> - <% @conference.required_data_fields.each do |field| %> - <div class="mb-4"> - <%= form.label "data[#{field}]", field.humanize, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %> - <%= form.url_field "data[#{field}]", value: @conference.data&.dig(field), 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 %> - - <% if @conference.required_data_fields.empty? %> - <p class="text-sm text-gray-500 dark:text-gray-400">No required fields for this import job class</p> - <% end %> - </div> - </fieldset> - - <fieldset class="mt-6 border border-gray-300 rounded-md p-4 dark:border-gray-600" data-controller="dynamic-fields"> - <legend class="px-2 text-sm font-medium text-gray-700 dark:text-gray-300">Custom Data Fields</legend> - - <div class="space-y-4" data-dynamic-fields-target="container"> - <% if @conference.data.present? %> - <% @conference.data.except('schedule_url', 'filedrop_url', 'engelsystem_url', 'heartbeat_url').each do |key, value| %> - <div class="flex items-center space-x-2 nested-field"> - <div class="flex-1"> - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label> - <input type="text" 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" data-field-key> - </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="data[<%= key %>]" 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"> - </div> - <div class="flex items-end"> - <button type="button" data-action="click->dynamic-fields#removeField" class="mt-1 p-2 text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"> - <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> - <path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" /> - </svg> - </button> - </div> - </div> - <% end %> - <% end %> - </div> - - <template data-dynamic-fields-target="template"> - <div class="flex items-center space-x-2 nested-field"> - <div class="flex-1"> - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label> - <input type="text" name="data[custom_key_NEW_RECORD]" 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" data-field-key> - </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="data[custom_value_NEW_RECORD]" 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"> - </div> - <div class="flex items-end"> - <button type="button" data-action="click->dynamic-fields#removeField" class="mt-1 p-2 text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"> - <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> - <path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" /> - </svg> - </button> - </div> - </div> - </template> - - <div class="mt-4"> - <button type="button" data-action="click->dynamic-fields#addField" class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:bg-indigo-900 dark:text-indigo-200 dark:hover:bg-indigo-800"> - <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 - </button> - </div> - </fieldset> - </div> - - <div class="flex justify-between pt-6"> - <%= link_to "Cancel", conference_path(slug: @conference.slug), class: "px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:bg-gray-700 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-600" %> - - <%= form.submit "Update Conference", class: "inline-flex justify-center px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:bg-blue-700 dark:hover:bg-blue-800" %> - </div> - <% end %> - - <div class="mt-8 pt-8 border-t border-gray-200 dark:border-gray-700"> - <h2 class="text-xl font-bold mb-4 dark:text-gray-200">Danger Zone</h2> - - <div class="bg-red-50 border border-red-300 rounded-md p-4 dark:bg-red-900/20 dark:border-red-800"> - <h3 class="text-lg font-medium text-red-800 dark:text-red-300">Delete This Conference</h3> - <p class="mt-1 text-sm text-red-700 dark:text-red-400">Once you delete a conference, there is no going back. This will delete all associated data including sessions, speakers, and stages.</p> - - <div class="mt-4"> - <%= button_to "Delete Conference", conference_path(slug: @conference.slug), method: :delete, - data: { confirm: "Are you sure you want to delete this conference? This action cannot be undone." }, - class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 dark:bg-red-700 dark:hover:bg-red-800" %> - </div> - </div> - </div> -</div> diff --git a/app/views/conferences/index.html.erb b/app/views/conferences/index.html.erb index 514fc3d060f26f6f56c9a371fe9d12fea0624c45..da7bbad8dbcfb791e3affedea454626bde7c462d 100644 --- a/app/views/conferences/index.html.erb +++ b/app/views/conferences/index.html.erb @@ -2,8 +2,8 @@ <div class="flex justify-between items-center mb-6"> <h1 class="text-2xl font-bold dark:text-gray-200">Conferences</h1> - <% if user_signed_in? && current_user.has_role?("events_admin") %> - <%= link_to new_conference_path, class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:bg-blue-700 dark:hover:bg-blue-800" do %> + <% if user_signed_in? && current_user.can?("manage_conferences") %> + <%= link_to new_admin_conference_path, class: "inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:bg-blue-700 dark:hover:bg-blue-800" do %> <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" 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> @@ -35,9 +35,9 @@ </div> </div> - <% if user_signed_in? && current_user.has_role?("events_admin") %> + <% if user_signed_in? && current_user.can?("manage_conferences") %> <div class="flex-shrink-0 flex"> - <%= link_to edit_conference_path(slug: conference.slug), class: "ml-2 text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" do %> + <%= link_to edit_admin_conference_path(slug: conference.slug), class: "ml-2 text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" do %> <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> <path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" /> </svg> diff --git a/app/views/conferences/new.html.erb b/app/views/conferences/new.html.erb deleted file mode 100644 index 6f58f4fcf31050922e838cb86b424cfe30ad9ab3..0000000000000000000000000000000000000000 --- a/app/views/conferences/new.html.erb +++ /dev/null @@ -1,115 +0,0 @@ -<div class="container mx-auto px-4 py-8"> - <h1 class="text-2xl font-bold mb-6 dark:text-gray-200">New Conference</h1> - - <%= form_with(model: @conference, url: conferences_path, class: "space-y-6") do |form| %> - <% if @conference.errors.any? %> - <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> - <h2 class="font-bold"><%= pluralize(@conference.errors.count, "error") %> prohibited this conference from being saved:</h2> - <ul class="list-disc list-inside mt-2"> - <% @conference.errors.full_messages.each do |message| %> - <li><%= message %></li> - <% end %> - </ul> - </div> - <% 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> - <%= 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, 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> - - <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="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, 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 :ends_at, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %> - <%= form.datetime_local_field :ends_at, 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 data-controller="dynamic-fields"> - <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: { dynamic_fields_target: "importJobClass", action: "change->dynamic-fields#updateRequiredFields" } } %> - <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> - - <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-dynamic-fields-target="requiredFields"> - <!-- Required fields will be dynamically added here --> - <p class="text-sm text-gray-500 dark:text-gray-400">Select an import job class to see required fields</p> - </div> - </fieldset> - - <fieldset class="mt-6 border border-gray-300 rounded-md p-4 dark:border-gray-600" data-controller="dynamic-fields"> - <legend class="px-2 text-sm font-medium text-gray-700 dark:text-gray-300">Custom Data Fields</legend> - - <div class="space-y-4" data-dynamic-fields-target="container"> - <!-- Dynamic fields will be added here --> - </div> - - <template data-dynamic-fields-target="template"> - <div class="flex items-center space-x-2 nested-field"> - <div class="flex-1"> - <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Key</label> - <input type="text" name="data[custom_key_NEW_RECORD]" 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" data-field-key> - </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="data[custom_value_NEW_RECORD]" 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"> - </div> - <div class="flex items-end"> - <button type="button" data-action="click->dynamic-fields#removeField" class="mt-1 p-2 text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"> - <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"> - <path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" /> - </svg> - </button> - </div> - </div> - </template> - - <div class="mt-4"> - <button type="button" data-action="click->dynamic-fields#addField" class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:bg-indigo-900 dark:text-indigo-200 dark:hover:bg-indigo-800"> - <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 - </button> - </div> - </fieldset> - </div> - - <div class="flex justify-between pt-6"> - <%= link_to "Cancel", conferences_path, class: "px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:bg-gray-700 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-600" %> - - <%= form.submit "Create Conference", class: "inline-flex justify-center px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:bg-blue-700 dark:hover:bg-blue-800" %> - </div> - <% end %> -</div> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 1289c8d41e086d148408915f5841ebf883aedaef..cf4a9afe6f212966f302723c733dd9066e003a30 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -21,18 +21,18 @@ </div> <nav class="flex items-center space-x-4"> <% if user_signed_in? %> - <div class="flex items-center mr-4"> - <div class="w-8 h-8 rounded-full flex items-center justify-center mr-2" style="background-color: <%= current_user.avatar_color %>; color: <%= current_user.text_color %>"> - <%= current_user.initials %> - </div> - <span class="text-gray-700 dark:text-gray-300"><%= current_user.name %></span> - </div> <% if current_user.has_role?("events_admin") %> <%= link_to "Admin", admin_conferences_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <% end %> <%= link_to "Conferences", conferences_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <%= link_to "Assignments", assignments_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <%= link_to "Sign Out", destroy_user_session_path, method: :delete, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> + <div class="flex items-center mr-4"> + <div class="w-8 h-8 rounded-full flex items-center justify-center mr-2" style="background-color: <%= current_user.avatar_color %>; color: <%= current_user.text_color %>"> + <%= current_user.initials %> + </div> + <span class="text-gray-700 dark:text-gray-300"><%= current_user.name %></span> + </div> <% else %> <%= link_to "Sign In", new_user_session_path, class: "text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white" %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index 9fbdf753d4564e08b330a4b88eababcf629fbd67..561cc66032eaf710ccdd047c641b891a18a5af1c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,10 +15,9 @@ Rails.application.routes.draw do get "up" => "rails/health#show", as: :rails_health_check # Defines the root path route ("/") - # root "posts#index" root "conferences#index" - resources :conferences, param: :slug do + resources :conferences, param: :slug, only: [ :index, :show ] do collection do get "required_fields", to: "conferences#required_fields" end