mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 09:54:30 +01:00
Improve payouts UI (#3792)
* Improve payouts UI * Display units * Update badges * Update badge background
This commit is contained in:
parent
5616b7550f
commit
ba0e46b465
@ -12,6 +12,7 @@ using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Security;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Rates;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using LNURL;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@ -35,6 +36,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
private readonly IOptions<LightningNetworkOptions> _options;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly CurrencyNameTable _currencyNameTable;
|
||||
|
||||
public UILightningLikePayoutController(ApplicationDbContextFactory applicationDbContextFactory,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
@ -42,6 +44,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
IEnumerable<IPayoutHandler> payoutHandlers,
|
||||
BTCPayNetworkProvider btcPayNetworkProvider,
|
||||
StoreRepository storeRepository,
|
||||
CurrencyNameTable currencyNameTable,
|
||||
LightningClientFactoryService lightningClientFactoryService,
|
||||
IOptions<LightningNetworkOptions> options, IAuthorizationService authorizationService)
|
||||
{
|
||||
@ -53,6 +56,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
_lightningClientFactoryService = lightningClientFactoryService;
|
||||
_options = options;
|
||||
_storeRepository = storeRepository;
|
||||
_currencyNameTable = currencyNameTable;
|
||||
_authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
@ -103,7 +107,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
{
|
||||
var blob = payoutData.GetBlob(_btcPayNetworkJsonSerializerSettings);
|
||||
|
||||
return new ConfirmVM()
|
||||
return new ConfirmVM
|
||||
{
|
||||
Amount = blob.CryptoAmount.Value,
|
||||
Destination = blob.Destination,
|
||||
@ -133,11 +137,11 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
var boltAmount = bolt11PaymentRequest.MinimumAmount.ToDecimal(LightMoneyUnit.BTC);
|
||||
if (boltAmount != payoutBlob.CryptoAmount)
|
||||
{
|
||||
results.Add(new ResultVM()
|
||||
results.Add(new ResultVM
|
||||
{
|
||||
PayoutId = payoutData.Id,
|
||||
Result = PayResult.Error,
|
||||
Message = $"The BOLT11 invoice amount did not match the payout's amount ({boltAmount} instead of {payoutBlob.CryptoAmount})",
|
||||
Message = $"The BOLT11 invoice amount ({_currencyNameTable.DisplayFormatCurrency(boltAmount, pmi.CryptoCode)}) did not match the payout's amount ({_currencyNameTable.DisplayFormatCurrency(payoutBlob.CryptoAmount.GetValueOrDefault(), pmi.CryptoCode)})",
|
||||
Destination = payoutBlob.Destination
|
||||
});
|
||||
return;
|
||||
@ -145,21 +149,26 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
var result = await lightningClient.Pay(bolt11PaymentRequest.ToString());
|
||||
if (result.Result == PayResult.Ok)
|
||||
{
|
||||
results.Add(new ResultVM()
|
||||
var message = result.Details?.TotalAmount != null
|
||||
? $"Paid out {result.Details.TotalAmount.ToDecimal(LightMoneyUnit.BTC)}"
|
||||
: null;
|
||||
results.Add(new ResultVM
|
||||
{
|
||||
PayoutId = payoutData.Id,
|
||||
Result = result.Result,
|
||||
Destination = payoutBlob.Destination
|
||||
Destination = payoutBlob.Destination,
|
||||
Message = message
|
||||
});
|
||||
payoutData.State = PayoutState.Completed;
|
||||
}
|
||||
else
|
||||
{
|
||||
results.Add(new ResultVM()
|
||||
results.Add(new ResultVM
|
||||
{
|
||||
PayoutId = payoutData.Id,
|
||||
Result = result.Result,
|
||||
Destination = payoutBlob.Destination
|
||||
Destination = payoutBlob.Destination,
|
||||
Message = result.ErrorDetail
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -184,8 +193,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
PayoutId = payoutData.Id,
|
||||
Result = PayResult.Error,
|
||||
Destination = blob.Destination,
|
||||
Message =
|
||||
$"You are currently using the internal lightning node for this payout's store but you are not a server admin."
|
||||
Message = "You are currently using the internal Lightning node for this payout's store but you are not a server admin."
|
||||
});
|
||||
}
|
||||
|
||||
@ -204,7 +212,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
switch (claim.destination)
|
||||
{
|
||||
case LNURLPayClaimDestinaton lnurlPayClaimDestinaton:
|
||||
var endpoint = LNURL.LNURL.Parse(lnurlPayClaimDestinaton.LNURL, out var tag);
|
||||
var endpoint = LNURL.LNURL.Parse(lnurlPayClaimDestinaton.LNURL, out _);
|
||||
var lightningPayoutHandler = (LightningLikePayoutHandler)payoutHandler;
|
||||
var httpClient = lightningPayoutHandler.CreateClient(endpoint);
|
||||
var lnurlInfo =
|
||||
@ -213,7 +221,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
var lm = new LightMoney(blob.CryptoAmount.Value, LightMoneyUnit.BTC);
|
||||
if (lm > lnurlInfo.MaxSendable || lm < lnurlInfo.MinSendable)
|
||||
{
|
||||
results.Add(new ResultVM()
|
||||
results.Add(new ResultVM
|
||||
{
|
||||
PayoutId = payoutData.Id,
|
||||
Result = PayResult.Error,
|
||||
@ -260,13 +268,14 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception exception)
|
||||
{
|
||||
results.Add(new ResultVM
|
||||
{
|
||||
PayoutId = payoutData.Id,
|
||||
Result = PayResult.Error,
|
||||
Destination = blob.Destination
|
||||
Destination = blob.Destination,
|
||||
Message = exception.Message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -5,20 +5,19 @@
|
||||
var cryptoCode = Context.GetRouteValue("cryptoCode");
|
||||
}
|
||||
|
||||
<h2 class="mt-1 mb-4">@ViewData["Title"]</h2>
|
||||
<h2 class="mt-1 mb-2">@ViewData["Title"]</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<ul class="list-group">
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach (var item in Model)
|
||||
{
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="text-break" style="max-width:60em;">@item.Destination</div>
|
||||
<span class="text-capitalize badge bg-secondary">@item.Amount @cryptoCode</span>
|
||||
<li class="list-group-item py-4 px-0">
|
||||
<div class="text-break">@item.Destination</div>
|
||||
<form method="post" class="mt-4 mb-1" id="pay-invoices-form">
|
||||
<button type="submit" class="btn btn-primary" id="Pay">Pay @item.Amount @cryptoCode</button>
|
||||
<a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Context.GetStoreData().Id" class="btn btn-secondary mx-2 px-4">Cancel</a>
|
||||
</form>
|
||||
</li>
|
||||
<form method="post" class="list-group-item justify-content-center" id="pay-invoices-form">
|
||||
<button type="submit" class="btn btn-primary px-5" id="Pay">Pay</button>
|
||||
<a asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Context.GetStoreData().Id" class="btn btn-secondary mx-2 px-4">Cancel</a>
|
||||
</form>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -8,15 +8,14 @@
|
||||
<h2 class="mt-1 mb-4">@ViewData["Title"]</h2>
|
||||
@foreach (var item in Model)
|
||||
{
|
||||
<div class="alert alert-@(item.Result == PayResult.Ok ? "success" : "danger") d-flex justify-content-between align-items-center mb-3" role="alert">
|
||||
@if (item.Result == PayResult.Ok)
|
||||
{
|
||||
<div class="text-break me-3" title="@item.Destination">@item.Destination</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-break me-3" title="@item.Destination">@item.Destination: @item.Message (@item.Result)</div>
|
||||
}
|
||||
<span class="badge fs-5">@(item.Result == PayResult.Ok ? "Sent" : "Failed")</span>
|
||||
<div class="alert alert-@(item.Result == PayResult.Ok ? "success" : "danger") mb-3" role="alert">
|
||||
<h5 class="alert-heading">
|
||||
@(item.Result == PayResult.Ok ? "Sent" : "Failed")
|
||||
@if (!string.IsNullOrEmpty(item.Message))
|
||||
{
|
||||
<span>- @item.Message</span>
|
||||
}
|
||||
</h5>
|
||||
<div class="text-break me-3" title="@item.Destination">@item.Destination</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -39,6 +39,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
@section PageHeadContent {
|
||||
<style>
|
||||
#Payouts .badge.rounded-pill {
|
||||
font-size: var(--btcpay-font-size-s);
|
||||
color: inherit;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
|
||||
@section PageFootContent {
|
||||
<script>
|
||||
delegate('click', '.selectAll', e => {
|
||||
@ -52,10 +61,6 @@
|
||||
|
||||
<partial name="_StatusMessage"/>
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
@if (_payoutProcessorFactories.Any(factory => factory.GetSupportedPaymentMethods().Contains(paymentMethodId)) && !(await _payoutProcessorService.GetProcessors(new PayoutProcessorService.PayoutProcessorQuery()
|
||||
{
|
||||
Stores = new[] {storeId},
|
||||
@ -70,7 +75,7 @@
|
||||
}
|
||||
<h2 class="mt-1 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<form method="post">
|
||||
<form method="post" id="Payouts">
|
||||
<input type="hidden" asp-for="PaymentMethodId"/>
|
||||
<input type="hidden" asp-for="PayoutState"/>
|
||||
<div class="d-flex justify-content-between mb-4">
|
||||
@ -82,13 +87,13 @@
|
||||
asp-route-payoutState="@Model.PayoutState"
|
||||
asp-route-paymentMethodId="@state.ToString()"
|
||||
asp-route-pullPaymentId="@Model.PullPaymentId"
|
||||
class="btcpay-pill @(state.ToString() == Model.PaymentMethodId ? "active" : "")"
|
||||
class="btcpay-pill position-relative @(state.ToString() == Model.PaymentMethodId ? "active" : "")"
|
||||
id="@state.ToString()-view"
|
||||
role="tab">
|
||||
@state.ToPrettyString()
|
||||
@if (Model.PaymentMethodCount.TryGetValue(state.ToString(), out var count) && count > 0)
|
||||
{
|
||||
<span>(@count)</span>
|
||||
<span class="badge rounded-pill fw-semibold pe-0">@count</span>
|
||||
}
|
||||
</a>
|
||||
</li>
|
||||
@ -119,7 +124,11 @@
|
||||
asp-route-pullPaymentId="@Model.PullPaymentId"
|
||||
asp-route-paymentMethodId="@Model.PaymentMethodId"
|
||||
class="nav-link @(state.Key == Model.PayoutState ? "active" : "")" role="tab">
|
||||
@state.Key.GetStateString() (@state.Value)
|
||||
@state.Key.GetStateString()
|
||||
@if (state.Value > 0)
|
||||
{
|
||||
<span class="badge rounded-pill border fw-semibold ms-1 bg-tile">@state.Value</span>
|
||||
}
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
|
@ -41,6 +41,7 @@
|
||||
--btcpay-secondary: transparent;
|
||||
--btcpay-secondary-text-active: var(--btcpay-primary);
|
||||
--btcpay-secondary-border: var(--btcpay-neutral-700);
|
||||
--btcpay-secondary-rgb: 22, 27, 34;
|
||||
--btcpay-light: var(--btcpay-neutral-800);
|
||||
--btcpay-light-accent: var(--btcpay-black);
|
||||
--btcpay-light-text: var(--btcpay-neutral-200);
|
||||
|
Loading…
Reference in New Issue
Block a user