dahsboard connected to backend

This commit is contained in:
nabijonovdavronbek619@gmail.com
2026-04-07 13:11:23 +05:00
parent df485b5797
commit b09e2ebc59
4 changed files with 53 additions and 28 deletions

View File

@@ -1,6 +1,16 @@
import React from 'react';
import { TrendingUp, Calendar, Tag, Wallet } from 'lucide-react';
import type { CabinetStats } from '../../lib/types';
import { TrendingUp, Calendar, Wallet, Loader2 } from 'lucide-react';
import { useQuery } from '@tanstack/react-query';
import { apiRequest } from '@/shared/request/apiRequest';
import { links } from '@/shared/request/links';
// ─── Types ─────────────────────────────────────────────────────────────────────
type Stats = {
total_documents: number;
this_month_documents: number;
paid_price: number;
};
// ─── Single stat card ──────────────────────────────────────────────────────────
@@ -33,46 +43,62 @@ const StatCard: React.FC<StatCardProps> = ({
</div>
);
const StatCardSkeleton = () => (
<div className="bg-white rounded-2xl border border-slate-100 p-5 shadow-sm animate-pulse">
<div className="w-10 h-10 rounded-xl bg-slate-100 mb-4" />
<div className="h-7 w-16 bg-slate-100 rounded mb-2" />
<div className="h-3 w-24 bg-slate-100 rounded" />
</div>
);
// ─── Grid ──────────────────────────────────────────────────────────────────────
interface StatsCardsProps {
stats: CabinetStats;
}
export const StatsCards = () => {
const { data, isLoading } = useQuery({
queryKey: ['statistics'],
queryFn: (): Promise<Stats> =>
apiRequest('GET', links.statistics).then((res) => res.data as Stats),
});
export const StatsCards: React.FC<StatsCardsProps> = ({ stats }) => {
const discountPct = Math.round(
(stats.discountUsed / stats.discountTotal) * 100,
);
if (isLoading) {
return (
<div className="grid grid-cols-2 lg:grid-cols-3 gap-4">
<StatCardSkeleton />
<StatCardSkeleton />
<StatCardSkeleton />
</div>
);
}
if (!data) {
return (
<div className="flex items-center justify-center py-10 gap-2 text-slate-400">
<Loader2 size={18} className="animate-spin" />
<span className="text-sm">Ma&apos;lumot topilmadi</span>
</div>
);
}
return (
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
<div className="grid grid-cols-2 lg:grid-cols-3 gap-4">
<StatCard
icon={TrendingUp}
label="Jami tekshiruvlar"
value={String(stats.total)}
value={String(data.total_documents)}
iconColor="text-blue-600"
iconBg="bg-blue-50"
/>
<StatCard
icon={Calendar}
label="Bu oy"
value={String(stats.thisMonth)}
sub={`${stats.discountUsed}/${stats.discountTotal} ta hujjat`}
value={String(data.this_month_documents)}
iconColor="text-emerald-600"
iconBg="bg-emerald-50"
/>
<StatCard
icon={Tag}
label="Chegirma holati"
value={`${discountPct}%`}
sub={`${stats.discountUsed}/${stats.discountTotal} ta ishlatilgan`}
iconColor="text-amber-600"
iconBg="bg-amber-50"
/>
<StatCard
icon={Wallet}
label="Balans"
value={`${stats.balance.toLocaleString()} ${stats.currency}`}
label="To'langan summa"
value={`${data.paid_price.toLocaleString('uz-UZ')} UZS`}
iconColor="text-violet-600"
iconBg="bg-violet-50"
/>