fix(default): correct subscription payment display
Some checks failed
Publish Docker image (Multi-arch) / Build & push (amd64) (push) Has been cancelled
Publish Docker image (Multi-arch) / Build & push (arm64) (push) Has been cancelled
Publish Docker image (Multi-arch) / Create multi-arch manifests (push) Has been cancelled
Release (Linux, macOS, Windows) / Linux Release (push) Has been cancelled
Release (Linux, macOS, Windows) / macOS Release (push) Has been cancelled
Release (Linux, macOS, Windows) / Windows Release (push) Has been cancelled

This commit is contained in:
CaIon 2026-05-06 18:38:02 +08:00
parent dc8deb0c24
commit 446a8420f5
No known key found for this signature in database
GPG Key ID: 0CFA613529A9921D
3 changed files with 39 additions and 16 deletions

View File

@ -65,6 +65,11 @@ export function SubscriptionPurchaseDialog(props: Props) {
const hasEpay =
props.enableOnlineTopUp && (props.epayMethods || []).length > 0
const hasAnyPayment = hasStripe || hasCreem || hasEpay
const selectedEpayMethodLabel =
(props.epayMethods || []).find((m) => m.type === selectedEpayMethod)
?.name ||
selectedEpayMethod ||
t('Select payment method')
const totalAmount = Number(plan.total_amount || 0)
const price = Number(plan.price_amount || 0).toFixed(2)
const limitReached =
@ -272,7 +277,7 @@ export function SubscriptionPurchaseDialog(props: Props) {
disabled={limitReached}
>
<SelectTrigger className='flex-1'>
<SelectValue placeholder={t('Select payment method')} />
<SelectValue>{selectedEpayMethodLabel}</SelectValue>
</SelectTrigger>
<SelectContent>
{(props.epayMethods || []).map((m) => (

View File

@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { formatQuota } from '@/lib/format'
import { cn } from '@/lib/utils'
import { useStatus } from '@/hooks/use-status'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader } from '@/components/ui/card'
import { Progress } from '@/components/ui/progress'
@ -52,12 +51,29 @@ function getEpayMethods(payMethods: PaymentMethod[] = []): PaymentMethod[] {
)
}
function getBillingPreferenceLabel(
preference: string,
t: (key: string) => string
): string {
switch (preference) {
case 'subscription_first':
return t('Subscription First')
case 'wallet_first':
return t('Wallet First')
case 'subscription_only':
return t('Subscription Only')
case 'wallet_only':
return t('Wallet Only')
default:
return preference
}
}
export function SubscriptionPlansCard({
topupInfo,
onAvailabilityChange,
}: SubscriptionPlansCardProps) {
const { t } = useTranslation()
const { status } = useStatus()
const [plans, setPlans] = useState<PlanRecord[]>([])
const [activeSubscriptions, setActiveSubscriptions] = useState<
@ -74,9 +90,9 @@ export function SubscriptionPlansCard({
const [purchaseOpen, setPurchaseOpen] = useState(false)
const [selectedPlan, setSelectedPlan] = useState<PlanRecord | null>(null)
const enableStripe = !!status?.enable_stripe_topup
const enableStripe = !!topupInfo?.enable_stripe_topup
const enableCreem = !!topupInfo?.enable_creem_topup
const enableOnlineTopUp = !!status?.enable_online_topup
const enableOnlineTopUp = !!topupInfo?.enable_online_topup
const epayMethods = useMemo(
() => getEpayMethods(topupInfo?.pay_methods),
[topupInfo?.pay_methods]
@ -264,22 +280,24 @@ export function SubscriptionPlansCard({
onValueChange={(v) => v !== null && handlePreferenceChange(v)}
>
<SelectTrigger className='h-8 flex-1 text-xs sm:w-[140px] sm:flex-none'>
<SelectValue />
<SelectValue>
{getBillingPreferenceLabel(displayPref, t)}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value='subscription_first' disabled={disablePref}>
{t('Subscription First')}
{getBillingPreferenceLabel('subscription_first', t)}
{disablePref ? ` (${t('No Active')})` : ''}
</SelectItem>
<SelectItem value='wallet_first'>
{t('Wallet First')}
{getBillingPreferenceLabel('wallet_first', t)}
</SelectItem>
<SelectItem value='subscription_only' disabled={disablePref}>
{t('Subscription Only')}
{getBillingPreferenceLabel('subscription_only', t)}
{disablePref ? ` (${t('No Active')})` : ''}
</SelectItem>
<SelectItem value='wallet_only'>
{t('Wallet Only')}
{getBillingPreferenceLabel('wallet_only', t)}
</SelectItem>
</SelectContent>
</Select>

View File

@ -1,4 +1,3 @@
import { formatLocalCurrencyAmount } from '@/lib/currency'
import { DEFAULT_DISCOUNT_RATE } from '../constants'
// ============================================================================
@ -36,11 +35,12 @@ export function formatQuotaShort(quota: number): string {
export function formatCurrency(amount: number | string): string {
const numeric =
typeof amount === 'number' ? amount : Number.parseFloat(String(amount))
return formatLocalCurrencyAmount(Number.isFinite(numeric) ? numeric : null, {
digitsLarge: 2,
digitsSmall: 2,
abbreviate: false,
})
if (!Number.isFinite(numeric)) return '-'
return new Intl.NumberFormat(undefined, {
minimumFractionDigits: 0,
maximumFractionDigits: Math.abs(numeric) >= 1 ? 2 : 4,
}).format(numeric)
}
/**