Worlds Bets
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"editor.tabSize": 2
|
||||
}
|
||||
135
app/controllers/worlds_controller.rb
Normal file
135
app/controllers/worlds_controller.rb
Normal file
@@ -0,0 +1,135 @@
|
||||
class WorldsController < ApplicationController
|
||||
allow_unauthenticated_access
|
||||
|
||||
before_action :set_title
|
||||
before_action :set_fr_lang
|
||||
|
||||
def set_title
|
||||
@title = I18n.t("worlds.title")
|
||||
@nonav = true
|
||||
end
|
||||
|
||||
def set_fr_lang
|
||||
I18n.locale = "fr"
|
||||
end
|
||||
|
||||
def main
|
||||
authorize :world_bet
|
||||
|
||||
@world_bets_w = WorldBet.all.order(world_score: :desc)
|
||||
@world_bets_f = WorldBet.all.order(french_score: :desc)
|
||||
end
|
||||
|
||||
def about
|
||||
authorize :world_bet
|
||||
end
|
||||
|
||||
def collab
|
||||
authorize :world_bet
|
||||
|
||||
participant_ids = Set[]
|
||||
@world_bets = WorldBet.all.each do |b|
|
||||
b.bet.split(";", -1).first.split(",", -1).each do |participant_id|
|
||||
participant_ids.add(participant_id)
|
||||
end
|
||||
b.bet.split(";", -1).last.split(",", -1).each do |participant_id|
|
||||
participant_ids.add(participant_id)
|
||||
end
|
||||
end
|
||||
|
||||
@participants = WorldParticipant.includes([ :world_country ]).find(participant_ids.to_a).sort_by { |p| p.name }
|
||||
end
|
||||
|
||||
def view
|
||||
authorize :world_bet
|
||||
|
||||
@world_bet = WorldBet.find(params[:bet_id])
|
||||
@french_participants = WorldParticipant.includes([ :world_country ]).find(@world_bet.bet.split(";", -1).last.split(",", -1).map { |x| Integer(x) })
|
||||
@world_participants = WorldParticipant.includes([ :world_country ]).find(@world_bet.bet.split(";", -1).first.split(",", -1).map { |x| Integer(x) })
|
||||
end
|
||||
|
||||
def new
|
||||
authorize :world_bet
|
||||
|
||||
@world_bet = WorldBet.new
|
||||
@world_participants = WorldParticipant.includes([ :world_country ]).all.order(:name)
|
||||
france = WorldCountry.where(code: "FR").first
|
||||
@french_participants = WorldParticipant.includes([ :world_country ]).where(world_country: france).order(:name)
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :world_bet
|
||||
|
||||
|
||||
@world_bet = WorldBet.new(world_bet_params)
|
||||
@world_bet.score = 0
|
||||
@world_bet.french_score = 0
|
||||
@world_bet.world_score = 0
|
||||
all_params = params.require(:world_bet)
|
||||
|
||||
w_set = Set[]
|
||||
f_set = Set[]
|
||||
@w_array = []
|
||||
@f_array = []
|
||||
(1..10).each do |i|
|
||||
if all_params.key?("w_bet_#{i}")
|
||||
p_id = all_params["w_bet_#{i}"]
|
||||
w_set.add(p_id)
|
||||
@w_array.push(p_id)
|
||||
end
|
||||
if all_params.key?("f_bet_#{i}")
|
||||
p_id = all_params["f_bet_#{i}"]
|
||||
f_set.add(p_id)
|
||||
@f_array.push(p_id)
|
||||
end
|
||||
end
|
||||
@world_bet.serialize_bet(@w_array, @f_array)
|
||||
|
||||
if w_set.length != 10 || f_set.length != 10
|
||||
@world_bet.errors.add(:name, I18n.t("activerecord.errors.models.world_bet.attributes.bet.duplicate"))
|
||||
end
|
||||
|
||||
if w_set.length == 10 && f_set.length == 10 && @world_bet.save
|
||||
redirect_to "/wjpc_bets/main", notice: t("worlds.new.notice")
|
||||
else
|
||||
@world_participants = WorldParticipant.all.sort_by { |p| p.name }
|
||||
france = WorldCountry.where(code: "FR").first
|
||||
@french_participants = WorldParticipant.where(world_country: france).sort_by { |p| p.name }
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize :world_bet
|
||||
|
||||
@participant = WorldParticipant.find(params[:participant_id])
|
||||
if @participant.update(world_participant_params)
|
||||
participants_hash = {}
|
||||
WorldParticipant.all.each do |p|
|
||||
if p.score != nil
|
||||
participants_hash[p.id] = p.score
|
||||
end
|
||||
end
|
||||
WorldBet.all.each do |b|
|
||||
old_score = b.score
|
||||
b.compute_score(participants_hash)
|
||||
if b.score != old_score
|
||||
b.save
|
||||
end
|
||||
end
|
||||
redirect_back(fallback_location: root_path, notice: t("worlds.collab.notice"))
|
||||
else
|
||||
redirect_to "/wjpc_bets/collab", notice: t("worlds.collab.error")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def world_bet_params
|
||||
params.expect(world_bet: [ :name ])
|
||||
end
|
||||
|
||||
def world_participant_params
|
||||
params.expect(world_participant: [ :qualifier_result, :semifinal_result, :final_result ])
|
||||
end
|
||||
end
|
||||
2
app/helpers/worlds_helper.rb
Normal file
2
app/helpers/worlds_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module WorldsHelper
|
||||
end
|
||||
261
app/lib/flags.rb
Normal file
261
app/lib/flags.rb
Normal file
@@ -0,0 +1,261 @@
|
||||
module Flags
|
||||
FLAGS = {
|
||||
AD: "🇦🇩",
|
||||
AE: "🇦🇪",
|
||||
AF: "🇦🇫",
|
||||
AG: "🇦🇬",
|
||||
AI: "🇦🇮",
|
||||
AL: "🇦🇱",
|
||||
AM: "🇦🇲",
|
||||
AO: "🇦🇴",
|
||||
AQ: "🇦🇶",
|
||||
AR: "🇦🇷",
|
||||
AS: "🇦🇸",
|
||||
AT: "🇦🇹",
|
||||
AU: "🇦🇺",
|
||||
AW: "🇦🇼",
|
||||
AX: "🇦🇽",
|
||||
AZ: "🇦🇿",
|
||||
BA: "🇧🇦",
|
||||
BB: "🇧🇧",
|
||||
BD: "🇧🇩",
|
||||
BE: "🇧🇪",
|
||||
BF: "🇧🇫",
|
||||
BG: "🇧🇬",
|
||||
BH: "🇧🇭",
|
||||
BI: "🇧🇮",
|
||||
BJ: "🇧🇯",
|
||||
BL: "🇧🇱",
|
||||
BM: "🇧🇲",
|
||||
BN: "🇧🇳",
|
||||
BO: "🇧🇴",
|
||||
BQ: "🇧🇶",
|
||||
BR: "🇧🇷",
|
||||
BS: "🇧🇸",
|
||||
BT: "🇧🇹",
|
||||
BV: "🇧🇻",
|
||||
BW: "🇧🇼",
|
||||
BY: "🇧🇾",
|
||||
BZ: "🇧🇿",
|
||||
CA: "🇨🇦",
|
||||
CC: "🇨🇨",
|
||||
CD: "🇨🇩",
|
||||
CF: "🇨🇫",
|
||||
CG: "🇨🇬",
|
||||
CH: "🇨🇭",
|
||||
CI: "🇨🇮",
|
||||
CK: "🇨🇰",
|
||||
CL: "🇨🇱",
|
||||
CM: "🇨🇲",
|
||||
CN: "🇨🇳",
|
||||
CO: "🇨🇴",
|
||||
CR: "🇨🇷",
|
||||
CU: "🇨🇺",
|
||||
CV: "🇨🇻",
|
||||
CW: "🇨🇼",
|
||||
CX: "🇨🇽",
|
||||
CY: "🇨🇾",
|
||||
CZ: "🇨🇿",
|
||||
DE: "🇩🇪",
|
||||
DJ: "🇩🇯",
|
||||
DK: "🇩🇰",
|
||||
DM: "🇩🇲",
|
||||
DO: "🇩🇴",
|
||||
DZ: "🇩🇿",
|
||||
EC: "🇪🇨",
|
||||
EE: "🇪🇪",
|
||||
EG: "🇪🇬",
|
||||
EH: "🇪🇭",
|
||||
ER: "🇪🇷",
|
||||
ES: "🇪🇸",
|
||||
ET: "🇪🇹",
|
||||
FI: "🇫🇮",
|
||||
FJ: "🇫🇯",
|
||||
FK: "🇫🇰",
|
||||
FM: "🇫🇲",
|
||||
FO: "🇫🇴",
|
||||
FR: "🇫🇷",
|
||||
GA: "🇬🇦",
|
||||
GB: "🇬🇧",
|
||||
GD: "🇬🇩",
|
||||
GE: "🇬🇪",
|
||||
GF: "🇬🇫",
|
||||
GG: "🇬🇬",
|
||||
GH: "🇬🇭",
|
||||
GI: "🇬🇮",
|
||||
GL: "🇬🇱",
|
||||
GM: "🇬🇲",
|
||||
GN: "🇬🇳",
|
||||
GP: "🇬🇵",
|
||||
GQ: "🇬🇶",
|
||||
GR: "🇬🇷",
|
||||
GS: "🇬🇸",
|
||||
GT: "🇬🇹",
|
||||
GU: "🇬🇺",
|
||||
GW: "🇬🇼",
|
||||
GY: "🇬🇾",
|
||||
HK: "🇭🇰",
|
||||
HM: "🇭🇲",
|
||||
HN: "🇭🇳",
|
||||
HR: "🇭🇷",
|
||||
HT: "🇭🇹",
|
||||
HU: "🇭🇺",
|
||||
ID: "🇮🇩",
|
||||
IE: "🇮🇪",
|
||||
IL: "🇮🇱",
|
||||
IM: "🇮🇲",
|
||||
IN: "🇮🇳",
|
||||
IO: "🇮🇴",
|
||||
IQ: "🇮🇶",
|
||||
IR: "🇮🇷",
|
||||
IS: "🇮🇸",
|
||||
IT: "🇮🇹",
|
||||
JE: "🇯🇪",
|
||||
JM: "🇯🇲",
|
||||
JO: "🇯🇴",
|
||||
JP: "🇯🇵",
|
||||
KE: "🇰🇪",
|
||||
KG: "🇰🇬",
|
||||
KH: "🇰🇭",
|
||||
KI: "🇰🇮",
|
||||
KM: "🇰🇲",
|
||||
KN: "🇰🇳",
|
||||
KP: "🇰🇵",
|
||||
KR: "🇰🇷",
|
||||
KW: "🇰🇼",
|
||||
KY: "🇰🇾",
|
||||
KZ: "🇰🇿",
|
||||
LA: "🇱🇦",
|
||||
LB: "🇱🇧",
|
||||
LC: "🇱🇨",
|
||||
LI: "🇱🇮",
|
||||
LK: "🇱🇰",
|
||||
LR: "🇱🇷",
|
||||
LS: "🇱🇸",
|
||||
LT: "🇱🇹",
|
||||
LU: "🇱🇺",
|
||||
LV: "🇱🇻",
|
||||
LY: "🇱🇾",
|
||||
MA: "🇲🇦",
|
||||
MC: "🇲🇨",
|
||||
MD: "🇲🇩",
|
||||
ME: "🇲🇪",
|
||||
MF: "🇲🇫",
|
||||
MG: "🇲🇬",
|
||||
MH: "🇲🇭",
|
||||
MK: "🇲🇰",
|
||||
ML: "🇲🇱",
|
||||
MM: "🇲🇲",
|
||||
MN: "🇲🇳",
|
||||
MO: "🇲🇴",
|
||||
MP: "🇲🇵",
|
||||
MQ: "🇲🇶",
|
||||
MR: "🇲🇷",
|
||||
MS: "🇲🇸",
|
||||
MT: "🇲🇹",
|
||||
MU: "🇲🇺",
|
||||
MV: "🇲🇻",
|
||||
MW: "🇲🇼",
|
||||
MX: "🇲🇽",
|
||||
MY: "🇲🇾",
|
||||
MZ: "🇲🇿",
|
||||
NA: "🇳🇦",
|
||||
NC: "🇳🇨",
|
||||
NE: "🇳🇪",
|
||||
NF: "🇳🇫",
|
||||
NG: "🇳🇬",
|
||||
NI: "🇳🇮",
|
||||
NL: "🇳🇱",
|
||||
NO: "🇳🇴",
|
||||
NP: "🇳🇵",
|
||||
NR: "🇳🇷",
|
||||
NU: "🇳🇺",
|
||||
NZ: "🇳🇿",
|
||||
OM: "🇴🇲",
|
||||
PA: "🇵🇦",
|
||||
PE: "🇵🇪",
|
||||
PF: "🇵🇫",
|
||||
PG: "🇵🇬",
|
||||
PH: "🇵🇭",
|
||||
PK: "🇵🇰",
|
||||
PL: "🇵🇱",
|
||||
PM: "🇵🇲",
|
||||
PN: "🇵🇳",
|
||||
PR: "🇵🇷",
|
||||
PS: "🇵🇸",
|
||||
PT: "🇵🇹",
|
||||
PW: "🇵🇼",
|
||||
PY: "🇵🇾",
|
||||
QA: "🇶🇦",
|
||||
RE: "🇷🇪",
|
||||
RO: "🇷🇴",
|
||||
RS: "🇷🇸",
|
||||
RU: "🇷🇺",
|
||||
RW: "🇷🇼",
|
||||
SA: "🇸🇦",
|
||||
SB: "🇸🇧",
|
||||
SC: "🇸🇨",
|
||||
SD: "🇸🇩",
|
||||
SE: "🇸🇪",
|
||||
SG: "🇸🇬",
|
||||
SH: "🇸🇭",
|
||||
SI: "🇸🇮",
|
||||
SJ: "🇸🇯",
|
||||
SK: "🇸🇰",
|
||||
SL: "🇸🇱",
|
||||
SM: "🇸🇲",
|
||||
SN: "🇸🇳",
|
||||
SO: "🇸🇴",
|
||||
SR: "🇸🇷",
|
||||
SS: "🇸🇸",
|
||||
ST: "🇸🇹",
|
||||
SV: "🇸🇻",
|
||||
SX: "🇸🇽",
|
||||
SY: "🇸🇾",
|
||||
SZ: "🇸🇿",
|
||||
TC: "🇹🇨",
|
||||
TD: "🇹🇩",
|
||||
TF: "🇹🇫",
|
||||
TG: "🇹🇬",
|
||||
TH: "🇹🇭",
|
||||
TJ: "🇹🇯",
|
||||
TK: "🇹🇰",
|
||||
TL: "🇹🇱",
|
||||
TM: "🇹🇲",
|
||||
TN: "🇹🇳",
|
||||
TO: "🇹🇴",
|
||||
TR: "🇹🇷",
|
||||
TT: "🇹🇹",
|
||||
TV: "🇹🇻",
|
||||
TW: "🇹🇼",
|
||||
TZ: "🇹🇿",
|
||||
UA: "🇺🇦",
|
||||
UG: "🇺🇬",
|
||||
UM: "🇺🇲",
|
||||
US: "🇺🇸",
|
||||
UY: "🇺🇾",
|
||||
UZ: "🇺🇿",
|
||||
VA: "🇻🇦",
|
||||
VC: "🇻🇨",
|
||||
VE: "🇻🇪",
|
||||
VG: "🇻🇬",
|
||||
VI: "🇻🇮",
|
||||
VN: "🇻🇳",
|
||||
VU: "🇻🇺",
|
||||
WF: "🇼🇫",
|
||||
WS: "🇼🇸",
|
||||
YE: "🇾🇪",
|
||||
YT: "🇾🇹",
|
||||
ZA: "🇿🇦",
|
||||
ZM: "🇿🇲",
|
||||
ZW: "🇿🇼"
|
||||
}
|
||||
|
||||
def self.get_flag(code)
|
||||
sym_code = code.to_sym
|
||||
if FLAGS.has_key?(sym_code)
|
||||
return FLAGS[sym_code]
|
||||
end
|
||||
""
|
||||
end
|
||||
end
|
||||
93
app/models/world_bet.rb
Normal file
93
app/models/world_bet.rb
Normal file
@@ -0,0 +1,93 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_bets
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# bet :string
|
||||
# french_score :integer
|
||||
# name :string
|
||||
# score :integer
|
||||
# world_score :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class WorldBet < ApplicationRecord
|
||||
validates :name, presence: true, uniqueness: true
|
||||
validates :score, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
||||
validates :french_score, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
||||
validates :world_score, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
||||
|
||||
@@multiplier_array = [ 20, 15, 12, 10, 8, 6, 4, 3, 2, 1 ]
|
||||
@@points_array = [ 100, 70, 50, 40, 30, 26, 23, 20, 17, 15 ]
|
||||
|
||||
def self.multiplier(i)
|
||||
if i < 0 or i > 9
|
||||
return 0
|
||||
end
|
||||
@@multiplier_array[i]
|
||||
end
|
||||
|
||||
def self.points(i)
|
||||
if !i || i < 1
|
||||
return 0
|
||||
end
|
||||
if i <= 10
|
||||
return @@points_array[i - 1]
|
||||
end
|
||||
if i <= 20
|
||||
return 12
|
||||
end
|
||||
if i <= 30
|
||||
return 10
|
||||
end
|
||||
if i <= 40
|
||||
return 8
|
||||
end
|
||||
if i <= 50
|
||||
return 7
|
||||
end
|
||||
if i <= 60
|
||||
return 6
|
||||
end
|
||||
if i <= 70
|
||||
return 5
|
||||
end
|
||||
if i <= 80
|
||||
return 4
|
||||
end
|
||||
if i <= 90
|
||||
return 3
|
||||
end
|
||||
if i <= 100
|
||||
return 2
|
||||
end
|
||||
if i <= 150
|
||||
return 1
|
||||
end
|
||||
0
|
||||
end
|
||||
|
||||
def serialize_bet(w, f)
|
||||
self.bet = "#{w.join(',')};#{f.join(',')}"
|
||||
end
|
||||
|
||||
def compute_score(participant_scores)
|
||||
self.score = 0
|
||||
self.french_score = 0
|
||||
self.world_score = 0
|
||||
w = self.bet.split(";", -1).first.split(",", -1)
|
||||
w.each_with_index do |participant_id, i|
|
||||
if participant_scores.has_key?(Integer(participant_id))
|
||||
self.score += participant_scores[Integer(participant_id)] * WorldBet.multiplier(i)
|
||||
self.world_score += participant_scores[Integer(participant_id)] * WorldBet.multiplier(i)
|
||||
end
|
||||
end
|
||||
f = self.bet.split(";", -1).last.split(",", -1)
|
||||
f.each_with_index do |participant_id, i|
|
||||
if participant_scores.has_key?(Integer(participant_id))
|
||||
self.score += participant_scores[Integer(participant_id)] * WorldBet.multiplier(i)
|
||||
self.french_score += participant_scores[Integer(participant_id)] * WorldBet.multiplier(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
app/models/world_country.rb
Normal file
24
app/models/world_country.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_countries
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# code :string not null
|
||||
# name :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class WorldCountry < ApplicationRecord
|
||||
has_many :world_participants
|
||||
|
||||
validates :code, presence: true, uniqueness: true
|
||||
validates :name, presence: true, uniqueness: true
|
||||
|
||||
def self.add_countries(str)
|
||||
str.split(";", -1).each do |c|
|
||||
name = c.split(",", -1).first
|
||||
code = c.split(",", -1).last
|
||||
WorldCountry.create(name: name, code: code)
|
||||
end
|
||||
end
|
||||
end
|
||||
56
app/models/world_participant.rb
Normal file
56
app/models/world_participant.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_participants
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# final_result :integer
|
||||
# name :string not null
|
||||
# qualifier_result :integer
|
||||
# round :string not null
|
||||
# score :integer
|
||||
# semifinal_result :integer
|
||||
# username :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# world_country_id :integer not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_world_participants_on_world_country_id (world_country_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# world_country_id (world_country_id => world_countries.id)
|
||||
#
|
||||
class WorldParticipant < ApplicationRecord
|
||||
belongs_to :world_country
|
||||
|
||||
validates :name, presence: true
|
||||
validates :username, presence: true
|
||||
validates :round, inclusion: { in: %w[a b c d], message: "%{value} is not a valid round" }
|
||||
validates :qualifier_result, numericality: { greater_than_or_equal_to: 1 }, if: -> { qualifier_result.present? }
|
||||
validates :semifinal_result, numericality: { greater_than_or_equal_to: 1 }, if: -> { semifinal_result.present? }
|
||||
validates :final_result, numericality: { greater_than_or_equal_to: 1 }, if: -> { final_result.present? }
|
||||
|
||||
before_save :compute_score
|
||||
|
||||
def compute_score
|
||||
self.score = WorldBet.points(qualifier_result) + WorldBet.points(semifinal_result) * 2 + WorldBet.points(final_result) * 4
|
||||
end
|
||||
|
||||
def self.add_participants(str)
|
||||
str.split(";", -1).each do |c|
|
||||
cs = c.split(",", -1)
|
||||
if cs.length >= 4
|
||||
name = cs.first
|
||||
username = cs[1]
|
||||
country_code = cs[2]
|
||||
round = cs.last
|
||||
country = WorldCountry.where(code: country_code).first
|
||||
if country
|
||||
WorldParticipant.create(name: name, username: username, world_country: country, round: round)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
29
app/policies/world_bet_policy.rb
Normal file
29
app/policies/world_bet_policy.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class WorldBetPolicy < ApplicationPolicy
|
||||
def main?
|
||||
true
|
||||
end
|
||||
|
||||
def about?
|
||||
true
|
||||
end
|
||||
|
||||
def new?
|
||||
true
|
||||
end
|
||||
|
||||
def create?
|
||||
true
|
||||
end
|
||||
|
||||
def collab?
|
||||
true
|
||||
end
|
||||
|
||||
def update?
|
||||
true
|
||||
end
|
||||
|
||||
def view?
|
||||
true
|
||||
end
|
||||
end
|
||||
15
app/views/application/_worlds_nav.html.slim
Normal file
15
app/views/application/_worlds_nav.html.slim
Normal file
@@ -0,0 +1,15 @@
|
||||
.row
|
||||
.col
|
||||
ul.nav.nav-tabs.mb-4
|
||||
li.nav-item
|
||||
a.nav-link class=active_page("/wjpc_bets/main") href="/wjpc_bets/main"
|
||||
= t("worlds.main.tab")
|
||||
li.nav-item
|
||||
a.nav-link class=active_page("/wjpc_bets/about") href="/wjpc_bets/about"
|
||||
= t("worlds.about.tab")
|
||||
li.nav-item
|
||||
a.nav-link class=active_page("/wjpc_bets/collaborative_filling") href="/wjpc_bets/collaborative_filling"
|
||||
= t("worlds.collab.tab")
|
||||
li.nav-item
|
||||
a.nav-link class=active_page("/wjpc_bets/new") href="/wjpc_bets/new"
|
||||
= t("worlds.new.tab")
|
||||
83
app/views/worlds/about.html.slim
Normal file
83
app/views/worlds/about.html.slim
Normal file
@@ -0,0 +1,83 @@
|
||||
= render "worlds_nav"
|
||||
|
||||
.alert.alert-warning role="alert"
|
||||
= t("worlds.about.one_bet_message")
|
||||
|
||||
.alert.alert-primary role="alert"
|
||||
= t("worlds.about.details_message")
|
||||
.mt-3
|
||||
= t("worlds.about.two_rankings_message")
|
||||
.mt-3
|
||||
= t("worlds.about.collaborative_filling_message")
|
||||
|
||||
.row.mt-4
|
||||
.col
|
||||
table.table.table-striped.table-hover
|
||||
thead
|
||||
tr
|
||||
th = t("worlds.about.ranking")
|
||||
th = t("worlds.about.qualifier_round")
|
||||
th = t("worlds.about.semifinal_round")
|
||||
th = t("worlds.about.finals_round")
|
||||
tbody
|
||||
- (1..10).each do |i|
|
||||
tr
|
||||
td #{i}
|
||||
td #{WorldBet.points(i)}
|
||||
td #{WorldBet.points(i) * 2}
|
||||
td #{WorldBet.points(i) * 4}
|
||||
tr
|
||||
td 11-20
|
||||
td #{WorldBet.points(20)}
|
||||
td #{WorldBet.points(20) * 2}
|
||||
td #{WorldBet.points(20) * 4}
|
||||
tr
|
||||
td 21-30
|
||||
td #{WorldBet.points(30)}
|
||||
td #{WorldBet.points(30) * 2}
|
||||
td #{WorldBet.points(30) * 4}
|
||||
tr
|
||||
td 31-40
|
||||
td #{WorldBet.points(40)}
|
||||
td #{WorldBet.points(40) * 2}
|
||||
td #{WorldBet.points(40) * 4}
|
||||
tr
|
||||
td 41-50
|
||||
td #{WorldBet.points(50)}
|
||||
td #{WorldBet.points(50) * 2}
|
||||
td #{WorldBet.points(50) * 4}
|
||||
tr
|
||||
td 51-60
|
||||
td #{WorldBet.points(60)}
|
||||
td #{WorldBet.points(60) * 2}
|
||||
td #{WorldBet.points(60) * 4}
|
||||
tr
|
||||
td 61-70
|
||||
td #{WorldBet.points(70)}
|
||||
td #{WorldBet.points(70) * 2}
|
||||
td #{WorldBet.points(70) * 4}
|
||||
tr
|
||||
td 71-80
|
||||
td #{WorldBet.points(80)}
|
||||
td #{WorldBet.points(80) * 2}
|
||||
td #{WorldBet.points(80) * 4}
|
||||
tr
|
||||
td 81-90
|
||||
td #{WorldBet.points(90)}
|
||||
td #{WorldBet.points(90) * 2}
|
||||
td #{WorldBet.points(90) * 4}
|
||||
tr
|
||||
td 91-100
|
||||
td #{WorldBet.points(100)}
|
||||
td #{WorldBet.points(100) * 2}
|
||||
td #{WorldBet.points(100) * 4}
|
||||
tr
|
||||
td 101-150
|
||||
td #{WorldBet.points(150)}
|
||||
td #{WorldBet.points(150) * 2}
|
||||
td #{WorldBet.points(150) * 4}
|
||||
tr
|
||||
td 151+
|
||||
td #{WorldBet.points(151)}
|
||||
td #{WorldBet.points(151) * 2}
|
||||
td #{WorldBet.points(151) * 4}
|
||||
131
app/views/worlds/collab.html.slim
Normal file
131
app/views/worlds/collab.html.slim
Normal file
@@ -0,0 +1,131 @@
|
||||
= render "worlds_nav"
|
||||
|
||||
.alert.alert-primary role="alert"
|
||||
= t("worlds.collab.details_message")
|
||||
.mt-3
|
||||
= t("worlds.collab.error_message")
|
||||
|
||||
.alert.alert-warning role="alert"
|
||||
= t("worlds.collab.rank_message")
|
||||
|
||||
h4.mt-4 Round A
|
||||
|
||||
- @participants.each do |p|
|
||||
- if p.round == 'a'
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :qualifier_result, value: p.qualifier_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.qualifier_result)}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
javascript:
|
||||
function updateScrollPos() {
|
||||
wsy = window.scrollY;
|
||||
setTimeout(() => window.scrollTo(0, wsy), 25);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 50);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 75);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 100);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 125);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 150);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 175);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 200);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 225);
|
||||
setTimeout(() => window.scrollTo(0, wsy), 250);
|
||||
}
|
||||
|
||||
|
||||
h4.mt-5 Round B
|
||||
|
||||
- @participants.each do |p|
|
||||
- if p.round == 'b'
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :qualifier_result, value: p.qualifier_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.qualifier_result)}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
h4.mt-5 Round C
|
||||
|
||||
- @participants.each do |p|
|
||||
- if p.round == 'c'
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :qualifier_result, value: p.qualifier_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.qualifier_result)}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
h4.mt-5 Round D
|
||||
|
||||
- @participants.each do |p|
|
||||
- if p.round == 'd'
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :qualifier_result, value: p.qualifier_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.qualifier_result)}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
h4.mt-5 = "#{t("worlds.collab.semifinal")} 1"
|
||||
|
||||
- @participants.each do |p|
|
||||
- if p.round == 'a' || p.round == 'b'
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :semifinal_result, value: p.semifinal_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.semifinal_result) * 2}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
h4.mt-5 = "#{t("worlds.collab.semifinal")} 2"
|
||||
|
||||
- @participants.each do |p|
|
||||
- if p.round == 'c' || p.round == 'd'
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :semifinal_result, value: p.semifinal_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.semifinal_result) * 2}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
h4.mt-5 = "#{t("worlds.collab.final")}"
|
||||
|
||||
- @participants.each do |p|
|
||||
.row.mt-3
|
||||
.col
|
||||
= form_with model: WorldParticipant, url: "/wjpc_bets/update/#{p.id}", method: :patch do |form|
|
||||
.input-group
|
||||
.input-group-text style="width: 350px;" #{Flags.get_flag(p.world_country.code) + " " + p.name}
|
||||
.input-group-text = t("worlds.main.rank")
|
||||
= form.text_field :final_result, value: p.final_result, autocomplete: "off", class: "form-control", style: "color: orange; max-width: 60px;"
|
||||
.input-group-text = t("worlds.main.points")
|
||||
.input-group-text style="color: green; width: 60px;" #{WorldBet.points(p.final_result) * 4}
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary", onclick: "updateScrollPos()"
|
||||
|
||||
.mb-5
|
||||
52
app/views/worlds/main.html.slim
Normal file
52
app/views/worlds/main.html.slim
Normal file
@@ -0,0 +1,52 @@
|
||||
= render "worlds_nav"
|
||||
|
||||
.row.mt-3
|
||||
.col-6
|
||||
h4 = t("worlds.main.world_participants")
|
||||
table.table.table-striped.table-hover
|
||||
thead
|
||||
tr
|
||||
th = t("worlds.main.rank")
|
||||
th = t("worlds.main.name")
|
||||
th = t("worlds.main.score")
|
||||
tbody
|
||||
- @world_bets_w.each_with_index do |b, i|
|
||||
tr
|
||||
- if i == 0
|
||||
td 🥇
|
||||
- elsif i == 1
|
||||
td 🥈
|
||||
- elsif i == 2
|
||||
td 🥉
|
||||
- else
|
||||
td #{i + 1}
|
||||
td #{b.name}
|
||||
td #{b.world_score}
|
||||
td
|
||||
a.btn.btn-sm.btn-secondary href="/wjpc_bets/view/#{b.id}"
|
||||
= t("worlds.main.view_bet")
|
||||
|
||||
.col-6
|
||||
h4 = t("worlds.main.french_participants")
|
||||
table.table.table-striped.table-hover
|
||||
thead
|
||||
tr
|
||||
th = t("worlds.main.rank")
|
||||
th = t("worlds.main.name")
|
||||
th = t("worlds.main.score")
|
||||
tbody
|
||||
- @world_bets_f.each_with_index do |b, i|
|
||||
tr
|
||||
- if i == 0
|
||||
td 🥇
|
||||
- elsif i == 1
|
||||
td 🥈
|
||||
- elsif i == 2
|
||||
td 🥉
|
||||
- else
|
||||
td #{i + 1}
|
||||
td #{b.name}
|
||||
td #{b.french_score}
|
||||
td
|
||||
a.btn.btn-sm.btn-secondary href="/wjpc_bets/view/#{b.id}"
|
||||
= t("worlds.main.view_bet")
|
||||
45
app/views/worlds/new.html.slim
Normal file
45
app/views/worlds/new.html.slim
Normal file
@@ -0,0 +1,45 @@
|
||||
= render "worlds_nav"
|
||||
|
||||
= form_with model: @world_bet, url: "/wjpc_bets/new", method: :post do |form|
|
||||
.alert.alert-primary role="alert"
|
||||
= t("worlds.new.message")
|
||||
|
||||
.row.mt-4
|
||||
.col
|
||||
.form-floating
|
||||
= form.text_field :name, autocomplete: "off", class: "form-control"
|
||||
= form.label :name, class: "required"
|
||||
|
||||
.row.mt-4
|
||||
.col
|
||||
h4 = t("worlds.new.world_section")
|
||||
|
||||
- (1..10).each do |i|
|
||||
.row.mt-3
|
||||
.col
|
||||
.input-group
|
||||
.input-group-text ##{i} <i class="ms-2" style="color: cadetblue;">(x#{WorldBet.multiplier(i - 1)})</i>
|
||||
= form.select "w_bet_#{i}", @world_participants.map { |p| [Flags.get_flag(p.world_country.code) + " " + p.name, p.id] }, {}, class: "form-select"
|
||||
|
||||
.row.mt-4
|
||||
.col
|
||||
h4 = t("worlds.new.french_section")
|
||||
|
||||
- (1..10).each do |i|
|
||||
.row.mt-3
|
||||
.col
|
||||
.input-group
|
||||
.input-group-text ##{i} <i class="ms-2" style="color: cadetblue;">(x#{WorldBet.multiplier(i - 1)})</i>
|
||||
= form.select "f_bet_#{i}", @french_participants.map { |p| [Flags.get_flag(p.world_country.code) + " " + p.name, p.id] }, {}, class: "form-select"
|
||||
|
||||
- if @w_array && @f_array
|
||||
- (1..10).each do |i|
|
||||
javascript:
|
||||
el = document.querySelector('select[name="world_bet[w_bet_#{i}]"]');
|
||||
el.value = "#{@w_array[i - 1]}"
|
||||
el = document.querySelector('select[name="world_bet[f_bet_#{i}]"]');
|
||||
el.value = "#{@f_array[i - 1]}"
|
||||
|
||||
.row.mt-4.mb-5
|
||||
.col
|
||||
= form.submit t("helpers.buttons.validate"), class: "btn btn-primary"
|
||||
49
app/views/worlds/view.html.slim
Normal file
49
app/views/worlds/view.html.slim
Normal file
@@ -0,0 +1,49 @@
|
||||
= render "worlds_nav"
|
||||
|
||||
h4.mt-3 = t("worlds.view.subtitle", name: @world_bet.name).html_safe
|
||||
|
||||
.row.mt-3
|
||||
.col
|
||||
h5 = t("worlds.view.world_participants")
|
||||
table.table.table-striped.table-hover
|
||||
thead
|
||||
tr
|
||||
th = t("worlds.view.participant")
|
||||
th = t("worlds.view.multiplier")
|
||||
th Q
|
||||
th S
|
||||
th F
|
||||
th = t("worlds.view.total")
|
||||
tbody
|
||||
- @world_participants.each_with_index do |p, i|
|
||||
tr
|
||||
td = Flags.get_flag(p.world_country.code) + " " + p.name
|
||||
td style="color: cadetblue;"
|
||||
= "x#{WorldBet.multiplier(i)}"
|
||||
td = "<span style='color: orange'>#{p.qualifier_result || "?"}</span> > <span style='color: green'>#{WorldBet.points(p.qualifier_result)}p</span>".html_safe
|
||||
td = "<span style='color: orange'>#{p.semifinal_result || "?"}</span> > <span style='color: green'>#{WorldBet.points(p.semifinal_result) * 2}p</span>".html_safe
|
||||
td = "<span style='color: orange'>#{p.final_result || "?"}</span> > <span style='color: green'>#{WorldBet.points(p.final_result) * 4}p</span>".html_safe
|
||||
td = "<span style='color: green'>#{p.score || 0}</span> x <span style='color: cadetblue'>#{WorldBet.multiplier(i)}</span> = <span style='color: green'>#{(p.score || 0) * WorldBet.multiplier(i)}p</span>".html_safe
|
||||
|
||||
.row.mt-3
|
||||
.col
|
||||
h5 = t("worlds.view.french_participants")
|
||||
table.table.table-striped.table-hover
|
||||
thead
|
||||
tr
|
||||
th = t("worlds.view.participant")
|
||||
th = t("worlds.view.multiplier")
|
||||
th Q
|
||||
th S
|
||||
th F
|
||||
th = t("worlds.view.total")
|
||||
tbody
|
||||
- @french_participants.each_with_index do |p, i|
|
||||
tr
|
||||
td = Flags.get_flag(p.world_country.code) + " " + p.name
|
||||
td style="color: cadetblue;"
|
||||
= "x#{WorldBet.multiplier(i)}"
|
||||
td = "<span style='color: orange'>#{p.qualifier_result || "?"}</span> > <span style='color: green'>#{WorldBet.points(p.qualifier_result)}p</span>".html_safe
|
||||
td = "<span style='color: orange'>#{p.semifinal_result || "?"}</span> > <span style='color: green'>#{WorldBet.points(p.semifinal_result) * 2}p</span>".html_safe
|
||||
td = "<span style='color: orange'>#{p.final_result || "?"}</span> > <span style='color: green'>#{WorldBet.points(p.final_result) * 4}p</span>".html_safe
|
||||
td = "<span style='color: green'>#{p.score || 0}</span> x <span style='color: cadetblue'>#{WorldBet.multiplier(i)}</span> = <span style='color: green'>#{(p.score || 0) * WorldBet.multiplier(i)}p</span>".html_safe
|
||||
@@ -113,6 +113,8 @@ en:
|
||||
email_address: Email address
|
||||
lang: Language
|
||||
password: New password
|
||||
world_bet:
|
||||
name: Name
|
||||
errors:
|
||||
models:
|
||||
completion:
|
||||
@@ -182,6 +184,13 @@ en:
|
||||
taken: This username is already taken
|
||||
password:
|
||||
blank: Your password cannot be empty
|
||||
world_bet:
|
||||
attributes:
|
||||
bet:
|
||||
duplicate: You can't select a participant twice in either of the two selection
|
||||
name:
|
||||
blank: You must provide a name
|
||||
taken: This name is already taken
|
||||
categories:
|
||||
destroy:
|
||||
notice: Category deleted
|
||||
@@ -420,3 +429,47 @@ en:
|
||||
new:
|
||||
notice: User created
|
||||
title: "New user"
|
||||
worlds:
|
||||
about:
|
||||
collaborative_filling_message: The ranking is updated collaboratively, see the dedicated tab for more details.
|
||||
details_message: To make a bet you'll have to select some contestants (see the dedicated tab for more details on that, and multipliers). You'll score points when they do well in the competition, the table below gives the amount of points you get depending on their ranking on each round, from qualifiers to the finals. This however only accounts for the solo category.
|
||||
final_round: Finals
|
||||
one_bet_message: Only one bet is allowed per person, please do not overflow the system with bets.
|
||||
points: Points
|
||||
qualifier_round: Qualifier round
|
||||
ranking: Ranking
|
||||
semifinal_round: Semifinals
|
||||
tab: Rules
|
||||
two_rankings_message: There are two rankings, one for the bet over all participants, and one for the bet over French participants.
|
||||
collab:
|
||||
details_message: Here you will all be able to collaboratively keep up-to-date the ranks of the participants that were selectec by bets. Anyone is able to make any update here, I trust you to do it with care, not cheating, and correcting errors if you see any. I'm doing it this way, so you don't have to wait for me to have the time to update everything :)
|
||||
error: An error occured, the rank must be a numerical value in the range [1, 250]
|
||||
error_message: If a participant did not qualify, do not fill their ranks for the subsequent rounds. If a rank was filled for them by mistake, please change it to any value above 150 so its score remains 0.
|
||||
final: Final
|
||||
notice: Participant rank updated
|
||||
rank_message: Below should be indicated the *rank* reached by each participant on each round, not the points. Points are automatically calculated.
|
||||
semifinal: Semifinal
|
||||
tab: Collaborative filling
|
||||
main:
|
||||
french_participants: French participants
|
||||
name: Name
|
||||
points: Points
|
||||
rank: Rank
|
||||
score: Score
|
||||
tab: Rankings
|
||||
view_bet: View bet
|
||||
world_participants: All participants
|
||||
new:
|
||||
french_section: Bet over French participants
|
||||
message: To make a bet, you have to provide two ordered lists of 10 participants, one among all participants, and the other one only among French participants. The order matters! A score multiplier will be applied to each selected contestant (in parenthesis below). You can't select a participant twice on a list, but of course you can totally put a French contestant in both lists ;)
|
||||
notice: The bet has been made!
|
||||
tab: Make a bet!
|
||||
world_section: Bet over all participants
|
||||
title: WJPC bets
|
||||
view:
|
||||
french_participants: On French participants
|
||||
multiplier: Multiplier
|
||||
participant: Participant
|
||||
subtitle: "<b>%{name}</b>'s bet"
|
||||
total: Total
|
||||
world_participants: On all participants
|
||||
|
||||
@@ -84,6 +84,8 @@ fr:
|
||||
email_address: Adresse email
|
||||
lang: Langue de l'interface
|
||||
password: Nouveau mot de passe
|
||||
world_bet:
|
||||
name: Nom
|
||||
errors:
|
||||
models:
|
||||
completion:
|
||||
@@ -153,6 +155,14 @@ fr:
|
||||
taken: Ce nom d'utilisateur.ice est déjà utilisé
|
||||
password:
|
||||
blank: Le mot de passe ne peut pas être vide
|
||||
world_bet:
|
||||
attributes:
|
||||
bet:
|
||||
duplicate:
|
||||
Il n'est pas possible de choisir un.e participant.e plusieurs fois dans une des deux listes
|
||||
name:
|
||||
blank: Le nom est obligatoire
|
||||
taken: Ce nom est déjà pris
|
||||
categories:
|
||||
destroy:
|
||||
notice: Catégorie supprimée
|
||||
@@ -391,3 +401,48 @@ fr:
|
||||
new:
|
||||
notice: Utilisateur.ice ajouté.e
|
||||
title: "Nouveau.elle utilisateur.ice"
|
||||
worlds:
|
||||
about:
|
||||
collaborative_filling_message: Les résultats des participant.e.s sont mis à jour de manière collaborative, plus d'infos dans l'onglet dédié.
|
||||
details_message: Pour faire un pari, tu devras choisir plusieurs participant.e.s (plus d'infos sur comment ça marche et sur les facteurs multiplicatifs dans l'onglet dédié). Tu marqueras des points en fonction de comment iels se classent dans chaque round, depuis les qualifs jusqu'à la finale (catégorie solo uniquement). La table ci-dessous donne la répartition des points en fonction des classements.
|
||||
final_round: Finale
|
||||
one_bet_message: Un seul pari par personne, ne surchargez pas le système svp.
|
||||
points: Points
|
||||
qualifier_round: Qualifications
|
||||
ranking: Classement
|
||||
semifinal_round: Demi-finales
|
||||
tab: Règles
|
||||
two_rankings_message: "Il y a deux classements : un sur les paris parmi l'ensemble des participant.e.s, et l'autres sur les paris sur les français.e.s."
|
||||
collab:
|
||||
details_message: Ici est l'endroit pour mettre librement et collaborativement à jour les résultats des participant.e.s sélectionné.e.s dans les paris. Je mets cet espace à disposition pour permettre un remplissage plus rapide sans avoir besoin d'attendre que j'ai le temps de tout remplir moi-même. Je vous fais confiance pour faire ça avec soin, sans tricher, et en corrigeant des erreurs si vous en trouvez :)
|
||||
error: "Une erreur est survenue : vérifie que tu as bien rentré un rang dans l'intervalle [1, 250]"
|
||||
error_message: Si une participant.e ne se qualifie pas lors d'un round, pas besoin alors de remplir son rang pour les rounds qui suivent. Si un rang a été rempli par erreur, changez-le pour n'importe quel rang au-dessus de 150 histoire que ça revienne à un score de 0.
|
||||
final: Finale
|
||||
notice: "Le rang de cet.te participant.e a été mis à jour"
|
||||
rank_message: Il s'agit ici d'indiquer les *classements* obtenus par les participant.e.s lors des différents rounds. Les points seront ensuite calculés automatiquement.
|
||||
semifinal: Semifinal
|
||||
tab: Remplisage collaboratif
|
||||
main:
|
||||
french_participants: Sur les participant.e.s français.e.s
|
||||
name: Nom
|
||||
points: Points
|
||||
rank: Rang
|
||||
score: Score
|
||||
tab: Classements
|
||||
view_bet: Voir le pari
|
||||
world_participants: Sur toutes les participant.e.s
|
||||
new:
|
||||
french_section: Pari sur les participant.e.s français.e.s
|
||||
message: Pour faire un pari, tu dois choisir 10 participant.e.s sur 2 listes, une comprenant l'ensemble des participant.e.s, l'autre comprenant uniquement les participant.e.s français.e.s. L'ordre a son importance ! Un facteur multiplicatif sera appliqué sur chaque participant.e que tu auras sélectionné.e (en parenthèses ci-dessous). Tu ne peux pas choisir un.e même participant.e plusieurs fois dans une liste, mais tu peux en revanche tout à fait choisir un.e participant.e français.e dans les deux listes !
|
||||
notice: Le pari est enregistré !
|
||||
tab: Fais ton pari !
|
||||
title: Nouveau pari
|
||||
world_section: Pari sur l'ensemble des participant.e.s
|
||||
title: Les paris des WJPC
|
||||
view:
|
||||
french_participants: Sur les français.e.s
|
||||
multiplier: Multiplicateur
|
||||
participant: Participant.e
|
||||
subtitle: "Le pari de <b>%{name}</b>"
|
||||
total: Total
|
||||
world_participants: Sur tout le monde
|
||||
|
||||
@@ -82,4 +82,13 @@ Rails.application.routes.draw do
|
||||
direct :offline_form_completed do |contest, offline|
|
||||
"/public/#{contest.friendly_id}/offline/#{offline.generate_token_for(:token)}/completed"
|
||||
end
|
||||
|
||||
get "wjpc_bets", to: redirect("/wjpc_bets/main")
|
||||
get "wjpc_bets/main", to: "worlds#main"
|
||||
get "wjpc_bets/about", to: "worlds#about"
|
||||
get "wjpc_bets/collaborative_filling", to: "worlds#collab"
|
||||
get "wjpc_bets/new", to: "worlds#new"
|
||||
post "wjpc_bets/new", to: "worlds#create"
|
||||
patch "wjpc_bets/update/:participant_id", to: "worlds#update"
|
||||
get "wjpc_bets/view/:bet_id", to: "worlds#view"
|
||||
end
|
||||
|
||||
10
db/migrate/20260904063514_create_world_countries.rb
Normal file
10
db/migrate/20260904063514_create_world_countries.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateWorldCountries < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :world_countries do |t|
|
||||
t.string :name, null: false
|
||||
t.string :code, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
14
db/migrate/20260904063926_create_world_participants.rb
Normal file
14
db/migrate/20260904063926_create_world_participants.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class CreateWorldParticipants < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :world_participants do |t|
|
||||
t.string :username, null: false
|
||||
t.string :name, null: false
|
||||
t.belongs_to :world_country, null: false, foreign_key: true
|
||||
t.integer :qualifier_result
|
||||
t.integer :semifinal_result
|
||||
t.integer :final_result
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddRoundToWorldParticipant < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :world_participants, :round, :string, null: false
|
||||
end
|
||||
end
|
||||
11
db/migrate/20260904131402_create_world_bets.rb
Normal file
11
db/migrate/20260904131402_create_world_bets.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateWorldBets < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :world_bets do |t|
|
||||
t.string :name
|
||||
t.string :bet
|
||||
t.integer :score
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddScoreToWorldParticipant < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :world_participants, :score, :integer
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddWorldScoreToWorldBet < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :world_bets, :world_score, :integer
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddFrenchScoreToWorldBet < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :world_bets, :french_score, :integer
|
||||
end
|
||||
end
|
||||
34
db/schema.rb
generated
34
db/schema.rb
generated
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_08_25_071844) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_09_05_120106) do
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "record_type", null: false
|
||||
@@ -203,6 +203,37 @@ ActiveRecord::Schema[8.0].define(version: 2026_08_25_071844) do
|
||||
t.index ["email_address"], name: "index_users_on_email_address", unique: true
|
||||
end
|
||||
|
||||
create_table "world_bets", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "bet"
|
||||
t.integer "score"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "world_score"
|
||||
t.integer "french_score"
|
||||
end
|
||||
|
||||
create_table "world_countries", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "code", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "world_participants", force: :cascade do |t|
|
||||
t.string "username", null: false
|
||||
t.string "name", null: false
|
||||
t.integer "world_country_id", null: false
|
||||
t.integer "qualifier_result"
|
||||
t.integer "semifinal_result"
|
||||
t.integer "final_result"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "round", null: false
|
||||
t.integer "score"
|
||||
t.index ["world_country_id"], name: "index_world_participants_on_world_country_id"
|
||||
end
|
||||
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "categories", "contests"
|
||||
@@ -220,4 +251,5 @@ ActiveRecord::Schema[8.0].define(version: 2026_08_25_071844) do
|
||||
add_foreign_key "offlines", "contests"
|
||||
add_foreign_key "puzzles", "contests"
|
||||
add_foreign_key "sessions", "users"
|
||||
add_foreign_key "world_participants", "world_countries"
|
||||
end
|
||||
|
||||
20
spec/factories/world_bets.rb
Normal file
20
spec/factories/world_bets.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_bets
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# bet :string
|
||||
# french_score :integer
|
||||
# name :string
|
||||
# score :integer
|
||||
# world_score :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
FactoryBot.define do
|
||||
factory :world_bet do
|
||||
name { "MyString" }
|
||||
bet { "MyString" }
|
||||
score { 1 }
|
||||
end
|
||||
end
|
||||
16
spec/factories/world_countries.rb
Normal file
16
spec/factories/world_countries.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_countries
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# code :string not null
|
||||
# name :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
FactoryBot.define do
|
||||
factory :world_country do
|
||||
name { "MyString" }
|
||||
code { "MyString" }
|
||||
end
|
||||
end
|
||||
34
spec/factories/world_participants.rb
Normal file
34
spec/factories/world_participants.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_participants
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# final_result :integer
|
||||
# name :string not null
|
||||
# qualifier_result :integer
|
||||
# round :string not null
|
||||
# score :integer
|
||||
# semifinal_result :integer
|
||||
# username :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# world_country_id :integer not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_world_participants_on_world_country_id (world_country_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# world_country_id (world_country_id => world_countries.id)
|
||||
#
|
||||
FactoryBot.define do
|
||||
factory :world_participant do
|
||||
username { "MyString" }
|
||||
name { "MyString" }
|
||||
world_country { nil }
|
||||
qualifier_result { 1 }
|
||||
semifinal_result { 1 }
|
||||
final_result { 1 }
|
||||
end
|
||||
end
|
||||
15
spec/helpers/worlds_helper_spec.rb
Normal file
15
spec/helpers/worlds_helper_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the WorldsHelper. For example:
|
||||
#
|
||||
# describe WorldsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe WorldsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
18
spec/models/world_bet_spec.rb
Normal file
18
spec/models/world_bet_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_bets
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# bet :string
|
||||
# french_score :integer
|
||||
# name :string
|
||||
# score :integer
|
||||
# world_score :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
RSpec.describe WorldBet, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
15
spec/models/world_country_spec.rb
Normal file
15
spec/models/world_country_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_countries
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# code :string not null
|
||||
# name :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
RSpec.describe WorldCountry, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
29
spec/models/world_participant_spec.rb
Normal file
29
spec/models/world_participant_spec.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: world_participants
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# final_result :integer
|
||||
# name :string not null
|
||||
# qualifier_result :integer
|
||||
# round :string not null
|
||||
# score :integer
|
||||
# semifinal_result :integer
|
||||
# username :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# world_country_id :integer not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_world_participants_on_world_country_id (world_country_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# world_country_id (world_country_id => world_countries.id)
|
||||
#
|
||||
RSpec.describe WorldParticipant, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
7
spec/requests/worlds_spec.rb
Normal file
7
spec/requests/worlds_spec.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe "Worlds", type: :request do
|
||||
describe "GET /index" do
|
||||
pending "add some examples (or delete) #{__FILE__}"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user