feat: implement comprehensive i18n internationalization support

- Add custom i18n infrastructure with TypeScript support
- Support Chinese (zh-CN) and English (en-US) languages
- Implement language switching with localStorage persistence
- Update all components with translation keys:
  * System info components (board-info-panel, board-index)
  * Display management components (display-state-index, display-state-card)
  * LED strip configuration components (led-strip-configuration, led-count-control-panel)
  * White balance component with detailed usage instructions
  * LED test component with test pattern descriptions
- Add comprehensive translation coverage for:
  * Navigation menus and page titles
  * Common UI elements (buttons, status, actions)
  * Hardware information and connection status
  * Display configuration options
  * LED strip settings and controls
  * White balance adjustment instructions and tips
  * LED test modes and descriptions
  * Error messages and status indicators
- Features:
  * Dynamic language switching without app restart
  * Type-safe translation keys with full TypeScript support
  * Modular design for easy language extension
  * Responsive UI updates using SolidJS reactivity
This commit is contained in:
2025-07-08 16:55:12 +08:00
parent 4a3d7681d6
commit 2c6b777fa6
16 changed files with 893 additions and 115 deletions

View File

@@ -8,10 +8,12 @@ import { setLedStripStore } from './stores/led-strip.store';
import { LedStripConfigContainer } from './models/led-strip-config';
import { InfoIndex } from './components/info/info-index';
import { DisplayStateIndex } from './components/displays/display-state-index';
import { useLanguage } from './i18n/index';
function App() {
const location = useLocation();
const [previousPath, setPreviousPath] = createSignal<string>('');
const { t, locale, setLocale } = useLanguage();
// Monitor route changes and cleanup LED tests when leaving the test page
createEffect(() => {
@@ -57,26 +59,49 @@ function App() {
</svg>
</div>
<ul class="menu menu-sm dropdown-content mt-3 z-[100] p-2 shadow bg-base-100 rounded-box w-52 border border-base-300">
<li><A href="/info" class="text-base-content hover:bg-base-200"></A></li>
<li><A href="/displays" class="text-base-content hover:bg-base-200"></A></li>
<li><A href="/led-strips-configuration" class="text-base-content hover:bg-base-200"></A></li>
<li><A href="/white-balance" class="text-base-content hover:bg-base-200"></A></li>
<li><A href="/led-strip-test" class="text-base-content hover:bg-base-200"></A></li>
<li><A href="/info" class="text-base-content hover:bg-base-200">{t('nav.info')}</A></li>
<li><A href="/displays" class="text-base-content hover:bg-base-200">{t('nav.displays')}</A></li>
<li><A href="/led-strips-configuration" class="text-base-content hover:bg-base-200">{t('nav.ledConfiguration')}</A></li>
<li><A href="/white-balance" class="text-base-content hover:bg-base-200">{t('nav.whiteBalance')}</A></li>
<li><A href="/led-strip-test" class="text-base-content hover:bg-base-200">{t('nav.ledTest')}</A></li>
</ul>
</div>
<a class="btn btn-ghost text-xl text-primary font-bold"></a>
<a class="btn btn-ghost text-xl text-primary font-bold">{t('nav.title')}</a>
</div>
<div class="navbar-center hidden lg:flex">
<ul class="menu menu-horizontal px-1">
<li><A href="/info" class="btn btn-ghost text-base-content hover:text-primary"></A></li>
<li><A href="/displays" class="btn btn-ghost text-base-content hover:text-primary"></A></li>
<li><A href="/led-strips-configuration" class="btn btn-ghost text-base-content hover:text-primary"></A></li>
<li><A href="/white-balance" class="btn btn-ghost text-base-content hover:text-primary"></A></li>
<li><A href="/led-strip-test" class="btn btn-ghost text-base-content hover:text-primary"></A></li>
<li><A href="/info" class="btn btn-ghost text-base-content hover:text-primary">{t('nav.info')}</A></li>
<li><A href="/displays" class="btn btn-ghost text-base-content hover:text-primary">{t('nav.displays')}</A></li>
<li><A href="/led-strips-configuration" class="btn btn-ghost text-base-content hover:text-primary">{t('nav.ledConfiguration')}</A></li>
<li><A href="/white-balance" class="btn btn-ghost text-base-content hover:text-primary">{t('nav.whiteBalance')}</A></li>
<li><A href="/led-strip-test" class="btn btn-ghost text-base-content hover:text-primary">{t('nav.ledTest')}</A></li>
</ul>
</div>
<div class="navbar-end">
<div class="badge badge-primary badge-outline">v1.0</div>
<div class="dropdown dropdown-end">
<div tabindex="0" role="button" class="btn btn-ghost btn-sm">
{locale() === 'zh-CN' ? '中文' : 'English'}
</div>
<ul class="dropdown-content z-[100] menu p-2 shadow bg-base-100 rounded-box w-32 border border-base-300">
<li>
<button
class={`${locale() === 'zh-CN' ? 'active' : ''}`}
onClick={() => setLocale('zh-CN')}
>
</button>
</li>
<li>
<button
class={`${locale() === 'en-US' ? 'active' : ''}`}
onClick={() => setLocale('en-US')}
>
English
</button>
</li>
</ul>
</div>
<div class="badge badge-primary badge-outline ml-2">v1.0</div>
</div>
</div>