list of shipment methods

This commit is contained in:
hamid zarghami
2025-11-23 16:03:26 +03:30
parent 45122f4d7a
commit d77e83c08d
7 changed files with 229 additions and 11 deletions
+46 -3
View File
@@ -1,13 +1,36 @@
import { type FC } from 'react'
import { useGetRestaurantShipmentMethods } from './hooks/useShipmentMethodData'
import Table from '@/components/Table'
import Filters from '@/components/Filters'
import { useGetRestaurantShipmentMethods, useDeleteRestaurantShipmentMethod } from './hooks/useShipmentMethodData'
import { useShipmentMethodFilters } from './hooks/useShipmentMethodFilters'
import { getShipmentMethodTableColumns } from './components/ShipmentMethodTableColumns'
import { useShipmentMethodFiltersFields } from './components/ShipmentMethodFiltersFields'
import { Add } from 'iconsax-react'
import { Link } from 'react-router-dom'
import { Pages } from '@/config/Pages'
import Button from '@/components/Button'
import { Add } from 'iconsax-react'
const ShipmentMethodList: FC = () => {
const {
filters,
currentPage,
apiParams,
handleFiltersChange,
handlePageChange,
limit,
} = useShipmentMethodFilters()
const { data: shipmentMethodsData, isLoading } = useGetRestaurantShipmentMethods()
const { data: shipmentMethodsData, isLoading } = useGetRestaurantShipmentMethods(apiParams)
const { mutate: deleteShipmentMethod, isPending: isDeleting } = useDeleteRestaurantShipmentMethod()
const shipmentMethods = shipmentMethodsData?.data || []
const columns = getShipmentMethodTableColumns({
onDelete: (id: string) => deleteShipmentMethod(id),
isDeleting
})
const filterFields = useShipmentMethodFiltersFields()
const totalPages = Math.ceil(shipmentMethods.length / limit) || 1
return (
<div className='mt-5'>
@@ -22,6 +45,26 @@ const ShipmentMethodList: FC = () => {
</Button>
</Link>
</div>
<div className='mt-8'>
<Filters
fields={filterFields}
onChange={handleFiltersChange}
initialValues={filters}
searchField="search"
/>
</div>
<Table
columns={columns}
data={shipmentMethods}
isloading={isLoading}
pagination={{
currentPage,
totalPages,
onPageChange: handlePageChange,
}}
/>
</div>
)
}
@@ -0,0 +1,13 @@
import { useMemo } from 'react'
import type { FieldType } from '@/components/Filters'
export const useShipmentMethodFiltersFields = (): FieldType[] => {
return useMemo(() => [
{
type: 'input',
name: 'search',
placeholder: 'جستجو',
},
], [])
}
@@ -0,0 +1,81 @@
import type { ColumnType } from '@/components/types/TableTypes'
import type { RestaurantShipmentMethod } from '../types/Types'
import TrashWithConfrim from '@/components/TrashWithConfrim'
import { Eye } from 'iconsax-react'
import { Link } from 'react-router-dom'
import { Pages } from '@/config/Pages'
import Status from '@/components/Status'
interface GetShipmentMethodTableColumnsParams {
onDelete?: (id: string) => void
isDeleting?: boolean
}
export const getShipmentMethodTableColumns = ({ onDelete, isDeleting }: GetShipmentMethodTableColumnsParams = {}): ColumnType<RestaurantShipmentMethod>[] => {
return [
{
key: 'title',
title: 'عنوان',
render: (item: RestaurantShipmentMethod) => {
return item.shipmentMethod?.title || '-'
}
},
{
key: 'description',
title: 'توضیحات',
render: (item: RestaurantShipmentMethod) => {
return item.shipmentMethod?.description || '-'
}
},
{
key: 'price',
title: 'قیمت',
render: (item: RestaurantShipmentMethod) => {
return item.price ? `${item.price.toLocaleString()} تومان` : '-'
}
},
{
key: 'minOrderPrice',
title: 'حداقل قیمت سفارش',
render: (item: RestaurantShipmentMethod) => {
return item.minOrderPrice ? `${item.minOrderPrice.toLocaleString()} تومان` : '-'
}
},
{
key: 'isActive',
title: 'وضعیت',
render: (item: RestaurantShipmentMethod) => {
return (
<Status
variant={item.isActive ? 'success' : 'error'}
label={item.isActive ? 'فعال' : 'غیرفعال'}
/>
)
}
},
{
key: 'actions',
title: '',
render: (item: RestaurantShipmentMethod) => {
return (
<div className='flex gap-2 items-center'>
<Link to={Pages.shipment_methods.update + item.id}>
<Eye
size={20}
color='#8C90A3'
className='cursor-pointer'
/>
</Link>
{onDelete && (
<TrashWithConfrim
onDelete={() => onDelete(item.id)}
isloading={isDeleting}
/>
)}
</div>
)
}
},
]
}
@@ -1,10 +1,13 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as api from "../service/ShipmentMethodService";
import type { GetRestaurantShipmentMethodsParams } from "../types/Types";
export const useGetRestaurantShipmentMethods = () => {
export const useGetRestaurantShipmentMethods = (
params?: GetRestaurantShipmentMethodsParams
) => {
return useQuery({
queryKey: ["restaurant-shipment-methods"],
queryFn: api.getRestaurantShipmentMethods,
queryKey: ["restaurant-shipment-methods", params],
queryFn: () => api.getRestaurantShipmentMethods(params),
});
};
@@ -16,7 +19,25 @@ export const useGetShipmentMethods = () => {
};
export const useCreateRestaurantShipmentMethod = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: api.createRestaurantShipmentMethod,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["restaurant-shipment-methods"],
});
},
});
};
export const useDeleteRestaurantShipmentMethod = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: api.deleteRestaurantShipmentMethod,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["restaurant-shipment-methods"],
});
},
});
};
@@ -0,0 +1,44 @@
import { useState, useMemo } from "react";
import type { FilterValues } from "@/components/Filters";
import type { GetRestaurantShipmentMethodsParams } from "../types/Types";
const DEFAULT_PAGE = 1;
const DEFAULT_LIMIT = 10;
export const useShipmentMethodFilters = () => {
const [filters, setFilters] = useState<FilterValues>({});
const [currentPage, setCurrentPage] = useState(DEFAULT_PAGE);
const [limit] = useState(DEFAULT_LIMIT);
const apiParams = useMemo<GetRestaurantShipmentMethodsParams>(() => {
const params: GetRestaurantShipmentMethodsParams = {
page: currentPage,
limit: limit,
};
if (filters.search) {
params.search = filters.search;
}
return params;
}, [filters, currentPage, limit]);
const handleFiltersChange = (newFilters: FilterValues) => {
setFilters(newFilters);
setCurrentPage(DEFAULT_PAGE);
};
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
return {
filters,
currentPage,
apiParams,
handleFiltersChange,
handlePageChange,
limit,
};
};
@@ -3,6 +3,7 @@ import type {
CreateShipmentMethodType,
GetShipmentMethodsResponseType,
GetRestaurantShipmentMethodsResponseType,
GetRestaurantShipmentMethodsParams,
} from "../types/Types";
export const getShipmentMethods = async (): Promise<
@@ -12,10 +13,12 @@ export const getShipmentMethods = async (): Promise<
return data;
};
export const getRestaurantShipmentMethods = async (): Promise<
GetRestaurantShipmentMethodsResponseType
> => {
const { data } = await axios.get("/admin/restaurant-shipment-methods");
export const getRestaurantShipmentMethods = async (
params?: GetRestaurantShipmentMethodsParams
): Promise<GetRestaurantShipmentMethodsResponseType> => {
const { data } = await axios.get("/admin/restaurant-shipment-methods", {
params,
});
return data;
};
@@ -28,3 +31,10 @@ export const createRestaurantShipmentMethod = async (
);
return data;
};
export const deleteRestaurantShipmentMethod = async (id: string) => {
const { data } = await axios.delete(
`/admin/restaurant-shipment-methods/${id}`
);
return data;
};
+6
View File
@@ -34,3 +34,9 @@ export type RestaurantShipmentMethod = {
export type GetRestaurantShipmentMethodsResponseType = IResponse<
RestaurantShipmentMethod[]
>;
export type GetRestaurantShipmentMethodsParams = {
page?: number;
limit?: number;
search?: string;
};