109 lines
4.1 KiB
Plaintext
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;
|
|
}
|
|
}
|
|
}
|