Files
analiticaNucleo/nuxt4-app/app.html

245 lines
6.5 KiB
HTML

<!DOCTYPE html>
<html {{ HTML_ATTRS }} style="background: #1b1209;">
<head {{ HEAD_ATTRS }}>
<!-- Critical styles - must load FIRST to prevent white flash -->
<style>
/* Critical: Load background immediately */
html, body {
margin: 0 !important;
padding: 0 !important;
background: #1b1209 !important;
min-height: 100vh;
overflow: hidden;
}
/* Show loading screen immediately */
#nuxt-loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #1b1209 0%, #2a1a0f 100%);
display: flex !important;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 99999;
}
</style>
{{ HEAD }}
<style>
/* Ultra-lightweight loading screen - loads instantly */
#nuxt-loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #1b1209 0%, #2a1a0f 100%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
font-family: system-ui, -apple-system, sans-serif;
opacity: 1;
transition: opacity 0.3s ease-out;
}
#nuxt-loading-screen.fade-out {
opacity: 0;
pointer-events: none;
}
.loading-logo {
width: 80px;
height: 80px;
margin-bottom: 24px;
border-radius: 50%;
border: 3px solid rgba(255, 224, 160, 0.4);
background: radial-gradient(circle, #c08040 0%, #8b5a2b 100%);
display: flex;
align-items: center;
justify-content: center;
animation: pulse 2s ease-in-out infinite;
}
.loading-icon {
width: 40px;
height: 40px;
border: 3px solid transparent;
border-top-color: #ffe0a0;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes pulse {
0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(192, 128, 64, 0.7); }
50% { transform: scale(1.05); box-shadow: 0 0 20px 10px rgba(192, 128, 64, 0); }
}
.loading-title {
font-size: 24px;
font-weight: 600;
color: #ffe0a0;
margin-bottom: 8px;
letter-spacing: 0.5px;
}
.loading-subtitle {
font-size: 14px;
color: #c08040;
margin-bottom: 32px;
opacity: 0.9;
}
.loading-progress {
width: 300px;
max-width: 80%;
margin-bottom: 16px;
}
.progress-bar {
width: 100%;
height: 4px;
background: rgba(192, 128, 64, 0.2);
border-radius: 2px;
overflow: hidden;
position: relative;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #c08040 0%, #ffe0a0 100%);
border-radius: 2px;
transition: width 0.3s ease-out;
width: 0%;
box-shadow: 0 0 10px rgba(255, 224, 160, 0.5);
}
.loading-status {
font-size: 13px;
color: #8b7355;
text-align: center;
min-height: 20px;
margin-top: 12px;
font-weight: 500;
}
.loading-dots::after {
content: '';
animation: dots 1.5s steps(4, end) infinite;
}
@keyframes dots {
0%, 20% { content: '.'; }
40% { content: '..'; }
60%, 100% { content: '...'; }
}
/* Hide the loading screen when Nuxt is ready */
html.nuxt-ready #nuxt-loading-screen {
display: none;
}
</style>
</head>
<body {{ BODY_ATTRS }} style="background: #1b1209; margin: 0; padding: 0;">
<!-- Ultra-lightweight loading screen -->
<div id="nuxt-loading-screen">
<div class="loading-logo">
<div class="loading-icon"></div>
</div>
<div class="loading-title">Analítica Núcleo</div>
<div class="loading-subtitle">Data Studio</div>
<div class="loading-progress">
<div class="progress-bar">
<div class="progress-fill" id="loading-progress-fill"></div>
</div>
<div class="loading-status">
<span id="loading-status-text" class="loading-dots">Iniciando aplicación</span>
</div>
</div>
</div>
{{ APP }}
<script>
// Ultra-lightweight progress simulator
(function() {
const progressFill = document.getElementById('loading-progress-fill');
const statusText = document.getElementById('loading-status-text');
const loadingScreen = document.getElementById('nuxt-loading-screen');
const stages = [
{ progress: 20, text: 'Cargando recursos', delay: 100 },
{ progress: 35, text: 'Inicializando Vue', delay: 300 },
{ progress: 50, text: 'Cargando componentes', delay: 500 },
{ progress: 65, text: 'Configurando rutas', delay: 700 },
{ progress: 80, text: 'Preparando datos', delay: 900 },
{ progress: 95, text: 'Finalizando', delay: 1200 }
];
let currentStage = 0;
function updateProgress() {
if (currentStage < stages.length) {
const stage = stages[currentStage];
setTimeout(() => {
if (progressFill && statusText) {
progressFill.style.width = stage.progress + '%';
statusText.textContent = stage.text;
statusText.className = 'loading-dots';
}
currentStage++;
// Check if app is ready
if (document.documentElement.classList.contains('nuxt-ready')) {
completeLoading();
} else {
updateProgress();
}
}, stage.delay);
}
}
function completeLoading() {
if (progressFill && statusText && loadingScreen) {
progressFill.style.width = '100%';
statusText.textContent = '¡Listo!';
statusText.className = '';
setTimeout(() => {
loadingScreen.classList.add('fade-out');
setTimeout(() => {
loadingScreen.style.display = 'none';
}, 300);
}, 200);
}
}
// Start progress
updateProgress();
// Fallback: hide loading screen after 5 seconds max
setTimeout(() => {
document.documentElement.classList.add('nuxt-ready');
completeLoading();
}, 5000);
// Listen for when the app is actually ready
window.addEventListener('load', () => {
setTimeout(() => {
document.documentElement.classList.add('nuxt-ready');
completeLoading();
}, 500);
});
})();
</script>
</body>
</html>