mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
feat(settings): appearance settings tab
New Appearance tab with color mode (moved out of Display), color-scheme swatches, a custom accent picker with a live WCAG contrast hint, transparency and reduce-motion toggles, density, a global text-size slider with advanced per-tier controls, and per-device dashboard widget toggles. Edits preview live and commit on a short debounce. i18n keys added across all locales, translated for German.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
// FE-COMP-APPEARANCE-001+ — color mode moved here from DisplaySettingsTab,
|
||||
// plus the new scheme / readability / dashboard-widget controls.
|
||||
import { render, screen, waitFor } from '../../../tests/helpers/render';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { server } from '../../../tests/helpers/msw/server';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import { useSettingsStore } from '../../store/settingsStore';
|
||||
import { resetAllStores, seedStore } from '../../../tests/helpers/store';
|
||||
import { buildUser, buildSettings } from '../../../tests/helpers/factories';
|
||||
import AppearanceSettingsTab from './AppearanceSettingsTab';
|
||||
|
||||
beforeEach(() => {
|
||||
resetAllStores();
|
||||
server.use(http.put('/api/settings', async () => HttpResponse.json({ success: true })));
|
||||
seedStore(useAuthStore, { user: buildUser(), isAuthenticated: true });
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light', language: 'en' }) });
|
||||
});
|
||||
|
||||
describe('AppearanceSettingsTab', () => {
|
||||
it('FE-COMP-APPEARANCE-001: renders without crashing', () => {
|
||||
render(<AppearanceSettingsTab />);
|
||||
expect(document.body).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-002: shows the color-mode buttons', () => {
|
||||
render(<AppearanceSettingsTab />);
|
||||
expect(screen.getByText('Light')).toBeInTheDocument();
|
||||
expect(screen.getByText('Dark')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /Auto/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-003: clicking Dark calls updateSetting with dark', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
render(<AppearanceSettingsTab />);
|
||||
await user.click(screen.getByText('Dark'));
|
||||
expect(updateSetting).toHaveBeenCalledWith('dark_mode', 'dark');
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-004: clicking Light calls updateSetting with light', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'dark' }), updateSetting });
|
||||
render(<AppearanceSettingsTab />);
|
||||
await user.click(screen.getByText('Light'));
|
||||
expect(updateSetting).toHaveBeenCalledWith('dark_mode', 'light');
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-005: clicking Auto calls updateSetting with auto', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
render(<AppearanceSettingsTab />);
|
||||
await user.click(screen.getByRole('button', { name: /Auto/i }));
|
||||
expect(updateSetting).toHaveBeenCalledWith('dark_mode', 'auto');
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-006: shows readability + dashboard widget sections', () => {
|
||||
render(<AppearanceSettingsTab />);
|
||||
expect(screen.getByText('Readability')).toBeInTheDocument();
|
||||
expect(screen.getByText('Transparency')).toBeInTheDocument();
|
||||
expect(screen.getByText('Dashboard widgets')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-007: shows the preset color schemes', () => {
|
||||
render(<AppearanceSettingsTab />);
|
||||
expect(screen.getByText('Indigo')).toBeInTheDocument();
|
||||
expect(screen.getByText('Teal')).toBeInTheDocument();
|
||||
expect(screen.getByText('High contrast')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-008: choosing a scheme persists the appearance config', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
render(<AppearanceSettingsTab />);
|
||||
await user.click(screen.getByText('Indigo'));
|
||||
await waitFor(
|
||||
() => expect(updateSetting).toHaveBeenCalledWith('appearance', expect.objectContaining({ schemeId: 'indigo' })),
|
||||
{ timeout: 1500 },
|
||||
);
|
||||
});
|
||||
|
||||
it('FE-COMP-APPEARANCE-009: toggling transparency persists transparency:false', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
render(<AppearanceSettingsTab />);
|
||||
await user.click(screen.getByRole('button', { name: 'Transparency' }));
|
||||
await waitFor(
|
||||
() => expect(updateSetting).toHaveBeenCalledWith('appearance', expect.objectContaining({ transparency: false })),
|
||||
{ timeout: 1500 },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,390 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { Paintbrush, Eye, LayoutDashboard, Sun, Moon, Monitor, RotateCcw } from 'lucide-react'
|
||||
import { useTranslation } from '../../i18n'
|
||||
import { useSettingsStore } from '../../store/settingsStore'
|
||||
import { useToast } from '../shared/Toast'
|
||||
import Section from './Section'
|
||||
import ToggleSwitch from './ToggleSwitch'
|
||||
import { applyAppearance } from '../../theme/applyAppearance'
|
||||
import { APPEARANCE_SCHEMES, CUSTOM_ACCENT_PRESETS } from '../../theme/schemes'
|
||||
import {
|
||||
DEFAULT_APPEARANCE,
|
||||
normalizeAppearance,
|
||||
APPEARANCE_SCALE_MIN,
|
||||
APPEARANCE_SCALE_MAX,
|
||||
type AppearanceConfig,
|
||||
} from '@trek/shared'
|
||||
|
||||
// ── WCAG contrast helpers (for the custom-accent legibility hint) ────────────
|
||||
function channelLum(v: number): number {
|
||||
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)
|
||||
}
|
||||
function relLuminance(hex: string): number {
|
||||
const c = hex.replace('#', '')
|
||||
const full = c.length === 3 ? c.split('').map((x) => x + x).join('') : c
|
||||
const r = channelLum(parseInt(full.slice(0, 2), 16) / 255)
|
||||
const g = channelLum(parseInt(full.slice(2, 4), 16) / 255)
|
||||
const b = channelLum(parseInt(full.slice(4, 6), 16) / 255)
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
||||
}
|
||||
function contrastRatio(a: string, b: string): number {
|
||||
const la = relLuminance(a)
|
||||
const lb = relLuminance(b)
|
||||
const [hi, lo] = la > lb ? [la, lb] : [lb, la]
|
||||
return (hi + 0.05) / (lo + 0.05)
|
||||
}
|
||||
const isHex = (v: string) => /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v)
|
||||
|
||||
type DesktopWidgetKey = keyof AppearanceConfig['dashboard']['desktop']
|
||||
type MobileWidgetKey = keyof AppearanceConfig['dashboard']['mobile']
|
||||
|
||||
const DESKTOP_WIDGETS: { key: DesktopWidgetKey; fallback: string }[] = [
|
||||
{ key: 'sidebar', fallback: 'Right sidebar' },
|
||||
{ key: 'currency', fallback: 'Currency' },
|
||||
{ key: 'timezones', fallback: 'Timezones' },
|
||||
{ key: 'upcomingReservations', fallback: 'Upcoming reservations' },
|
||||
{ key: 'atlas', fallback: 'Atlas / countries' },
|
||||
{ key: 'tripsTotal', fallback: 'Trips total' },
|
||||
{ key: 'daysTraveled', fallback: 'Days traveled' },
|
||||
{ key: 'distanceFlown', fallback: 'Distance flown' },
|
||||
]
|
||||
const MOBILE_WIDGETS: { key: MobileWidgetKey; fallback: string }[] = [
|
||||
{ key: 'tripsTotal', fallback: 'Trips total' },
|
||||
{ key: 'daysTraveled', fallback: 'Days traveled' },
|
||||
{ key: 'currency', fallback: 'Currency' },
|
||||
{ key: 'timezones', fallback: 'Timezones' },
|
||||
{ key: 'upcomingReservations', fallback: 'Upcoming reservations' },
|
||||
]
|
||||
|
||||
// shared segmented-button style (matches DisplaySettingsTab)
|
||||
function segStyle(active: boolean): React.CSSProperties {
|
||||
return {
|
||||
display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center',
|
||||
padding: '10px 14px', borderRadius: 10, cursor: 'pointer', flex: '1 1 0', minWidth: 0,
|
||||
fontFamily: 'inherit', fontSize: 14, fontWeight: 500,
|
||||
border: active ? '2px solid var(--text-primary)' : '2px solid var(--border-primary)',
|
||||
background: active ? 'var(--bg-hover)' : 'var(--bg-card)',
|
||||
color: 'var(--text-primary)', transition: 'all 0.15s',
|
||||
}
|
||||
}
|
||||
|
||||
export default function AppearanceSettingsTab(): React.ReactElement {
|
||||
const { settings, updateSetting } = useSettingsStore()
|
||||
const { t } = useTranslation()
|
||||
const toast = useToast()
|
||||
const tr = (key: string, fallback: string) => t(key) || fallback
|
||||
|
||||
const [cfg, setCfg] = useState<AppearanceConfig>(() => normalizeAppearance(settings.appearance))
|
||||
const [advancedType, setAdvancedType] = useState(false)
|
||||
const persistTimer = useRef<number | undefined>(undefined)
|
||||
|
||||
// Re-sync when settings change elsewhere (e.g. server reconcile / another tab).
|
||||
useEffect(() => {
|
||||
setCfg(normalizeAppearance(settings.appearance))
|
||||
}, [settings.appearance])
|
||||
|
||||
// Flush any pending persist on unmount.
|
||||
useEffect(() => () => {
|
||||
if (persistTimer.current) window.clearTimeout(persistTimer.current)
|
||||
}, [])
|
||||
|
||||
const isDark =
|
||||
settings.dark_mode === true ||
|
||||
settings.dark_mode === 'dark' ||
|
||||
(settings.dark_mode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
|
||||
// Live preview now (DOM), persist after a short debounce (API).
|
||||
const update = (patch: Partial<AppearanceConfig>) => {
|
||||
const next = { ...cfg, ...patch }
|
||||
setCfg(next)
|
||||
applyAppearance({ darkMode: settings.dark_mode, appearance: next, isSharedPage: false })
|
||||
if (persistTimer.current) window.clearTimeout(persistTimer.current)
|
||||
persistTimer.current = window.setTimeout(() => {
|
||||
updateSetting('appearance', next).catch((e: unknown) =>
|
||||
toast.error(e instanceof Error ? e.message : t('common.error'))
|
||||
)
|
||||
}, 350)
|
||||
}
|
||||
|
||||
const setMode = async (mode: string) => {
|
||||
try {
|
||||
await updateSetting('dark_mode', mode)
|
||||
} catch (e: unknown) {
|
||||
toast.error(e instanceof Error ? e.message : t('common.error'))
|
||||
}
|
||||
}
|
||||
|
||||
const setWidget = (device: 'desktop' | 'mobile', key: string, on: boolean) => {
|
||||
update({
|
||||
dashboard: {
|
||||
...cfg.dashboard,
|
||||
[device]: { ...cfg.dashboard[device], [key]: on },
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const resetAll = () => update({ ...DEFAULT_APPEARANCE })
|
||||
|
||||
const accentLight = cfg.accent?.light ?? '#4f46e5'
|
||||
const accentDark = cfg.accent?.dark ?? '#6366f1'
|
||||
const customRatio = contrastRatio(isDark ? accentDark : accentLight, isDark ? '#ffffff' : '#ffffff')
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* ── Theme ───────────────────────────────────────────────── */}
|
||||
<Section title={tr('settings.appearance.theme', 'Theme')} icon={Paintbrush}>
|
||||
{/* Color mode */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2 text-content-secondary">
|
||||
{tr('settings.colorMode', 'Color mode')}
|
||||
</label>
|
||||
<div className="flex gap-3" style={{ flexWrap: 'wrap' }}>
|
||||
{[
|
||||
{ value: 'light', label: tr('settings.light', 'Light'), icon: Sun },
|
||||
{ value: 'dark', label: tr('settings.dark', 'Dark'), icon: Moon },
|
||||
{ value: 'auto', label: tr('settings.auto', 'Auto'), icon: Monitor },
|
||||
].map((opt) => {
|
||||
const cur = settings.dark_mode
|
||||
const active =
|
||||
cur === opt.value ||
|
||||
(opt.value === 'light' && cur === false) ||
|
||||
(opt.value === 'dark' && cur === true)
|
||||
return (
|
||||
<button key={opt.value} onClick={() => setMode(opt.value)} style={segStyle(active)}>
|
||||
<span className="hidden sm:inline-flex"><opt.icon size={16} /></span>
|
||||
{opt.label}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Color scheme swatches */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2 text-content-secondary">
|
||||
{tr('settings.appearance.scheme', 'Color scheme')}
|
||||
</label>
|
||||
<div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
|
||||
{APPEARANCE_SCHEMES.map((s) => {
|
||||
const active = cfg.schemeId === s.id
|
||||
const dot = isDark ? s.swatch.dark : s.swatch.light
|
||||
return (
|
||||
<button
|
||||
key={s.id}
|
||||
onClick={() => update({ schemeId: s.id })}
|
||||
style={{
|
||||
display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px',
|
||||
borderRadius: 10, cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: 500,
|
||||
border: active ? '2px solid var(--text-primary)' : '2px solid var(--border-primary)',
|
||||
background: active ? 'var(--bg-hover)' : 'var(--bg-card)', color: 'var(--text-primary)',
|
||||
transition: 'all 0.15s',
|
||||
}}
|
||||
>
|
||||
<span style={{ width: 16, height: 16, borderRadius: '50%', background: dot, flexShrink: 0, boxShadow: 'inset 0 0 0 1px var(--border-faint)' }} />
|
||||
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||||
{tr(`settings.appearance.scheme.${s.id}`, schemeFallback(s.id))}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
{/* Custom */}
|
||||
<button
|
||||
onClick={() => update({ schemeId: 'custom', accent: cfg.accent ?? { light: accentLight, dark: accentDark } })}
|
||||
style={{
|
||||
display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px', borderRadius: 10,
|
||||
cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: 500,
|
||||
border: cfg.schemeId === 'custom' ? '2px solid var(--text-primary)' : '2px solid var(--border-primary)',
|
||||
background: cfg.schemeId === 'custom' ? 'var(--bg-hover)' : 'var(--bg-card)', color: 'var(--text-primary)',
|
||||
transition: 'all 0.15s',
|
||||
}}
|
||||
>
|
||||
<span style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0, background: 'conic-gradient(#ef4444,#f59e0b,#22c55e,#3b82f6,#8b5cf6,#ef4444)' }} />
|
||||
{tr('settings.appearance.scheme.custom', 'Custom')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Custom accent picker */}
|
||||
{cfg.schemeId === 'custom' && (
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2 text-content-secondary">
|
||||
{tr('settings.appearance.customAccent', 'Custom accent')}
|
||||
</label>
|
||||
<div className="flex flex-wrap gap-2 mb-3">
|
||||
{CUSTOM_ACCENT_PRESETS.map((c) => (
|
||||
<button
|
||||
key={c}
|
||||
aria-label={c}
|
||||
onClick={() => update({ accent: { light: c, dark: c } })}
|
||||
style={{ width: 28, height: 28, borderRadius: '50%', background: c, cursor: 'pointer', border: '2px solid var(--border-primary)' }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-4 items-center">
|
||||
<label className="flex items-center gap-2 text-sm text-content-secondary">
|
||||
{tr('settings.light', 'Light')}
|
||||
<input type="color" value={isHex(accentLight) ? accentLight : '#4f46e5'}
|
||||
onChange={(e) => update({ accent: { light: e.target.value, dark: accentDark } })}
|
||||
style={{ width: 36, height: 28, border: 'none', background: 'none', cursor: 'pointer' }} />
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm text-content-secondary">
|
||||
{tr('settings.dark', 'Dark')}
|
||||
<input type="color" value={isHex(accentDark) ? accentDark : '#6366f1'}
|
||||
onChange={(e) => update({ accent: { light: accentLight, dark: e.target.value } })}
|
||||
style={{ width: 36, height: 28, border: 'none', background: 'none', cursor: 'pointer' }} />
|
||||
</label>
|
||||
<span
|
||||
className="text-xs font-medium px-2 py-1 rounded-md"
|
||||
style={{ background: customRatio >= 4.5 ? 'var(--success-soft)' : 'var(--warning-soft)', color: customRatio >= 4.5 ? 'var(--success)' : 'var(--warning)' }}
|
||||
>
|
||||
{customRatio >= 4.5
|
||||
? `${tr('settings.appearance.contrastOk', 'Good contrast')} (${customRatio.toFixed(1)}:1)`
|
||||
: `${tr('settings.appearance.contrastLow', 'Low contrast')} (${customRatio.toFixed(1)}:1)`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Section>
|
||||
|
||||
{/* ── Readability ─────────────────────────────────────────── */}
|
||||
<Section title={tr('settings.appearance.readability', 'Readability')} icon={Eye}>
|
||||
<ToggleRow
|
||||
label={tr('settings.appearance.transparency', 'Transparency')}
|
||||
hint={tr('settings.appearance.transparencyHint', 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.')}
|
||||
on={cfg.transparency}
|
||||
onToggle={() => update({ transparency: !cfg.transparency })}
|
||||
/>
|
||||
<ToggleRow
|
||||
label={tr('settings.appearance.reduceMotion', 'Reduce motion')}
|
||||
hint={tr('settings.appearance.reduceMotionHint', 'Minimize animations and transitions.')}
|
||||
on={cfg.reduceMotion}
|
||||
onToggle={() => update({ reduceMotion: !cfg.reduceMotion })}
|
||||
/>
|
||||
|
||||
{/* Density */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2 text-content-secondary">
|
||||
{tr('settings.appearance.density', 'Density')}
|
||||
</label>
|
||||
<div className="flex gap-3">
|
||||
{[
|
||||
{ value: 'comfortable', label: tr('settings.appearance.comfortable', 'Comfortable') },
|
||||
{ value: 'compact', label: tr('settings.appearance.compact', 'Compact') },
|
||||
].map((opt) => (
|
||||
<button key={opt.value} onClick={() => update({ density: opt.value as AppearanceConfig['density'] })} style={segStyle(cfg.density === opt.value)}>
|
||||
{opt.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Text size (global) */}
|
||||
<SliderRow
|
||||
label={tr('settings.appearance.textSize', 'Text size')}
|
||||
value={cfg.fontScale}
|
||||
onChange={(v) => update({ fontScale: v })}
|
||||
/>
|
||||
<button
|
||||
onClick={() => setAdvancedType((v) => !v)}
|
||||
className="text-xs font-medium text-content-muted hover:text-content"
|
||||
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}
|
||||
>
|
||||
{advancedType ? tr('settings.appearance.hideAdvanced', 'Hide advanced') : tr('settings.appearance.advancedTextSizes', 'Advanced text sizes')}
|
||||
</button>
|
||||
{advancedType && (
|
||||
<div className="space-y-3 pl-1">
|
||||
<SliderRow label={tr('settings.appearance.tier.title', 'Titles')} value={cfg.typeScale.title} onChange={(v) => update({ typeScale: { ...cfg.typeScale, title: v } })} />
|
||||
<SliderRow label={tr('settings.appearance.tier.subtitle', 'Subtitles')} value={cfg.typeScale.subtitle} onChange={(v) => update({ typeScale: { ...cfg.typeScale, subtitle: v } })} />
|
||||
<SliderRow label={tr('settings.appearance.tier.body', 'Body')} value={cfg.typeScale.body} onChange={(v) => update({ typeScale: { ...cfg.typeScale, body: v } })} />
|
||||
<SliderRow label={tr('settings.appearance.tier.caption', 'Captions')} value={cfg.typeScale.caption} onChange={(v) => update({ typeScale: { ...cfg.typeScale, caption: v } })} />
|
||||
</div>
|
||||
)}
|
||||
</Section>
|
||||
|
||||
{/* ── Dashboard widgets ───────────────────────────────────── */}
|
||||
<Section title={tr('settings.appearance.dashboardWidgets', 'Dashboard widgets')} icon={LayoutDashboard}>
|
||||
<p className="text-xs text-content-faint -mt-1">
|
||||
{tr('settings.appearance.dashboardWidgetsHint', 'Show or hide dashboard widgets independently on desktop and mobile.')}
|
||||
</p>
|
||||
<div>
|
||||
<div className="text-sm font-medium mb-2 text-content-secondary">{tr('settings.appearance.desktop', 'Desktop')}</div>
|
||||
{DESKTOP_WIDGETS.map((w) => (
|
||||
<ToggleRow
|
||||
key={w.key}
|
||||
label={tr(`settings.appearance.widget.${w.key}`, w.fallback)}
|
||||
on={cfg.dashboard.desktop[w.key]}
|
||||
onToggle={() => setWidget('desktop', w.key, !cfg.dashboard.desktop[w.key])}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm font-medium mb-2 text-content-secondary">{tr('settings.appearance.mobile', 'Mobile')}</div>
|
||||
{MOBILE_WIDGETS.map((w) => (
|
||||
<ToggleRow
|
||||
key={w.key}
|
||||
label={tr(`settings.appearance.widget.${w.key}`, w.fallback)}
|
||||
on={cfg.dashboard.mobile[w.key]}
|
||||
onToggle={() => setWidget('mobile', w.key, !cfg.dashboard.mobile[w.key])}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<div className="flex justify-end mb-6">
|
||||
<button
|
||||
onClick={resetAll}
|
||||
className="flex items-center gap-2 text-sm font-medium text-content-muted hover:text-content"
|
||||
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '6px 4px' }}
|
||||
>
|
||||
<RotateCcw size={15} />
|
||||
{tr('settings.appearance.reset', 'Reset to defaults')}
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function schemeFallback(id: string): string {
|
||||
const map: Record<string, string> = {
|
||||
default: 'Default',
|
||||
highContrast: 'High contrast',
|
||||
indigo: 'Indigo',
|
||||
teal: 'Teal',
|
||||
rose: 'Rose',
|
||||
amber: 'Amber',
|
||||
violet: 'Violet',
|
||||
}
|
||||
return map[id] || id
|
||||
}
|
||||
|
||||
function ToggleRow({ label, hint, on, onToggle }: { label: string; hint?: string; on: boolean; onToggle: () => void }) {
|
||||
return (
|
||||
<div className="flex items-start justify-between gap-4 py-1.5">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-content-secondary">{label}</div>
|
||||
{hint && <div className="text-xs text-content-faint mt-0.5">{hint}</div>}
|
||||
</div>
|
||||
<ToggleSwitch on={on} onToggle={onToggle} label={label} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function SliderRow({ label, value, onChange }: { label: string; value: number; onChange: (v: number) => void }) {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<span className="text-sm font-medium text-content-secondary">{label}</span>
|
||||
<span className="text-xs text-content-muted tabular-nums">{Math.round(value * 100)}%</span>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
min={APPEARANCE_SCALE_MIN}
|
||||
max={APPEARANCE_SCALE_MAX}
|
||||
step={0.05}
|
||||
value={value}
|
||||
onChange={(e) => onChange(Number(e.target.value))}
|
||||
style={{ width: '100%', accentColor: 'var(--accent)', cursor: 'pointer' }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// FE-COMP-DISPLAY-001 to FE-COMP-DISPLAY-027
|
||||
import { render, screen, waitFor } from '../../../tests/helpers/render';
|
||||
import { render, screen } from '../../../tests/helpers/render';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { server } from '../../../tests/helpers/msw/server';
|
||||
@@ -30,21 +30,6 @@ describe('DisplaySettingsTab', () => {
|
||||
expect(screen.getByText('Display')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-003: shows Light mode button', () => {
|
||||
render(<DisplaySettingsTab />);
|
||||
expect(screen.getByText('Light')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-004: shows Dark mode button', () => {
|
||||
render(<DisplaySettingsTab />);
|
||||
expect(screen.getByText('Dark')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-005: shows Auto mode button', () => {
|
||||
render(<DisplaySettingsTab />);
|
||||
expect(screen.getByRole('button', { name: /Auto/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-006: shows Language section', () => {
|
||||
render(<DisplaySettingsTab />);
|
||||
expect(screen.getByText('Language')).toBeInTheDocument();
|
||||
@@ -55,20 +40,6 @@ describe('DisplaySettingsTab', () => {
|
||||
expect(screen.getByText('Time Format')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-008: clicking Dark mode button calls updateSetting', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
render(<DisplaySettingsTab />);
|
||||
await user.click(screen.getByText('Dark'));
|
||||
expect(updateSetting).toHaveBeenCalledWith('dark_mode', 'dark');
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-009: shows Color Mode label', () => {
|
||||
render(<DisplaySettingsTab />);
|
||||
expect(screen.getByText('Color Mode')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-010: shows 24h time format option', () => {
|
||||
render(<DisplaySettingsTab />);
|
||||
// Label is "24h (14:30)"
|
||||
@@ -81,35 +52,6 @@ describe('DisplaySettingsTab', () => {
|
||||
expect(screen.getByText(/12h/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-012: clicking Light mode calls updateSetting with light', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'dark' }), updateSetting });
|
||||
render(<DisplaySettingsTab />);
|
||||
await user.click(screen.getByText('Light'));
|
||||
expect(updateSetting).toHaveBeenCalledWith('dark_mode', 'light');
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-013: clicking Auto mode button calls updateSetting with auto', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
render(<DisplaySettingsTab />);
|
||||
await user.click(screen.getByRole('button', { name: /Auto/i }));
|
||||
expect(updateSetting).toHaveBeenCalledWith('dark_mode', 'auto');
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-014: active color mode button has border with var(--text-primary)', () => {
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'dark' }) });
|
||||
render(<DisplaySettingsTab />);
|
||||
const darkBtn = screen.getByRole('button', { name: /^Dark$/i });
|
||||
const lightBtn = screen.getByRole('button', { name: /^Light$/i });
|
||||
const autoBtn = screen.getByRole('button', { name: /Auto/i });
|
||||
expect(darkBtn.style.border).toContain('var(--text-primary)');
|
||||
expect(lightBtn.style.border).toContain('var(--border-primary)');
|
||||
expect(autoBtn.style.border).toContain('var(--border-primary)');
|
||||
});
|
||||
|
||||
it('FE-COMP-DISPLAY-015: clicking a language button calls updateSetting with that language code', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockResolvedValue(undefined);
|
||||
@@ -193,9 +135,9 @@ describe('DisplaySettingsTab', () => {
|
||||
it('FE-COMP-DISPLAY-026: updateSetting failure shows toast error', async () => {
|
||||
const user = userEvent.setup();
|
||||
const updateSetting = vi.fn().mockRejectedValue(new Error('Server error'));
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ dark_mode: 'light' }), updateSetting });
|
||||
seedStore(useSettingsStore, { settings: buildSettings({ temperature_unit: 'celsius' }), updateSetting });
|
||||
render(<><ToastContainer /><DisplaySettingsTab /></>);
|
||||
await user.click(screen.getByText('Dark'));
|
||||
await user.click(screen.getByText('°F Fahrenheit'));
|
||||
await screen.findByText('Server error');
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect, useRef } from 'react'
|
||||
import { Palette, Sun, Moon, Monitor, ChevronDown, Check } from 'lucide-react'
|
||||
import { Palette, ChevronDown, Check } from 'lucide-react'
|
||||
import { SUPPORTED_LANGUAGES, useTranslation } from '../../i18n'
|
||||
import { useSettingsStore } from '../../store/settingsStore'
|
||||
import { useToast } from '../shared/Toast'
|
||||
@@ -51,48 +51,6 @@ export default function DisplaySettingsTab(): React.ReactElement {
|
||||
<p className="text-xs text-content-faint mt-2">{t('settings.currencyHint')}</p>
|
||||
</div>
|
||||
|
||||
{/* Color Mode */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2 text-content-secondary">{t('settings.colorMode')}</label>
|
||||
<div className="flex gap-3" style={{ flexWrap: 'wrap' }}>
|
||||
{[
|
||||
{ value: 'light', label: t('settings.light'), icon: Sun },
|
||||
{ value: 'dark', label: t('settings.dark'), icon: Moon },
|
||||
{ value: 'auto', label: t('settings.auto'), icon: Monitor },
|
||||
].map(opt => {
|
||||
const current = settings.dark_mode
|
||||
const isActive = current === opt.value || (opt.value === 'light' && current === false) || (opt.value === 'dark' && current === true)
|
||||
return (
|
||||
<button
|
||||
key={opt.value}
|
||||
onClick={async () => {
|
||||
try {
|
||||
await updateSetting('dark_mode', opt.value)
|
||||
} catch (e: unknown) { toast.error(e instanceof Error ? e.message : t('common.error')) }
|
||||
}}
|
||||
style={{
|
||||
display: 'flex', alignItems: 'center', gap: 6,
|
||||
padding: '10px 14px', borderRadius: 10, cursor: 'pointer', flex: '1 1 0', justifyContent: 'center', minWidth: 0,
|
||||
fontFamily: 'inherit', fontSize: 14, fontWeight: 500,
|
||||
border: isActive ? '2px solid var(--text-primary)' : '2px solid var(--border-primary)',
|
||||
background: isActive ? 'var(--bg-hover)' : 'var(--bg-card)',
|
||||
color: 'var(--text-primary)',
|
||||
transition: 'all 0.15s',
|
||||
}}
|
||||
>
|
||||
<span className="hidden sm:inline-flex"><opt.icon size={16} /></span>
|
||||
{opt.value === 'auto' ? (
|
||||
<>
|
||||
<span className="hidden sm:inline">{opt.label}</span>
|
||||
<span className="sm:hidden">Auto</span>
|
||||
</>
|
||||
) : opt.label}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Language */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2 text-content-secondary">{t('settings.language')}</label>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from 'react'
|
||||
import { Settings, Palette, Map, Bell, Plug, CloudOff, User, Info } from 'lucide-react'
|
||||
import { Settings, Palette, Paintbrush, Map, Bell, Plug, CloudOff, User, Info } from 'lucide-react'
|
||||
import { useTranslation } from '../i18n'
|
||||
import PageShell from '../components/Layout/PageShell'
|
||||
import PageSidebar, { type PageSidebarTab } from '../components/Layout/PageSidebar'
|
||||
import DisplaySettingsTab from '../components/Settings/DisplaySettingsTab'
|
||||
import AppearanceSettingsTab from '../components/Settings/AppearanceSettingsTab'
|
||||
import MapSettingsTab from '../components/Settings/MapSettingsTab'
|
||||
import NotificationsTab from '../components/Settings/NotificationsTab'
|
||||
import IntegrationsTab from '../components/Settings/IntegrationsTab'
|
||||
@@ -19,6 +20,7 @@ export default function SettingsPage(): React.ReactElement {
|
||||
|
||||
const tabs: PageSidebarTab[] = [
|
||||
{ id: 'display', label: t('settings.tabs.display'), icon: Palette },
|
||||
{ id: 'appearance', label: t('settings.tabs.appearance'), icon: Paintbrush },
|
||||
{ id: 'map', label: t('settings.tabs.map'), icon: Map },
|
||||
{ id: 'notifications', label: t('settings.tabs.notifications'), icon: Bell },
|
||||
...(hasIntegrations
|
||||
@@ -54,6 +56,7 @@ export default function SettingsPage(): React.ReactElement {
|
||||
footer={appVersion ? `v${appVersion} · self-hosted` : 'self-hosted'}
|
||||
>
|
||||
{activeTab === 'display' && <DisplaySettingsTab />}
|
||||
{activeTab === 'appearance' && <AppearanceSettingsTab />}
|
||||
{activeTab === 'map' && <MapSettingsTab />}
|
||||
{activeTab === 'notifications' && <NotificationsTab />}
|
||||
{activeTab === 'integrations' && hasIntegrations && <IntegrationsTab />}
|
||||
|
||||
@@ -332,6 +332,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'للنماذج القادرة على الرؤية — يرسل ملف PDF الأصلي بدلًا من النص المستخرج.',
|
||||
'settings.aiParsing.toast.saved': 'تم حفظ إعدادات الذكاء الاصطناعي',
|
||||
'settings.aiParsing.toast.saveError': 'تعذّر حفظ إعدادات الذكاء الاصطناعي',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -342,6 +342,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Para modelos com capacidade de visão — envia o PDF original em vez do texto extraído.',
|
||||
'settings.aiParsing.toast.saved': 'Configurações de IA salvas',
|
||||
'settings.aiParsing.toast.saveError': 'Não foi possível salvar as configurações de IA',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -339,6 +339,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Pro modely se schopností zpracovat obraz — odešle původní PDF místo extrahovaného textu.',
|
||||
'settings.aiParsing.toast.saved': 'Nastavení AI uloženo',
|
||||
'settings.aiParsing.toast.saveError': 'Nastavení AI se nepodařilo uložit',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -346,6 +346,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Für Modelle mit Bildverständnis — sendet das Original-PDF statt extrahiertem Text.',
|
||||
'settings.aiParsing.toast.saved': 'KI-Einstellungen gespeichert',
|
||||
'settings.aiParsing.toast.saveError': 'KI-Einstellungen konnten nicht gespeichert werden',
|
||||
'settings.tabs.appearance': 'Erscheinungsbild',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Farbschema',
|
||||
'settings.appearance.scheme.default': 'Standard',
|
||||
'settings.appearance.scheme.highContrast': 'Hoher Kontrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Türkis',
|
||||
'settings.appearance.scheme.rose': 'Rosé',
|
||||
'settings.appearance.scheme.amber': 'Bernstein',
|
||||
'settings.appearance.scheme.violet': 'Violett',
|
||||
'settings.appearance.scheme.custom': 'Eigene',
|
||||
'settings.appearance.customAccent': 'Eigene Akzentfarbe',
|
||||
'settings.appearance.contrastOk': 'Guter Kontrast',
|
||||
'settings.appearance.contrastLow': 'Niedriger Kontrast',
|
||||
'settings.appearance.readability': 'Lesbarkeit',
|
||||
'settings.appearance.transparency': 'Transparenz',
|
||||
'settings.appearance.transparencyHint': 'Glasige, durchscheinende Flächen. Aus = solide, kontrastreichere Hintergründe.',
|
||||
'settings.appearance.reduceMotion': 'Bewegung reduzieren',
|
||||
'settings.appearance.reduceMotionHint': 'Animationen und Übergänge minimieren.',
|
||||
'settings.appearance.density': 'Dichte',
|
||||
'settings.appearance.comfortable': 'Komfortabel',
|
||||
'settings.appearance.compact': 'Kompakt',
|
||||
'settings.appearance.textSize': 'Textgröße',
|
||||
'settings.appearance.advancedTextSizes': 'Erweiterte Textgrößen',
|
||||
'settings.appearance.hideAdvanced': 'Erweitert ausblenden',
|
||||
'settings.appearance.tier.title': 'Titel',
|
||||
'settings.appearance.tier.subtitle': 'Untertitel',
|
||||
'settings.appearance.tier.body': 'Fließtext',
|
||||
'settings.appearance.tier.caption': 'Beschriftungen',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard-Widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Dashboard-Widgets unabhängig für Desktop und Mobil ein-/ausblenden.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobil',
|
||||
'settings.appearance.widget.sidebar': 'Rechte Seitenleiste',
|
||||
'settings.appearance.widget.currency': 'Währung',
|
||||
'settings.appearance.widget.timezones': 'Zeitzonen',
|
||||
'settings.appearance.widget.upcomingReservations': 'Anstehende Reservierungen',
|
||||
'settings.appearance.widget.atlas': 'Atlas / Länder',
|
||||
'settings.appearance.widget.tripsTotal': 'Reisen gesamt',
|
||||
'settings.appearance.widget.daysTraveled': 'Reisetage',
|
||||
'settings.appearance.widget.distanceFlown': 'Flugdistanz',
|
||||
'settings.appearance.reset': 'Auf Standard zurücksetzen',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -340,6 +340,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'For vision-capable models — sends the original PDF instead of extracted text.',
|
||||
'settings.aiParsing.toast.saved': 'AI settings saved',
|
||||
'settings.aiParsing.toast.saveError': 'Could not save AI settings',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -345,6 +345,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Para modelos con visión: envía el PDF original en lugar del texto extraído.',
|
||||
'settings.aiParsing.toast.saved': 'Ajustes de IA guardados',
|
||||
'settings.aiParsing.toast.saveError': 'No se han podido guardar los ajustes de IA',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -350,6 +350,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Pour les modèles capables d\'analyser des images — envoie le PDF d\'origine au lieu du texte extrait.',
|
||||
'settings.aiParsing.toast.saved': 'Paramètres d\'IA enregistrés',
|
||||
'settings.aiParsing.toast.saveError': 'Impossible d\'enregistrer les paramètres d\'IA',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -351,6 +351,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Για μοντέλα με δυνατότητα όρασης — στέλνει το αρχικό PDF αντί για το εξαγόμενο κείμενο.',
|
||||
'settings.aiParsing.toast.saved': 'Οι ρυθμίσεις AI αποθηκεύτηκαν',
|
||||
'settings.aiParsing.toast.saveError': 'Δεν ήταν δυνατή η αποθήκευση των ρυθμίσεων AI',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -344,6 +344,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Képfelismerésre képes modellekhez — az eredeti PDF-et küldi a kinyert szöveg helyett.',
|
||||
'settings.aiParsing.toast.saved': 'AI-beállítások elmentve',
|
||||
'settings.aiParsing.toast.saveError': 'Az AI-beállítások mentése nem sikerült',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -343,6 +343,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Untuk model yang mendukung visi — mengirim PDF asli alih-alih teks yang diekstrak.',
|
||||
'settings.aiParsing.toast.saved': 'Pengaturan AI disimpan',
|
||||
'settings.aiParsing.toast.saveError': 'Tidak dapat menyimpan pengaturan AI',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -343,6 +343,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Per i modelli con capacità visive: invia il PDF originale invece del testo estratto.',
|
||||
'settings.aiParsing.toast.saved': 'Impostazioni AI salvate',
|
||||
'settings.aiParsing.toast.saveError': 'Impossibile salvare le impostazioni AI',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -320,6 +320,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': '画像認識対応モデル向け — 抽出したテキストの代わりに元のPDFを送信します。',
|
||||
'settings.aiParsing.toast.saved': 'AI設定を保存しました',
|
||||
'settings.aiParsing.toast.saveError': 'AI設定を保存できませんでした',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -335,6 +335,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': '비전 지원 모델용 — 추출된 텍스트 대신 원본 PDF를 전송합니다.',
|
||||
'settings.aiParsing.toast.saved': 'AI 설정이 저장되었습니다',
|
||||
'settings.aiParsing.toast.saveError': 'AI 설정을 저장할 수 없습니다',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -343,6 +343,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Voor modellen met beeldherkenning — verstuurt de originele PDF in plaats van geëxtraheerde tekst.',
|
||||
'settings.aiParsing.toast.saved': 'AI-instellingen opgeslagen',
|
||||
'settings.aiParsing.toast.saveError': 'AI-instellingen konden niet worden opgeslagen',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -344,6 +344,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Dla modeli obsługujących obraz — wysyła oryginalny plik PDF zamiast wyodrębnionego tekstu.',
|
||||
'settings.aiParsing.toast.saved': 'Zapisano ustawienia AI',
|
||||
'settings.aiParsing.toast.saveError': 'Nie udało się zapisać ustawień AI',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -345,6 +345,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Для моделей с поддержкой изображений — отправляет исходный PDF вместо извлечённого текста.',
|
||||
'settings.aiParsing.toast.saved': 'Настройки ИИ сохранены',
|
||||
'settings.aiParsing.toast.saveError': 'Не удалось сохранить настройки ИИ',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -340,6 +340,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'För modeller med bildstöd — skickar original-PDF:en istället för extraherad text.',
|
||||
'settings.aiParsing.toast.saved': 'AI-inställningar sparade',
|
||||
'settings.aiParsing.toast.saveError': 'Kunde inte spara AI-inställningarna',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -340,6 +340,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Görüntü işleyebilen modeller için — çıkarılan metin yerine orijinal PDF\'yi gönderir.',
|
||||
'settings.aiParsing.toast.saved': 'Yapay zekâ ayarları kaydedildi',
|
||||
'settings.aiParsing.toast.saveError': 'Yapay zekâ ayarları kaydedilemedi',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -344,6 +344,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': 'Для моделей із підтримкою зображень — надсилає оригінальний PDF замість вилученого тексту.',
|
||||
'settings.aiParsing.toast.saved': 'Налаштування ШІ збережено',
|
||||
'settings.aiParsing.toast.saveError': 'Не вдалося зберегти налаштування ШІ',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -324,6 +324,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': '適用於具備視覺能力的模型 — 傳送原始 PDF,而非擷取出的文字。',
|
||||
'settings.aiParsing.toast.saved': 'AI 設定已儲存',
|
||||
'settings.aiParsing.toast.saveError': '無法儲存 AI 設定',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
@@ -322,6 +322,48 @@ const settings: TranslationStrings = {
|
||||
'settings.aiParsing.multimodalHint': '适用于支持视觉的模型——发送原始 PDF 而非提取的文本。',
|
||||
'settings.aiParsing.toast.saved': 'AI 设置已保存',
|
||||
'settings.aiParsing.toast.saveError': '无法保存 AI 设置',
|
||||
'settings.tabs.appearance': 'Appearance',
|
||||
'settings.appearance.theme': 'Theme',
|
||||
'settings.appearance.scheme': 'Color scheme',
|
||||
'settings.appearance.scheme.default': 'Default',
|
||||
'settings.appearance.scheme.highContrast': 'High contrast',
|
||||
'settings.appearance.scheme.indigo': 'Indigo',
|
||||
'settings.appearance.scheme.teal': 'Teal',
|
||||
'settings.appearance.scheme.rose': 'Rose',
|
||||
'settings.appearance.scheme.amber': 'Amber',
|
||||
'settings.appearance.scheme.violet': 'Violet',
|
||||
'settings.appearance.scheme.custom': 'Custom',
|
||||
'settings.appearance.customAccent': 'Custom accent',
|
||||
'settings.appearance.contrastOk': 'Good contrast',
|
||||
'settings.appearance.contrastLow': 'Low contrast',
|
||||
'settings.appearance.readability': 'Readability',
|
||||
'settings.appearance.transparency': 'Transparency',
|
||||
'settings.appearance.transparencyHint': 'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
||||
'settings.appearance.reduceMotion': 'Reduce motion',
|
||||
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
||||
'settings.appearance.density': 'Density',
|
||||
'settings.appearance.comfortable': 'Comfortable',
|
||||
'settings.appearance.compact': 'Compact',
|
||||
'settings.appearance.textSize': 'Text size',
|
||||
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
||||
'settings.appearance.hideAdvanced': 'Hide advanced',
|
||||
'settings.appearance.tier.title': 'Titles',
|
||||
'settings.appearance.tier.subtitle': 'Subtitles',
|
||||
'settings.appearance.tier.body': 'Body',
|
||||
'settings.appearance.tier.caption': 'Captions',
|
||||
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
||||
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
||||
'settings.appearance.desktop': 'Desktop',
|
||||
'settings.appearance.mobile': 'Mobile',
|
||||
'settings.appearance.widget.sidebar': 'Right sidebar',
|
||||
'settings.appearance.widget.currency': 'Currency',
|
||||
'settings.appearance.widget.timezones': 'Timezones',
|
||||
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
||||
'settings.appearance.widget.atlas': 'Atlas / countries',
|
||||
'settings.appearance.widget.tripsTotal': 'Trips total',
|
||||
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
||||
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
||||
'settings.appearance.reset': 'Reset to defaults',
|
||||
};
|
||||
|
||||
export default settings;
|
||||
|
||||
Reference in New Issue
Block a user