Portal application - initial.

This commit is contained in:
2021-07-08 20:50:46 +01:00
parent 13c79a8da4
commit 01ae03ddfc
1208 changed files with 186342 additions and 1690 deletions
@@ -0,0 +1,7 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
</div>
@@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
@@ -0,0 +1,69 @@
@model Model_Security
@inject SbmLocaliser Localiser
@{
ViewData["Title"] = "Change Password";
}
<div class="">
<div class="sbm-panel-form security">
<div class="sbm-header"><div class="sbm-caption">@Localiser["security.caption.change.password"]</div></div>
<div class="sbm-content">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmChangePassword", @class = "sbm-form" }))
{
@if (!Model.RequestPasswordMode)
{
/* Current password - required when setting password within user session. */
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="sbm-label"><label for="ifPasswordCurrent"><span><span class="required">*</span> @Localiser["label.password.current"]</span></label></div>
<div class="sbm-control">
@Html.PasswordFor(model => model.PasswordCurrent, new { @id = "ifPasswordCurrent", @class = "sbm-input", @maxlength = Model.PasswordMaxLength })
</div>
<div class="sbm-message"></div>
</div>
}
else
{
/* 'Request Password' encrypted parameters from email link. */
@Html.HiddenFor(model => model.rpe, new { @id = "ifRpe" });
}
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="sbm-label"><label for="ifPassword"><span><span class="required">*</span> @Localiser["label.password"]</span></label></div>
<div class="sbm-control">
@Html.PasswordFor(model => model.Password, new { @id = "ifPassword", @class = "sbm-input", @maxlength = Model.PasswordMaxLength })
</div>
<div class="row">
<div class="col-auto sbm-label-text pt4">@Localiser["label.strength"]&nbsp;</div>
<div id="" class="col-auto"><div id="prgPasswordStrength" class="col-auto"></div></div>
</div>
<div class="sbm-message"></div>
</div>
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="sbm-label"><label for="ifPasswordConfirm"><span><span class="required">*</span> @Localiser["label.password.confirm"]</span></label></div>
<div class="sbm-control">
@Html.PasswordFor(model => model.PasswordConfirm, new { @id = "ifPasswordConfirm", @class = "sbm-input", @maxlength = Model.PasswordMaxLength })
</div>
<div class="sbm-message"></div>
</div>
<div class="spacer4"></div>
<div class="">
<div id="pbChangePassword" class="sbm-button-action fullwidth pointer" style="margin:16px 0;">@Localiser["security.caption.change.password"]</div>
</div>
}
</div>
</div>
</div>
@@ -0,0 +1,39 @@
@model Model_Security
@inject SbmLocaliser Localiser
@{
ViewData["Title"] = "Change Password";
}
<div class="">
<div class="sbm-panel-form security">
<div class="sbm-header"><div class="sbm-caption">@Localiser["security.caption.request.password"]</div></div>
<div class="sbm-content">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmRequestPassword", @class = "sbm-form" }))
{
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="sbm-label">
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
</div>
<div class="sbm-control">
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = "128" })
</div>
<div class="sbm-message"></div>
</div>
<div class="spacer4"></div>
<div class="">
<div id="pbRequestPassword" class="sbm-button-action fullwidth pointer" style="margin:16px 0;">@Localiser["security.caption.request.password"]</div>
</div>
}
</div>
</div>
</div>
@@ -0,0 +1,71 @@
@using Sarand.Net.Standard.Base.Security
@model Model_Security
@inject SbmLocaliser Localiser
@{
ViewData["Title"] = "Signin";
ulong emailAddressLen = SaSecurityDbDfn.GetColTextLen(SaSecurityDbDfn.ColumnIdx.SaSecItem_EmailAddress);
}
<div class="">
<div class="sbm-panel-form security">
<div class="sbm-header"><div class="sbm-caption">@Localiser["security.caption.signin"]</div></div>
<div class="sbm-content">
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmSignIn", @class = "sbm-form" }))
{
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="sbm-label">
<label for="ifEmailAddress"><span><span class="required">*</span> @Localiser["label.email.address"]</span></label>
</div>
<div class="sbm-control">
@Html.TextBoxFor(model => model.EmailAddress, new { @id = "ifEmailAddress", @class = "sbm-input lower", @maxlength = @emailAddressLen })
</div>
<div class="sbm-message"></div>
</div>
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="row">
<div class="col-6">
<div class="sbm-label">
<label for="ifPassword"><span><span class="required">*</span> @Localiser["label.password"]</span></label>
</div>
</div>
</div>
<div class="sbm-control">
@Html.PasswordFor(model => model.Password, new { @id = "ifPassword", @class = "sbm-input", @maxlength = @Model.PasswordMaxLength })
</div>
<div class="sbm-message"></div>
</div>
<div class="spacer4"></div>
<div class="sbm-form-control">
<div class="row">
<div class="col-6">
@Html.CheckBoxFor(model => model.KeepMeSignedIn, new { @id = "chkKeepMeSignedIn" })
&nbsp;
<span class="sbm-label pointer" onclick="$('#chkKeepMeSignedIn').click()">@Localiser["label.keep.signed.in"]</span>
</div>
<div class="col-6 right">
<div class="sbm-action-link" style="font-size:0.9rem;" onclick="sbm.goToPage('Security/RequestPassword');">@Localiser["label.forgotten.password"]</div>
</div>
</div>
</div>
<div class="spacer4"></div>
<div class="">
<div id="pbSignIn" class="sbm-button-action fullwidth pointer" style="margin:16px 0;">@Localiser["security.caption.signin"]</div>
</div>
}
</div>
</div>
</div>
@@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@@ -0,0 +1,196 @@
@model SbmModel_Portal
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery AntiForgery;
@inject SbmLocaliser Localiser
@*
Application: BusinessMgr Web Portal
Purpose: Page template.
*@
@{
// Model properties to become javascript values.
var awaitingLogin = Model.AwaitingLogin ? "1" : "0";
var keepLoggedIn = Model.KeepLoggedIn ? "1" : "0";
var debug = Model.DebugMode ? "1" : "0";
}
<!DOCTYPE html>
<html lang="en">
<head>
@* Set base URL the same for all pages so that relative URLs work the same for all. *@
<base href="@Model.RedirectLocation.Base" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@* IE11 incompatibility eg. 'border-radius' not recognised. Must be at top of head *@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
@if (Model.ProhibitCache)
{
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
}
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="application/javascript" />
<title>@ViewData["Title"] - BusinessMgr</title>
@* Stylesheets *@
<link rel="stylesheet" href="~/lib/jqueryui/jquery-ui.css" />
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
crossorigin="anonymous"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" />
</environment>
<link rel="stylesheet" href="~/css/sbm-base.css?@Model.HrefVersion" />
<link rel="stylesheet" href="~/css/sbm-main.css?@Model.HrefVersion" />
<link rel="stylesheet" href="~/css/sbm-form.css?@Model.HrefVersion" />
<link rel="stylesheet" href="~/css/sbm-data.css?@Model.HrefVersion" />
@foreach (var cssFile in Model.AdditionalFiles_CSS)
{
<link rel="stylesheet" href="~/@cssFile?@Model.HrefVersion" />
}
@* Scripts *@
<script>
var sbm = sbm || { page: {}, url: {}, links: {}, data: {}, form: {}, ajax: {}, msg: {}, lbl: {}, dlg: { title: {}, btn: {} }, $frm: {}, $dlg: {}, $pnl: {} };
sbm.url.base = '@Model.RedirectLocation.Base';
sbm.url.home = '@Model.RedirectLocation.Home';
sbm.url.sessionExpired = '@Model.RedirectLocation.Home_SessionExpired';
sbm.form.calendarDateFormat = '@(Model.CalendarDateFormat)';
sbm.lbl.calendar='@Localiser.GetJavascriptText("label.calendar")';
sbm.dlg.title.alert = '@Localiser.GetJavascriptText("dialog.title.alert")';
sbm.dlg.title.confirm = '@Localiser.GetJavascriptText("dialog.title.confirm")';
sbm.dlg.title.progress = '@Localiser.GetJavascriptText("dialog.title.progress")';
sbm.dlg.title.signOut = '@Localiser.GetJavascriptText("label.signout")';
sbm.dlg.btn.yes = '@Localiser["label.yes"]';
sbm.dlg.btn.no = '@Localiser["label.no"]';
sbm.dlg.btn.ok = '@Localiser["label.ok"]';
sbm.dlg.btn.close = '@Localiser["label.close"]';
sbm.dlg.btn.cancel = '@Localiser["label.cancel"]';
sbm.lbl.availableCharacter = '@Localiser.GetJavascriptText("label.characters.one")';
sbm.lbl.availableCharacters = '@Localiser.GetJavascriptText("label.characters.count", "{0}")';
sbm.lbl.noneSelected = '@Localiser.GetJavascriptText("label.selected.none")';
sbm.lbl.numberSelected = '@Localiser.GetJavascriptText("label.selected.count", "{0}")';
sbm.msg.itemRemoveConfirm = '@Localiser.GetJavascriptText("msg.confirm.item.remove")';
sbm.msg.signOutConfirm = '@Localiser.GetJavascriptText("security.msg.signout.confirm")';
sbm.msg.somethingGoneWrong = '@Localiser.GetJavascriptText("msg.something.gone.wrong")';
sbm.msg.dataRefreshing = '@Localiser.GetJavascriptText("msg.data.refreshing")';
sbm.msg.dataQuerying = '@Localiser.GetJavascriptText("msg.data.querying")';
sbm.msg.dataNoneFound = '@Localiser.GetJavascriptText("msg.data.noneFound")';
sbm.maxProfileImageSize = 2*10**6;
sbm.sessionCookieName = '@Model.SessionCookieName';
sbm.awaitingLogin = @awaitingLogin;
sbm.keepLoggedIn = @keepLoggedIn;
sbm.keepLoggedInDelay = @(Sbm.Config.Admin.Session.Cookie.KeepLoggedInTimeoutMillis);
sbm.debugMode = @debug;
</script>
</head>
<body>
@* Header *@
<header id="sbm-page-header">
@* Navigation bar *@
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Sarand BusinessMgr</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">@Localiser["label.home"]</a>
</li>
@if (Model.AwaitingLogin)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Security" asp-action="">@Localiser["label.signin"]</a>
</li>
}
else
{
<li class="nav-item dropdown">
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@Localiser["label.reference"]
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Contacts');">@Localiser["label.contacts"]</div>
</div>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sbm-action" onclick="sbm.goToPage('Commodities');">@Localiser["label.commodities"]</div>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link text-dark dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@Localiser["label.security"]
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<div class="dropdown-item text-dark sbm-action" onclick="sbm.navigateTo('Security/ChangePassword');">@Localiser["label.change.password"]</div>
<div class="dropdown-divider"></div>
<div class="dropdown-item text-dark sbm-action" onclick="sbm.onSignOut();">@Localiser["label.signout"]</div>
</div>
</li>
}
</ul>
</div>
</div>
</nav>
</header>
@* Page body *@
<div id="sbm-page-body" class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
@* Footer *@
<footer id="sbm-page-footer" class="">
<div class="container">
&copy; 2021 - Sarand BusinessMgr Portal
</div>
</footer>
@* Form to allow page navigation. *@
@using (@Html.BeginForm(FormMethod.Post, new { @id = "frmNavigate" })) { }
<div id='sbm-please-wait'></div>
@* Scripts *@
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
</environment>
<environment exclude="Development">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o">
</script>
</environment>
<script src="~/lib/jqueryui/jquery-ui.js"></script>
<script src="~/js/sbm-main.js?@Model.HrefVersion"></script>
@foreach (var jsFile in Model.AdditionalFiles_JS)
{
<script src="~/@jsFile?@Model.HrefVersion"></script>
}
@if (Model.IncludeGoogleAnalytics)
{
<partial name="~/Views/Shared/_GoogleAnalytics.cshtml" />
}
@RenderSection("Scripts", required: false)
</body>
</html>
@@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
@@ -0,0 +1,4 @@
@using Sarand.BusinessMgr.Net.Standard.Base.App
@using Sarand.BusinessMgr.Net.Core.Web.App
@using Sarand.BusinessMgr.Net.Core.Web.Portal.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}