fix: polish empty states and status page layout
CI / lint-and-check (push) Failing after 5m4s
CI / test (push) Has been skipped
CI / docker-build (push) Has been skipped

- Boards: improved empty state with create button for admins
- Status: 2-column grid layout, colored left border by status, better empty state
This commit is contained in:
2026-04-10 19:06:53 +03:00
parent aedc91e321
commit 76ce85c9bb
2 changed files with 55 additions and 22 deletions
+20 -4
View File
@@ -31,9 +31,10 @@
</div>
{#if data.boards.length === 0}
<div class="rounded-xl border border-border bg-card/50 p-12 text-center">
<div class="flex flex-col items-center rounded-xl border border-dashed border-border bg-card/30 px-6 py-16 text-center">
<div class="mb-4 flex h-16 w-16 items-center justify-center rounded-2xl bg-primary/10">
<svg
class="mx-auto mb-3 h-12 w-12 text-muted-foreground/40"
class="h-8 w-8 text-primary"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
@@ -46,9 +47,24 @@
<line x1="3" y1="9" x2="21" y2="9" />
<line x1="9" y1="21" x2="9" y2="9" />
</svg>
<p class="text-muted-foreground">{$t('board.no_boards')}</p>
</div>
<p class="text-lg font-medium text-foreground">{$t('board.no_boards')}</p>
{#if data.isGuest}
<p class="mt-2 text-sm text-muted-foreground/70">{$t('board.sign_in_more')}</p>
<p class="mt-1 max-w-sm text-sm text-muted-foreground">{$t('board.sign_in_more')}</p>
{:else if data.user?.role === 'admin'}
<p class="mt-1 max-w-sm text-sm text-muted-foreground">
Create your first board to organize apps into a custom dashboard.
</p>
<a
href="/boards/new"
class="mt-4 inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90"
>
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19" />
<line x1="5" y1="12" x2="19" y2="12" />
</svg>
{$t('board.new')}
</a>
{/if}
</div>
{:else}
+22 -5
View File
@@ -42,6 +42,19 @@
}
}
function statusBorderColor(status: string): string {
switch (status) {
case 'online':
return 'border-l-green-500';
case 'offline':
return 'border-l-red-500';
case 'degraded':
return 'border-l-yellow-500';
default:
return 'border-l-gray-400';
}
}
function formatUptime(value: number | null): string {
if (value === null) return 'N/A';
return `${value.toFixed(2)}%`;
@@ -58,7 +71,7 @@
</svelte:head>
<div class="p-6">
<div class="mx-auto max-w-5xl">
<div class="mx-auto max-w-7xl">
<!-- Header -->
<div class="mb-8">
<h1 class="text-3xl font-bold text-foreground">Status Page</h1>
@@ -101,14 +114,18 @@
</div>
<!-- Apps List -->
<div class="space-y-3">
<div class="grid grid-cols-1 gap-3 xl:grid-cols-2">
{#if data.apps.length === 0}
<div class="rounded-xl border border-border bg-card p-12 text-center">
<p class="text-muted-foreground">No monitored services found</p>
<div class="col-span-full rounded-xl border border-border bg-card p-12 text-center">
<svg class="mx-auto mb-3 h-12 w-12 text-muted-foreground/30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 12h-4l-3 9L9 3l-3 9H2" />
</svg>
<p class="text-lg font-medium text-muted-foreground">No monitored services</p>
<p class="mt-1 text-sm text-muted-foreground/70">Add apps with health checking enabled to see their status here</p>
</div>
{:else}
{#each data.apps as app (app.appId)}
<div class="rounded-xl border border-border bg-card p-4 transition-colors hover:bg-card/80">
<div class="rounded-xl border border-l-4 border-border {statusBorderColor(app.currentStatus ?? 'unknown')} bg-card p-4 transition-colors hover:bg-card/80">
<div class="flex items-center gap-4">
<!-- Status Dot -->
<div class="flex-shrink-0">