diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 2f4ca17e4..a8b54a4e5 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -782,6 +782,7 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.Id("Create")).Click(); Assert.Contains("App successfully created", s.FindAlertMessage().Text); + s.Driver.FindElement(By.CssSelector("label[for='DefaultView_Cart']")).Click(); s.Driver.FindElement(By.CssSelector(".template-item:nth-of-type(1) .btn-primary")).Click(); s.Driver.FindElement(By.Id("BuyButtonText")).SendKeys("Take my money"); s.Driver.FindElement(By.Id("SaveItemChanges")).Click(); @@ -790,7 +791,6 @@ namespace BTCPayServer.Tests var template = s.Driver.FindElement(By.Id("Template")).GetAttribute("value"); Assert.Contains("buyButtonText: Take my money", template); - s.Driver.FindElement(By.Id("DefaultView")).SendKeys("Item list and cart"); s.Driver.FindElement(By.Id("SaveSettings")).Click(); Assert.Contains("App updated", s.FindAlertMessage().Text); @@ -1796,8 +1796,7 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.Id("AppName")).SendKeys(Guid.NewGuid().ToString()); s.Driver.FindElement(By.Id("Create")).Click(); TestUtils.Eventually(() => Assert.Contains("App successfully created", s.FindAlertMessage().Text)); - s.Driver.FindElement(By.Id("DefaultView")).Click(); - s.Driver.FindElement(By.CssSelector("option[value='3']")).Click(); + s.Driver.FindElement(By.CssSelector("label[for='DefaultView_Print']")).Click(); s.Driver.FindElement(By.Id("SaveSettings")).Click(); Assert.Contains("App updated", s.FindAlertMessage().Text); diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs index d562e8042..cfe159f3c 100644 --- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs +++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs @@ -352,7 +352,6 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers RedirectUrl = settings.RedirectUrl, SearchTerm = app.TagAllInvoices ? $"storeid:{app.StoreDataId}" : $"orderid:{AppService.GetAppOrderId(app)}", RedirectAutomatically = settings.RedirectAutomatically.HasValue ? settings.RedirectAutomatically.Value ? "true" : "false" : "", - RequiresRefundEmail = settings.RequiresRefundEmail, FormId = settings.FormId }; if (HttpContext?.Request != null) @@ -440,8 +439,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers Description = vm.Description, EmbeddedCSS = vm.EmbeddedCSS, RedirectAutomatically = - string.IsNullOrEmpty(vm.RedirectAutomatically) ? (bool?)null : bool.Parse(vm.RedirectAutomatically), - RequiresRefundEmail = vm.RequiresRefundEmail + string.IsNullOrEmpty(vm.RedirectAutomatically) ? (bool?)null : bool.Parse(vm.RedirectAutomatically) }; settings.FormId = vm.FormId; diff --git a/BTCPayServer/Plugins/PointOfSale/Models/UpdatePointOfSaleViewModel.cs b/BTCPayServer/Plugins/PointOfSale/Models/UpdatePointOfSaleViewModel.cs index d39b81bff..893df0c3b 100644 --- a/BTCPayServer/Plugins/PointOfSale/Models/UpdatePointOfSaleViewModel.cs +++ b/BTCPayServer/Plugins/PointOfSale/Models/UpdatePointOfSaleViewModel.cs @@ -99,10 +99,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Models public string EmbeddedCSS { get; set; } public string Description { get; set; } - [Display(Name = "Require refund email on checkout")] - public RequiresRefundEmail RequiresRefundEmail { get; set; } = RequiresRefundEmail.InheritFromStore; - [Display(Name = "Request customer data on checkout")] - public string FormId { get; set; } = null; + public string FormId { get; set; } } } diff --git a/BTCPayServer/Services/Apps/AppType.cs b/BTCPayServer/Services/Apps/AppType.cs index 325aae6e2..66621e45e 100644 --- a/BTCPayServer/Services/Apps/AppType.cs +++ b/BTCPayServer/Services/Apps/AppType.cs @@ -11,12 +11,13 @@ namespace BTCPayServer.Services.Apps public enum PosViewType { - [Display(Name = "Item list only")] + [Display(Name = "Product list")] Static, - [Display(Name = "Item list and cart")] + [Display(Name = "Product list with cart")] Cart, [Display(Name = "Keypad only")] Light, + [Display(Name = "Print display")] Print } diff --git a/BTCPayServer/Views/Shared/Crowdfund/UpdateCrowdfund.cshtml b/BTCPayServer/Views/Shared/Crowdfund/UpdateCrowdfund.cshtml index e9ed99766..69d33d3e6 100644 --- a/BTCPayServer/Views/Shared/Crowdfund/UpdateCrowdfund.cshtml +++ b/BTCPayServer/Views/Shared/Crowdfund/UpdateCrowdfund.cshtml @@ -42,44 +42,49 @@
-
-
- - - -
-
- - - +
+
+
+
+ + + +
+
+
+
+ + + +
+
-
-
-
-
-
- - - -
- - +
The crowdfund will be visible to anyone.
+
+
+
+ + + +
+
+

Goal

diff --git a/BTCPayServer/Views/Shared/PointOfSale/Public/Print.cshtml b/BTCPayServer/Views/Shared/PointOfSale/Public/Print.cshtml index 9a93a3344..19f11099c 100644 --- a/BTCPayServer/Views/Shared/PointOfSale/Public/Print.cshtml +++ b/BTCPayServer/Views/Shared/PointOfSale/Public/Print.cshtml @@ -38,77 +38,89 @@
} -else -{ - if (Model.ShowCustomAmount) - { - Model.Items = Model.Items.Concat(new[] +
+
+

@Model.Title

+ @if (!string.IsNullOrEmpty(Model.Description)) { - new ViewPointOfSaleViewModel.Item() - { - Description = "Create invoice to pay custom amount", - Title = "Custom amount", - BuyButtonText = Model.CustomButtonText, - Price = new ViewPointOfSaleViewModel.Item.ItemPrice() - { - Type = ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Topup, - - } - } - }).ToArray(); - } - -} - -
- @for (int x = 0; x < Model.Items.Length; x++) - { - var item = Model.Items[x]; -
-
-

@item.Title

- @if (!string.IsNullOrEmpty(item.Description)) - { -

@item.Description

- - } -
- @switch (item.Price.Type) - { - case ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Topup: - Any amount - break; - case ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Minimum: - @item.Price.Formatted minimum - break; - case ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Fixed: - @item.Price.Formatted - break; - default: - throw new ArgumentOutOfRangeException(); - } -
- @if (!item.Inventory.HasValue || item.Inventory.Value > 0) - { - if (supported != null) - { - var lnurlEndpoint = new Uri(Url.Action("GetLNURLForApp", "UILNURL", new - { - cryptoCode = supported.CryptoCode, - appid = Model.AppId, - ItemCode = item.Id - }, Context.Request.Scheme, Context.Request.Host.ToString())); - var lnUrl = LNURL.EncodeUri(lnurlEndpoint, "payRequest", supported.UseBech32Scheme); - - } - } +
+
@Safe.Raw(Model.Description)
+ } + + @if (supported is not null) + { + if (Model.ShowCustomAmount) + { + Model.Items = Model.Items.Concat(new[] + { + new ViewPointOfSaleViewModel.Item() + { + Description = "Create invoice to pay custom amount", + Title = "Custom amount", + BuyButtonText = Model.CustomButtonText, + Price = new ViewPointOfSaleViewModel.Item.ItemPrice() + { + Type = ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Topup, + + } + } + }).ToArray(); + } + + } + +
+ @for (int x = 0; x < Model.Items.Length; x++) + { + var item = Model.Items[x]; +
+
+

@item.Title

+ @if (!string.IsNullOrEmpty(item.Description)) + { +

@item.Description

+ + } +
+ @switch (item.Price.Type) + { + case ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Topup: + Any amount + break; + case ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Minimum: + @item.Price.Formatted minimum + break; + case ViewPointOfSaleViewModel.Item.ItemPrice.ItemPriceType.Fixed: + @item.Price.Formatted + break; + default: + throw new ArgumentOutOfRangeException(); + } +
+ @if (!item.Inventory.HasValue || item.Inventory.Value > 0) + { + if (supported != null) + { + var lnurlEndpoint = new Uri(Url.Action("GetLNURLForApp", "UILNURL", new + { + cryptoCode = supported.CryptoCode, + appid = Model.AppId, + ItemCode = item.Id + }, Context.Request.Scheme, Context.Request.Host.ToString())); + var lnUrl = LNURL.EncodeUri(lnurlEndpoint, "payRequest", supported.UseBech32Scheme); + + } + } +
+
+ }
- } +
diff --git a/BTCPayServer/Views/Shared/PointOfSale/UpdatePointOfSale.cshtml b/BTCPayServer/Views/Shared/PointOfSale/UpdatePointOfSale.cshtml index c33965f09..076d89c68 100644 --- a/BTCPayServer/Views/Shared/PointOfSale/UpdatePointOfSale.cshtml +++ b/BTCPayServer/Views/Shared/PointOfSale/UpdatePointOfSale.cshtml @@ -26,18 +26,37 @@
-
-
- - - +
+
+
+
+ + + +
+
+
+
+ + + +
+
- - - + +
+ @foreach (var type in Enum.GetValues()) + { + + + } +
-
+
Uses the store's default currency (@Model.StoreDefaultCurrency) if empty.
@@ -45,7 +64,7 @@
-
+
@@ -54,46 +73,59 @@
-
-
- +
+
+
+ +
-
-
-
-
- - - +
+
+
+ + + +
-
-
-

Appearance

-
- - - -
Choose the point of sale style for your customers.
-
-
- - - -
-
- - - -
-
- - - -
-
-

Discounts

+
+
+

Checkout

+
+
+ + + +
+
+ + + +
+
+
+ Tips +
+ + + +
+
+
+ + + +
+
+ + + +
+
+
+
+ Discounts
@@ -102,47 +134,27 @@
-
-
-

Custom Payments

+ +
+ Custom Payments
-
+
-
-
-

Tips

-
- - - -
-
-
- - - -
-
- - - -
-
-
+
-
+
-

Additional Options

+

Additional Options

@@ -334,104 +346,61 @@
- } diff --git a/BTCPayServer/wwwroot/img/icon-sprite.svg b/BTCPayServer/wwwroot/img/icon-sprite.svg index af2fc82c4..06cd3af7a 100644 --- a/BTCPayServer/wwwroot/img/icon-sprite.svg +++ b/BTCPayServer/wwwroot/img/icon-sprite.svg @@ -50,4 +50,8 @@ + + + + diff --git a/BTCPayServer/wwwroot/main/site.css b/BTCPayServer/wwwroot/main/site.css index ddf4c98f2..cb63b32ba 100644 --- a/BTCPayServer/wwwroot/main/site.css +++ b/BTCPayServer/wwwroot/main/site.css @@ -588,3 +588,41 @@ svg.icon-note { } .modal-footer .modal-footer-left{ margin-right: auto; } + +/* List Select */ +.btcpay-list-select { + display: flex; + flex-wrap: wrap; + gap: var(--btcpay-space-s); +} +.btcpay-list-select > input { + display: none; +} +.btcpay-list-select-item { + display: flex; + flex: 1 1 45%; + align-items: center; + border: 1px solid var(--btcpay-form-border); + padding: .75rem var(--btcpay-space-s); + background-color: var(--btcpay-form-bg); + border-radius: var(--btcpay-border-radius); + transition: border-color 0.15s ease-in-out; + cursor: pointer; +} +@media (max-width: 575px) { + .btcpay-list-select-item { + flex-basis: 100%; + } +} +.btcpay-list-select-item .icon { + width: 1.5rem; + height: 1.5rem; + margin: 0 var(--btcpay-space-s); +} +.btcpay-list-select-item:hover { + border-color: var(--btcpay-form-border-hover); + background-color: var(--btcpay-form-bg-hover); +} +input:checked + .btcpay-list-select-item { + border-color: var(--btcpay-form-border-focus); +}