diff --git a/app/controllers/contestants_controller.rb b/app/controllers/contestants_controller.rb index 6c2d1d2..5791415 100644 --- a/app/controllers/contestants_controller.rb +++ b/app/controllers/contestants_controller.rb @@ -149,7 +149,7 @@ class ContestantsController < ApplicationController end @contest = @contestant.contest I18n.locale = @contest.lang - @puzzles = @contest.puzzles + @puzzles = @contest.puzzles.where(hidden: false).or(@contest.puzzles.where(hidden: nil)).order(:id) @completion = Completion.new @completion.completed = true @public = true diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index f161b47..48c52ea 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -99,7 +99,7 @@ class ContestsController < ApplicationController if params.key?(:hide_offline) && params[:hide_offline] == "true" @contestants = @contestants.select { |contestant| !contestant.offline.present? } end - @puzzles = @contest.puzzles.order(:id) + @puzzles = @contest.puzzles.where(hidden: false).or(@contest.puzzles.where(hidden: nil)).order(:id) if params.key?(:hide_offline) && params.key?(:category) @action_path = "/public/#{@contest.friendly_id}?hide_offline=#{params[:hide_offline]}&category=#{params[:category]}" elsif params.key?(:category) diff --git a/app/controllers/puzzles_controller.rb b/app/controllers/puzzles_controller.rb index 8f42ead..b450dd2 100644 --- a/app/controllers/puzzles_controller.rb +++ b/app/controllers/puzzles_controller.rb @@ -59,6 +59,6 @@ class PuzzlesController < ApplicationController end def puzzle_params - params.expect(puzzle: [ :brand, :name, :image, :pieces ]) + params.expect(puzzle: [ :brand, :name, :image, :pieces, :hidden ]) end end diff --git a/app/models/puzzle.rb b/app/models/puzzle.rb index 6a84289..b690d9b 100644 --- a/app/models/puzzle.rb +++ b/app/models/puzzle.rb @@ -4,6 +4,7 @@ # # id :integer not null, primary key # brand :string +# hidden :boolean # name :string # pieces :integer not null # created_at :datetime not null diff --git a/app/views/contests/scoreboard.html.slim b/app/views/contests/scoreboard.html.slim index b22a5f3..df8606f 100644 --- a/app/views/contests/scoreboard.html.slim +++ b/app/views/contests/scoreboard.html.slim @@ -9,7 +9,7 @@ css: - if @contest.puzzles.size <= 1 .row.small-screen-image style="display: none" - - @contest.puzzles.each do |puzzle| + - @puzzles.each do |puzzle| .d-flex.flex-column.justify-content-center.mb-5 = image_tag(puzzle.image, style: "max-height: 200px; object-fit: contain") if puzzle.image.attached? .mt-2.fs-6 style="text-align: center" @@ -54,7 +54,7 @@ css: = contestant.display_time .col-1 .col-5 - - @contest.puzzles.each do |puzzle| + - @puzzles.each do |puzzle| = image_tag(puzzle.image, class: "img-fluid ms-3 me-3") if puzzle.image.attached? .mt-3.fs-4 style="margin-left: 15px" = puzzle.name @@ -76,7 +76,7 @@ css: th th th - - @contest.puzzles.each do |puzzle| + - @puzzles.each do |puzzle| th scope="col" = image_tag(puzzle.image, class: "img-fluid", style: "max-height: 64px;") if puzzle.image.attached? tr @@ -88,7 +88,7 @@ css: = t("activerecord.attributes.contestant.completions") th scope="col" = t("activerecord.attributes.contestant.display_time") - - @contest.puzzles.each do |puzzle| + - @puzzles.each do |puzzle| th scope="col" = puzzle.name tbody @@ -102,7 +102,7 @@ css: = contestant.completions.where(remaining_pieces: nil).length td = contestant.completions.size > 0 && contestant.completions[-1].remaining_pieces ? "#{contestant.completions.map{|completion| completion.puzzle.pieces}.sum - contestant.completions[-1].remaining_pieces}p" : contestant.display_time - - @contest.puzzles.each do |puzzle| + - @puzzles.each do |puzzle| td - contestant.completions.each do |completion| - if completion.puzzle == puzzle diff --git a/app/views/puzzles/_form.html.slim b/app/views/puzzles/_form.html.slim index ce68ef3..c6d26c1 100644 --- a/app/views/puzzles/_form.html.slim +++ b/app/views/puzzles/_form.html.slim @@ -21,6 +21,13 @@ .form-floating = form.number_field :pieces, autocomplete: "off", class: "form-control" = form.label :pieces, class: "required" + .row.mb-3 + .col + .form-check.form-switch + = form.check_box :hidden, class: "form-check-input" + = form.label :hidden + .form-text + = t("activerecord.attributes.puzzle.hidden_description") .row.mb-3 .col .form-text.mb-1 @@ -42,7 +49,7 @@ } setMaxUploadSize(); - .row.mt-4 + .row.mt-4.mb-5 .col - if method == :patch = link_to t("helpers.buttons.delete"), contest_puzzle_path(contest, puzzle), data: { turbo_method: :delete }, class: "btn btn-danger me-2" diff --git a/app/views/puzzles/index.html.slim b/app/views/puzzles/index.html.slim index 379d8bb..a175fa5 100644 --- a/app/views/puzzles/index.html.slim +++ b/app/views/puzzles/index.html.slim @@ -16,6 +16,8 @@ = t("activerecord.attributes.puzzle.brand") th = t("activerecord.attributes.puzzle.pieces") + th + = t("activerecord.attributes.puzzle.hidden") tbody - @puzzles.each do |puzzle| tr.align-middle scope="row" @@ -27,6 +29,12 @@ = puzzle.brand td = puzzle.pieces + td + - if puzzle.hidden? + + + + td a.btn.btn-sm.btn-secondary href=edit_contest_puzzle_path(@contest, puzzle) = t("helpers.buttons.edit") \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index ca7b281..a36b145 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -91,6 +91,8 @@ en: remaining_pieces: Remaining pieces puzzle: brand: Brand + hidden: hidden + hidden_description: When hidden, a puzzle doesn't appear in the public scoreboard, nor public forms image: Image name: Name pieces: Number of pieces diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 3461a55..548083b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -62,6 +62,8 @@ fr: remaining_pieces: Pièces restantes puzzle: brand: Marque + hidden: Non découvert + hidden_description: Un puzzle non découvert n'apparaît pas dans le classement public, ni dans les formulaires publics image: Image name: Nom pieces: Nombre de pièces diff --git a/db/migrate/20251204100550_add_hidden_to_puzzle.rb b/db/migrate/20251204100550_add_hidden_to_puzzle.rb new file mode 100644 index 0000000..c337fd1 --- /dev/null +++ b/db/migrate/20251204100550_add_hidden_to_puzzle.rb @@ -0,0 +1,5 @@ +class AddHiddenToPuzzle < ActiveRecord::Migration[8.0] + def change + add_column :puzzles, :hidden, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index b638e33..563fa05 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_11_20_152211) do +ActiveRecord::Schema[8.0].define(version: 2025_12_04_100550) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false @@ -161,6 +161,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_11_20_152211) do t.integer "contest_id", null: false t.string "brand" t.integer "pieces", null: false + t.boolean "hidden" t.index ["contest_id"], name: "index_puzzles_on_contest_id" end