293 lines
11 KiB
HTML
293 lines
11 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1.0, user-scalable=no"
|
||
/>
|
||
<title>Health Routine – Package Scanner</title>
|
||
<link rel="stylesheet" href="styles.css" />
|
||
</head>
|
||
<body class="tab-scan">
|
||
<!-- Brand bar -->
|
||
<div class="brand-bar">
|
||
<div class="brand-logo-wrap">
|
||
<img src="./logo.png" alt="Health Routine Logo" />
|
||
</div>
|
||
<span class="brand-name">Health Routine</span>
|
||
<div class="brand-divider"></div>
|
||
<span class="brand-subtitle">Package Scanner</span>
|
||
</div>
|
||
|
||
<!-- Controls bar -->
|
||
<div class="controls-bar">
|
||
<div class="controls-inner">
|
||
<div class="scan-wrap">
|
||
<span class="scan-icon">
|
||
<!-- Barcode icon -->
|
||
<svg
|
||
viewBox="0 0 24 24"
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
>
|
||
<rect x="2" y="4" width="2" height="16" />
|
||
<rect x="6" y="4" width="1" height="16" />
|
||
<rect x="9" y="4" width="2" height="16" />
|
||
<rect x="13" y="4" width="1" height="16" />
|
||
<rect x="16" y="4" width="3" height="16" />
|
||
<rect x="21" y="4" width="1" height="16" />
|
||
</svg>
|
||
</span>
|
||
<input
|
||
type="text"
|
||
id="scanInput"
|
||
name="NAME"
|
||
placeholder="SCAN HERE"
|
||
autocomplete="off"
|
||
autocorrect="off"
|
||
autocapitalize="off"
|
||
spellcheck="false"
|
||
inputmode="text"
|
||
/>
|
||
</div>
|
||
|
||
<select id="userSelect">
|
||
<option value="">Loading…</option>
|
||
</select>
|
||
|
||
<button class="btn-clear" onclick="clearTable()">
|
||
<svg
|
||
width="12"
|
||
height="12"
|
||
viewBox="0 0 12 12"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
>
|
||
<line x1="1" y1="1" x2="11" y2="11" />
|
||
<line x1="11" y1="1" x2="1" y2="11" />
|
||
</svg>
|
||
Clear
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab bar -->
|
||
<div class="tab-bar">
|
||
<button
|
||
class="tab-btn active"
|
||
data-tab="scan"
|
||
onclick="switchTab('scan')"
|
||
>
|
||
Scan Log
|
||
</button>
|
||
<button
|
||
class="tab-btn"
|
||
data-tab="batches"
|
||
onclick="switchTab('batches')"
|
||
>
|
||
Batches
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Status banner -->
|
||
<div id="statusBanner"></div>
|
||
|
||
<!-- Scan Log panel -->
|
||
<main id="scanPanel">
|
||
<div class="scan-search-wrap">
|
||
<svg
|
||
class="scan-search-icon"
|
||
viewBox="0 0 24 24"
|
||
width="16"
|
||
height="16"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
>
|
||
<circle cx="11" cy="11" r="8" />
|
||
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
||
</svg>
|
||
<input
|
||
type="text"
|
||
id="scanSearch"
|
||
placeholder="Filter scans…"
|
||
autocomplete="off"
|
||
/>
|
||
<span class="count-pill zero" id="countPill">0 scans</span>
|
||
<span class="queue-pill hidden" id="queuePill">
|
||
<span
|
||
class="pending-spinner"
|
||
style="width: 10px; height: 10px; border-width: 1.5px"
|
||
></span>
|
||
<span id="queuePillText">0 pending</span>
|
||
</span>
|
||
</div>
|
||
<div class="table-wrapper" id="tableWrapper">
|
||
<table id="scanTable">
|
||
<thead>
|
||
<tr>
|
||
<th>Land</th>
|
||
<th>Name</th>
|
||
<th>Tag</th>
|
||
<th class="col-code">Code</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="tableBody"></tbody>
|
||
</table>
|
||
|
||
<!-- Empty state (shown when no rows) -->
|
||
<div class="empty-state" id="emptyState">
|
||
<div class="empty-icon">
|
||
<svg viewBox="0 0 24 24">
|
||
<path
|
||
d="M3 7V5a2 2 0 012-2h2M17 3h2a2 2 0 012 2v2M21 17v2a2 2 0 01-2 2h-2M7 21H5a2 2 0 01-2-2v-2"
|
||
/>
|
||
<rect x="7" y="7" width="10" height="10" rx="1" />
|
||
</svg>
|
||
</div>
|
||
<div class="empty-title">No scans yet</div>
|
||
<div class="empty-hint">
|
||
Select a user, then scan or type a package code and
|
||
press Enter
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<!-- Auth Modal -->
|
||
<div class="modal-overlay hidden" id="authModal">
|
||
<div class="modal-card">
|
||
<div class="modal-icon">
|
||
<svg viewBox="0 0 24 24">
|
||
<rect
|
||
x="3"
|
||
y="11"
|
||
width="18"
|
||
height="11"
|
||
rx="2"
|
||
ry="2"
|
||
/>
|
||
<path d="M7 11V7a5 5 0 0110 0v4" />
|
||
</svg>
|
||
</div>
|
||
<div class="modal-title">Authentication Required</div>
|
||
<div class="modal-sub">
|
||
The webhook requires basic authentication. Enter your
|
||
credentials to continue.
|
||
</div>
|
||
|
||
<label class="field-label" for="authUser">Username</label>
|
||
<input
|
||
type="text"
|
||
class="field-input"
|
||
id="authUser"
|
||
autocomplete="username"
|
||
placeholder="your username"
|
||
/>
|
||
|
||
<label class="field-label" for="authPass">Password</label>
|
||
<input
|
||
type="password"
|
||
class="field-input"
|
||
id="authPass"
|
||
autocomplete="current-password"
|
||
placeholder="••••••••"
|
||
/>
|
||
|
||
<div class="modal-error" id="modalError">
|
||
Incorrect credentials. Please try again.
|
||
</div>
|
||
|
||
<div class="modal-actions">
|
||
<button class="btn-ghost" onclick="cancelAuth()">
|
||
Cancel
|
||
</button>
|
||
<button
|
||
class="btn-primary"
|
||
id="authBtn"
|
||
onclick="submitAuth()"
|
||
>
|
||
<span class="btn-spinner"></span>
|
||
<span class="btn-text">Connect</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Batches panel -->
|
||
<div class="tab-panel" id="batchesPanel" style="display: none">
|
||
<div class="batch-search-wrap">
|
||
<svg
|
||
class="batch-search-icon"
|
||
viewBox="0 0 24 24"
|
||
width="16"
|
||
height="16"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
>
|
||
<circle cx="11" cy="11" r="8" />
|
||
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
||
</svg>
|
||
<input
|
||
type="text"
|
||
id="batchSearch"
|
||
placeholder="Search batches…"
|
||
autocomplete="off"
|
||
/>
|
||
<select id="batchStateFilter">
|
||
<option value="!done">Active</option>
|
||
<option value="">All</option>
|
||
<option value="done">Done</option>
|
||
<option value="open">Open</option>
|
||
</select>
|
||
</div>
|
||
<div class="batch-table-wrap">
|
||
<table class="batch-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Charge</th>
|
||
<th
|
||
class="batch-th-sort"
|
||
onclick="sortBatches('name')"
|
||
>
|
||
Name
|
||
<span class="sort-arrow" id="sortArrowName"
|
||
>▲</span
|
||
>
|
||
</th>
|
||
<th>Transport</th>
|
||
<th
|
||
class="batch-th-sort"
|
||
onclick="sortBatches('state')"
|
||
>
|
||
Status
|
||
<span
|
||
class="sort-arrow"
|
||
id="sortArrowState"
|
||
></span>
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="batchList">
|
||
<tr>
|
||
<td colspan="4" class="batch-empty">
|
||
Loading batches…
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Toast notification -->
|
||
<div id="toast"></div>
|
||
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|