Files
PowderCoatingLogix/src/PowderCoating.Web/wwwroot/js/catalog-price-check.js
T
2026-04-25 22:45:36 -04:00

87 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function () {
'use strict';
var form = document.getElementById('runForm');
var btn = document.getElementById('runBtn');
var overlay = document.getElementById('price-check-overlay');
var bar = document.getElementById('overlay-bar');
var pctLabel = document.getElementById('overlay-pct');
var statusMsg = document.getElementById('overlay-status');
if (!form || !btn || !overlay) return;
// Estimate total seconds based on item count.
// Haiku sequential: 1 batch at a time, ~27s each (API time + 20s pacing gap).
function estimateDuration(itemCount) {
var batches = Math.max(1, Math.ceil(itemCount / 25));
return Math.max(30, batches * 27);
}
// Messages keyed to approximate progress milestones (0100).
function messageAt(pct, batchCount) {
if (pct < 10) return 'Loading catalog items…';
if (pct < 20) return 'Sending items for analysis…';
if (batchCount <= 1) {
if (pct < 75) return 'Analyzing your catalog with AI…';
if (pct < 92) return 'Reviewing pricing data…';
} else {
var batchDone = Math.floor((pct / 100) * batchCount);
if (batchDone < batchCount) {
return 'Analyzing batch ' + (batchDone + 1) + ' of ' + batchCount + '…';
}
}
if (pct < 97) return 'Compiling results…';
return 'Almost done…';
}
function setProgress(pct, batchCount) {
var clamped = Math.min(99, Math.max(0, pct));
bar.style.width = clamped + '%';
pctLabel.textContent = Math.round(clamped);
statusMsg.textContent = messageAt(clamped, batchCount);
}
form.addEventListener('submit', function () {
btn.disabled = true;
var itemCount = parseInt(btn.getAttribute('data-item-count') || '0', 10);
var batchCount = Math.max(1, Math.ceil(itemCount / 25));
var totalSecs = estimateDuration(itemCount);
overlay.classList.add('active');
setProgress(0, batchCount);
// Animate progress: fast to ~85%, then slow crawl toward 99%.
// Uses two easing phases so it never "finishes" before the server responds.
var start = Date.now();
var phase1End = totalSecs * 0.80 * 1000; // 80% of time -> 85% progress
var raf;
function tick() {
var elapsed = Date.now() - start;
var pct;
if (elapsed < phase1End) {
// Phase 1: ease-out from 0 -> 85
var t = elapsed / phase1End;
pct = 85 * (1 - Math.pow(1 - t, 2));
} else {
// Phase 2: slow crawl 85 -> 99 (never quite reaches 99)
var t2 = (elapsed - phase1End) / (totalSecs * 1000);
pct = 85 + 14 * (1 - Math.exp(-t2 * 1.5));
}
setProgress(pct, batchCount);
raf = requestAnimationFrame(tick);
}
raf = requestAnimationFrame(tick);
// The page navigation itself tears down the overlay; cancel the RAF to avoid
// running after the page is gone.
window.addEventListener('pagehide', function () {
cancelAnimationFrame(raf);
});
});
}());