navigate back
This commit is contained in:
+99
-104
@@ -1,47 +1,47 @@
|
||||
import { type FC, useState, useEffect } from 'react'
|
||||
import { useFormik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { TickCircle } from 'iconsax-react'
|
||||
import { toast } from 'react-toastify'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import Button from '@/components/Button'
|
||||
import CreateFoodSidebar from './components/CreateFoodSidebar'
|
||||
import BasicInfoSection from './components/BasicInfoSection'
|
||||
import FoodContentSection from './components/FoodContentSection'
|
||||
import MealTimesSection from './components/MealTimesSection'
|
||||
import WeekDaysSection from './components/WeekDaysSection'
|
||||
import ServiceOptionsSection from './components/ServiceOptionsSection'
|
||||
import type { CreateFoodType } from './types/Types'
|
||||
import { useUpdateFood, useGetFoodDetails, useGetCategories } from './hooks/useFoodData'
|
||||
import { useMultipleUpload } from '../uploader/hooks/useUploaderData'
|
||||
import { Pages } from '@/config/Pages'
|
||||
import type { ErrorType } from '@/helpers/types'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
import Button from "@/components/Button";
|
||||
import { extractErrorMessage } from "@/config/func";
|
||||
import type { ErrorType } from "@/helpers/types";
|
||||
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 CreateFoodSidebar from "./components/CreateFoodSidebar";
|
||||
import FoodContentSection from "./components/FoodContentSection";
|
||||
import MealTimesSection from "./components/MealTimesSection";
|
||||
import ServiceOptionsSection from "./components/ServiceOptionsSection";
|
||||
import WeekDaysSection from "./components/WeekDaysSection";
|
||||
import { useGetCategories, useGetFoodDetails, useUpdateFood } from "./hooks/useFoodData";
|
||||
import type { CreateFoodType } from "./types/Types";
|
||||
|
||||
const UpdateFood: FC = () => {
|
||||
const { id } = useParams<{ id: string }>()
|
||||
const { data: foodData, isLoading } = useGetFoodDetails(id || '')
|
||||
const { data: categoriesData } = useGetCategories()
|
||||
const [isActive, setIsActive] = useState<boolean>(true)
|
||||
const [isSpecial, setIsSpecial] = useState<boolean>(false)
|
||||
const [imageFiles, setImageFiles] = useState<File[]>([])
|
||||
const [existingImages, setExistingImages] = useState<string[]>([])
|
||||
const { mutate: updateFood, isPending } = useUpdateFood()
|
||||
const { mutate: multipleUpload, isPending: isUploading } = useMultipleUpload()
|
||||
const navigate = useNavigate()
|
||||
const categories = categoriesData?.data?.map(category => ({
|
||||
label: category.title,
|
||||
value: category.id
|
||||
})) || []
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const { data: foodData, isLoading } = useGetFoodDetails(id || "");
|
||||
const { data: categoriesData } = useGetCategories();
|
||||
const [isActive, setIsActive] = useState<boolean>(true);
|
||||
const [isSpecial, setIsSpecial] = useState<boolean>(false);
|
||||
const [imageFiles, setImageFiles] = useState<File[]>([]);
|
||||
const [existingImages, setExistingImages] = useState<string[]>([]);
|
||||
const { mutate: updateFood, isPending } = useUpdateFood();
|
||||
const { mutate: multipleUpload, isPending: isUploading } = useMultipleUpload();
|
||||
const navigate = useNavigate();
|
||||
const categories =
|
||||
categoriesData?.data?.map((category) => ({
|
||||
label: category.title,
|
||||
value: category.id,
|
||||
})) || [];
|
||||
|
||||
const food = foodData?.data
|
||||
const food = foodData?.data;
|
||||
|
||||
const formik = useFormik<CreateFoodType>({
|
||||
initialValues: {
|
||||
title: '',
|
||||
desc: '',
|
||||
title: "",
|
||||
desc: "",
|
||||
content: [],
|
||||
categoryId: '',
|
||||
categoryId: "",
|
||||
price: 0,
|
||||
discount: 0,
|
||||
prepareTime: 0,
|
||||
@@ -54,72 +54,73 @@ const UpdateFood: FC = () => {
|
||||
isSpecialOffer: false,
|
||||
dailyStock: 0,
|
||||
availableStock: 0,
|
||||
order: 0
|
||||
order: 0,
|
||||
},
|
||||
validationSchema: Yup.object().shape({
|
||||
title: Yup.string().required('نام غذا الزامی است'),
|
||||
categoryId: Yup.string().required('دستهبندی الزامی است'),
|
||||
price: Yup.number().required('قیمت الزامی است').min(0, 'قیمت باید مثبت باشد'),
|
||||
prepareTime: Yup.number().required('زمان آمادهسازی الزامی است').min(0, 'زمان آمادهسازی باید مثبت باشد'),
|
||||
discount: Yup.number().min(0, 'تخفیف باید مثبت باشد'),
|
||||
dailyStock: Yup.number().required('موجودی روزانه الزامی است').min(0, 'موجودی روزانه باید مثبت باشد'),
|
||||
availableStock: Yup.number()
|
||||
.required('موجودی فعلی الزامی است')
|
||||
.min(0, 'موجودی فعلی باید مثبت باشد'),
|
||||
title: Yup.string().required("نام غذا الزامی است"),
|
||||
categoryId: Yup.string().required("دستهبندی الزامی است"),
|
||||
price: Yup.number().required("قیمت الزامی است").min(0, "قیمت باید مثبت باشد"),
|
||||
prepareTime: Yup.number().required("زمان آمادهسازی الزامی است").min(0, "زمان آمادهسازی باید مثبت باشد"),
|
||||
discount: Yup.number().min(0, "تخفیف باید مثبت باشد"),
|
||||
dailyStock: Yup.number().required("موجودی روزانه الزامی است").min(0, "موجودی روزانه باید مثبت باشد"),
|
||||
availableStock: Yup.number().required("موجودی فعلی الزامی است").min(0, "موجودی فعلی باید مثبت باشد"),
|
||||
content: Yup.array().of(Yup.string()),
|
||||
weekDays: Yup.array().of(Yup.number()),
|
||||
mealTypes: Yup.array().of(Yup.string())
|
||||
mealTypes: Yup.array().of(Yup.string()),
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
if (!id) {
|
||||
toast.error('شناسه غذا یافت نشد')
|
||||
return
|
||||
toast.error("شناسه غذا یافت نشد");
|
||||
return;
|
||||
}
|
||||
|
||||
const submitFood = (newImageUrls: string[] = []) => {
|
||||
const allImages = [...values.images, ...newImageUrls]
|
||||
const allImages = [...values.images, ...newImageUrls];
|
||||
const foodData: CreateFoodType = {
|
||||
...values,
|
||||
isActive,
|
||||
isSpecialOffer: isSpecial,
|
||||
images: allImages,
|
||||
content: values.content.filter(item => item && item.trim().length > 0)
|
||||
}
|
||||
content: values.content.filter((item) => item && item.trim().length > 0),
|
||||
};
|
||||
|
||||
updateFood({ id, params: foodData }, {
|
||||
onSuccess: () => {
|
||||
toast.success('غذا با موفقیت بهروزرسانی شد')
|
||||
navigate(Pages.foods.list)
|
||||
updateFood(
|
||||
{ id, params: foodData },
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success("غذا با موفقیت بهروزرسانی شد");
|
||||
navigate(-1);
|
||||
},
|
||||
onError: (error: ErrorType) => {
|
||||
toast.error(extractErrorMessage(error));
|
||||
},
|
||||
},
|
||||
onError: (error: ErrorType) => {
|
||||
toast.error(extractErrorMessage(error))
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (imageFiles.length > 0) {
|
||||
multipleUpload(imageFiles, {
|
||||
onSuccess: (response) => {
|
||||
const imageUrls = response?.data?.map(item => item.url) || []
|
||||
submitFood(imageUrls)
|
||||
const imageUrls = response?.data?.map((item) => item.url) || [];
|
||||
submitFood(imageUrls);
|
||||
},
|
||||
onError: (error: ErrorType) => {
|
||||
toast.error(error?.response?.data?.error?.message[0] || 'خطا در آپلود تصاویر')
|
||||
}
|
||||
})
|
||||
toast.error(error?.response?.data?.error?.message[0] || "خطا در آپلود تصاویر");
|
||||
},
|
||||
});
|
||||
} else {
|
||||
submitFood()
|
||||
submitFood();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (food) {
|
||||
formik.setValues({
|
||||
title: food.title || '',
|
||||
desc: food.desc || '',
|
||||
title: food.title || "",
|
||||
desc: food.desc || "",
|
||||
content: food.content || [],
|
||||
categoryId: food.category?.id || '',
|
||||
categoryId: food.category?.id || "",
|
||||
price: food.price || 0,
|
||||
discount: food.discount || 0,
|
||||
prepareTime: food.prepareTime || 0,
|
||||
@@ -132,59 +133,53 @@ const UpdateFood: FC = () => {
|
||||
isSpecialOffer: food.isSpecialOffer || false,
|
||||
dailyStock: food.inventory?.totalStock || 0,
|
||||
availableStock: food.inventory?.availableStock || 0,
|
||||
order: food.order || 0
|
||||
})
|
||||
setIsActive(food.isActive || false)
|
||||
setIsSpecial(food.isSpecialOffer || false)
|
||||
setExistingImages(food.images || [])
|
||||
order: food.order || 0,
|
||||
});
|
||||
setIsActive(food.isActive || false);
|
||||
setIsSpecial(food.isSpecialOffer || false);
|
||||
setExistingImages(food.images || []);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [food])
|
||||
}, [food]);
|
||||
|
||||
useEffect(() => {
|
||||
formik.setFieldValue('images', existingImages)
|
||||
formik.setFieldValue("images", existingImages);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [existingImages])
|
||||
}, [existingImages]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className='w-full mt-4 flex justify-center items-center'>
|
||||
<div className="w-full mt-4 flex justify-center items-center">
|
||||
<div>در حال بارگذاری...</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!food) {
|
||||
return (
|
||||
<div className='w-full mt-4 flex justify-center items-center'>
|
||||
<div className="w-full mt-4 flex justify-center items-center">
|
||||
<div>غذا یافت نشد</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='w-full mt-4'>
|
||||
<div className='flex flex-col sm:flex-row w-full justify-between items-start sm:items-center gap-4'>
|
||||
<div className='text-lg font-light'>
|
||||
ویرایش غذا
|
||||
</div>
|
||||
<div className="w-full mt-4">
|
||||
<div className="flex flex-col sm:flex-row w-full justify-between items-start sm:items-center gap-4">
|
||||
<div className="text-lg font-light">ویرایش غذا</div>
|
||||
<div>
|
||||
<Button
|
||||
className='px-5 w-full sm:w-auto'
|
||||
onClick={() => formik.handleSubmit()}
|
||||
isloading={isPending || isUploading}
|
||||
>
|
||||
<div className='flex gap-2 items-center'>
|
||||
<TickCircle className='size-5' color='white' />
|
||||
<Button className="px-5 w-full sm:w-auto" onClick={() => formik.handleSubmit()} isloading={isPending || isUploading}>
|
||||
<div className="flex gap-2 items-center">
|
||||
<TickCircle className="size-5" color="white" />
|
||||
<div>ذخیره تغییرات</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col lg:flex-row gap-6 mt-6'>
|
||||
<div className='flex-1'>
|
||||
<div className='bg-white py-6 sm:py-8 xl:px-10 px-4 rounded-3xl'>
|
||||
<div className="flex flex-col lg:flex-row gap-6 mt-6">
|
||||
<div className="flex-1">
|
||||
<div className="bg-white py-6 sm:py-8 xl:px-10 px-4 rounded-3xl">
|
||||
<BasicInfoSection formik={formik} categories={categories} />
|
||||
<FoodContentSection formik={formik} />
|
||||
<MealTimesSection formik={formik} />
|
||||
@@ -193,7 +188,7 @@ const UpdateFood: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='w-full lg:w-auto'>
|
||||
<div className="w-full lg:w-auto">
|
||||
<CreateFoodSidebar
|
||||
isActive={isActive}
|
||||
isSpecial={isSpecial}
|
||||
@@ -206,7 +201,7 @@ const UpdateFood: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdateFood
|
||||
export default UpdateFood;
|
||||
|
||||
Reference in New Issue
Block a user