Add admin roles, user management, and campaign deletion

This commit is contained in:
2026-02-26 17:15:10 +01:00
parent 3026221cd6
commit 2e2f364c5e
26 changed files with 1127 additions and 31 deletions

View File

@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using RpgRoller.Contracts;
using RpgRoller.Domain;
namespace RpgRoller.Components.Pages;
@@ -231,6 +232,12 @@ public partial class Workspace : IAsyncDisposable
return SwitchScreenAsync("management");
}
private async Task OpenAdminAsync()
{
IsScreenMenuOpen = false;
await AdminRequested.InvokeAsync();
}
private async Task SetMobilePanelAsync(string panel)
{
MobilePanel = string.Equals(panel, "log", StringComparison.OrdinalIgnoreCase) ? "log" : "character";
@@ -290,7 +297,7 @@ public partial class Workspace : IAsyncDisposable
EditCharacterInitialModel = new()
{
Name = character.Name,
CampaignId = character.CampaignId.ToString(),
CampaignId = character.CampaignId?.ToString() ?? string.Empty,
OwnerUsername = string.Empty
};
@@ -325,6 +332,34 @@ public partial class Workspace : IAsyncDisposable
SetStatus("Character updated.", false);
}
private async Task DeleteSelectedCampaignAsync()
{
if (SelectedCampaign is null || IsMutating || !CanDeleteSelectedCampaign)
return;
var confirmed = await JS.InvokeAsync<bool>("confirm", $"Delete campaign '{SelectedCampaign.Name}'?");
if (!confirmed)
return;
IsMutating = true;
try
{
_ = await ApiClient.RequestAsync<bool>("DELETE", $"/api/campaigns/{SelectedCampaign.Id}");
await ReloadCampaignsAsync(null);
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
SetStatus("Campaign deleted.", false);
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsMutating = false;
}
}
private async Task SelectCharacterAsync(Guid characterId)
{
SelectedCharacterId = characterId;
@@ -577,7 +612,7 @@ public partial class Workspace : IAsyncDisposable
return skill.DiceRollDefinition;
var fumbleLabel = skill.AllowFumble ? "fumble on" : "fumble off";
return $"{skill.DiceRollDefinition} | wild {skill.WildDice}, {fumbleLabel}";
return $"{skill.DiceRollDefinition}, wild {skill.WildDice}, {fumbleLabel}";
}
private string RollerLabel(CampaignLogEntry entry)
@@ -728,6 +763,9 @@ public partial class Workspace : IAsyncDisposable
[Parameter]
public EventCallback<string?> LoggedOut { get; set; }
[Parameter]
public EventCallback AdminRequested { get; set; }
private string? SelectedCampaignName => SelectedCampaign?.Name;
private CharacterSummary? SelectedCharacter =>
@@ -736,6 +774,12 @@ public partial class Workspace : IAsyncDisposable
private bool IsCurrentUserGm =>
SelectedCampaign is not null && User is not null && SelectedCampaign.Gm.Id == User.Id;
private bool IsCurrentUserAdmin =>
User is not null && User.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
private bool CanDeleteSelectedCampaign =>
SelectedCampaign is not null && User is not null && (SelectedCampaign.Gm.Id == User.Id || IsCurrentUserAdmin);
private bool IsSelectedCampaignD6 =>
string.Equals(SelectedCampaign?.RulesetId, "d6", StringComparison.OrdinalIgnoreCase);