Files
Homepage/index.html

103 lines
4.5 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Services Homepage</title>
<!-- PWA Meta Tags -->
<meta name="description" content="Quick access to your self-hosted services" />
<meta name="theme-color" content="#0f3460" />
<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="Services" />
<link rel="manifest" href="/manifest.json" />
<link rel="apple-touch-icon" href="/logos/icon-192.png" />
<link rel="stylesheet" href="/styles.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
<canvas id="galaxy-canvas"></canvas>
<div id="background-overlay"></div>
<header>
<h1>My Services</h1>
<p class="subtitle">Quick links to the commonly used containers on this host</p>
<div class="search-container">
<input type="text" id="search-input" placeholder="🔍 Search services or press Enter to search DuckDuckGo..." />
<button id="ddg-search-btn" title="Search on DuckDuckGo" aria-label="Search on DuckDuckGo">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm0 23C5.925 23 1 18.075 1 12S5.925 1 12 1s11 4.925 11 11-4.925 11-11 11zm-1.424-8.93c-1.492 0-2.412-1.02-2.412-2.474 0-1.476.93-2.51 2.401-2.51 1.492 0 2.391 1.034 2.391 2.51.011 1.465-.92 2.475-2.38 2.475zm4.703-.004c-1.476 0-2.396-1.016-2.396-2.47 0-1.476.93-2.51 2.401-2.51 1.492 0 2.391 1.034 2.391 2.51 0 1.465-.92 2.47-2.396 2.47zM12 17.906c-3.153 0-4.976-1.951-5.281-3.28h1.097c.322.968 1.645 2.184 4.184 2.184s3.862-1.216 4.184-2.184h1.097c-.305 1.329-2.128 3.28-5.281 3.28z"/>
</svg>
</button>
</div>
</header>
<main>
<section id="services-container">
<!-- Service groups will be populated dynamically from /services.xml -->
</section>
<section class="notes" id="readme-section">
<div id="readme-content">Loading documentation...</div>
</section>
</main>
<footer>
<small>Generated: static homepage — served by nginx in a container. Edit and rebuild to update.</small>
</footer>
<!-- JavaScript modules -->
<script src="/js/galaxy-background.js"></script>
<script src="/js/themes.js"></script>
<script src="/js/services-loader.js"></script>
<script src="/js/drag-drop.js"></script>
<script src="/js/collapsible-groups.js"></script>
<script src="/js/search.js"></script>
<script src="/js/keyboard-nav.js"></script>
<script src="/js/readme-loader.js"></script>
<script src="/js/export-import.js"></script>
<script src="/js/widgets.js"></script>
<!-- Initialize features after DOM is loaded -->
<script>
// Register Service Worker for PWA
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then((registration) => {
console.log('Service Worker registered:', registration.scope);
})
.catch((error) => {
console.log('Service Worker registration failed:', error);
});
});
}
window.addEventListener('DOMContentLoaded', () => {
// Wait for services to be loaded
const checkServicesLoaded = setInterval(() => {
if (window.servicesData && window.servicesData.allServices.length > 0) {
clearInterval(checkServicesLoaded);
// Initialize all features
if (window.themesModule) window.themesModule.init();
if (window.dragDropModule) {
window.dragDropModule.init();
window.dragDropModule.applySavedOrder();
}
if (window.collapsibleGroupsModule) window.collapsibleGroupsModule.init();
if (window.importExportModule) window.importExportModule.init();
if (window.widgetsModule) window.widgetsModule.init();
}
}, 100);
// Timeout after 5 seconds
setTimeout(() => clearInterval(checkServicesLoaded), 5000);
});
</script>
</body>
</html>