Files
dkala-admin/src/pages/coupon/Update.tsx
T
2026-02-07 16:20:18 +03:30

178 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { type FC, useState, useMemo, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { TickCircle } from 'iconsax-react'
import { toast } from 'react-toastify'
import Button from '@/components/Button'
import type { CreateCouponType } from './types/Types'
import { useGetCouponDetails, useUpdateCoupon } 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 UpdateCoupon: FC = () => {
const navigate = useNavigate()
const { id } = useParams<{ id: string }>()
const { data: couponData, isLoading } = useGetCouponDetails(id || '')
const { mutate: updateCoupon, isPending: isUpdating } = useUpdateCoupon()
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(),
}),
enableReinitialize: true,
onSubmit: (values) => {
if (!id) {
toast.error('شناسه کوپن یافت نشد')
return
}
const submitValues = {
...values,
userPhone: values.userPhone?.trim() || undefined,
}
updateCoupon(
{ id, params: submitValues },
{
onSuccess: () => {
toast.success('کوپن با موفقیت به‌روزرسانی شد')
navigate(Pages.coupons.list)
},
onError: (error: ErrorType) => {
toast.error(extractErrorMessage(error))
},
}
)
},
})
useEffect(() => {
if (couponData?.data) {
const coupon = couponData.data
setCouponType(coupon.type)
formik.setValues({
code: coupon.code,
name: coupon.name,
description: coupon.description || '',
value: coupon.value,
maxDiscount: coupon.maxDiscount,
minOrderAmount: coupon.minOrderAmount,
maxUses: coupon.maxUses,
maxUsesPerUser: coupon.maxUsesPerUser,
startDate: coupon.startDate,
endDate: coupon.endDate,
isActive: coupon.isActive,
foodCategories: coupon.foodCategories || [],
foods: coupon.foods || [],
userPhone: coupon.userPhone || '',
type: coupon.type,
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [couponData?.data])
if (isLoading) {
return (
<div className='mt-5'>
<div className='text-center'>در حال بارگذاری...</div>
</div>
)
}
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={isUpdating}
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}
/>
{
formik.values.startDate && (
<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 UpdateCoupon