task(H4): i18n foundation - strings.ts de/en maps, t() with key fallback, language persistence, useT hook, LayoutBar + Topbar texts switched
This commit is contained in:
@@ -11,6 +11,7 @@ import type { LayoutDefinition } from '../types/cad.types';
|
||||
import { getActiveDocument, onActiveDocumentChanged } from '../kernel/document/documentService';
|
||||
import { insertTitleBlockForLayout } from '../services/titleBlockService';
|
||||
import { printLayout } from '../services/printService';
|
||||
import { useT } from '../i18n/strings';
|
||||
|
||||
export interface LayoutView {
|
||||
center: { x: number; y: number };
|
||||
@@ -80,6 +81,8 @@ const WIDGET_W = 100;
|
||||
const WIDGET_H = 80;
|
||||
|
||||
const LayoutBar: React.FC<LayoutBarProps> = ({ doc: docProp, bridge: bridgeProp }) => {
|
||||
const t = useT();
|
||||
|
||||
const [doc, setDoc] = useState(docProp ?? getActiveDocument());
|
||||
const [layouts, setLayouts] = useState<LayoutDefinition[]>([]);
|
||||
|
||||
@@ -134,23 +137,23 @@ const LayoutBar: React.FC<LayoutBarProps> = ({ doc: docProp, bridge: bridgeProp
|
||||
return (
|
||||
<div className="layout-bar" data-testid="layout-bar">
|
||||
<div className="layout-bar-header">
|
||||
<span className="layout-bar-title">Layouts</span>
|
||||
<span className="layout-bar-title">{t('layouts.title')}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="layout-bar-add"
|
||||
title="Layout hinzufügen"
|
||||
title={t('layouts.add')}
|
||||
onClick={handleAdd}
|
||||
disabled={!bridge || !doc}
|
||||
>+</button>
|
||||
<button
|
||||
type="button"
|
||||
className="layout-bar-print screen-only"
|
||||
title="Layout drucken (A4 landscape)"
|
||||
title={t('layouts.print')}
|
||||
onClick={handlePrint}
|
||||
>🖨</button>
|
||||
</div>
|
||||
{layouts.length === 0 ? (
|
||||
<div className="layout-bar-empty">Keine Layouts</div>
|
||||
<div className="layout-bar-empty">{t('layouts.empty')}</div>
|
||||
) : (
|
||||
<div className="layout-bar-list">
|
||||
{layouts.map((l) => {
|
||||
@@ -161,7 +164,7 @@ const LayoutBar: React.FC<LayoutBarProps> = ({ doc: docProp, bridge: bridgeProp
|
||||
type="button"
|
||||
className="layout-bar-entry"
|
||||
data-testid={`layout-entry-${l.id}`}
|
||||
title={`Zoom zu ${l.name}`}
|
||||
title={t('layouts.zoomto', l.name)}
|
||||
onClick={() => handleZoomTo(l)}
|
||||
>
|
||||
<svg
|
||||
@@ -187,7 +190,7 @@ const LayoutBar: React.FC<LayoutBarProps> = ({ doc: docProp, bridge: bridgeProp
|
||||
<button
|
||||
type="button"
|
||||
className="layout-bar-tb"
|
||||
title={`Titelblock für ${l.name} einfügen/aktualisieren`}
|
||||
title={t('layouts.titleblock', l.name)}
|
||||
onClick={() => {
|
||||
if (!doc) return;
|
||||
insertTitleBlockForLayout(doc as never, l.id, {
|
||||
@@ -202,7 +205,7 @@ const LayoutBar: React.FC<LayoutBarProps> = ({ doc: docProp, bridge: bridgeProp
|
||||
<button
|
||||
type="button"
|
||||
className="layout-bar-del"
|
||||
title={`Layout ${l.name} löschen`}
|
||||
title={t('layouts.delete', l.name)}
|
||||
onClick={() => handleDelete(l.id)}
|
||||
>🗑</button>
|
||||
</div>
|
||||
|
||||
@@ -2,12 +2,15 @@ import React from 'react';
|
||||
import type { TopbarProps } from '../types/ui.types';
|
||||
import type { UnitType } from '../utils/format';
|
||||
import { useUIMode, toggleUIMode, getUIMode } from '../services/uiModeService';
|
||||
import { useT } from '../i18n/strings';
|
||||
|
||||
const Topbar: React.FC<TopbarProps> = ({
|
||||
projectName, savedStatus, onUndo, onRedo, onThemeToggle, theme,
|
||||
onOpenSettings, onOpenLeftDrawer, onOpenRightDrawer,
|
||||
unit = 'mm', onUnitChange, onNavigateBack,
|
||||
}) => {
|
||||
const t = useT();
|
||||
|
||||
const uiMode = useUIMode();
|
||||
|
||||
return (
|
||||
@@ -38,8 +41,8 @@ const Topbar: React.FC<TopbarProps> = ({
|
||||
<div className="topbar-right">
|
||||
<button
|
||||
className="icon-btn-top"
|
||||
title={uiMode === 'pro' ? 'Zum einfachen Modus wechseln' : 'Zum Profi-Modus wechseln'}
|
||||
aria-label={uiMode === 'pro' ? 'Zum einfachen Modus wechseln' : 'Zum Profi-Modus wechseln'}
|
||||
title={uiMode === 'pro' ? t('mode.toSimple') : t('mode.toPro')}
|
||||
aria-label={uiMode === 'pro' ? t('mode.toSimple') : t('mode.toPro')}
|
||||
onClick={toggleUIMode}
|
||||
>
|
||||
{uiMode === 'pro' ? '😊' : '🛠'}
|
||||
|
||||
Reference in New Issue
Block a user