refactor(web): streamline pricing table rendering

- reuse translated endpoint select options between trigger data and menu items.
- precompute dynamic pricing maps per group so table cells only resolve formatted values.
- add local dynamic pricing type aliases to keep helper signatures readable.
This commit is contained in:
QuentinHsu
2026-06-10 08:30:44 +08:00
parent e6f910e329
commit 9190895708
2 changed files with 41 additions and 27 deletions
@@ -219,6 +219,14 @@ export function ChannelTestDialog({
pageIndex: 0,
pageSize: 10,
})
const endpointSelectItems = useMemo(
() =>
endpointTypeOptions.map((option) => ({
value: option.value,
label: t(option.label),
})),
[t]
)
const resetState = useCallback(() => {
setEndpointType('auto')
@@ -539,10 +547,7 @@ export function ChannelTestDialog({
<div className='grid gap-2'>
<Label htmlFor='endpoint-type'>{t('Endpoint Type')}</Label>
<Select
items={endpointTypeOptions.map((option) => ({
value: option.value,
label: t(option.label),
}))}
items={endpointSelectItems}
value={endpointType}
onValueChange={(v) => v !== null && setEndpointType(v)}
>
@@ -551,14 +556,11 @@ export function ChannelTestDialog({
</SelectTrigger>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{endpointTypeOptions.map((option) => {
const itemValue = option.value
return (
<SelectItem key={itemValue} value={itemValue}>
{t(option.label)}
</SelectItem>
)
})}
{endpointSelectItems.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
+27 -15
View File
@@ -577,9 +577,13 @@ function AutoGroupChain(props: { model: PricingModel; autoGroups: string[] }) {
)
}
type DynamicPriceOptions = Parameters<typeof getDynamicPriceEntries>[1]
type DynamicPricingTier = ReturnType<typeof getDynamicPricingTiers>[number]
type DynamicFormattedPricesByTier = Map<DynamicPricingTier, Map<string, string>>
function getDynamicPriceFields(
tiers: ReturnType<typeof getDynamicPricingTiers>,
options: Parameters<typeof getDynamicPriceEntries>[1]
tiers: DynamicPricingTier[],
options: DynamicPriceOptions
) {
return Array.from(
new Map(
@@ -591,9 +595,9 @@ function getDynamicPriceFields(
}
function getDynamicFormattedPricesByTier(
tiers: ReturnType<typeof getDynamicPricingTiers>,
options: Parameters<typeof getDynamicPriceEntries>[1]
) {
tiers: DynamicPricingTier[],
options: DynamicPriceOptions
): DynamicFormattedPricesByTier {
return new Map(
tiers.map((tier) => [
tier,
@@ -704,6 +708,21 @@ function GroupPricingSection(props: {
usdExchangeRate: props.usdExchangeRate,
groupRatioMultiplier: 1,
})
const formattedPricesByGroup = new Map(
availableGroups.map((group) => {
const ratio = props.groupRatio[group] || 1
return [
group,
getDynamicFormattedPricesByTier(dynamicTiers, {
tokenUnit: props.tokenUnit,
showRechargePrice,
priceRate: props.priceRate,
usdExchangeRate: props.usdExchangeRate,
groupRatioMultiplier: ratio,
}),
] as const
})
)
return (
<section>
@@ -712,16 +731,9 @@ function GroupPricingSection(props: {
<div className='space-y-3'>
{availableGroups.map((group) => {
const ratio = props.groupRatio[group] || 1
const formattedPricesByTier = getDynamicFormattedPricesByTier(
dynamicTiers,
{
tokenUnit: props.tokenUnit,
showRechargePrice,
priceRate: props.priceRate,
usdExchangeRate: props.usdExchangeRate,
groupRatioMultiplier: ratio,
}
)
const formattedPricesByTier =
formattedPricesByGroup.get(group) ??
new Map<DynamicPricingTier, Map<string, string>>()
return (
<div key={group} className='overflow-hidden rounded-lg border'>