Aggiunge i tornei con hub, pagina pubblica e tabellone per semifinali e finali.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-05 15:05:57 +02:00
co-authored by Cursor
parent d52434fb2e
commit a1f4c24a43
124 changed files with 6979 additions and 91 deletions
@@ -0,0 +1,136 @@
module Public
class TournamentInvitationsController < WebBaseController
before_action :require_login!
before_action :set_tournament
def create
if params[:intent] == "save"
save_draft
return
end
match_ids = Array(params[:match_ids]).reject(&:blank?)
scope_kind = if match_ids.any?
"matches"
elsif params[:whole_court].present? || params[:scope_kind].to_s == "court_day"
"court_day"
else
raise ArgumentError, t("tournaments.hub.stream_plan_need_selection")
end
persist_draft! unless calendar_invite?
invitation, token = Tournaments::Invite.call(
tournament: @tournament,
email: params[:email],
scope_kind: scope_kind,
match_ids: match_ids,
court: params[:court],
on_date: params[:on_date].presence,
invited_by: current_user,
note: params[:note]
)
invite_url = public_invitation_url(token: token)
flash[:invite_url] = invite_url unless calendar_invite?
body_html = Tournaments::ComposeInviteEmail.call(
html: draft_html,
invite_url: invite_url,
expires_on: I18n.l(invitation.expires_at.to_date, format: :long)
)
invitation.update!(email_html: body_html)
begin
Tournaments::InvitationMailer.transmission_invite(
tournament: @tournament,
invitation: invitation,
invite_url: invite_url,
invited_by: current_user,
body_html: body_html
).deliver_now
flash[:notice] = t("flash.tournaments.invite_email_sent", email: invitation.email)
rescue StandardError => e
Rails.logger.error("[tournament_invite] #{e.class}: #{e.message}")
flash[:alert] = t("flash.tournaments.invite_email_failed", email: invitation.email)
end
redirect_to public_tournament_path(@tournament, tab: invite_return_tab, anchor: calendar_invite? ? nil : "invito-generato")
rescue Tournaments::EntitlementError => e
redirect_to public_club_billing_path(@club), alert: e.message
rescue ActiveRecord::RecordInvalid, ArgumentError => e
redirect_to public_tournament_path(@tournament, tab: invite_return_tab), alert: e.message
end
def save_draft
Tournaments::Entitlements.new(@club).assert_writable!
persist_draft!
redirect_to public_tournament_path(@tournament, tab: "dirette"),
notice: t("flash.tournaments.invite_draft_saved")
rescue Tournaments::EntitlementError => e
redirect_to public_club_billing_path(@club), alert: e.message
rescue ActiveRecord::RecordInvalid => e
redirect_to public_tournament_path(@tournament, tab: "dirette"), alert: e.message
end
def upload_image
Tournaments::Entitlements.new(@club).assert_writable!
file = params[:file]
unless file.respond_to?(:content_type) && file.content_type.to_s.in?(%w[image/png image/jpeg image/webp image/gif])
return render json: { error: t("tournaments.hub.invite_image_invalid") }, status: :unprocessable_entity
end
if file.size > 2.megabytes
return render json: { error: t("tournaments.hub.invite_image_too_big") }, status: :unprocessable_entity
end
@tournament.invite_email_images.attach(file)
blob = @tournament.invite_email_images.blobs.last
render json: { url: url_for(blob) }
rescue Tournaments::EntitlementError => e
render json: { error: e.message }, status: :forbidden
end
def destroy
Tournaments::Entitlements.new(@club).assert_writable!
invitation = @tournament.broadcast_invitations.find(params[:invitation_id])
invitation.destroy!
redirect_to public_tournament_path(@tournament, tab: invite_return_tab), notice: t("flash.tournaments.invite_canceled")
rescue Tournaments::EntitlementError => e
redirect_to public_club_billing_path(@club), alert: e.message
end
private
def set_tournament
@tournament = Tournament.find(params[:id])
@club = @tournament.club
require_club_owner!(@club)
end
def persist_draft!
@tournament.update!(
invite_draft_html: Tournaments::ComposeInviteEmail.sanitize_html(draft_html),
invite_draft_note: params[:note].to_s.strip.presence,
invite_draft_email: params[:email].to_s.strip.presence,
invite_draft_saved_at: Time.current
)
end
def draft_html
html = params[:email_html].to_s
stripped = ActionController::Base.helpers.strip_tags(html).to_s.gsub(/\s+/, "")
return html if stripped.present?
stored = @tournament.invite_draft_html.to_s
if ActionController::Base.helpers.strip_tags(stored).to_s.gsub(/\s+/, "").present?
return stored
end
Tournaments::ComposeInviteEmail.default_html(tournament: @tournament, invited_by: current_user)
end
def calendar_invite?
params[:from].to_s == "calendar" || invite_return_tab == "calendario"
end
def invite_return_tab
tab = params[:tab].to_s
tab = "dirette" if tab == "delega"
tab.presence_in(%w[calendario dirette]) || "dirette"
end
end
end