copy dmenu-admin to dkala-admin

This commit is contained in:
hamid zarghami
2026-02-07 16:20:18 +03:30
commit 6b9e808bfd
292 changed files with 27167 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
import { type FC, useState, useMemo } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { TickCircle } from 'iconsax-react'
import { toast } from 'react-toastify'
import { useNavigate } from 'react-router-dom'
import Button from '@/components/Button'
import type { CreateCouponType } from './types/Types'
import { useCreateCoupon } from './hooks/useCouponData'
import { useGetCategories } from '@/pages/food/hooks/useFoodData'
import { useGetFoods } from '@/pages/food/hooks/useFoodData'
import { Pages } from '@/config/Pages'
import type { ErrorType } from '@/helpers/types'
import { extractErrorMessage } from '@/config/func'
import CouponBasicInfo from './components/CouponBasicInfo'
import CouponDiscountSettings from './components/CouponDiscountSettings'
import CouponUsageSettings from './components/CouponUsageSettings'
import CouponSidebar from './components/CouponSidebar'
const CreateCoupon: FC = () => {
const navigate = useNavigate()
const { mutate: createCoupon, isPending: isCreating } = useCreateCoupon()
const { data: categoriesData } = useGetCategories()
const { data: foodsData } = useGetFoods()
const [couponType, setCouponType] = useState<'PERCENTAGE' | 'FIXED'>('PERCENTAGE')
const categories = useMemo(() => categoriesData?.data || [], [categoriesData?.data])
const foods = useMemo(() => foodsData?.data || [], [foodsData?.data])
const formik = useFormik<CreateCouponType>({
initialValues: {
code: '',
name: '',
description: '',
value: 0,
maxDiscount: null,
minOrderAmount: 0,
maxUses: 0,
maxUsesPerUser: null,
startDate: null,
endDate: null,
isActive: true,
foodCategories: [],
foods: [],
userPhone: '',
type: 'PERCENTAGE',
},
validationSchema: Yup.object().shape({
type: Yup.string().required('نوع کوپن الزامی است'),
code: Yup.string().required('کد کوپن الزامی است'),
name: Yup.string().required('نام کوپن الزامی است'),
description: Yup.string(),
value: Yup.number().min(0, 'مقدار باید بیشتر از صفر باشد').required('مقدار کوپن الزامی است'),
maxDiscount: Yup.number().nullable().min(0, 'حداکثر تخفیف باید بیشتر از صفر باشد'),
minOrderAmount: Yup.number().min(0, 'حداقل مبلغ سفارش باید بیشتر از صفر باشد').required('حداقل مبلغ سفارش الزامی است'),
maxUses: Yup.number().min(0, 'حداکثر استفاده باید بیشتر از صفر باشد').required('حداکثر استفاده الزامی است'),
maxUsesPerUser: Yup.number().nullable().min(0, 'حداکثر استفاده برای هر کاربر باید بیشتر از صفر باشد'),
startDate: Yup.string().nullable(),
endDate: Yup.string().nullable(),
userPhone: Yup.string().nullable(),
}),
onSubmit: (values) => {
const submitValues = {
...values,
userPhone: values.userPhone?.trim() || undefined,
}
createCoupon(submitValues, {
onSuccess: () => {
toast.success('کوپن با موفقیت ایجاد شد')
navigate(Pages.coupons.list)
},
onError: (error: ErrorType) => {
toast.error(extractErrorMessage(error))
},
})
},
})
return (
<div className='mt-5'>
<div className='flex justify-between items-center mb-6'>
<h1 className='text-lg font-light'>کد تخفیف جدید</h1>
</div>
<div className='flex justify-end'>
<Button
className='flex gap-4 w-full sm:w-fit px-5'
isloading={isCreating}
onClick={() => formik.handleSubmit()}
>
<div className='flex gap-2 items-center'>
<TickCircle color='white' size={20} className='ml-2' />
<span>ثبت تخفیف</span>
</div>
</Button>
</div>
<div className='flex flex-col lg:flex-row gap-7 mt-7'>
<div className='flex-1'>
<div className='bg-white rounded-4xl p-4 sm:p-6 lg:p-8'>
<div className='text-lg font-light mb-6'>کد تخفیف جدید</div>
<CouponBasicInfo
formik={formik}
/>
<CouponDiscountSettings
formik={formik}
couponType={couponType}
onCouponTypeChange={setCouponType}
/>
<CouponUsageSettings formik={formik} />
</div>
</div>
<div className='w-full lg:w-80 flex-shrink-0'>
<CouponSidebar
formik={formik}
categories={categories}
foods={foods}
/>
</div>
</div>
</div>
)
}
export default CreateCoupon