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:
@@ -9,6 +9,7 @@ import { Select } from '@/components/ui/Select';
|
||||
import { Badge } from '@/components/ui/Badge';
|
||||
import { X } from 'lucide-react';
|
||||
import type { CustomFieldDefinition } from '@/api/customFieldDefinitions';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface CustomFieldRendererProps {
|
||||
definition: CustomFieldDefinition;
|
||||
@@ -17,6 +18,7 @@ export interface CustomFieldRendererProps {
|
||||
}
|
||||
|
||||
export function CustomFieldRenderer({ definition, value, onChange }: CustomFieldRendererProps) {
|
||||
const { t } = useTranslation();
|
||||
const generatedId = useId();
|
||||
const fieldId = `cf-${definition.id || generatedId}`;
|
||||
const { field_type, options, required } = definition;
|
||||
@@ -39,7 +41,7 @@ export function CustomFieldRenderer({ definition, value, onChange }: CustomField
|
||||
/>
|
||||
<span>
|
||||
{definition.label}
|
||||
{required && <span className="text-danger-500 ml-1" aria-label="required">*</span>}
|
||||
{required && <span className="text-danger-500 ml-1" aria-label={t('customFieldRenderer.required')}>*</span>}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
@@ -73,7 +75,7 @@ export function CustomFieldRenderer({ definition, value, onChange }: CustomField
|
||||
<div className="w-full">
|
||||
<label className="block text-sm font-medium text-secondary-700 mb-1">
|
||||
{definition.label}
|
||||
{required && <span className="text-danger-500 ml-1" aria-label="required">*</span>}
|
||||
{required && <span className="text-danger-500 ml-1" aria-label={t('customFieldRenderer.required')}>*</span>}
|
||||
</label>
|
||||
{selectedValues.length > 0 && (
|
||||
<div className="flex flex-wrap gap-1.5 mb-2">
|
||||
@@ -106,9 +108,9 @@ export function CustomFieldRenderer({ definition, value, onChange }: CustomField
|
||||
))}
|
||||
</div>
|
||||
) : availableOptions.length === 0 ? (
|
||||
<p className="text-sm text-secondary-400">Keine Optionen verfügbar</p>
|
||||
<p className="text-sm text-secondary-400">{t('customFieldRenderer.keineoptionenverfügbar')}</p>
|
||||
) : (
|
||||
<p className="text-sm text-secondary-400">Alle Optionen ausgewählt</p>
|
||||
<p className="text-sm text-secondary-400">{t('customFieldRenderer.alleoptionenausgewählt')}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@@ -123,7 +125,7 @@ export function CustomFieldRenderer({ definition, value, onChange }: CustomField
|
||||
label={definition.label}
|
||||
required={required}
|
||||
options={selectOptions}
|
||||
placeholder="— Bitte wählen —"
|
||||
placeholder={t('customFieldRenderer.bittewählen')}
|
||||
value={value ?? ''}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user