This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import Button from '@/components/Button'
|
import Button from '@/components/Button'
|
||||||
import Filters from '@/components/Filters'
|
import Filters, { type FilterValues } from '@/components/Filters'
|
||||||
import Table from '@/components/Table'
|
import Table from '@/components/Table'
|
||||||
|
import Tabs from '@/components/Tabs'
|
||||||
import { AddSquare, Edit, More2 } from 'iconsax-react'
|
import { AddSquare, Edit, More2 } from 'iconsax-react'
|
||||||
import { type FC, useState } from 'react'
|
import { type FC, useMemo, useState } from 'react'
|
||||||
import { useDeleteProduct, useDuplicateProduct, useGetProducts } from './hooks/useProductData'
|
import { useDeleteProduct, useDuplicateProduct, useGetCategory, useGetProducts } from './hooks/useProductData'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { Paths } from '@/config/Paths'
|
import { Paths } from '@/config/Paths'
|
||||||
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
import TrashWithConfrim from '@/components/TrashWithConfrim'
|
||||||
@@ -12,8 +13,37 @@ import { toast } from 'react-toastify'
|
|||||||
import { extractErrorMessage } from '@/config/func'
|
import { extractErrorMessage } from '@/config/func'
|
||||||
|
|
||||||
const ProductList: FC = () => {
|
const ProductList: FC = () => {
|
||||||
|
const [page, setPage] = useState<number>(1)
|
||||||
|
const [search, setSearch] = useState<string>('')
|
||||||
|
const [categoryId, setCategoryId] = useState<string>('')
|
||||||
|
|
||||||
const { data: products, refetch } = useGetProducts()
|
const { data: categoriesData } = useGetCategory({ limit: 1000 })
|
||||||
|
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,
|
||||||
|
})) ?? []),
|
||||||
|
],
|
||||||
|
[categoriesData?.data],
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleFiltersChange = (filters: FilterValues) => {
|
||||||
|
setSearch((filters.search as string) ?? '')
|
||||||
|
setPage(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCategoryTabChange = (tab: string) => {
|
||||||
|
setCategoryId(tab)
|
||||||
|
setPage(1)
|
||||||
|
}
|
||||||
const { mutate: deleteProduct, isPending: isDeleting } = useDeleteProduct()
|
const { mutate: deleteProduct, isPending: isDeleting } = useDeleteProduct()
|
||||||
const { mutate: duplicateProduct, isPending: isDuplicating } = useDuplicateProduct()
|
const { mutate: duplicateProduct, isPending: isDuplicating } = useDuplicateProduct()
|
||||||
const [duplicatingId, setDuplicatingId] = useState<string | null>(null)
|
const [duplicatingId, setDuplicatingId] = useState<string | null>(null)
|
||||||
@@ -68,6 +98,14 @@ const ProductList: FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-8'>
|
||||||
|
<Tabs
|
||||||
|
items={categoryTabs}
|
||||||
|
activeTab={categoryId}
|
||||||
|
onTabChange={handleCategoryTabChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='mt-8'>
|
<div className='mt-8'>
|
||||||
<Filters
|
<Filters
|
||||||
fields={[
|
fields={[
|
||||||
@@ -77,7 +115,7 @@ const ProductList: FC = () => {
|
|||||||
placeholder: 'جستجوی محصول'
|
placeholder: 'جستجوی محصول'
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
onChange={() => { }}
|
onChange={handleFiltersChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -88,6 +126,11 @@ const ProductList: FC = () => {
|
|||||||
key: 'title',
|
key: 'title',
|
||||||
title: 'عنوان محصول',
|
title: 'عنوان محصول',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'category',
|
||||||
|
title: 'دستهبندی',
|
||||||
|
render: (item) => item.category?.title ?? '-',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'attribute',
|
key: 'attribute',
|
||||||
title: 'ویژگی ها',
|
title: 'ویژگی ها',
|
||||||
@@ -133,6 +176,11 @@ const ProductList: FC = () => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
data={products?.data}
|
data={products?.data}
|
||||||
|
pagination={{
|
||||||
|
currentPage: page,
|
||||||
|
onPageChange: setPage,
|
||||||
|
totalPages: products?.meta?.totalPages ?? 1,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,10 +12,14 @@ import type {
|
|||||||
CreateProductType,
|
CreateProductType,
|
||||||
} from "../types/Types";
|
} from "../types/Types";
|
||||||
|
|
||||||
export const useGetCategory = () => {
|
export const useGetCategory = (params?: api.GetCategoryParams) => {
|
||||||
|
const page = params?.page ?? 1;
|
||||||
|
const limit = params?.limit;
|
||||||
|
const search = params?.search;
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["category"],
|
queryKey: ["category", page, limit, search],
|
||||||
queryFn: api.getCategory,
|
queryFn: () => api.getCategory({ page, limit, search }),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,10 +56,15 @@ export const useGetCategoryDetail = (id: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetProducts = () => {
|
export const useGetProducts = (params?: api.GetProductsParams) => {
|
||||||
|
const page = params?.page ?? 1;
|
||||||
|
const search = params?.search;
|
||||||
|
const limit = params?.limit;
|
||||||
|
const categoryId = params?.categoryId;
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["products"],
|
queryKey: ["products", page, search, limit, categoryId],
|
||||||
queryFn: api.getProducts,
|
queryFn: () => api.getProducts({ page, search, limit, categoryId }),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,20 @@
|
|||||||
import axios from "@/config/axios";
|
import axios from "@/config/axios";
|
||||||
import { type AttributeDetailResponseType, type AttributeResponseType, type AttributeValueDetailResponseType, type AttributeValuesResponseType, type CategoriesResponse, type CategoryResponse, type CreateAttributeType, type CreateAttributeValueType, type CreateCategoryType, type CreateProductType, type ProductDetailResponeType, type ProductResponeType } from "../types/Types";
|
import { type AttributeDetailResponseType, type AttributeResponseType, type AttributeValueDetailResponseType, type AttributeValuesResponseType, type CategoriesResponse, type CategoryResponse, type CreateAttributeType, type CreateAttributeValueType, type CreateCategoryType, type CreateProductType, type ProductDetailResponeType, type ProductResponeType } from "../types/Types";
|
||||||
|
|
||||||
export const getCategory = async () => {
|
export type GetCategoryParams = {
|
||||||
const { data } = await axios.get<CategoriesResponse>("/admin/category");
|
page?: number;
|
||||||
|
limit?: number;
|
||||||
|
search?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCategory = async (params?: GetCategoryParams) => {
|
||||||
|
const { data } = await axios.get<CategoriesResponse>("/admin/category", {
|
||||||
|
params: {
|
||||||
|
page: params?.page,
|
||||||
|
limit: params?.limit,
|
||||||
|
search: params?.search || undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,8 +38,22 @@ export const getCategoryDetail = async(id:string) => {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getProducts = async () => {
|
export type GetProductsParams = {
|
||||||
const { data } = await axios.get<ProductResponeType>("/admin/products");
|
page?: number;
|
||||||
|
limit?: number;
|
||||||
|
search?: string;
|
||||||
|
categoryId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getProducts = async (params?: GetProductsParams) => {
|
||||||
|
const { data } = await axios.get<ProductResponeType>("/admin/products", {
|
||||||
|
params: {
|
||||||
|
page: params?.page,
|
||||||
|
limit: params?.limit,
|
||||||
|
search: params?.search || undefined,
|
||||||
|
categoryId: params?.categoryId || undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user