From 1fc05bea63fb77fb8d61f9079a923d3dcec15d95 Mon Sep 17 00:00:00 2001 From: sto Date: Mon, 8 Dec 2025 09:49:24 +0100 Subject: [PATCH] Split scoreboard UI in partials https://gitea.puzzle-scoreboard.org/sto/puzzle-scoreboard/issues/13 --- .../_scoreboard_desktop_marathon.html.slim | 47 ++++++++ .../_scoreboard_desktop_single.html.slim | 45 +++++++ .../_scoreboard_mobile_single.html.slim | 48 ++++++++ app/views/contests/scoreboard.html.slim | 114 ++---------------- 4 files changed, 149 insertions(+), 105 deletions(-) create mode 100644 app/views/contests/_scoreboard_desktop_marathon.html.slim create mode 100644 app/views/contests/_scoreboard_desktop_single.html.slim create mode 100644 app/views/contests/_scoreboard_mobile_single.html.slim diff --git a/app/views/contests/_scoreboard_desktop_marathon.html.slim b/app/views/contests/_scoreboard_desktop_marathon.html.slim new file mode 100644 index 0000000..e9dcdfe --- /dev/null +++ b/app/views/contests/_scoreboard_desktop_marathon.html.slim @@ -0,0 +1,47 @@ +.d-flex.flex-column style="height: calc(100vh - 180px)" + + = render "selectors" + + .d-flex.flex-column style="overflow-y: auto" + .table-responsive-md + table.table.table-striped.table-hover + thead + tr + th + th + th + th + - @puzzles.each do |puzzle| + th scope="col" + = image_tag(puzzle.image, class: "img-fluid", style: "max-height: 64px;") if puzzle.image.attached? + tr + th scope="col" + = t("helpers.rank") + th scope="col" + = t("activerecord.attributes.contestant.name") + th scope="col" + = t("activerecord.attributes.contestant.completions") + th scope="col" + = t("activerecord.attributes.contestant.display_time") + - @puzzles.each do |puzzle| + th scope="col" + = puzzle.name + tbody + - @contestants.each_with_index do |contestant, index| + tr scope="row" + td + = index + 1 + td + = contestant.name + td + = 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 + - @puzzles.each do |puzzle| + td + - contestant.completions.each do |completion| + - if completion.puzzle == puzzle + - if completion.completed + = completion.display_relative_time + - elsif completion.remaining_pieces.present? + = "#{puzzle.pieces - completion.remaining_pieces}p" \ No newline at end of file diff --git a/app/views/contests/_scoreboard_desktop_single.html.slim b/app/views/contests/_scoreboard_desktop_single.html.slim new file mode 100644 index 0000000..35bed93 --- /dev/null +++ b/app/views/contests/_scoreboard_desktop_single.html.slim @@ -0,0 +1,45 @@ += render "selectors" + +.row + .mt-3.col-6.d-flex.flex-column style="height: calc(100vh - 250px)" + .d-flex.flex-column style="overflow-y: auto" + table.table.table-striped.table-hover + thead + tr + th + = t("helpers.rank") + th + = t("activerecord.attributes.contestant.name") + - if @contest.puzzles.size > 1 + th + = t("activerecord.attributes.contestant.completions") + th style="width: 170px" + = t("activerecord.attributes.contestant.display_time") + tbody + - @contestants.each_with_index do |contestant, index| + tr scope="row" + td + = index + 1 + - if contestant.offline.present? + = @space + | (hors-ligne) + td + = contestant.name + - if @contest.puzzles.size > 1 + td + = contestant.completions.where(remaining_pieces: nil).length + td style="position: relative" + - if index > 0 && contestant.time_seconds > 0 && contestant.completions.where(completed: true).size > 0 + .relative-time style="position:absolute; margin: 1px 0 0 112px; font-size: 14px; color: grey" + |> + + = display_time(contestant.time_seconds - @contestants[index - 1].time_seconds) + = contestant.display_time + .col-1 + .col-5 + - @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 + .fs-6 style="margin-left: 15px" + b + = "#{puzzle.brand} - #{puzzle.pieces}p" \ No newline at end of file diff --git a/app/views/contests/_scoreboard_mobile_single.html.slim b/app/views/contests/_scoreboard_mobile_single.html.slim new file mode 100644 index 0000000..636527e --- /dev/null +++ b/app/views/contests/_scoreboard_mobile_single.html.slim @@ -0,0 +1,48 @@ +css: + .container { margin-top: 2rem !important; } + +.row + - if @puzzles.size > 0 + .d-flex.flex-column.justify-content-center.mb-5 + = image_tag(@puzzles[0].image, style: "max-height: 200px; object-fit: contain") if @puzzles[0].image.attached? + .mt-2.fs-6 style="text-align: center" + => "#{@puzzles[0].name} -" + = "#{@puzzles[0].brand} #{@puzzles[0].pieces}p" + += render "selectors" + +.row + .mt-3.d-flex.flex-column style="height: calc(100vh - 250px)" + .d-flex.flex-column style="overflow-y: auto" + table.table.table-striped.table-hover + thead + tr + th + = t("helpers.rank") + th + = t("activerecord.attributes.contestant.name") + - if @contest.puzzles.size > 1 + th + = t("activerecord.attributes.contestant.completions") + th style="width: 170px" + = t("activerecord.attributes.contestant.display_time") + tbody + - @contestants.each_with_index do |contestant, index| + tr scope="row" + td + = index + 1 + - if contestant.offline.present? + = @space + | (hors-ligne) + td + = contestant.name + - if @contest.puzzles.size > 1 + td + = contestant.completions.where(remaining_pieces: nil).length + td style="position: relative" + - if index > 0 && contestant.time_seconds > 0 && contestant.completions.where(completed: true).size > 0 + .relative-time style="position:absolute; margin: 1px 0 0 112px; font-size: 14px; color: grey" + |> + + = display_time(contestant.time_seconds - @contestants[index - 1].time_seconds) + = contestant.display_time + .col-1 \ No newline at end of file diff --git a/app/views/contests/scoreboard.html.slim b/app/views/contests/scoreboard.html.slim index df8606f..7c8db60 100644 --- a/app/views/contests/scoreboard.html.slim +++ b/app/views/contests/scoreboard.html.slim @@ -1,112 +1,16 @@ css: @media (max-width: 800px) { - a.btn { display: none; } - .col-5 { display: none; } - .col-6 { width: 100% !important; display: block !important; } - .small-screen-image { display: block !important; } - .container { margin-top: 2rem !important; } + .mobile-single { display: block !important; } + .desktop-single { display: none; } } -- if @contest.puzzles.size <= 1 - .row.small-screen-image style="display: none" - - @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" - => "#{puzzle.name} -" - = "#{puzzle.brand} #{puzzle.pieces}p" - = render "selectors" - .row - .mt-3.col-6.d-flex.flex-column style="height: calc(100vh - 250px)" - .d-flex.flex-column style="overflow-y: auto" - table.table.table-striped.table-hover - thead - tr - th - = t("helpers.rank") - th - = t("activerecord.attributes.contestant.name") - - if @contest.puzzles.size > 1 - th - = t("activerecord.attributes.contestant.completions") - th style="width: 170px" - = t("activerecord.attributes.contestant.display_time") - tbody - - @contestants.each_with_index do |contestant, index| - tr scope="row" - td - = index + 1 - - if contestant.offline.present? - = @space - | (hors-ligne) - td - = contestant.name - - if @contest.puzzles.size > 1 - td - = contestant.completions.where(remaining_pieces: nil).length - td style="position: relative" - - if index > 0 && contestant.time_seconds > 0 && contestant.completions.where(completed: true).size > 0 - .relative-time style="position:absolute; margin: 1px 0 0 112px; font-size: 14px; color: grey" - |> + - = display_time(contestant.time_seconds - @contestants[index - 1].time_seconds) - = contestant.display_time - .col-1 - .col-5 - - @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 - .fs-6 style="margin-left: 15px" - b - = "#{puzzle.brand} - #{puzzle.pieces}p" - +- if @contest.puzzles.size < 2 + .mobile-single style="display: none;" + = render "scoreboard_mobile_single" + .desktop-single + = render "scoreboard_desktop_single" + - else - .d-flex.flex-column style="height: calc(100vh - 180px)" - - = render "selectors" - - .d-flex.flex-column style="overflow-y: auto" - .table-responsive-md - table.table.table-striped.table-hover - thead - tr - th - th - th - th - - @puzzles.each do |puzzle| - th scope="col" - = image_tag(puzzle.image, class: "img-fluid", style: "max-height: 64px;") if puzzle.image.attached? - tr - th scope="col" - = t("helpers.rank") - th scope="col" - = t("activerecord.attributes.contestant.name") - th scope="col" - = t("activerecord.attributes.contestant.completions") - th scope="col" - = t("activerecord.attributes.contestant.display_time") - - @puzzles.each do |puzzle| - th scope="col" - = puzzle.name - tbody - - @contestants.each_with_index do |contestant, index| - tr scope="row" - td - = index + 1 - td - = contestant.name - td - = 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 - - @puzzles.each do |puzzle| - td - - contestant.completions.each do |completion| - - if completion.puzzle == puzzle - - if completion.completed - = completion.display_relative_time - - else - = "#{puzzle.pieces - completion.remaining_pieces}p" \ No newline at end of file + = render "scoreboard_desktop_marathon" \ No newline at end of file