Show offline contestants in dashboard
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
class ContestsController < ApplicationController
|
class ContestsController < ApplicationController
|
||||||
|
include CompletionsConcern
|
||||||
|
|
||||||
before_action :set_contest, only: %i[ destroy edit show update ]
|
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 ]
|
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 ]
|
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
|
end
|
||||||
|
|
||||||
@offline.completed = true
|
@offline.completed = true
|
||||||
|
@offline.end_time = Time.now()
|
||||||
@offline.images.attach(params[:offline][:end_image])
|
@offline.images.attach(params[:offline][:end_image])
|
||||||
if @offline.save
|
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"
|
redirect_to "/public/#{@contest.friendly_id}/offline/#{@offline.generate_token_for(:token)}/completed"
|
||||||
else
|
else
|
||||||
render :offline_edit, status: :unprocessable_entity
|
render :offline_edit, status: :unprocessable_entity
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
class Contestant < ApplicationRecord
|
class Contestant < ApplicationRecord
|
||||||
belongs_to :contest
|
belongs_to :contest
|
||||||
has_many :completions, dependent: :destroy
|
has_many :completions, dependent: :destroy
|
||||||
|
has_one :offline
|
||||||
has_and_belongs_to_many :categories
|
has_and_belongs_to_many :categories
|
||||||
|
|
||||||
before_validation :initialize_time_seconds_if_empty
|
before_validation :initialize_time_seconds_if_empty
|
||||||
|
|||||||
@@ -2,25 +2,29 @@
|
|||||||
#
|
#
|
||||||
# Table name: offlines
|
# Table name: offlines
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# completed :boolean
|
# completed :boolean
|
||||||
# end_time :datetime
|
# end_time :datetime
|
||||||
# name :string not null
|
# name :string not null
|
||||||
# start_time :datetime not null
|
# start_time :datetime not null
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# contest_id :integer not null
|
# contest_id :integer not null
|
||||||
|
# contestant_id :integer
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# index_offlines_on_contest_id (contest_id)
|
# index_offlines_on_contest_id (contest_id)
|
||||||
|
# index_offlines_on_contestant_id (contestant_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
# Foreign Keys
|
||||||
#
|
#
|
||||||
# contest_id (contest_id => contests.id)
|
# contest_id (contest_id => contests.id)
|
||||||
|
# contestant_id (contestant_id => contestants.id)
|
||||||
#
|
#
|
||||||
class Offline < ApplicationRecord
|
class Offline < ApplicationRecord
|
||||||
belongs_to :contest
|
belongs_to :contest
|
||||||
|
belongs_to :contestant, optional: true
|
||||||
|
|
||||||
has_many_attached :images
|
has_many_attached :images
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
displayTimeEl.innerHTML = `${hh < 10 ? `0${hh}` : hh}:${mm < 10 ? `0${mm}` : mm}:${ss < 10 ? `0${ss}` : ss}`;
|
displayTimeEl.innerHTML = `${hh < 10 ? `0${hh}` : hh}:${mm < 10 ? `0${mm}` : mm}:${ss < 10 ? `0${ss}` : ss}`;
|
||||||
setTimeout(updateTime, 1000);
|
setTimeout(updateTime, 1000);
|
||||||
}
|
}
|
||||||
setTimeout(updateTime, 5);
|
setTimeout(updateTime, 50);
|
||||||
.row.mt-5.mb-3
|
.row.mt-5.mb-3
|
||||||
.col
|
.col
|
||||||
.form-text.mb-1
|
.form-text.mb-1
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ javascript:
|
|||||||
table.table.table-striped.table-hover
|
table.table.table-striped.table-hover
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th
|
|
||||||
= t("helpers.rank")
|
|
||||||
th
|
th
|
||||||
= t("activerecord.attributes.contestant.name")
|
= t("activerecord.attributes.contestant.name")
|
||||||
|
th
|
||||||
|
= t("activerecord.attributes.contestant.offline")
|
||||||
th
|
th
|
||||||
= t("activerecord.attributes.contestant.completions")
|
= t("activerecord.attributes.contestant.completions")
|
||||||
th
|
th
|
||||||
@@ -86,10 +86,14 @@ javascript:
|
|||||||
tbody
|
tbody
|
||||||
- @contestants.each_with_index do |contestant, index|
|
- @contestants.each_with_index do |contestant, index|
|
||||||
tr scope="row"
|
tr scope="row"
|
||||||
td
|
|
||||||
= index + 1
|
|
||||||
td
|
td
|
||||||
= contestant.name
|
= 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
|
td
|
||||||
= contestant.completions.where(remaining_pieces: nil).length
|
= contestant.completions.where(remaining_pieces: nil).length
|
||||||
td
|
td
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ en:
|
|||||||
display_time: Time
|
display_time: Time
|
||||||
email: Email
|
email: Email
|
||||||
name: Name
|
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.
|
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:
|
csv_import:
|
||||||
file: File
|
file: File
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ fr:
|
|||||||
display_time: Temps
|
display_time: Temps
|
||||||
email: Email
|
email: Email
|
||||||
name: Nom
|
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é.
|
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:
|
csv_import:
|
||||||
file: Fichier
|
file: Fichier
|
||||||
|
|||||||
5
db/migrate/20251105153647_add_contestant_to_offline.rb
Normal file
5
db/migrate/20251105153647_add_contestant_to_offline.rb
Normal 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
5
db/schema.rb
generated
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# 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|
|
create_table "active_storage_attachments", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "record_type", 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.datetime "end_time"
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.boolean "completed"
|
t.boolean "completed"
|
||||||
|
t.integer "contestant_id"
|
||||||
t.index ["contest_id"], name: "index_offlines_on_contest_id"
|
t.index ["contest_id"], name: "index_offlines_on_contest_id"
|
||||||
|
t.index ["contestant_id"], name: "index_offlines_on_contestant_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "puzzles", force: :cascade do |t|
|
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 "contestants", "contests"
|
||||||
add_foreign_key "contests", "users"
|
add_foreign_key "contests", "users"
|
||||||
add_foreign_key "messages", "contests"
|
add_foreign_key "messages", "contests"
|
||||||
|
add_foreign_key "offlines", "contestants"
|
||||||
add_foreign_key "offlines", "contests"
|
add_foreign_key "offlines", "contests"
|
||||||
add_foreign_key "puzzles", "contests"
|
add_foreign_key "puzzles", "contests"
|
||||||
add_foreign_key "sessions", "users"
|
add_foreign_key "sessions", "users"
|
||||||
|
|||||||
@@ -2,22 +2,25 @@
|
|||||||
#
|
#
|
||||||
# Table name: offlines
|
# Table name: offlines
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# completed :boolean
|
# completed :boolean
|
||||||
# end_time :datetime
|
# end_time :datetime
|
||||||
# name :string not null
|
# name :string not null
|
||||||
# start_time :datetime not null
|
# start_time :datetime not null
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# contest_id :integer not null
|
# contest_id :integer not null
|
||||||
|
# contestant_id :integer
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# index_offlines_on_contest_id (contest_id)
|
# index_offlines_on_contest_id (contest_id)
|
||||||
|
# index_offlines_on_contestant_id (contestant_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
# Foreign Keys
|
||||||
#
|
#
|
||||||
# contest_id (contest_id => contests.id)
|
# contest_id (contest_id => contests.id)
|
||||||
|
# contestant_id (contestant_id => contestants.id)
|
||||||
#
|
#
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :offline do
|
factory :offline do
|
||||||
|
|||||||
@@ -2,22 +2,25 @@
|
|||||||
#
|
#
|
||||||
# Table name: offlines
|
# Table name: offlines
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# completed :boolean
|
# completed :boolean
|
||||||
# end_time :datetime
|
# end_time :datetime
|
||||||
# name :string not null
|
# name :string not null
|
||||||
# start_time :datetime not null
|
# start_time :datetime not null
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# contest_id :integer not null
|
# contest_id :integer not null
|
||||||
|
# contestant_id :integer
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# index_offlines_on_contest_id (contest_id)
|
# index_offlines_on_contest_id (contest_id)
|
||||||
|
# index_offlines_on_contestant_id (contestant_id)
|
||||||
#
|
#
|
||||||
# Foreign Keys
|
# Foreign Keys
|
||||||
#
|
#
|
||||||
# contest_id (contest_id => contests.id)
|
# contest_id (contest_id => contests.id)
|
||||||
|
# contestant_id (contestant_id => contestants.id)
|
||||||
#
|
#
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user