Show offline contestants in dashboard
Some checks failed
CI / scan_ruby (push) Failing after 18s
CI / scan_js (push) Successful in 13s
CI / lint (push) Successful in 17s
CI / test (push) Failing after 53s

This commit is contained in:
sto
2025-11-05 17:18:47 +01:00
parent d62b46b7df
commit 5348574ea4
11 changed files with 73 additions and 36 deletions

View File

@@ -1,4 +1,6 @@
class ContestsController < ApplicationController
include CompletionsConcern
before_action :set_contest, only: %i[ destroy edit show update ]
before_action :offline_setup, only: %i[ offline_new offline_create offline_edit offline_update offline_completed ]
skip_before_action :require_authentication, only: %i[ scoreboard offline_new offline_create offline_edit offline_update offline_completed ]
@@ -139,8 +141,18 @@ class ContestsController < ApplicationController
end
@offline.completed = true
@offline.end_time = Time.now()
@offline.images.attach(params[:offline][:end_image])
if @offline.save
if @contest.puzzles.length > 0
dp = display_time(@offline.end_time.to_i - @offline.start_time.to_i)
contestant = Contestant.create(contest: @contest, name: @offline.name, offline: @offline)
Completion.create(contest: @contest,
contestant: contestant,
puzzle: @contest.puzzles[0],
display_time_from_start: dp)
extend_completions!(contestant)
end
redirect_to "/public/#{@contest.friendly_id}/offline/#{@offline.generate_token_for(:token)}/completed"
else
render :offline_edit, status: :unprocessable_entity

View File

@@ -22,6 +22,7 @@
class Contestant < ApplicationRecord
belongs_to :contest
has_many :completions, dependent: :destroy
has_one :offline
has_and_belongs_to_many :categories
before_validation :initialize_time_seconds_if_empty

View File

@@ -2,25 +2,29 @@
#
# Table name: offlines
#
# id :integer not null, primary key
# completed :boolean
# end_time :datetime
# name :string not null
# start_time :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
# contest_id :integer not null
# id :integer not null, primary key
# completed :boolean
# end_time :datetime
# name :string not null
# start_time :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
# contest_id :integer not null
# contestant_id :integer
#
# Indexes
#
# index_offlines_on_contest_id (contest_id)
# index_offlines_on_contest_id (contest_id)
# index_offlines_on_contestant_id (contestant_id)
#
# Foreign Keys
#
# contest_id (contest_id => contests.id)
# contest_id (contest_id => contests.id)
# contestant_id (contestant_id => contestants.id)
#
class Offline < ApplicationRecord
belongs_to :contest
belongs_to :contestant, optional: true
has_many_attached :images

View File

@@ -13,7 +13,7 @@
displayTimeEl.innerHTML = `${hh < 10 ? `0${hh}` : hh}:${mm < 10 ? `0${mm}` : mm}:${ss < 10 ? `0${ss}` : ss}`;
setTimeout(updateTime, 1000);
}
setTimeout(updateTime, 5);
setTimeout(updateTime, 50);
.row.mt-5.mb-3
.col
.form-text.mb-1

View File

@@ -75,10 +75,10 @@ javascript:
table.table.table-striped.table-hover
thead
tr
th
= t("helpers.rank")
th
= t("activerecord.attributes.contestant.name")
th
= t("activerecord.attributes.contestant.offline")
th
= t("activerecord.attributes.contestant.completions")
th
@@ -86,10 +86,14 @@ javascript:
tbody
- @contestants.each_with_index do |contestant, index|
tr scope="row"
td
= index + 1
td
= contestant.name
td
- if contestant.offline.present?
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-square" viewBox="0 0 16 16">
<path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
<path d="M10.97 4.97a.75.75 0 0 1 1.071 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425z"/>
</svg>
td
= contestant.completions.where(remaining_pieces: nil).length
td

View File

@@ -65,6 +65,7 @@ en:
display_time: Time
email: Email
name: Name
offline: Offline?
email_description: Optional. Used for sending emails through this app, or for identifying participants whose gmeet handle doesn't match their registered name.
csv_import:
file: File

View File

@@ -36,6 +36,7 @@ fr:
display_time: Temps
email: Email
name: Nom
offline: Hors-ligne ?
email_description: Optionnel. Utile pour envoyer des emails aux participant.e.s depuis cette app, ou pour reconnaître les pseudos gmeet quand ils ne correspondent pas au nom préalablement entré.
csv_import:
file: Fichier

View File

@@ -0,0 +1,5 @@
class AddContestantToOffline < ActiveRecord::Migration[8.0]
def change
add_reference :offlines, :contestant, foreign_key: true
end
end

5
db/schema.rb generated
View File

@@ -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_10_31_095604) do
ActiveRecord::Schema[8.0].define(version: 2025_11_05_153647) do
create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
@@ -134,7 +134,9 @@ ActiveRecord::Schema[8.0].define(version: 2025_10_31_095604) do
t.datetime "end_time"
t.string "name", null: false
t.boolean "completed"
t.integer "contestant_id"
t.index ["contest_id"], name: "index_offlines_on_contest_id"
t.index ["contestant_id"], name: "index_offlines_on_contestant_id"
end
create_table "puzzles", force: :cascade do |t|
@@ -177,6 +179,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_10_31_095604) do
add_foreign_key "contestants", "contests"
add_foreign_key "contests", "users"
add_foreign_key "messages", "contests"
add_foreign_key "offlines", "contestants"
add_foreign_key "offlines", "contests"
add_foreign_key "puzzles", "contests"
add_foreign_key "sessions", "users"

View File

@@ -2,22 +2,25 @@
#
# Table name: offlines
#
# id :integer not null, primary key
# completed :boolean
# end_time :datetime
# name :string not null
# start_time :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
# contest_id :integer not null
# id :integer not null, primary key
# completed :boolean
# end_time :datetime
# name :string not null
# start_time :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
# contest_id :integer not null
# contestant_id :integer
#
# Indexes
#
# index_offlines_on_contest_id (contest_id)
# index_offlines_on_contest_id (contest_id)
# index_offlines_on_contestant_id (contestant_id)
#
# Foreign Keys
#
# contest_id (contest_id => contests.id)
# contest_id (contest_id => contests.id)
# contestant_id (contestant_id => contestants.id)
#
FactoryBot.define do
factory :offline do

View File

@@ -2,22 +2,25 @@
#
# Table name: offlines
#
# id :integer not null, primary key
# completed :boolean
# end_time :datetime
# name :string not null
# start_time :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
# contest_id :integer not null
# id :integer not null, primary key
# completed :boolean
# end_time :datetime
# name :string not null
# start_time :datetime not null
# created_at :datetime not null
# updated_at :datetime not null
# contest_id :integer not null
# contestant_id :integer
#
# Indexes
#
# index_offlines_on_contest_id (contest_id)
# index_offlines_on_contest_id (contest_id)
# index_offlines_on_contestant_id (contestant_id)
#
# Foreign Keys
#
# contest_id (contest_id => contests.id)
# contest_id (contest_id => contests.id)
# contestant_id (contestant_id => contestants.id)
#
require 'rails_helper'