wrolpi/etc/raspberrypios/maintenance.html
2025-12-06 15:11:37 -07:00

210 lines
5.8 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WROLPi - Upgrade in Progress</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
color: #333;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 50%, #dde4ed 100%);
}
.container {
text-align: center;
padding: 2rem;
max-width: 500px;
width: 90%;
}
.logo {
font-size: 3rem;
margin-bottom: 1rem;
}
h1 {
color: #5829bb;
font-size: 1.8rem;
margin-bottom: 0.5rem;
font-weight: 600;
}
.subtitle {
color: #666;
font-size: 1rem;
margin-bottom: 2rem;
}
.spinner-container {
margin: 2rem 0;
}
.spinner {
width: 50px;
height: 50px;
border: 4px solid #ddd;
border-top: 4px solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.status {
font-size: 1.1rem;
margin: 1.5rem 0;
min-height: 1.5em;
}
.elapsed {
color: #666;
font-size: 0.9rem;
margin-top: 1rem;
}
.warning {
background: rgba(255, 193, 7, 0.1);
border: 1px solid rgba(255, 193, 7, 0.3);
border-radius: 8px;
padding: 1rem;
margin-top: 2rem;
font-size: 0.9rem;
color: #b38600;
}
.success {
color: #4CAF50;
}
.check-icon {
font-size: 3rem;
color: #4CAF50;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: scale(0.5); }
to { opacity: 1; transform: scale(1); }
}
.hidden {
display: none;
}
.help-link {
margin-top: 1.5em;
font-size: 1.2em;
}
.help-link a {
color: #5829bb;
text-decoration: none;
}
.help-link a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<div class="logo">WROLPi</div>
<h1>Upgrade in Progress</h1>
<p class="subtitle">Please wait while your system is being upgraded</p>
<div class="spinner-container" id="spinnerContainer">
<div class="spinner"></div>
</div>
<div class="spinner-container hidden" id="successContainer">
<div class="check-icon">&#10003;</div>
</div>
<p class="status" id="status">Checking upgrade status...</p>
<p class="elapsed" id="elapsed">Elapsed: 0:00</p>
<div class="warning">
<strong>Do not power off</strong> your device or close this window during the upgrade.
</div>
<p class="help-link">
<a id="helpLink" href="#" target="_blank">WROLPi Help</a>
</p>
</div>
<script>
const startTime = Date.now();
let pollInterval;
let elapsedInterval;
function updateElapsed() {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
const minutes = Math.floor(elapsed / 60);
const seconds = elapsed % 60;
document.getElementById('elapsed').textContent =
`Elapsed: ${minutes}:${seconds.toString().padStart(2, '0')}`;
}
function showSuccess() {
document.getElementById('spinnerContainer').classList.add('hidden');
document.getElementById('successContainer').classList.remove('hidden');
}
async function checkApiStatus() {
try {
const response = await fetch('/api/status', {
method: 'GET',
headers: { 'Accept': 'application/json' },
// Short timeout to avoid long waits
signal: AbortSignal.timeout(5000)
});
if (response.ok) {
// API is back online!
clearInterval(pollInterval);
clearInterval(elapsedInterval);
showSuccess();
document.getElementById('status').innerHTML =
'<span class="success">Upgrade complete! Redirecting...</span>';
// Redirect to home after a short delay
setTimeout(() => {
window.location.href = '/';
}, 2000);
}
} catch (e) {
// API is still down or timeout - this is expected during upgrade
document.getElementById('status').textContent = 'Upgrade in progress...';
}
}
// Update elapsed time every second
elapsedInterval = setInterval(updateElapsed, 1000);
// Check API status every 3 seconds
pollInterval = setInterval(checkApiStatus, 3000);
// Initial check
checkApiStatus();
// Set help link to correct hostname
document.getElementById('helpLink').href = `https://${window.location.hostname}:8086`;
</script>
</body>
</html>