feat(i18n): migrate hardcoded German strings to t() across 104 components/pages — AST-based batch with re-parse gate, 423 new de.json keys; tsc clean; vitest failures byte-identical to clean-tree baseline (pre-existing)

This commit is contained in:
Agent Zero
2026-08-27 01:43:06 +02:00
parent 5680179260
commit 4cb5298768
105 changed files with 1204 additions and 459 deletions
@@ -8,12 +8,14 @@ import VideoBlock from './VideoBlock';
import FileBlock from './FileBlock';
import { getBlockComponent } from './registry';
import './registrations'; // plugin-contributed block registrations
import { useTranslation } from 'react-i18next';
interface BlockRendererProps {
blocks: MessageBlock[];
}
const BlockRenderer: React.FC<BlockRendererProps> = ({ blocks }) => {
const { t } = useTranslation();
if (!blocks || blocks.length === 0) {
return null;
}
@@ -55,7 +57,7 @@ const BlockRenderer: React.FC<BlockRendererProps> = ({ blocks }) => {
// Fallback for unknown block types
return (
<div className="text-xs text-secondary-400 italic p-2 rounded bg-secondary-50">
Unbekannter Block-Typ: {block.block_type}
{t('blockRenderer.unbekannterblocktyp')} {block.block_type}
</div>
);
}
@@ -1,12 +1,14 @@
import React from 'react';
import type { MessageBlock } from '@/store/commStore';
import { ChevronRight } from 'lucide-react';
import { useTranslation } from 'react-i18next';
interface ContactCardBlockProps {
block: MessageBlock;
}
const ContactCardBlock: React.FC<ContactCardBlockProps> = ({ block }) => {
const { t } = useTranslation();
const { contact_id, name } = block.block_data;
const contactName: string = name || 'Unbekannter Kontakt';
@@ -30,7 +32,7 @@ const ContactCardBlock: React.FC<ContactCardBlockProps> = ({ block }) => {
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-secondary-700 truncate">{contactName}</p>
<p className="text-xs text-secondary-400">Kontakt anzeigen</p>
<p className="text-xs text-secondary-400">{t('contactCardBlock.kontaktanzeigen')}</p>
</div>
<ChevronRight className="w-4 h-4 text-secondary-400 flex-shrink-0" aria-hidden="true" strokeWidth={2} />
</a>
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import type { MessageBlock } from '@/store/commStore';
import { AppWindow, Loader2 } from 'lucide-react';
import { apiClient } from '@/api/client';
import { useTranslation } from 'react-i18next';
interface MiniAppBlockProps {
block: MessageBlock;
@@ -17,6 +18,7 @@ interface MiniAppDef {
}
const MiniAppBlock: React.FC<MiniAppBlockProps> = ({ block }) => {
const { t } = useTranslation();
const { app_id, config } = block.block_data;
const [appDef, setAppDef] = useState<MiniAppDef | null>(null);
const [loading, setLoading] = useState(false);
@@ -88,7 +90,7 @@ const MiniAppBlock: React.FC<MiniAppBlockProps> = ({ block }) => {
)}
{!hasConfig && !hasSchema && (
<p className="text-xs text-secondary-400 text-center py-2">Keine Konfiguration</p>
<p className="text-xs text-secondary-400 text-center py-2">{t('miniAppBlock.keinekonfiguration')}</p>
)}
</div>
);