bbbe3705d8
- watchdog inline no index.html: erro de asset /assets/ (404 de bundle antiga em cache), import dinâmico falho, ou #root vazio após 8s → reload automático - index.tsx: listener vite:preloadError → reload - anti-loop por timestamp (só recarrega se última tentativa >30s; re-arma sozinho) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
70 lines
2.6 KiB
HTML
70 lines
2.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="pt-BR">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>ScoreOdonto CRM</title>
|
|
|
|
<script>
|
|
(function () {
|
|
var path = window.location.pathname;
|
|
if (path.indexOf('/odonto') !== -1 && !path.endsWith('/') && path.split('/').pop().indexOf('.') === -1) {
|
|
var newUrl = path + '/' + window.location.search + window.location.hash;
|
|
window.location.replace(newUrl);
|
|
}
|
|
})();
|
|
</script>
|
|
|
|
<script>
|
|
/* Anti-tela-branca pós-deploy: se um asset (bundle/chunk/css) falhar — ex.: index
|
|
antigo em cache apontando p/ bundle removida (404) — ou o app não montar,
|
|
recarrega UMA vez para pegar o index/bundle novo. O flag é limpo no app ao
|
|
montar com sucesso, rearmando a proteção para o próximo deploy. */
|
|
(function () {
|
|
function reloadOnce() {
|
|
try {
|
|
var last = +sessionStorage.getItem('__sd_stale_reload__') || 0;
|
|
if (Date.now() - last < 30000) return; /* recarregou há <30s → evita loop */
|
|
sessionStorage.setItem('__sd_stale_reload__', String(Date.now()));
|
|
} catch (_) {}
|
|
location.reload();
|
|
}
|
|
window.addEventListener('error', function (e) {
|
|
var t = e && e.target; if (!t) return;
|
|
var url = t.src || t.href || '';
|
|
if ((t.tagName === 'SCRIPT' || t.tagName === 'LINK') && /\/assets\/|\/index\.tsx/.test(url)) reloadOnce();
|
|
}, true);
|
|
window.addEventListener('unhandledrejection', function (e) {
|
|
var m = e && e.reason && (e.reason.message || String(e.reason));
|
|
if (m && /dynamically imported module|module script failed|Failed to fetch/i.test(m)) reloadOnce();
|
|
});
|
|
window.addEventListener('load', function () {
|
|
setTimeout(function () {
|
|
var root = document.getElementById('root');
|
|
if (root && root.childElementCount === 0) reloadOnce();
|
|
}, 8000);
|
|
});
|
|
})();
|
|
</script>
|
|
|
|
<base href="/">
|
|
|
|
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
|
|
<link rel="stylesheet" href="./index.css">
|
|
</head>
|
|
|
|
<body>
|
|
<div id="root"></div>
|
|
<div id="toast-container"></div>
|
|
<div id="global-error-display"
|
|
style="display: none; position: fixed; top: 10px; left: 10px; right: 10px; background-color: #ef4444; color: white; padding: 16px; border-radius: 8px; z-index: 9999; font-family: monospace; font-size: 14px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
|
</div>
|
|
|
|
<script type="module" src="/index.tsx"></script>
|
|
</body>
|
|
|
|
</html> |