+25
-23
@@ -1,7 +1,6 @@
|
||||
import Button from '@/components/Button'
|
||||
import Filters, { type FilterValues } from '@/components/Filters'
|
||||
import Table from '@/components/Table'
|
||||
import Tabs from '@/components/Tabs'
|
||||
import { AddSquare, Edit, More2 } from 'iconsax-react'
|
||||
import { type FC, useMemo, useState } from 'react'
|
||||
import { useDeleteProduct, useDuplicateProduct, useGetCategory, useGetProducts } from './hooks/useProductData'
|
||||
@@ -11,39 +10,44 @@ import TrashWithConfrim from '@/components/TrashWithConfrim'
|
||||
import CopyWithConfirm from '@/components/CopyWithConfirm'
|
||||
import { toast } from 'react-toastify'
|
||||
import { extractErrorMessage } from '@/config/func'
|
||||
import type { CategoryType } from './types/Types'
|
||||
|
||||
const flattenCategoryOptions = (categories: CategoryType[]) => {
|
||||
const options: { label: string; value: string }[] = []
|
||||
|
||||
for (const category of categories) {
|
||||
options.push({ label: category.title, value: category.id })
|
||||
for (const child of category.children ?? []) {
|
||||
options.push({ label: `— ${child.title}`, value: child.id })
|
||||
}
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
const ProductList: FC = () => {
|
||||
const [page, setPage] = useState<number>(1)
|
||||
const [search, setSearch] = useState<string>('')
|
||||
const [categoryId, setCategoryId] = useState<string>('')
|
||||
|
||||
const { data: categoriesData } = useGetCategory({ limit: 1000 })
|
||||
const { data: categoriesData } = useGetCategory({ limit: 1000, parentId: 'null' })
|
||||
const { data: products, refetch } = useGetProducts({
|
||||
page,
|
||||
search: search || undefined,
|
||||
categoryId: categoryId || undefined,
|
||||
})
|
||||
|
||||
const categoryTabs = useMemo(
|
||||
() => [
|
||||
{ label: 'همه', value: '' },
|
||||
...(categoriesData?.data?.map((category) => ({
|
||||
label: category.title,
|
||||
value: category.id,
|
||||
})) ?? []),
|
||||
],
|
||||
const categoryOptions = useMemo(
|
||||
() => flattenCategoryOptions((categoriesData?.data ?? []) as CategoryType[]),
|
||||
[categoriesData?.data],
|
||||
)
|
||||
|
||||
const handleFiltersChange = (filters: FilterValues) => {
|
||||
setSearch((filters.search as string) ?? '')
|
||||
setSearch(filters.search ?? '')
|
||||
setCategoryId(filters.categoryId ?? '')
|
||||
setPage(1)
|
||||
}
|
||||
|
||||
const handleCategoryTabChange = (tab: string) => {
|
||||
setCategoryId(tab)
|
||||
setPage(1)
|
||||
}
|
||||
const { mutate: deleteProduct, isPending: isDeleting } = useDeleteProduct()
|
||||
const { mutate: duplicateProduct, isPending: isDuplicating } = useDuplicateProduct()
|
||||
const [duplicatingId, setDuplicatingId] = useState<string | null>(null)
|
||||
@@ -98,14 +102,6 @@ const ProductList: FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-8'>
|
||||
<Tabs
|
||||
items={categoryTabs}
|
||||
activeTab={categoryId}
|
||||
onTabChange={handleCategoryTabChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='mt-8'>
|
||||
<Filters
|
||||
fields={[
|
||||
@@ -113,6 +109,12 @@ const ProductList: FC = () => {
|
||||
name: 'search',
|
||||
type: 'input',
|
||||
placeholder: 'جستجوی محصول'
|
||||
},
|
||||
{
|
||||
name: 'categoryId',
|
||||
type: 'select',
|
||||
placeholder: 'دستهبندی',
|
||||
options: categoryOptions,
|
||||
}
|
||||
]}
|
||||
onChange={handleFiltersChange}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { type FC, type SelectHTMLAttributes } from 'react'
|
||||
import { type FC, type SelectHTMLAttributes, useMemo } from 'react'
|
||||
import { useGetCategory } from '../hooks/useProductData'
|
||||
import Select from '@/components/Select'
|
||||
import type { CategoryType } from '../types/Types'
|
||||
|
||||
type Props = {
|
||||
error_text?: string,
|
||||
@@ -9,6 +10,19 @@ type Props = {
|
||||
clearable?: boolean,
|
||||
} & SelectHTMLAttributes<HTMLSelectElement>
|
||||
|
||||
const flattenCategoryOptions = (categories: CategoryType[]) => {
|
||||
const options: { label: string; value: string }[] = []
|
||||
|
||||
for (const category of categories) {
|
||||
options.push({ label: category.title, value: category.id })
|
||||
for (const child of category.children ?? []) {
|
||||
options.push({ label: `— ${child.title}`, value: child.id })
|
||||
}
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
const CategoriesSelect: FC<Props> = ({
|
||||
isDisableShowLable,
|
||||
placeholder,
|
||||
@@ -16,8 +30,12 @@ const CategoriesSelect: FC<Props> = ({
|
||||
clearable = true,
|
||||
...selectProps
|
||||
}) => {
|
||||
const { data: categories } = useGetCategory({ limit: 1000, parentId: 'null' })
|
||||
|
||||
const { data: categories } = useGetCategory()
|
||||
const items = useMemo(
|
||||
() => flattenCategoryOptions((categories?.data ?? []) as CategoryType[]),
|
||||
[categories?.data],
|
||||
)
|
||||
|
||||
return (
|
||||
<Select
|
||||
@@ -25,12 +43,7 @@ const CategoriesSelect: FC<Props> = ({
|
||||
placeholder={placeholder || 'انتخاب'}
|
||||
error_text={error_text}
|
||||
clearable={clearable}
|
||||
items={categories?.data?.map((item) => {
|
||||
return {
|
||||
label: item.title,
|
||||
value: item.id + ''
|
||||
}
|
||||
}) || []}
|
||||
items={items}
|
||||
{...selectProps}
|
||||
/>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user