0bd30c5e17
Add layout system (sidebar, header, main layout), dark/light/system theme with HSL customization, 3 ambient backgrounds (mesh gradient, particle field, aurora), Cmd/Ctrl+K search dialog, page transitions, card hover effects, status pulse animations, skeleton loaders, and responsive design. Polish all existing pages with consistent theming.
46 lines
1.1 KiB
Svelte
46 lines
1.1 KiB
Svelte
<script lang="ts">
|
|
import AppWidget from './AppWidget.svelte';
|
|
import WidgetContainer from './WidgetContainer.svelte';
|
|
|
|
interface WidgetData {
|
|
id: string;
|
|
type: string;
|
|
order: number;
|
|
config: string;
|
|
appId: string | null;
|
|
app: {
|
|
id: string;
|
|
name: string;
|
|
url: string;
|
|
icon: string | null;
|
|
iconType: string;
|
|
description: string | null;
|
|
statuses: Array<{ status: string; responseTime: number | null }>;
|
|
} | null;
|
|
}
|
|
|
|
interface Props {
|
|
widgets: WidgetData[];
|
|
}
|
|
|
|
let { widgets }: Props = $props();
|
|
</script>
|
|
|
|
{#if widgets.length === 0}
|
|
<p class="text-sm text-muted-foreground">No widgets in this section.</p>
|
|
{:else}
|
|
<div class="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4">
|
|
{#each widgets as widget (widget.id)}
|
|
<WidgetContainer>
|
|
{#if widget.type === 'app' && widget.app}
|
|
<AppWidget app={widget.app} />
|
|
{:else}
|
|
<div class="flex h-full items-center justify-center rounded-xl border border-border bg-card p-4">
|
|
<span class="text-xs text-muted-foreground">{widget.type} widget</span>
|
|
</div>
|
|
{/if}
|
|
</WidgetContainer>
|
|
{/each}
|
|
</div>
|
|
{/if}
|