Skip to content

Commit

Permalink
Move User Selector from Home tab to Settings tab
Browse files Browse the repository at this point in the history
Closes #55.
  • Loading branch information
dennisreimann committed Dec 14, 2024
1 parent e1b3443 commit d560502
Show file tree
Hide file tree
Showing 13 changed files with 575 additions and 543 deletions.
17 changes: 0 additions & 17 deletions BTCPayApp.UI/Components/AccountInfo.razor

This file was deleted.

144 changes: 0 additions & 144 deletions BTCPayApp.UI/Components/AccountSwitch.razor

This file was deleted.

12 changes: 0 additions & 12 deletions BTCPayApp.UI/Components/AccountSwitch.razor.css

This file was deleted.

32 changes: 32 additions & 0 deletions BTCPayApp.UI/Components/UserInfo.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div class="user-info d-flex align-items-center gap-2">
@if (!string.IsNullOrEmpty(ImageUrl))
{
<img src="@ImageUrl" alt="@DisplayName" class="profile-picture" />
}
else
{
<Icon Symbol="nav-account" class="profile-picture" />
}
<div class="text-start">
@if (string.IsNullOrEmpty(Name))
{
<h5 class="mb-0 fw-semibold">@Email</h5>
}
else
{
<h5 class="mb-1 fw-semibold">@Name</h5>
<span class="text-muted">@Email</span>
}
</div>
</div>

@code {
[Parameter, EditorRequired]
public string Email { get; set; } = null!;
[Parameter]
public string? Name { get; set; }
[Parameter]
public string? ImageUrl { get; set; }

private string DisplayName => Name ?? Email;
}
146 changes: 146 additions & 0 deletions BTCPayApp.UI/Components/UserSwitch.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
@using BTCPayApp.Core
@using BTCPayApp.Core.Auth
@using BTCPayApp.UI.Models
@using BTCPayServer.Client.Models
@inject IJSRuntime JS
@inject IAccountManager AccountManager
@inject NavigationManager NavigationManager
@implements IDisposable

<div class="d-inline-flex align-items-center p-0 gap-3">
@if (false && Users?.Count() > 1)
{
<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">
<UserInfo Email="@_account!.Email" Name="@_account.Name" ImageUrl="@_account.ImageUrl" />
<Icon Symbol="caret-down"/>
</button>
<ul class="dropdown-menu">
@foreach (var user in Users)
{
if (user.UserId == _account.Id) continue;
<li>
<button class="d-inline-flex align-items-center dropdown-item gap-2" type="button" @onclick="() => SwitchToUser(user)">
<UserInfo Email="@user.Email" Name="@user.Name" ImageUrl="@user.ImageUrl" />
</button>
</li>
}
</ul>
<div class="modal fade" id="UserSwitchModal" 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="cross"/>
</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>
}
else if (_account != null)
{
<UserInfo Email="@_account.Email" Name="@_account.Name" ImageUrl="@_account.ImageUrl" />
}
</div>

@code {
private BTCPayAccount? _account;
private bool _sending;
private string? _errorMessage;
private LoginModel? Model { get; set; }

[Parameter]
public IEnumerable<StoreUserData>? Users { get; set; }

protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();

AccountManager.OnAccountInfoChange += OnAccountInfoChange;

_account = AccountManager.GetAccount();
}

public void Dispose()
{
AccountManager.OnAccountInfoChange -= OnAccountInfoChange;
}

private async Task OnAccountInfoChange(object? sender, BTCPayAccount? account)
{
_account = account;
await InvokeAsync(StateHasChanged);
}

private async Task SwitchToUser(StoreUserData user)
{
// Model = new LoginModel { Uri = account.BaseUri, Email = account.Email };
await JS.InvokeVoidAsync("Interop.openModal", "#UserSwitchModal");
AccountManager.OnBeforeAccountChange += OnBeforeAccountChange;
}

private async Task OnBeforeAccountChange(object? sender, BTCPayAccount? previousAccount)
{
await JS.InvokeVoidAsync("Interop.closeModal", "#UserSwitchModal");
}

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)
{
AccountManager.OnBeforeAccountChange -= OnBeforeAccountChange;
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.";
}
}
}
37 changes: 37 additions & 0 deletions BTCPayApp.UI/Components/UserSwitch.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.dropdown-menu {
margin-left: -1rem !important;
}

.dropdown-item {
--btcpay-dropdown-item-padding-y: var(--btcpay-space-s);
}

::deep .profile-picture {
--profile-picture-size: 3rem;
margin-right: var(--btcpay-space-s);
}


.user {

display: flex;
align-items: center;
justify-content: space-between;
gap: var(--btcpay-space-m);
color: var(--btcpay-nav-link-color);
font-weight: var(--btcpay-font-weight-semibold);
}

.user:hover {
color: var(--btcpay-nav-link-hover-color);
}

.user h5 {
font-weight: var(--btcpay-font-weight-semibold);
margin-bottom: var(--btcpay-space-xs);
}

.user ::deep .icon-caret-right {
margin-left: auto;
color: var(--btcpay-body-text-muted);
}
Loading

0 comments on commit d560502

Please sign in to comment.