app/BTCPayApp.UI/Pages/CreateStorePage.razor
2024-07-30 10:54:54 +02:00

165 lines
5.5 KiB
Plaintext

@attribute [Route(Routes.CreateStore)]
@layout SimpleLayout
@using BTCPayApp.CommonServer.Models
@using BTCPayApp.Core.Auth
@using BTCPayApp.UI.Components.Layout
@using BTCPayApp.UI.Features
@using BTCPayServer.Client.Models
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@inject IAccountManager AccountManager
@inject NavigationManager NavigationManager
@inject IDispatcher Dispatcher
<PageTitle>Create a new store</PageTitle>
<SectionContent SectionId="_Layout.Top">
<Titlebar BackLink="@BackUrl">
<SectionContent SectionId="Titlebar.End">
<NavLink class="btn-icon" href="@Routes.Dashboard">
<Icon Symbol="close"/>
</NavLink>
</SectionContent>
</Titlebar>
</SectionContent>
<SectionContent SectionId="_Layout.MainTop">
<InstanceLogo/>
<h1>Create a new store</h1>
@if (!string.IsNullOrEmpty(_errorMessage))
{
<Alert Type="danger">@_errorMessage</Alert>
}
</SectionContent>
@if (_loading)
{
<div class="p-3 text-center">
<LoadingIndicator/>
</div>
}
else if (_data is not null)
{
<p class="lead text-secondary mb-4">Create a store to begin accepting payments.</p>
<ValidationEditContext @ref="_validationEditContext" Model="Model" OnValidSubmit="HandleValidSubmit" FormName="CreateStore" method="post">
<div class="form-group">
<label for="Name" class="form-label" data-required>Name</label>
<InputText @bind-Value="Model.Name" id="Name" class="form-control"/>
<ValidationMessage For="@(() => Model.Name)"/>
</div>
<div class="form-group">
<label for="DefaultCurrency" class="form-label" data-required>Default Currency</label>
<InputText @bind-Value="Model.DefaultCurrency" id="DefaultCurrency" class="form-control"/>
<ValidationMessage For="@(() => Model.DefaultCurrency)"/>
</div>
<div class="form-group">
<label for="PreferredExchange" class="form-label" data-required>Preferred Exchange</label>
<InputSelect @bind-Value="Model.PreferredExchange" id="PreferredExchange" class="form-select">
@foreach (var e in _data.Exchanges)
{
<option value="@e.Key">@e.Value</option>
}
</InputSelect>
<div class="form-text mt-2 only-for-js">The recommended price source gets chosen based on the default currency.</div>
<ValidationMessage For="@(() => Model.PreferredExchange)"/>
</div>
<button class="btn btn-primary w-100" type="submit" data-testid="CreateStoreButton" disabled="@(_validationEditContext.Invalid || _sending)">
@if (_sending)
{
<LoadingIndicator />
}
else
{
<span>Create Store</span>
}
</button>
</ValidationEditContext>
}
@code {
[SupplyParameterFromQuery]
public string? BackUrl { get; set; }
private bool _loading;
private bool _sending;
private string? _errorMessage;
private CreateStoreData? _data;
private ValidationEditContext? _validationEditContext;
CreateStoreModel Model { get; set; } = new();
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
try
{
_loading = true;
_errorMessage = null;
_data = await AccountManager.GetClient().GetCreateStore();
Model.DefaultCurrency = _data.DefaultCurrency;
Model.PreferredExchange = _data.RecommendedExchangeId;
}
catch (Exception e)
{
_data = null;
_errorMessage = e.InnerException?.Message ?? e.Message;
}
finally
{
_loading = false;
}
}
private async Task HandleValidSubmit()
{
_sending = true;
_errorMessage = null;
var request = new CreateStoreRequest
{
Name = Model.Name,
DefaultCurrency = Model.DefaultCurrency
};
try
{
var store = await AccountManager.GetClient().CreateStore(request);
if (store != null)
{
// set rate configuration
var rateConfig = new StoreRateConfiguration { PreferredSource = Model.PreferredExchange };
await AccountManager.GetClient().UpdateStoreRateConfiguration(store.Id, rateConfig);
// refresh store info and set id of new store
await AccountManager.CheckAuthenticated(true);
var result = await AccountManager.SetCurrentStoreId(store.Id);
var resultMessage = result.Messages != null ? string.Join(",", result.Messages) : null;
if (result.Succeeded)
{
var storeInfo = AccountManager.GetUserStore(store.Id);
Dispatcher.Dispatch(new StoreState.SetStoreInfo(storeInfo));
NavigationManager.NavigateTo(Routes.Dashboard);
}
else
{
_errorMessage = resultMessage ?? "Store creation failed.";
}
}
}
catch (Exception e)
{
_errorMessage = e.Message;
}
finally
{
_sending = false;
}
}
private class CreateStoreModel
{
[Required] public string? Name { get; set; }
[Required] public string? DefaultCurrency { get; set; }
[Required] public string? PreferredExchange { get; set; }
}
}