module Public class MatchesController < WebBaseController before_action :require_login! before_action :set_team before_action :require_can_schedule! before_action :set_match, only: %i[edit update destroy] def index @matches = @team.matches .includes(:stream_sessions) .order(Arel.sql("scheduled_at ASC NULLS LAST"), created_at: :desc) @can_manage = @team.club.owned_by?(current_user) end def new @match = @team.matches.build( sport: @team.sport, sets_to_win: 3, scheduled_at: default_scheduled_at ) end def create @match = @team.matches.create!( match_params.merge(sport: @team.sport, sets_to_win: match_params[:sets_to_win].presence || 3) ) redirect_to public_team_matches_path(@team), notice: "Partita programmata: #{@match.opponent_name}. Avvia lo streaming dall’app quando sei in palestra." rescue ActiveRecord::RecordInvalid => e @match = @team.matches.build(match_params) flash.now[:alert] = e.record.errors.full_messages.join(", ") render :new, status: :unprocessable_entity end def edit end def update @match.update!(match_params) redirect_to public_team_matches_path(@team), notice: "Partita aggiornata." rescue ActiveRecord::RecordInvalid => e flash.now[:alert] = e.record.errors.full_messages.join(", ") render :edit, status: :unprocessable_entity end def destroy active = active_session_for(@match) if active&.resumable? redirect_to public_team_matches_path(@team), alert: "Chiudi la diretta prima di eliminare questa partita." return end @match.destroy! redirect_to public_team_matches_path(@team), notice: "Partita eliminata." end private def set_team @team = current_user.manageable_teams.find(params[:team_id]) @club = @team.club end def require_can_schedule! return if current_user.can_schedule_for?(@team) redirect_to public_team_details_path(@team), alert: "Solo un responsabile trasmissione o il titolare della società possono programmare le partite." end def set_match @match = @team.matches.find(params[:id]) end def match_params p = params.require(:match).permit(:opponent_name, :location, :scheduled_at, :sport, :sets_to_win) p[:scheduled_at] = parse_scheduled_at(p[:scheduled_at]) if p[:scheduled_at].present? p end def parse_scheduled_at(value) raw = value.to_s.strip return nil if raw.blank? Time.zone.strptime(raw, "%Y-%m-%dT%H:%M") rescue ArgumentError Time.zone.parse(raw) end def default_scheduled_at t = Time.current + 2.hours Time.zone.local(t.year, t.month, t.day, t.hour, 0, 0) end def active_session_for(match) match.stream_sessions .order(created_at: :desc) .find { |s| !%w[ended error].include?(s.status) } end end end