feat(34-06): wire useTranslation into 10 remaining components

- ThreadTabs: tab labels (gear, planning, setups) via collection namespace
- PlanningView: section title, tab labels, empty state steps, CTAs via threads namespace
- TotalsBar: 'Sign in' link via common.auth.signIn
- ThreadCard: resolved badge and candidate count (plural) via threads namespace
- PublicSetupCard: by/anonymous and item count (plural) via setups namespace
- SetupImpactSelector: compare dropdown placeholder via setups.impact.compareWith
- ClassificationBadge: base/worn/consumable labels via collection.classificationBadge
- ImpactDeltaBadge: add mode label via setups.impact.adding
- ImageUpload: click-to-add, error messages via common.imageUpload
- DashboardCard: skipped (renders props only, no hardcoded UI strings)
- Add card, planning keys to en/de threads.json
- Add classificationBadge, tabs, totals keys to en/de collection.json
- Add card.by, card.anonymous, impact.compareWith to en/de setups.json
- Add imageUpload keys to en/de common.json
- Build passes, all 19 i18n parity tests pass
This commit is contained in:
2026-04-17 20:26:50 +02:00
parent 755c0ab89f
commit 480abdd17f
17 changed files with 133 additions and 44 deletions

View File

@@ -1,8 +1,4 @@
const CLASSIFICATION_LABELS: Record<string, string> = {
base: "Base Weight",
worn: "Worn",
consumable: "Consumable",
};
import { useTranslation } from "react-i18next";
interface ClassificationBadgeProps {
classification: string;
@@ -13,7 +9,10 @@ export function ClassificationBadge({
classification,
onCycle,
}: ClassificationBadgeProps) {
const label = CLASSIFICATION_LABELS[classification] ?? "Base Weight";
const { t } = useTranslation("collection");
const label = t(`classificationBadge.${classification}`, {
defaultValue: t("classificationBadge.base"),
});
return (
<button