Add frontend
This commit is contained in:
81
frontend/src/routes/+layout.svelte
Normal file
81
frontend/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,81 @@
|
||||
<script lang="ts">
|
||||
import '../app.css';
|
||||
import { onMount } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import { checkHealth } from '$lib/api';
|
||||
let { children } = $props();
|
||||
|
||||
interface Notification {
|
||||
id: number;
|
||||
type: 'success' | 'error';
|
||||
message: string;
|
||||
}
|
||||
|
||||
let notifications: Notification[] = $state([]);
|
||||
let notificationId = 0;
|
||||
|
||||
let healthStatus = writable<'healthy' | 'unhealthy'>('unhealthy');
|
||||
|
||||
async function updateHealthStatus() {
|
||||
const status = await checkHealth();
|
||||
healthStatus.set(status);
|
||||
}
|
||||
|
||||
function showNotification(type: 'success' | 'error', message: string): void {
|
||||
const id = notificationId++;
|
||||
notifications = [...notifications, { id, type, message }];
|
||||
setTimeout(() => {
|
||||
notifications = notifications.filter((n) => n.id !== id);
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
window.showNotification = showNotification;
|
||||
updateHealthStatus();
|
||||
setInterval(updateHealthStatus, 10000); // Check health every 10 seconds
|
||||
});
|
||||
</script>
|
||||
|
||||
<nav class="bg-gray-800 text-white shadow-md">
|
||||
<div class="container mx-auto flex justify-between items-center p-4">
|
||||
<a href="/" class="text-2xl font-bold hover:text-gray-400">Project Monitor</a>
|
||||
<div class="flex space-x-6">
|
||||
<a href="/" class="text-lg hover:text-gray-400">Home</a>
|
||||
<a href="/scripts" class="text-lg hover:text-gray-400">Scripts</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="relative">
|
||||
{@render children()}
|
||||
|
||||
<div class="fixed bottom-4 right-4 space-y-2">
|
||||
{#each notifications as notification (notification.id)}
|
||||
<div
|
||||
class="p-4 rounded shadow-lg text-white"
|
||||
class:bg-green-500={notification.type === 'success'}
|
||||
class:bg-red-500={notification.type === 'error'}
|
||||
>
|
||||
{notification.message}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fixed bottom-4 left-4 group">
|
||||
{#if $healthStatus === 'healthy'}
|
||||
<span class="text-green-500">✅</span>
|
||||
<div
|
||||
class="absolute bottom-full left-1/2 hidden group-hover:flex group-hover:w-max bg-green-500 text-white px-2 py-1 rounded shadow-lg"
|
||||
>
|
||||
Connected to backend
|
||||
</div>
|
||||
{:else}
|
||||
<span class="text-red-500">✘</span>
|
||||
<div
|
||||
class="absolute bottom-full left-1/2 hidden group-hover:flex group-hover:w-max bg-red-500 text-white px-2 py-1 rounded shadow-lg"
|
||||
>
|
||||
Not connected
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
Reference in New Issue
Block a user