Multiples traductions
All checks were successful
CI / scan_ruby (push) Successful in 16s
CI / scan_js (push) Successful in 14s
CI / lint (push) Successful in 14s
CI / test (push) Successful in 32s

This commit is contained in:
sto 2025-06-19 11:20:33 +02:00
parent 4645b45f5d
commit 79fb1edfaf
13 changed files with 106 additions and 32 deletions

View File

@ -76,6 +76,8 @@ class ContestantsController < ApplicationController
def convert_csv def convert_csv
authorize @contest authorize @contest
@action_name = t("helpers.buttons.back")
@action_path = contest_path(@contest)
@csv_import = CsvImport.find(params[:id]) @csv_import = CsvImport.find(params[:id])
@content = JSON.parse(@csv_import.content) @content = JSON.parse(@csv_import.content)
@form = Forms::CsvConversionForm.new @form = Forms::CsvConversionForm.new
@ -92,15 +94,17 @@ class ContestantsController < ApplicationController
@content.each_with_index do |row, i| @content.each_with_index do |row, i|
if all_params["row_#{i}".to_sym] == "1" if all_params["row_#{i}".to_sym] == "1"
if @form.email_column == -1 if @form.email_column == -1
Contestant.create(name: row[@form.name_column], contest: @contest, time_seconds: 0) Contestant.create(name: row[@form.name_column], contest: @contest)
else else
logger.info("Email") logger.info("Email")
Contestant.create(name: row[@form.name_column], email: row[@form.email_column], contest: @contest, time_seconds: 0) Contestant.create(name: row[@form.name_column], email: row[@form.email_column], contest: @contest)
end end
end end
end end
redirect_to contest_path(@contest) redirect_to contest_path(@contest)
else else
@action_name = t("helpers.buttons.back")
@action_path = contest_path(@contest)
render :convert_csv, status: :unprocessable_entity render :convert_csv, status: :unprocessable_entity
end end
end end

View File

@ -52,6 +52,8 @@ class ContestsController < ApplicationController
if @contest.update(contest_params) if @contest.update(contest_params)
redirect_to @contest redirect_to @contest
else else
@action_name = t("helpers.buttons.back")
@action_path = contest_path(@contest)
render :edit, status: :unprocessable_entity render :edit, status: :unprocessable_entity
end end
end end

View File

@ -23,14 +23,16 @@ class Contestant < ApplicationRecord
belongs_to :contest belongs_to :contest
has_many :completions, dependent: :destroy has_many :completions, dependent: :destroy
before_create :initialize_time_seconds before_validation :initialize_time_seconds_if_empty
validates :name, presence: true validates :name, presence: true
validates :time_seconds, presence: true validates :time_seconds, presence: true
private private
def initialize_time_seconds def initialize_time_seconds_if_empty
if !self.time_seconds
self.time_seconds = 0 self.time_seconds = 0
end end
end end
end

View File

@ -24,5 +24,4 @@ class Puzzle < ApplicationRecord
has_one_attached :image has_one_attached :image
validates :name, presence: true validates :name, presence: true
validates :brand, presence: true
end end

View File

@ -1 +1 @@
= render "form", contest: @contest, completion: @completion, submit_text: "Save", method: :patch, url: "/contests/#{@contest.id}/completions/#{@completion.id}" = render "form", contest: @contest, completion: @completion, submit_text: t("helpers.buttons.save"), method: :patch, url: "/contests/#{@contest.id}/completions/#{@completion.id}"

View File

@ -1 +1 @@
= render "form", completion: @completion, submit_text: "Create", method: :post, url: "/contests/#{@contest.id}/completions" = render "form", completion: @completion, submit_text: t("helpers.buttons.create"), method: :post, url: "/contests/#{@contest.id}/completions"

View File

@ -13,11 +13,12 @@
.form-floating .form-floating
= form.text_field :email, autocomplete: "off", class: "form-control" = form.text_field :email, autocomplete: "off", class: "form-control"
= form.label :email = form.label :email
.form-text Optional. Fill this only if you intend to send emails through this app. .form-text
= t("activerecord.attributes.contestant.email_description")
.row.mt-4 .row.mt-4
.col .col
- if method == :patch - if method == :patch
= link_to "Delete", contest_contestant_path(contest, contestant), data: { turbo_method: :delete }, class: "btn btn-danger me-2" = link_to t("helpers.buttons.delete"), contest_contestant_path(contest, contestant), data: { turbo_method: :delete }, class: "btn btn-danger me-2"
= form.submit submit_text, class: "btn btn-primary" = form.submit submit_text, class: "btn btn-primary"
- if method == :patch - if method == :patch
@ -27,27 +28,35 @@
table.table.table-striped.table-hover table.table.table-striped.table-hover
thead thead
tr tr
- if @contest.puzzles.size > 1
th scope="col" th scope="col"
| Time since start = t("activerecord.attributes.completion.display_time_from_start")
th scope="col" th scope="col"
| Relative time = t("activerecord.attributes.completion.display_relative_time")
- else
th scope="col" th scope="col"
| Puzzle = t("activerecord.attributes.completion.display_time")
th scope="col"
= t("activerecord.attributes.completion.puzzle")
tbody tbody
- @completions.each do |completion| - @completions.each do |completion|
tr scope="row" tr scope="row"
td td
= completion.display_time_from_start = completion.display_time_from_start
- if @contest.puzzles.size > 1
td td
= completion.display_relative_time = completion.display_relative_time
td td
- if !completion.puzzle.brand.blank?
| #{completion.puzzle.name} - #{completion.puzzle.brand} | #{completion.puzzle.name} - #{completion.puzzle.brand}
- else
| #{completion.puzzle.name}
td td
a.btn.btn-sm.btn-secondary.me-2 href=edit_contest_completion_path(@contest, completion, contestant_id: contestant.id) a.btn.btn-sm.btn-secondary.me-2 href=edit_contest_completion_path(@contest, completion, contestant_id: contestant.id)
| Edit = t("helpers.buttons.edit")
= link_to "Delete", contest_completion_path(contest, completion, contestant_id: contestant.id), = link_to t("helpers.buttons.delete"), contest_completion_path(contest, completion, contestant_id: contestant.id),
data: { turbo_method: :delete }, class: "btn btn-sm btn-secondary" data: { turbo_method: :delete }, class: "btn btn-sm btn-secondary"
.row .row
.col .col
a.btn.btn-primary href=new_contest_completion_path(@contest, contestant_id: contestant.id) a.btn.btn-primary href=new_contest_completion_path(@contest, contestant_id: contestant.id)
| Add completion = t("helpers.buttons.add")

View File

@ -26,7 +26,7 @@
- @content[0].each_with_index do |_, i| - @content[0].each_with_index do |_, i|
th scope="col" th scope="col"
= t("helpers.field") + "_#{i}" = t("helpers.field") + "_#{i}"
th scope="col" th scope="col" style="white-space: nowrap"
= t("contestants.import.import_column") = t("contestants.import.import_column")
tbody tbody
- @content.each_with_index do |row, i| - @content.each_with_index do |row, i|

View File

@ -1 +1 @@
= render "form", contest: @contest, contestant: @contestant, submit_text: "Save", method: :patch, url: "/contests/#{@contest.id}/contestants/#{@contestant.id}" = render "form", contest: @contest, contestant: @contestant, submit_text: t("helpers.buttons.save"), method: :patch, url: "/contests/#{@contest.id}/contestants/#{@contestant.id}"

View File

@ -1 +1 @@
= render "form", contest: @contest, contestant: @contestant, submit_text: "Add", method: :post, url: "/contests/#{@contest.id}/contestants" = render "form", contest: @contest, contestant: @contestant, submit_text: t("helpers.buttons.add"), method: :post, url: "/contests/#{@contest.id}/contestants"

View File

@ -103,7 +103,7 @@
thead thead
tr tr
th scope="col" th scope="col"
| Rank = t("helpers.rank")
th scope="col" th scope="col"
= t("activerecord.attributes.contestant.name") = t("activerecord.attributes.contestant.name")
th scope="col" th scope="col"

View File

@ -38,6 +38,12 @@ en:
greater_than: "Participant names are required" greater_than: "Participant names are required"
activerecord: activerecord:
attributes: attributes:
completion:
contestant: Participant
display_time: Time
display_time_from_start: Time since start
display_relative_time: Time for this puzzle
puzzle: Puzzle
contest: contest:
name: "Name" name: "Name"
team: "Team contest" team: "Team contest"
@ -45,7 +51,14 @@ en:
allow_registration: "Allow registration" allow_registration: "Allow registration"
allow_registration_description: "Generates a shareable registration form for this contest" allow_registration_description: "Generates a shareable registration form for this contest"
contestant: contestant:
completions: completions
display_time: Time
email: "Email"
name: "Name" name: "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:
file: File
separator: Separator
message: message:
author: "Author" author: "Author"
processed: "Processed?" processed: "Processed?"
@ -65,15 +78,28 @@ en:
completion: completion:
attributes: attributes:
display_time_from_start: display_time_from_start:
blank: Mandatory
invalid: "Allowed formats: xx:xx:xx, x:xx:xx, xx:xx, x:xx, xx" invalid: "Allowed formats: xx:xx:xx, x:xx:xx, xx:xx, x:xx, xx"
puzzle_id: puzzle_id:
taken: "This contestant has already completed this puzzle" taken: "This contestant has already completed this puzzle"
contest:
attributes:
name:
blank: The contest name cannot be empty
contestant:
attributes:
name:
blank: The participant name cannot be empty
csv_import: csv_import:
attributes: attributes:
file: file:
blank: "No file selected" blank: "No file selected"
empty: "This file is empty" empty: "This file is empty"
not_a_csv_file: "it must be a CSV file" not_a_csv_file: "it must be a CSV file"
puzzle:
attributes:
name:
blank: The puzzle name cannot be empty
completions: completions:
edit: edit:
title: "Edit completion" title: "Edit completion"
@ -132,9 +158,12 @@ en:
create: "Create" create: "Create"
delete: "Delete" delete: "Delete"
edit: "Edit" edit: "Edit"
import: "CSV Import" import: CSV Import
save: "Save" open: Open
field: "Field" save: Save
field: Field
none: No field selected
rank: Rank
messages: messages:
convert: convert:
title: "New completion" title: "New completion"

View File

@ -9,6 +9,12 @@ fr:
greater_than: "Choisir une colonne pour les noms des participant.e.s est nécessaire" greater_than: "Choisir une colonne pour les noms des participant.e.s est nécessaire"
activerecord: activerecord:
attributes: attributes:
completion:
contestant_id: Participant.e
display_time: Temps
display_time_from_start: Temps depuis le début
display_relative_time: Temps pour ce puzzle
puzzle: Puzzle
contest: contest:
name: "Nom" name: "Nom"
team: "Concours par équipes" team: "Concours par équipes"
@ -16,7 +22,14 @@ fr:
allow_registration: "Autoriser l'inscription via l'interface" allow_registration: "Autoriser l'inscription via l'interface"
allow_registration_description: "Génère un formulaire d'inscription pour ce concours" allow_registration_description: "Génère un formulaire d'inscription pour ce concours"
contestant: contestant:
completions: Complétions
display_time: Temps
email: "Email"
name: "Nom" name: "Nom"
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
separator: Délimiteur
message: message:
author: "Auteur.ice" author: "Auteur.ice"
processed: "Traité ?" processed: "Traité ?"
@ -36,15 +49,28 @@ fr:
completion: completion:
attributes: attributes:
display_time_from_start: display_time_from_start:
blank: Obligatoire
invalid: "Formats autorisés: xx:xx:xx, x:xx:xx, xx:xx, x:xx, xx" invalid: "Formats autorisés: xx:xx:xx, x:xx:xx, xx:xx, x:xx, xx"
puzzle_id: puzzle_id:
taken: "Ce.tte participant.e a déjà complété ce puzzle" taken: "Ce.tte participant.e a déjà complété ce puzzle"
contest:
attributes:
name:
blank: Le nom du concours ne peut pas être vide
contestant:
attributes:
name:
blank: Le nom du ou de la participant.e ne peut pas être vide
csv_import: csv_import:
attributes: attributes:
file: file:
blank: "Aucun fichier sélectionné" blank: "Aucun fichier sélectionné"
empty: "Ce fichier est vide" empty: "Ce fichier est vide"
not_a_csv_file: "Le fichier doit être au format CSV" not_a_csv_file: "Le fichier doit être au format CSV"
puzzle:
attributes:
name:
blank: Le nom du puzzle est obligatoire
completions: completions:
edit: edit:
title: "Modifier la complétion" title: "Modifier la complétion"
@ -103,9 +129,12 @@ fr:
create: "Créer" create: "Créer"
delete: "Supprimer" delete: "Supprimer"
edit: "Modifier" edit: "Modifier"
import: "Importer un CSV" import: Importer un CSV
save: "Modifier" open: Détails
field: "Champ" save: Modifier
field: Champ
none: Aucun champ sélectionné
rank: Rang
messages: messages:
convert: convert:
title: "Ajout d'une complétion" title: "Ajout d'une complétion"