- 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
43 lines
1000 B
TypeScript
43 lines
1000 B
TypeScript
import { useTranslation } from "react-i18next";
|
|
import type { CandidateDelta } from "../hooks/useImpactDeltas";
|
|
|
|
interface ImpactDeltaBadgeProps {
|
|
delta: CandidateDelta | undefined;
|
|
type: "weight" | "price";
|
|
formatFn: (value: number) => string;
|
|
}
|
|
|
|
export function ImpactDeltaBadge({
|
|
delta,
|
|
type,
|
|
formatFn,
|
|
}: ImpactDeltaBadgeProps) {
|
|
const { t } = useTranslation("setups");
|
|
|
|
if (!delta || delta.mode === "none") return null;
|
|
|
|
const value = type === "weight" ? delta.weightDelta : delta.priceDelta;
|
|
|
|
if (value === null) {
|
|
return <span className="text-xs text-gray-400">—</span>;
|
|
}
|
|
|
|
if (value === 0) {
|
|
return <span className="text-xs text-gray-400">±0</span>;
|
|
}
|
|
|
|
if (value > 0) {
|
|
return (
|
|
<span className="text-xs text-green-600">
|
|
+{formatFn(value)}
|
|
{delta.mode === "add" && (
|
|
<span className="ml-0.5 text-green-500">({t("impact.adding")})</span>
|
|
)}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
// value < 0
|
|
return <span className="text-xs text-red-500">{formatFn(value)}</span>;
|
|
}
|