import { useEffect, useMemo } from 'react' import * as z from 'zod' import { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' import { Combobox } from '@/components/ui/combobox' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form' import { Input } from '@/components/ui/input' const createPaymentMethodDialogSchema = (t: (key: string) => string) => z.object({ name: z.string().min(1, t('Payment method name is required')), type: z.string().min(1, t('Payment method type is required')), color: z.string().min(1, t('Color is required')), min_topup: z.string().optional(), }) type PaymentMethodDialogFormValues = z.infer< ReturnType > export type PaymentMethodData = { name: string type: string color: string min_topup?: string } type PaymentMethodDialogProps = { open: boolean onOpenChange: (open: boolean) => void onSave: (data: PaymentMethodData) => void editData?: PaymentMethodData | null } const PAYMENT_TYPES = [ { value: 'alipay', label: 'Alipay' }, { value: 'wxpay', label: 'WeChat Pay' }, { value: 'stripe', label: 'Stripe' }, ] const getColorPreview = (color: string) => { if (color.includes('var(--')) { return null } return color } const COLOR_PRESETS = [ { value: '#1677FF', label: 'Blue (Alipay)' }, { value: '#07C160', label: 'Green (WeChat)' }, { value: '#635BFF', label: 'Purple (Stripe)' }, { value: '#1890FF', label: 'Sky Blue' }, { value: '#52C41A', label: 'Lime Green' }, { value: 'black', label: 'Black' }, { value: '#FF4D4F', label: 'Red' }, { value: '#FFA940', label: 'Orange' }, ].map((preset) => { const previewColor = getColorPreview(preset.value) return { ...preset, icon: previewColor ? (
) : (
), } }) export function PaymentMethodDialog({ open, onOpenChange, onSave, editData, }: PaymentMethodDialogProps) { const { t } = useTranslation() const isEditMode = !!editData const paymentMethodDialogSchema = createPaymentMethodDialogSchema(t) const form = useForm({ resolver: zodResolver(paymentMethodDialogSchema), defaultValues: { name: '', type: '', color: '', min_topup: '', }, }) const colorValue = form.watch('color') const colorPreview = useMemo(() => { if (!colorValue) return null try { // For CSS variables like rgba(var(--semi-blue-5), 1), we can't preview accurately // but we can detect common patterns if (colorValue.includes('var(--')) { return null // Can't preview CSS variables reliably } return colorValue } catch { return null } }, [colorValue]) useEffect(() => { if (editData) { form.reset(editData) } else { form.reset({ name: '', type: '', color: '', min_topup: '', }) } }, [editData, form, open]) const handleSubmit = (values: PaymentMethodDialogFormValues) => { const data: PaymentMethodData = { name: values.name, type: values.type, color: values.color, } if (values.min_topup && values.min_topup.trim() !== '') { data.min_topup = values.min_topup } onSave(data) form.reset() onOpenChange(false) } return ( {isEditMode ? t('Edit payment method') : t('Add payment method')} {t('Configure a payment method for user recharge options.')}
( {t('Name')} {t('Display name for this payment method.')} )} /> ( {t('Type')} {t('Select from presets or type custom identifier.')} )} /> ( {t('Color')}
{colorPreview && (
)}
{t('Select preset or enter custom CSS color value.')} )} /> ( {t('Minimum top-up (optional)')} {t('Optional minimum recharge amount for this method.')} )} />
) }