panel-web/apps/user/components/subscribe/payment-methods.tsx
2025-08-12 05:38:14 -07:00

84 lines
2.6 KiB
TypeScript

'use client';
import { getAvailablePaymentMethods } from '@/services/user/portal';
import { useQuery } from '@tanstack/react-query';
import { Label } from '@workspace/airo-ui/components/label';
import { RadioGroup, RadioGroupItem } from '@workspace/airo-ui/components/radio-group';
import { cn } from '@workspace/airo-ui/lib/utils';
import { useTranslations } from 'next-intl';
import Image from 'next/image';
import React, { memo, useState } from 'react';
interface PaymentMethodsProps {
value: number;
onChange: (value: number) => void;
balance?: boolean;
titleClassName: string;
}
const PaymentMethods: React.FC<PaymentMethodsProps> = ({
value,
onChange,
balance = true,
titleClassName,
}) => {
const t = useTranslations('subscribe');
const [methods, setMethods] = useState({});
const { data } = useQuery({
queryKey: ['getAvailablePaymentMethods', { balance }],
queryFn: async () => {
const { data } = await getAvailablePaymentMethods();
const list = data.data?.list || [];
const methods = balance ? list : list.filter((item) => item.id !== -1);
const defaultMethod = methods.find((item) => item.id);
if (defaultMethod?.id) {
onChange(defaultMethod?.id);
setMethods(defaultMethod);
}
return methods;
},
});
return (
<>
<div className='mb-2 flex items-center font-semibold'>
<span className={titleClassName}>{t('paymentMethod')}</span>
<span className={'ml-4 text-sm font-medium text-[#666]'}>{methods.name}</span>
</div>
<RadioGroup
className='flex flex-wrap gap-2'
value={String(value)}
onValueChange={(item) => {
setMethods(item);
onChange(Number(item.id));
}}
>
{data?.map((item) => (
<div key={item.id} className='relative size-10'>
<RadioGroupItem
value={item}
id={String(item.id)}
className='absolute inset-0 z-10 h-full w-full cursor-pointer opacity-0'
/>
<Label
htmlFor={String(item.id)}
className={cn(
'border-muted bg-popover hover:bg-accent hover:text-accent-foreground flex size-10 flex-col items-center justify-center rounded-md border-2',
String(value) === String(item.id) ? 'border-primary' : '',
)}
>
<Image
src={item.icon || `/payment/balance.svg`}
width={32}
height={32}
alt={item.name}
/>
</Label>
</div>
))}
</RadioGroup>
</>
);
};
export default memo(PaymentMethods);