125 lines
4.8 KiB
Plaintext
125 lines
4.8 KiB
Plaintext
@page "/session/{SessionId:guid}/history"
|
|
@using GmRelay.Web.Services
|
|
@using Microsoft.AspNetCore.Authorization
|
|
@using Microsoft.AspNetCore.Components.Authorization
|
|
@attribute [Authorize]
|
|
@inject AuthorizedSessionService SessionService
|
|
@inject AuthenticationStateProvider AuthStateProvider
|
|
@inject NavigationManager Navigation
|
|
|
|
<PageTitle>История изменений — GM-Relay</PageTitle>
|
|
|
|
<div class="page-container">
|
|
<ul class="gm-breadcrumb animate-fade-in">
|
|
<li><a href="/">Главная</a></li>
|
|
<li><a href="/group/@groupId">Группа</a></li>
|
|
<li class="active">История изменений</li>
|
|
</ul>
|
|
|
|
<div class="page-header animate-fade-in">
|
|
<h2>📜 История изменений</h2>
|
|
@if (sessionTitle is not null)
|
|
{
|
|
<p style="color: var(--text-muted); margin-top: 0.25rem;">@sessionTitle</p>
|
|
}
|
|
</div>
|
|
|
|
@if (entries is null)
|
|
{
|
|
<div class="glass-card" style="padding: 2rem;">
|
|
<div class="skeleton skeleton-text" style="width: 50%; margin-bottom: 1.5rem;"></div>
|
|
<div class="skeleton skeleton-text" style="width: 100%; height: 2.5rem; margin-bottom: 1.5rem;"></div>
|
|
</div>
|
|
}
|
|
else if (entries.Count == 0)
|
|
{
|
|
<div class="glass-card animate-slide-up" style="padding: 2rem; text-align: center;">
|
|
<p style="color: var(--text-muted);">История изменений пуста. Значимые изменения (время, ссылка, название, участники) будут отображаться здесь.</p>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="glass-card animate-slide-up">
|
|
<div class="table-responsive">
|
|
<table class="gm-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Время</th>
|
|
<th>Актор</th>
|
|
<th>Тип изменения</th>
|
|
<th>Было</th>
|
|
<th>Стало</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var entry in entries)
|
|
{
|
|
<tr>
|
|
<td>@entry.ChangedAt.ToString("dd.MM.yyyy HH:mm") UTC</td>
|
|
<td>@entry.ActorName (@entry.ActorTelegramId)</td>
|
|
<td>
|
|
<span class="status-badge @(GetBadgeClass(entry.ChangeType))">
|
|
@GetChangeTypeLabel(entry.ChangeType)
|
|
</span>
|
|
</td>
|
|
<td style="max-width: 200px; overflow-wrap: break-word; color: var(--text-muted);">@(entry.OldValue ?? "—")</td>
|
|
<td style="max-width: 200px; overflow-wrap: break-word;">@(entry.NewValue ?? "—")</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter] public Guid SessionId { get; set; }
|
|
private List<SessionAuditLogEntry>? entries;
|
|
private string? sessionTitle;
|
|
private Guid? groupId;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
|
if (!authState.User.TryGetTelegramId(out var telegramId))
|
|
{
|
|
Navigation.NavigateTo("/access-denied");
|
|
return;
|
|
}
|
|
|
|
var session = await SessionService.GetSessionForGmAsync(SessionId, telegramId);
|
|
if (session is null)
|
|
{
|
|
Navigation.NavigateTo("/access-denied");
|
|
return;
|
|
}
|
|
|
|
sessionTitle = session.Title;
|
|
groupId = session.GroupId;
|
|
entries = await SessionService.GetSessionHistoryForGmAsync(SessionId, telegramId);
|
|
}
|
|
|
|
private string GetChangeTypeLabel(string changeType) => changeType switch
|
|
{
|
|
"Title" => "Название",
|
|
"Time" => "Время",
|
|
"Link" => "Ссылка",
|
|
"MaxPlayers" => "Лимит мест",
|
|
"Status" => "Статус",
|
|
"WaitlistPromote" => "Продвижение из листа ожидания",
|
|
"PlayerRemoved" => "Исключение игрока",
|
|
"BatchRescheduled" => "Перенос батча",
|
|
"Cancelled" => "Отмена",
|
|
_ => changeType
|
|
};
|
|
|
|
private string GetBadgeClass(string changeType) => changeType switch
|
|
{
|
|
"Cancelled" or "PlayerRemoved" => "status-danger",
|
|
"WaitlistPromote" => "status-success",
|
|
"BatchRescheduled" or "Time" => "status-warning",
|
|
_ => "status-info"
|
|
};
|
|
}
|