top stats
This commit is contained in:
@@ -3,8 +3,24 @@ import { type FC } from 'react'
|
|||||||
import FoodSalesChart from './components/FoodSalesChart'
|
import FoodSalesChart from './components/FoodSalesChart'
|
||||||
import RevenueChart from './components/RevenueChart'
|
import RevenueChart from './components/RevenueChart'
|
||||||
import StatCard from './components/StatCard'
|
import StatCard from './components/StatCard'
|
||||||
|
import { useGetStatistics } from './hooks/useStatsData'
|
||||||
|
import { formatFaNumber, formatPrice } from '@/helpers/func'
|
||||||
|
import PageLoading from '@/components/PageLoading'
|
||||||
|
|
||||||
const Statistics: FC = () => {
|
const Statistics: FC = () => {
|
||||||
|
|
||||||
|
const { data: statisticsData, isLoading } = useGetStatistics();
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<div className='p-6 max-w-[1600px] mx-auto flex justify-center items-center min-h-[400px]'>
|
||||||
|
<PageLoading />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stats = statisticsData?.data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='p-6 max-w-[1600px] mx-auto'>
|
<div className='p-6 max-w-[1600px] mx-auto'>
|
||||||
{/* Stats Cards */}
|
{/* Stats Cards */}
|
||||||
@@ -12,25 +28,25 @@ const Statistics: FC = () => {
|
|||||||
<StatCard
|
<StatCard
|
||||||
icon={<Category size={24} color='#6B7FED' />}
|
icon={<Category size={24} color='#6B7FED' />}
|
||||||
title='غذاها'
|
title='غذاها'
|
||||||
value='۱۰۴ عددی'
|
value={`${formatFaNumber(stats?.activeFoods)} عددی`}
|
||||||
color='#6B7FED'
|
color='#6B7FED'
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={<People size={24} color='#6B7FED' />}
|
icon={<People size={24} color='#6B7FED' />}
|
||||||
title='مشتریان'
|
title='مشتریان'
|
||||||
value='۲۶۰ مشتری'
|
value={`${formatFaNumber(stats?.totalClients)} مشتری`}
|
||||||
color='#6B7FED'
|
color='#6B7FED'
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={<DocumentText size={24} color='#FF9A62' />}
|
icon={<DocumentText size={24} color='#FF9A62' />}
|
||||||
title='سفارشات'
|
title='سفارشات'
|
||||||
value='۳۰۳ سفارش'
|
value={`${formatFaNumber(stats?.totalOrders)} سفارش`}
|
||||||
color='#FF9A62'
|
color='#FF9A62'
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={<DollarCircle size={24} color='#10B981' />}
|
icon={<DollarCircle size={24} color='#10B981' />}
|
||||||
title='درآمد'
|
title='درآمد'
|
||||||
value='۲۰,۰۰۰,۰۰۰ تومان'
|
value={stats?.totalRevenue ? formatPrice(stats.totalRevenue) : '۰ تومان'}
|
||||||
color='#10B981'
|
color='#10B981'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import * as api from "../service/StatisticsService";
|
||||||
|
|
||||||
|
export const useGetStatistics = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["statistics"],
|
||||||
|
queryFn: api.getStatistics,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetFoodSalesPieChart = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["food-sales-pie-chart"],
|
||||||
|
queryFn: api.getFoodSalesPieChart,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import axios from "@/config/axios";
|
||||||
|
import type { IStatisticsResponse } from "../types/Types";
|
||||||
|
|
||||||
|
export const getStatistics = async (): Promise<IStatisticsResponse> => {
|
||||||
|
const { data } = await axios.get<IStatisticsResponse>("/admin/orders/stats");
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFoodSalesPieChart = async () => {
|
||||||
|
const { data } = await axios.get("/admin/orders/food-sales-pie-chart");
|
||||||
|
return data;
|
||||||
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import type { IResponse } from "@/types/response.types";
|
||||||
|
|
||||||
|
export interface IStatisticsData {
|
||||||
|
totalOrders: number;
|
||||||
|
activeFoods: number;
|
||||||
|
totalClients: number;
|
||||||
|
totalRevenue: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IStatisticsResponse = IResponse<IStatisticsData>;
|
||||||
@@ -60,6 +60,8 @@ const MainRouter: FC = () => {
|
|||||||
)}>
|
)}>
|
||||||
<div className='pb-20'>
|
<div className='pb-20'>
|
||||||
<Routes>
|
<Routes>
|
||||||
|
<Route path={Pages.dashboard} element={<Statistics />} />
|
||||||
|
|
||||||
<Route path={Pages.foods.list} element={<FoodsList />} />
|
<Route path={Pages.foods.list} element={<FoodsList />} />
|
||||||
<Route path={Pages.foods.add} element={<CreateFood />} />
|
<Route path={Pages.foods.add} element={<CreateFood />} />
|
||||||
<Route path={Pages.foods.update + ':id'} element={<UpdateFood />} />
|
<Route path={Pages.foods.update + ':id'} element={<UpdateFood />} />
|
||||||
|
|||||||
Reference in New Issue
Block a user