mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 01:43:50 +01:00
Store Branding: Apply brand color to backend as well (#5992)
* Store Branding: Apply brand color to backend as well Closes #5990. * Add adjustments for different theme scenarios * Add description text * Make it optional to apply the brand color to the backend * Toggle color fixes
This commit is contained in:
parent
b7ba53eb60
commit
7348a6a62f
@ -17,6 +17,7 @@ namespace BTCPayServer.Client.Models
|
||||
public string Website { get; set; }
|
||||
|
||||
public string BrandColor { get; set; }
|
||||
public bool ApplyBrandColorToBackend { get; set; }
|
||||
public string LogoUrl { get; set; }
|
||||
public string CssUrl { get; set; }
|
||||
public string PaymentSoundUrl { get; set; }
|
||||
|
@ -1622,6 +1622,7 @@ namespace BTCPayServer.Tests
|
||||
CssUrl = "https://example.org/style.css",
|
||||
LogoUrl = "https://example.org/logo.svg",
|
||||
BrandColor = "#003366",
|
||||
ApplyBrandColorToBackend = true,
|
||||
PaymentMethodCriteria = new List<PaymentMethodCriteriaData>
|
||||
{
|
||||
new()
|
||||
@ -1637,6 +1638,7 @@ namespace BTCPayServer.Tests
|
||||
Assert.Equal("https://example.org/style.css", updatedStore.CssUrl);
|
||||
Assert.Equal("https://example.org/logo.svg", updatedStore.LogoUrl);
|
||||
Assert.Equal("#003366", updatedStore.BrandColor);
|
||||
Assert.True(updatedStore.ApplyBrandColorToBackend);
|
||||
var s = (await client.GetStore(newStore.Id));
|
||||
Assert.Equal("B", s.Name);
|
||||
var pmc = Assert.Single(s.PaymentMethodCriteria);
|
||||
|
@ -175,6 +175,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
Website = data.StoreWebsite,
|
||||
Archived = data.Archived,
|
||||
BrandColor = storeBlob.BrandColor,
|
||||
ApplyBrandColorToBackend = storeBlob.ApplyBrandColorToBackend,
|
||||
CssUrl = storeBlob.CssUrl == null ? null : await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), storeBlob.CssUrl),
|
||||
LogoUrl = storeBlob.LogoUrl == null ? null : await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), storeBlob.LogoUrl),
|
||||
PaymentSoundUrl = storeBlob.PaymentSoundUrl == null ? null : await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), storeBlob.PaymentSoundUrl),
|
||||
@ -255,6 +256,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
blob.PaymentTolerance = restModel.PaymentTolerance;
|
||||
blob.PayJoinEnabled = restModel.PayJoinEnabled;
|
||||
blob.BrandColor = restModel.BrandColor;
|
||||
blob.ApplyBrandColorToBackend = restModel.ApplyBrandColorToBackend;
|
||||
blob.LogoUrl = restModel.LogoUrl is null ? null : UnresolvedUri.Create(restModel.LogoUrl);
|
||||
blob.CssUrl = restModel.CssUrl is null ? null : UnresolvedUri.Create(restModel.CssUrl);
|
||||
blob.PaymentSoundUrl = restModel.PaymentSoundUrl is null ? null : UnresolvedUri.Create(restModel.PaymentSoundUrl);
|
||||
|
@ -34,6 +34,7 @@ public partial class UIStoresController
|
||||
LogoUrl = await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), storeBlob.LogoUrl),
|
||||
CssUrl = await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), storeBlob.CssUrl),
|
||||
BrandColor = storeBlob.BrandColor,
|
||||
ApplyBrandColorToBackend = storeBlob.ApplyBrandColorToBackend,
|
||||
NetworkFeeMode = storeBlob.NetworkFeeMode,
|
||||
AnyoneCanCreateInvoice = storeBlob.AnyoneCanInvoice,
|
||||
PaymentTolerance = storeBlob.PaymentTolerance,
|
||||
@ -75,10 +76,11 @@ public partial class UIStoresController
|
||||
blob.RefundBOLT11Expiration = TimeSpan.FromDays(model.BOLT11Expiration);
|
||||
if (!string.IsNullOrEmpty(model.BrandColor) && !ColorPalette.IsValid(model.BrandColor))
|
||||
{
|
||||
ModelState.AddModelError(nameof(model.BrandColor), "Invalid color");
|
||||
ModelState.AddModelError(nameof(model.BrandColor), "The brand color needs to be a valid hex color code");
|
||||
return View(model);
|
||||
}
|
||||
blob.BrandColor = model.BrandColor;
|
||||
blob.ApplyBrandColorToBackend = model.ApplyBrandColorToBackend && !string.IsNullOrEmpty(model.BrandColor);
|
||||
|
||||
var userId = GetUserId();
|
||||
if (userId is null)
|
||||
|
@ -191,6 +191,8 @@ namespace BTCPayServer.Data
|
||||
|
||||
public List<UIStoresController.StoreEmailRule> EmailRules { get; set; }
|
||||
public string BrandColor { get; set; }
|
||||
public bool ApplyBrandColorToBackend { get; set; }
|
||||
|
||||
[JsonConverter(typeof(UnresolvedUriJsonConverter))]
|
||||
public UnresolvedUri LogoUrl { get; set; }
|
||||
[JsonConverter(typeof(UnresolvedUriJsonConverter))]
|
||||
|
@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Data;
|
||||
@ -10,6 +9,7 @@ namespace BTCPayServer.Models;
|
||||
public class StoreBrandingViewModel
|
||||
{
|
||||
public string BrandColor { get; set; }
|
||||
public bool ApplyBrandColorToBackend { get; set; }
|
||||
public string LogoUrl { get; set; }
|
||||
public string CssUrl { get; set; }
|
||||
|
||||
@ -20,13 +20,16 @@ public class StoreBrandingViewModel
|
||||
{
|
||||
if (storeBlob == null)
|
||||
return new StoreBrandingViewModel();
|
||||
var result = new StoreBrandingViewModel(storeBlob);
|
||||
result.LogoUrl = await uriResolver.Resolve(request.GetAbsoluteRootUri(), storeBlob.LogoUrl);
|
||||
result.CssUrl = await uriResolver.Resolve(request.GetAbsoluteRootUri(), storeBlob.CssUrl);
|
||||
var result = new StoreBrandingViewModel(storeBlob)
|
||||
{
|
||||
LogoUrl = await uriResolver.Resolve(request.GetAbsoluteRootUri(), storeBlob.LogoUrl),
|
||||
CssUrl = await uriResolver.Resolve(request.GetAbsoluteRootUri(), storeBlob.CssUrl)
|
||||
};
|
||||
return result;
|
||||
}
|
||||
private StoreBrandingViewModel(StoreBlob storeBlob)
|
||||
{
|
||||
BrandColor = storeBlob.BrandColor;
|
||||
ApplyBrandColorToBackend = storeBlob.ApplyBrandColorToBackend;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ namespace BTCPayServer.Models.StoreViewModels
|
||||
[Display(Name = "Brand Color")]
|
||||
public string BrandColor { get; set; }
|
||||
|
||||
[Display(Name = "Apply the brand color to the store's backend as well")]
|
||||
public bool ApplyBrandColorToBackend { get; set; }
|
||||
|
||||
[Display(Name = "Logo")]
|
||||
public IFormFile LogoFile { get; set; }
|
||||
public string LogoUrl { get; set; }
|
||||
|
@ -1,4 +1,17 @@
|
||||
@inject BTCPayServer.Services.PoliciesSettings PoliciesSettings
|
||||
@using BTCPayServer.Services
|
||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@inject PoliciesSettings PoliciesSettings
|
||||
@inject UriResolver UriResolver
|
||||
@{
|
||||
ViewData.TryGetValue("StoreBranding", out var storeBranding);
|
||||
var store = Context.GetStoreData();
|
||||
var storeBlob = store?.GetStoreBlob();
|
||||
var isBackend = store != null && storeBranding == null;
|
||||
if (isBackend && storeBlob.ApplyBrandColorToBackend)
|
||||
{
|
||||
storeBranding = await StoreBrandingViewModel.CreateAsync(Context.Request, UriResolver, storeBlob);
|
||||
}
|
||||
}
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
@if (PoliciesSettings.DiscourageSearchEngines)
|
||||
@ -14,7 +27,7 @@
|
||||
<link href="~/main/site.css" asp-append-version="true" rel="stylesheet" />
|
||||
|
||||
<partial name="LayoutHeadTheme" />
|
||||
@if (ViewData.TryGetValue("StoreBranding", out var storeBranding) && storeBranding != null)
|
||||
@if (storeBranding != null)
|
||||
{
|
||||
<partial name="LayoutHeadStoreBranding" model="storeBranding" />
|
||||
}
|
||||
|
@ -1,10 +1,17 @@
|
||||
@using BTCPayServer.Services
|
||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@model StoreBrandingViewModel
|
||||
@inject ThemeSettings Theme
|
||||
@if (!string.IsNullOrEmpty(Model.BrandColor))
|
||||
{
|
||||
var hasCustomeTheme = Theme.CustomTheme && Theme.CustomThemeCssUrl is not null;
|
||||
var brand = Model.BrandColor;
|
||||
var brandColor = ColorPalette.Default.FromHtml(brand);
|
||||
var brandRgbValues = $"{brandColor.R}, {brandColor.G}, {brandColor.B}";
|
||||
var accent = ColorPalette.Default.AdjustBrightness(brand, (float)-0.15);
|
||||
var brightness = brandColor.GetBrightness();
|
||||
var accent = ColorPalette.Default.AdjustBrightness(brand, (float)-.15);
|
||||
var accentColor = ColorPalette.Default.FromHtml(accent);
|
||||
var accentRgbValues = $"{accentColor.R}, {accentColor.G}, {accentColor.B}";
|
||||
var complement = ColorPalette.Default.TextColor(brand);
|
||||
var complementVar = $"var(--btcpay-{(complement == "black" ? "black" : "white")})";
|
||||
<style>
|
||||
@ -14,19 +21,93 @@
|
||||
--btcpay-primary-shadow: @brand;
|
||||
--btcpay-primary-bg-hover: @accent;
|
||||
--btcpay-primary-bg-active: @accent;
|
||||
--btcpay-body-link: @brand;
|
||||
--btcpay-body-link-accent: @accent;
|
||||
--btcpay-body-link-accent-rgb: @accentRgbValues;
|
||||
--btcpay-primary-text: @complementVar;
|
||||
--btcpay-primary-text-hover: @complementVar;
|
||||
--btcpay-primary-text-active: @complementVar;
|
||||
}
|
||||
a {
|
||||
color: var(--btcpay-body-link);
|
||||
}
|
||||
a:hover {
|
||||
color: var(--btcpay-body-link-accent);
|
||||
}
|
||||
</style>
|
||||
@if (brightness > .5 || (Theme.CustomThemeExtension == ThemeExtension.Dark && brightness < .5))
|
||||
{
|
||||
var brandAdjusted = ColorPalette.Default.AdjustBrightness(brand, (float)(.35-brightness));
|
||||
var brandColorAdjusted = ColorPalette.Default.FromHtml(brandAdjusted);
|
||||
var brandRgbValuesAdjusted = $"{brandColorAdjusted.R}, {brandColorAdjusted.G}, {brandColorAdjusted.B}";
|
||||
var accentAdjusted = ColorPalette.Default.AdjustBrightness(brandAdjusted, (float)-.15);
|
||||
var accentColorAdjusted = ColorPalette.Default.FromHtml(accentAdjusted);
|
||||
var accentRgbValuesAdjusted = $"{accentColorAdjusted.R}, {accentColorAdjusted.G}, {accentColorAdjusted.B}";
|
||||
var complementAdjusted = ColorPalette.Default.TextColor(brandAdjusted);
|
||||
var complementVarAdjusted = $"var(--btcpay-{(complementAdjusted == "black" ? "black" : "white")})";
|
||||
<style>
|
||||
:root[data-theme='light'],
|
||||
:root[data-btcpay-theme='light'] {
|
||||
--btcpay-primary: @brandAdjusted;
|
||||
--btcpay-primary-rgb: @brandRgbValuesAdjusted;
|
||||
--btcpay-primary-shadow: @brandAdjusted;
|
||||
--btcpay-primary-bg-hover: @accentAdjusted;
|
||||
--btcpay-primary-bg-active: @accentAdjusted;
|
||||
--btcpay-body-link-accent: @accentAdjusted;
|
||||
--btcpay-body-link-accent-rgb: @accentRgbValuesAdjusted;
|
||||
--btcpay-primary-text: @complementVarAdjusted;
|
||||
--btcpay-primary-text-hover: @complementVarAdjusted;
|
||||
--btcpay-primary-text-active: @complementVarAdjusted;
|
||||
}
|
||||
@@media (prefers-color-scheme: light) {
|
||||
:root:not([data-btcpay-theme], [data-theme]) {
|
||||
--btcpay-primary: @brandAdjusted;
|
||||
--btcpay-primary-rgb: @brandRgbValuesAdjusted;
|
||||
--btcpay-primary-shadow: @brandAdjusted;
|
||||
--btcpay-primary-bg-hover: @accentAdjusted;
|
||||
--btcpay-primary-bg-active: @accentAdjusted;
|
||||
--btcpay-body-link-accent: @accentAdjusted;
|
||||
--btcpay-body-link-accent-rgb: @accentRgbValuesAdjusted;
|
||||
--btcpay-primary-text: @complementVarAdjusted;
|
||||
--btcpay-primary-text-hover: @complementVarAdjusted;
|
||||
--btcpay-primary-text-active: @complementVarAdjusted;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
}
|
||||
@if (brightness < .5 && (!hasCustomeTheme || Theme.CustomThemeExtension == ThemeExtension.Dark))
|
||||
{
|
||||
var brandAdjusted = ColorPalette.Default.AdjustBrightness(brand, (float)(.5-brightness));
|
||||
var brandColorAdjusted = ColorPalette.Default.FromHtml(brandAdjusted);
|
||||
var brandRgbValuesAdjusted = $"{brandColorAdjusted.R}, {brandColorAdjusted.G}, {brandColorAdjusted.B}";
|
||||
var accentAdjusted = ColorPalette.Default.AdjustBrightness(brandAdjusted, (float).15);
|
||||
var accentColorAdjusted = ColorPalette.Default.FromHtml(accentAdjusted);
|
||||
var accentRgbValuesAdjusted = $"{accentColorAdjusted.R}, {accentColorAdjusted.G}, {accentColorAdjusted.B}";
|
||||
var complementAdjusted = ColorPalette.Default.TextColor(brandAdjusted);
|
||||
var complementVarAdjusted = $"var(--btcpay-{(complementAdjusted == "black" ? "black" : "white")})";
|
||||
<style>
|
||||
:root[data-theme='dark'],
|
||||
:root[data-btcpay-theme='dark'] {
|
||||
--btcpay-primary: @brandAdjusted;
|
||||
--btcpay-primary-rgb: @brandRgbValuesAdjusted;
|
||||
--btcpay-primary-shadow: @brandAdjusted;
|
||||
--btcpay-primary-bg-hover: @accentAdjusted;
|
||||
--btcpay-primary-bg-active: @accentAdjusted;
|
||||
--btcpay-body-link-accent: @accentAdjusted;
|
||||
--btcpay-body-link-accent-rgb: @accentRgbValuesAdjusted;
|
||||
--btcpay-primary-text: @complementVarAdjusted;
|
||||
--btcpay-primary-text-hover: @complementVarAdjusted;
|
||||
--btcpay-primary-text-active: @complementVarAdjusted;
|
||||
}
|
||||
@@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-btcpay-theme], [data-theme]) {
|
||||
--btcpay-primary: @brandAdjusted;
|
||||
--btcpay-primary-rgb: @brandRgbValuesAdjusted;
|
||||
--btcpay-primary-shadow: @brandAdjusted;
|
||||
--btcpay-primary-bg-hover: @accentAdjusted;
|
||||
--btcpay-primary-bg-active: @accentAdjusted;
|
||||
--btcpay-body-link-accent: @accentAdjusted;
|
||||
--btcpay-body-link-accent-rgb: @accentRgbValuesAdjusted;
|
||||
--btcpay-primary-text: @complementVarAdjusted;
|
||||
--btcpay-primary-text-hover: @complementVarAdjusted;
|
||||
--btcpay-primary-text-active: @complementVarAdjusted;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
}
|
||||
<meta name="theme-color" content="@brand">
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(Model.CssUrl))
|
||||
|
@ -21,7 +21,7 @@
|
||||
<div class="col-xxl-constrain col-xl-8">
|
||||
@if (!ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div asp-validation-summary="All"></div>
|
||||
<div asp-validation-summary="All" class="@(ViewContext.ModelState.ErrorCount.Equals(1) ? "no-marker" : "")"></div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<label asp-for="Id" class="form-label"></label>
|
||||
@ -38,15 +38,29 @@
|
||||
<span asp-validation-for="StoreWebsite" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5 mb-3" text-translate="true">Branding</h3>
|
||||
<div class="form-group">
|
||||
<h3 class="mt-5 mb-3" text-translate="true">Branding</h3>
|
||||
<p>
|
||||
The custom color, logo and CSS are applied on the public/customer-facing pages (Invoice, Payment Request, Pull Payment, etc.).
|
||||
The brand color is used as the accent color for buttons, links, etc. It might get adapted to fit the light/dark color scheme.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<label asp-for="BrandColor" class="form-label"></label>
|
||||
<div class="input-group">
|
||||
<input id="BrandColorInput" class="form-control form-control-color flex-grow-0" type="color" style="width:3rem" aria-describedby="BrandColorValue" value="@Model.BrandColor" />
|
||||
<input asp-for="BrandColor" class="form-control form-control-color flex-grow-0 font-monospace" pattern="@ColorPalette.Pattern" style="width:5.5rem;font-size:0.9rem" />
|
||||
<div class="d-flex flex-wrap">
|
||||
<div class="form-group me-4">
|
||||
<div class="input-group">
|
||||
<input id="BrandColorInput" class="form-control form-control-color flex-grow-0" type="color" style="width:3rem" aria-describedby="BrandColorValue" value="@Model.BrandColor" />
|
||||
<input asp-for="BrandColor" class="form-control form-control-color flex-grow-0 font-monospace" pattern="@ColorPalette.Pattern" style="width:5.5rem;font-size:0.9rem" />
|
||||
</div>
|
||||
<span asp-validation-for="BrandColor" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group d-flex align-items-center">
|
||||
<input asp-for="ApplyBrandColorToBackend" type="checkbox" class="btcpay-toggle me-3" disabled="@(string.IsNullOrEmpty(Model.BrandColor))"/>
|
||||
<label asp-for="ApplyBrandColorToBackend" class="form-check-label"></label>
|
||||
</div>
|
||||
</div>
|
||||
<span asp-validation-for="BrandColor" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="d-flex align-items-center justify-content-between gap-2">
|
||||
<label asp-for="LogoFile" class="form-label"></label>
|
||||
@ -94,9 +108,6 @@
|
||||
}
|
||||
</div>
|
||||
<span asp-validation-for="LogoFile" class="text-danger"></span>
|
||||
<div class="form-text">
|
||||
Use this CSS to customize the public/customer-facing pages of this store. (Invoice, Payment Request, Pull Payment, etc.)
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -193,13 +204,17 @@
|
||||
(() => {
|
||||
const $colorValue = document.getElementById('BrandColor');
|
||||
const $colorInput = document.getElementById('BrandColorInput');
|
||||
const $applyToBackend = document.getElementById('ApplyBrandColorToBackend');
|
||||
delegate('change', '#BrandColor', e => {
|
||||
const value = e.target.value;
|
||||
if (value.match(@Safe.Json(@ColorPalette.Pattern)))
|
||||
if (value.match(@Safe.Json(ColorPalette.Pattern)))
|
||||
$colorInput.value = value;
|
||||
$applyToBackend.disabled = !value;
|
||||
});
|
||||
delegate('change', '#BrandColorInput', e => {
|
||||
$colorValue.value = e.target.value;
|
||||
const value = e.target.value;
|
||||
$colorValue.value = value;
|
||||
$applyToBackend.disabled = !value;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
@ -12840,7 +12840,7 @@ input[type='number'].hide-number-spin {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btcpay-toggle:hover {
|
||||
.btcpay-toggle:not(:disabled):hover {
|
||||
background: var(--btcpay-toggle-bg-hover);
|
||||
}
|
||||
|
||||
@ -12855,8 +12855,8 @@ input.btcpay-toggle:checked,
|
||||
background: var(--btcpay-toggle-bg-active);
|
||||
}
|
||||
|
||||
input.btcpay-toggle:checked:hover,
|
||||
.btcpay-toggle.btcpay-toggle--active:hover {
|
||||
input.btcpay-toggle:not(:disabled):checked:hover,
|
||||
.btcpay-toggle.btcpay-toggle--active:not(:disabled):hover {
|
||||
background: var(--btcpay-toggle-bg-active-hover);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Variables */
|
||||
:root {
|
||||
--chart-main-rgb: 68, 164, 49;
|
||||
--chart-main-rgb: var(--btcpay-primary-rgb);
|
||||
--chart-series-a-rgb: var(--chart-main-rgb);
|
||||
--chart-series-b-rgb: 245, 0, 0;
|
||||
--chart-series-c-rgb: 0, 109, 242;
|
||||
@ -186,8 +186,8 @@ h2 .icon.icon-info {
|
||||
top: -.0125em;
|
||||
}
|
||||
|
||||
#descriptor p {
|
||||
max-width: 40em;
|
||||
#mainContent section p {
|
||||
max-width: 46em;
|
||||
}
|
||||
|
||||
/* Invoices */
|
||||
|
@ -239,9 +239,9 @@
|
||||
--btcpay-form-shadow-invalid: var(--btcpay-danger-shadow);
|
||||
|
||||
--btcpay-toggle-bg: var(--btcpay-neutral-500);
|
||||
--btcpay-toggle-bg-hover: var(--btcpay-neutral-600);
|
||||
--btcpay-toggle-bg-hover: var(--btcpay-primary-bg-hover);
|
||||
--btcpay-toggle-bg-active: var(--btcpay-primary);
|
||||
--btcpay-toggle-bg-active-hover: var(--btcpay-primary-600);
|
||||
--btcpay-toggle-bg-active-hover: var(--btcpay-primary-bg-active);
|
||||
|
||||
--btcpay-footer-bg: var(--btcpay-body-bg);
|
||||
--btcpay-footer-text: var(--btcpay-body-text-muted);
|
||||
|
@ -509,6 +509,11 @@
|
||||
"nullable": true,
|
||||
"example": "#F7931A"
|
||||
},
|
||||
"applyBrandColorToBackend": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Apply the brand color to the store's backend as well"
|
||||
},
|
||||
"defaultCurrency": {
|
||||
"type": "string",
|
||||
"description": "The default currency of the store",
|
||||
|
Loading…
Reference in New Issue
Block a user