AVS-Carton-Shipment-Verifier/Views/Home/Index.cshtml

285 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

@model VerificationDashboardViewModel
@{
ViewData["Title"] = "Carton Shipment Verification";
}
<header class="topbar">
<div class="topbar-brand">
<span class="brand-icon">&#x25C8;</span>
<span>SHIPPING MARK</span>
</div>
<div class="topbar-siren" id="siren-indicator">
<span>&#128266;</span>
<span>SIREN: ON</span>
</div>
</header>
<main class="dashboard-main">
<section class="top-grid">
<section class="panel panel-scan">
<h2 class="section-title"><span class="section-icon">&#128438;</span> SCAN QR CODE</h2>
<form id="scan-form" autocomplete="off" novalidate onsubmit="return false;">
@Html.AntiForgeryToken()
<div class="scan-input-wrap">
<span class="scan-icon">&#9881;</span>
<input id="qr-input"
name="qrValue"
class="scan-input"
type="text"
placeholder="Use scanner or paste (typing is not allowed)…"
autofocus
spellcheck="false" />
</div>
<div class="form-hint">Format: modelnumber;uniquenumber — scans submit automatically.</div>
</form>
</section>
<section class="panel panel-scanned-details">
<h2 class="section-title"><span class="section-icon">&#9432;</span> SCANNED DETAILS</h2>
<div class="info-grid">
<span>Model Number</span><strong id="detail-model">-</strong>
<span>Unique Number</span><strong id="detail-unique">-</strong>
</div>
</section>
</section>
<section class="kpi-grid">
<section id="status-card" class="panel panel-status status-neutral" aria-live="polite">
<h2 class="section-title"><span class="section-icon">&#8767;</span> VERIFICATION STATUS</h2>
<div class="status-mini-icon" id="status-mini-icon">-</div>
<div class="status-mini-headline" id="status-mini-headline">AWAITING SCAN</div>
<div id="status-mini-message" class="status-mini-message">Waiting for QR input.</div>
<div class="last-updated">
<span>&#9716; Last Updated:</span>
<strong id="last-updated-time">-</strong>
</div>
</section>
<section class="panel panel-available-cartons" aria-live="polite">
<h2 class="section-title section-title-center"><span class="section-icon">&#128230;</span> AVAILABLE CARTONS</h2>
<div id="available-cartons-count" class="available-cartons-value">@(Model.AvailableCartonsCount.HasValue ? Model.AvailableCartonsCount.Value.ToString("N0") : "—")</div>
<div class="available-cartons-subtitle">Not moved to warehouse</div>
</section>
<section class="panel panel-verification-result">
<h2 class="section-title"><span class="section-icon">&#128737;</span> VERIFICATION RESULT</h2>
<div class="info-grid">
<span>Exists in Carton Logs</span><strong id="detail-exists">-</strong>
<span>Shipment Marked</span><strong id="detail-marked">-</strong>
<span>Marked At</span><strong id="detail-time">-</strong>
<span>Marked By</span><strong id="detail-marked-by">System</strong>
</div>
</section>
</section>
<section class="panel panel-history">
<div class="panel-history-head">
<h2 class="section-title section-title-tight"><span class="section-icon">&#128462;</span> RECENT SCANS</h2>
<button type="button" class="btn-scan-history" id="btn-open-scan-history">History</button>
</div>
<div class="history-split">
<div class="history-column">
<h3 class="history-subtitle">Successful Scans</h3>
<div class="table-responsive history-wrap">
<table class="table table-sm align-middle" id="history-success-table">
<thead>
<tr>
<th>#</th>
<th>MODEL NUMBER</th>
<th>UNIQUE NUMBER</th>
<th>STATUS</th>
<th>MOVED TO WAREHOUSE AT</th>
<th>MARKED AT</th>
<th>MARKED BY</th>
</tr>
</thead>
<tbody id="history-success-body">
@{
var rowNumber = 1;
}
@foreach (var item in Model.RecentSuccessfulScans)
{
<tr>
<td>@rowNumber</td>
<td>@item.ModelNumber</td>
<td>@item.UniqueNumber</td>
<td>
<span class="status-pill status-true">TRUE</span>
</td>
<td>@(item.MovedToWarehouseAtUtc.HasValue ? DateTime.SpecifyKind(item.MovedToWarehouseAtUtc.Value, DateTimeKind.Utc).ToLocalTime().ToString("dd-MM-yyyy HH:mm:ss") : "-")</td>
<td>@DateTime.SpecifyKind(item.ProcessedAtUtc, DateTimeKind.Utc).ToLocalTime().ToString("dd MMM yyyy h:mm tt")</td>
<td>System</td>
</tr>
rowNumber++;
}
</tbody>
</table>
<div class="history-empty @(Model.RecentSuccessfulScans.Count > 0 ? "is-hidden" : string.Empty)" id="history-success-empty">
<div class="empty-icon">&#128230;</div>
<div class="empty-title">No successful scans yet</div>
<div class="empty-text">Verified cartons will appear here.</div>
</div>
</div>
</div>
<div class="history-column">
<h3 class="history-subtitle">Rejected Scans</h3>
<div class="table-responsive history-wrap">
<table class="table table-sm align-middle" id="history-rejected-table">
<thead>
<tr>
<th>TIME</th>
<th>SCANNED / INPUT</th>
<th>MODEL</th>
<th>UNIQUE</th>
<th>REASON</th>
</tr>
</thead>
<tbody id="history-rejected-body">
@foreach (var item in Model.RecentRejectedScans)
{
<tr>
<td>@DateTime.SpecifyKind(item.ProcessedAtUtc, DateTimeKind.Utc).ToLocalTime().ToString("dd MMM yyyy h:mm tt")</td>
<td>@item.RawInputValue</td>
<td>@(string.IsNullOrEmpty(item.ModelNumber) ? "—" : item.ModelNumber)</td>
<td>@(string.IsNullOrEmpty(item.UniqueNumber) ? "—" : item.UniqueNumber)</td>
<td>@item.RejectionReason</td>
</tr>
}
</tbody>
</table>
<div class="history-empty @(Model.RecentRejectedScans.Count > 0 ? "is-hidden" : string.Empty)" id="history-rejected-empty">
<div class="empty-icon">&#9888;</div>
<div class="empty-title">No rejected scans</div>
<div class="empty-text">Rejections will appear here with a reason.</div>
</div>
</div>
</div>
</div>
</section>
<dialog id="scan-history-dialog" class="scan-history-dialog scan-history-dialog--wide" aria-labelledby="scan-history-dialog-title">
<div class="scan-history-dialog-content">
<header class="scan-history-dialog-header">
<h2 id="scan-history-dialog-title" class="scan-history-dialog-title">Scan History &amp; Analytics</h2>
<button type="button" class="scan-history-dialog-close" id="scan-history-dialog-close" aria-label="Close">&times;</button>
</header>
<div class="scan-history-dialog-toolbar scan-history-mode-toolbar">
<label class="scan-history-filter-label" for="scan-history-filter">Show</label>
<select id="scan-history-filter" class="scan-history-filter" aria-label="Record type">
<option value="successful">Successful Records</option>
<option value="rejected">Rejected Records</option>
</select>
<button type="button" class="btn-history-mode" id="btn-movement-analytics">Movement Analytics</button>
</div>
<div id="scan-history-records-view">
<div class="scan-history-dialog-body table-responsive">
<table class="table table-sm align-middle" id="scan-history-modal-table">
<thead id="scan-history-modal-thead"></thead>
<tbody id="scan-history-modal-tbody"></tbody>
</table>
</div>
</div>
<div id="scan-history-analytics-view" class="scan-history-analytics-view is-hidden" hidden>
<div class="scan-history-dialog-toolbar analytics-toolbar">
<div class="analytics-toolbar-filters">
<label class="scan-history-filter-label" for="analytics-date-from">Date Range</label>
<input type="date" id="analytics-date-from" class="analytics-date-input" aria-label="From date" />
<span class="analytics-date-sep"></span>
<input type="date" id="analytics-date-to" class="analytics-date-input" aria-label="To date" />
<label class="scan-history-filter-label" for="analytics-group-by">Show</label>
<select id="analytics-group-by" class="scan-history-filter" aria-label="Grouping">
<option value="day" selected>Day-wise</option>
</select>
</div>
<button type="button" class="btn-analytics-export" id="btn-analytics-export">Export</button>
</div>
<div class="analytics-summary-grid">
<article class="analytics-summary-card">
<span class="analytics-summary-icon analytics-icon-box" aria-hidden="true">&#128230;</span>
<div>
<div class="analytics-summary-value" id="summary-moved-today">0</div>
<div class="analytics-summary-label">Moved Today</div>
</div>
</article>
<article class="analytics-summary-card">
<span class="analytics-summary-icon analytics-icon-week" aria-hidden="true">&#128197;</span>
<div>
<div class="analytics-summary-value" id="summary-moved-week">0</div>
<div class="analytics-summary-label">Moved This Week</div>
</div>
</article>
<article class="analytics-summary-card">
<span class="analytics-summary-icon analytics-icon-month" aria-hidden="true">&#128197;</span>
<div>
<div class="analytics-summary-value" id="summary-moved-month">0</div>
<div class="analytics-summary-label">Moved This Month</div>
</div>
</article>
<article class="analytics-summary-card">
<span class="analytics-summary-icon analytics-icon-total" aria-hidden="true">&#128230;</span>
<div>
<div class="analytics-summary-value" id="summary-total-moved">0</div>
<div class="analytics-summary-label">Total Moved</div>
</div>
</article>
</div>
<div class="analytics-charts-row">
<section class="analytics-chart-panel">
<h3 class="analytics-panel-title">Cartons Moved to Warehouse by Day</h3>
<div class="analytics-bar-chart-wrap">
<canvas id="analytics-bar-chart" aria-label="Cartons moved by day"></canvas>
</div>
</section>
<section class="analytics-chart-panel analytics-donut-panel">
<h3 class="analytics-panel-title">Status Share</h3>
<div class="analytics-donut-wrap">
<canvas id="analytics-donut-chart" aria-label="Moved versus pending share"></canvas>
</div>
<ul class="analytics-legend" id="analytics-status-legend"></ul>
</section>
</div>
<section class="analytics-table-section">
<h3 class="analytics-panel-title">Day-wise Movement Details</h3>
<div class="table-responsive analytics-table-wrap">
<table class="table table-sm align-middle" id="analytics-day-table">
<thead>
<tr>
<th>DATE</th>
<th>MOVED CARTONS</th>
<th>SUCCESSFUL SCANS</th>
<th>DUPLICATE REJECTIONS</th>
<th>MANUAL ENTRY REJECTIONS</th>
<th>LAST MOVED AT</th>
</tr>
</thead>
<tbody id="analytics-day-tbody"></tbody>
</table>
</div>
</section>
<div class="scan-history-dialog-footer">
<button type="button" class="btn-scan-history-dialog-close" id="btn-scan-history-dialog-close">Close</button>
</div>
</div>
</div>
</dialog>
</main>
<footer class="page-footer">
<span>SHIPPING MARK BY TECHNOLOGY</span>
<span>|</span>
<span>SHIPPING MARK</span>
</footer>
@section Scripts {
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js" crossorigin="anonymous"></script>
<script src="~/js/movement-analytics.js" asp-append-version="true"></script>
<script src="~/js/verification-dashboard.js" asp-append-version="true"></script>
}