order report by food
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { type FC, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Table from '@/components/Table';
|
||||
import Filters from '@/components/Filters';
|
||||
import { useGetFoodOrderReport } from './hooks/useFoodOrderReportData';
|
||||
import { useFoodOrderReportFilters } from './hooks/useFoodOrderReportFilters';
|
||||
import { getFoodOrderReportTableColumns } from './components/FoodOrderReportTableColumns';
|
||||
import { useFoodOrderReportFiltersFields } from './components/FoodOrderReportFiltersFields';
|
||||
import type { FoodOrderReportItem } from './types/Types';
|
||||
import type { RowDataType } from '@/components/types/TableTypes';
|
||||
|
||||
const FoodOrderReport: FC = () => {
|
||||
const { t } = useTranslation('global');
|
||||
const { filters, apiParams, handleFiltersChange } = useFoodOrderReportFilters();
|
||||
const { data: reportData, isLoading } = useGetFoodOrderReport(apiParams);
|
||||
|
||||
const columns = getFoodOrderReportTableColumns();
|
||||
const filterFields = useFoodOrderReportFiltersFields();
|
||||
|
||||
const reportItems = useMemo(() => {
|
||||
return (reportData?.data || []).map((item) => ({
|
||||
...item,
|
||||
id: item.food.id,
|
||||
}));
|
||||
}, [reportData?.data]);
|
||||
|
||||
return (
|
||||
<div className='mt-5'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<h1 className='text-lg font-light'>{t('submenu.orders_food_report')}</h1>
|
||||
</div>
|
||||
|
||||
<div className='mt-8'>
|
||||
<Filters
|
||||
fields={filterFields}
|
||||
onChange={handleFiltersChange}
|
||||
initialValues={filters}
|
||||
showClearButton
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Table<FoodOrderReportItem & RowDataType>
|
||||
columns={columns}
|
||||
data={reportItems as (FoodOrderReportItem & RowDataType)[]}
|
||||
isloading={isLoading}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FoodOrderReport;
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useMemo } from 'react';
|
||||
import type { FieldType } from '@/components/Filters';
|
||||
|
||||
export const useFoodOrderReportFiltersFields = (): FieldType[] => {
|
||||
return useMemo(() => [
|
||||
{
|
||||
type: 'datetime',
|
||||
name: 'from',
|
||||
placeholder: 'از تاریخ',
|
||||
},
|
||||
{
|
||||
type: 'datetime',
|
||||
name: 'to',
|
||||
placeholder: 'تا تاریخ',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
name: 'sortBy',
|
||||
placeholder: 'مرتبسازی',
|
||||
defaultValue: 'count',
|
||||
options: [
|
||||
{ label: 'تعداد سفارش', value: 'count' },
|
||||
{ label: 'قیمت', value: 'price' },
|
||||
],
|
||||
},
|
||||
], []);
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { ColumnType } from '@/components/types/TableTypes';
|
||||
import type { FoodOrderReportItem } from '../types/Types';
|
||||
import { formatFaNumber, formatPrice } from '@/helpers/func';
|
||||
|
||||
export const getFoodOrderReportTableColumns = (): ColumnType<FoodOrderReportItem>[] => {
|
||||
return [
|
||||
{
|
||||
key: 'foodTitle',
|
||||
title: 'غذا',
|
||||
render: (item: FoodOrderReportItem) => item.food.title || '-',
|
||||
},
|
||||
{
|
||||
key: 'count',
|
||||
title: 'تعداد',
|
||||
render: (item: FoodOrderReportItem) => formatFaNumber(item.count),
|
||||
},
|
||||
{
|
||||
key: 'price',
|
||||
title: 'قیمت',
|
||||
render: (item: FoodOrderReportItem) => formatPrice(item.price),
|
||||
},
|
||||
{
|
||||
key: 'totalPrice',
|
||||
title: 'جمع کل',
|
||||
render: (item: FoodOrderReportItem) => formatPrice(item.totalPrice),
|
||||
},
|
||||
];
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import * as api from '../service/OrderService';
|
||||
import type { GetFoodOrderReportParams } from '../service/OrderService';
|
||||
|
||||
export const useGetFoodOrderReport = (params?: GetFoodOrderReportParams) => {
|
||||
return useQuery({
|
||||
queryKey: ['food-order-report', params],
|
||||
queryFn: () => api.getFoodOrderReport(params),
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { useState, useMemo } from 'react';
|
||||
import type { FilterValues } from '@/components/Filters';
|
||||
import type { GetFoodOrderReportParams } from '../service/OrderService';
|
||||
|
||||
export const useFoodOrderReportFilters = () => {
|
||||
const [filters, setFilters] = useState<FilterValues>({
|
||||
sortBy: 'count',
|
||||
});
|
||||
|
||||
const apiParams = useMemo(() => {
|
||||
const params: GetFoodOrderReportParams = {};
|
||||
|
||||
if (filters.from) {
|
||||
params.from = filters.from as string;
|
||||
}
|
||||
|
||||
if (filters.to) {
|
||||
params.to = filters.to as string;
|
||||
}
|
||||
|
||||
if (filters.sortBy) {
|
||||
params.sortBy = filters.sortBy as GetFoodOrderReportParams['sortBy'];
|
||||
}
|
||||
|
||||
return params;
|
||||
}, [filters]);
|
||||
|
||||
const handleFiltersChange = (newFilters: FilterValues) => {
|
||||
setFilters(newFilters);
|
||||
};
|
||||
|
||||
return {
|
||||
filters,
|
||||
apiParams,
|
||||
handleFiltersChange,
|
||||
};
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import axios from "@/config/axios";
|
||||
import type { GetOrdersResponse, GetOrderByIdResponse } from "../types/Types";
|
||||
import type { GetOrdersResponse, GetOrderByIdResponse, GetFoodOrderReportResponse } from "../types/Types";
|
||||
|
||||
export interface GetOrdersParams {
|
||||
page?: number;
|
||||
@@ -82,3 +82,19 @@ export const refundPayment = async (
|
||||
): Promise<void> => {
|
||||
await axios.post(`/admin/orders/${orderId}/refund`, params);
|
||||
};
|
||||
|
||||
export interface GetFoodOrderReportParams {
|
||||
from?: string;
|
||||
to?: string;
|
||||
sortBy?: 'count' | 'price';
|
||||
}
|
||||
|
||||
export const getFoodOrderReport = async (
|
||||
params?: GetFoodOrderReportParams
|
||||
) => {
|
||||
const { data } = await axios.get<GetFoodOrderReportResponse>(
|
||||
'/admin/orders/report/by-food',
|
||||
{ params }
|
||||
);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -220,3 +220,17 @@ export interface Order extends RowDataType {
|
||||
|
||||
export type GetOrdersResponse = IResponse<Order[]>;
|
||||
export type GetOrderByIdResponse = IResponse<Order>;
|
||||
|
||||
export interface FoodOrderReportFood {
|
||||
id: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface FoodOrderReportItem extends RowDataType {
|
||||
food: FoodOrderReportFood;
|
||||
count: number;
|
||||
price: number;
|
||||
totalPrice: number;
|
||||
}
|
||||
|
||||
export type GetFoodOrderReportResponse = IResponse<FoodOrderReportItem[]>;
|
||||
|
||||
Reference in New Issue
Block a user