feat: implement Blazor web interface for GM session management
Deploy Telegram Bot / deploy (push) Has been cancelled
Deploy Telegram Bot / deploy (push) Has been cancelled
- Created GmRelay.Web project (Blazor Server) - Created GmRelay.Shared library for domain models and rendering - Refactored GmRelay.Bot to use the Shared library - Integrated Telegram Login widget with server-side HMAC verification - Added Dashboard, Group Details, and Edit Session pages - Enabled bot notifications and in-place message updates from web actions - Updated .NET Aspire orchestration and Docker Compose configuration
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
@page "/session/edit/{SessionId:guid}"
|
||||
@using GmRelay.Web.Services
|
||||
@using GmRelay.Shared.Domain
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@attribute [Authorize]
|
||||
@inject SessionService SessionService
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
<PageTitle>Edit Session - GM-Relay</PageTitle>
|
||||
|
||||
<div class="container mt-4">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/">Dashboard</a></li>
|
||||
<li class="breadcrumb-item active">Edit Session</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<h2>Edit Session</h2>
|
||||
|
||||
@if (session == null)
|
||||
{
|
||||
<p>Loading session details...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card shadow-sm mt-4">
|
||||
<div class="card-body">
|
||||
<EditForm Model="@model" OnValidSubmit="HandleSubmit">
|
||||
<div class="mb-3">
|
||||
<label class="form-label font-weight-bold">Game Title</label>
|
||||
<InputText @bind-Value="model.Title" class="form-control" placeholder="e.g. D&D 5e: Dragon's Hoard" />
|
||||
<div class="form-text">Changing this will update all sessions in the same batch.</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label font-weight-bold">Scheduled Time (Moscow UTC+3)</label>
|
||||
<input type="datetime-local" @bind="model.ScheduledAtLocal" class="form-control" />
|
||||
<div class="form-text">Current: @session.ScheduledAt.FormatMoscow()</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label font-weight-bold">Join Link</label>
|
||||
<InputText @bind-Value="model.JoinLink" class="form-control" placeholder="Discord or VTT link" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-success" disabled="@isSubmitting">
|
||||
@(isSubmitting ? "Saving..." : "Save Changes")
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary ms-2" @onclick="GoBack">Cancel</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
<div class="alert alert-danger mt-3">@errorMessage</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public Guid SessionId { get; set; }
|
||||
private WebSession? session;
|
||||
private SessionEditModel model = new();
|
||||
private bool isSubmitting = false;
|
||||
private string? errorMessage;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
session = await SessionService.GetSessionAsync(SessionId);
|
||||
if (session != null)
|
||||
{
|
||||
model.Title = session.Title;
|
||||
// Convert UTC to Moscow for the picker
|
||||
model.ScheduledAtLocal = session.ScheduledAt.ToMoscow();
|
||||
model.JoinLink = session.JoinLink;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleSubmit()
|
||||
{
|
||||
isSubmitting = true;
|
||||
errorMessage = null;
|
||||
|
||||
try
|
||||
{
|
||||
// The value from <input type="datetime-local"> is considered as "unspecified" or local to browser.
|
||||
// We treat it as Moscow time (UTC+3) and convert to UTC.
|
||||
var utcTime = new DateTimeOffset(model.ScheduledAtLocal, TimeSpan.FromHours(3)).ToUniversalTime().UtcDateTime;
|
||||
|
||||
await SessionService.UpdateSessionAsync(SessionId, model.Title, utcTime, model.JoinLink);
|
||||
Navigation.NavigateTo($"/group/{session!.GroupId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = "Failed to save changes: " + ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
isSubmitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void GoBack() => Navigation.NavigateTo("/");
|
||||
|
||||
public class SessionEditModel
|
||||
{
|
||||
public string Title { get; set; } = "";
|
||||
public DateTime ScheduledAtLocal { get; set; } = DateTime.Now;
|
||||
public string JoinLink { get; set; } = "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user