btcpayserver/BTCPayServer/Views/UIUserStores/CreateStore.cshtml
d11n e43b4ed540
Onboarding: Invite new users (#5714)
* Server Users: More precise message when inviting users

This lets the admin who invited a new user know whether or not an email has been sent. If the SMTP server hasn't been set up, they need to share the invite link with the user.

* Onboarding: Invite new users

- Separates the user self-registration and invite cases
- Adds invitation email for users created by the admin
- Adds invitation tokens to verify user was invited
- Adds handler action for invite links
- Refactors `UserEventHostedService`

* Remove duplicate status message from views that use the wizard layout

* Auto-approve users created by an admin

* Notify admins via email if a new account requires approval

* Update wording

* Fix update user error

* Fix redirect to email confirmation in invite action

* Fix precondition checks after signup

* Improve admin notification

Send notification only if the user does not require email confirmation or when they confirmed their email address. Rationale: We want to inform admins only about qualified users and not annoy them with bot registrations.

* Allow approval alongside resending confirm email

* Use user email in log messages instead of ID

* Prevent unnecessary notification after email confirmation

* Use ApplicationUser type explicitly

* Fix after rebase

* Refactoring: Do not subclass UserRegisteredEvent
2024-02-28 20:43:18 +09:00

65 lines
2.3 KiB
Text

@model BTCPayServer.Models.StoreViewModels.CreateStoreViewModel
@{
Layout = Model.IsFirstStore ? "_LayoutWizard" : "_Layout";
ViewData.SetActivePage(StoreNavPages.Create, Model.IsFirstStore ? "Create your first store" : "Create a new store");
}
@section PageFootContent {
<partial name="_ValidationScriptsPartial" />
<script>
const exchanges = @Safe.Json(StoreBlob.RecommendedExchanges);
const recommended = document.querySelector("#PreferredExchange option[value='']")
const updateRecommended = currency => {
const source = exchanges[currency] || 'coingecko'
const name = source.charAt(0).toUpperCase() + source.slice(1)
recommended.innerText = `${name} (Recommended)`
}
updateRecommended(@Safe.Json(Model.DefaultCurrency))
delegate('change', '#DefaultCurrency', e => updateRecommended(e.target.value))
</script>
}
@if (Model.IsFirstStore)
{
@section Navbar {
<a asp-route-skipWizard="true" class="cancel" id="SkipWizard">
<vc:icon symbol="close" />
</a>
}
@section PageHeadContent {
<style>
#FirstStore { max-width: 27rem; margin: 0 auto; text-align: center; }
#FirstStore .main-logo { height: 4.5rem; max-width: 18rem; }
#FirstStore .main-logo.main-logo-btcpay { width: 2.5rem; }
#FirstStore .main-logo-btcpay .main-logo-btcpay--large { display: none; }
#FirstStore .form-control, #FirstStore .form-select { width: 100%; }
#FirstStore .form-text { font-size: var(--btcpay-font-size-s); }
#FirstStore .form-group:last-of-type { text-align: center; }
</style>
}
<div id="FirstStore">
<a asp-controller="UIHome" asp-action="Index" tabindex="-1" class="d-inline-block mb-4">
<vc:main-logo />
</a>
<h1 class="h2 mb-3">@ViewData["Title"]</h1>
<p class="lead text-secondary">Create a store to begin accepting payments.</p>
<div class="text-start">
<partial name="_CreateStoreForm" model="Model" />
</div>
</div>
}
else
{
<h2 class="mt-1 mb-4">@ViewData["Title"]</h2>
<div class="row">
<div class="col-xl-8 col-xxl-constrain">
<partial name="_CreateStoreForm" model="Model" />
</div>
</div>
}