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 { search } from '$lib/stores/search.svelte.js';
|
||||
import SearchResult from './SearchResult.svelte';
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
<div
|
||||
class="w-full max-w-lg rounded-lg border border-border bg-popover shadow-2xl"
|
||||
role="dialog"
|
||||
aria-label="Search"
|
||||
aria-label={$t('search.placeholder')}
|
||||
>
|
||||
<!-- Input -->
|
||||
<div class="flex items-center gap-2 border-b border-border px-4 py-3">
|
||||
@@ -54,7 +55,7 @@
|
||||
bind:this={inputEl}
|
||||
bind:value={search.query}
|
||||
type="text"
|
||||
placeholder="Search apps and boards..."
|
||||
placeholder={$t('search.placeholder')}
|
||||
class="flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus:outline-none"
|
||||
/>
|
||||
<kbd
|
||||
@@ -76,17 +77,17 @@
|
||||
<p class="py-6 text-center text-sm text-destructive">{search.error}</p>
|
||||
{:else if search.query.length < 2}
|
||||
<p class="py-6 text-center text-sm text-muted-foreground">
|
||||
Type at least 2 characters to search
|
||||
{$t('search.min_chars')}
|
||||
</p>
|
||||
{:else if search.results.length === 0}
|
||||
<p class="py-6 text-center text-sm text-muted-foreground">
|
||||
No results for "{search.query}"
|
||||
{$t('search.no_results', { values: { query: search.query } })}
|
||||
</p>
|
||||
{:else}
|
||||
{#if appResults.length > 0}
|
||||
<div class="mb-2">
|
||||
<p class="mb-1 px-3 text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
||||
Apps
|
||||
{$t('search.apps')}
|
||||
</p>
|
||||
{#each appResults as result (result.id)}
|
||||
<SearchResult {result} onselect={() => search.close()} />
|
||||
@@ -97,7 +98,7 @@
|
||||
{#if boardResults.length > 0}
|
||||
<div>
|
||||
<p class="mb-1 px-3 text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
||||
Boards
|
||||
{$t('search.boards')}
|
||||
</p>
|
||||
{#each boardResults as result (result.id)}
|
||||
<SearchResult {result} onselect={() => search.close()} />
|
||||
|
||||
Reference in New Issue
Block a user