From 8732374c9a43817090da204752cc3f8c245ebc95 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sun, 15 Feb 2026 09:43:19 +0330 Subject: [PATCH] select category and subcategory --- .env | 4 +- src/pages/product/Category.tsx | 1 + src/pages/product/Create.tsx | 5 +- src/pages/product/Update.tsx | 21 ++--- .../product/components/BasicInfoSection.tsx | 87 +++++++++++++++---- src/pages/product/components/CategoryForm.tsx | 11 ++- .../components/CategoryTableColumns.tsx | 16 +++- src/pages/product/types/Types.ts | 5 +- 8 files changed, 106 insertions(+), 44 deletions(-) diff --git a/.env b/.env index 4374b7e..07c35e7 100644 --- a/.env +++ b/.env @@ -1,7 +1,7 @@ VITE_TOKEN_NAME = 'dkala_a_t' VITE_REFRESH_TOKEN_NAME = 'dkala-a-rt' -VITE_BASE_URL = 'https://dkala-api.danakcorp.com' -# VITE_BASE_URL = 'http://10.191.241.88:4000' +# VITE_BASE_URL = 'https://dkala-api.danakcorp.com' +VITE_BASE_URL = 'http://10.191.241.88:4000' VITE_SOCKET_URL = 'https://dkala-api.danakcorp.com' \ No newline at end of file diff --git a/src/pages/product/Category.tsx b/src/pages/product/Category.tsx index 8a3b1b5..3254497 100644 --- a/src/pages/product/Category.tsx +++ b/src/pages/product/Category.tsx @@ -176,6 +176,7 @@ const CategoryProduct: FC = () => { } const columns = CategoryTableColumns({ + categories, onStatusChange: handleStatusChange, onEdit: handleEdit, onDelete: handleDelete, diff --git a/src/pages/product/Create.tsx b/src/pages/product/Create.tsx index 0768ec4..7b17e40 100644 --- a/src/pages/product/Create.tsx +++ b/src/pages/product/Create.tsx @@ -23,10 +23,7 @@ const CreateProduct: FC = () => { const { mutate: createProduct, isPending } = useCreateProduct() const { mutate: multipleUpload, isPending: isUploading } = useMultipleUpload() - const categories = data?.data?.map(category => ({ - label: category.title, - value: category.id - })) || [] + const categories = data?.data ?? [] const formik = useFormik({ initialValues: { diff --git a/src/pages/product/Update.tsx b/src/pages/product/Update.tsx index 4a0a861..c506ba1 100644 --- a/src/pages/product/Update.tsx +++ b/src/pages/product/Update.tsx @@ -27,10 +27,7 @@ const UpdateProduct: FC = () => { const { mutate: updateProduct, isPending } = useUpdateProduct() const { mutate: multipleUpload, isPending: isUploading } = useMultipleUpload() const navigate = useNavigate() - const categories = categoriesData?.data?.map(category => ({ - label: category.title, - value: category.id - })) || [] + const categories = categoriesData?.data ?? [] const product = productData?.data @@ -75,11 +72,11 @@ const UpdateProduct: FC = () => { const variants = values.variants.length > 0 ? values.variants.map((v) => ({ - ...(v.id && { id: v.id }), - value: v.value ?? '', - price: v.price ?? 0, - ...(v.stock !== undefined && v.stock !== null && { stock: v.stock }) - })) + ...(v.id && { id: v.id }), + value: v.value ?? '', + price: v.price ?? 0, + ...(v.stock !== undefined && v.stock !== null && { stock: v.stock }) + })) : [{ value: '', price: values.price, ...(values.stock !== undefined && values.stock !== null && { stock: values.stock }) }] const productData: CreateProductType = { ...values, @@ -192,9 +189,9 @@ const UpdateProduct: FC = () => { formik={formik} categories={categories} initialHasVariants={ - (product?.variants?.length ?? 0) > 1 || - ((product?.variants?.length === 1) && (product.variants[0].value ?? '') !== '') - } + (product?.variants?.length ?? 0) > 1 || + ((product?.variants?.length === 1) && (product.variants[0].value ?? '') !== '') + } /> diff --git a/src/pages/product/components/BasicInfoSection.tsx b/src/pages/product/components/BasicInfoSection.tsx index baa5922..9d1ee6f 100644 --- a/src/pages/product/components/BasicInfoSection.tsx +++ b/src/pages/product/components/BasicInfoSection.tsx @@ -1,16 +1,16 @@ -import { type FC, useState, useEffect } from 'react' +import { type FC, useState, useEffect, useMemo } from 'react' import type { FormikProps } from 'formik' import Input from '@/components/Input' import Select from '@/components/Select' import Textarea from '@/components/Textarea' import Button from '@/components/Button' import RadioGroup from '@/components/RadioGroup' -import type { CreateProductType, ProductVariant } from '../types/Types' +import type { CreateProductType, ProductVariant, Category } from '../types/Types' import { Add, Trash } from 'iconsax-react' type BasicInfoSectionProps = { formik: FormikProps - categories: Array<{ label: string; value: string }> + categories: Category[] /** در صفحه ویرایش، اگر کالا تنوع دارد مقدار true پاس داده شود */ initialHasVariants?: boolean } @@ -19,6 +19,24 @@ const newVariant = (): ProductVariant => ({ value: '', price: 0 }) const BasicInfoSection: FC = ({ formik, categories, initialHasVariants }) => { const [hasVariants, setHasVariants] = useState(initialHasVariants ?? false) + /** دسته اصلی انتخاب‌شده برای نمایش زیردسته‌ها */ + const [parentCategoryId, setParentCategoryId] = useState('') + + const mainCategories = useMemo( + () => categories.filter((c) => !c.parent).map((c) => ({ label: c.title, value: c.id })), + [categories] + ) + + const selectedParent = useMemo( + () => categories.find((c) => c.id === parentCategoryId), + [categories, parentCategoryId] + ) + + const subCategories = useMemo( + () => + (selectedParent?.children || []).map((c) => ({ label: c.title, value: c.id })), + [selectedParent] + ) useEffect(() => { if (initialHasVariants !== undefined) { @@ -26,6 +44,19 @@ const BasicInfoSection: FC = ({ formik, categories, initi } }, [initialHasVariants]) + /** همگام‌سازی parentCategoryId با categoryId وقتی فرم مقداردهی می‌شود (مثلاً در ویرایش) */ + useEffect(() => { + const catId = formik.values.categoryId + if (!catId) return + const cat = categories.find((c) => c.id === catId) + const child = categories.flatMap((c) => c.children || []).find((ch) => ch.id === catId) + if (child) { + setParentCategoryId(child.parent || '') + } else if (cat && !cat.parent) { + setParentCategoryId(catId) + } + }, [formik.values.categoryId, categories]) + const handleHasVariantsChange = (value: string | boolean) => { const next = value === true setHasVariants(next) @@ -65,20 +96,44 @@ const BasicInfoSection: FC = ({ formik, categories, initi error_text={formik.touched.title && formik.errors.title ? formik.errors.title : ''} /> -
- { + const value = e.target.value + setParentCategoryId(value) + formik.setFieldValue('categoryId', value) + }} + /> +
+ {subCategories.length > 0 && ( +
+ = ({