forensic-pathways/src/pages/status.astro
overcuriousity a7dc688753 finalize
2025-07-15 00:33:26 +02:00

88 lines
3.2 KiB
Plaintext

---
import BaseLayout from '../layouts/BaseLayout.astro';
import { promises as fs } from 'fs';
import { load } from 'js-yaml';
import path from 'path';
// Load tools data to get self-hosted services
const yamlPath = path.join(process.cwd(), 'src/data/tools.yaml');
const yamlContent = await fs.readFile(yamlPath, 'utf8');
const data = load(yamlContent) as any;
// Filter for hosted services based on projectUrl presence
const hostedServices = data.tools.filter((tool: any) => {
return tool.projectUrl !== undefined &&
tool.projectUrl !== null &&
tool.projectUrl !== "" &&
tool.projectUrl.trim() !== "";
});
---
<BaseLayout title="Service Status">
<section style="padding: 2rem 0;">
<h1 style="text-align: center; margin-bottom: 1rem;">Service Status</h1>
<p class="text-muted" style="text-align: center; max-width: 600px; margin: 0 auto 3rem;">
Live-Monitoring zum Onlinestatus der Dienste.
</p>
<!-- Service Status Grid -->
<div class="grid grid-cols-2 gap-4" style="margin-bottom: 3rem;">
{hostedServices.map((service: any) => (
<div class="card">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h3 style="margin: 0;">{service.name}</h3>
<div id={`status-${service.name.toLowerCase().replace(/\s+/g, '-')}`}>
<!-- Status badge will be inserted here -->
<span class="badge badge-warning">Loading...</span>
</div>
</div>
<p class="text-muted" style="font-size: 0.875rem; margin-bottom: 1rem;">
{service.description}
</p>
<a href={service.projectUrl} target="_blank" rel="noopener noreferrer" class="btn btn-secondary">
Zugreifen →
</a>
</div>
))}
</div>
<!-- Uptime Kuma Embed -->
<div class="card" style="padding: 0; overflow: hidden;">
<iframe
src="https://status.mikoshi.de/status/cc24-hub?embed=true"
style="width: 100%; height: 600px; border: none;"
title="Uptime Kuma Status Page"
></iframe>
</div>
</section>
</BaseLayout>
<script define:vars={{ hostedServices }}>
// Load status badges for each service
document.addEventListener('DOMContentLoaded', () => {
hostedServices.forEach(service => {
const statusElement = document.getElementById(`status-${service.name.toLowerCase().replace(/\s+/g, '-')}`);
if (statusElement && service.statusUrl) {
// Create image element
const img = document.createElement('img');
img.src = service.statusUrl;
img.alt = `Status for ${service.name}`;
img.style.height = '20px';
img.style.verticalAlign = 'middle';
// Handle load error
img.onerror = function() {
statusElement.innerHTML = '<span class="badge badge-warning">Unknown</span>';
};
// Replace loading badge with image
statusElement.innerHTML = '';
statusElement.appendChild(img);
} else if (statusElement) {
// No status URL available
statusElement.innerHTML = '<span class="badge badge-warning">No Status</span>';
}
});
});
</script>