import Button from "@/components/Button"; import { extractErrorMessage } from "@/config/func"; import type { ErrorType } from "@/helpers/types"; import { useQueryClient } from "@tanstack/react-query"; import { useFormik } from "formik"; import { TickCircle } from "iconsax-react"; import { type FC, useEffect, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { toast } from "react-toastify"; import * as Yup from "yup"; import { useMultipleUpload } from "../uploader/hooks/useUploaderData"; import BasicInfoSection from "./components/BasicInfoSection"; import CreateProductSidebar from "./components/CreateProductSidebar"; import { PaymentType, PricingType, PurchaseUnit } from "./enum/Enum"; import { useGetCategories, useGetProductDetails, useUpdateProduct } from "./hooks/useProductData"; import type { CreateProductType } from "./types/Types"; import { buildProductPayload } from "./utils/productPayload"; const UpdateProduct: FC = () => { const { id } = useParams<{ id: string }>(); const queryClient = useQueryClient(); const { data: productData, isLoading } = useGetProductDetails(id || ""); const { data: categoriesData } = useGetCategories(); const [isActive, setIsActive] = useState(true); const [isSpecial, setIsSpecial] = useState(false); const [imageFiles, setImageFiles] = useState([]); const [existingImages, setExistingImages] = useState([]); const { mutate: updateProduct, isPending } = useUpdateProduct(); const { mutate: multipleUpload, isPending: isUploading } = useMultipleUpload(); const navigate = useNavigate(); const categories = categoriesData?.data ?? []; const product = productData?.data; const isSubmitting = isPending || isUploading; const formik = useFormik({ initialValues: { categoryId: "", title: "", attribute: "", variants: [], desc: "", price: 0, isActive: true, images: [], discount: 0, isSpecialOffer: false, order: 0, stock: undefined, maxPurchaseQuantity: undefined, minPurchaseQuantity: undefined, purchasePitch: undefined, pricingType: PricingType.FIXED, paymentType: PaymentType.INSTANT, purchaseUnit: PurchaseUnit.NUMBER, needAdminAcceptance: false, }, validationSchema: Yup.object().shape({ title: Yup.string().required("نام کالا الزامی است"), categoryId: Yup.string().required("دسته‌بندی الزامی است"), price: Yup.number().required("قیمت الزامی است").min(0, "قیمت باید مثبت باشد"), discount: Yup.number().min(0, "تخفیف باید مثبت باشد"), attribute: Yup.string(), pricingType: Yup.string().required(), paymentType: Yup.string().required(), minPurchaseQuantity: Yup.number().when("pricingType", { is: PricingType.VARIABLE, then: (schema) => schema.required("حداقل مقدار الزامی است").positive("حداقل مقدار باید مثبت باشد"), }), maxPurchaseQuantity: Yup.number().required("حداکثر مقدار الزامی است").positive("حداکثر مقدار باید مثبت باشد"), purchasePitch: Yup.number().when("pricingType", { is: PricingType.VARIABLE, then: (schema) => schema.min(0, "گام تغییر باید مثبت باشد"), }), variants: Yup.array().of( Yup.object().shape({ id: Yup.string(), value: Yup.string(), price: Yup.number().min(0), }), ), }), onSubmit: (values) => { if (!id) { toast.error("شناسه کالا یافت نشد"); return; } const submitProduct = (newImageUrls: string[] = []) => { const allImages = [...values.images, ...newImageUrls]; const productData = buildProductPayload({ values, isActive, isSpecialOffer: isSpecial, images: allImages, }); updateProduct( { id, params: productData }, { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["product", id] }); queryClient.invalidateQueries({ queryKey: ["products"] }); toast.success("کالا با موفقیت به‌روزرسانی شد"); navigate(-1); }, onError: (error: ErrorType) => { toast.error(extractErrorMessage(error)); }, }, ); }; if (imageFiles.length > 0) { multipleUpload(imageFiles, { onSuccess: (response) => { const imageUrls = response?.data?.map((item) => item.url) || []; submitProduct(imageUrls); }, onError: (error: ErrorType) => { toast.error(extractErrorMessage(error, "خطا در آپلود تصاویر")); }, }); } else { submitProduct(); } }, }); useEffect(() => { if (product) { const variants = product.variants || []; const priceFromVariant = variants.length > 0 ? variants[0].price : product.price; formik.setValues({ categoryId: product.category?.id || "", title: product.title || "", attribute: product.attribute || "", variants, desc: product.desc || "", price: priceFromVariant ?? product.price ?? 0, isActive: product.isActive || false, images: product.images || [], discount: product.discount || 0, isSpecialOffer: product.isSpecialOffer || false, order: product.order ?? 0, stock: product.variants?.[0]?.stock, maxPurchaseQuantity: product.maxPurchaseQuantity, minPurchaseQuantity: product.minPurchaseQuantity, purchasePitch: product.purchasePitch, pricingType: product.pricingType ?? PricingType.FIXED, paymentType: product.paymentType ?? (product.needAdminAcceptance ? PaymentType.AFTER_PREPARATION : PaymentType.INSTANT), purchaseUnit: product.purchaseUnit ?? PurchaseUnit.NUMBER, needAdminAcceptance: product.needAdminAcceptance ?? false, }); setIsActive(product.isActive || false); setIsSpecial(product.isSpecialOffer || false); setExistingImages(product.images || []); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [product]); useEffect(() => { formik.setFieldValue("images", existingImages); // eslint-disable-next-line react-hooks/exhaustive-deps }, [existingImages]); if (isLoading) { return (
در حال بارگذاری...
); } if (!product) { return (
کالا یافت نشد
); } return (
ویرایش کالا
1 || (product?.variants?.length === 1 && (product.variants[0].value ?? "") !== "")} />
); }; export default UpdateProduct;