app/BTCPayApp.UI/Components/AccountSwitch.razor
Dennis Reimann a239f92aed
Handle user data changes
Closes #21.
2024-07-30 23:58:54 +02:00

144 lines
5.7 KiB
Plaintext

@using BTCPayApp.CommonServer.Models
@using BTCPayApp.Core
@using BTCPayApp.Core.Auth
@using BTCPayApp.UI.Models
@inject IJSRuntime JS
@inject IAccountManager AccountManager
@inject NavigationManager NavigationManager
@if (_account != null)
{
<button class="d-inline-flex align-items-center btn btn-link text-body dropdown-toggle dropdown-toggle-no-caret p-0 gap-2" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<AccountInfo Account="@_account" />
<Icon Symbol="caret-down"/>
</button>
<ul class="dropdown-menu">
@if (_accounts.Count() > 1)
{
@foreach (var account in _accounts)
{
if (account.Id == _account.Id) continue;
<li>
<button class="d-inline-flex align-items-center dropdown-item gap-2" type="button" @onclick="() => SwitchToAccount(account)">
<AccountInfo Account="@account" />
</button>
</li>
}
<li><hr class="dropdown-divider"></li>
}
<li>
<a class="dropdown-item fw-semibold text-danger" href="@Routes.Logout">
<span>Logout @(_account.Name ?? _account.Email)</span>
</a>
</li>
</ul>
<div class="modal fade" id="AccountSwitchModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
@if (Model != null)
{
<EditForm Model="Model" OnValidSubmit="HandleValidSubmit" FormName="SwitchAccount">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5">Switch account to @Model.Email</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
<Icon Symbol="close"/>
</button>
</div>
<div class="modal-body">
@if (!string.IsNullOrEmpty(_errorMessage))
{
<Alert Type="danger">@_errorMessage</Alert>
}
<div class="form-group" hidden="@Model.RequireTwoFactor">
<label for="Password" class="form-label">Password</label>
<InputText @bind-Value="Model.Password" type="password" id="Password" autocomplete="current-password" class="form-control"/>
<ValidationMessage For="@(() => Model.Password)"/>
</div>
@if (Model.RequireTwoFactor)
{
<div class="form-group">
<label for="TwoFactorCode" class="form-label">Two Factor Code</label>
<InputText @bind-Value="Model.TwoFactorCode" type="number" id="TwoFactorCode" autocomplete="one-time-code" class="form-control hide-number-spin"/>
<ValidationMessage For="@(() => Model.TwoFactorCode)"/>
</div>
}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary w-100">
@if (_sending)
{
<LoadingIndicator />
}
else
{
<span>Sign in as @Model.Email</span>
}
</button>
</div>
</div>
</EditForm>
}
</div>
</div>
}
@code {
private BTCPayAccount? _account;
private IEnumerable<BTCPayAccount> _accounts;
private bool _sending;
private string? _errorMessage;
private LoginModel? Model { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
AccountManager.OnAccountInfoChange += OnAccountInfoChange;
_account = AccountManager.GetAccount();
_accounts = await AccountManager.GetAccounts();
}
private Task OnAccountInfoChange(object? sender, BTCPayAccount? account)
{
_account = account;
InvokeAsync(StateHasChanged);
return Task.CompletedTask;
}
private async Task SwitchToAccount(BTCPayAccount account)
{
Model = new LoginModel { Uri = account.BaseUri, Email = account.Email };
await JS.InvokeVoidAsync("Interop.openModal", "#AccountSwitchModal");
AccountManager.OnBeforeAccountChange += OnBeforeAccountChange;
}
private async Task OnBeforeAccountChange(object? sender, BTCPayAccount? previousAccount)
{
await JS.InvokeVoidAsync("Interop.closeModal", "#AccountSwitchModal");
}
private async Task HandleValidSubmit()
{
_errorMessage = null;
_sending = true;
var result = await AccountManager.Login(Model.Uri!, Model.Email!, Model.Password!, Model.TwoFactorCode);
_sending = false;
if (result.Succeeded)
{
NavigationManager.NavigateTo(Routes.Index);
}
else
{
if (result.Messages?.Contains("RequiresTwoFactor") is true)
Model.RequireTwoFactor = true;
else
_errorMessage = result.Messages?.Contains("Failed") is false
? string.Join(",", result.Messages)
: "Invalid login attempt.";
}
}
}