mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 06:24:24 +01:00
Improves create point of sale view (#2646)
* re-ordering * adds section header * updates label on "products" * changes button to primary * moves description * updates partial * re-ordering + section headers * more section heads and ordering * redorders * Toggle custom amount and tips settings * Use display name for point of sale app type * Use switches for enabling options * Add space before required indicator * Set and consolidate view model display names * Move redirects and custom CSS to additional options * Revert to checkbox for discounts * adds padding * removes bs-parent for multiple open elements on accordion * adds helper text to discount checkbox * updates "default view" label text * wording cleanup * more wording adjustments * updates * Add display names for app types * Extract template editor inline styles * updates helper text * Display names for app types * Typo fix * Move template back to editor * Fix selenium test Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
@@ -498,10 +498,9 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("Apps")).Click();
|
s.Driver.FindElement(By.Id("Apps")).Click();
|
||||||
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
|
s.Driver.FindElement(By.Id("CreateNewApp")).Click();
|
||||||
s.Driver.FindElement(By.Name("Name")).SendKeys("PoS" + Guid.NewGuid());
|
s.Driver.FindElement(By.Name("Name")).SendKeys("PoS" + Guid.NewGuid());
|
||||||
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("PointOfSale");
|
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Point of Sale");
|
||||||
s.Driver.FindElement(By.Id("SelectedStore")).SendKeys(storeName);
|
s.Driver.FindElement(By.Id("SelectedStore")).SendKeys(storeName);
|
||||||
s.Driver.FindElement(By.Id("Create")).Click();
|
s.Driver.FindElement(By.Id("Create")).Click();
|
||||||
s.Driver.FindElement(By.Id("DefaultView")).SendKeys("Cart");
|
|
||||||
s.Driver.FindElement(By.CssSelector(".template-item:nth-of-type(1) .btn-primary")).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("BuyButtonText")).SendKeys("Take my money");
|
||||||
s.Driver.FindElement(By.Id("SaveItemChanges")).Click();
|
s.Driver.FindElement(By.Id("SaveItemChanges")).Click();
|
||||||
@@ -510,6 +509,7 @@ namespace BTCPayServer.Tests
|
|||||||
var template = s.Driver.FindElement(By.Id("Template")).GetAttribute("value");
|
var template = s.Driver.FindElement(By.Id("Template")).GetAttribute("value");
|
||||||
Assert.Contains("buyButtonText: Take my money", template);
|
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();
|
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||||
s.Driver.FindElement(By.Id("ViewApp")).Click();
|
s.Driver.FindElement(By.Id("ViewApp")).Click();
|
||||||
|
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ namespace BTCPayServer.Controllers
|
|||||||
private async Task<List<SelectListItem>> GetAppSelectList()
|
private async Task<List<SelectListItem>> GetAppSelectList()
|
||||||
{
|
{
|
||||||
var apps = (await _AppService.GetAllApps(null, true))
|
var apps = (await _AppService.GetAllApps(null, true))
|
||||||
.Select(a => new SelectListItem($"{a.AppType} - {a.AppName} - {a.StoreName}", a.Id)).ToList();
|
.Select(a => new SelectListItem($"{typeof(AppType).DisplayName(a.AppType)} - {a.AppName} - {a.StoreName}", a.Id)).ToList();
|
||||||
apps.Insert(0, new SelectListItem("(None)", null));
|
apps.Insert(0, new SelectListItem("(None)", null));
|
||||||
return apps;
|
return apps;
|
||||||
}
|
}
|
||||||
|
|||||||
13
BTCPayServer/Extensions/EnumExtensions.cs
Normal file
13
BTCPayServer/Extensions/EnumExtensions.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace BTCPayServer
|
||||||
|
{
|
||||||
|
public static class EnumExtensions
|
||||||
|
{
|
||||||
|
public static string DisplayName(this Type enumType, string input) =>
|
||||||
|
enumType.GetMember(input).First().GetCustomAttribute<DisplayAttribute>()?.Name ?? input;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
@@ -44,7 +45,11 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
void SetApps()
|
void SetApps()
|
||||||
{
|
{
|
||||||
var defaultAppType = AppType.PointOfSale.ToString();
|
var defaultAppType = AppType.PointOfSale.ToString();
|
||||||
var choices = typeof(AppType).GetEnumNames().Select(o => new Format() { Name = o, Value = o }).ToArray();
|
var choices = typeof(AppType).GetEnumNames().Select(o => new Format
|
||||||
|
{
|
||||||
|
Name = typeof(AppType).DisplayName(o),
|
||||||
|
Value = o
|
||||||
|
}).ToArray();
|
||||||
var chosen = choices.FirstOrDefault(f => f.Value == defaultAppType) ?? choices.FirstOrDefault();
|
var chosen = choices.FirstOrDefault(f => f.Value == defaultAppType) ?? choices.FirstOrDefault();
|
||||||
AppTypes = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen);
|
AppTypes = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen);
|
||||||
SelectedAppType = chosen.Value;
|
SelectedAppType = chosen.Value;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
[Display(Name = "Featured Image")]
|
[Display(Name = "Featured Image")]
|
||||||
public string MainImageUrl { get; set; }
|
public string MainImageUrl { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Callback Notification Url")]
|
[Display(Name = "Callback Notification URL")]
|
||||||
[Uri]
|
[Uri]
|
||||||
public string NotificationUrl { get; set; }
|
public string NotificationUrl { get; set; }
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string PerksTemplate { get; set; }
|
public string PerksTemplate { get; set; }
|
||||||
|
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
[Display(Name = "Custom bootstrap CSS file")]
|
[Display(Name = "Custom CSS URL")]
|
||||||
public string CustomCSSLink { get; set; }
|
public string CustomCSSLink { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Custom CSS Code")]
|
[Display(Name = "Custom CSS Code")]
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string Currency { get; set; }
|
public string Currency { get; set; }
|
||||||
public string Template { get; set; }
|
public string Template { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Default view")]
|
[Display(Name = "Point of Sale Style")]
|
||||||
public PosViewType DefaultView { get; set; }
|
public PosViewType DefaultView { get; set; }
|
||||||
[Display(Name = "User can input custom amount")]
|
[Display(Name = "User can input custom amount")]
|
||||||
public bool ShowCustomAmount { get; set; }
|
public bool ShowCustomAmount { get; set; }
|
||||||
@@ -32,20 +32,20 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string ExampleCallback { get; internal set; }
|
public string ExampleCallback { get; internal set; }
|
||||||
public string InvoiceUrl { get; internal set; }
|
public string InvoiceUrl { get; internal set; }
|
||||||
|
|
||||||
[Display(Name = "Callback Notification Url")]
|
[Display(Name = "Callback Notification URL")]
|
||||||
[Uri]
|
[Uri]
|
||||||
public string NotificationUrl { get; set; }
|
public string NotificationUrl { get; set; }
|
||||||
[Display(Name = "Redirect Url")]
|
[Display(Name = "Redirect URL")]
|
||||||
[Uri]
|
[Uri]
|
||||||
public string RedirectUrl { get; set; }
|
public string RedirectUrl { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(30)]
|
[MaxLength(30)]
|
||||||
[Display(Name = "Text to display on each buttons for items with a specific price")]
|
[Display(Name = "Text to display on each button for items with a specific price")]
|
||||||
public string ButtonText { get; set; }
|
public string ButtonText { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(30)]
|
[MaxLength(30)]
|
||||||
[Display(Name = "Text to display on buttons next to the input allowing the user to enter a custom amount")]
|
[Display(Name = "Text to display on buttons allowing the user to enter a custom amount")]
|
||||||
public string CustomButtonText { get; set; }
|
public string CustomButtonText { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
[MaxLength(30)]
|
[MaxLength(30)]
|
||||||
@@ -56,7 +56,7 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string CustomTipPercentages { get; set; }
|
public string CustomTipPercentages { get; set; }
|
||||||
|
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
[Display(Name = "Custom bootstrap CSS file")]
|
[Display(Name = "Custom CSS URL")]
|
||||||
public string CustomCSSLink { get; set; }
|
public string CustomCSSLink { get; set; }
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
@@ -87,6 +87,7 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
}
|
}
|
||||||
}, nameof(SelectListItem.Value), nameof(SelectListItem.Text), RedirectAutomatically);
|
}, nameof(SelectListItem.Value), nameof(SelectListItem.Text), RedirectAutomatically);
|
||||||
|
|
||||||
|
[Display(Name = "Custom CSS Code")]
|
||||||
public string EmbeddedCSS { get; set; }
|
public string EmbeddedCSS { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
|
|
||||||
namespace BTCPayServer.Models.AppViewModels
|
namespace BTCPayServer.Models.AppViewModels
|
||||||
@@ -49,9 +50,11 @@ namespace BTCPayServer.Models.AppViewModels
|
|||||||
public string CustomTipText { get; set; }
|
public string CustomTipText { get; set; }
|
||||||
public int[] CustomTipPercentages { get; set; }
|
public int[] CustomTipPercentages { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "Custom CSS URL")]
|
||||||
public string CustomCSSLink { get; set; }
|
public string CustomCSSLink { get; set; }
|
||||||
public string CustomLogoLink { get; set; }
|
public string CustomLogoLink { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
[Display(Name = "Custom CSS Code")]
|
||||||
public string EmbeddedCSS { get; set; }
|
public string EmbeddedCSS { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ namespace BTCPayServer.Models.PaymentRequestViewModels
|
|||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
|
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
[Display(Name = "Custom bootstrap CSS file")]
|
[Display(Name = "Custom CSS URL")]
|
||||||
public string CustomCSSLink { get; set; }
|
public string CustomCSSLink { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Custom CSS Code")]
|
[Display(Name = "Custom CSS Code")]
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace BTCPayServer.Models.WalletViewModels
|
|||||||
[ReadOnly(true)]
|
[ReadOnly(true)]
|
||||||
public string Currency { get; set; }
|
public string Currency { get; set; }
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
[Display(Name = "Custom bootstrap CSS file")]
|
[Display(Name = "Custom CSS URL")]
|
||||||
public string CustomCSSLink { get; set; }
|
public string CustomCSSLink { get; set; }
|
||||||
[Display(Name = "Custom CSS Code")]
|
[Display(Name = "Custom CSS Code")]
|
||||||
public string EmbeddedCSS { get; set; }
|
public string EmbeddedCSS { get; set; }
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Apps
|
namespace BTCPayServer.Services.Apps
|
||||||
{
|
{
|
||||||
public enum AppType
|
public enum AppType
|
||||||
{
|
{
|
||||||
|
[Display(Name = "Point of Sale")]
|
||||||
PointOfSale,
|
PointOfSale,
|
||||||
Crowdfund
|
Crowdfund
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PosViewType
|
public enum PosViewType
|
||||||
{
|
{
|
||||||
|
[Display(Name = "Item list only")]
|
||||||
Static,
|
Static,
|
||||||
|
[Display(Name = "Item list and cart")]
|
||||||
Cart,
|
Cart,
|
||||||
|
[Display(Name = "Keypad only")]
|
||||||
Light
|
Light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace BTCPayServer.Services
|
|||||||
|
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
[MaxLength(500)]
|
[MaxLength(500)]
|
||||||
[Display(Name = "Custom bootstrap CSS file")]
|
[Display(Name = "Custom Bootstrap CSS file")]
|
||||||
public string BootstrapCssUri { get; set; }
|
public string BootstrapCssUri { get; set; }
|
||||||
|
|
||||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@model ListAppsViewModel
|
@using BTCPayServer.Services.Apps
|
||||||
|
@model ListAppsViewModel
|
||||||
@{
|
@{
|
||||||
ViewData.SetActivePageAndTitle(AppsNavPages.Index, "Apps");
|
ViewData.SetActivePageAndTitle(AppsNavPages.Index, "Apps");
|
||||||
var storeNameSortOrder = (string)ViewData["StoreNameSortOrder"];
|
var storeNameSortOrder = (string)ViewData["StoreNameSortOrder"];
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@app.AppName</td>
|
<td>@app.AppName</td>
|
||||||
<td>@app.AppType</td>
|
<td>@typeof(AppType).DisplayName(app.AppType)</td>
|
||||||
<td style="text-align:right">
|
<td style="text-align:right">
|
||||||
@if (app.IsOwner)
|
@if (app.IsOwner)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,26 +1,13 @@
|
|||||||
@model (string templateId, string title)
|
@model (string templateId, string title)
|
||||||
<style>
|
|
||||||
.card-deck {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
||||||
grid-gap: .5rem;
|
|
||||||
}
|
|
||||||
.card-deck .card{
|
|
||||||
max-width:480px;
|
|
||||||
}
|
|
||||||
.card-img-top{
|
|
||||||
min-height:247px; background-repeat: no-repeat; background-size:contain; background-position: top;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div id="template-editor-app" v-cloak>
|
<div id="template-editor-app" v-cloak>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label mb-3">@Model.title </label>
|
<h4 class="mt-5 mb-4">@Model.title </h4>
|
||||||
@if (ViewContext.ViewData.ModelState.TryGetValue(Model.templateId, out var errors))
|
@if (ViewContext.ViewData.ModelState.TryGetValue(Model.templateId, out var errors))
|
||||||
{
|
{
|
||||||
foreach (var error in errors.Errors)
|
foreach (var error in errors.Errors)
|
||||||
{
|
{
|
||||||
<br/>
|
<br />
|
||||||
<span class="text-danger">@error.ErrorMessage</span>
|
<span class="text-danger">@error.ErrorMessage</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,14 +25,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!items || items.length === 0" class="col-12 text-center">
|
<div v-if="!items || items.length === 0" class="col-12 text-center">
|
||||||
No items.<br/>
|
No items.<br />
|
||||||
<button type="button" class="btn btn-link" v-on:click="editItem(-1)" id="btn-add-first">
|
<button type="button" class="btn btn-link" v-on:click="editItem(-1)" id="btn-add-first">
|
||||||
Add your first item
|
Add your first item
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-start p-3">
|
<div class="card-footer text-start p-3">
|
||||||
<button type="button" class="btn btn-secondary" v-on:click="editItem(-1)" id="btn-add">
|
<button type="button" class="btn btn-primary" v-on:click="editItem(-1)" id="btn-add">
|
||||||
<i class="fa fa-plus fa-fw"></i> Add
|
<i class="fa fa-plus fa-fw"></i> Add
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-secondary ms-2" v-on:click="toggleTemplateElement()" id="ToggleRawEditor">
|
<button type="button" class="btn btn-secondary ms-2" v-on:click="toggleTemplateElement()" id="ToggleRawEditor">
|
||||||
@@ -79,7 +66,7 @@
|
|||||||
min="0"
|
min="0"
|
||||||
type="number"
|
type="number"
|
||||||
required
|
required
|
||||||
v-model="editingItem.price" ref="txtPrice"/>
|
v-model="editingItem.price" ref="txtPrice" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<label class="form-label">Custom price</label>
|
<label class="form-label">Custom price</label>
|
||||||
@@ -90,7 +77,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Image</label>
|
<label class="form-label">Image</label>
|
||||||
<input type="text" class="form-control mb-2" pattern="[^\*#]+" v-model="editingItem.image" ref="txtImage"/>
|
<input type="text" class="form-control mb-2" pattern="[^\*#]+" v-model="editingItem.image" ref="txtImage" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Description</label>
|
<label class="form-label">Description</label>
|
||||||
@@ -102,11 +89,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Id (leave blank to generate from title)</label>
|
<label class="form-label">Id (leave blank to generate from title)</label>
|
||||||
<input type="text" required pattern="[^\*#]+" class="form-control mb-2" v-model="editingItem.id" ref="txtId"/>
|
<input type="text" required pattern="[^\*#]+" class="form-control mb-2" v-model="editingItem.id" ref="txtId" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Buy Button Text</label>
|
<label class="form-label">Buy Button Text</label>
|
||||||
<input type="text" id="BuyButtonText" class="form-control mb-2" v-model="editingItem.buyButtonText" ref="txtBuyButtonText"/>
|
<input type="text" id="BuyButtonText" class="form-control mb-2" v-model="editingItem.buyButtonText" ref="txtBuyButtonText" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
|
|
||||||
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
<h2 class="mb-4">@ViewData["PageTitle"]</h2>
|
||||||
|
|
||||||
<div class="row">
|
<form method="post">
|
||||||
<div class="col-lg-12">
|
<input type="hidden" asp-for="StoreId" />
|
||||||
<form method="post">
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
<input type="hidden" asp-for="StoreId" />
|
|
||||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="Title" class="form-label" data-required></label>
|
<label asp-for="Title" class="form-label" data-required></label>
|
||||||
<input asp-for="Title" class="form-control" required />
|
<input asp-for="Title" class="form-control" required />
|
||||||
@@ -25,26 +26,30 @@
|
|||||||
<input asp-for="Currency" class="form-control" required />
|
<input asp-for="Currency" class="form-control" required />
|
||||||
<span asp-validation-for="Currency" class="text-danger"></span>
|
<span asp-validation-for="Currency" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-9">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label asp-for="Description" class="form-label"></label>
|
||||||
<label asp-for="DefaultView" class="form-label" data-required></label>
|
<textarea asp-for="Description" rows="10" cols="40" class="form-control richtext"></textarea>
|
||||||
<select asp-for="DefaultView" asp-items="@Html.GetEnumSelectList<PosViewType>()" class="form-select" required></select>
|
<span asp-validation-for="Description" class="text-danger"></span>
|
||||||
<span asp-validation-for="DefaultView" class="text-danger"></span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="col-lg-12">
|
||||||
<input asp-for="ShowCustomAmount" type="checkbox" class="form-check-input" />
|
<partial name="TemplateEditor" model="@(nameof(Model.Template), "Products")" />
|
||||||
<label asp-for="ShowCustomAmount" class="form-check-label"></label>
|
<div class="form-group">
|
||||||
<span asp-validation-for="ShowCustomAmount" class="text-danger"></span>
|
<label asp-for="Template" class="form-label"></label>
|
||||||
</div>
|
<textarea asp-for="Template" rows="10" cols="40" class="js-product-template form-control"></textarea>
|
||||||
<div class="form-check">
|
<span asp-validation-for="Template" class="text-danger"></span>
|
||||||
<input asp-for="ShowDiscount" type="checkbox" class="form-check-input" />
|
</div>
|
||||||
<label asp-for="ShowDiscount" class="form-check-label"></label>
|
</div>
|
||||||
<span asp-validation-for="ShowDiscount" class="text-danger"></span>
|
<div class="col-lg-6">
|
||||||
</div>
|
<h4 class="mt-5 mb-4">Appearance</h4>
|
||||||
<div class="form-check">
|
<div class="form-group">
|
||||||
<input asp-for="EnableTips" type="checkbox" class="form-check-input" />
|
<label asp-for="DefaultView" class="form-label" data-required></label>
|
||||||
<label asp-for="EnableTips" class="form-check-label"></label>
|
<select asp-for="DefaultView" asp-items="@Html.GetEnumSelectList<PosViewType>()" class="form-select" required></select>
|
||||||
<span asp-validation-for="EnableTips" class="text-danger"></span>
|
<span asp-validation-for="DefaultView" class="text-danger"></span>
|
||||||
|
<div class="mt-2">
|
||||||
|
<span class="text-secondary">Choose the point of sale style for your customers.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -52,89 +57,59 @@
|
|||||||
<input asp-for="ButtonText" class="form-control" required />
|
<input asp-for="ButtonText" class="form-control" required />
|
||||||
<span asp-validation-for="ButtonText" class="text-danger"></span>
|
<span asp-validation-for="ButtonText" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<h4 class="mt-5 mb-4">Discounts</h4>
|
||||||
<label asp-for="CustomButtonText" class="form-label" data-required></label>
|
<div class="form-check mb-4">
|
||||||
<input asp-for="CustomButtonText" class="form-control" required />
|
<input asp-for="ShowDiscount" type="checkbox" class="form-check-input" />
|
||||||
<span asp-validation-for="CustomButtonText" class="text-danger"></span>
|
<label asp-for="ShowDiscount" class="form-check-label"></label>
|
||||||
</div>
|
<span asp-validation-for="ShowDiscount" class="text-danger"></span>
|
||||||
<div class="form-group">
|
<div class="mt-2">
|
||||||
<label asp-for="CustomTipText" class="form-label" data-required></label>
|
<span class="text-secondary">Not recommended for customer self-checkout.</span>
|
||||||
<input asp-for="CustomTipText" class="form-control" required />
|
|
||||||
<span asp-validation-for="CustomTipText" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="CustomTipPercentages" class="form-label"></label>
|
|
||||||
<input asp-for="CustomTipPercentages" class="form-control" />
|
|
||||||
<span asp-validation-for="CustomTipPercentages" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="CustomCSSLink" class="form-label"></label>
|
|
||||||
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank" rel="noreferrer noopener">
|
|
||||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
|
||||||
</a>
|
|
||||||
<input asp-for="CustomCSSLink" class="form-control" />
|
|
||||||
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<partial name="TemplateEditor" model="@(nameof(Model.Template), "Products")" />
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="Template" class="form-label"></label>
|
|
||||||
<textarea asp-for="Template" rows="10" cols="40" class="js-product-template form-control"></textarea>
|
|
||||||
<span asp-validation-for="Template" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="NotificationUrl" class="form-label"></label>
|
|
||||||
<input asp-for="NotificationUrl" class="form-control" />
|
|
||||||
<span asp-validation-for="NotificationUrl" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="RedirectUrl" class="form-label"></label>
|
|
||||||
<input asp-for="RedirectUrl" class="form-control" />
|
|
||||||
<span asp-validation-for="RedirectUrl" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="RedirectAutomatically" class="form-label"></label>
|
|
||||||
<select asp-for="RedirectAutomatically" asp-items="Model.RedirectAutomaticallySelectList" class="form-select"></select>
|
|
||||||
<span asp-validation-for="RedirectAutomatically" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="Description" class="form-label"></label>
|
|
||||||
<textarea asp-for="Description" rows="10" cols="40" class="form-control richtext"></textarea>
|
|
||||||
<span asp-validation-for="Description" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="EmbeddedCSS" class="form-label"></label>
|
|
||||||
<textarea asp-for="EmbeddedCSS" rows="10" cols="40" class="form-control"></textarea>
|
|
||||||
<span asp-validation-for="EmbeddedCSS" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-primary" id="SaveSettings">Save Settings</button>
|
|
||||||
<div class="btn-group">
|
|
||||||
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
|
|
||||||
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm"
|
|
||||||
target="viewinvoices_@Model.Id"><span class="fa fa-external-link"></span></a>
|
|
||||||
</div>
|
|
||||||
<div class="btn-group">
|
|
||||||
<a class="btn btn-outline-primary" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id" id="ViewApp">View App</a>
|
|
||||||
<a class="btn btn-outline-primary" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id"
|
|
||||||
target="viewapp_@Model.Id"><span class="fa fa-external-link"></span></a>
|
|
||||||
</div>
|
|
||||||
<div class="btn-group">
|
|
||||||
<a class="btn btn-outline-primary" asp-action="ListApps">Back to the app list</a>
|
|
||||||
<a class="btn btn-outline-primary" asp-action="ListApps" target="viewapp_@Model.Id"><span class="fa fa-external-link"></span></a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<h4 class="mt-5 mb-4">Custom Payments</h4>
|
||||||
|
<div class="form-group mb-4 d-flex align-items-center">
|
||||||
|
<input asp-for="ShowCustomAmount" type="checkbox" class="btcpay-toggle me-2" data-bs-toggle="collapse" data-bs-target="#CustomAmountSettings" aria-expanded="@Model.ShowCustomAmount" aria-controls="CustomAmountSettings"/>
|
||||||
|
<label asp-for="ShowCustomAmount" class="form-label mb-0"></label>
|
||||||
|
<span asp-validation-for="ShowCustomAmount" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="collapse @(Model.ShowCustomAmount ? "show" : "")" id="CustomAmountSettings">
|
||||||
|
<div class="form-group mb-0 pb-3">
|
||||||
|
<label asp-for="CustomButtonText" class="form-label" data-required></label>
|
||||||
|
<input asp-for="CustomButtonText" class="form-control" required />
|
||||||
|
<span asp-validation-for="CustomButtonText" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 class="mt-5 mb-4">Tips</h4>
|
||||||
|
<div class="form-group mb-4 d-flex align-items-center">
|
||||||
|
<input asp-for="EnableTips" type="checkbox" class="btcpay-toggle me-2" data-bs-toggle="collapse" data-bs-target="#CustomTipsSettings" aria-expanded="@Model.EnableTips" aria-controls="CustomTipsSettings" />
|
||||||
|
<label asp-for="EnableTips" class="form-label mb-0"></label>
|
||||||
|
<span asp-validation-for="EnableTips" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="collapse @(Model.EnableTips ? "show" : "")" id="CustomTipsSettings">
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="CustomTipText" class="form-label" data-required></label>
|
||||||
|
<input asp-for="CustomTipText" class="form-control" required />
|
||||||
|
<span asp-validation-for="CustomTipText" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-0 pb-3">
|
||||||
|
<label asp-for="CustomTipPercentages" class="form-label"></label>
|
||||||
|
<input asp-for="CustomTipPercentages" class="form-control" />
|
||||||
|
<span asp-validation-for="CustomTipPercentages" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-9">
|
||||||
|
<h4 class="mt-5 mb-4">Additional Options</h4>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="accordion" id="accordion-dev-info">
|
<div class="accordion" id="accordion-dev-info">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header" id="accordion-dev-info-embed-payment-button-header">
|
<h2 class="accordion-header" id="accordion-dev-info-embed-payment-button-header">
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-embed-payment-button" aria-expanded="false" aria-controls="accordion-dev-info-embed-payment-button">
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-embed-payment-button" aria-expanded="false" aria-controls="accordion-dev-info-embed-payment-button">
|
||||||
Embed Payment Button linking to POS item
|
Embed a payment button linking to POS item
|
||||||
<vc:icon symbol="caret-down"/>
|
<vc:icon symbol="caret-down" />
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="accordion-dev-info-embed-payment-button" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-embed-payment-button-header" data-bs-parent="#accordion-dev-info">
|
<div id="accordion-dev-info-embed-payment-button" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-embed-payment-button-header">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<p>You can host point of sale buttons in an external website with the following code.</p>
|
<p>You can host point of sale buttons in an external website with the following code.</p>
|
||||||
@if (Model.Example1 != null)
|
@if (Model.Example1 != null)
|
||||||
@@ -153,13 +128,13 @@
|
|||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header" id="accordion-dev-info-embed-pos-iframe-header">
|
<h2 class="accordion-header" id="accordion-dev-info-embed-pos-iframe-header">
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-embed-pos-iframe" aria-expanded="false" aria-controls="accordion-dev-info-embed-pos-iframe">
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-embed-pos-iframe" aria-expanded="false" aria-controls="accordion-dev-info-embed-pos-iframe">
|
||||||
Embed POS with Iframe
|
Embed Point of Sale via Iframe
|
||||||
<vc:icon symbol="caret-down"/>
|
<vc:icon symbol="caret-down" />
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="accordion-dev-info-embed-pos-iframe" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-embed-pos-iframe-header" data-bs-parent="#accordion-dev-info">
|
<div id="accordion-dev-info-embed-pos-iframe" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-embed-pos-iframe-header">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
You can embed the POS using an iframe
|
You can embed this POS via an iframe.
|
||||||
@{
|
@{
|
||||||
var iframe = $"<iframe src='{(Url.Action("ViewPointOfSale", "AppsPublic", new { appId = Model.Id }, Context.Request.Scheme))}' style='max-width: 100%; border: 0;'></iframe>";
|
var iframe = $"<iframe src='{(Url.Action("ViewPointOfSale", "AppsPublic", new { appId = Model.Id }, Context.Request.Scheme))}' style='max-width: 100%; border: 0;'></iframe>";
|
||||||
}
|
}
|
||||||
@@ -168,14 +143,41 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header" id="accordion-dev-info-notification-header">
|
<h2 class="accordion-header" id="accordion-dev-info-redirect-header">
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-notification" aria-expanded="false" aria-controls="accordion-dev-info-notification">
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-redirect" aria-expanded="false" aria-controls="accordion-dev-info-redirect">
|
||||||
Notification Url Callbacks
|
Redirects
|
||||||
<vc:icon symbol="caret-down"/>
|
<vc:icon symbol="caret-down" />
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="accordion-dev-info-notification" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-notification-header" data-bs-parent="#accordion-dev-info">
|
<div id="accordion-dev-info-redirect" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-redirect-header">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="RedirectUrl" class="form-label"></label>
|
||||||
|
<input asp-for="RedirectUrl" class="form-control" />
|
||||||
|
<span asp-validation-for="RedirectUrl" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="RedirectAutomatically" class="form-label"></label>
|
||||||
|
<select asp-for="RedirectAutomatically" asp-items="Model.RedirectAutomaticallySelectList" class="form-select"></select>
|
||||||
|
<span asp-validation-for="RedirectAutomatically" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="accordion-dev-info-notification-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-notification" aria-expanded="false" aria-controls="accordion-dev-info-notification">
|
||||||
|
Notification URL Callbacks
|
||||||
|
<vc:icon symbol="caret-down" />
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="accordion-dev-info-notification" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-notification-header">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="NotificationUrl" class="form-label"></label>
|
||||||
|
<input asp-for="NotificationUrl" class="form-control" />
|
||||||
|
<span asp-validation-for="NotificationUrl" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
<p>A <code>POST</code> callback will be sent to notification with the following form will be sent to <code>notificationUrl</code> once the enough is paid and once again once there is enough confirmations to the payment:</p>
|
<p>A <code>POST</code> callback will be sent to notification with the following form will be sent to <code>notificationUrl</code> once the enough is paid and once again once there is enough confirmations to the payment:</p>
|
||||||
<pre><code class="json">@Model.ExampleCallback</code></pre>
|
<pre><code class="json">@Model.ExampleCallback</code></pre>
|
||||||
<p><strong>Never</strong> trust anything but <code>id</code>, <strong>ignore</strong> the other fields completely, an attacker can spoof those, they are present only for backward compatibility reason:</p>
|
<p><strong>Never</strong> trust anything but <code>id</code>, <strong>ignore</strong> the other fields completely, an attacker can spoof those, they are present only for backward compatibility reason:</p>
|
||||||
@@ -189,11 +191,53 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" id="accordion-dev-info-appearance-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-dev-info-appearance" aria-expanded="false" aria-controls="accordion-dev-info-appearance">
|
||||||
|
Custom CSS
|
||||||
|
<vc:icon symbol="caret-down" />
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="accordion-dev-info-appearance" class="accordion-collapse collapse" aria-labelledby="accordion-dev-info-redirect-header">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="CustomCSSLink" class="form-label"></label>
|
||||||
|
<a href="https://docs.btcpayserver.org/Theme/#2-bootstrap-themes" target="_blank" rel="noreferrer noopener">
|
||||||
|
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||||
|
</a>
|
||||||
|
<input asp-for="CustomCSSLink" class="form-control" />
|
||||||
|
<span asp-validation-for="CustomCSSLink" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="EmbeddedCSS" class="form-label"></label>
|
||||||
|
<textarea asp-for="EmbeddedCSS" rows="10" cols="40" class="form-control"></textarea>
|
||||||
|
<span asp-validation-for="EmbeddedCSS" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-primary" id="SaveSettings">Save Settings</button>
|
||||||
|
<div class="btn-group ms-2">
|
||||||
|
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
|
||||||
|
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm"
|
||||||
|
target="viewinvoices_@Model.Id"><span class="fa fa-external-link"></span></a>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group ms-2">
|
||||||
|
<a class="btn btn-outline-primary" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id" id="ViewApp">View App</a>
|
||||||
|
<a class="btn btn-outline-primary" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id"
|
||||||
|
target="viewapp_@Model.Id"><span class="fa fa-external-link"></span></a>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group ms-2">
|
||||||
|
<a class="btn btn-outline-primary" asp-action="ListApps">Back to the app list</a>
|
||||||
|
<a class="btn btn-outline-primary" asp-action="ListApps" target="viewapp_@Model.Id"><span class="fa fa-external-link"></span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,8 @@
|
|||||||
"outputFileName": "wwwroot/bundles/crowdfund-admin-bundle.min.css",
|
"outputFileName": "wwwroot/bundles/crowdfund-admin-bundle.min.css",
|
||||||
"inputFiles": [
|
"inputFiles": [
|
||||||
"wwwroot/vendor/highlightjs/default.min.css",
|
"wwwroot/vendor/highlightjs/default.min.css",
|
||||||
"wwwroot/vendor/summernote/summernote-bs5.css"
|
"wwwroot/vendor/summernote/summernote-bs5.css",
|
||||||
|
"wwwroot/main/template-editor.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,7 +121,8 @@
|
|||||||
"outputFileName": "wwwroot/bundles/pos-admin-bundle.min.css",
|
"outputFileName": "wwwroot/bundles/pos-admin-bundle.min.css",
|
||||||
"inputFiles": [
|
"inputFiles": [
|
||||||
"wwwroot/vendor/highlightjs/default.min.css",
|
"wwwroot/vendor/highlightjs/default.min.css",
|
||||||
"wwwroot/vendor/summernote/summernote-bs5.css"
|
"wwwroot/vendor/summernote/summernote-bs5.css",
|
||||||
|
"wwwroot/main/template-editor.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9615,7 +9615,7 @@ input[type=number].hide-number-spin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[data-required]::after {
|
[data-required]::after {
|
||||||
content: "*";
|
content: " *";
|
||||||
color: var(--btcpay-danger);
|
color: var(--btcpay-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
BTCPayServer/wwwroot/main/template-editor.css
Normal file
16
BTCPayServer/wwwroot/main/template-editor.css
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#template-editor-app .card-deck {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
grid-gap: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#template-editor-app .card-deck .card{
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#template-editor-app .card-img-top {
|
||||||
|
min-height: 247px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size:contain;
|
||||||
|
background-position: top;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user