211 lines
9.5 KiB
Plaintext
211 lines
9.5 KiB
Plaintext
@using RpgRoller.Components.Pages.HomeControls
|
|
<div class="@AppCssClass">
|
|
<p class="sr-only" aria-live="polite">@LiveAnnouncement</p>
|
|
|
|
@if (HasHealthIssue)
|
|
{
|
|
<section class="health-banner" role="alert">
|
|
<div>
|
|
<strong>API currently unavailable.</strong>
|
|
<p>@HealthIssueMessage</p>
|
|
</div>
|
|
<button type="button" @onclick="RetryAfterHealthIssueAsync">Retry</button>
|
|
</section>
|
|
}
|
|
|
|
<div class="workspace-shell">
|
|
<AppHeader
|
|
User="User"
|
|
ShowCampaign="true"
|
|
CampaignName="@SelectedCampaignName"
|
|
ShowConnectionState="true"
|
|
ConnectionStateLabel="@ConnectionStateLabel"
|
|
ConnectionStateCssClass="@ConnectionStateCssClass"
|
|
IsMenuOpen="IsScreenMenuOpen"
|
|
MenuButtonId="workspace-screen-menu-button"
|
|
MenuId="workspace-screen-menu"
|
|
MenuItems="HeaderMenuItems"
|
|
ToggleMenuRequested="ToggleScreenMenu"
|
|
LogoutRequested="LogoutAsync"/>
|
|
|
|
@if (IsPlayScreen)
|
|
{
|
|
<main class="play-screen @(MobilePanel == "log" ? "mobile-log" : "mobile-character")">
|
|
<CharacterPanel
|
|
IsCampaignDataLoading="IsCampaignDataLoading"
|
|
SelectedCampaign="PlaySelectedCampaign"
|
|
SelectedCharacterId="PlaySelectedCharacterId"
|
|
SelectedCharacter="PlaySelectedCharacter"
|
|
IsMutating="IsMutating"
|
|
SelectedCharacterSkills="PlaySelectedCharacterSkills"
|
|
SelectedCharacterSkillGroups="PlaySelectedCharacterSkillGroups"
|
|
SelectedCampaignRulesetId="@(PlaySelectedCampaign?.RulesetId ?? string.Empty)"
|
|
RollVisibility="RollVisibility"
|
|
RollVisibilityChanged="OnRollVisibilityChanged"
|
|
OwnerLabel="OwnerLabel"
|
|
SkillDefinitionLabel="SkillDefinitionLabel"
|
|
CanEditCharacter="CanEditCharacter"
|
|
CanEditSkill="CanEditSkill"
|
|
CharacterSelected="SelectCharacterAsync"
|
|
EditCharacterRequested="OpenEditCharacterModal"
|
|
SkillCreated="OnSkillCreatedAsync"
|
|
SkillUpdated="OnSkillUpdatedAsync"
|
|
SkillGroupCreated="OnSkillGroupCreatedAsync"
|
|
SkillGroupUpdated="OnSkillGroupUpdatedAsync"
|
|
SkillDeleted="OnSkillDeletedAsync"
|
|
SkillGroupDeleted="OnSkillGroupDeletedAsync"
|
|
ErrorOccurred="OnCharacterPanelErrorAsync"
|
|
RollRequested="RollSkillAsync"/>
|
|
|
|
<CampaignLogPanel
|
|
IsCampaignDataLoading="IsCampaignDataLoading"
|
|
CampaignLog="PlayVisibleCampaignLog"
|
|
ExpandedRollId="ExpandedCampaignLogRollId"
|
|
FreshRollId="FreshCampaignLogRollId"
|
|
ToggleRollDetailRequested="ToggleRollDetailAsync"
|
|
ResolveRollDetail="ResolveRollDetail"
|
|
IsRollDetailLoading="IsRollDetailLoading"
|
|
GetRollDetailError="GetRollDetailError"/>
|
|
</main>
|
|
<nav class="mobile-bottom-nav" aria-label="Play panel selector">
|
|
<button type="button" class="switch @(MobilePanel == "character" ? "active" : string.Empty)"
|
|
@onclick="SetMobilePanelCharacterAsync">Character
|
|
</button>
|
|
<button type="button" class="switch @(MobilePanel == "log" ? "active" : string.Empty)"
|
|
@onclick="SetMobilePanelLogAsync">Log
|
|
</button>
|
|
</nav>
|
|
}
|
|
else if (IsManagementScreen)
|
|
{
|
|
<CampaignManagementPanel
|
|
Campaigns="Campaigns"
|
|
SelectedCampaignId="SelectedCampaignId"
|
|
SelectedCampaign="SelectedCampaign"
|
|
Rulesets="Rulesets"
|
|
IsMutating="IsMutating"
|
|
OwnerLabel="OwnerLabel"
|
|
CanEditCharacter="CanEditCharacter"
|
|
CanDeleteCharacter="CanDeleteCharacter"
|
|
CanDeleteCampaign="CanDeleteSelectedCampaign"
|
|
CampaignSelectionChanged="OnCampaignSelectionChangedAsync"
|
|
CampaignCreated="OnCampaignCreatedAsync"
|
|
DeleteCampaignRequested="DeleteSelectedCampaignAsync"
|
|
CreateCharacterRequested="OpenCreateCharacterModal"
|
|
EditCharacterRequested="OpenEditCharacterModal"
|
|
DeleteCharacterRequested="DeleteCharacterAsync"/>
|
|
}
|
|
else if (IsAdminScreen)
|
|
{
|
|
<main class="management-screen">
|
|
@if (IsCurrentUserAdmin)
|
|
{
|
|
<section class="card">
|
|
<div class="section-head">
|
|
<h2>Database</h2>
|
|
</div>
|
|
<p class="muted">Download the current SQLite file for backup or offline inspection.</p>
|
|
<div class="management-actions">
|
|
<a class="action-link" href="@AdminDatabaseDownloadUrl" download>Download SQLite database</a>
|
|
</div>
|
|
</section>
|
|
}
|
|
<section class="card">
|
|
<div class="section-head">
|
|
<h2>User Management</h2>
|
|
</div>
|
|
@if (IsAdminDataLoading)
|
|
{
|
|
<p class="empty">Loading users...</p>
|
|
}
|
|
else if (!IsCurrentUserAdmin)
|
|
{
|
|
<p class="empty">Admin role is required to manage users.</p>
|
|
}
|
|
else if (AdminUsers.Count == 0)
|
|
{
|
|
<p class="empty">No users found.</p>
|
|
}
|
|
else
|
|
{
|
|
<ul class="management-list">
|
|
@foreach (var user in AdminUsers)
|
|
{
|
|
<li>
|
|
<div>
|
|
<strong>@user.Username</strong>
|
|
<p class="muted">@user.DisplayName</p>
|
|
<p class="muted">Roles: @(user.Roles.Count == 0 ? "none" : string.Join(", ", user.Roles))</p>
|
|
</div>
|
|
<div class="skill-chip-actions">
|
|
<button type="button"
|
|
class="chip-button"
|
|
disabled="@(IsMutating || user.Id == User?.Id)"
|
|
@onclick="() => ToggleAdminRoleAsync(user)">
|
|
<span aria-hidden="true" class="emoji">🛡️</span>
|
|
<span class="sr-only">Toggle admin role for @user.Username</span>
|
|
</button>
|
|
<button type="button"
|
|
class="chip-button"
|
|
disabled="@(IsMutating || user.Id == User?.Id)"
|
|
@onclick="() => DeleteUserAsync(user)">
|
|
<span aria-hidden="true" class="emoji">🗑️</span>
|
|
<span class="sr-only">Delete user @user.Username</span>
|
|
</button>
|
|
</div>
|
|
</li>
|
|
}
|
|
</ul>
|
|
}
|
|
</section>
|
|
</main>
|
|
}
|
|
</div>
|
|
|
|
@if (Toasts.Count > 0)
|
|
{
|
|
<div class="toast-stack" aria-live="polite" aria-atomic="false">
|
|
@foreach (var toast in Toasts)
|
|
{
|
|
<div class="toast @(toast.IsError ? "error" : "success")" role="status">
|
|
<p>@toast.Message</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<CharacterFormModal
|
|
Visible="ShowCreateCharacterModal"
|
|
Title="Create Character"
|
|
SubmitLabel="Create Character"
|
|
NameInputId="character-create-name"
|
|
CampaignInputId="character-create-campaign"
|
|
OwnerUsernameInputId="character-create-owner"
|
|
InitialModel="CreateCharacterInitialModel"
|
|
FormVersion="CreateCharacterFormVersion"
|
|
EditingCharacterId="null"
|
|
CampaignOptions="CharacterCampaignOptions"
|
|
IsMutating="IsMutating"
|
|
AllowOwnerEdit="false"
|
|
AvailableUsernames="KnownUsernames"
|
|
CharacterSaved="OnCharacterCreatedAsync"
|
|
CancelRequested="CloseCharacterModals"/>
|
|
|
|
<CharacterFormModal
|
|
Visible="ShowEditCharacterModal"
|
|
Title="Edit Character"
|
|
SubmitLabel="Save Character"
|
|
NameInputId="character-edit-name"
|
|
CampaignInputId="character-edit-campaign"
|
|
OwnerUsernameInputId="character-edit-owner"
|
|
InitialModel="EditCharacterInitialModel"
|
|
FormVersion="EditCharacterFormVersion"
|
|
EditingCharacterId="EditingCharacterId"
|
|
CampaignOptions="CharacterCampaignOptions"
|
|
IsMutating="IsMutating"
|
|
AllowOwnerEdit="CanEditCharacterOwner"
|
|
AvailableUsernames="KnownUsernames"
|
|
CharacterSaved="OnCharacterUpdatedAsync"
|
|
CancelRequested="CloseCharacterModals"/>
|