feat(phase2): localization EN/RU + additional widget types
- Add svelte-i18n with 224 translation keys (English + Russian) - Language switcher in header (EN/RU toggle, persists to localStorage) - Extract all hardcoded strings from 37 component/page files - Add 4 new widget types: Bookmark, Note (markdown), Embed (iframe), Status - WidgetRenderer dispatches by type, WidgetGrid supports full-width widgets - Type-specific config forms in board editor - Install marked for markdown rendering
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { t } from 'svelte-i18n';
|
||||
import { ui } from '$lib/stores/ui.svelte.js';
|
||||
import { page } from '$app/stores';
|
||||
import DynamicIcon from '$lib/components/ui/DynamicIcon.svelte';
|
||||
@@ -46,10 +47,10 @@
|
||||
<rect x="14" y="14" width="7" height="7" />
|
||||
<rect x="3" y="14" width="7" height="7" />
|
||||
</svg>
|
||||
<span class="text-sm font-semibold">App Launcher</span>
|
||||
<span class="text-sm font-semibold">{$t('app_name')}</span>
|
||||
</a>
|
||||
{:else}
|
||||
<a href="/" class="mx-auto text-sidebar-primary" title="App Launcher">
|
||||
<a href="/" class="mx-auto text-sidebar-primary" title={$t('app_name')}>
|
||||
<svg
|
||||
class="h-6 w-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -75,7 +76,7 @@
|
||||
<div class="mb-3">
|
||||
{#if !collapsed}
|
||||
<p class="mb-1 px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/50">
|
||||
Navigation
|
||||
{$t('nav.navigation')}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
@@ -84,7 +85,7 @@
|
||||
class="flex items-center gap-2 rounded-md px-2 py-2 text-sm transition-colors {isActive('/boards')
|
||||
? 'bg-sidebar-accent text-sidebar-accent-foreground'
|
||||
: 'text-sidebar-foreground hover:bg-sidebar-accent/50'}"
|
||||
title={collapsed ? 'Boards' : undefined}
|
||||
title={collapsed ? $t('nav.boards') : undefined}
|
||||
>
|
||||
<svg
|
||||
class="h-4 w-4 shrink-0"
|
||||
@@ -100,7 +101,7 @@
|
||||
<line x1="3" y1="9" x2="21" y2="9" />
|
||||
<line x1="9" y1="21" x2="9" y2="9" />
|
||||
</svg>
|
||||
{#if !collapsed}<span>Boards</span>{/if}
|
||||
{#if !collapsed}<span>{$t('nav.boards')}</span>{/if}
|
||||
</a>
|
||||
|
||||
<a
|
||||
@@ -108,7 +109,7 @@
|
||||
class="flex items-center gap-2 rounded-md px-2 py-2 text-sm transition-colors {isActive('/apps')
|
||||
? 'bg-sidebar-accent text-sidebar-accent-foreground'
|
||||
: 'text-sidebar-foreground hover:bg-sidebar-accent/50'}"
|
||||
title={collapsed ? 'Apps' : undefined}
|
||||
title={collapsed ? $t('nav.apps') : undefined}
|
||||
>
|
||||
<svg
|
||||
class="h-4 w-4 shrink-0"
|
||||
@@ -126,7 +127,7 @@
|
||||
d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"
|
||||
/>
|
||||
</svg>
|
||||
{#if !collapsed}<span>Apps</span>{/if}
|
||||
{#if !collapsed}<span>{$t('nav.apps')}</span>{/if}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -137,7 +138,7 @@
|
||||
<p
|
||||
class="mb-1 px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/50"
|
||||
>
|
||||
Boards
|
||||
{$t('nav.boards')}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
@@ -174,7 +175,7 @@
|
||||
<p
|
||||
class="mb-1 px-2 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/50"
|
||||
>
|
||||
Admin
|
||||
{$t('nav.admin')}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
@@ -183,7 +184,7 @@
|
||||
class="flex items-center gap-2 rounded-md px-2 py-2 text-sm transition-colors {isActive('/admin')
|
||||
? 'bg-sidebar-accent text-sidebar-accent-foreground'
|
||||
: 'text-sidebar-foreground hover:bg-sidebar-accent/50'}"
|
||||
title={collapsed ? 'Admin Panel' : undefined}
|
||||
title={collapsed ? $t('nav.admin_panel') : undefined}
|
||||
>
|
||||
<svg
|
||||
class="h-4 w-4 shrink-0"
|
||||
@@ -200,7 +201,7 @@
|
||||
/>
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
{#if !collapsed}<span>Admin Panel</span>{/if}
|
||||
{#if !collapsed}<span>{$t('nav.admin_panel')}</span>{/if}
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -213,7 +214,7 @@
|
||||
type="button"
|
||||
onclick={() => ui.toggleSidebar()}
|
||||
class="flex w-full items-center justify-center rounded-md p-2 text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
|
||||
title={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
|
||||
title={collapsed ? $t('sidebar.expand') : $t('sidebar.collapse')}
|
||||
>
|
||||
<svg
|
||||
class="h-4 w-4 transition-transform duration-200"
|
||||
|
||||
Reference in New Issue
Block a user