generate code

This commit is contained in:
hamid zarghami
2025-12-06 16:55:23 +03:30
parent 6447177b05
commit 7558dbb586
6 changed files with 56 additions and 37 deletions
+2 -1
View File
@@ -6,6 +6,7 @@ import { clx } from '../helpers/utils'
type Props = { type Props = {
className?: string; className?: string;
isloading?: boolean, isloading?: boolean,
colorLoading?: string,
} & ButtonHTMLAttributes<HTMLButtonElement> & } & ButtonHTMLAttributes<HTMLButtonElement> &
XOR<{ children: ReactNode }, { label: string }>; XOR<{ children: ReactNode }, { label: string }>;
@@ -21,7 +22,7 @@ const Button: FC<Props> = memo((props: Props) => {
<button disabled={props.isloading} {...props} className={`${buttonClass} ${props.className}`} > <button disabled={props.isloading} {...props} className={`${buttonClass} ${props.className}`} >
{ {
props.isloading ? props.isloading ?
<MoonLoader color="white" size={16} /> <MoonLoader color={props.colorLoading || 'white'} size={16} />
: :
props.label || props.children props.label || props.children
} }
-10
View File
@@ -72,15 +72,6 @@ const CreateCoupon: FC = () => {
}, },
}) })
const generateRandomCode = () => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
let code = ''
for (let i = 0; i < 8; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length))
}
formik.setFieldValue('code', code)
}
return ( return (
<div className='mt-5'> <div className='mt-5'>
<div className='flex justify-between items-center mb-6'> <div className='flex justify-between items-center mb-6'>
@@ -109,7 +100,6 @@ const CreateCoupon: FC = () => {
formik={formik} formik={formik}
discountType={discountType} discountType={discountType}
onDiscountTypeChange={setDiscountType} onDiscountTypeChange={setDiscountType}
onGenerateCode={generateRandomCode}
/> />
<CouponDiscountSettings <CouponDiscountSettings
@@ -6,20 +6,36 @@ import Textarea from '@/components/Textarea'
import RadioGroup from '@/components/RadioGroup' import RadioGroup from '@/components/RadioGroup'
import Button from '@/components/Button' import Button from '@/components/Button'
import type { CreateCouponType } from '../types/Types' import type { CreateCouponType } from '../types/Types'
import { useGenerateCouponCode } from '../hooks/useCouponData'
import { extractErrorMessage } from '@/config/func'
import { toast } from 'react-toastify'
interface CouponBasicInfoProps { interface CouponBasicInfoProps {
formik: FormikProps<CreateCouponType> formik: FormikProps<CreateCouponType>
discountType: 'DIRECT' | 'CODE' discountType: 'DIRECT' | 'CODE'
onDiscountTypeChange: (value: 'DIRECT' | 'CODE') => void onDiscountTypeChange: (value: 'DIRECT' | 'CODE') => void
onGenerateCode?: () => void
} }
const CouponBasicInfo: FC<CouponBasicInfoProps> = ({ const CouponBasicInfo: FC<CouponBasicInfoProps> = ({
formik, formik,
discountType, discountType,
onDiscountTypeChange, onDiscountTypeChange,
onGenerateCode,
}) => { }) => {
const { mutate: generateCouponCode, isPending: isGenerating } = useGenerateCouponCode()
const handleGenerateCode = () => {
generateCouponCode(undefined, {
onSuccess: (data) => {
formik.setFieldValue('code', data.data)
},
onError: (error) => {
toast.error(extractErrorMessage(error))
}
})
}
return ( return (
<> <>
<div className='mb-6'> <div className='mb-6'>
@@ -74,7 +90,9 @@ const CouponBasicInfo: FC<CouponBasicInfoProps> = ({
</div> </div>
<Button <Button
className='w-auto bg-transparent px-4 h-10 text-black border border-primary' className='w-auto bg-transparent px-4 h-10 text-black border border-primary'
onClick={onGenerateCode} onClick={handleGenerateCode}
isloading={isGenerating}
colorLoading='black'
> >
<Refresh color='black' size={20} className='ml-2' /> <Refresh color='black' size={20} className='ml-2' />
ساخت کد ساخت کد
+6
View File
@@ -31,3 +31,9 @@ export const useCreateCoupon = () => {
}, },
}); });
}; };
export const useGenerateCouponCode = () => {
return useMutation({
mutationFn: api.generateCouponCode,
});
};
+14 -15
View File
@@ -1,22 +1,22 @@
import { useState, useMemo } from 'react' import { useState } from "react";
import type { FilterValues } from '@/components/Filters' import type { FilterValues } from "@/components/Filters";
const DEFAULT_PAGE = 1 const DEFAULT_PAGE = 1;
const DEFAULT_LIMIT = 10 const DEFAULT_LIMIT = 10;
export const useCouponFilters = () => { export const useCouponFilters = () => {
const [filters, setFilters] = useState<FilterValues>({}) const [filters, setFilters] = useState<FilterValues>({});
const [currentPage, setCurrentPage] = useState(DEFAULT_PAGE) const [currentPage, setCurrentPage] = useState(DEFAULT_PAGE);
const [limit] = useState(DEFAULT_LIMIT) const [limit] = useState(DEFAULT_LIMIT);
const handleFiltersChange = (newFilters: FilterValues) => { const handleFiltersChange = (newFilters: FilterValues) => {
setFilters(newFilters) setFilters(newFilters);
setCurrentPage(DEFAULT_PAGE) setCurrentPage(DEFAULT_PAGE);
} };
const handlePageChange = (page: number) => { const handlePageChange = (page: number) => {
setCurrentPage(page) setCurrentPage(page);
} };
return { return {
filters, filters,
@@ -24,6 +24,5 @@ export const useCouponFilters = () => {
handleFiltersChange, handleFiltersChange,
handlePageChange, handlePageChange,
limit, limit,
} };
} };
@@ -15,3 +15,8 @@ export const deleteCoupon = async (id: string) => {
const { data } = await axios.delete(`/admin/coupons/${id}`); const { data } = await axios.delete(`/admin/coupons/${id}`);
return data; return data;
}; };
export const generateCouponCode = async () => {
const { data } = await axios.get(`/admin/coupons/generate-code`);
return data;
};