This commit is contained in:
Zeeshaun
2026-03-17 08:54:34 -05:00
parent 64856c640e
commit cdcba54aa4
330 changed files with 54110 additions and 0 deletions
@@ -0,0 +1,6 @@
@if (Loaded)
{
<div class="alert @ResultClass">
Last Import: Started @Import.StartDate.ToString("M/d/yyyy h:mm tt"), @GetCompletedText()@GetResultText()
</div>
}
@@ -0,0 +1,93 @@
using Blazored.Modal;
using Blazored.Modal.Services;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using ReserveManagementSystemLib.Models;
using ReserveManagementSystemUI.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ReserveManagementSystemUI.Shared.Components
{
public partial class ImportBanner: ComponentBase
{
[Inject]
ReserveService ReserveService { get; set; }
[Inject]
IToastService ToastService { get; set; }
[Inject]
IModalService Modal { get; set; }
public Import Import = new Import();
public bool Loaded = false;
public string ResultClass => Import.Success ? "alert-success" : "alert-danger";
[Parameter]
public bool Refresh { get; set; }
protected override async Task OnParametersSetAsync()
{
if (Refresh) {
await GetImport();
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await GetImport();
}
await base.OnAfterRenderAsync(firstRender);
}
public async Task<bool> GetImport()
{
var result = true;
Import = (await ReserveService.GetRecentImports(1)).FirstOrDefault();
if (Import == null)
{
ToastService.ShowError("There was an issue retrieving import data.");
Import = new Import();
result = false;
}
Loaded = true;
StateHasChanged();
return result;
}
public string GetCompletedText()
{
if (Import.EndDate.HasValue)
{
return $"Completed {Import.EndDate?.ToString("M/d/yyyy h:mm tt")}, ";
}
return string.Empty;
}
public string GetResultText()
{
if (Import.Success)
{
return $"Processed {Import.RecordCount} records";
}
if (!Import.Success && Import.RecordCount > 0)
{
return $"Processed {Import.RecordCount} records, but only saved {Import.RecordsSaved}";
}
return $"Failed to process";
}
}
}
@@ -0,0 +1,56 @@
@using ReserveManagementSystemUI.Shared.Components.Table;
@attribute [Authorize(Policy = "IsRMSAssociate")]
<ImportBanner Refresh="@updateBanner"></ImportBanner>
<TabControl>
<TabTextTemplate Context="TheTab">
@TheTab.Text
</TabTextTemplate>
<ChildContent>
<TabPage Text="Recent Imports">
<div class="import-heading"><h5>This is a list of @HeadingText imports; please click Select to view the loans in that import.</h5></div>
<div class="basic-float-right">
<div style="text-align: center;padding: 15px;">
<button type="button" class="btn btn-primary" @onclick="@(() => ImportActiveLoans())">Import Active Loans</button>
<button type="button" class="btn btn-primary" @onclick="@(() => ImportClosedLoans())">Import Closed Loans</button>
</div>
</div>
<table class="table table-striped table-hover">
<thead>
<tr>
<TableHeader TableHeaderValue="Import Type" OnClick="OnSortClick" HeaderName="ImportType" SelectedHeader="@currentSortedHeader" Ascending="@ascending" />
<TableHeader TableHeaderValue="Start Date" OnClick="OnSortClick" HeaderName="StartDate" SelectedHeader="@currentSortedHeader" Ascending="@ascending" />
<TableHeader TableHeaderValue="End Date" OnClick="OnSortClick" HeaderName="EndDate" SelectedHeader="@currentSortedHeader" Ascending="@ascending" />
<TableHeader TableHeaderValue="Record Count" OnClick="OnSortClick" HeaderName="RecordCount" SelectedHeader="@currentSortedHeader" Ascending="@ascending" />
<TableHeader TableHeaderValue="Records Saved" OnClick="OnSortClick" HeaderName="RecordsSaved" SelectedHeader="@currentSortedHeader" Ascending="@ascending" />
<TableHeader TableHeaderValue="Success" OnClick="OnSortClick" HeaderName="Success" SelectedHeader="@currentSortedHeader" Ascending="@ascending" />
<TableData TableDataValue="" />
</tr>
</thead>
<tbody>
@foreach (var import in Imports)
{
<tr>
<TableData TableDataValue="@import.ImportType" />
<TableData TableDataValue="@import.StartDate.ToString("M/d/yyyy h:mm:ss tt")" />
<TableData TableDataValue="@import.EndDate?.ToString("M/d/yyyy h:mm:ss tt")" />
<TableData TableDataValue="@import.RecordCount.ToString()" />
<TableData TableDataValue="@import.RecordsSaved.ToString()" />
<TableData TableDataValue="@(import.Success ? "Yes": "No")" />
<td>
<div style="text-align: center;padding: 5px;width: 115px;">
<button type="button" class="btn btn-primary" @onclick="@(() => GoToLoanSummary(import.ImportId))">Select</button>
</div>
</td>
</tr>
}
</tbody>
</table>
</TabPage>
</ChildContent>
</TabControl>
@@ -0,0 +1,154 @@
using Blazored.Modal;
using Blazored.Modal.Services;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using ReserveManagementSystemLib.Models;
using ReserveManagementSystemUI.Helpers;
using ReserveManagementSystemUI.Services;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.Globalization;
using System;
using Serilog;
namespace ReserveManagementSystemUI.Shared.Components
{
public partial class ImportList: ComponentBase
{
[Inject]
IToastService ToastService { get; set; }
[Inject]
IModalService Modal { get; set; }
[Inject]
ReserveService ReserveService { get; set; }
[Inject]
NavigationManager NavigationManager { get; set; }
[Inject]
GridHelpers GridHelpers { get; set; }
[Inject]
ServiceHelpers ServiceHelpers { get; set; }
[Parameter]
public bool ShowAllImports { get; set; }
[Parameter]
public int NumberOfImportsToShow { get; set; }
public List<Import> Imports = new List<Import>();
private bool ascending;
private string currentSortedHeader;
private bool updateBanner;
private IModalReference openModal;
private string HeadingText => ShowAllImports ? "all" : $"the last {NumberOfImportsToShow}";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
openModal = Modal.Show<LoadingSpinner>();
await GetImports();
}
await base.OnAfterRenderAsync(firstRender);
}
public async Task<bool> GetImports()
{
var result = true;
if (ShowAllImports)
{
Imports = await ReserveService.GetAllImports();
}
else
{
Imports = await ReserveService.GetRecentImports(NumberOfImportsToShow);
}
if (Imports == null)
{
ToastService.ShowError("There was an issue retrieving import data.");
Imports = new List<Import>();
result = false;
}
StateHasChanged();
openModal.Close();
return result;
}
private void OnSortClick(string sortBy)
{
var sameClick = sortBy == currentSortedHeader;
if (sameClick)
{
ascending = !ascending;
}
if (ascending)
{
Imports = GridHelpers.OrderByAscending(Imports, sortBy);
}
else
{
Imports = GridHelpers.OrderByDescending(Imports, sortBy);
}
currentSortedHeader = sortBy;
StateHasChanged();
}
void GoToLoanSummary(int importId)
{
NavigationManager.NavigateTo($"Loans/{importId}");
}
private async Task ImportActiveLoans()
{
openModal = Modal.Show<LoadingLighthouse>();
await Task.Delay(500);
Log.Information("Import Active Loans started by user:" + ServiceHelpers.GetUserName());
ToastService.ShowSuccess("Import Active Loans has started, please wait before clicking again may produce import errors.");
//import the active loans since last successful active import start date
await ReserveService.GetActiveLoans();
await GetImports(); //update the banner and import list with new import
updateBanner = true;
openModal.Close();
}
private async Task ImportClosedLoans()
{
openModal = Modal.Show<LoadingLighthouse>();
await Task.Delay(500);
Log.Information("Import Closed Loans started by user:" + ServiceHelpers.GetUserName());
//import the closed loans since last successful closed import start date
await ReserveService.GetClosedLoans();
await GetImports(); //update the banner and import list with new import
updateBanner = true;
openModal.Close();
}
}
}
@@ -0,0 +1,5 @@
<img src="images/lighthouse.gif" alt="LCU Lighthouse" class="loading-lighthouse">
@code {
[CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; }
}
@@ -0,0 +1,9 @@
<div class="loading-spinner">
<div class="fa-5x">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
@code {
[CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; }
}
@@ -0,0 +1,20 @@
<td class="alignTextCenter">
<div class="basicInlineBlock">
@TableDataValue
</div>
@if (@DisplayWarning)
{
<div class="basicInlineBlock">
<i class="oi oi-warning warningColor"></i>
</div>
}
</td>
@code {
[Parameter]
public string TableDataValue { get; set; } = "";
[Parameter]
public bool DisplayWarning { get; set; } = false;
}
@@ -0,0 +1,29 @@
<td class="alignTextCenter sortableTableHeader" @onclick="@(e=> OnClick(HeaderName))">
<div class="basicInlineBlock">
@if (HeaderName == SelectedHeader)
{
if (Ascending)
{
<span class="oi oi-caret-top" />
}
else
{
<span class="oi oi-caret-bottom" />
}
}
@TableHeaderValue
</div>
</td>
@code {
[Parameter]
public string TableHeaderValue { get; set; } = "";
[Parameter]
public Action<string> OnClick { get; set; }
[Parameter]
public string SelectedHeader { get; set; } = "";
[Parameter]
public string HeaderName { get; set; }
[Parameter]
public bool Ascending { get; set; }
}
@@ -0,0 +1,5 @@
<AuthorizeView >
<div class="login-Display">
Hello, @context.User.Identity.Name.Substring(4)
</div>
</AuthorizeView>
@@ -0,0 +1,23 @@
@inherits LayoutComponentBase
@using Blazored.Toast.Configuration
<link rel="stylesheet" href="css/font-awesome/css/fontawesome.min.css" />
<NavMenu />
<CascadingValue Value="this">
<div class="main d-flex flex-column min-vh-100">
<div class="flex-fill">
<LoginDisplay />
<BlazoredToasts Position="ToastPosition.BottomRight" />
<div class="content px-4">
@Body
</div>
</div>
<footer class="footer py-3">
<p class="m-0 text-center text-white">
Copyright &copy; @DateTime.Now.Year Landmark Credit Union
@GetAppVersion()
</p>
</footer>
</div>
</CascadingValue>
@@ -0,0 +1,33 @@
using Blazored.Modal.Services;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace ReserveManagementSystemUI.Shared
{
public partial class MainLayout: LayoutComponentBase
{
[Inject]
IToastService ToastService { get; set; }
[Inject]
IConfiguration Configuration { get; set; }
[Inject]
IModalService Modal { get; set; }
private string GetAppVersion()
{
var version = string.IsNullOrEmpty(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion) ?
"" :
$"v{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion}";
return version;
}
}
}
@@ -0,0 +1,50 @@
@using Microsoft.Extensions.Configuration;
@inject IConfiguration Configuration;
<nav class="navbar navbar-expand-lg navbar-dark fixed-top lcu-navbar">
<a class="navbar-brand title-main" href="">
<img src="images/LMCU-White-Logo-Only.png" alt="Landmark Lighthouse Logo" class="logo-main App-logo">
<span className="nav-app-title">Reserve Management System</span>
</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="@NavMenuCssClass" id="navbarResponsive">
<LoginDisplay />
<ul class="navbar-nav-addon navbar-nav ml-auto">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<AuthorizeView Policy="IsRMSAssociate">
<li class="nav-item px-3">
<NavLink class="nav-link" href="Loans" Match="NavLinkMatch.All">
<span class="oi oi-credit-card" aria-hidden="true"></span> Loans
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="Statements">
<span class="oi oi-folder" aria-hidden="true"></span> Statements
</NavLink>
</li>
</AuthorizeView>
</ul>
</div>
</nav>
@code {
bool collapseNavMenu = true;
string NavMenuCssClass => collapseNavMenu ? "collapse navbar-collapse" : "collapse navbar-collapse show";
void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
void ForceClosed()
{
collapseNavMenu = true;
}
}