diff --git a/app/controllers/contestants_controller.rb b/app/controllers/contestants_controller.rb index c6fa194..545c786 100644 --- a/app/controllers/contestants_controller.rb +++ b/app/controllers/contestants_controller.rb @@ -164,7 +164,7 @@ class ContestantsController < ApplicationController skip_authorization @contestant = Contestant.find(params[:contestant_id]) - if !@contestant || !@contestant.contest.code.present? + if !@contestant || !@contestant.contest.code.present? || !@contestant.contest.organizer_form not_found and return end @contest = @contestant.contest diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index 88c7df2..c355cfa 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -286,7 +286,7 @@ class ContestsController < ApplicationController end def settings_onsite_params - params.expect(contest: [ :code ]) + params.expect(contest: [ :code, :organizer_form ]) end def settings_online_params diff --git a/app/models/contest.rb b/app/models/contest.rb index 1b4ded9..cd42a54 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -10,6 +10,7 @@ # lang :string default("en") # name :string # offline_form :boolean default(FALSE) +# organizer_form :boolean # pause_time :datetime # public :boolean default(FALSE) # ranking_mode :string diff --git a/app/views/contests/settings_onsite_edit.html.slim b/app/views/contests/settings_onsite_edit.html.slim index f6d793b..cc60dfd 100644 --- a/app/views/contests/settings_onsite_edit.html.slim +++ b/app/views/contests/settings_onsite_edit.html.slim @@ -1,7 +1,17 @@ = render "params_nav" = form_with model: @contest, url: "/contests/#{@contest.id}/settings/onsite" do |form| - .row.mt-2.mb-3 + .row + .col + .alert.alert-warning role="alert" + = t("contests.nav.onsite_description") + .row.mt-1 + .col + .form-check.form-switch + = form.check_box :organizer_form, class: "form-check-input" + = form.label :organizer_form + .form-text = t("activerecord.attributes.contest.organizer_form") + .row.mt-3.mb-3 .col .form-floating = form.text_field :code, autocomplete: "off", class: "form-control" diff --git a/config/locales/en.yml b/config/locales/en.yml index f931286..f981a3f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -63,6 +63,8 @@ en: offline_form: Enable the offline participation form offline_form_description: Offline participants will have to fill the form by providing an image taken of the puzzle before starting solving it, and validate their finish time with an upload of an image of the completed puzzle offline_form_warning: Only for single-puzzle contests + organizer_form: Enable the public organizer forms + organizer_form_description: Required for QR codes to work. public: Enable the public scoreboard ranking_mode: Ranking mode (public scoreboard & CSV exports) show_stopwatch: Display the stopwatch @@ -213,6 +215,7 @@ en: general: General online: Online contests onsite: Onsite contests + onsite_description: Beware once those forms are activated, the puzzle names become findable through guessing the form URL. Later I'll work on better securing them so this setting won't be necessary anymore. public: Public scoreboard settings: Settings stopwatch: Stopwatch diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 08871e6..c4e869e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -25,7 +25,7 @@ fr: projected_time: Temps projeté remaining_pieces: Pièces restantes (puzzle non fini) contest: - code: Code pour les organisateur.ice.s + code: Code pour les organisateur.ices code_description: Optionnel. Utilisé pour les organisateur.ices dans les concours en présentiel lorsque sont imprimés des QR codes à placer sur les tables duration: Durée duration_description: Format h:mm ou hh:mm @@ -34,6 +34,8 @@ fr: offline_form: Activer le formulaire de participation hors-ligne offline_form_description: Les participant.e.s hors-ligne pourront participer en prenant une photo du puzzle avant de le commencer, puis valider leur temps avec une photo du puzzle une fois complété offline_form_warning: Activable uniquement pour les concours avec un seul puzzle + organizer_form: Activer les formulaires publics pour les organisateur.ices + organizer_form_description: Nécessaire pour que les QR codes fonctionnent public: Activer le classement public ranking_mode: Mode de classement (classement public & exports CSV) show_stopwatch: Afficher le chronomètre @@ -184,6 +186,7 @@ fr: general: Général online: Concours en ligne onsite: Concours en présentiel + onsite_description: Attention, les URLs de ces formulaires sont actuellement techniquement devinables, et une personne mal intentionnée pourrait y trouver la liste de noms des puzzles grâce au menu déroulant présent sur ce formulaire. Je vais travailler bientôt à mieux sécuriser ces formulaires et ce paramètre deviendra alors non nécessaire. En attendant je recommande de garder ce paramètre désactivé tant que le concours n'est pas commencé. public: Classement public settings: Paramètres stopwatch: Chronomètre diff --git a/db/migrate/20260424091108_add_organizer_form_to_contest.rb b/db/migrate/20260424091108_add_organizer_form_to_contest.rb new file mode 100644 index 0000000..9847e3b --- /dev/null +++ b/db/migrate/20260424091108_add_organizer_form_to_contest.rb @@ -0,0 +1,5 @@ +class AddOrganizerFormToContest < ActiveRecord::Migration[8.0] + def change + add_column :contests, :organizer_form, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 4548a40..ee2454f 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[8.0].define(version: 2025_12_10_092658) do +ActiveRecord::Schema[8.0].define(version: 2026_04_24_091108) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false @@ -106,6 +106,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_10_092658) do t.datetime "start_time" t.datetime "pause_time" t.boolean "show_stopwatch" + t.string "organizer_form" t.index ["slug"], name: "index_contests_on_slug", unique: true t.index ["user_id"], name: "index_contests_on_user_id" end diff --git a/spec/factories/contests.rb b/spec/factories/contests.rb index 0ace6f5..2189a13 100644 --- a/spec/factories/contests.rb +++ b/spec/factories/contests.rb @@ -10,6 +10,7 @@ # lang :string default("en") # name :string # offline_form :boolean default(FALSE) +# organizer_form :boolean # pause_time :datetime # public :boolean default(FALSE) # ranking_mode :string