- 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
30 lines
689 B
TypeScript
30 lines
689 B
TypeScript
import { useTranslation } from "react-i18next";
|
|
|
|
interface ClassificationBadgeProps {
|
|
classification: string;
|
|
onCycle: () => void;
|
|
}
|
|
|
|
export function ClassificationBadge({
|
|
classification,
|
|
onCycle,
|
|
}: ClassificationBadgeProps) {
|
|
const { t } = useTranslation("collection");
|
|
const label = t(`classificationBadge.${classification}`, {
|
|
defaultValue: t("classificationBadge.base"),
|
|
});
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onCycle();
|
|
}}
|
|
className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600 hover:bg-gray-200 transition-colors cursor-pointer"
|
|
>
|
|
{label}
|
|
</button>
|
|
);
|
|
}
|