change create coupon
This commit is contained in:
@@ -23,7 +23,6 @@ const CreateCoupon: FC = () => {
|
||||
const { data: categoriesData } = useGetCategories()
|
||||
const { data: foodsData } = useGetFoods()
|
||||
|
||||
const [discountType, setDiscountType] = useState<'DIRECT' | 'CODE'>('CODE')
|
||||
const [couponType, setCouponType] = useState<'PERCENTAGE' | 'FIXED'>('PERCENTAGE')
|
||||
|
||||
const categories = useMemo(() => categoriesData?.data || [], [categoriesData?.data])
|
||||
@@ -34,7 +33,6 @@ const CreateCoupon: FC = () => {
|
||||
code: '',
|
||||
name: '',
|
||||
description: '',
|
||||
type: 'PERCENTAGE',
|
||||
value: 0,
|
||||
maxDiscount: null,
|
||||
minOrderAmount: 0,
|
||||
@@ -43,14 +41,16 @@ const CreateCoupon: FC = () => {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
isActive: true,
|
||||
categoryIds: [],
|
||||
foodIds: [],
|
||||
foodCategories: [],
|
||||
foods: [],
|
||||
userPhone: '',
|
||||
type: 'PERCENTAGE',
|
||||
},
|
||||
validationSchema: Yup.object().shape({
|
||||
type: Yup.string().required('نوع کوپن الزامی است'),
|
||||
code: Yup.string().required('کد کوپن الزامی است'),
|
||||
name: Yup.string().required('نام کوپن الزامی است'),
|
||||
description: Yup.string(),
|
||||
type: Yup.string().required('نوع کوپن الزامی است'),
|
||||
value: Yup.number().min(0, 'مقدار باید بیشتر از صفر باشد').required('مقدار کوپن الزامی است'),
|
||||
maxDiscount: Yup.number().nullable().min(0, 'حداکثر تخفیف باید بیشتر از صفر باشد'),
|
||||
minOrderAmount: Yup.number().min(0, 'حداقل مبلغ سفارش باید بیشتر از صفر باشد').required('حداقل مبلغ سفارش الزامی است'),
|
||||
@@ -58,9 +58,14 @@ const CreateCoupon: FC = () => {
|
||||
maxUsesPerUser: Yup.number().nullable().min(0, 'حداکثر استفاده برای هر کاربر باید بیشتر از صفر باشد'),
|
||||
startDate: Yup.string().nullable(),
|
||||
endDate: Yup.string().nullable(),
|
||||
userPhone: Yup.string().nullable(),
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
createCoupon(values, {
|
||||
const submitValues = {
|
||||
...values,
|
||||
userPhone: values.userPhone?.trim() || undefined,
|
||||
}
|
||||
createCoupon(submitValues, {
|
||||
onSuccess: () => {
|
||||
toast.success('کوپن با موفقیت ایجاد شد')
|
||||
navigate(Pages.coupons.list)
|
||||
@@ -98,8 +103,6 @@ const CreateCoupon: FC = () => {
|
||||
|
||||
<CouponBasicInfo
|
||||
formik={formik}
|
||||
discountType={discountType}
|
||||
onDiscountTypeChange={setDiscountType}
|
||||
/>
|
||||
|
||||
<CouponDiscountSettings
|
||||
|
||||
@@ -25,26 +25,26 @@ const CategorySelector: FC<CategorySelectorProps> = ({ formik, categories }) =>
|
||||
}, [categories, search])
|
||||
|
||||
const handleToggle = (categoryId: string, checked: boolean) => {
|
||||
const currentIds = formik.values.categoryIds || []
|
||||
const currentIds = formik.values.foodCategories || []
|
||||
if (checked) {
|
||||
formik.setFieldValue('categoryIds', [...currentIds, categoryId])
|
||||
formik.setFieldValue('foodCategories', [...currentIds, categoryId])
|
||||
} else {
|
||||
formik.setFieldValue('categoryIds', currentIds.filter((id) => id !== categoryId))
|
||||
formik.setFieldValue('foodCategories', currentIds.filter((id) => id !== categoryId))
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectAll = (checked: boolean) => {
|
||||
if (checked) {
|
||||
formik.setFieldValue('categoryIds', filteredCategories.map((cat) => cat.id))
|
||||
formik.setFieldValue('foodCategories', filteredCategories.map((cat) => cat.id))
|
||||
} else {
|
||||
formik.setFieldValue('categoryIds', [])
|
||||
formik.setFieldValue('foodCategories', [])
|
||||
}
|
||||
}
|
||||
|
||||
const isAllSelected = useMemo(() => {
|
||||
return filteredCategories.length > 0 &&
|
||||
filteredCategories.every((cat) => formik.values.categoryIds?.includes(cat.id))
|
||||
}, [filteredCategories, formik.values.categoryIds])
|
||||
filteredCategories.every((cat) => formik.values.foodCategories?.includes(cat.id))
|
||||
}, [filteredCategories, formik.values.foodCategories])
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -68,7 +68,7 @@ const CategorySelector: FC<CategorySelectorProps> = ({ formik, categories }) =>
|
||||
{filteredCategories.map((category) => (
|
||||
<div key={category.id} className='flex items-center gap-2'>
|
||||
<Checkbox
|
||||
checked={formik.values.categoryIds?.includes(category.id) || false}
|
||||
checked={formik.values.foodCategories?.includes(category.id) || false}
|
||||
onCheckedChange={(checked) =>
|
||||
handleToggle(category.id, checked as boolean)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Refresh } from 'iconsax-react'
|
||||
import type { FormikProps } from 'formik'
|
||||
import Input from '@/components/Input'
|
||||
import Textarea from '@/components/Textarea'
|
||||
import RadioGroup from '@/components/RadioGroup'
|
||||
import Button from '@/components/Button'
|
||||
import type { CreateCouponType } from '../types/Types'
|
||||
import { useGenerateCouponCode } from '../hooks/useCouponData'
|
||||
@@ -12,14 +11,10 @@ import { toast } from 'react-toastify'
|
||||
|
||||
interface CouponBasicInfoProps {
|
||||
formik: FormikProps<CreateCouponType>
|
||||
discountType: 'DIRECT' | 'CODE'
|
||||
onDiscountTypeChange: (value: 'DIRECT' | 'CODE') => void
|
||||
}
|
||||
|
||||
const CouponBasicInfo: FC<CouponBasicInfoProps> = ({
|
||||
formik,
|
||||
discountType,
|
||||
onDiscountTypeChange,
|
||||
}) => {
|
||||
|
||||
const { mutate: generateCouponCode, isPending: isGenerating } = useGenerateCouponCode()
|
||||
@@ -38,18 +33,6 @@ const CouponBasicInfo: FC<CouponBasicInfoProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='mb-6'>
|
||||
<div className='text-sm mb-3'>نوع تخفیف</div>
|
||||
<RadioGroup
|
||||
items={[
|
||||
{ label: 'تخفیف مستقیم', value: 'DIRECT' },
|
||||
{ label: 'کد تخفیف', value: 'CODE' },
|
||||
]}
|
||||
selected={discountType}
|
||||
onChange={(value) => onDiscountTypeChange(value as 'DIRECT' | 'CODE')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='mb-6'>
|
||||
<div className='flex items-end gap-2'>
|
||||
<div className='flex-1'>
|
||||
|
||||
@@ -42,7 +42,7 @@ const CouponUsageSettings: FC<CouponUsageSettingsProps> = ({ formik }) => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='grid grid-cols-2 gap-4'>
|
||||
<div className='grid grid-cols-2 gap-4 mb-6'>
|
||||
<DatePickerComponent
|
||||
label='تاریخ شروع'
|
||||
placeholder='تاریخ شروع را انتخاب کنید'
|
||||
@@ -60,6 +60,21 @@ const CouponUsageSettings: FC<CouponUsageSettingsProps> = ({ formik }) => {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='mb-6'>
|
||||
<Input
|
||||
label='شماره تلفن کاربر (اختیاری)'
|
||||
placeholder='09123456789'
|
||||
name='userPhone'
|
||||
type='tel'
|
||||
value={formik.values.userPhone || ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value.trim()
|
||||
formik.setFieldValue('userPhone', value || undefined)
|
||||
}}
|
||||
error_text={formik.touched.userPhone && formik.errors.userPhone ? formik.errors.userPhone : ''}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -25,26 +25,26 @@ const FoodSelector: FC<FoodSelectorProps> = ({ formik, foods }) => {
|
||||
}, [foods, search])
|
||||
|
||||
const handleToggle = (foodId: string, checked: boolean) => {
|
||||
const currentIds = formik.values.foodIds || []
|
||||
const currentIds = formik.values.foods || []
|
||||
if (checked) {
|
||||
formik.setFieldValue('foodIds', [...currentIds, foodId])
|
||||
formik.setFieldValue('foods', [...currentIds, foodId])
|
||||
} else {
|
||||
formik.setFieldValue('foodIds', currentIds.filter((id) => id !== foodId))
|
||||
formik.setFieldValue('foods', currentIds.filter((id) => id !== foodId))
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectAll = (checked: boolean) => {
|
||||
if (checked) {
|
||||
formik.setFieldValue('foodIds', filteredFoods.map((food) => food.id))
|
||||
formik.setFieldValue('foods', filteredFoods.map((food) => food.id))
|
||||
} else {
|
||||
formik.setFieldValue('foodIds', [])
|
||||
formik.setFieldValue('foods', [])
|
||||
}
|
||||
}
|
||||
|
||||
const isAllSelected = useMemo(() => {
|
||||
return filteredFoods.length > 0 &&
|
||||
filteredFoods.every((food) => formik.values.foodIds?.includes(food.id))
|
||||
}, [filteredFoods, formik.values.foodIds])
|
||||
filteredFoods.every((food) => formik.values.foods?.includes(food.id))
|
||||
}, [filteredFoods, formik.values.foods])
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -68,7 +68,7 @@ const FoodSelector: FC<FoodSelectorProps> = ({ formik, foods }) => {
|
||||
{filteredFoods.map((food) => (
|
||||
<div key={food.id} className='flex items-center gap-2'>
|
||||
<Checkbox
|
||||
checked={formik.values.foodIds?.includes(food.id) || false}
|
||||
checked={formik.values.foods?.includes(food.id) || false}
|
||||
onCheckedChange={(checked) =>
|
||||
handleToggle(food.id, checked as boolean)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ export type CreateCouponType = {
|
||||
code: string;
|
||||
name: string;
|
||||
description: string;
|
||||
type: CouponType;
|
||||
value: number;
|
||||
maxDiscount: number | null;
|
||||
minOrderAmount: number;
|
||||
@@ -39,6 +38,8 @@ export type CreateCouponType = {
|
||||
startDate: string | null;
|
||||
endDate: string | null;
|
||||
isActive: boolean;
|
||||
categoryIds?: string[];
|
||||
foodIds?: string[];
|
||||
foodCategories?: string[];
|
||||
foods?: string[];
|
||||
userPhone?: string;
|
||||
type: CouponType;
|
||||
};
|
||||
|
||||
@@ -142,7 +142,7 @@ const SideBar: FC = () => {
|
||||
icon={<TicketDiscount variant={isActive('discounts') ? 'Bold' : 'Outline'} color={isActive('discounts') ? 'black' : '#8C90A3'} size={iconSizeSideBar} />}
|
||||
title={t('sidebar.discount')}
|
||||
isActive={isActive('discounts')}
|
||||
link={Pages.discount.list}
|
||||
link={Pages.coupons.list}
|
||||
name='discounts'
|
||||
activeName='discounts'
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user