@page "/home" @using Microsoft.AspNetCore.Authorization @using Indotalent.Infrastructure.Authorization.Identity @using Indotalent.Features.Root.Home.Cqrs @using Indotalent.Features.Root.Home @attribute [Authorize(Roles = $"{ApplicationRoles.Admin},{ApplicationRoles.Member}")] @inject HomeService HomeService @inject IJSRuntime JS OMS Dashboard @if (!_dataReady) {

Loading OMS Dashboard...

} else {
@* HEADER *@

OMS Dashboard

@* ROW 1: 12-col KPI layout *@
@* Key Metrics Card *@

OMS Overview

Key Metrics

MTD Sales

@_data.FormattedMonthlySales

MTD Purchase

@_data.FormattedMonthlyPurchase

Growth Rate

@_data.OrderGrowthRate%

Total SO

@_data.FormattedTotalSalesOrders

AR: @_data.FormattedPendingPayments FY @DateTime.Now.Year
@* 8 Small KPI Cards (row 1, cols 6-12) *@

MTD Sales

@_data.FormattedMonthlySales

MTD Purchase

@_data.FormattedMonthlyPurchase

Growth Rate

@_data.OrderGrowthRate%

Total SO

@_data.FormattedTotalSalesOrders

Avg Order Value

@_data.FormattedAvgOrderValue

Fulfillment Rate

@_data.SlaPercentage%

Pending Docs

@_data.ActiveDealsCount

Total Payable

@_data.FormattedTotalPayable

@* Metrics Matrix *@

OMS Metrics Matrix

Key indicators across all categories

@foreach (var item in _data.DocGrid.Take(20)) { var mmColors = new[] { "mm-c1","mm-c2","mm-c3","mm-c4","mm-c5","mm-c6","mm-c7","mm-c8","mm-c9","mm-c10","mm-c11","mm-c12","mm-c13","mm-c14","mm-c15","mm-c16","mm-c17","mm-c18","mm-c19","mm-c20" }; var idx = _data.DocGrid.IndexOf(item); var colorClass = idx < mmColors.Length ? mmColors[idx] : "mm-c1";

@item.Label

@item.Value

}
@* ROW 2: Revenue Trend + Document Sources *@

Sales vs Purchase Trend

Monthly comparison

Sales Purchase

Document Sources

By category this period

@if (_data.OrderSources.Any()) { @foreach (var src in _data.OrderSources) {
@src.Source @src.Percentage%
} } else {
SO 0%
PO 0%
INV 0%
BILL 0%
}
@* ROW 3: Pipeline Summary + Doc Stages + Order Activity *@

Pipeline Summary

As of @DateTime.Now.ToString("MMMM dd, yyyy")

@if (_data.PipelineSummary.Any()) { @foreach (var ps in _data.PipelineSummary) {

@ps.Label

@(ps.FormattedValue ?? ps.Value.ToString("N0"))

} }
Growth Rate@_data.OrderGrowthRate% Orders@_data.FormattedTotalSalesOrders

Doc Stages

Orders by status

@foreach (var ds in _data.DealStages) {

@ds.Stage

@ds.Count

}
SLA: @_data.SlaPercentage%Active: @_data.ActiveDealsCount

Order Activity

Document volume

@foreach (var sa in _data.OrderActivities.Take(3)) {
+@sa.Count

@sa.Category

}
@* ROW 4: Recent Orders + OMS Activity *@

Recent Orders

Latest transactions

@if (_data.RecentOrders.Any()) { @foreach (var order in _data.RecentOrders) { } } else { }
DateOrder#DescriptionValueStatus
@(order.Date?.ToString("MMM dd") ?? "-") @order.OrderNumber @order.Description @order.Value.ToString("N0") @order.Status
No recent orders available
Pending Docs: @_data.ActiveDealsCount Total AR: @_data.FormattedPipeline

OMS Activity

Real-time updates

Live
@if (_data.ActivityFeeds.Any()) { @foreach (var af in _data.ActivityFeeds) {
@af.AvatarText

@af.Title

@af.Detail

@af.TimeAgo

@af.ChipLabel
} } else {

No recent activity

}
@* ROW 5: Order Metrics + Top Customers + Quick Stats *@

Order Metrics

@DateTime.Now.Year Performance

@foreach (var cm in _data.OrderMetrics) {

@cm.Label

@cm.Current / @cm.Target
}
Target SLA: @_data.TargetGrowth% @(_data.SlaPercentage >= 90 ? "On Track" : "Improving")

Top Customers

By order volume

@if (_data.SalesLeaderboard.Any()) { var perfColors = new[] { "#f97316", "#f59e0b", "#6366f1", "#8b5cf6" }; @for (int i = 0; i < Math.Min(_data.SalesLeaderboard.Count, 4); i++) { var p = _data.SalesLeaderboard[i];

@p.Name

@p.Achievement.ToString("N0")

@p.WinRate.ToString("F0")%
} } else {

No performance data available

}
Top Orders: @_data.FormattedTotalSalesOrdersAvg Growth: @_data.OrderGrowthRate%

Quick Stats

System overview

Pending Docs

Drafts SO+PO

@_data.ActiveDealsCount

Total Customers

Active

@_data.FormattedTotalCustomers

Retention Rate

Customer loyalty

@_data.CustomerRetention%

Receivable

Total AR

@_data.FormattedTotalReceivable
@* ROW 6: Vendor Overview + Pending Invoices *@

Vendor Overview

As of @DateTime.Now.ToString("MMM dd, yyyy") · Active vendors

@if (_data.RecentVendors.Any()) { @foreach (var vend in _data.RecentVendors) { } } else { }
VendorGroupAmountStage
@vend.LeadTitle @vend.Company @vend.Amount.ToString("N0") @vend.Stage
No vendors available
Total Vendors: @_data.TotalVendors.ToString("N0") Products: @_data.TotalProducts.ToString("N0")

Pending Invoices

Awaiting confirmation

@if (_data.OverdueInvoices.Any()) { @foreach (var inv in _data.OverdueInvoices) { } } else { }
InvoiceCustomerAmountStatus
@inv.Number @inv.Customer @inv.Amount.ToString("N0") @inv.Status
No pending invoices
Total AR: @_data.FormattedPendingPayments Count: @_data.OverdueInvoices.Count
} @code { private DashboardOmsResponse _data = new(); private bool _isLoading = true; private bool _chartsInitialized = false; private bool _dataReady = false; protected override async Task OnInitializedAsync() { _isLoading = true; try { var res = await HomeService.GetOmsDashboardStatsAsync(); if (res?.IsSuccess == true && res.Value != null) { _data = res.Value; _dataReady = true; StateHasChanged(); } } finally { _isLoading = false; } } protected override async Task OnAfterRenderAsync(bool firstRender) { if (_dataReady && !_chartsInitialized) { _chartsInitialized = true; await InitCharts(); } } private async Task InitCharts() { var ml = _data.RevenueTrend.Any() ? _data.RevenueTrend.Select(x => x.Label ?? "").ToArray() : new[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun" }; var ms = _data.RevenueTrend.Any() ? _data.RevenueTrend.Select(x => x.SalesAmount).ToArray() : new double[ml.Length]; var mp = _data.RevenueTrend.Any() ? _data.RevenueTrend.Select(x => x.PurchaseAmount).ToArray() : new double[ml.Length]; var sl = _data.OrderSources.Any() ? _data.OrderSources.Select(x => x.Source ?? "").ToArray() : new[] { "SO", "PO", "INV", "BILL" }; var sd = _data.OrderSources.Any() ? _data.OrderSources.Select(x => x.Percentage).Cast().ToArray() : new object[] { 10, 10, 10, 10 }; var sc = _data.OrderSources.Any() ? _data.OrderSources.Select(x => x.Color ?? "#06b6d4").ToArray() : new[] { "#06b6d4", "#10b981", "#6366f1", "#dc2626" }; var al = _data.OrderActivities.Any() ? _data.OrderActivities.Take(4).Select(x => x.Category ?? "").ToArray() : new[] { "SO", "PO", "INV" }; var ad = _data.OrderActivities.Any() ? _data.OrderActivities.Take(4).Select(x => (double)x.Count).ToArray() : new double[] { 0, 0, 0 }; var ac = _data.OrderActivities.Any() ? _data.OrderActivities.Take(4).Select(x => x.Color ?? "#6366f1").ToArray() : new[] { "#10b981", "#e11d48", "#6366f1" }; await JS.InvokeVoidAsync("initOmsDashboardCharts", ml, ms, mp, sl, sd, sc, al, ad, ac); } } @* Chart initialization script *@