innercontext/frontend/src/routes/+page.svelte
Piotr Oleszczyk 99584521a1 feat(frontend): add PL/EN i18n using @inlang/paraglide-js v2
- Install @inlang/paraglide-js v2 with Vite plugin and paraglideMiddleware hook
- Add messages/pl.json and messages/en.json with ~400 translation keys
- Create project.inlang/settings.json (PL as base locale)
- Add LanguageSwitcher component (cookie-based, no URL prefix needed)
- Replace all hardcoded strings across 14 pages/components with m.*() calls
- ProductForm uses derived label maps for all enum types (category, texture, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 13:20:34 +01:00

85 lines
2.6 KiB
Svelte

<script lang="ts">
import type { PageData } from './$types';
import { m } from '$lib/paraglide/messages.js';
import { Badge } from '$lib/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';
let { data }: { data: PageData } = $props();
const stateColors: Record<string, string> = {
excellent: 'bg-green-100 text-green-800',
good: 'bg-blue-100 text-blue-800',
fair: 'bg-yellow-100 text-yellow-800',
poor: 'bg-red-100 text-red-800'
};
</script>
<svelte:head><title>{m.dashboard_title()} — innercontext</title></svelte:head>
<div class="space-y-8">
<div>
<h2 class="text-2xl font-bold tracking-tight">{m.dashboard_title()}</h2>
<p class="text-muted-foreground">{m.dashboard_subtitle()}</p>
</div>
<div class="grid gap-6 md:grid-cols-2">
<!-- Latest skin snapshot -->
<Card>
<CardHeader>
<CardTitle>{m["dashboard_latestSnapshot"]()}</CardTitle>
</CardHeader>
<CardContent>
{#if data.latestSnapshot}
{@const s = data.latestSnapshot}
<div class="space-y-3">
<div class="flex items-center justify-between">
<span class="text-sm text-muted-foreground">{s.snapshot_date}</span>
{#if s.overall_state}
<span class="rounded-full px-2 py-0.5 text-xs font-medium {stateColors[s.overall_state] ?? ''}">
{s.overall_state}
</span>
{/if}
</div>
{#if s.active_concerns.length}
<div class="flex flex-wrap gap-1">
{#each s.active_concerns as concern (concern)}
<Badge variant="secondary">{concern.replace(/_/g, ' ')}</Badge>
{/each}
</div>
{/if}
{#if s.notes}
<p class="text-sm text-muted-foreground">{s.notes}</p>
{/if}
</div>
{:else}
<p class="text-sm text-muted-foreground">{m["dashboard_noSnapshots"]()}</p>
{/if}
</CardContent>
</Card>
<!-- Recent routines -->
<Card>
<CardHeader>
<CardTitle>{m["dashboard_recentRoutines"]()}</CardTitle>
</CardHeader>
<CardContent>
{#if data.recentRoutines.length}
<ul class="space-y-2">
{#each data.recentRoutines as routine (routine.id)}
<li class="flex items-center justify-between">
<a href="/routines/{routine.id}" class="text-sm hover:underline">
{routine.routine_date}
</a>
<Badge variant={routine.part_of_day === 'am' ? 'default' : 'secondary'}>
{routine.part_of_day.toUpperCase()}
</Badge>
</li>
{/each}
</ul>
{:else}
<p class="text-sm text-muted-foreground">{m["dashboard_noRoutines"]()}</p>
{/if}
</CardContent>
</Card>
</div>
</div>