id-ocr-engine / static /js /results.js
Kevin-KES
Deploy current main to HF Space
50c6ee2
Raw
History Blame Contribute Delete
12.7 kB
window.Results = {
currentImageUrl: null,
render: function (result, file) {
this._hideAll();
Utils.$('#results-data').classList.remove('hidden');
if (file) {
this.showImagePreview(file);
}
this.renderOverallResult(result);
this.renderExtractionInfo(result);
this.renderFields(result);
this.renderChecks(result.checks || {});
this.renderConfidence(result.confidence || {}, result.doc_type);
this.renderRawText(result.raw_text || []);
this.renderMachineData(result);
},
showImagePreview: function (file) {
if (this.currentImageUrl) {
URL.revokeObjectURL(this.currentImageUrl);
}
var container = Utils.$('#image-preview-container');
container.classList.remove('hidden');
this.currentImageUrl = URL.createObjectURL(file);
Utils.$('#image-preview').src = this.currentImageUrl;
},
hideImagePreview: function () {
Utils.$('#image-preview-container').classList.add('hidden');
},
renderOverallResult: function (result) {
var banner = Utils.$('#overall-result-banner');
var overall = result.overall_result || 'unknown';
banner.className = 'overall-result-banner result-' + overall;
var icon = overall === 'pass' ? '✓' : overall === 'fail' ? '✗' : '⚠';
var label = overall === 'pass' ? 'PASS' : overall === 'fail' ? 'FAIL' : 'INCONCLUSIVE';
banner.innerHTML = '<span class="result-icon">' + icon + '</span> ' + label;
},
renderExtractionInfo: function (result) {
var el = Utils.$('#extraction-info');
var parts = [];
if (result.doc_type) {
parts.push('<span class="info-tag">' + Utils.docTypeLabel(result.doc_type) + '</span>');
}
if (result.extraction_method) {
parts.push('<span class="info-tag method">' + result.extraction_method + '</span>');
}
el.innerHTML = parts.join(' ');
},
renderFields: function (result) {
var tbody = Utils.$('#fields-table tbody');
tbody.innerHTML = '';
var fields = result.fields || {};
var fieldOrder = Utils.fieldsForDocType(result.doc_type);
for (var i = 0; i < fieldOrder.length; i++) {
var key = fieldOrder[i];
var value = fields[key];
var tr = document.createElement('tr');
var tdLabel = document.createElement('td');
tdLabel.textContent = Utils.fieldLabel(key);
var tdValue = document.createElement('td');
if (value) {
tdValue.textContent = value;
} else {
tdValue.textContent = 'Not detected';
tdValue.className = 'field-missing';
}
tr.appendChild(tdLabel);
tr.appendChild(tdValue);
tbody.appendChild(tr);
}
},
renderChecks: function (checks) {
var section = Utils.$('#checks-section');
section.innerHTML = '';
var checkOrder = ['image_quality', 'id_number_valid', 'barcode_valid', 'mrz_valid', 'data_crosscheck', 'dob_crosscheck', 'gender_crosscheck'];
for (var i = 0; i < checkOrder.length; i++) {
var key = checkOrder[i];
var val = checks[key];
if (val === undefined) continue;
var span = document.createElement('span');
if (val === 'passed') {
span.className = 'validation-check pass';
span.innerHTML = '&#10003; ' + Utils.checkLabel(key);
} else if (val === 'failed') {
span.className = 'validation-check fail';
span.innerHTML = '&#10007; ' + Utils.checkLabel(key);
} else {
span.className = 'validation-check na';
span.innerHTML = '&mdash; ' + Utils.checkLabel(key);
}
section.appendChild(span);
}
},
renderConfidence: function (confidence, docType) {
var section = Utils.$('#confidence-section');
section.innerHTML = '';
var fieldOrder = Utils.fieldsForDocType(docType);
for (var i = 0; i < fieldOrder.length; i++) {
var key = fieldOrder[i];
var val = confidence[key];
if (val === undefined || val === null) continue;
var row = document.createElement('div');
row.className = 'confidence-row';
var label = document.createElement('span');
label.className = 'confidence-label';
label.textContent = Utils.fieldLabel(key);
var bar = document.createElement('div');
bar.className = 'confidence-bar';
var fill = document.createElement('div');
fill.className = 'confidence-fill ' + Utils.confidenceLevel(val);
fill.style.width = Utils.formatConfidence(val);
fill.textContent = Utils.formatConfidence(val);
bar.appendChild(fill);
row.appendChild(label);
row.appendChild(bar);
section.appendChild(row);
}
},
renderRawText: function (rawText) {
var content = Utils.$('#raw-text-content');
content.innerHTML = '';
for (var i = 0; i < rawText.length; i++) {
var line = document.createElement('div');
line.textContent = rawText[i];
content.appendChild(line);
}
},
renderMachineData: function (result) {
var section = Utils.$('#machine-data-section');
var content = Utils.$('#machine-data-content');
content.innerHTML = '';
var data = result.barcode_data || result.mrz_data;
if (!data) {
section.classList.add('hidden');
return;
}
section.classList.remove('hidden');
var label = result.barcode_data ? 'Barcode Data' : 'MRZ Data';
Utils.$('#machine-data-section summary').textContent = label;
var pre = document.createElement('pre');
pre.textContent = JSON.stringify(data, null, 2);
content.appendChild(pre);
},
showLoading: function (file) {
this._hideAll();
if (file) {
this.showImagePreview(file);
}
Utils.$('#results-loading').classList.remove('hidden');
this._startTimer();
},
hideLoading: function () {
Utils.$('#results-loading').classList.add('hidden');
this._stopTimer();
},
showEmpty: function () {
this._hideAll();
Utils.$('#results-empty').classList.remove('hidden');
},
showError: function (message) {
this._hideAll();
Utils.$('#results-error').classList.remove('hidden');
Utils.$('#error-message').textContent = message;
},
renderSerial: function (result, file) {
this._hideAll();
Utils.$('#serial-results').classList.remove('hidden');
if (file) this.showImagePreview(file);
// Banner
var banner = Utils.$('#serial-result-banner');
var hasSerial = !!result.serial_number;
banner.className = 'overall-result-banner ' + (hasSerial ? 'result-pass' : 'result-fail');
banner.innerHTML = hasSerial
? '<span class="result-icon">&#10003;</span> SERIAL NUMBER FOUND'
: '<span class="result-icon">&#10007;</span> ' + (result.failure_reason || 'NO SERIAL NUMBER DETECTED');
// Failure guidance
var failGuidance = Utils.$('#serial-fail-guidance');
if (!hasSerial) {
failGuidance.classList.remove('hidden');
failGuidance.innerHTML = '';
var tips = [];
if (result.quality && result.quality.issues && result.quality.issues.length > 0) {
for (var q = 0; q < result.quality.issues.length; q++) {
tips.push(result.quality.issues[q]);
}
}
if (result.quality && !result.quality.usable) {
tips.push('Image quality is too low for reliable extraction');
}
if (tips.length === 0) {
tips.push('Try better lighting, hold the label steady, or move closer');
}
var ul = document.createElement('ul');
for (var t = 0; t < tips.length; t++) {
var li = document.createElement('li');
li.textContent = tips[t];
ul.appendChild(li);
}
failGuidance.appendChild(ul);
} else {
failGuidance.classList.add('hidden');
failGuidance.innerHTML = '';
}
// Cropped image preview
var cropContainer = Utils.$('#serial-crop-container');
if (result.cropped_image) {
cropContainer.classList.remove('hidden');
Utils.$('#serial-crop-preview').src = 'data:image/jpeg;base64,' + result.cropped_image;
} else {
cropContainer.classList.add('hidden');
}
// Fields table
var tbody = Utils.$('#serial-fields-table tbody');
tbody.innerHTML = '';
var confidenceClass = '';
if (result.confidence === 'high') confidenceClass = 'confidence-high';
else if (result.confidence === 'medium') confidenceClass = 'confidence-medium';
else if (result.confidence === 'low') confidenceClass = 'confidence-low';
var rows = [
['Serial Number', result.serial_number || 'Not detected', !result.serial_number ? 'field-missing' : ''],
['Extraction Source', result.extraction_source || '-', ''],
['Confidence', result.confidence || '-', confidenceClass],
];
for (var i = 0; i < rows.length; i++) {
var tr = document.createElement('tr');
var tdLabel = document.createElement('td');
tdLabel.textContent = rows[i][0];
var tdValue = document.createElement('td');
tdValue.textContent = rows[i][1];
if (rows[i][2]) tdValue.className = rows[i][2];
tr.appendChild(tdLabel);
tr.appendChild(tdValue);
tbody.appendChild(tr);
}
// Validation details (styled pills instead of raw JSON)
var valContent = Utils.$('#serial-validation-content');
valContent.innerHTML = '';
if (result.validation) {
var validPill = document.createElement('span');
validPill.className = 'validation-pill ' + (result.validation.valid ? 'pill-pass' : 'pill-fail');
validPill.textContent = result.validation.valid ? 'Valid' : 'Invalid';
valContent.appendChild(validPill);
if (result.validation.prefix_match) {
var prefixPill = document.createElement('span');
prefixPill.className = 'validation-pill pill-info';
prefixPill.textContent = result.validation.prefix_match;
valContent.appendChild(prefixPill);
}
if (result.validation.issues && result.validation.issues.length > 0) {
for (var j = 0; j < result.validation.issues.length; j++) {
var issuePill = document.createElement('span');
issuePill.className = 'validation-pill pill-warn';
issuePill.textContent = result.validation.issues[j];
valContent.appendChild(issuePill);
}
}
} else {
valContent.textContent = 'No validation data';
}
},
_hideAll: function () {
Utils.$('#results-empty').classList.add('hidden');
Utils.$('#results-loading').classList.add('hidden');
Utils.$('#results-data').classList.add('hidden');
Utils.$('#serial-results').classList.add('hidden');
Utils.$('#results-error').classList.add('hidden');
Utils.$('#image-preview-container').classList.add('hidden');
this._stopTimer();
},
_timerInterval: null,
_timerStart: 0,
_startTimer: function () {
this._timerStart = performance.now();
var el = Utils.$('#elapsed-timer');
var self = this;
el.textContent = 'Elapsed: 0s';
this._timerInterval = setInterval(function () {
var secs = Math.floor((performance.now() - self._timerStart) / 1000);
el.textContent = 'Elapsed: ' + secs + 's';
}, 1000);
},
_stopTimer: function () {
if (this._timerInterval) {
clearInterval(this._timerInterval);
this._timerInterval = null;
}
},
};