@@ -0,0 +1,12 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import * as api from '../service/DashboardService';
|
||||||
|
|
||||||
|
const DASHBOARD_COUNTS_REFETCH_MS = 2 * 60 * 1000;
|
||||||
|
|
||||||
|
export const useGetDashboardCounts = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ['dashboard-counts'],
|
||||||
|
queryFn: () => api.getDashboardCounts(),
|
||||||
|
refetchInterval: DASHBOARD_COUNTS_REFETCH_MS,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import axios from '@/config/axios';
|
||||||
|
import type { BaseResponse } from '@/shared/types/Types';
|
||||||
|
|
||||||
|
export type DashboardCountsType = {
|
||||||
|
requestsCount: number;
|
||||||
|
invoicesCount: number;
|
||||||
|
ordersCount: number;
|
||||||
|
paymentsCount: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDashboardCounts = async (): Promise<BaseResponse<DashboardCountsType>> => {
|
||||||
|
const { data } = await axios.get<BaseResponse<DashboardCountsType>>('/public/dashboard/counts');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
@@ -7,11 +7,14 @@ import { Paths } from '../config/Paths'
|
|||||||
import { useSharedStore } from './store/useSharedStore'
|
import { useSharedStore } from './store/useSharedStore'
|
||||||
import { clx } from '../helpers/utils'
|
import { clx } from '../helpers/utils'
|
||||||
import { t } from '../locale'
|
import { t } from '../locale'
|
||||||
|
import { useGetDashboardCounts } from '@/pages/dashboard/hooks/useDashboardData'
|
||||||
|
|
||||||
const SideBar: FC = () => {
|
const SideBar: FC = () => {
|
||||||
|
|
||||||
const { openSidebar, setOpenSidebar } = useSharedStore()
|
const { openSidebar, setOpenSidebar } = useSharedStore()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const { data: dashboardCounts } = useGetDashboardCounts()
|
||||||
|
const counts = dashboardCounts?.data
|
||||||
|
|
||||||
const isActive = (name: string) => {
|
const isActive = (name: string) => {
|
||||||
return location.pathname.includes(name)
|
return location.pathname.includes(name)
|
||||||
@@ -56,6 +59,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.myRequests')}
|
title={t('sidebar.myRequests')}
|
||||||
isActive={isActive('request')}
|
isActive={isActive('request')}
|
||||||
link={Paths.request.myRequest}
|
link={Paths.request.myRequest}
|
||||||
|
badge={counts?.requestsCount}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -63,6 +67,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.preFactors')}
|
title={t('sidebar.preFactors')}
|
||||||
isActive={isActive('/proforma-invoice')}
|
isActive={isActive('/proforma-invoice')}
|
||||||
link={Paths.proformaInvoice}
|
link={Paths.proformaInvoice}
|
||||||
|
badge={counts?.invoicesCount}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -70,6 +75,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.myOrders')}
|
title={t('sidebar.myOrders')}
|
||||||
isActive={isActive('order')}
|
isActive={isActive('order')}
|
||||||
link={Paths.order.myOrders}
|
link={Paths.order.myOrders}
|
||||||
|
badge={counts?.ordersCount}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ type Props = {
|
|||||||
isActive: boolean,
|
isActive: boolean,
|
||||||
link: string,
|
link: string,
|
||||||
isLogout?: boolean,
|
isLogout?: boolean,
|
||||||
isWithoutLine?: boolean
|
isWithoutLine?: boolean,
|
||||||
|
badge?: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
const SideBarItem: FC<Props> = (props: Props) => {
|
const SideBarItem: FC<Props> = (props: Props) => {
|
||||||
@@ -28,7 +29,7 @@ const SideBarItem: FC<Props> = (props: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link onClick={props.isLogout ? handleLogout : undefined} to={props.link} className={clx(
|
<Link onClick={props.isLogout ? handleLogout : undefined} to={props.link} className={clx(
|
||||||
'h-12 rounded-2xl flex gap-2 text-[#4F5260] px-4 text-[13px] items-center',
|
'h-12 rounded-2xl flex justify-between gap-2 text-[#4F5260] px-4 text-[13px] items-center',
|
||||||
props.isActive && 'bg-[#F5F7FC]',
|
props.isActive && 'bg-[#F5F7FC]',
|
||||||
)}>
|
)}>
|
||||||
<div className='flex gap-3 items-center'>
|
<div className='flex gap-3 items-center'>
|
||||||
@@ -37,7 +38,11 @@ const SideBarItem: FC<Props> = (props: Props) => {
|
|||||||
{props.title}
|
{props.title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{props.badge != null && props.badge > 0 && (
|
||||||
|
<span className="min-w-5 h-5 px-1.5 rounded-full bg-[#FFEDCA] text-[#FF7B00] text-[10px] font-medium flex items-center justify-center">
|
||||||
|
{props.badge > 99 ? '99+' : props.badge}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user