btcpayserver/BTCPayServer/Views/Shared/PointOfSale/Public/Print.cshtml
d11n ff79a31066
Refactoring: Move AppItem to Client lib and use the class for item list (#6258)
* Refactoring: Move AppItem to Client lib and use the class for item list

This makes it available for the app, which would otherwise have to replicate the model. Also uses the proper class for the item/perk list of the app models.

* Remove unused app item payment methods property

* Do not ignore nullable values in JSON

* Revert to use Newtonsoft types
2024-11-05 11:49:30 +09:00

147 lines
6.8 KiB
Text

@using BTCPayServer.Abstractions.TagHelpers
@using BTCPayServer.Client.Models
@using BTCPayServer.Components.QRCode
@using BTCPayServer.Payments
@using BTCPayServer.Payments.Lightning
@using BTCPayServer.Services
@using BTCPayServer.Services.Invoices
@using BTCPayServer.Services.Stores
@using LNURL
@using Microsoft.AspNetCore.Mvc.TagHelpers
@inject StoreRepository StoreRepository
@inject PaymentMethodHandlerDictionary Handlers
@inject DisplayFormatter DisplayFormatter
@model BTCPayServer.Plugins.PointOfSale.Models.ViewPointOfSaleViewModel
@{
var store = await StoreRepository.FindStore(Model.StoreId);
Layout = "PointOfSale/Public/_Layout";
Context.Request.Query.TryGetValue("cryptocode", out var cryptoCodeValues);
var cryptoCode = cryptoCodeValues.FirstOrDefault() ?? "BTC";
var pmi = PaymentTypes.LNURL.GetPaymentMethodId(cryptoCode);
var supported = store.GetPaymentMethodConfig<LNURLPaymentMethodConfig>(pmi, Handlers);
if (supported is not null && !store.GetEnabledPaymentIds().Contains(pmi))
{
supported = null;
}
}
@section PageHeadContent {
<link href="~/pos/print.css" asp-append-version="true" rel="stylesheet" />
}
@if (supported is null)
{
<div class="alert alert-warning text-center sticky-top mb-0 rounded-0" role="alert">
LNURL is not enabled on your store, which this print feature relies on.
<a asp-controller="UIStores" asp-action="LightningSettings" asp-route-cryptoCode="BTC" asp-route-storeId="@store.Id" class="alert-link p-0">
Enable LNURL
</a>
</div>
}
else
{
<div class="alert alert-info alert-dismissible d-flex align-items-center justify-content-center sticky-top mb-0 rounded-0 d-print-none fade show" role="alert">
<button type="button" class="btn btn-info me-4 border border-light" onclick="window.print()">
<vc:icon symbol="pos-print" />&nbsp;Print
</button>
This view is intended for printing only —
<a asp-route-viewType="static" class="alert-link">Regular version</a>
</div>
}
<div id="PosPrint" class="public-page-wrap">
<partial name="_StatusMessage" />
<partial name="_StoreHeader" model="(string.IsNullOrEmpty(Model.Title) ? Model.StoreName : Model.Title, Model.StoreBranding)" />
@if (!string.IsNullOrEmpty(Model.Description))
{
<div class="lead text-center">@Safe.Raw(Model.Description)</div>
}
<main>
@if (supported is not null)
{
if (Model.ShowCustomAmount)
{
Model.Items = Model.Items.Concat([
new AppItem
{
Description = "Create invoice to pay custom amount",
Title = "Custom amount",
BuyButtonText = Model.CustomButtonText,
PriceType = AppItemPriceType.Topup
}
]).ToArray();
}
}
<div class="posItems">
@for (var x = 0; x < Model.Items.Length; x++)
{
var item = Model.Items[x];
var formatted = DisplayFormatter.Currency(item.Price ?? 0, Model.CurrencyCode, DisplayFormatter.CurrencyFormat.Symbol);
if (item.PriceType == AppItemPriceType.Fixed && item.Price == 0) continue;
<div class="d-flex flex-wrap">
<div class="tile card w-100" data-id="@x">
<div class="card-body pt-0 d-flex flex-column gap-2">
<h5 class="card-title m-0">@Safe.Raw(item.Title)</h5>
<div class="d-flex gap-2 align-items-center">
<span class="fw-semibold">
@switch (item.PriceType)
{
case AppItemPriceType.Topup:
<span>Any amount</span>
break;
case AppItemPriceType.Minimum:
<span>@formatted minimum</span>
break;
case AppItemPriceType.Fixed:
@formatted
break;
default:
throw new ArgumentOutOfRangeException();
}
</span>
@if (item.Inventory.HasValue)
{
<span class="badge text-bg-light">
@if (item.Inventory > 0)
{
<span>@ViewLocalizer["{0} left", item.Inventory.ToString()]</span>
}
else
{
<span text-translate="true">Sold out</span>
}
</span>
}
</div>
@if (!string.IsNullOrWhiteSpace(item.Description))
{
<p class="card-text">@Safe.Raw(item.Description)</p>
}
</div>
@if (item.Inventory is null or > 0)
{
if (supported != null)
{
var lnurlEndpoint = new Uri(Url.Action("GetLNURLForApp", "UILNURL", new
{
cryptoCode = cryptoCode,
appid = Model.AppId,
ItemCode = item.Id
}, Context.Request.Scheme, Context.Request.Host.ToString()));
var lnUrl = LNURL.EncodeUri(lnurlEndpoint, "payRequest", supported.UseBech32Scheme);
<a href="@lnUrl" rel="noreferrer noopener" class="card-img-bottom">
<vc:qr-code data="@lnUrl.ToString().ToUpperInvariant()" />
</a>
}
}
</div>
</div>
}
</div>
</main>
<footer class="store-footer d-print-none">
<a class="store-powered-by" href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">
<span text-translate="true">Powered by</span> <partial name="_StoreFooterLogo" />
</a>
</footer>
</div>