Aggiunge filtri/colonne (società, orari) e dettaglio leggibile; evita 422 CSRF su logout e non cancella le cover slate custom in sync prod. Co-authored-by: Cursor <cursoragent@cursor.com>
248 lines
9.1 KiB
ERB
248 lines
9.1 KiB
ERB
<% content_for :body_class, "admin-body" %>
|
|
<% team = @session.match.team %>
|
|
<% club = @club || team.club %>
|
|
|
|
<div class="admin-page-head admin-session-head">
|
|
<div>
|
|
<p class="muted admin-page-sub">
|
|
<%= link_to t("admin.sessions.show.back"), admin_sessions_path %>
|
|
</p>
|
|
<h2 class="admin-page-title"><%= t("admin.sessions.show.heading") %></h2>
|
|
<p class="admin-session-match">
|
|
<strong><%= team.name %></strong>
|
|
<span class="muted">vs</span>
|
|
<strong><%= @session.match.opponent_name %></strong>
|
|
</p>
|
|
<% if club %>
|
|
<p class="muted">
|
|
<%= t("admin.sessions.show.club_label") %>
|
|
<%= link_to club.name, admin_club_path(club) %>
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
<div class="admin-session-head-actions">
|
|
<span class="badge <%= admin_session_status_badge_class(@session.status) %>"><%= @session.status %></span>
|
|
<% unless @session.terminal? %>
|
|
<%= button_to t("admin.sessions.show.stop_button"),
|
|
stop_admin_session_path(@session),
|
|
method: :post,
|
|
class: "admin-btn admin-btn--danger admin-btn--sm",
|
|
form: { data: { turbo_confirm: t("admin.sessions.show.stop_confirm") } } %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="admin-session-grid">
|
|
<section class="panel">
|
|
<h3><%= t("admin.sessions.show.summary_title") %></h3>
|
|
<dl class="admin-kv">
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.id") %></dt>
|
|
<dd><code class="admin-mono"><%= @session.id %></code></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.club") %></dt>
|
|
<dd><%= club&.name || t("admin.common.dash") %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.team") %></dt>
|
|
<dd><%= team.name %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.opponent") %></dt>
|
|
<dd><%= @session.match.opponent_name %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.operator") %></dt>
|
|
<dd>
|
|
<% if @session.user %>
|
|
<%= @session.user.name.presence || @session.user.email %>
|
|
<span class="muted">(<%= @session.user.email %>)</span>
|
|
<% else %>
|
|
<%= t("admin.common.dash") %>
|
|
<% end %>
|
|
</dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.platform") %></dt>
|
|
<dd><%= @session.platform %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.privacy") %></dt>
|
|
<dd><%= @session.privacy_status %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.quality") %></dt>
|
|
<dd><%= @session.quality_preset %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.min_quality") %></dt>
|
|
<dd><%= @session.min_quality_preset %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.audio") %></dt>
|
|
<dd><%= @session.audio_muted? ? t("admin.sessions.show.audio_muted") : t("admin.sessions.show.audio_on") %></dd>
|
|
</div>
|
|
</dl>
|
|
</section>
|
|
|
|
<section class="panel">
|
|
<h3><%= t("admin.sessions.show.timing_title") %></h3>
|
|
<dl class="admin-kv">
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.created") %></dt>
|
|
<dd><%= admin_datetime(@session.created_at, with_seconds: true) %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.started") %></dt>
|
|
<dd><%= admin_datetime(@session.started_at, with_seconds: true) %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.ended") %></dt>
|
|
<dd><%= admin_datetime(@session.ended_at, with_seconds: true) %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.duration") %></dt>
|
|
<dd><%= admin_session_duration_label(@session) %></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.disconnects") %></dt>
|
|
<dd><%= @session.disconnection_count %></dd>
|
|
</div>
|
|
<% if @session.match.scheduled_at %>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.scheduled") %></dt>
|
|
<dd><%= admin_datetime(@session.match.scheduled_at) %></dd>
|
|
</div>
|
|
<% end %>
|
|
<% if @session.match.location.present? %>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.location") %></dt>
|
|
<dd><%= @session.match.location %></dd>
|
|
</div>
|
|
<% end %>
|
|
</dl>
|
|
</section>
|
|
|
|
<section class="panel">
|
|
<h3><%= t("admin.sessions.show.ingest_title") %></h3>
|
|
<dl class="admin-kv">
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.node") %></dt>
|
|
<dd>
|
|
<% if @session.stream_node %>
|
|
<code><%= @session.stream_node.slug %></code>
|
|
<span class="badge <%= admin_session_ingest_badge_class(@session.stream_node) %>">
|
|
<%= admin_session_ingest_role_label(@session.stream_node) %>
|
|
</span>
|
|
<span class="muted">(<%= @session.stream_node.provider %>)</span>
|
|
<% else %>
|
|
<span class="muted"><%= t("admin.sessions.ingest.none") %></span>
|
|
<% end %>
|
|
</dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.rtmp") %></dt>
|
|
<dd><code class="admin-mono admin-mono--wrap"><%= @session.rtmp_ingest_url %></code></dd>
|
|
</div>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.hls") %></dt>
|
|
<dd><code class="admin-mono admin-mono--wrap"><%= @session.hls_playback_url %></code></dd>
|
|
</div>
|
|
<% if @session.youtube_broadcast_id.present? %>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.youtube_studio") %></dt>
|
|
<dd>
|
|
<a href="https://studio.youtube.com/video/<%= @session.youtube_broadcast_id %>/livestreaming" target="_blank" rel="noopener">
|
|
<%= t("admin.sessions.show.broadcast") %>
|
|
</a>
|
|
<span class="muted">(<%= @session.youtube_broadcast_id %>)</span>
|
|
</dd>
|
|
</div>
|
|
<% end %>
|
|
<% if @session.recording %>
|
|
<div>
|
|
<dt><%= t("admin.sessions.show.fields.recording") %></dt>
|
|
<dd>
|
|
<span class="badge badge--<%= @session.recording.status == 'ready' ? 'ready' : 'paused' %>">
|
|
<%= @session.recording.status %>
|
|
</span>
|
|
<% if club %>
|
|
<%= link_to t("admin.sessions.show.open_replays"), admin_club_recordings_path(club) %>
|
|
<% end %>
|
|
</dd>
|
|
</div>
|
|
<% end %>
|
|
</dl>
|
|
</section>
|
|
</div>
|
|
|
|
<%= render "admin/sessions/links", session: @session %>
|
|
|
|
<% if @session.device_states.any? %>
|
|
<section class="panel">
|
|
<h3><%= t("admin.sessions.show.devices_title") %></h3>
|
|
<div class="admin-table-wrap">
|
|
<table class="admin-table">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t("admin.sessions.show.devices.role") %></th>
|
|
<th><%= t("admin.sessions.show.devices.network") %></th>
|
|
<th><%= t("admin.sessions.show.devices.battery") %></th>
|
|
<th><%= t("admin.sessions.show.devices.bitrate") %></th>
|
|
<th><%= t("admin.sessions.show.devices.fps") %></th>
|
|
<th><%= t("admin.sessions.show.devices.last_seen") %></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% @session.device_states.order(:device_role).each do |device| %>
|
|
<tr>
|
|
<td><%= device.device_role %></td>
|
|
<td class="muted"><%= device.network_type.presence || t("admin.common.dash") %></td>
|
|
<td class="muted"><%= device.battery_level.nil? ? t("admin.common.dash") : "#{device.battery_level}%" %></td>
|
|
<td class="muted">
|
|
<% if device.current_bitrate || device.target_bitrate %>
|
|
<%= device.current_bitrate || t("admin.common.dash") %>
|
|
<span class="muted">/ <%= device.target_bitrate || t("admin.common.dash") %></span>
|
|
<% else %>
|
|
<%= t("admin.common.dash") %>
|
|
<% end %>
|
|
</td>
|
|
<td class="muted"><%= device.fps || t("admin.common.dash") %></td>
|
|
<td class="muted"><%= admin_datetime(device.last_seen_at, with_seconds: true) %></td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
<% end %>
|
|
|
|
<section class="panel">
|
|
<h3><%= t("admin.sessions.show.events_title") %></h3>
|
|
<% if @events.any? %>
|
|
<div class="admin-table-wrap">
|
|
<table class="admin-table admin-table--events">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t("admin.sessions.show.table.type") %></th>
|
|
<th><%= t("admin.sessions.show.table.when") %></th>
|
|
<th><%= t("admin.sessions.show.table.meta") %></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% @events.each do |e| %>
|
|
<tr>
|
|
<td><span class="admin-event-type"><%= e.event_type %></span></td>
|
|
<td class="muted"><%= admin_datetime(e.occurred_at, with_seconds: true) %></td>
|
|
<td><%= admin_format_event_meta(e.metadata) %></td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<% else %>
|
|
<p class="empty"><%= t("admin.sessions.show.events_none") %></p>
|
|
<% end %>
|
|
</section>
|