feat: UI overhaul - component library + route layouts with instant headers

- Created 11 reusable UI components: PageHeader, SectionCard, StatCard, StatusBadge, TabBar, MemberList, ActivityFeed, EventCard, ContentSkeleton, QuickLinkGrid, ModuleCard
- Created route-specific +layout.svelte for documents, calendar, kanban, events, settings, account
- Each layout renders PageHeader instantly from parent data, shows ContentSkeleton during navigation
- Removed full-page PageSkeleton from parent layout
- Refactored all pages to use new components instead of inline markup
- Overview page: uses StatCard, SectionCard, EventCard, ActivityFeed, MemberList, QuickLinkGrid
- Events list: uses EventCard, Button components
- Event detail: uses ModuleCard, SectionCard
- Settings/Account/Calendar/Kanban: headers in layouts, toolbars in pages
- Added i18n keys for overview page (EN + ET)
- 0 errors, 112 tests pass
This commit is contained in:
AlacrisDevs
2026-02-07 10:44:53 +02:00
parent fe6ec6e0af
commit 2913912cb8
30 changed files with 1240 additions and 604 deletions

View File

@@ -0,0 +1,46 @@
<script lang="ts">
import type { Snippet } from "svelte";
interface Props {
title: string;
subtitle?: string;
icon?: string;
iconColor?: string;
actions?: Snippet;
class?: string;
}
let {
title,
subtitle,
icon,
iconColor = "text-white",
actions,
class: className = "",
}: Props = $props();
</script>
<header
class="flex items-center justify-between px-6 py-5 border-b border-light/5 shrink-0 {className}"
>
<div class="flex items-center gap-3 min-w-0">
{#if icon}
<span
class="material-symbols-rounded {iconColor} shrink-0"
style="font-size: 28px; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 28;"
>{icon}</span
>
{/if}
<div class="min-w-0">
<h1 class="text-h1 font-heading text-white truncate">{title}</h1>
{#if subtitle}
<p class="text-body-sm text-light/50 mt-0.5">{subtitle}</p>
{/if}
</div>
</div>
{#if actions}
<div class="flex items-center gap-2 shrink-0 ml-4">
{@render actions()}
</div>
{/if}
</header>