Unifica admin società/squadre e YouTube Full con fallback MLTV.

Premium Full senza canale società usa il canale piattaforma come Light;
in app restano solo Match Live TV e YouTube Live.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 22:38:28 +02:00
parent 82ff1972a0
commit 9b40deeb61
14 changed files with 125 additions and 144 deletions

View File

@@ -3,13 +3,14 @@ module Admin
before_action :set_club, only: %i[show grant_comped revoke_comped]
def index
@clubs = Club.includes(:subscription, subscription: :plan, subscription: :admin_comped_by)
@clubs = Club.includes(:subscription, :teams, subscription: :plan, subscription: :admin_comped_by)
.order(:name)
end
def show
@subscription = @club.subscription || @club.build_subscription(plan: Plan["free"], status: "active")
@plans = Plan.ordered.reject { |p| p.slug == "free" }
@teams = @club.teams.includes(:youtube_credential).order(:name)
end
def grant_comped

View File

@@ -1,7 +1,7 @@
module Admin
class TeamsController < Admin::BaseController
def index
@teams = Team.all.order(:name)
redirect_to admin_clubs_path, status: :moved_permanently
end
def show

View File

@@ -6,19 +6,20 @@ module Youtube
def initialize(team)
@team = team
@status = TeamStatus.new(team)
@mode = team.entitlements.plan.youtube_mode
end
def resolve
if @mode == "matchlivetv_light" && PlatformCredential.configured?
if @status.uses_platform_channel?
PlatformCredential.new
else
elsif @mode == "team"
@team.youtube_credential
end
end
def uses_platform_channel?
@mode == "matchlivetv_light" && PlatformCredential.configured?
@status.uses_platform_channel?
end
end
end

View File

@@ -15,7 +15,7 @@ module Youtube
when "matchlivetv_light"
PlatformCredential.configured?
when "team"
@team.youtube_credential.present?
@team.youtube_credential.present? || PlatformCredential.configured?
else
false
end
@@ -26,7 +26,15 @@ module Youtube
end
def uses_platform_channel?
@mode == "matchlivetv_light" && PlatformCredential.configured?
return false unless @ent.youtube_enabled?
if @mode == "matchlivetv_light"
PlatformCredential.configured?
elsif @mode == "team"
@team.youtube_credential.blank? && PlatformCredential.configured?
else
false
end
end
def channel_title
@@ -38,7 +46,7 @@ module Youtube
end
def needs_team_oauth?
@mode == "team" && @ent.premium_full?
@mode == "team" && @ent.premium_full? && @team.youtube_credential.blank? && !PlatformCredential.configured?
end
end
end

View File

@@ -1,6 +1,7 @@
<h2>Società</h2>
<h2>Società e squadre</h2>
<p style="color:#888;margin-bottom:16px">
Gestisci abbonamenti omaggio (sponsor / promozioni). Per pagamenti Stripe usa <%= link_to "Fatturazione", admin_billing_path %>.
Abbonamenti omaggio (sponsor / promozioni) e stato YouTube per squadra.
Pagamenti Stripe: <%= link_to "Fatturazione", admin_billing_path %>.
</p>
<table class="admin-table">
@@ -8,6 +9,7 @@
<tr>
<th>Società</th>
<th>Piano</th>
<th>Squadre</th>
<th>Omaggio</th>
<th>Stripe</th>
<th></th>
@@ -19,6 +21,7 @@
<tr>
<td><strong><%= club.name %></strong></td>
<td><%= sub&.plan&.name || "Free" %></td>
<td><%= club.teams.size %></td>
<td>
<% if sub&.admin_comped? %>
<span style="color:#ffb74d">Sì</span>

View File

@@ -1,16 +1,52 @@
<p style="margin-bottom:16px"><%= link_to "← Tutte le società", admin_clubs_path %></p>
<p style="margin-bottom:16px"><%= link_to "← Società e squadre", admin_clubs_path %></p>
<h2><%= @club.name %></h2>
<p style="color:#888">
Sport: <%= @club.sport %>
· <%= link_to "Pagamenti e fatture", admin_billing_path(club_id: @club.id) %>
· <%= link_to "Canale YouTube piattaforma", admin_youtube_platform_path %>
</p>
<%= render "admin/clubs/comped_form", club: @club, subscription: @subscription, return_to: admin_club_path(@club) %>
<h3 style="font-size:1rem;margin-top:24px">Squadre</h3>
<ul>
<% @club.teams.order(:name).each do |team| %>
<li><%= link_to team.name, admin_team_path(team) %></li>
<% end %>
</ul>
<h3 style="font-size:1rem;margin-top:28px">Squadre</h3>
<% if @teams.empty? %>
<p class="muted">Nessuna squadra registrata.</p>
<% else %>
<table class="admin-table">
<thead>
<tr>
<th>Squadra</th>
<th>Sport</th>
<th>YouTube</th>
<th></th>
</tr>
</thead>
<tbody>
<% @teams.each do |team| %>
<% yt = Youtube::TeamStatus.new(team) %>
<tr>
<td><strong><%= team.name %></strong></td>
<td><%= team.sport %></td>
<td>
<% if yt.selectable? %>
<% if yt.uses_platform_channel? %>
<span style="color:#81c784">Match Live TV</span>
<% if team.youtube_credential.blank? && team.entitlements.premium_full? %>
<span class="muted"> (default Full)</span>
<% end %>
<% else %>
<span style="color:#81c784">✓ <%= yt.channel_title.presence || "Canale società" %></span>
<% end %>
<% elsif team.entitlements.youtube_enabled? %>
<span class="muted">In configurazione</span>
<% else %>
<% end %>
</td>
<td><%= link_to "Partite e dettagli", admin_team_path(team) %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>

View File

@@ -123,7 +123,7 @@
<% end %>
</ul>
<% if @stats[:teams_count] > @teams.size %>
<p class="kpi-sub" style="margin-top:0.75rem"><%= link_to "Vedi tutte (#{@stats[:teams_count]})", admin_teams_path %></p>
<p class="kpi-sub" style="margin-top:0.75rem"><%= link_to "Vedi società (#{@stats[:teams_count]} squadre)", admin_clubs_path %></p>
<% end %>
</div>
</section>

View File

@@ -1,21 +0,0 @@
<h2>Teams</h2>
<table class="admin-table">
<thead><tr><th>Nome</th><th>Società</th><th>Sport</th><th>YouTube</th><th>Fatture</th></tr></thead>
<tbody>
<% @teams.each do |t| %>
<tr>
<td><%= link_to t.name, admin_team_path(t) %></td>
<td><%= t.club&.name || "—" %></td>
<td><%= t.sport %></td>
<td><%= t.youtube_credential.present? ? "✓" : "—" %></td>
<td>
<% if t.club %>
<%= link_to "Fatturazione", admin_billing_path(club_id: t.club.id) %>
<% else %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -1,14 +1,32 @@
<% if @team.club %>
<p style="margin-bottom:16px"><%= link_to "← #{@team.club.name}", admin_club_path(@team.club) %></p>
<% end %>
<h2><%= @team.name %></h2>
<p>Sport: <%= @team.sport %></p>
<% if @team.club %>
<p>Società: <%= @team.club.name %> · <%= link_to "Pagamenti e fatture", admin_billing_path(club_id: @team.club.id) %></p>
<% end %>
<% yt = Youtube::TeamStatus.new(@team) %>
<p>YouTube: <%= yt.channel_title || "—" %> · <%= yt.selectable? ? "pronto" : "non pronto" %></p>
<% if @team.entitlements.plan.youtube_mode == "team" && @team.youtube_credential.blank? %>
<p><%= link_to "Collega (da account titolare sul sito)", public_team_details_path(@team) %></p>
<p>
YouTube:
<% if yt.selectable? %>
<strong><%= yt.channel_title || "—" %></strong>
<% if yt.uses_platform_channel? %>
(canale piattaforma<%= @team.entitlements.premium_full? && @team.youtube_credential.blank? ? ", default senza OAuth società" : "" %>)
<% else %>
(canale società)
<% end %>
<% else %>
non pronto
<% end %>
</p>
<% if @team.entitlements.premium_full? && @team.youtube_credential.blank? %>
<p class="muted">
Senza canale collegato, lapp usa il canale Match Live TV.
<%= link_to "Collega canale (sito pubblico)", public_team_details_path(@team) %>.
</p>
<% end %>
<p><%= link_to "Token canale Match Live TV (Light)", admin_youtube_platform_path %></p>
<h3>Partite</h3>
<ul>

View File

@@ -16,8 +16,7 @@
<nav class="admin-nav">
<% if admin_logged_in? %>
<%= link_to "Dashboard", admin_root_path, class: ("active" if controller_name == "dashboard") %>
<%= link_to "Teams", admin_teams_path, class: ("active" if controller_name == "teams") %>
<%= link_to "Società", admin_clubs_path, class: ("active" if controller_name == "clubs") %>
<%= link_to "Società e squadre", admin_clubs_path, class: ("active" if controller_name.in?(%w[clubs teams])) %>
<%= link_to "Fatturazione", admin_billing_path, class: ("active" if controller_name.in?(%w[billing billing_invoices])) %>
<%= link_to "YouTube", admin_youtube_platform_path, class: ("active" if controller_name == "youtube") %>
<%= link_to "Sessions", admin_sessions_path, class: ("active" if controller_name == "sessions") %>

View File

@@ -28,13 +28,18 @@
<%= button_to "Scollega canale", public_team_youtube_disconnect_path(team),
method: :delete,
class: "btn btn-secondary",
form: { data: { turbo_confirm: "Scollegare il canale YouTube? Le dirette future richiederanno un nuovo collegamento." } } %>
form: { data: { turbo_confirm: "Scollegare il canale YouTube? Le dirette useranno il canale Match Live TV finché non ricolleghi il tuo." } } %>
<% else %>
<p class="muted">
Collega il canale YouTube della società per trasmettere dallapp con la piattaforma «YouTube Live».
<p>
Senza canale collegato, le dirette YouTube dallapp vanno sul canale ufficiale
<strong>Match Live TV</strong>.
Puoi collegare il canale della società quando vuoi per trasmettere sul tuo profilo.
</p>
<% if yt.selectable? %>
<p class="muted">YouTube pronto in app (canale Match Live TV).</p>
<% end %>
<% if ENV["YOUTUBE_CLIENT_ID"].present? %>
<%= link_to "Collega canale YouTube", public_team_youtube_connect_path(team), class: "btn btn-primary" %>
<%= link_to "Collega il tuo canale YouTube", public_team_youtube_connect_path(team), class: "btn btn-primary" %>
<% else %>
<p class="muted">OAuth YouTube non ancora configurato sul server.</p>
<% end %>

View File

@@ -67,7 +67,7 @@ Rails.application.routes.draw do
get "metrics", to: "dashboard#metrics"
get "billing", to: "billing#index", as: :billing
post "billing/payments/:payment_id/attach_pdf", to: "billing#attach_pdf", as: :billing_payment_attach_pdf
resources :teams, only: %i[index show]
resources :teams, only: %i[show]
resources :clubs, only: %i[index show] do
member do
post :grant_comped