<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/icon-192.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MCP Fullstack Dashboard</title>
<!-- PWA Meta Tags -->
<meta name="application-name" content="MCP Dashboard" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="MCP Dashboard" />
<meta name="description" content="Monitor and manage your MCP Fullstack server" />
<meta name="format-detection" content="telephone=no" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="msapplication-config" content="/browserconfig.xml" />
<meta name="msapplication-TileColor" content="#4f46e5" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="theme-color" content="#4f46e5" />
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="/icon-192.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/icon-192.png" />
<link rel="apple-touch-icon" sizes="512x512" href="/icon-512.png" />
<!-- PWA Manifest -->
<link rel="manifest" href="/manifest.json" />
<!-- Drag regions for custom window controls -->
<style>
.drag-region {
-webkit-app-region: drag;
app-region: drag;
}
.no-drag {
-webkit-app-region: no-drag;
app-region: no-drag;
}
/* Custom scrollbar for better native feel */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #f1f5f9;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
@media (prefers-color-scheme: dark) {
::-webkit-scrollbar-track {
background: #1e293b;
}
::-webkit-scrollbar-thumb {
background: #475569;
}
::-webkit-scrollbar-thumb:hover {
background: #64748b;
}
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<!-- PWA Service Worker Registration -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then((registration) => {
console.log('SW registered: ', registration);
// Listen for updates
registration.addEventListener('updatefound', () => {
const newWorker = registration.installing;
if (newWorker) {
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// New update available
if (confirm('New version available! Reload to update?')) {
newWorker.postMessage({ type: 'SKIP_WAITING' });
window.location.reload();
}
}
});
}
});
})
.catch((registrationError) => {
console.log('SW registration failed: ', registrationError);
});
});
// Handle service worker messages
navigator.serviceWorker.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SYNC_COMPLETE') {
console.log('App is back online!');
// Optionally show a toast notification
}
});
}
// PWA Install Prompt
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
console.log('PWA install prompt available');
deferredPrompt = e;
// Show custom install button if desired
const installButton = document.getElementById('install-pwa');
if (installButton) {
installButton.style.display = 'block';
installButton.addEventListener('click', () => {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
console.log('User choice:', choiceResult.outcome);
deferredPrompt = null;
installButton.style.display = 'none';
});
}
});
}
});
// Handle app installation
window.addEventListener('appinstalled', () => {
console.log('PWA was installed');
deferredPrompt = null;
const installButton = document.getElementById('install-pwa');
if (installButton) {
installButton.style.display = 'none';
}
});
// Window Controls Overlay API (for custom title bars)
if ('windowControlsOverlay' in navigator) {
const updateWindowControls = () => {
const titleBar = document.getElementById('titlebar');
if (titleBar && navigator.windowControlsOverlay.visible) {
const { x, y, width, height } = navigator.windowControlsOverlay.getTitlebarAreaRect();
titleBar.style.setProperty('--wco-x', x + 'px');
titleBar.style.setProperty('--wco-y', y + 'px');
titleBar.style.setProperty('--wco-width', width + 'px');
titleBar.style.setProperty('--wco-height', height + 'px');
}
};
navigator.windowControlsOverlay.addEventListener('geometrychange', updateWindowControls);
updateWindowControls();
}
</script>
</body>
</html>