id-ocr-engine / static /index.html
Kevin-KES
Deploy current main to HF Space
50c6ee2
Raw
History Blame Contribute Delete
12.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ID OCR Engine</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<header id="app-header">
<div class="header-left">
<h1>ID OCR Engine</h1>
</div>
<div class="header-right">
<div class="health-status">
<span id="health-indicator" class="health-dot offline" title="Checking..."></span>
<span class="health-label">API</span>
</div>
<div class="api-key-group">
<label for="api-key-input">API Key</label>
<div class="input-wrapper">
<input type="password" id="api-key-input" placeholder="Optional" autocomplete="off">
<button id="toggle-key-vis" type="button" title="Show/hide key">
<span class="eye-icon">&#9678;</span>
</button>
</div>
</div>
</div>
</header>
<main id="app-main">
<!-- Upload Panel -->
<section id="upload-panel" class="card">
<h2>Upload</h2>
<!-- Document Type Selector -->
<div class="doc-type-selector">
<label for="doc-type-select">Document Type</label>
<select id="doc-type-select">
<option value="sa_id_card">SA Smart Card</option>
<option value="sa_id_book">SA Green Book</option>
<option value="passport">Passport</option>
<option value="product_serial">Product Serial Number</option>
</select>
</div>
<!-- Front Image -->
<div class="upload-group">
<label class="upload-label">Front Image <span class="required">*</span></label>
<div id="drop-zone-front" class="drop-zone" tabindex="0" role="button" aria-label="Drop front image here or click to browse">
<div class="drop-zone-content">
<div class="drop-icon">&#128196;</div>
<p>Drag & drop front image here</p>
<p class="text-muted text-small">PNG, JPG, BMP, WEBP &bull; Max 10MB</p>
<button class="btn btn-ghost btn-small btn-camera" data-side="front" type="button">&#127909; Use Camera</button>
</div>
<div class="drop-zone-camera-only hidden">
<div class="drop-icon">&#127909;</div>
<p>Scan serial number with camera</p>
<button class="btn btn-primary btn-camera" data-side="front" type="button">Open Camera</button>
</div>
<div class="drop-zone-preview hidden">
<img class="preview-thumb" alt="Front preview">
<span class="preview-name"></span>
<button class="btn-remove" title="Remove">&times;</button>
</div>
</div>
<input type="file" id="file-input-front" accept=".png,.jpg,.jpeg,.bmp,.webp" hidden>
</div>
<!-- Back Image (only for sa_id_card) -->
<div id="back-upload-group" class="upload-group">
<label class="upload-label">Back Image <span class="text-muted">(optional, barcode)</span></label>
<div id="drop-zone-back" class="drop-zone drop-zone-small" tabindex="0" role="button" aria-label="Drop back image here or click to browse">
<div class="drop-zone-content">
<div class="drop-icon">&#128196;</div>
<p>Back of ID card (has barcode)</p>
<p class="text-muted text-small">Optional &mdash; improves accuracy</p>
</div>
<div class="drop-zone-preview hidden">
<img class="preview-thumb" alt="Back preview">
<span class="preview-name"></span>
<button class="btn-remove" title="Remove">&times;</button>
</div>
</div>
<input type="file" id="file-input-back" accept=".png,.jpg,.jpeg,.bmp,.webp" hidden>
</div>
<button id="btn-process" class="btn btn-primary btn-full" disabled>Process Document</button>
</section>
<!-- Results Panel -->
<section id="results-panel" class="card">
<h2>Results</h2>
<div id="results-content">
<div id="results-empty" class="empty-state">
<div class="empty-icon">&#128247;</div>
<p>Upload a document image to see results</p>
</div>
<div id="image-preview-container" class="hidden">
<img id="image-preview" alt="Uploaded document">
</div>
<div id="results-loading" class="loading-overlay hidden">
<div class="spinner"></div>
<p>Processing image...</p>
<p id="elapsed-timer" class="text-muted text-small"></p>
</div>
<div id="results-data" class="hidden">
<!-- Overall Result Banner -->
<div id="overall-result-banner"></div>
<!-- Extraction Method -->
<div id="extraction-info" class="extraction-info"></div>
<h3>Extracted Fields</h3>
<table id="fields-table">
<tbody></tbody>
</table>
<h3>Checks</h3>
<div id="checks-section"></div>
<h3>Confidence</h3>
<div id="confidence-section"></div>
<details id="raw-text-section">
<summary>Raw OCR Text</summary>
<div id="raw-text-content"></div>
</details>
<details id="machine-data-section" class="hidden">
<summary>Machine-Readable Data</summary>
<div id="machine-data-content"></div>
</details>
</div>
<div id="serial-results" class="hidden">
<div id="serial-result-banner"></div>
<div id="serial-fail-guidance" class="serial-fail-guidance hidden"></div>
<div id="serial-crop-container" class="hidden">
<h3>Detected Region</h3>
<img id="serial-crop-preview" alt="Detected serial number region">
</div>
<h3>Extracted Fields</h3>
<table id="serial-fields-table">
<tbody></tbody>
</table>
<details id="serial-validation-section">
<summary>Validation Details</summary>
<div id="serial-validation-content"></div>
</details>
</div>
<div id="results-error" class="hidden">
<div class="error-icon">&#9888;</div>
<p id="error-message"></p>
</div>
</div>
</section>
<!-- Statistics Panel -->
<section id="stats-panel" class="card">
<h2>Statistics</h2>
<div id="stats-content">
<div id="stats-empty" class="empty-state">
<p class="text-muted">Process some images to see statistics</p>
</div>
<div id="stats-data" class="hidden">
<div id="stat-cards"></div>
<h3>Field Extraction Rates</h3>
<div id="field-rates"></div>
</div>
</div>
</section>
<!-- History Panel -->
<section id="history-panel" class="card">
<div class="history-header">
<h2>History</h2>
<div class="history-actions">
<button id="btn-export-csv" class="btn btn-ghost btn-small" disabled>Export CSV</button>
<button id="btn-clear-history" class="btn btn-ghost btn-small btn-danger" disabled>Clear</button>
</div>
</div>
<div id="history-content">
<div id="history-empty" class="empty-state">
<p class="text-muted">No processing history yet</p>
</div>
<div id="history-table-wrapper" class="hidden">
<table id="history-table">
<thead>
<tr>
<th>#</th>
<th>Time</th>
<th>Type</th>
<th>File</th>
<th>ID/Passport #</th>
<th>Name</th>
<th>Method</th>
<th>Result</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</section>
</main>
<!-- Camera Capture Modal -->
<div id="camera-modal" class="camera-modal hidden" role="dialog" aria-label="Camera capture" aria-modal="true">
<div class="camera-modal-backdrop"></div>
<div class="camera-modal-container">
<div class="camera-modal-header">
<h3 class="camera-modal-title">Scan Document</h3>
<button id="camera-close-btn" class="btn-remove" type="button" title="Close camera">&times;</button>
</div>
<div class="camera-modal-body">
<div class="camera-video-wrapper">
<video id="camera-video" autoplay playsinline muted></video>
<div id="camera-scan-guide" class="camera-scan-guide hidden">
<div class="scan-guide-rect">
<div class="scan-guide-corner tl"></div>
<div class="scan-guide-corner tr"></div>
<div class="scan-guide-corner bl"></div>
<div class="scan-guide-corner br"></div>
</div>
<p class="scan-guide-label">Position serial number here</p>
</div>
<div id="camera-loading" class="camera-loading">
<div class="spinner"></div>
<p>Starting camera...</p>
</div>
</div>
</div>
<div id="camera-scan-status" class="camera-scan-status hidden">
<div class="scan-pulse"></div>
<span id="camera-scan-text">Scanning...</span>
</div>
<div class="camera-modal-footer">
<button id="camera-switch-btn" class="btn btn-ghost hidden" type="button" title="Switch camera">&#128260; Switch</button>
<button id="camera-scan-btn" class="btn btn-primary" type="button" disabled>&#128269; Scan ID</button>
<button id="camera-capture-btn" class="btn btn-ghost" type="button">&#128247; Capture</button>
<button id="camera-cancel-btn" class="btn btn-ghost" type="button">Cancel</button>
</div>
</div>
</div>
<div id="toast-container"></div>
<script src="/static/js/utils.js"></script>
<script src="/static/js/api.js"></script>
<script src="/static/js/results.js"></script>
<script src="/static/js/history.js"></script>
<script src="/static/js/stats.js"></script>
<script src="/static/js/camera.js"></script>
<script src="/static/js/upload.js"></script>
<script src="/static/js/app.js"></script>
</body>
</html>