mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Sticky headers (#3416)
* Make headers sticky Closes #3344. * Decrease headline margin bottom on mobile * increases gap * adds bottom padding * Update BTCPayServer/Views/UIApps/UpdatePointOfSale.cshtml * add "_blank" to view action * Fix markup and tests * Spacing updates * Try test fix * Re-add sticky account header and add test logs for timeout check * Fix timeout issues * Apply scroll padding on pages with sticky header Co-authored-by: dstrukt <gfxdsign@gmail.com> Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
This commit is contained in:
parent
c652a2f122
commit
20a9472ee2
10 changed files with 276 additions and 291 deletions
|
@ -47,6 +47,7 @@ namespace BTCPayServer.Tests
|
|||
s.GoToProfile(ManageNavPages.APIKeys);
|
||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||
|
||||
TestLogs.LogInformation("Checking admin permissions");
|
||||
//not an admin, so this permission should not show
|
||||
Assert.DoesNotContain("btcpay.server.canmodifyserversettings", s.Driver.PageSource);
|
||||
await user.MakeAdmin();
|
||||
|
@ -56,30 +57,34 @@ namespace BTCPayServer.Tests
|
|||
s.GoToProfile(ManageNavPages.APIKeys);
|
||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||
Assert.Contains("btcpay.server.canmodifyserversettings", s.Driver.PageSource);
|
||||
|
||||
//server management should show now
|
||||
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true);
|
||||
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
|
||||
s.Driver.SetCheckbox(By.Id("btcpay.user.canviewprofile"), true);
|
||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||
var superApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||
|
||||
TestLogs.LogInformation("Checking super admin key");
|
||||
|
||||
//this api key has access to everything
|
||||
await TestApiAgainstAccessToken(superApiKey, tester, user, Policies.CanModifyServerSettings, Policies.CanModifyStoreSettings, Policies.CanViewProfile);
|
||||
|
||||
|
||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||
s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true);
|
||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||
var serverOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||
|
||||
TestLogs.LogInformation("Checking CanModifyServerSettings permissions");
|
||||
|
||||
await TestApiAgainstAccessToken(serverOnlyApiKey, tester, user,
|
||||
Policies.CanModifyServerSettings);
|
||||
|
||||
|
||||
|
||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||
s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true);
|
||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||
var allStoreOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||
|
||||
TestLogs.LogInformation("Checking CanModifyStoreSettings permissions");
|
||||
|
||||
await TestApiAgainstAccessToken(allStoreOnlyApiKey, tester, user,
|
||||
Policies.CanModifyStoreSettings);
|
||||
|
||||
|
@ -97,12 +102,18 @@ namespace BTCPayServer.Tests
|
|||
option.Click();
|
||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||
var selectiveStoreApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||
|
||||
TestLogs.LogInformation("Checking CanModifyStoreSettings with StoreId permissions");
|
||||
|
||||
await TestApiAgainstAccessToken(selectiveStoreApiKey, tester, user,
|
||||
Permission.Create(Policies.CanModifyStoreSettings, storeId).ToString());
|
||||
|
||||
s.Driver.FindElement(By.Id("AddApiKey")).Click();
|
||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||
var noPermissionsApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||
|
||||
TestLogs.LogInformation("Checking no permissions");
|
||||
|
||||
await TestApiAgainstAccessToken(noPermissionsApiKey, tester, user);
|
||||
|
||||
await Assert.ThrowsAnyAsync<HttpRequestException>(async () =>
|
||||
|
@ -110,6 +121,8 @@ namespace BTCPayServer.Tests
|
|||
await TestApiAgainstAccessToken<bool>("incorrect key", $"{TestApiPath}/me/id",
|
||||
tester.PayTester.HttpClient);
|
||||
});
|
||||
|
||||
TestLogs.LogInformation("Checking authorize screen");
|
||||
|
||||
//let's test the authorized screen now
|
||||
//options for authorize are:
|
||||
|
@ -157,6 +170,9 @@ namespace BTCPayServer.Tests
|
|||
Assert.Equal(callbackUrl, s.Driver.Url);
|
||||
|
||||
accessToken = GetAccessTokenFromCallbackResult(s.Driver);
|
||||
|
||||
TestLogs.LogInformation("Checking authorized permissions");
|
||||
|
||||
await TestApiAgainstAccessToken(accessToken, tester, user,
|
||||
(await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions);
|
||||
|
||||
|
@ -191,7 +207,10 @@ namespace BTCPayServer.Tests
|
|||
}
|
||||
s.Driver.FindElement(By.Id("Generate")).Click();
|
||||
var allAPIKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text;
|
||||
var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(allAPIKey, $"api/v1/api-keys/current", tester.PayTester.HttpClient);
|
||||
|
||||
TestLogs.LogInformation("Checking API key permissions");
|
||||
|
||||
var apikeydata = await TestApiAgainstAccessToken<ApiKeyData>(allAPIKey, "api/v1/api-keys/current", tester.PayTester.HttpClient);
|
||||
Assert.Equal(checkedPermissionCount, apikeydata.Permissions.Length);
|
||||
}
|
||||
|
||||
|
|
|
@ -135,6 +135,15 @@ retry:
|
|||
}
|
||||
public static void WaitForAndClick(this IWebDriver driver, By selector)
|
||||
{
|
||||
// Try fast path
|
||||
try
|
||||
{
|
||||
driver.FindElement(selector).Click();
|
||||
return;
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Sometimes, selenium complain, so we enter hack territory
|
||||
var wait = new WebDriverWait(driver, SeleniumTester.ImplicitWait);
|
||||
wait.UntilJsIsReady();
|
||||
|
||||
|
@ -158,22 +167,8 @@ retry:
|
|||
public static void SetCheckbox(this IWebDriver driver, By selector, bool value)
|
||||
{
|
||||
var element = driver.FindElement(selector);
|
||||
if ((value && !element.Selected) || (!value && element.Selected))
|
||||
{
|
||||
try
|
||||
{
|
||||
driver.WaitForAndClick(selector);
|
||||
}
|
||||
catch (ElementClickInterceptedException)
|
||||
{
|
||||
element.SendKeys(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if (value != element.Selected)
|
||||
{
|
||||
driver.SetCheckbox(selector, value);
|
||||
}
|
||||
driver.WaitForAndClick(selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -585,6 +585,8 @@ namespace BTCPayServer.Tests
|
|||
s.Driver.FindElement(By.Name("AppName")).SendKeys("PoS" + Guid.NewGuid());
|
||||
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Point of Sale");
|
||||
s.Driver.FindElement(By.Id("Create")).Click();
|
||||
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
||||
|
||||
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();
|
||||
|
@ -595,9 +597,14 @@ namespace BTCPayServer.Tests
|
|||
|
||||
s.Driver.FindElement(By.Id("DefaultView")).SendKeys("Item list and cart");
|
||||
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||
s.Driver.FindElement(By.Id("ViewApp")).Click();
|
||||
Assert.Contains("App updated", s.FindAlertMessage().Text);
|
||||
|
||||
var posBaseUrl = s.Driver.Url.Replace("/Cart", "");
|
||||
s.Driver.FindElement(By.Id("ViewApp")).Click();
|
||||
var windows = s.Driver.WindowHandles;
|
||||
Assert.Equal(2, windows.Count);
|
||||
s.Driver.SwitchTo().Window(windows[1]);
|
||||
|
||||
var posBaseUrl = s.Driver.Url.Replace("/cart", "");
|
||||
Assert.True(s.Driver.PageSource.Contains("Tea shop"), "Unable to create PoS");
|
||||
Assert.True(s.Driver.PageSource.Contains("Cart"), "PoS not showing correct default view");
|
||||
Assert.True(s.Driver.PageSource.Contains("Take my money"), "PoS not showing correct default view");
|
||||
|
@ -607,6 +614,9 @@ namespace BTCPayServer.Tests
|
|||
|
||||
s.Driver.Url = posBaseUrl + "/cart";
|
||||
Assert.True(s.Driver.PageSource.Contains("Cart"), "Cart PoS not showing correct view");
|
||||
|
||||
s.Driver.Close();
|
||||
s.Driver.SwitchTo().Window(windows[0]);
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
|
@ -622,14 +632,26 @@ namespace BTCPayServer.Tests
|
|||
s.Driver.FindElement(By.Name("AppName")).SendKeys("CF" + Guid.NewGuid());
|
||||
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Crowdfund");
|
||||
s.Driver.FindElement(By.Id("Create")).Click();
|
||||
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
||||
|
||||
s.Driver.FindElement(By.Id("Title")).SendKeys("Kukkstarter");
|
||||
s.Driver.FindElement(By.CssSelector("div.note-editable.card-block")).SendKeys("1BTC = 1BTC");
|
||||
s.Driver.FindElement(By.Id("TargetCurrency")).Clear();
|
||||
s.Driver.FindElement(By.Id("TargetCurrency")).SendKeys("JPY");
|
||||
s.Driver.FindElement(By.Id("TargetAmount")).SendKeys("700");
|
||||
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||
Assert.Contains("App updated", s.FindAlertMessage().Text);
|
||||
|
||||
s.Driver.FindElement(By.Id("ViewApp")).Click();
|
||||
var windows = s.Driver.WindowHandles;
|
||||
Assert.Equal(2, windows.Count);
|
||||
s.Driver.SwitchTo().Window(windows[1]);
|
||||
|
||||
Assert.Equal("currently active!",
|
||||
s.Driver.FindElement(By.CssSelector("[data-test='time-state']")).Text);
|
||||
|
||||
s.Driver.Close();
|
||||
s.Driver.SwitchTo().Window(windows[0]);
|
||||
}
|
||||
|
||||
[Fact(Timeout = TestTimeout)]
|
||||
|
@ -1529,10 +1551,19 @@ namespace BTCPayServer.Tests
|
|||
s.Driver.FindElement(By.Name("AppName")).SendKeys("CF" + Guid.NewGuid());
|
||||
s.Driver.FindElement(By.Id("SelectedAppType")).SendKeys("Crowdfund");
|
||||
s.Driver.FindElement(By.Id("Create")).Click();
|
||||
Assert.Contains("App successfully created", s.FindAlertMessage().Text);
|
||||
|
||||
s.Driver.FindElement(By.Id("Title")).SendKeys("Kukkstarter");
|
||||
s.Driver.FindElement(By.CssSelector("div.note-editable.card-block")).SendKeys("1BTC = 1BTC");
|
||||
s.Driver.FindElement(By.Id("SaveSettings")).Click();
|
||||
Assert.Contains("App updated", s.FindAlertMessage().Text);
|
||||
|
||||
s.Driver.FindElement(By.Id("ViewApp")).Click();
|
||||
|
||||
var windows = s.Driver.WindowHandles;
|
||||
Assert.Equal(2, windows.Count);
|
||||
s.Driver.SwitchTo().Window(windows[1]);
|
||||
|
||||
s.Driver.FindElement(By.CssSelector("#crowdfund-body-contribution-container .perk")).Click();
|
||||
s.Driver.FindElement(By.PartialLinkText("LNURL")).Click();
|
||||
lnurl = s.Driver.FindElement(By.ClassName("lnurl"))
|
||||
|
@ -1540,7 +1571,8 @@ namespace BTCPayServer.Tests
|
|||
|
||||
LNURL.LNURL.Parse(lnurl, out tag);
|
||||
|
||||
|
||||
s.Driver.Close();
|
||||
s.Driver.SwitchTo().Window(windows[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1552,7 +1584,6 @@ namespace BTCPayServer.Tests
|
|||
s.Server.ActivateLightning();
|
||||
await s.StartAsync();
|
||||
await s.Server.EnsureChannelsSetup();
|
||||
var cryptoCode = "BTC";
|
||||
s.RegisterNewUser(true);
|
||||
//ln address tests
|
||||
s.CreateNewStore();
|
||||
|
|
|
@ -14,11 +14,26 @@
|
|||
<bundle name="wwwroot/bundles/crowdfund-admin-bundle.min.js" asp-append-version="true"></bundle>
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mt-1 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<form method="post">
|
||||
<div class="sticky-header-setup"></div>
|
||||
<header class="sticky-header d-sm-flex align-items-center justify-content-between">
|
||||
<h2 class="mb-0">@ViewData["Title"]</h2>
|
||||
<div class="d-flex gap-3 mt-3 mt-sm-0">
|
||||
<button type="submit" class="btn btn-primary order-sm-1" id="SaveSettings">Save</button>
|
||||
@if (Model.ModelWithMinimumData)
|
||||
{
|
||||
<a class="btn btn-secondary" asp-action="ViewCrowdfund" asp-controller="UIAppsPublic" asp-route-appId="@Model.AppId" id="ViewApp" target="app_@Model.AppId">View</a>
|
||||
}
|
||||
<a class="btn btn-secondary" asp-action="ListInvoices" asp-controller="UIInvoice" asp-route-storeId="@Model.StoreId" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
|
||||
</div>
|
||||
</header>
|
||||
<script>
|
||||
const { offsetHeight } = document.querySelector('.sticky-header-setup + .sticky-header');
|
||||
document.documentElement.style.scrollPaddingTop = `calc(${offsetHeight}px + var(--btcpay-space-m))`;
|
||||
</script>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<input type="hidden" asp-for="StoreId" />
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
|
||||
|
@ -123,6 +138,7 @@
|
|||
<textarea asp-for="PerksTemplate" rows="10" cols="40" class="js-product-template form-control"></textarea>
|
||||
<span asp-validation-for="PerksTemplate" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5 mb-4">Contributions</h3>
|
||||
<div class="form-check mb-3">
|
||||
<input asp-for="SortPerksByPopularity" type="checkbox" class="form-check-input" />
|
||||
|
@ -144,6 +160,7 @@
|
|||
<label asp-for="EnforceTargetAmount" class="form-check-label"></label>
|
||||
<span asp-validation-for="EnforceTargetAmount" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5 mb-4">Crowdfund Behavior</h3>
|
||||
<div class="form-group">
|
||||
<label asp-for="NotificationUrl" class="form-label"></label>
|
||||
|
@ -155,9 +172,9 @@
|
|||
<label asp-for="UseAllStoreInvoices" class="form-check-label"></label>
|
||||
<span asp-validation-for="UseAllStoreInvoices" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5 mb-4">Sound</h3>
|
||||
<div class="form-group mb-0">
|
||||
<div class="form-group d-flex align-items-center mb-0">
|
||||
<input asp-for="SoundsEnabled" type="checkbox" class="btcpay-toggle me-2" data-bs-toggle="collapse" data-bs-target="#SoundsEnabledSettings" aria-expanded="@Model.SoundsEnabled" aria-controls="SoundsEnabledSettings"/>
|
||||
<label asp-for="SoundsEnabled" class="form-label mb-0"></label>
|
||||
<span asp-validation-for="SoundsEnabled" class="text-danger"></span>
|
||||
|
@ -169,9 +186,9 @@
|
|||
<span asp-validation-for="Sounds" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5 mb-4">Animation</h3>
|
||||
<div class="form-group mb-3">
|
||||
<div class="form-group d-flex align-items-center mb-0">
|
||||
<input asp-for="AnimationsEnabled" type="checkbox" class="btcpay-toggle me-2" data-bs-toggle="collapse" data-bs-target="#AnimationsEnabledSettings" aria-expanded="@Model.AnimationsEnabled" aria-controls="AnimationsEnabledSettings"/>
|
||||
<label asp-for="AnimationsEnabled" class="form-label mb-0"></label>
|
||||
<span asp-validation-for="AnimationsEnabled" class="text-danger"></span>
|
||||
|
@ -183,9 +200,9 @@
|
|||
<span asp-validation-for="AnimationColors" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5 mb-4">Discussion</h3>
|
||||
<div class="form-group mb-3">
|
||||
<div class="form-group d-flex align-items-center mb-0">
|
||||
<input asp-for="DisqusEnabled" type="checkbox" class="btcpay-toggle me-2" data-bs-toggle="collapse" data-bs-target="#DisqusEnabledSettings" aria-expanded="@Model.DisqusEnabled" aria-controls="DisqusEnabledSettings"/>
|
||||
<label asp-for="DisqusEnabled" class="form-label mb-0"></label>
|
||||
<span asp-validation-for="DisqusEnabled" class="text-danger"></span>
|
||||
|
@ -235,27 +252,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 mt-2">
|
||||
<div class="d-grid gap-3 d-md-block">
|
||||
<button type="submit" class="btn btn-primary me-md-2" id="SaveSettings">Save Settings</button>
|
||||
<div class="btn-group me-md-2">
|
||||
<a class="btn btn-secondary flex-grow-1" asp-action="ListInvoices" asp-controller="UIInvoice" asp-route-storeId="@Model.StoreId" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
|
||||
<a class="btn btn-secondary px-3 flex-grow-0" asp-action="ListInvoices" asp-controller="UIInvoice" asp-route-storeId="@Model.StoreId" asp-route-searchterm="@Model.SearchTerm"
|
||||
target="viewinvoices_@Model.AppId"><span class="fa fa-external-link"></span></a>
|
||||
</div>
|
||||
@if (Model.ModelWithMinimumData)
|
||||
{
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-secondary flex-grow-1" asp-action="ViewCrowdfund" asp-controller="UIAppsPublic" asp-route-appId="@Model.AppId" id="ViewApp">View Crowdfund</a>
|
||||
<a class="btn btn-secondary px-3 flex-grow-0" asp-action="ViewCrowdfund" asp-controller="UIAppsPublic" asp-route-appId="@Model.AppId"
|
||||
target="viewapp_@Model.AppId"><span class="fa fa-external-link"></span></a>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h3 class="mt-5 mb-4">Other Actions</h3>
|
||||
|
|
|
@ -5,11 +5,23 @@
|
|||
ViewData.SetActivePage(AppsNavPages.Update, "Update Point of Sale", Model.Id);
|
||||
}
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<h2 class="mt-1 mb-4">@ViewData["Title"]</h2>
|
||||
|
||||
<form method="post">
|
||||
<div class="sticky-header-setup"></div>
|
||||
<header class="sticky-header d-sm-flex align-items-center justify-content-between">
|
||||
<h2 class="mb-0">@ViewData["Title"]</h2>
|
||||
<div class="d-flex gap-3 mt-3 mt-sm-0">
|
||||
<button type="submit" class="btn btn-primary order-sm-1" id="SaveSettings">Save</button>
|
||||
<a class="btn btn-secondary" asp-action="ViewPointOfSale" asp-controller="UIAppsPublic" asp-route-appId="@Model.Id" id="ViewApp" target="app_@Model.AppId">View</a>
|
||||
<a class="btn btn-secondary" asp-action="ListInvoices" asp-controller="UIInvoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
|
||||
</div>
|
||||
</header>
|
||||
<script>
|
||||
const { offsetHeight } = document.querySelector('.sticky-header-setup + .sticky-header');
|
||||
document.documentElement.style.scrollPaddingTop = `calc(${offsetHeight}px + var(--btcpay-space-m))`;
|
||||
</script>
|
||||
|
||||
<partial name="_StatusMessage" />
|
||||
|
||||
<input type="hidden" asp-for="StoreId" />
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
|
||||
|
@ -204,13 +216,11 @@
|
|||
<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 class="p-3">@Model.ExampleCallback</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>
|
||||
<ul>
|
||||
<li>Send a <code>GET</code> request to <code>https://btcpay.example.com/invoices/{invoiceId}</code> with <code>Content-Type: application/json; Authorization: Basic YourLegacyAPIkey"</code>, Legacy API key can be created with Access Tokens in Store settings</li>
|
||||
<li>Verify that the <code>orderId</code> is from your backend, that the <code>price</code> is correct and that <code>status</code> is <code>settled</code></li>
|
||||
<li>You can then ship your order</li>
|
||||
</ul>
|
||||
</p>
|
||||
<ul>
|
||||
<li>Send a <code>GET</code> request to <code>https://btcpay.example.com/invoices/{invoiceId}</code> with <code>Content-Type: application/json; Authorization: Basic YourLegacyAPIkey"</code>, Legacy API key can be created with Access Tokens in Store settings</li>
|
||||
<li>Verify that the <code>orderId</code> is from your backend, that the <code>price</code> is correct and that <code>status</code> is <code>settled</code></li>
|
||||
<li>You can then ship your order</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -243,23 +253,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 mt-2">
|
||||
<div class="d-grid gap-3 d-md-block">
|
||||
<button type="submit" class="btn btn-primary me-md-2" id="SaveSettings">Save Settings</button>
|
||||
<div class="btn-group me-md-2">
|
||||
<a class="btn btn-secondary flex-grow-1" asp-action="ListInvoices" asp-controller="UIInvoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
|
||||
<a class="btn btn-secondary px-3 flex-grow-0" asp-action="ListInvoices" asp-controller="UIInvoice" 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-secondary flex-grow-1" asp-action="ViewPointOfSale" asp-controller="UIAppsPublic" asp-route-appId="@Model.Id" id="ViewApp">View Point of Sale</a>
|
||||
<a class="btn btn-secondary px-3 flex-grow-0" asp-action="ViewPointOfSale" asp-controller="UIAppsPublic" asp-route-appId="@Model.Id"
|
||||
target="viewapp_@Model.Id"><span class="fa fa-external-link"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h3 class="mt-5 mb-4">Other Actions</h3>
|
||||
|
@ -332,7 +325,7 @@
|
|||
</div>
|
||||
</script>
|
||||
<script>
|
||||
var posStyleSelector = document.getElementById('DefaultView');
|
||||
const posStyleSelector = document.getElementById('DefaultView');
|
||||
posStyleSelector.addEventListener('change', function(e) {
|
||||
handleStyleSelected(e.target.value);
|
||||
});
|
||||
|
@ -362,7 +355,7 @@
|
|||
|
||||
/** Show/hide discounts section */
|
||||
|
||||
var discountsSection = document.getElementById('discounts');
|
||||
const discountsSection = document.getElementById('discounts');
|
||||
|
||||
function hideDiscountsSection() {
|
||||
hideElement(discountsSection);
|
||||
|
@ -376,7 +369,7 @@
|
|||
|
||||
/** Show/hide button text section */
|
||||
|
||||
var buttonPriceTextSection = document.getElementById('button-price-text');
|
||||
const buttonPriceTextSection = document.getElementById('button-price-text');
|
||||
|
||||
function hideButtonPriceTextSection() {
|
||||
hideElement(buttonPriceTextSection);
|
||||
|
@ -390,7 +383,7 @@
|
|||
|
||||
/** Show/hide custom payments amount seciton */
|
||||
|
||||
var customPaymentAmountSection = document.getElementById('custom-payments');
|
||||
const customPaymentAmountSection = document.getElementById('custom-payments');
|
||||
|
||||
function hideCustomPaymentAmountSection() {
|
||||
hideElement(customPaymentAmountSection);
|
||||
|
@ -404,7 +397,7 @@
|
|||
|
||||
/** Show/hide tips seciton */
|
||||
|
||||
var tipsSection = document.getElementById('tips');
|
||||
const tipsSection = document.getElementById('tips');
|
||||
|
||||
function hideTipsSection() {
|
||||
hideElement(tipsSection);
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
<h2 class="mt-1 mb-4">Account Settings</h2>
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a id="SectionNav-@ManageNavPages.Index.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.Index)" asp-controller="UIManage" asp-action="Index">Account</a>
|
||||
<a id="SectionNav-@ManageNavPages.ChangePassword.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.ChangePassword)" asp-controller="UIManage" asp-action="ChangePassword">Password</a>
|
||||
<a id="SectionNav-@ManageNavPages.TwoFactorAuthentication.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.TwoFactorAuthentication)" asp-controller="UIManage" asp-action="TwoFactorAuthentication">Two-Factor Authentication</a>
|
||||
<a id="SectionNav-@ManageNavPages.APIKeys.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.APIKeys)" asp-controller="UIManage" asp-action="APIKeys">API Keys</a>
|
||||
<a id="SectionNav-@ManageNavPages.Notifications.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.Notifications)" asp-controller="UIManage" asp-action="NotificationSettings">Notifications</a>
|
||||
<a id="SectionNav-@ManageNavPages.LoginCodes.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.LoginCodes)" asp-controller="UIManage" asp-action="LoginCodes">Login Codes</a>
|
||||
<vc:ui-extension-point location="user-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sticky-header-setup"></div>
|
||||
<header class="sticky-header mb-l">
|
||||
<h2 class="mt-1 mb-2 mb-lg-4">Account Settings</h2>
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a id="SectionNav-@ManageNavPages.Index.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.Index)" asp-controller="UIManage" asp-action="Index">Account</a>
|
||||
<a id="SectionNav-@ManageNavPages.ChangePassword.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.ChangePassword)" asp-controller="UIManage" asp-action="ChangePassword">Password</a>
|
||||
<a id="SectionNav-@ManageNavPages.TwoFactorAuthentication.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.TwoFactorAuthentication)" asp-controller="UIManage" asp-action="TwoFactorAuthentication">Two-Factor Authentication</a>
|
||||
<a id="SectionNav-@ManageNavPages.APIKeys.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.APIKeys)" asp-controller="UIManage" asp-action="APIKeys">API Keys</a>
|
||||
<a id="SectionNav-@ManageNavPages.Notifications.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.Notifications)" asp-controller="UIManage" asp-action="NotificationSettings">Notifications</a>
|
||||
<a id="SectionNav-@ManageNavPages.LoginCodes.ToString()" class="nav-link @ViewData.IsActivePage(ManageNavPages.LoginCodes)" asp-controller="UIManage" asp-action="LoginCodes">Login Codes</a>
|
||||
<vc:ui-extension-point location="user-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<script>
|
||||
const { offsetHeight } = document.querySelector('.sticky-header-setup + .sticky-header');
|
||||
document.documentElement.style.scrollPaddingTop = `calc(${offsetHeight}px + var(--btcpay-space-m))`;
|
||||
</script>
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
@using BTCPayServer.Configuration
|
||||
@inject BTCPayServerOptions _btcPayServerOptions
|
||||
<h2 class="mt-1 mb-4">Server Settings</h2>
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Users" class="nav-link @ViewData.IsActivePage(ServerNavPages.Users)" asp-action="ListUsers">Users</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Emails" class="nav-link @ViewData.IsActivePage(ServerNavPages.Emails)" asp-action="Emails">Email</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Policies" class="nav-link @ViewData.IsActivePage(ServerNavPages.Policies)" asp-action="Policies">Policies</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Services" class="nav-link @ViewData.IsActivePage(ServerNavPages.Services)" asp-action="Services">Services</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Theme" class="nav-link @ViewData.IsActivePage(ServerNavPages.Theme)" asp-action="Theme">Theme</a>
|
||||
@if (_btcPayServerOptions.DockerDeployment)
|
||||
{
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Maintenance" class="nav-link @ViewData.IsActivePage(ServerNavPages.Maintenance)" asp-action="Maintenance">Maintenance</a>
|
||||
}
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Logs" class="nav-link @ViewData.IsActivePage(ServerNavPages.Logs)" asp-action="LogsView">Logs</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Files" class="nav-link @ViewData.IsActivePage(ServerNavPages.Files)" asp-action="Files">Files</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Plugins" class="nav-link @ViewData.IsActivePage(ServerNavPages.Plugins)" asp-action="ListPlugins">Plugins</a>
|
||||
<vc:ui-extension-point location="server-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sticky-header-setup"></div>
|
||||
<header class="sticky-header mb-l">
|
||||
<h2 class="mt-1 mb-2 mb-lg-4">Server Settings</h2>
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Users" class="nav-link @ViewData.IsActivePage(ServerNavPages.Users)" asp-action="ListUsers">Users</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Emails" class="nav-link @ViewData.IsActivePage(ServerNavPages.Emails)" asp-action="Emails">Email</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Policies" class="nav-link @ViewData.IsActivePage(ServerNavPages.Policies)" asp-action="Policies">Policies</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Services" class="nav-link @ViewData.IsActivePage(ServerNavPages.Services)" asp-action="Services">Services</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Theme" class="nav-link @ViewData.IsActivePage(ServerNavPages.Theme)" asp-action="Theme">Theme</a>
|
||||
@if (_btcPayServerOptions.DockerDeployment)
|
||||
{
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Maintenance" class="nav-link @ViewData.IsActivePage(ServerNavPages.Maintenance)" asp-action="Maintenance">Maintenance</a>
|
||||
}
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Logs" class="nav-link @ViewData.IsActivePage(ServerNavPages.Logs)" asp-action="LogsView">Logs</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Files" class="nav-link @ViewData.IsActivePage(ServerNavPages.Files)" asp-action="Files">Files</a>
|
||||
<a asp-controller="UIServer" id="SectionNav-@ServerNavPages.Plugins" class="nav-link @ViewData.IsActivePage(ServerNavPages.Plugins)" asp-action="ListPlugins">Plugins</a>
|
||||
<vc:ui-extension-point location="server-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<script>
|
||||
const { offsetHeight } = document.querySelector('.sticky-header-setup + .sticky-header');
|
||||
document.documentElement.style.scrollPaddingTop = `calc(${offsetHeight}px + var(--btcpay-space-m))`;
|
||||
</script>
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
@using BTCPayServer.Client
|
||||
<h2 class="mt-1 mb-4">Store Settings</h2>
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.General))" class="nav-link @ViewData.IsActivePage(StoreNavPages.General)" asp-controller="UIStores" asp-action="GeneralSettings" asp-route-storeId="@Context.GetRouteValue("storeId")">General</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Rates))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Rates)" asp-controller="UIStores" asp-action="Rates" asp-route-storeId="@Context.GetRouteValue("storeId")">Rates</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.CheckoutAppearance))" class="nav-link @ViewData.IsActivePage(StoreNavPages.CheckoutAppearance)" asp-controller="UIStores" asp-action="CheckoutAppearance" asp-route-storeId="@Context.GetRouteValue("storeId")">Checkout Appearance</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Tokens))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Tokens)" asp-controller="UIStores" asp-action="ListTokens" asp-route-storeId="@Context.GetRouteValue("storeId")">Access Tokens</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Users))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Users)" asp-controller="UIStores" asp-action="StoreUsers" asp-route-storeId="@Context.GetRouteValue("storeId")">Users</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Integrations))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Integrations)" asp-controller="UIStores" asp-action="Integrations" asp-route-storeId="@Context.GetRouteValue("storeId")">Integrations</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Webhooks))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Webhooks)" asp-controller="UIStores" asp-action="Webhooks" asp-route-storeId="@Context.GetRouteValue("storeId")">Webhooks</a>
|
||||
<vc:ui-extension-point location="store-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sticky-header-setup"></div>
|
||||
<header class="sticky-header mb-l">
|
||||
<h2 class="mt-1 mb-2 mb-lg-4">Store Settings</h2>
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.General))" class="nav-link @ViewData.IsActivePage(StoreNavPages.General)" asp-controller="UIStores" asp-action="GeneralSettings" asp-route-storeId="@Context.GetRouteValue("storeId")">General</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Rates))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Rates)" asp-controller="UIStores" asp-action="Rates" asp-route-storeId="@Context.GetRouteValue("storeId")">Rates</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.CheckoutAppearance))" class="nav-link @ViewData.IsActivePage(StoreNavPages.CheckoutAppearance)" asp-controller="UIStores" asp-action="CheckoutAppearance" asp-route-storeId="@Context.GetRouteValue("storeId")">Checkout Appearance</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Tokens))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Tokens)" asp-controller="UIStores" asp-action="ListTokens" asp-route-storeId="@Context.GetRouteValue("storeId")">Access Tokens</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Users))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Users)" asp-controller="UIStores" asp-action="StoreUsers" asp-route-storeId="@Context.GetRouteValue("storeId")">Users</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Integrations))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Integrations)" asp-controller="UIStores" asp-action="Integrations" asp-route-storeId="@Context.GetRouteValue("storeId")">Integrations</a>
|
||||
<a permission="@Policies.CanModifyStoreSettings" id="SectionNav-@(nameof(StoreNavPages.Webhooks))" class="nav-link @ViewData.IsActivePage(StoreNavPages.Webhooks)" asp-controller="UIStores" asp-action="Webhooks" asp-route-storeId="@Context.GetRouteValue("storeId")">Webhooks</a>
|
||||
<vc:ui-extension-point location="store-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<script>
|
||||
const { offsetHeight } = document.querySelector('.sticky-header-setup + .sticky-header');
|
||||
document.documentElement.style.scrollPaddingTop = `calc(${offsetHeight}px + var(--btcpay-space-m))`;
|
||||
</script>
|
||||
|
|
210
BTCPayServer/wwwroot/main/bootstrap/bootstrap.css
vendored
210
BTCPayServer/wwwroot/main/bootstrap/bootstrap.css
vendored
|
@ -10617,25 +10617,25 @@ fieldset:disabled .btn {
|
|||
}
|
||||
/* Scrollbar - first works on Firefox, rest on WebKit-based browsers */
|
||||
* {
|
||||
--btcpay-scrollbar-width: .375rem;
|
||||
--btcpay-scrollbar-color: var(--btcpay-neutral-500);
|
||||
--btcpay-scrollbar-bg: transparent;
|
||||
scrollbar-width: var(--btcpay-scrollbar-width);
|
||||
scrollbar-color: var(--btcpay-scrollbar-color) var(--btcpay-scrollbar-bg);
|
||||
--btcpay-scrollbar-width: .375rem;
|
||||
--btcpay-scrollbar-color: var(--btcpay-neutral-500);
|
||||
--btcpay-scrollbar-bg: transparent;
|
||||
scrollbar-width: var(--btcpay-scrollbar-width);
|
||||
scrollbar-color: var(--btcpay-scrollbar-color) var(--btcpay-scrollbar-bg);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: var(--btcpay-scrollbar-width);
|
||||
width: var(--btcpay-scrollbar-width);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: var(--btcpay-scrollbar-bg);
|
||||
background: var(--btcpay-scrollbar-bg);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: var(--btcpay-scrollbar-color);
|
||||
border-radius: 1rem;
|
||||
border: 1rem solid var(--btcpay-scrollbar-bg);
|
||||
background-color: var(--btcpay-scrollbar-color);
|
||||
border-radius: 1rem;
|
||||
border: 1rem solid var(--btcpay-scrollbar-bg);
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -10901,149 +10901,59 @@ input[type=number].hide-number-spin {
|
|||
color: var(--btcpay-danger);
|
||||
}
|
||||
|
||||
/* Custom space utils, as Bootstrap has a different spacing scale for > M */
|
||||
.pt-l { padding-top: var(--btcpay-space-l); }
|
||||
.pt-xl { padding-top: var(--btcpay-space-xl); }
|
||||
.pb-l { padding-bottom: var(--btcpay-space-l); }
|
||||
.pb-xl { padding-bottom: var(--btcpay-space-xl); }
|
||||
.mt-l { margin-top: var(--btcpay-space-l); }
|
||||
.mt-xl { margin-top: var(--btcpay-space-xl); }
|
||||
.mb-l { margin-bottom: var(--btcpay-space-l); }
|
||||
.mb-xl { margin-bottom: var(--btcpay-space-xl); }
|
||||
|
||||
/* Negative margin utils (only include bare minimum) */
|
||||
|
||||
.mt-n1 {
|
||||
margin-top: -0.25rem !important;
|
||||
}
|
||||
|
||||
.mt-n2 {
|
||||
margin-top: -0.5rem !important;
|
||||
}
|
||||
|
||||
.mt-n3 {
|
||||
margin-top: -1rem !important;
|
||||
}
|
||||
|
||||
.mt-n4 {
|
||||
margin-top: -1.5rem !important;
|
||||
}
|
||||
|
||||
.mt-n5 {
|
||||
margin-top: -3rem !important;
|
||||
}
|
||||
|
||||
.me-n1 {
|
||||
margin-right: -0.25rem !important;
|
||||
}
|
||||
|
||||
.me-n2 {
|
||||
margin-right: -0.5rem !important;
|
||||
}
|
||||
|
||||
.me-n3 {
|
||||
margin-right: -1rem !important;
|
||||
}
|
||||
|
||||
.me-n4 {
|
||||
margin-right: -1.5rem !important;
|
||||
}
|
||||
|
||||
.me-n5 {
|
||||
margin-right: -3rem !important;
|
||||
}
|
||||
|
||||
.mb-n1 {
|
||||
margin-bottom: -0.25rem !important;
|
||||
}
|
||||
|
||||
.mb-n2 {
|
||||
margin-bottom: -0.5rem !important;
|
||||
}
|
||||
|
||||
.mb-n3 {
|
||||
margin-bottom: -1rem !important;
|
||||
}
|
||||
|
||||
.mb-n4 {
|
||||
margin-bottom: -1.5rem !important;
|
||||
}
|
||||
|
||||
.mb-n5 {
|
||||
margin-bottom: -3rem !important;
|
||||
}
|
||||
|
||||
.ms-n1 {
|
||||
margin-left: -0.25rem !important;
|
||||
}
|
||||
|
||||
.ms-n2 {
|
||||
margin-left: -0.5rem !important;
|
||||
}
|
||||
|
||||
.ms-n3 {
|
||||
margin-left: -1rem !important;
|
||||
}
|
||||
|
||||
.ms-n4 {
|
||||
margin-left: -1.5rem !important;
|
||||
}
|
||||
|
||||
.ms-n5 {
|
||||
margin-left: -3rem !important;
|
||||
}
|
||||
.mt-n1 { margin-top: -0.25rem !important; }
|
||||
.mt-n2 { margin-top: -0.5rem !important; }
|
||||
.mt-n3 { margin-top: -1rem !important; }
|
||||
.mt-n4 { margin-top: -1.5rem !important; }
|
||||
.mt-n5 { margin-top: -3rem !important; }
|
||||
.me-n1 { margin-right: -0.25rem !important; }
|
||||
.me-n2 { margin-right: -0.5rem !important; }
|
||||
.me-n3 { margin-right: -1rem !important; }
|
||||
.me-n4 { margin-right: -1.5rem !important; }
|
||||
.me-n5 { margin-right: -3rem !important; }
|
||||
.mb-n1 { margin-bottom: -0.25rem !important; }
|
||||
.mb-n2 { margin-bottom: -0.5rem !important; }
|
||||
.mb-n3 { margin-bottom: -1rem !important; }
|
||||
.mb-n4 { margin-bottom: -1.5rem !important; }
|
||||
.mb-n5 { margin-bottom: -3rem !important; }
|
||||
.ms-n1 { margin-left: -0.25rem !important; }
|
||||
.ms-n2 { margin-left: -0.5rem !important; }
|
||||
.ms-n3 { margin-left: -1rem !important; }
|
||||
.ms-n4 { margin-left: -1.5rem !important; }
|
||||
.ms-n5 { margin-left: -3rem !important; }
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.mt-lg-n1 {
|
||||
margin-top: -0.25rem !important;
|
||||
}
|
||||
.mt-lg-n2 {
|
||||
margin-top: -0.5rem !important;
|
||||
}
|
||||
.mt-lg-n3 {
|
||||
margin-top: -1rem !important;
|
||||
}
|
||||
.mt-lg-n4 {
|
||||
margin-top: -1.5rem !important;
|
||||
}
|
||||
.mt-lg-n5 {
|
||||
margin-top: -3rem !important;
|
||||
}
|
||||
.me-lg-n1 {
|
||||
margin-right: -0.25rem !important;
|
||||
}
|
||||
.me-lg-n2 {
|
||||
margin-right: -0.5rem !important;
|
||||
}
|
||||
.me-lg-n3 {
|
||||
margin-right: -1rem !important;
|
||||
}
|
||||
.me-lg-n4 {
|
||||
margin-right: -1.5rem !important;
|
||||
}
|
||||
.me-lg-n5 {
|
||||
margin-right: -3rem !important;
|
||||
}
|
||||
.mb-lg-n1 {
|
||||
margin-bottom: -0.25rem !important;
|
||||
}
|
||||
.mb-lg-n2 {
|
||||
margin-bottom: -0.5rem !important;
|
||||
}
|
||||
.mb-lg-n3 {
|
||||
margin-bottom: -1rem !important;
|
||||
}
|
||||
.mb-lg-n4 {
|
||||
margin-bottom: -1.5rem !important;
|
||||
}
|
||||
.mb-lg-n5 {
|
||||
margin-bottom: -3rem !important;
|
||||
}
|
||||
.ms-lg-n1 {
|
||||
margin-left: -0.25rem !important;
|
||||
}
|
||||
.ms-lg-n2 {
|
||||
margin-left: -0.5rem !important;
|
||||
}
|
||||
.ms-lg-n3 {
|
||||
margin-left: -1rem !important;
|
||||
}
|
||||
.ms-lg-n4 {
|
||||
margin-left: -1.5rem !important;
|
||||
}
|
||||
.ms-lg-n5 {
|
||||
margin-left: -3rem !important;
|
||||
}
|
||||
.mt-lg-n1 { margin-top: -0.25rem !important; }
|
||||
.mt-lg-n2 { margin-top: -0.5rem !important; }
|
||||
.mt-lg-n3 { margin-top: -1rem !important; }
|
||||
.mt-lg-n4 { margin-top: -1.5rem !important; }
|
||||
.mt-lg-n5 { margin-top: -3rem !important; }
|
||||
.me-lg-n1 { margin-right: -0.25rem !important; }
|
||||
.me-lg-n2 { margin-right: -0.5rem !important; }
|
||||
.me-lg-n3 { margin-right: -1rem !important; }
|
||||
.me-lg-n4 { margin-right: -1.5rem !important; }
|
||||
.me-lg-n5 { margin-right: -3rem !important; }
|
||||
.mb-lg-n1 { margin-bottom: -0.25rem !important; }
|
||||
.mb-lg-n2 { margin-bottom: -0.5rem !important; }
|
||||
.mb-lg-n3 { margin-bottom: -1rem !important; }
|
||||
.mb-lg-n4 { margin-bottom: -1.5rem !important; }
|
||||
.mb-lg-n5 { margin-bottom: -3rem !important; }
|
||||
.ms-lg-n1 { margin-left: -0.25rem !important; }
|
||||
.ms-lg-n2 { margin-left: -0.5rem !important; }
|
||||
.ms-lg-n3 { margin-left: -1rem !important; }
|
||||
.ms-lg-n4 { margin-left: -1.5rem !important; }
|
||||
.ms-lg-n5 { margin-left: -3rem !important; }
|
||||
}
|
||||
|
||||
.btcpay-pills input {
|
||||
|
|
|
@ -120,8 +120,8 @@
|
|||
}
|
||||
|
||||
#mainContent > section {
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
padding: var(--content-padding-top) var(--content-padding-horizontal) var(--content-padding-bottom);
|
||||
}
|
||||
|
||||
#StoreSelector {
|
||||
|
@ -335,6 +335,28 @@
|
|||
background: var(--btcpay-nav-bg-active);
|
||||
}
|
||||
|
||||
/* Sticky Header: The <div class="sticky-header-setup"></div> needs to be included once
|
||||
before the first sticky-header on the page. The sticky-header has a padding-top so
|
||||
that it does not scroll underneath the fixed header on mobile. The sticky-header-setup
|
||||
negates that padding with a negative margin, so that everything fits in the end. */
|
||||
.sticky-header-setup {
|
||||
margin-top: calc(var(--content-padding-top) * -1);
|
||||
}
|
||||
|
||||
.sticky-header {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1020;
|
||||
background: var(--btcpay-body-bg);
|
||||
padding-top: var(--content-padding-top);
|
||||
padding-bottom: var(--btcpay-space-l);
|
||||
}
|
||||
|
||||
.sticky-header #SectionNav {
|
||||
margin-bottom: calc(var(--btcpay-space-l) * -1);
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.btcpay-footer {
|
||||
font-size: var(--btcpay-font-size-s);
|
||||
|
@ -357,10 +379,12 @@
|
|||
@media (max-width: 991px) {
|
||||
:root {
|
||||
--header-height: var(--mobile-header-height);
|
||||
--content-padding-top: var(--btcpay-space-m);
|
||||
--content-padding-top: calc(var(--header-height) + var(--btcpay-space-m));
|
||||
--content-padding-bottom: var(--btcpay-space-xl);
|
||||
--content-padding-horizontal: var(--btcpay-space-m);
|
||||
|
||||
/* Prevent anchors from disappearing underneath the fixed header */
|
||||
scroll-padding: calc(var(--header-height) + var(--content-padding-top));
|
||||
scroll-padding: var(--content-padding-top);
|
||||
}
|
||||
|
||||
#mainMenu {
|
||||
|
@ -471,11 +495,6 @@
|
|||
z-index: 0;
|
||||
}
|
||||
|
||||
#mainContent > section {
|
||||
margin-top: var(--header-height);
|
||||
padding: var(--content-padding-top) var(--btcpay-space-m) var(--btcpay-space-xl);
|
||||
}
|
||||
|
||||
#SectionNav {
|
||||
--scroll-indicator-spacing: var(--btcpay-space-m);
|
||||
position: relative;
|
||||
|
@ -526,6 +545,9 @@
|
|||
@media (min-width: 992px) {
|
||||
:root {
|
||||
--header-height: var(--desktop-header-height);
|
||||
--content-padding-top: 5rem;
|
||||
--content-padding-bottom: 5rem;
|
||||
--content-padding-horizontal: var(--btcpay-space-xl);
|
||||
}
|
||||
|
||||
#mainMenu {
|
||||
|
@ -575,10 +597,6 @@
|
|||
max-width: calc(100vw - var(--sidebar-width) - (2 * var(--btcpay-space-xl)) - 1rem); /* 1rem for scrollbar */
|
||||
}
|
||||
|
||||
#mainContent > section {
|
||||
padding: 5rem var(--btcpay-space-xl);
|
||||
}
|
||||
|
||||
#mainContent > section,
|
||||
.btcpay-footer > .container {
|
||||
margin: 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue