/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
import { zodResolver } from '@hookform/resolvers/zod'
import { useEffect } from 'react'
import { useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import * as z from 'zod'
import { Dialog } from '@/components/dialog'
import { ReactIconByName } from '@/components/react-icon-by-name'
import { Button } from '@/components/ui/button'
import { Combobox } from '@/components/ui/combobox'
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 type key is required')),
icon: z.string().optional(),
min_topup: z.string().optional(),
})
type PaymentMethodDialogFormValues = z.infer<
ReturnType
>
const PAYMENT_METHOD_FORM_ID = 'payment-method-form'
export type PaymentMethodData = {
name: string
type: string
icon?: string
min_topup?: string
color?: string
}
type PaymentMethodDialogProps = {
open: boolean
onOpenChange: (open: boolean) => void
onSave: (data: PaymentMethodData) => void
editData?: PaymentMethodData | null
}
const PAYMENT_TYPE_ICON_NAMES: Record = {
alipay: 'SiAlipay',
stripe: 'SiStripe',
waffo_pancake: 'LuCreditCard',
wxpay: 'SiWechat',
}
const getDefaultIconName = (type: string) => PAYMENT_TYPE_ICON_NAMES[type] ?? ''
export function PaymentMethodDialog({
open,
onOpenChange,
onSave,
editData,
}: PaymentMethodDialogProps) {
const { t } = useTranslation()
const isEditMode = !!editData
const paymentMethodDialogSchema = createPaymentMethodDialogSchema(t)
const paymentTypeOptions = [
{
iconName: 'SiAlipay',
label: `${t('Alipay')} (Epay: alipay)`,
name: t('Alipay'),
value: 'alipay',
},
{
iconName: 'SiWechat',
label: `${t('WeChat Pay')} (Epay: wxpay)`,
name: t('WeChat Pay'),
value: 'wxpay',
},
{
iconName: 'SiStripe',
label: `${t('Stripe')} (stripe)`,
name: t('Stripe'),
value: 'stripe',
},
{
iconName: 'LuCreditCard',
label: 'Waffo Pancake (waffo_pancake)',
name: 'Waffo Pancake',
value: 'waffo_pancake',
},
]
const getPaymentTypeOption = (value: string) =>
paymentTypeOptions.find((option) => option.value === value)
const form = useForm({
resolver: zodResolver(paymentMethodDialogSchema),
defaultValues: {
name: '',
type: '',
icon: '',
min_topup: '',
},
})
const iconValue = form.watch('icon')
useEffect(() => {
if (editData) {
form.reset({
name: editData.name,
type: editData.type,
icon: editData.icon ?? getDefaultIconName(editData.type),
min_topup: editData.min_topup ?? '',
})
} else {
form.reset({
name: '',
type: '',
icon: '',
min_topup: '',
})
}
}, [editData, form, open])
const handleSubmit = (values: PaymentMethodDialogFormValues) => {
const data: PaymentMethodData = {
name: values.name,
type: values.type,
}
if (values.icon && values.icon.trim() !== '') {
data.icon = values.icon.trim()
}
if (values.min_topup && values.min_topup.trim() !== '') {
data.min_topup = values.min_topup
}
onSave(data)
form.reset()
onOpenChange(false)
}
return (
)
}