Files
MatchLiveTv/backend/app/controllers/public/teams_controller.rb
Emiliano Frascaro ad9d67ddb6 Completa multi-sport su web, API score_action e controlli Android board-aware.
Allinea i form società/squadra al catalogo sport, espone score_action per basket/timed e corregge bug namespace Sports e Result nel period engine; l'app nativa gestisce overlay e punteggio per board con wizard regole esteso.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 21:48:29 +02:00

186 lines
6.3 KiB
Ruby

module Public
class TeamsController < WebBaseController
include BrandingAttachments
before_action :require_login!
before_action :set_club, only: %i[new create]
before_action :set_team, only: %i[
details dashboard roster edit update invite create_invitation
assign_self_staff clear_self_staff remove_member destroy_invitation
youtube_connect youtube_disconnect
]
def new
redirect_to public_new_club_path if current_user.owned_clubs.none?
require_club_owner!(@club)
end
def create
require_club_owner!(@club)
team = @club.teams.create!(team_params)
attach_branding_logo(team)
redirect_to public_club_path(@club), notice: "Squadra «#{team.name}» aggiunta."
rescue ActiveRecord::RecordInvalid => e
flash.now[:alert] = e.record.errors.full_messages.join(", ")
render :new, status: :unprocessable_entity
end
def details
load_team_details!
render :details
end
def dashboard
redirect_to public_team_details_path(params[:id])
end
def roster
redirect_to public_team_details_path(params[:id])
end
def edit
require_club_owner_for_team!(@team)
@club = @team.club
end
def update
require_club_owner_for_team!(@team)
@team.assign_attributes(team_params)
attach_branding_logo(@team)
attach_team_photo(@team)
@team.save!
redirect_to public_team_details_path(@team), notice: "Squadra aggiornata."
rescue ActiveRecord::RecordInvalid => e
@club = @team.club
flash.now[:alert] = e.record.errors.full_messages.join(", ")
render :edit, status: :unprocessable_entity
end
def invite
require_club_owner_for_team!(@team)
@entitlements = @team.entitlements
end
def assign_self_staff
require_club_owner_for_team!(@team)
membership = current_user.user_teams.find_or_initialize_by(team: @team)
membership.role = "member" if membership.new_record?
Teams::StaffAssignment.call(team: @team, user: current_user, membership: membership)
redirect_to public_team_details_path(@team), notice: "Il tuo account è ora responsabile trasmissione."
rescue Teams::StaffAssignmentError, Teams::EntitlementError => e
redirect_to public_team_details_path(@team), alert: e.message
end
def clear_self_staff
require_club_owner_for_team!(@team)
membership = current_user.user_teams.find_by(team: @team)
membership&.update!(staff_kind: nil)
redirect_to public_team_details_path(@team), notice: "Ruolo staff rimosso dal tuo account."
end
def create_invitation
require_club_owner_for_team!(@team)
@entitlements = @team.entitlements
staff_kind = "transmission"
@entitlements.assert_can_invite!(staff_kind: staff_kind)
email = params[:email]&.downcase&.strip
Teams::StaffEmailValidator.assert_available!(team: @team, email: email, staff_kind: staff_kind)
token = TeamInvitation.generate_token
@team.team_invitations.create!(
email: email,
token_digest: Digest::SHA256.hexdigest(token),
role: "member",
staff_kind: staff_kind,
expires_at: 7.days.from_now
)
@invite_url = join_public_invitation_url(token: token)
flash.now[:notice] = "Link invito generato (valido 7 giorni)"
render :invite
rescue Teams::EntitlementError, Teams::StaffAssignmentError => e
redirect_to public_team_invite_path(@team), alert: e.message
end
def remove_member
require_club_owner_for_team!(@team)
ut = @team.user_teams.find_by!(user_id: params[:user_id], role: "member")
ut.destroy!
redirect_to public_team_details_path(@team), notice: "Accesso revocato"
end
def destroy_invitation
require_club_owner_for_team!(@team)
inv = @team.team_invitations.pending.find(params[:invitation_id])
inv.destroy!
redirect_to public_team_details_path(@team), notice: "Invito annullato"
end
def youtube_connect
redirect_to public_club_youtube_connect_path(
@team.club_id,
return_app: params[:return_app]
)
end
def youtube_disconnect
require_club_owner_for_team!(@team)
@team.club.youtube_credential&.destroy!
redirect_to public_club_path(@team.club), notice: "Canale YouTube della società scollegato"
end
private
def load_team_details!
@club = @team.club
@can_manage = @club.owned_by?(current_user)
@entitlements = @team.entitlements
@roster_by_category = @team.roster_by_category
if @can_manage
@roster_member = @team.roster_members.build(
category: params[:category].presence_in(TeamRosterMember::CATEGORIES) || "player"
)
end
@recordings = @team.recordings.not_deleted
.where(status: %w[ready processing])
.includes(stream_session: :match)
.order(recorded_at: :desc, created_at: :desc)
.limit(10)
@owner_membership = current_user.user_teams.find_by(team: @team)
@staff_memberships = @team.user_teams.includes(:user)
.where("user_teams.role = 'member' OR (user_teams.staff_kind IS NOT NULL)")
@pending_invitations = @team.team_invitations.pending.order(created_at: :desc)
end
def set_club
@club = current_user.owned_clubs.find(params[:club_id])
end
def set_team
@team = current_user.manageable_teams.find(params[:id])
end
def attach_team_photo(team)
file = params.dig(:team, :photo_file)
team.photo_file.attach(file) if file.present?
end
def team_params
p = params.require(:team).permit(:name, :sport, :sport_key, :description, :logo_url, :primary_color, :secondary_color)
if p[:sport].present? && p[:sport_key].blank?
p[:sport_key] = p.delete(:sport)
elsif p[:sport_key].present?
p.delete(:sport)
end
p[:primary_color] = p[:primary_color].presence
p[:secondary_color] = p[:secondary_color].presence
if p[:primary_color].present?
p[:primary_color] = normalize_hex_color(p[:primary_color], p[:primary_color])
end
if p[:secondary_color].present?
p[:secondary_color] = normalize_hex_color(p[:secondary_color], p[:secondary_color])
end
p
end
end
end