1
0
mirror of synced 2024-12-05 03:17:58 +01:00
TaikoLocalServer/TaikoWebUI/Components/UserCard.razor

251 lines
10 KiB
Plaintext

@using System.Text.Json
@using TaikoWebUI.Pages.Dialogs;
@inject Utilities.StringUtil StringUtil;
@inject IDialogService DialogService;
@inject AuthService AuthService;
@inject HttpClient Client
@inject NavigationManager NavigationManager
@if (User is not null)
{
<MudCard Outlined="true">
<MudCardHeader>
<CardHeaderContent>
<div style="display:flex;flex-wrap:wrap;align-items:center;gap:5px;">
@if (UserSetting is not null)
{
<MudText Typo="Typo.h6" Style="font-weight:bold;word-break:break-all">@UserSetting?.MyDonName</MudText>
} else
{
<MudSkeleton Width="35%" Height="32px" />
}
@if (AuthService.LoginRequired && User?.IsAdmin == true)
{
<MudChip Variant="Variant.Outlined" Color="Color.Info" Size="Size.Small" Icon="@Icons.Material.TwoTone.AdminPanelSettings">@Localizer["Admin"]</MudChip>
}
</div>
<MudText Typo="Typo.caption">@Localizer["User"] BAID: @User?.Baid</MudText>
</CardHeaderContent>
<CardHeaderActions>
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Dense="true" AnchorOrigin="Origin.BottomLeft"
TransformOrigin="Origin.TopLeft" Size="Size.Small">
<MudMenuItem Icon="@Icons.Material.Filled.QrCode"
OnClick="@(_ => ShowQrCode(User))"
OnTouch="@(_ => ShowQrCode(User))"
IconColor="@Color.Primary">
@Localizer["Show QR Code"]
</MudMenuItem>
<MudDivider />
<MudMenuItem Icon="@Icons.Material.Filled.FeaturedPlayList"
Href="@($"Users/{User.Baid}/AccessCode")"
IconColor="@Color.Primary">
@Localizer["Access Codes"]
</MudMenuItem>
<MudDivider />
@if (AuthService.OnlyAdmin || AuthService.LoginRequired)
{
<MudMenuItem Icon="@Icons.Material.Filled.Lock"
Href="@($"/ChangePassword")"
IconColor="@Color.Primary">
@Localizer["Change Password"]
</MudMenuItem>
<MudDivider />
}
@if (AuthService.LoginRequired && AuthService.IsAdmin)
{
<MudMenuItem Icon="@Icons.Material.Filled.Password"
OnClick="@(_ => GenerateInviteCode(User.Baid))"
OnTouch="@(_ => GenerateInviteCode(User.Baid))"
IconColor="@Color.Primary">
@Localizer["Generate Invite Code"]
</MudMenuItem>
<MudDivider />
}
@if (AuthService.LoginRequired && AuthService.IsAdmin)
{
<MudMenuItem Icon="@Icons.Material.Filled.LockReset"
OnClick="@(_ => ResetPassword(User))"
OnTouch="@(_ => ResetPassword(User))"
IconColor="@Color.Primary">
@Localizer["Unregister"]
</MudMenuItem>
<MudDivider />
}
@if (AuthService.AllowUserDelete)
{
<MudMenuItem Icon="@Icons.Material.Filled.Delete"
OnClick="@(_ => DeleteUser(User))"
OnTouch="@(_ => DeleteUser(User))"
IconColor="@Color.Error">
@Localizer["Delete User"]
</MudMenuItem>
}
</MudMenu>
</CardHeaderActions>
</MudCardHeader>
<MudCardContent>
<MudText Typo="Typo.body2" Style="font-weight:bold">@Localizer["Access Code"]</MudText>
<MudText Style="font-family:monospace;overflow:hidden;overflow-x:scroll">
@if (User.AccessCodes.Count > 0)
{
@foreach (var digitGroup in StringUtil.SplitIntoGroups(User.AccessCodes[0], 4))
{
<span class="mr-2">@digitGroup</span>
}
} else
{
<span class="mr-2">@Localizer["N/A"]</span>
}
</MudText>
@if (User.AccessCodes.Count > 1)
{
<MudText Typo="Typo.caption">... @Localizer["and"] @(User.AccessCodes.Count - 1) @Localizer["other access code(s)"]</MudText>
}
else
{
// Empty line to keep the layout consistent
<MudText Typo="Typo.caption"> </MudText>
}
</MudCardContent>
<MudCardActions>
<MudStack Row="true" Style="width:100%" Spacing="4" Justify="Justify.FlexEnd">
<MudButton Href="@($"Users/{User.Baid}/Profile")"
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Edit"
Color="Color.Primary">
@Localizer["edit profile"]
</MudButton>
<MudMenu Size="Size.Small"
Dense="true"
Color="Color.Primary"
Label="@Localizer["View Play Data"]"
StartIcon="@Icons.Material.Filled.EmojiEvents"
EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
FullWidth="true"
AnchorOrigin="Origin.BottomCenter"
TransformOrigin="Origin.TopCenter">
<MudMenuItem Href="@($"Users/{User.Baid}/HighScores")">@Localizer["High Scores"]</MudMenuItem>
<MudMenuItem Href="@($"Users/{User.Baid}/PlayHistory")">@Localizer["Play History"]</MudMenuItem>
<MudMenuItem Href="@($"Users/{User.Baid}/Songs")">@Localizer["Song List"]</MudMenuItem>
<MudMenuItem Href="@($"Users/{User.Baid}/DaniDojo")">@Localizer["Dani Dojo"]</MudMenuItem>
</MudMenu>
</MudStack>
</MudCardActions>
</MudCard>
}
@code {
[Parameter] public User? User { get; set; }
[Parameter] public UserSetting? UserSetting { get; set; }
protected override async Task OnInitializedAsync()
{
if (User is not null)
{
UserSetting = await Client.GetFromJsonAsync<UserSetting>($"api/UserSettings/{User.Baid}");
}
}
private Task ShowQrCode(User user)
{
var parameters = new DialogParameters
{
["user"] = user
};
var options = new DialogOptions { DisableBackdropClick = true };
DialogService.Show<UserQrCodeDialog>(Localizer["QR Code"], parameters, options);
return Task.CompletedTask;
}
private async Task ResetPassword(User user)
{
var options = new DialogOptions { DisableBackdropClick = true };
if (AuthService.LoginRequired && !AuthService.IsAdmin)
{
await DialogService.ShowMessageBox(
Localizer["Error"],
"Only admin can reset password.",
Localizer["Dialog OK"], null, null, options);
return;
}
var parameters = new DialogParameters
{
["user"] = user
};
var dialog = await DialogService.ShowAsync<ResetPasswordConfirmDialog>(Localizer["Reset Password"], parameters, options);
await dialog.Result;
}
private async Task DeleteUser(User user)
{
var options = new DialogOptions { DisableBackdropClick = true };
if (!AuthService.AllowUserDelete)
{
await DialogService.ShowMessageBox(
Localizer["Error"],
"User deletion is disabled by admin.",
Localizer["Dialog OK"], null, null, options);
return;
}
var parameters = new DialogParameters
{
["user"] = user
};
var dialog = await DialogService.ShowAsync<UserDeleteConfirmDialog>(Localizer["Delete User"], parameters, options);
var result = await dialog.Result;
if (result.Canceled) return;
if (user.Baid == AuthService.GetLoggedInBaid())
{
await AuthService.Logout();
}
NavigationManager.NavigateTo("/Users");
}
private async Task GenerateInviteCode(uint baid)
{
var request = new GenerateOtpRequest
{
Baid = baid
};
var responseMessage = await Client.PostAsJsonAsync("api/Auth/GenerateOtp", request);
if (!responseMessage.IsSuccessStatusCode)
{
await DialogService.ShowMessageBox(
Localizer["Error"],
Localizer["Unknown Error"],
Localizer["Dialog OK"], null, null, new DialogOptions { DisableBackdropClick = true });
return;
}
var responseContent = await responseMessage.Content.ReadAsStringAsync();
var responseJson = JsonSerializer.Deserialize<Dictionary<string, string>>(responseContent);
if (responseJson == null)
{
await DialogService.ShowMessageBox(
Localizer["Error"],
Localizer["Unknown Error"],
Localizer["Dialog OK"], null, null, new DialogOptions { DisableBackdropClick = true });
return;
}
var otp = responseJson["otp"];
var parameters = new DialogParameters
{
["otp"] = otp
};
var options = new DialogOptions { DisableBackdropClick = true };
await DialogService.ShowAsync<OTPDialog>(Localizer["Invite Code"], parameters, options);
}
}