refactor(ui): pass the member id into the team member reset dialogs as an element

Escaping the id still let Trans fill in placeholders like {{budget}} written inside it a second time. Rendering the id through its own component keeps it out of the translated string, so any id shows exactly as it did before the move to i18n
This commit is contained in:
Yuneng Jiang 2026-10-31 12:57:15 -07:00
parent cf7b869763
commit d6398e3274
No known key found for this signature in database
2 changed files with 11 additions and 17 deletions

View file

@ -26,7 +26,7 @@ const BUDGET_SOURCE_LABEL_KEYS: Record<Exclude<TeamMemberBudgetSource, "none">,
custom: "teams.memberTab.budgetSource.custom",
};
const ESCAPED_VALUES = { interpolation: { escapeValue: true } } as const;
const MemberName = ({ name }: { name: string | null | undefined }) => <strong>{name}</strong>;
const formatBudget = (t: TFunction, value: number | null): string =>
value === null ? t("teams.memberTab.unlimited") : `$${formatNumberWithCommas(value, 2)}`;
@ -372,10 +372,10 @@ export default function TeamMemberTab({
<p>
<Trans
i18nKey="teams.memberTab.resetSpendDialog.prompt"
values={{ member: memberToResetSpend?.user_email || memberToResetSpend?.user_id }}
components={{ strong: <strong /> }}
tOptions={ESCAPED_VALUES}
shouldUnescape
components={{
strong: <strong />,
member: <MemberName name={memberToResetSpend?.user_email || memberToResetSpend?.user_id} />,
}}
/>
</p>
<p className="text-sm text-muted-foreground">
@ -390,8 +390,6 @@ export default function TeamMemberTab({
amount: formatNumberWithCommas(getUserCurrentPeriodSpend(memberToResetSpend?.user_id ?? null), 4),
}}
components={{ strong: <strong /> }}
tOptions={ESCAPED_VALUES}
shouldUnescape
/>
</p>
<DialogFooter>
@ -412,13 +410,11 @@ export default function TeamMemberTab({
<p>
<Trans
i18nKey="teams.memberTab.resetBudgetDialog.prompt"
values={{
member: memberToResetBudget?.user_email || memberToResetBudget?.user_id,
budget: formatBudget(t, teamDefaultBudget),
values={{ budget: formatBudget(t, teamDefaultBudget) }}
components={{
strong: <strong />,
member: <MemberName name={memberToResetBudget?.user_email || memberToResetBudget?.user_id} />,
}}
components={{ strong: <strong /> }}
tOptions={ESCAPED_VALUES}
shouldUnescape
/>
</p>
<p className="text-sm text-muted-foreground">
@ -426,8 +422,6 @@ export default function TeamMemberTab({
i18nKey="teams.memberTab.resetBudgetDialog.summary"
values={{ budget: formatBudget(t, getUserBudget(memberToResetBudget?.user_id ?? null)) }}
components={{ strong: <strong /> }}
tOptions={ESCAPED_VALUES}
shouldUnescape
/>
</p>
<DialogFooter>

View file

@ -1605,7 +1605,7 @@
},
"resetSpendDialog": {
"title": "Reset Team Member Spend",
"prompt": "Reset current period spend for <strong>{{member}}</strong> in this team to <strong>$0</strong>?",
"prompt": "Reset current period spend for <member /> in this team to <strong>$0</strong>?",
"summary": "Current period spend: <strong>${{amount}}</strong>. This is the value checked against the member's budget. Total spend and logs are preserved.",
"summaryWithPeriod": "Current period spend ({{period}}): <strong>${{amount}}</strong>. This is the value checked against the member's budget. Total spend and logs are preserved.",
"cancel": "Cancel",
@ -1613,7 +1613,7 @@
},
"resetBudgetDialog": {
"title": "Reset Team Member Budget",
"prompt": "Remove the custom budget for <strong>{{member}}</strong> and put them back on the team default of <strong>{{budget}}</strong>?",
"prompt": "Remove the custom budget for <member /> and put them back on the team default of <strong>{{budget}}</strong>?",
"summary": "Custom budget: <strong>{{budget}}</strong>. Their spend is kept. Future changes to the team's member budget will apply to them again.",
"cancel": "Cancel",
"confirm": "Use team default"