Browse Source

Merge pull request 'Dashboard commit 6 ...80% complete' (#11) from BISK2023-21-develop-the-frontend-for-the-dashboard into dev

Reviewed-on: #11
BISK2023-4-item-search-feature
Benjamin Arhen 2 years ago
parent
commit
e189aeb4e2
  1. 1
      Client/Biskilog Accounting.Client.csproj
  2. 18
      Client/Pages/Dashboard/Dashboard.razor
  3. 64
      Client/Pages/Dashboard/Dashboard.razor.cs
  4. 44
      Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor
  5. 8
      Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor.cs
  6. 23
      Client/Pages/Dashboard/Elements/ChartElement.razor
  7. 24
      Client/Pages/Dashboard/Elements/LowStockItems.razor
  8. 4
      Client/Pages/Dashboard/Elements/LowStockItems.razor.cs
  9. 24
      Client/Pages/Dashboard/Elements/MostPurchasedElement.razor
  10. 16
      Client/Pages/Dashboard/Elements/ProductPriceHistory.razor
  11. 29
      Client/Pages/Dashboard/Elements/ProductPriceHistory.razor.cs
  12. 63
      Client/Pages/Dashboard/Elements/TransactionCard.razor
  13. 58
      Client/Pages/Dashboard/Elements/WelcomeCard.razor
  14. 5
      Client/Pages/Dashboard/Elements/WelcomeCard.razor.cs
  15. 7
      Client/Program.cs

1
Client/Biskilog Accounting.Client.csproj

@ -20,6 +20,7 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Blazor-ApexCharts" Version="0.9.21-beta" /> <PackageReference Include="Blazor-ApexCharts" Version="0.9.21-beta" />
<PackageReference Include="Microsoft.Fast.Components.FluentUI" Version="2.3.6" />
<PackageReference Include="Radzen.Blazor" Version="4.12.0" /> <PackageReference Include="Radzen.Blazor" Version="4.12.0" />
</ItemGroup> </ItemGroup>

18
Client/Pages/Dashboard/Dashboard.razor

@ -7,35 +7,35 @@
<div class="container-xxl flex-grow-1 container-p-y"> <div class="container-xxl flex-grow-1 container-p-y">
<div class="row"> <div class="row">
<div class="col-lg-8 mb-4 order-0"> <div class="col-lg-8 mb-4 order-0">
<WelcomeCard TradeSummary="@m_tradeSummary" Username="@m_username" /> <WelcomeCard TradeSummary="@m_tradeSummary" Username="@m_username" IsLoading="@m_loadingTradeSummary" />
</div> </div>
<div class="col-lg-4 col-md-4 order-1"> <div class="col-lg-4 col-md-4 order-1">
<div class="row"> <div class="row">
<div class="col-lg-6 col-md-12 col-6 mb-4"> <div class="col-lg-6 col-md-12 col-6 mb-4">
<AnalyticsItemSmall Icon="../assets/img/icons/unicons/chart-success.png" Title="Transactions" Value="@m_tradeSummary.CurrentTradeSales" Percentage="@(((m_tradeSummary.CurrentTradeSales-m_tradeSummary.LastTradeSales)/m_tradeSummary.LastTradeSales)*100)" /> <AnalyticsItemSmall IsLoading="@m_loadingTradeSummary" Icon="../assets/img/icons/unicons/chart-success.png" Title="Transactions" Value="@m_tradeSummary.CurrentTradeSales" Percentage="@(((m_tradeSummary.CurrentTradeSales-m_tradeSummary.LastTradeSales)/m_tradeSummary.LastTradeSales)*100)" />
</div> </div>
<div class="col-lg-6 col-md-12 col-6 mb-4"> <div class="col-lg-6 col-md-12 col-6 mb-4">
<AnalyticsItemSmall Icon="../assets/img/icons/unicons/wallet-info.png" Title="Cancelled Sales" Value="@(m_cancelledWeeklySale)" Percentage="@(m_cancelledPercentage)" /> <AnalyticsItemSmall IsLoading="@m_loadingCancelledSummary" Icon="../assets/img/icons/unicons/wallet-info.png" Title="Cancelled Sales" Value="@(m_cancelledWeeklySale)" Percentage="@(m_cancelledPercentage)" />
</div> </div>
</div> </div>
</div> </div>
<!-- Total Revenue --> <!-- Total Revenue -->
<div class="col-12 col-lg-8 order-2 order-md-3 order-lg-2 mb-4"> <div class="col-12 col-lg-8 order-2 order-md-3 order-lg-2 mb-4">
<ChartElement Series="@m_weeklySaleItems" Title="Weekly Revenue" SubTitle="Sale Trend" IsLoading="@loadWeeklySales" /> <ChartElement Series="@m_weeklySaleItems" Title="Weekly Revenue" SubTitle="Sale Trend" IsLoading="@m_loadingWeeklySales" />
</div> </div>
<!--/ Total Revenue --> <!--/ Total Revenue -->
<div class="col-12 col-md-8 col-lg-4 order-3 order-md-2"> <div class="col-12 col-md-8 col-lg-4 order-3 order-md-2">
<div class="row"> <div class="row">
<div class="col-6 mb-4"> <div class="col-6 mb-4">
<AnalyticsItemSmall Icon="../assets/img/icons/unicons/paypal.png" Title="Credit Sales" Value="2456" Percentage="-22" /> <AnalyticsItemSmall IsLoading="@(!m_loadingCreditSummary)" Icon="../assets/img/icons/unicons/paypal.png" Title="Credit Sales" Value="2456" Percentage="-22" />
</div> </div>
<div class="col-6 mb-4"> <div class="col-6 mb-4">
<AnalyticsItemSmall Icon="../assets/img/icons/unicons/cc-primary.png" Title="Debts To Collect" Value="@(m_totalDebt)" Percentage="-22" /> <AnalyticsItemSmall IsLoading="@m_loadingDebtSummary" Icon="../assets/img/icons/unicons/cc-primary.png" Title="Debts To Collect" Value="@(m_totalDebt)" Percentage="-22" />
</div> </div>
<!-- </div> <!-- </div>
<div class="row"> --> <div class="row"> -->
<div class="col-12 mb-4"> <div class="col-12 mb-4">
<ProductPriceHistory ProductHistory="@m_ProductPriceChanges" IsLoading="@loadingPriceHistory" /> <ProductPriceHistory ProductHistory="@m_ProductPriceChanges" IsLoading="@m_loadingPriceHistory" />
</div> </div>
</div> </div>
</div> </div>
@ -43,7 +43,7 @@
<div class="row"> <div class="row">
<!-- Low stock items --> <!-- Low stock items -->
<div class="col-md-6 col-lg-4 col-xl-4 order-0 mb-4"> <div class="col-md-6 col-lg-4 col-xl-4 order-0 mb-4">
<LowStockItems LowStockProducts="@m_lowstock" /> <LowStockItems LowStockProducts="@m_lowstock" IsLoading="@m_loadingLowStockSummary" />
</div> </div>
<!--/ Order Statistics --> <!--/ Order Statistics -->
<!-- Expense Overview --> <!-- Expense Overview -->
@ -54,7 +54,7 @@
<!-- Transactions --> <!-- Transactions -->
<div class="col-md-6 col-lg-4 order-2 mb-4"> <div class="col-md-6 col-lg-4 order-2 mb-4">
<!-- Recent Transactions --> <!-- Recent Transactions -->
<TransactionCard Sales="@m_recentTransaction" /> <TransactionCard Sales="@m_recentTransaction" IsLoading="@m_loadingRecentTransactionsSummary" />
<!--/ Recent Transactions --> <!--/ Recent Transactions -->
</div> </div>
<!--/ Transactions --> <!--/ Transactions -->

64
Client/Pages/Dashboard/Dashboard.razor.cs

@ -6,6 +6,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
public partial class Dashboard public partial class Dashboard
{ {
#region Declarations
private TradeSummary m_tradeSummary { get; set; } = new TradeSummary(); private TradeSummary m_tradeSummary { get; set; } = new TradeSummary();
private List<WeeklySaleItem> m_weeklySaleItems { get; set; } = new List<WeeklySaleItem> { }; private List<WeeklySaleItem> m_weeklySaleItems { get; set; } = new List<WeeklySaleItem> { };
private List<CancelledSales> m_weeklyCancelledSales { get; set; } = new List<CancelledSales> { }; private List<CancelledSales> m_weeklyCancelledSales { get; set; } = new List<CancelledSales> { };
@ -17,10 +18,18 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
private double m_cancelledPercentage { get; set; } = 0; private double m_cancelledPercentage { get; set; } = 0;
private double m_totalDebt { get; set; } = 0; private double m_totalDebt { get; set; } = 0;
private string m_username { get; set; } = string.Empty; private string m_username { get; set; } = string.Empty;
private bool loadWeeklySales = true; #region Loading Variables
private bool loadingPriceHistory = true; private bool m_loadingWeeklySales = true;
private bool m_loadingPriceHistory = true;
private bool m_loadingMostPurchased { get; set; } = true; private bool m_loadingMostPurchased { get; set; } = true;
private bool m_loadingTradeSummary { get; set; } = true;
private bool m_loadingDebtSummary { get; set; } = true;
private bool m_loadingLowStockSummary { get; set; } = true;
private bool m_loadingRecentTransactionsSummary { get; set; } = true;
private bool m_loadingCancelledSummary { get; set; } = true;
private bool m_loadingCreditSummary { get; set; } = true;
#endregion
#endregion
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
m_username = m_tokenService.GetUserNameFromToken(await m_tokenService.GetToken())!; m_username = m_tokenService.GetUserNameFromToken(await m_tokenService.GetToken())!;
@ -48,9 +57,6 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
productPriceChangeHistoryTask productPriceChangeHistoryTask
); );
}); });
// Rest of the code...
return; return;
} }
@ -62,6 +68,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
m_loadingTradeSummary = true;
StateHasChanged();
var response = await m_http.GetAsync("api/analytics/tradesummary"); var response = await m_http.GetAsync("api/analytics/tradesummary");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -69,6 +77,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var tradeSummary = JsonSerializer.Deserialize<TradeSummary>(jsonContent, options); var tradeSummary = JsonSerializer.Deserialize<TradeSummary>(jsonContent, options);
m_tradeSummary = tradeSummary; m_tradeSummary = tradeSummary;
m_loadingTradeSummary = false;
StateHasChanged(); StateHasChanged();
} }
} }
@ -85,6 +94,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
m_loadingDebtSummary = true;
StateHasChanged();
var response = await m_http.GetAsync("api/analytics/debtors"); var response = await m_http.GetAsync("api/analytics/debtors");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -92,6 +103,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var debt = JsonSerializer.Deserialize<List<InDebtCustomers>>(jsonContent, options); var debt = JsonSerializer.Deserialize<List<InDebtCustomers>>(jsonContent, options);
m_totalDebt = (double)debt.Sum(c => c.Debt); m_totalDebt = (double)debt.Sum(c => c.Debt);
m_loadingDebtSummary = false;
StateHasChanged(); StateHasChanged();
} }
} }
@ -108,6 +120,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
m_loadingWeeklySales = true;
StateHasChanged();
var response = await m_http.GetAsync("api/analytics/sales/weekly"); var response = await m_http.GetAsync("api/analytics/sales/weekly");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -115,7 +129,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var sales = JsonSerializer.Deserialize<List<WeeklySaleItem>>(jsonContent, options); var sales = JsonSerializer.Deserialize<List<WeeklySaleItem>>(jsonContent, options);
m_weeklySaleItems = sales; m_weeklySaleItems = sales;
loadWeeklySales = false; m_loadingWeeklySales = false;
StateHasChanged(); StateHasChanged();
} }
} }
@ -132,8 +146,10 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
DateTime start = DateTime.Now.AddDays(-7).Date; m_loadingCancelledSummary = true;
DateTime end = DateTime.Now.Date; StateHasChanged();
string start = m_tradeSummary.CurrentTradeDate.Date.AddDays(-7).ToString("yyyy-MM-dd");
string end = m_tradeSummary.CurrentTradeDate.ToString("yyyy-MM-dd");
var response = await m_http.GetAsync($"api/analytics/cancelledsales/{start}/{end}"); var response = await m_http.GetAsync($"api/analytics/cancelledsales/{start}/{end}");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -143,24 +159,21 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
m_weeklyCancelledSales = weekly; m_weeklyCancelledSales = weekly;
var loadCancelledSales = m_weeklyCancelledSales.OrderByDescending(t => t.CancelledTransaction.DateCancelled); var loadCancelledSales = m_weeklyCancelledSales.OrderByDescending(t => t.CancelledTransaction.DateCancelled);
if (loadCancelledSales.Count() > 1) if (loadCancelledSales.Count() >= 1)
{ {
m_cancelledWeeklySale = (double)loadCancelledSales.ToList()[0].Value; m_cancelledWeeklySale = (double)loadCancelledSales.ToList()[0].Value;
m_cancelledPercentage = (((double)loadCancelledSales.ToList()[0].Value - (double)loadCancelledSales.ToList()[1].Value) / (double)loadCancelledSales.ToList()[0].Value) * 100; m_cancelledPercentage = (((double)loadCancelledSales.ToList()[0].Value - (double)loadCancelledSales.ToList()[1].Value) / (double)loadCancelledSales.ToList()[0].Value) * 100;
} }
else else
{ {
m_cancelledWeeklySale = (double)loadCancelledSales.FirstOrDefault().Value; m_cancelledWeeklySale = 0;
m_cancelledPercentage = 0; m_cancelledPercentage = 0;
} }
m_loadingCancelledSummary = false;
StateHasChanged(); StateHasChanged();
} }
} }
catch (Exception ex) catch { }
{
Console.WriteLine(ex.Message);
}
} }
/// <summary> /// <summary>
/// Gets the recent transaction /// Gets the recent transaction
@ -170,6 +183,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
m_loadingRecentTransactionsSummary = true;
StateHasChanged();
var response = await m_http.GetAsync($"api/analytics/sales/recent/{50}"); var response = await m_http.GetAsync($"api/analytics/sales/recent/{50}");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -177,6 +192,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var recent = JsonSerializer.Deserialize<List<SaleItem>>(jsonContent, options); var recent = JsonSerializer.Deserialize<List<SaleItem>>(jsonContent, options);
m_recentTransaction = recent; m_recentTransaction = recent;
m_loadingRecentTransactionsSummary = false;
StateHasChanged(); StateHasChanged();
} }
} }
@ -191,6 +207,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
try try
{ {
m_loadingMostPurchased = true; m_loadingMostPurchased = true;
StateHasChanged();
string start = m_tradeSummary.LastTradeDate.ToString("yyyy-MM-dd"); string start = m_tradeSummary.LastTradeDate.ToString("yyyy-MM-dd");
string end = m_tradeSummary.CurrentTradeDate.ToString("yyyy-MM-dd"); string end = m_tradeSummary.CurrentTradeDate.ToString("yyyy-MM-dd");
var response = await m_http.GetAsync($"api/analytics/mostpurchaseditem/" + start + "/" + end); var response = await m_http.GetAsync($"api/analytics/mostpurchaseditem/" + start + "/" + end);
@ -214,6 +231,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
m_loadingLowStockSummary = true;
StateHasChanged();
var response = await m_http.GetAsync($"api/analytics/lowonstock"); var response = await m_http.GetAsync($"api/analytics/lowonstock");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -221,12 +240,11 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var recent = JsonSerializer.Deserialize<List<ProductItem>>(jsonContent, options); var recent = JsonSerializer.Deserialize<List<ProductItem>>(jsonContent, options);
m_lowstock = recent; m_lowstock = recent;
m_loadingLowStockSummary = false;
StateHasChanged(); StateHasChanged();
} }
} }
catch (Exception ex) catch { }
{
}
} }
/// <summary> /// <summary>
/// Gets a collection of items that are low on stock /// Gets a collection of items that are low on stock
@ -236,6 +254,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
{ {
try try
{ {
m_loadingPriceHistory = true;
StateHasChanged();
var response = await m_http.GetAsync($"api/analytics/pricechanges/product/history/{5}"); var response = await m_http.GetAsync($"api/analytics/pricechanges/product/history/{5}");
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -243,13 +263,11 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var recent = JsonSerializer.Deserialize<List<ProductPriceChange>>(jsonContent, options); var recent = JsonSerializer.Deserialize<List<ProductPriceChange>>(jsonContent, options);
m_ProductPriceChanges = recent; m_ProductPriceChanges = recent;
loadingPriceHistory = false; m_loadingPriceHistory = false;
StateHasChanged(); StateHasChanged();
} }
} }
catch (Exception ex) catch { }
{
}
} }
} }
} }

44
Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor

@ -1,17 +1,39 @@
@using Biskilog_Accounting.Shared.Interfaces @using Biskilog_Accounting.Shared.Interfaces
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator @inject ICalculator m_calculator
<div class="card"> @if (!IsLoading)
<div class="card-body"> {
<div class="card-title d-flex align-items-start justify-content-between"> <div class="card">
<div class="avatar flex-shrink-0"> <div class="card-body">
<img src="@Icon" <div class="card-title d-flex align-items-start justify-content-between">
alt="chart success" <div class="avatar flex-shrink-0">
class="rounded" /> <img src="@Icon"
alt="chart success"
class="rounded" />
</div>
</div> </div>
<span class="fw-semibold d-block mb-1">@Title</span>
<h6 class="card-title mb-2">@(m_calculator.FormatMoneyWithCurrency(Value))</h6>
<small class="@(Percentage > 0 ? "text-success" : Percentage == 0 ? "bx-forward-arrow-alt" : "text-danger") fw-semibold"><i class="bx @(Percentage > 0 ? "bx-up-arrow-alt" : Percentage == 0 ? "bx-forward-arrow-alt" : "bx-down-arrow-alt")"></i> @(Percentage.ToString("0.00")) %</small>
</div> </div>
<span class="fw-semibold d-block mb-1">@Title</span>
<h6 class="card-title mb-2">@(m_calculator.FormatMoneyWithCurrency(Value))</h6>
<small class="@(Percentage > 0 ? "text-success" : Percentage == 0 ? "bx-forward-arrow-alt" : "text-danger") fw-semibold"><i class="bx @(Percentage > 0 ? "bx-up-arrow-alt" : Percentage == 0 ? "bx-forward-arrow-alt" : "bx-down-arrow-alt")"></i> @(Percentage.ToString("0.00")) %</small>
</div> </div>
</div> }
else
{
<FluentCard class="card-padding">
<FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
}

8
Client/Pages/Dashboard/Elements/AnalyticsItemSmall.razor.cs

@ -7,10 +7,12 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
[Parameter] [Parameter]
public string Icon { get; set; } = string.Empty; public string Icon { get; set; } = string.Empty;
[Parameter] [Parameter]
public string Title { get; set; }= string.Empty; public string Title { get; set; } = string.Empty;
[Parameter] [Parameter]
public double Value{ get; set; } public double Value { get; set; }
[Parameter] [Parameter]
public double Percentage { get;set; } public double Percentage { get; set; }
[Parameter]
public bool IsLoading { get; set; } = true;
} }
} }

23
Client/Pages/Dashboard/Elements/ChartElement.razor

@ -1,10 +1,11 @@
@using Biskilog_Accounting.Shared.CustomModels; @using Biskilog_Accounting.Shared.CustomModels;
@using Biskilog_Accounting.Shared.Interfaces; @using Biskilog_Accounting.Shared.Interfaces;
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator @inject ICalculator m_calculator
@if (!IsLoading) @if (!IsLoading)
{ {
<div class="card"> <div class="card" style="min-height:480px;">
<div class="row row-bordered g-0"> <div class="row row-bordered g-0">
<div class="col-md-7"> <div class="col-md-7">
<h5 class="card-header m-0 me-2 pb-3">@Title</h5> <h5 class="card-header m-0 me-2 pb-3">@Title</h5>
@ -49,6 +50,22 @@
</div> </div>
</div> </div>
</div> </div>
}else{ }
else
{
<FluentCard class="card-padding">
<FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
} }

24
Client/Pages/Dashboard/Elements/LowStockItems.razor

@ -1,7 +1,9 @@
@using Biskilog_Accounting.Shared.CustomModels; @using Biskilog_Accounting.Shared.CustomModels;
@using Biskilog_Accounting.Shared.Interfaces; @using Biskilog_Accounting.Shared.Interfaces;
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator @inject ICalculator m_calculator
@if(!IsLoading){
<div class="card h-100"> <div class="card h-100">
<div class="card-header d-flex align-items-center justify-content-between pb-0"> <div class="card-header d-flex align-items-center justify-content-between pb-0">
<div class="card-title mb-0"> <div class="card-title mb-0">
@ -28,3 +30,25 @@
</RadzenDataGrid> </RadzenDataGrid>
</div> </div>
</div> </div>
}else{
<FluentCard class="card-padding">
<FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
}
<style>
.rz-datatable {
border: none !important;
}
</style>

4
Client/Pages/Dashboard/Elements/LowStockItems.razor.cs

@ -6,6 +6,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
public partial class LowStockItems public partial class LowStockItems
{ {
[Parameter] [Parameter]
public IEnumerable<ProductItem> LowStockProducts { get;set; } = new List<ProductItem>(); public IEnumerable<ProductItem> LowStockProducts { get; set; } = new List<ProductItem>();
[Parameter]
public bool IsLoading { get; set; } = true;
} }
} }

24
Client/Pages/Dashboard/Elements/MostPurchasedElement.razor

@ -1,5 +1,6 @@
@using Biskilog_Accounting.Shared.CustomModels; @using Biskilog_Accounting.Shared.CustomModels;
@using Biskilog_Accounting.Shared.Interfaces; @using Biskilog_Accounting.Shared.Interfaces;
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator @inject ICalculator m_calculator
@if (!IsLoading) @if (!IsLoading)
@ -34,10 +35,21 @@
} }
else else
{ {
<div class="card h-100"> <FluentCard class="card-padding">
<div class="card-body" style="padding:5px !important;"> <FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
</div> <FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
</div> <FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
} }
<style> <style>
.rz-datatable-thead th, .rz-grid-table thead th { .rz-datatable-thead th, .rz-grid-table thead th {
@ -52,4 +64,8 @@ else
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
} }
.rz-datatable {
border: none !important;
}
</style> </style>

16
Client/Pages/Dashboard/Elements/ProductPriceHistory.razor

@ -1,5 +1,6 @@
@using Biskilog_Accounting.Shared.CustomModels; @using Biskilog_Accounting.Shared.CustomModels;
@using Biskilog_Accounting.Shared.Interfaces; @using Biskilog_Accounting.Shared.Interfaces;
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator @inject ICalculator m_calculator
@if (!IsLoading) @if (!IsLoading)
{ {
@ -14,5 +15,20 @@
} }
else else
{ {
<FluentCard class="card-padding">
<FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
} }

29
Client/Pages/Dashboard/Elements/ProductPriceHistory.razor.cs

@ -16,12 +16,12 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
private bool m_increase { get; set; } = false; private bool m_increase { get; set; } = false;
private double m_currentPrice { get; set; } = 0; private double m_currentPrice { get; set; } = 0;
private ApexChartOptions<ProductPriceChange> options = new ApexChartOptions<ProductPriceChange>(); private ApexChartOptions<ProductPriceChange> options = new ApexChartOptions<ProductPriceChange>();
private string m_productName { get; set; }= string.Empty; private string m_productName { get; set; } = string.Empty;
private string m_subtitle { get;set; } = string.Empty; private string m_subtitle { get; set; } = string.Empty;
private string m_title { get;set; } = string.Empty; private string m_title { get; set; } = string.Empty;
protected override void OnInitialized() protected override void OnInitialized()
{ {
base.OnInitialized(); base.OnInitialized();
} }
protected override void OnParametersSet() protected override void OnParametersSet()
@ -52,11 +52,10 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
} }
} }
}; };
Random random = new Random(); Random random = new Random();
int randomNumber = random.Next(ProductHistory.Count); int randomNumber = random.Next(ProductHistory.Count);
m_currentProduct = ProductHistory[randomNumber].Pcode; m_currentProduct = ProductHistory[randomNumber].Pcode;
m_productHistory = ProductHistory.Where(t => t.Pcode == m_currentProduct).ToList(); m_productHistory = ValidateList(ProductHistory.Where(t => t.Pcode == m_currentProduct).ToList());
if (m_productHistory.Count > 0) if (m_productHistory.Count > 0)
{ {
@ -71,5 +70,23 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
} }
base.OnParametersSet(); base.OnParametersSet();
} }
/// <summary>
/// Validates list to remove duplicate dates
/// </summary>
/// <param name="a_list"></param>
/// <returns></returns>
private List<ProductPriceChange> ValidateList(List<ProductPriceChange> a_list)
{
List<ProductPriceChange> validated = new List<ProductPriceChange>();
foreach (ProductPriceChange change in a_list)
{
if (!validated.Select(d => d.ChangeDate).Contains(change.ChangeDate))
{
validated.Add(change);
}
}
return validated;
}
} }
} }

63
Client/Pages/Dashboard/Elements/TransactionCard.razor

@ -1,31 +1,58 @@
@using Biskilog_Accounting.Shared.CustomModels; @using Biskilog_Accounting.Shared.CustomModels;
@using Biskilog_Accounting.Shared.Interfaces; @using Biskilog_Accounting.Shared.Interfaces;
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator @inject ICalculator m_calculator
<div class="card h-100"> @if (!IsLoading)
<div class="card-header d-flex align-items-center justify-content-between"> {
<h5 class="card-title m-0 me-2">Last 50 Transactions</h5> <div class="card h-100">
</div> <div class="card-header d-flex align-items-center justify-content-between">
<div class="card-body" style="padding:5px !important;"> <h5 class="card-title m-0 me-2">Last 50 Transactions</h5>
<RadzenDataGrid Data="@Sales" TItem="SaleItem" AllowPaging="true" AllowSorting="true"> </div>
<Columns> <div class="card-body" style="padding:5px !important;">
<RadzenDataGridColumn TItem="SaleItem" Property="Transno" Title="Receipt#" /> <RadzenDataGrid Data="@Sales" TItem="SaleItem" AllowPaging="true" AllowSorting="true">
<RadzenDataGridColumn TItem="SaleItem" Property="Date" Title="Timestamp" /> <Columns>
<RadzenDataGridColumn TItem="SaleItem" Property="Total" Title="Total"> <RadzenDataGridColumn TItem="SaleItem" Property="Transno" Title="Receipt#" />
<Template Context="detail"> <RadzenDataGridColumn TItem="SaleItem" Property="Date" Title="Timestamp" />
@(m_calculator.FormatMoneyWithCurrencyKilo((double)detail.Total)) <RadzenDataGridColumn TItem="SaleItem" Property="Total" Title="Total">
</Template> <Template Context="detail">
</RadzenDataGridColumn> @(
m_calculator.FormatMoneyWithCurrencyKilo((double)detail.Total)
)
</Template>
</RadzenDataGridColumn>
</Columns> </Columns>
</RadzenDataGrid> </RadzenDataGrid>
</div>
</div> </div>
</div> }
else
{
<FluentCard class="card-padding">
<FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
}
<style> <style>
.rz-datatable-thead th, .rz-grid-table thead th { .rz-datatable-thead th, .rz-grid-table thead th {
background-color: #a4d5d3; background-color: #a4d5d3;
padding: 0; padding: 0;
color: white; color: white;
} }
.rz-datatable {
border: none !important;
}
</style> </style>

58
Client/Pages/Dashboard/Elements/WelcomeCard.razor

@ -1,25 +1,47 @@
@using Biskilog_Accounting.Shared.Interfaces; @using Biskilog_Accounting.Shared.Interfaces;
@using Microsoft.Fast.Components.FluentUI
@inject ICalculator m_calculator; @inject ICalculator m_calculator;
<div class="card"> @if (!IsLoading)
<div class="d-flex align-items-end row"> {
<div class="col-sm-7"> <div class="card">
<div class="card-body"> <div class="d-flex align-items-end row">
<h5 class="card-title text-primary">@(TradeSummary.CurrentTradeSales > TradeSummary.LastTradeSales ? "Congratulations 🎉" : TradeSummary.LastTradeSales > TradeSummary.CurrentTradeSales ? "Tough shift there" : "Well Done") @Username!</h5> <div class="col-sm-7">
<p class="mb-4"> <div class="card-body">
@m_remarks <h5 class="card-title text-primary">@(TradeSummary.CurrentTradeSales > TradeSummary.LastTradeSales ? "Congratulations 🎉" : TradeSummary.LastTradeSales > TradeSummary.CurrentTradeSales ? "Tough shift there" : "Well Done") @Username!</h5>
</p> <p class="mb-4">
<a href="javascript:;" class="btn btn-sm btn-outline-primary">View Trade Summary</a> @m_remarks
</p>
<a href="javascript:;" class="btn btn-sm btn-outline-primary">View Trade Summary</a>
</div>
</div> </div>
</div> <div class="col-sm-5 text-center text-sm-left">
<div class="col-sm-5 text-center text-sm-left"> <div class="card-body pb-0 px-0 px-md-4">
<div class="card-body pb-0 px-0 px-md-4"> <img src="../assets/img/illustrations/man-with-laptop-light.png"
<img src="../assets/img/illustrations/man-with-laptop-light.png" height="140"
height="140" alt="View Badge User"
alt="View Badge User" data-app-dark-img="illustrations/man-with-laptop-dark.png"
data-app-dark-img="illustrations/man-with-laptop-dark.png" data-app-light-img="illustrations/man-with-laptop-light.png" />
data-app-light-img="illustrations/man-with-laptop-light.png" /> </div>
</div> </div>
</div> </div>
</div> </div>
</div> }
else
{
<FluentCard class="card-padding">
<FluentSkeleton style="border-radius: 4px; width: 50px; height: 50px;" Shape="SkeletonShape.Circle" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="border-radius: 4px; margin-top: 10px; height: 10px;" Shape="SkeletonShape.Rect" Shimmer="true"></FluentSkeleton>
<FluentSkeleton style="
border-radius: 4px;
width: 75px;
height: 30px;
margin-top: 20px;
margin-bottom: 10px;
"
Shape="SkeletonShape.Rect"
Shimmer="true"></FluentSkeleton>
</FluentCard>
}

5
Client/Pages/Dashboard/Elements/WelcomeCard.razor.cs

@ -10,7 +10,8 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
[Parameter] [Parameter]
public TradeSummary TradeSummary { get; set; } = new TradeSummary(); public TradeSummary TradeSummary { get; set; } = new TradeSummary();
[Parameter]
public bool IsLoading { get; set; } = true;
private string m_remarks { get; set; } = ""; private string m_remarks { get; set; } = "";
private string m_currentTrade { get; set; } = string.Empty; private string m_currentTrade { get; set; } = string.Empty;
private string m_previousTrade { get; set; } = string.Empty; private string m_previousTrade { get; set; } = string.Empty;
@ -21,7 +22,7 @@ namespace Biskilog_Accounting.Client.Pages.Dashboard.Elements
} }
private void CalculateStatistic() private void CalculateStatistic()
{ {
if(TradeSummary.CurrentTradeDate != DateTime.Today) if (TradeSummary.CurrentTradeDate != DateTime.Today)
{ {
m_currentTrade = $"most recent trade date ({TradeSummary.CurrentTradeDate.ToString("dd MMM,yyy")})"; m_currentTrade = $"most recent trade date ({TradeSummary.CurrentTradeDate.ToString("dd MMM,yyy")})";
} }

7
Client/Program.cs

@ -6,6 +6,7 @@ using Blazored.LocalStorage;
using Blazored.SessionStorage; using Blazored.SessionStorage;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Fast.Components.FluentUI;
var builder = WebAssemblyHostBuilder.CreateDefault(args); var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<App>("#app");
@ -20,5 +21,11 @@ builder.Services.AddBlazoredSessionStorageAsSingleton();
builder.Services.AddScoped<ICalculator, CalculatorService>(); builder.Services.AddScoped<ICalculator, CalculatorService>();
builder.Services.AddScoped<ITokenService, TokenService>(); builder.Services.AddScoped<ITokenService, TokenService>();
builder.Services.AddFluentUIComponents(options =>
{
options.HostingModel = BlazorHostingModel.WebAssembly;
options.IconConfiguration = ConfigurationGenerator.GetIconConfiguration();
options.EmojiConfiguration = ConfigurationGenerator.GetEmojiConfiguration();
});
await builder.Build().RunAsync(); await builder.Build().RunAsync();

Loading…
Cancel
Save