mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-25 15:10:00 +01:00
* Store Branding: Refactoring and logo as favicon - Encapsulates store branding properties into their own view model - Uses the logo as favicon on public pages * Refactorings * Updates
115 lines
6.7 KiB
Text
115 lines
6.7 KiB
Text
@using BTCPayServer.Plugins.PointOfSale.Models
|
|
@using BTCPayServer.Services
|
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@model BTCPayServer.Plugins.PointOfSale.Models.ViewPointOfSaleViewModel
|
|
@inject DisplayFormatter DisplayFormatter
|
|
@{
|
|
Layout = "PointOfSale/Public/_Layout";
|
|
}
|
|
@functions {
|
|
private string GetItemPriceFormatted(ViewPointOfSaleViewModel.Item item)
|
|
{
|
|
if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup) return "any amount";
|
|
if (item.Price == 0) return "free";
|
|
var formatted = DisplayFormatter.Currency(item.Price ?? 0, Model.CurrencyCode, DisplayFormatter.CurrencyFormat.Symbol);
|
|
return item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Minimum ? $"{formatted} minimum" : formatted;
|
|
}
|
|
}
|
|
|
|
<div id="PosStatic" class="public-page-wrap">
|
|
<partial name="_StoreHeader" model="(string.IsNullOrEmpty(Model.Title) ? Model.StoreName : Model.Title, Model.StoreBranding)" />
|
|
<main>
|
|
<partial name="_StatusMessage" />
|
|
@if (!string.IsNullOrEmpty(Model.Description))
|
|
{
|
|
<div class="lead">@Safe.Raw(Model.Description)</div>
|
|
}
|
|
<div class="row row-cols row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4" id="PosItems">
|
|
@for (var x = 0; x < Model.Items.Length; x++)
|
|
{
|
|
var item = Model.Items[x];
|
|
var formatted = GetItemPriceFormatted(item);
|
|
var inStock = item.Inventory is null or > 0;
|
|
var buttonText = string.IsNullOrEmpty(item.BuyButtonText)
|
|
? item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup ? Model.CustomButtonText : Model.ButtonText
|
|
: item.BuyButtonText;
|
|
buttonText = buttonText.Replace("{0}", formatted).Replace("{Price}", formatted);
|
|
|
|
<div class="col posItem posItem--displayed@(x == 0 ? " posItem--first" : null)@(x == Model.Items.Length - 1 && !Model.ShowCustomAmount ? " posItem--last" : null)">
|
|
<div class="card h-100 px-0" data-id="@x">
|
|
@if (!string.IsNullOrWhiteSpace(item.Image))
|
|
{
|
|
<img class="card-img-top" src="@item.Image" alt="@Safe.Raw(item.Title)" asp-append-version="true">
|
|
}
|
|
<div class="card-body p-3 d-flex flex-column gap-2 mb-auto">
|
|
<h5 class="card-title m-0">@Safe.Raw(item.Title)</h5>
|
|
<div class="d-flex gap-2 align-items-center">
|
|
@if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup || item.Price == 0)
|
|
{
|
|
<span class="fw-semibold badge text-bg-info">@Safe.Raw(char.ToUpper(formatted[0]) + formatted[1..])</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="fw-semibold">@Safe.Raw(formatted)</span>
|
|
}
|
|
@if (item.Inventory.HasValue)
|
|
{
|
|
<span class="badge text-bg-warning">
|
|
@(item.Inventory > 0 ? $"{item.Inventory} left" : "Sold out")
|
|
</span>
|
|
}
|
|
</div>
|
|
@if (!string.IsNullOrWhiteSpace(item.Description))
|
|
{
|
|
<p class="card-text">@Safe.Raw(item.Description)</p>
|
|
}
|
|
</div>
|
|
<div class="card-footer bg-transparent border-0 pt-0 pb-3">
|
|
@if (inStock)
|
|
{
|
|
<form method="post" asp-action="ViewPointOfSale" asp-route-appId="@Model.AppId" asp-antiforgery="false" autocomplete="off">
|
|
<input type="hidden" name="requiresRefundEmail" value="@Model.RequiresRefundEmail.ToString()" />
|
|
<input type="hidden" name="choiceKey" value="@item.Id" />
|
|
@if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Minimum)
|
|
{
|
|
<div class="input-group mb-2">
|
|
<span class="input-group-text">@Model.CurrencySymbol</span>
|
|
<input class="form-control" type="number" min="@(item.Price ?? 0)" step="@Model.Step" name="amount" placeholder="Amount" value="@item.Price" required>
|
|
</div>
|
|
}
|
|
<button class="btn btn-primary w-100" type="submit">@Safe.Raw(buttonText)</button>
|
|
</form>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
@if (Model.ShowCustomAmount)
|
|
{
|
|
<div class="col posItem posItem--displayed posItem--last@(Model.Items.Length == 0 ? " posItem--first" : null)">
|
|
<div class="card h-100 px-0">
|
|
<div class="card-body p-3 d-flex flex-column gap-2 mb-auto">
|
|
<h5 class="card-title">Custom Amount</h5>
|
|
<p class="card-text">Create invoice to pay custom amount</p>
|
|
</div>
|
|
<div class="card-footer bg-transparent border-0 pb-3">
|
|
<form method="post" asp-action="ViewPointOfSale" asp-route-appId="@Model.AppId" asp-antiforgery="false" autocomplete="off">
|
|
<input type="hidden" name="requiresRefundEmail" value="@Model.RequiresRefundEmail.ToString()" />
|
|
<div class="input-group mb-2">
|
|
<span class="input-group-text">@Model.CurrencySymbol</span>
|
|
<input class="form-control" type="number" min="0" step="@Model.Step" name="amount" placeholder="Amount" required>
|
|
</div>
|
|
<button class="btn btn-primary w-100" type="submit">@Safe.Raw(Model.CustomButtonText ?? Model.ButtonText)</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</main>
|
|
<footer class="store-footer">
|
|
<a class="store-powered-by" href="https://btcpayserver.org" target="_blank" rel="noreferrer noopener">
|
|
Powered by <partial name="_StoreFooterLogo" />
|
|
</a>
|
|
</footer>
|
|
</div>
|