mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 14:04:26 +01:00
Home sweet home (#3313)
* Link to store home, show home only if there is no store * Handle store guest case * Apply correct policies to nav items
This commit is contained in:
@@ -382,11 +382,14 @@ namespace BTCPayServer.Tests
|
|||||||
s.Driver.FindElement(By.Id("SetupGuide-Store")).Click();
|
s.Driver.FindElement(By.Id("SetupGuide-Store")).Click();
|
||||||
Assert.Contains("/stores/create", s.Driver.Url);
|
Assert.Contains("/stores/create", s.Driver.Url);
|
||||||
|
|
||||||
s.CreateNewStore();
|
(_, string storeId) = s.CreateNewStore();
|
||||||
|
|
||||||
|
// should redirect to store
|
||||||
s.GoToUrl("/");
|
s.GoToUrl("/");
|
||||||
|
|
||||||
|
Assert.Contains($"/stores/{storeId}", s.Driver.Url);
|
||||||
Assert.True(s.Driver.PageSource.Contains("id=\"StoreSelectorDropdown\""), "Store selector dropdown should be present");
|
Assert.True(s.Driver.PageSource.Contains("id=\"StoreSelectorDropdown\""), "Store selector dropdown should be present");
|
||||||
Assert.False(s.Driver.PageSource.Contains("id=\"SetupGuide\""), "Setup guide should not be present");
|
Assert.True(s.Driver.PageSource.Contains("id=\"SetupGuide\""), "Store setup guide should be present");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact(Timeout = TestTimeout)]
|
[Fact(Timeout = TestTimeout)]
|
||||||
|
|||||||
@@ -43,13 +43,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="accordion-item" permission="@Policies.CanModifyStoreSettings">
|
<div class="accordion-item">
|
||||||
<header class="accordion-header" id="Nav-Wallets-Header">
|
<header class="accordion-header" id="Nav-Wallets-Header" permission="@Policies.CanModifyStoreSettings">
|
||||||
<div class="accordion-button">
|
<div class="accordion-button">
|
||||||
Wallets
|
Wallets
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div id="Nav-Wallets" class="accordion-collapse" aria-labelledby="Nav-Wallets-Header">
|
<div id="Nav-Wallets" class="accordion-collapse" aria-labelledby="Nav-Wallets-Header" permission="@Policies.CanModifyStoreSettings">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
@foreach (var scheme in Model.DerivationSchemes.OrderBy(scheme => scheme.Collapsed))
|
@foreach (var scheme in Model.DerivationSchemes.OrderBy(scheme => scheme.Collapsed))
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
<div id="Nav-Payments" class="accordion-collapse collapse show" aria-labelledby="Nav-Payments-Header">
|
<div id="Nav-Payments" class="accordion-collapse collapse show" aria-labelledby="Nav-Payments-Header">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item" permission="@Policies.CanModifyStoreSettings">
|
<li class="nav-item" permission="@Policies.CanViewInvoices">
|
||||||
<a asp-area="" asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" class="nav-link js-scroll-trigger @ViewData.IsActiveCategory(typeof(InvoiceNavPages))" id="StoreNav-Invoices">
|
<a asp-area="" asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.Store.Id" class="nav-link js-scroll-trigger @ViewData.IsActiveCategory(typeof(InvoiceNavPages))" id="StoreNav-Invoices">
|
||||||
<vc:icon symbol="invoice"/>
|
<vc:icon symbol="invoice"/>
|
||||||
<span>Invoices</span>
|
<span>Invoices</span>
|
||||||
@@ -118,13 +118,13 @@
|
|||||||
<span>Requests</span>
|
<span>Requests</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item" permission="@Policies.CanViewStoreSettings">
|
||||||
<a asp-area="" asp-controller="UIStorePullPayments" asp-action="PullPayments" asp-route-storeId="@Model.Store.Id" class="nav-link @ViewData.IsActivePage(StoreNavPages.PullPayments)" id="StoreNav-PullPayments">
|
<a asp-area="" asp-controller="UIStorePullPayments" asp-action="PullPayments" asp-route-storeId="@Model.Store.Id" class="nav-link @ViewData.IsActivePage(StoreNavPages.PullPayments)" id="StoreNav-PullPayments">
|
||||||
<vc:icon symbol="payment-2"/>
|
<vc:icon symbol="payment-2"/>
|
||||||
<span>Pull Payments</span>
|
<span>Pull Payments</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item" permission="@Policies.CanViewStoreSettings">
|
||||||
<a asp-area="" asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.Store.Id" class="nav-link @ViewData.IsActivePage(StoreNavPages.Payouts)" id="StoreNav-Payouts">
|
<a asp-area="" asp-controller="UIStorePullPayments" asp-action="Payouts" asp-route-storeId="@Model.Store.Id" class="nav-link @ViewData.IsActivePage(StoreNavPages.Payouts)" id="StoreNav-Payouts">
|
||||||
<vc:icon symbol="payment-2"/>
|
<vc:icon symbol="payment-2"/>
|
||||||
<span>Payouts</span>
|
<span>Payouts</span>
|
||||||
|
|||||||
@@ -1,6 +1,39 @@
|
|||||||
|
@inject BTCPayServer.Services.BTCPayServerEnvironment _env
|
||||||
|
@inject SignInManager<ApplicationUser> _signInManager
|
||||||
@model BTCPayServer.Components.StoreSelector.StoreSelectorViewModel
|
@model BTCPayServer.Components.StoreSelector.StoreSelectorViewModel
|
||||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS1998 *@
|
||||||
|
private async Task LogoContent()
|
||||||
|
{
|
||||||
|
var logoSrc = $"{ViewContext.HttpContext.Request.PathBase}/img/logo.svg";
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" role="img" alt="BTCPay Server" class="logo"><use href="@logoSrc#small" class="logo-small" /><use href="@logoSrc#large" class="logo-large" /></svg>
|
||||||
|
@if (_env.NetworkType != NBitcoin.ChainName.Mainnet)
|
||||||
|
{
|
||||||
|
<span class="badge bg-warning ms-1 ms-sm-0" style="font-size:10px;">@_env.NetworkType.ToString()</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string StoreName(string title)
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(title) ? "Unnamed Store" : title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.CurrentStoreId == null)
|
||||||
|
{
|
||||||
|
<a href="~/" class="navbar-brand py-2 js-scroll-trigger">@{await LogoContent();}</a>
|
||||||
|
}
|
||||||
|
else if (Model.CurrentStoreIsOwner)
|
||||||
|
{
|
||||||
|
<a asp-controller="UIStores" asp-action="Dashboard" asp-route-storeId="@Model.CurrentStoreId" class="navbar-brand py-2 js-scroll-trigger">@{await LogoContent();}</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@Model.CurrentStoreId" class="navbar-brand py-2 js-scroll-trigger">@{await LogoContent();}</a>
|
||||||
|
}
|
||||||
|
|
||||||
<div id="StoreSelector">
|
<div id="StoreSelector">
|
||||||
@if (Model.Options.Count > 0)
|
@if (Model.Options.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -10,13 +43,17 @@
|
|||||||
@foreach (var option in Model.Options)
|
@foreach (var option in Model.Options)
|
||||||
{
|
{
|
||||||
<li>
|
<li>
|
||||||
@if (option.WalletId != null)
|
@if (option.IsOwner && option.WalletId != null)
|
||||||
{
|
{
|
||||||
<a asp-controller="UIWallets" asp-action="WalletTransactions" asp-route-walletId="@option.WalletId" class="dropdown-item@(option.Selected ? " active" : "")" id="StoreSelectorMenuItem-@option.Value">@option.Text</a>
|
<a asp-controller="UIWallets" asp-action="WalletTransactions" asp-route-walletId="@option.WalletId" class="dropdown-item@(option.Selected ? " active" : "")" id="StoreSelectorMenuItem-@option.Value">@StoreName(option.Text)</a>
|
||||||
|
}
|
||||||
|
else if (option.IsOwner)
|
||||||
|
{
|
||||||
|
<a asp-controller="UIStores" asp-action="Dashboard" asp-route-storeId="@option.Value" class="dropdown-item@(option.Selected ? " active" : "")" id="StoreSelectorMenuItem-@option.Value">@StoreName(option.Text)</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a asp-controller="UIStores" asp-action="Dashboard" asp-route-storeId="@option.Value" class="dropdown-item@(option.Selected ? " active" : "")" id="StoreSelectorMenuItem-@option.Value">@option.Text</a>
|
<a asp-controller="UIInvoice" asp-action="ListInvoices" asp-route-storeId="@option.Value" class="dropdown-item@(option.Selected ? " active" : "")" id="StoreSelectorMenuItem-@option.Value">@StoreName(option.Text)</a>
|
||||||
}
|
}
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@@ -25,7 +62,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else if (_signInManager.IsSignedIn(User))
|
||||||
{
|
{
|
||||||
<a asp-controller="UIUserStores" asp-action="CreateStore" class="btn btn-primary w-100 rounded-pill" id="StoreSelectorCreate">Create Store</a>
|
<a asp-controller="UIUserStores" asp-action="CreateStore" class="btn btn-primary w-100 rounded-pill" id="StoreSelectorCreate">Create Store</a>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ namespace BTCPayServer.Components.StoreSelector
|
|||||||
Text = store.StoreName,
|
Text = store.StoreName,
|
||||||
Value = store.Id,
|
Value = store.Id,
|
||||||
Selected = store.Id == currentStore?.Id,
|
Selected = store.Id == currentStore?.Id,
|
||||||
|
IsOwner = store.Role == StoreRoles.Owner,
|
||||||
WalletId = walletId
|
WalletId = walletId
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -52,7 +53,8 @@ namespace BTCPayServer.Components.StoreSelector
|
|||||||
{
|
{
|
||||||
Options = options,
|
Options = options,
|
||||||
CurrentStoreId = currentStore?.Id,
|
CurrentStoreId = currentStore?.Id,
|
||||||
CurrentDisplayName = currentStore?.StoreName
|
CurrentDisplayName = currentStore?.StoreName,
|
||||||
|
CurrentStoreIsOwner = currentStore?.Role == StoreRoles.Owner
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ namespace BTCPayServer.Components.StoreSelector
|
|||||||
public List<StoreSelectorOption> Options { get; set; }
|
public List<StoreSelectorOption> Options { get; set; }
|
||||||
public string CurrentStoreId { get; set; }
|
public string CurrentStoreId { get; set; }
|
||||||
public string CurrentDisplayName { get; set; }
|
public string CurrentDisplayName { get; set; }
|
||||||
|
public bool CurrentStoreIsOwner { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StoreSelectorOption
|
public class StoreSelectorOption
|
||||||
{
|
{
|
||||||
public bool Selected { get; set; }
|
public bool Selected { get; set; }
|
||||||
|
public bool IsOwner { get; set; }
|
||||||
public string Text { get; set; }
|
public string Text { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
public WalletId WalletId { get; set; }
|
public WalletId WalletId { get; set; }
|
||||||
|
|||||||
@@ -78,14 +78,23 @@ namespace BTCPayServer.Controllers
|
|||||||
var storeId = HttpContext.GetUserPrefsCookie()?.CurrentStoreId;
|
var storeId = HttpContext.GetUserPrefsCookie()?.CurrentStoreId;
|
||||||
if (storeId != null)
|
if (storeId != null)
|
||||||
{
|
{
|
||||||
|
// verify store exists and redirect to it
|
||||||
var store = await _storeRepository.FindStore(storeId, userId);
|
var store = await _storeRepository.FindStore(storeId, userId);
|
||||||
if (store != null)
|
if (store != null)
|
||||||
{
|
{
|
||||||
HttpContext.SetStoreData(store);
|
return store.Role == StoreRoles.Owner
|
||||||
|
? RedirectToAction("Dashboard", "UIStores", new { storeId })
|
||||||
|
: RedirectToAction("ListInvoices", "UIInvoice", new { storeId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var stores = await _storeRepository.GetStoresByUserId(userId);
|
var stores = await _storeRepository.GetStoresByUserId(userId);
|
||||||
|
if (stores.Any())
|
||||||
|
{
|
||||||
|
// redirect to first store
|
||||||
|
storeId = stores.First().Id;
|
||||||
|
return RedirectToAction("Dashboard", "UIStores", new { storeId });
|
||||||
|
}
|
||||||
|
|
||||||
var vm = new HomeViewModel
|
var vm = new HomeViewModel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
@using BTCPayServer.Abstractions.Contracts
|
@using BTCPayServer.Abstractions.Contracts
|
||||||
@inject BTCPayServer.Services.BTCPayServerEnvironment _env
|
@inject BTCPayServer.Services.BTCPayServerEnvironment _env
|
||||||
|
@inject SignInManager<ApplicationUser> _signInManager
|
||||||
@inject UserManager<ApplicationUser> _userManager
|
@inject UserManager<ApplicationUser> _userManager
|
||||||
@inject ISettingsRepository _settingsRepository
|
@inject ISettingsRepository _settingsRepository
|
||||||
@inject LinkGenerator _linkGenerator
|
@inject LinkGenerator _linkGenerator
|
||||||
|
|
||||||
@{
|
@{
|
||||||
var logoSrc = $"{ViewContext.HttpContext.Request.PathBase}/img/logo.svg";
|
|
||||||
var notificationDisabled = (await _settingsRepository.GetPolicies()).DisableInstantNotifications;
|
var notificationDisabled = (await _settingsRepository.GetPolicies()).DisableInstantNotifications;
|
||||||
if (!notificationDisabled)
|
if (!notificationDisabled)
|
||||||
{
|
{
|
||||||
@@ -23,15 +23,11 @@
|
|||||||
<body class="d-flex flex-column flex-lg-row min-vh-100">
|
<body class="d-flex flex-column flex-lg-row min-vh-100">
|
||||||
<header id="mainMenu" class="btcpay-header d-flex flex-column">
|
<header id="mainMenu" class="btcpay-header d-flex flex-column">
|
||||||
<div id="mainMenuHead" class="d-flex flex-lg-wrap align-items-center justify-content-between py-2 px-3 py-lg-3 px-lg-4">
|
<div id="mainMenuHead" class="d-flex flex-lg-wrap align-items-center justify-content-between py-2 px-3 py-lg-3 px-lg-4">
|
||||||
<a href="~/" class="navbar-brand py-2 js-scroll-trigger">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" role="img" alt="BTCPay Server" class="logo"><use href="@logoSrc#small" class="logo-small" /><use href="@logoSrc#large" class="logo-large" /></svg>
|
|
||||||
@if (_env.NetworkType != NBitcoin.ChainName.Mainnet)
|
|
||||||
{
|
|
||||||
<span class="badge bg-warning ms-1 ms-sm-0" style="font-size:10px;">@_env.NetworkType.ToString()</span>
|
|
||||||
}
|
|
||||||
</a>
|
|
||||||
<vc:store-selector />
|
<vc:store-selector />
|
||||||
|
@if (_signInManager.IsSignedIn(User))
|
||||||
|
{
|
||||||
<vc:notifications appearance="Dropdown"/>
|
<vc:notifications appearance="Dropdown"/>
|
||||||
|
}
|
||||||
<button id="mainMenuToggle" class="mainMenuButton" type="button" data-bs-toggle="offcanvas" data-bs-target="#mainNav" aria-controls="mainNav" aria-expanded="false" aria-label="Toggle navigation">
|
<button id="mainMenuToggle" class="mainMenuButton" type="button" data-bs-toggle="offcanvas" data-bs-target="#mainNav" aria-controls="mainNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span>Menu</span>
|
<span>Menu</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -23,10 +23,6 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#NotificationsRecent .notification {
|
|
||||||
padding: var(--btcpay-space-s) var(--btcpay-space-m) !important;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,19 +30,11 @@
|
|||||||
|
|
||||||
<h2>Welcome to your BTCPay Server</h2>
|
<h2>Welcome to your BTCPay Server</h2>
|
||||||
|
|
||||||
@if (Model.HasStore)
|
@if (!Model.HasStore)
|
||||||
{
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8 col-xl-6 pt-3">
|
|
||||||
<vc:notifications appearance="Recent" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-9 col-xl-6">
|
<div class="col-lg-9 col-xl-6">
|
||||||
<p class="lead text-secondary">To start accepting payments, set up a store and a wallet.</p>
|
<p class="lead text-secondary">To start accepting payments, set up a store.</p>
|
||||||
|
|
||||||
<div class="list-group mt-4" id="SetupGuide">
|
<div class="list-group mt-4" id="SetupGuide">
|
||||||
<a asp-controller="UIUserStores" asp-action="CreateStore" id="SetupGuide-Store" class="list-group-item list-group-item-action d-flex align-items-center">
|
<a asp-controller="UIUserStores" asp-action="CreateStore" id="SetupGuide-Store" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||||
|
|||||||
Reference in New Issue
Block a user