Implement offline POST method for starting an offline participation
This commit is contained in:
		| @@ -30,8 +30,12 @@ class ApplicationController < ActionController::Base | ||||
|   def user_not_authorized(exception) | ||||
|     policy_name = exception.policy.class.to_s.underscore | ||||
|  | ||||
|     flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default | ||||
|     redirect_back_or_to(root_path) | ||||
|     if current_user | ||||
|       flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default | ||||
|       redirect_back_or_to(root_path) | ||||
|     else | ||||
|       not_found | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def not_found | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| class ContestsController < ApplicationController | ||||
|   before_action :set_contest, only: %i[ destroy edit show update ] | ||||
|   skip_before_action :require_authentication, only: %i[ scoreboard offline_new ] | ||||
|   before_action :offline_setup, only: %i[ offline_new offline_create ] | ||||
|   skip_before_action :require_authentication, only: %i[ scoreboard offline_new offline_create ] | ||||
|  | ||||
|   def index | ||||
|     authorize :contest | ||||
| @@ -100,22 +101,30 @@ class ContestsController < ApplicationController | ||||
|   end | ||||
|  | ||||
|   def offline_new | ||||
|     @contest = Contest.find_by(slug: params[:id]) | ||||
|     unless @contest && @contest.offline_form | ||||
|       skip_authorization | ||||
|       not_found and return | ||||
|     end | ||||
|     authorize :contest | ||||
|  | ||||
|     I18n.locale = @contest.lang | ||||
|  | ||||
|     @title = I18n.t("contests.scoreboard.title", name: @contest.name) | ||||
|  | ||||
|     authorize @contest | ||||
|     @offline = Offline.new | ||||
|   end | ||||
|  | ||||
|   def offline_create | ||||
|     authorize @contest | ||||
|     @offline = Offline.new(offline_start_params) | ||||
|     @offline.contest = @contest | ||||
|     @offline.start_time = Time.now() | ||||
|     if @offline.save | ||||
|       redirect_to "/public/#{@contest.friendly_id}/offline/test" | ||||
|     else | ||||
|       render :offline_new, status: :unprocessable_entity | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   private | ||||
|  | ||||
|   def offline_setup | ||||
|     @contest = Contest.find_by(slug: params[:id]) | ||||
|     I18n.locale = @contest.lang | ||||
|     @title = I18n.t("contests.scoreboard.title", name: @contest.name) | ||||
|   end | ||||
|  | ||||
|   def set_badges | ||||
|     @badges = [] | ||||
|     @badges.push(t("helpers.badges.team")) if @contest.team | ||||
| @@ -139,4 +148,8 @@ class ContestsController < ApplicationController | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def offline_start_params | ||||
|     params.expect(offline: [ :name, :start_image ]) | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| # | ||||
| #  id         :integer          not null, primary key | ||||
| #  end_time   :datetime | ||||
| #  name       :string           not null | ||||
| #  start_time :datetime         not null | ||||
| #  created_at :datetime         not null | ||||
| #  updated_at :datetime         not null | ||||
| @@ -23,5 +24,17 @@ class Offline < ApplicationRecord | ||||
|   has_one_attached :start_image | ||||
|   has_one_attached :end_image | ||||
|  | ||||
|   validates :name, presence: true | ||||
|   validates :start_time, presence: true | ||||
|  | ||||
|   validate :start_image_is_present | ||||
|  | ||||
|   def start_image_is_present | ||||
|     logger = Logger.new(STDOUT) | ||||
|     logger.info "TESTddfzefzef" | ||||
|     logger.info self.start_image.attached? | ||||
|     if !self.start_image.attached? | ||||
|       errors.add(:start_image, I18n.t("activerecord.errors.models.offline.attributes.start_image.blank")) | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -47,24 +47,28 @@ class ContestPolicy < ApplicationPolicy | ||||
|     record.user.id == user.id || user.admin? | ||||
|   end | ||||
|  | ||||
|   def offline? | ||||
|     record.offline_form | ||||
|   end | ||||
|  | ||||
|   def offline_new? | ||||
|     true | ||||
|     offline? | ||||
|   end | ||||
|  | ||||
|   def offline_create? | ||||
|     true | ||||
|     offline? | ||||
|   end | ||||
|  | ||||
|   def offline_edit? | ||||
|     true | ||||
|     offline? | ||||
|   end | ||||
|  | ||||
|   def offline_update? | ||||
|     true | ||||
|     offline? | ||||
|   end | ||||
|  | ||||
|   def scoreboard? | ||||
|     true | ||||
|     record.public | ||||
|   end | ||||
|  | ||||
|   def upload_csv? | ||||
|   | ||||
| @@ -1,8 +1,13 @@ | ||||
| = form_with model: @offline, url: "/public/#{@contest.id}/offline" do |form| | ||||
| = form_with model: @offline, url: "/public/#{@contest.friendly_id}/offline" do |form| | ||||
|   .row.mb-3 | ||||
|     .col | ||||
|       .form-floating | ||||
|         = form.text_field :name, autocomplete: "off", class: "form-control" | ||||
|         = form.label :name, class: "required" | ||||
|   .row.mb-3 | ||||
|     .col | ||||
|       .form-text.mb-1 | ||||
|         = t("puzzles.image_select") | ||||
|         = t("offlines.start_image_select") | ||||
|       = form.file_field :start_image, accept: "image/*", class: "form-control" | ||||
|       .form-text.error-message style="display: none;" id="image-error-message" | ||||
|         = t("puzzles.form.file_too_big") | ||||
| @@ -20,6 +25,6 @@ | ||||
|         } | ||||
|  | ||||
|         setMaxUploadSize(); | ||||
|   .row.mt-3 | ||||
|   .row.mt-4 | ||||
|     .col | ||||
|       = form.submit t("helpers.buttons.add"), class: "btn btn-primary" | ||||
|       = form.submit t("helpers.buttons.start"), class: "btn btn-primary" | ||||
		Reference in New Issue
	
	Block a user