first commit

This commit is contained in:
Eric Gullickson
2025-07-15 20:34:05 -05:00
commit f7eca4bad5
602 changed files with 158990 additions and 0 deletions

8
Views/Shared/401.cshtml Normal file
View File

@@ -0,0 +1,8 @@
<div class="row">
<div class="col-1">
<a href="/Home" class="btn btn-secondary btn-md mt-1 mb-1"><i class="bi bi-arrow-left-square"></i></a>
</div>
<div class="col-11">
<h1>Access Denied</h1>
</div>
</div>

25
Views/Shared/Error.cshtml Normal file
View File

@@ -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>

180
Views/Shared/_Layout.cshtml Normal file
View File

@@ -0,0 +1,180 @@
@using MotoVaultPro.Helper
@using System.Globalization
<!DOCTYPE html>
@inject IConfigHelper config
@inject ITranslationHelper translator
@{
var userConfig = config.GetUserConfig(User);
var useDarkMode = userConfig.UseDarkMode;
var useSystemColorMode = userConfig.UseSystemColorMode;
var enableCsvImports = userConfig.EnableCsvImports;
var useMPG = userConfig.UseMPG;
var useMarkDown = userConfig.UseMarkDownOnSavedNotes;
var useThreeDecimals = userConfig.UseThreeDecimalGasCost;
var automaticDecimalFormat = userConfig.AutomaticDecimalFormat;
var shortDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
var numberFormat = CultureInfo.CurrentCulture.NumberFormat;
var userLanguage = userConfig.UserLanguage;
shortDatePattern = shortDatePattern.ToLower();
if (!shortDatePattern.Contains("dd"))
{
shortDatePattern = shortDatePattern.Replace("d", "dd");
}
if (!shortDatePattern.Contains("mm"))
{
shortDatePattern = shortDatePattern.Replace("m", "mm");
}
}
<html lang="en" data-bs-theme="@(useDarkMode ? "dark" : "light")">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-title" content="MotoVaultPro" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#181818">
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f3f3f3">
<title>@ViewData["Title"] - MotoVaultPro</title>
<link rel="icon" type="image/x-icon" href="~/favicon.png">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap-icons.css" />
<link rel="stylesheet" href="~/lib/bootstrap-datepicker/css/bootstrap-datepicker.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap-tagsinput/bootstrap-tagsinput.css" />
<link rel="stylesheet" href="~/css/site.css"/>
<link rel="stylesheet" href="~/css/loader.css"/>
<link rel="stylesheet" href="~/sweetalert/sweetalert2.min.css"/>
<link rel="icon" sizes="192x192" href="~/defaults/motovaultpro_icon_192.png" />
<link rel="icon" sizes="128x128" href="~/defaults/motovaultpro_icon_128.png" />
<link rel="apple-touch-icon" sizes="128x128" href="~/defaults/motovaultpro_icon_128.png" />
<link rel="apple-touch-icon-precomposed" sizes="128x128" href="~/defaults/motovaultpro_icon_128.png" />
<link rel="apple-touch-startup-image" href="~/defaults/motovaultpro_launch.png" />
<link rel="manifest" href="~/manifest.json">
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/shared.js?v=@StaticHelper.VersionNumber"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script>
<script src="~/lib/bootstrap-tagsinput/bootstrap-tagsinput.js"></script>
<script src="~/sweetalert/sweetalert2.all.min.js"></script>
<script src="~/js/loader.js?v=@StaticHelper.VersionNumber"></script>
<script>
function getGlobalConfig() {
return {
useDarkMode: "@useDarkMode" == "True" || ("@useSystemColorMode" == "True" && window.matchMedia('(prefers-color-scheme: dark)').matches),
enableCsvImport : "@enableCsvImports" == "True",
useMarkDown: "@useMarkDown" == "True",
currencySymbol: decodeHTMLEntities("@numberFormat.CurrencySymbol"),
useThreeDecimals: "@useThreeDecimals" == "True",
useMPG: "@useMPG" == "True",
firstDayOfWeek: @firstDayOfWeek
}
}
function getShortDatePattern() {
return {
pattern: "@shortDatePattern"
}
}
function globalParseFloat(input){
//remove thousands separator.
var thousandSeparator = decodeHTMLEntities("@numberFormat.NumberGroupSeparator");
var decimalSeparator = decodeHTMLEntities("@numberFormat.NumberDecimalSeparator");
var currencySymbol = decodeHTMLEntities("@numberFormat.CurrencySymbol");
if (input == "---") {
input = "0";
}
//strip thousands from input.
input = input.replace(thousandSeparator, "");
//convert to JS format where decimal is only separated by .
input = input.replace(decimalSeparator, ".");
//remove any currency symbol
input = input.replace(currencySymbol, "");
return parseFloat(input);
}
function globalFloatToString(input) {
var decimalSeparator = decodeHTMLEntities("@numberFormat.NumberDecimalSeparator");
input = input.replace(".", decimalSeparator);
return input;
}
function fixDecimalInput(input, numOfDecimals) {
if ("@automaticDecimalFormat" == "True") {
//get the decimal separator.
var decimalSeparator = decodeHTMLEntities("@numberFormat.NumberDecimalSeparator");
var inputText = $(input).val().trim();
inputText = inputText.replace(decimalSeparator, '');
inputText = +inputText;
if (isNaN(inputText)){
return;
}
inputText = inputText.toString();
if (inputText == '') {
return;
};
//check number of decimals.
if (inputText.length <= numOfDecimals) {
//less than number of decimals, assume everything is behind the decimal.
inputText = `0${decimalSeparator}${inputText}`; //add leading zero.
$(input).val(inputText);
} else {
//check if leading zero
var charToSlice = numOfDecimals * -1;
var charsBehindDecimal = inputText.slice(charToSlice);
var charsFrontDecimal = inputText.substr(0, inputText.length - numOfDecimals);
inputText = `${charsFrontDecimal}${decimalSeparator}${charsBehindDecimal}`;
$(input).val(inputText);
}
}
}
function interceptDecimalKeys(event) {
if ("@automaticDecimalFormat" == "True") {
if (event.which == 190 || event.which == 188) {
event.preventDefault(); //intercept keys.
}
}
}
function genericErrorMessage(){
return decodeHTMLEntities('@translator.Translate(userLanguage, "An error has occurred, please try again later")');
}
function globalAppendCurrency(input){
//check currency symbol position
var currencySymbolPosition = "@numberFormat.CurrencyPositivePattern";
var currencySymbol = decodeHTMLEntities("@numberFormat.CurrencySymbol");
switch (currencySymbolPosition) {
case "0":
return `${currencySymbol}${input}`;
break;
case "1":
return `${input}${currencySymbol}`;
break;
case "2":
return `${currencySymbol} ${input}`;
break;
case "3":
return `${input} ${currencySymbol}`;
break;
}
}
function setThemeBasedOnDevice() {
var systemPrefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (systemPrefersDarkMode) {
$(document.documentElement).attr("data-bs-theme", "dark");
}
}
</script>
@await RenderSectionAsync("Scripts", required: false)
</head>
<body>
@await RenderSectionAsync("Nav", required: false)
<div class="container motovaultpro-body-container">
<main role="main">
@RenderBody()
</main>
</div>
@await RenderSectionAsync("Footer", required: false)
</body>
</html>
@if (useSystemColorMode)
{
<script>
setThemeBasedOnDevice();
</script>
}

View File

@@ -0,0 +1,48 @@
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

View File

@@ -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>