Files
GmRelayBot/src/GmRelay.Web/Components/Pages/GroupCompletedSessions.razor
T

109 lines
4.1 KiB
Plaintext

@page "/group/{GroupId:guid}/completed"
@using GmRelay.Web.Services
@using GmRelay.Web.Services.Portfolio
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@attribute [Authorize]
@inject AuthorizedPortfolioService PortfolioService
@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>
<p style="color: var(--text-muted); margin-top: 0.25rem;">
Добавьте проведённые игры в портфолио — система создаст черновик и предложит заполнить детали.
</p>
</div>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="gm-alert gm-alert-danger" style="margin-bottom: 1rem;">
⚠️ @errorMessage
</div>
}
@if (sessions is null)
{
<div class="glass-card" style="padding: 2rem;">
<div class="skeleton skeleton-text" style="width: 70%; margin-bottom: 1rem;"></div>
<div class="skeleton skeleton-text" style="width: 55%; margin-bottom: 0.75rem;"></div>
<div class="skeleton skeleton-text" style="width: 60%;"></div>
</div>
}
else if (sessions.Count == 0)
{
<div class="glass-card animate-slide-up">
<div class="empty-state">
<div class="empty-state-icon">📭</div>
<div class="empty-state-title">Проведённых сессий пока нет</div>
<p class="empty-state-text">Как только сессии закончатся, они появятся здесь и их можно будет добавить в портфолио.</p>
</div>
</div>
}
else
{
<div class="portfolio-completed-list animate-slide-up">
@foreach (var session in sessions)
{
<div class="portfolio-completed-row">
<div class="portfolio-completed-info">
<a href="/session/@session.Id/history" class="portfolio-completed-title">@session.Title</a>
<span class="portfolio-completed-date">@session.ScheduledAt.FormatMoscow()</span>
</div>
<div class="portfolio-completed-actions">
<button type="button" class="btn-gm btn-gm-primary" disabled="@(creatingDraftSessionId == session.Id)" @onclick="() => AddToPortfolio(session.Id)">
@(creatingDraftSessionId == session.Id ? "⏳..." : "➕ Добавить в портфолио")
</button>
</div>
</div>
}
</div>
}
</div>
@code {
[Parameter] public Guid GroupId { get; set; }
private IReadOnlyList<PortfolioSessionOption>? sessions;
private Guid? creatingDraftSessionId;
private string? errorMessage;
protected override async Task OnInitializedAsync()
{
sessions = await PortfolioService.GetCompletedSessionsForCurrentUserAsync(GroupId);
}
private async Task AddToPortfolio(Guid sessionId)
{
errorMessage = null;
creatingDraftSessionId = sessionId;
try
{
var portfolioId = await PortfolioService.CreateDraftForCurrentUserAsync(GroupId, sessionId);
Navigation.NavigateTo($"/portfolio/manage/{portfolioId}");
}
catch (SessionAccessDeniedException)
{
Navigation.NavigateTo("/access-denied");
}
catch (Exception ex)
{
errorMessage = "Не удалось создать черновик: " + ex.Message;
}
finally
{
creatingDraftSessionId = null;
}
}
}