179 lines
5.8 KiB
TypeScript
179 lines
5.8 KiB
TypeScript
"use client";
|
||
|
||
import { useMemo } from "react";
|
||
import { Card } from "@/components/ui/card";
|
||
import {
|
||
Clock,
|
||
CheckCircle,
|
||
Settings,
|
||
Truck,
|
||
Package,
|
||
TrendingUp,
|
||
Calendar,
|
||
DollarSign,
|
||
} from "lucide-react";
|
||
|
||
interface SupplierOrderStatsProps {
|
||
orders: Array<{
|
||
id: string;
|
||
status: string;
|
||
totalAmount: number;
|
||
totalItems: number;
|
||
createdAt: string;
|
||
}>;
|
||
}
|
||
|
||
export function SupplierOrderStats({ orders }: SupplierOrderStatsProps) {
|
||
const stats = useMemo(() => {
|
||
const pending = orders.filter((order) => order.status === "PENDING").length;
|
||
const approved = orders.filter(
|
||
(order) => order.status === "SUPPLIER_APPROVED"
|
||
).length;
|
||
const inProgress = orders.filter((order) =>
|
||
["CONFIRMED", "LOGISTICS_CONFIRMED"].includes(order.status)
|
||
).length;
|
||
const shipping = orders.filter((order) =>
|
||
["SHIPPED", "IN_TRANSIT"].includes(order.status)
|
||
).length;
|
||
const completed = orders.filter(
|
||
(order) => order.status === "DELIVERED"
|
||
).length;
|
||
|
||
const totalRevenue = orders
|
||
.filter((order) => order.status === "DELIVERED")
|
||
.reduce((sum, order) => sum + order.totalAmount, 0);
|
||
|
||
const totalItems = orders.reduce((sum, order) => sum + order.totalItems, 0);
|
||
|
||
// Заявки за сегодня
|
||
const today = new Date().toDateString();
|
||
const todayOrders = orders.filter(
|
||
(order) => new Date(order.createdAt).toDateString() === today
|
||
).length;
|
||
|
||
return {
|
||
pending,
|
||
approved,
|
||
inProgress,
|
||
shipping,
|
||
completed,
|
||
totalRevenue,
|
||
totalItems,
|
||
todayOrders,
|
||
total: orders.length,
|
||
};
|
||
}, [orders]);
|
||
|
||
return (
|
||
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
|
||
{/* Ожидают одобрения */}
|
||
<Card className="glass-card border-white/10 p-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-yellow-500/20 rounded-lg">
|
||
<Clock className="h-5 w-5 text-yellow-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">Ожидают одобрения</p>
|
||
<p className="text-xl font-bold text-white">{stats.pending}</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Одобренные */}
|
||
<Card className="glass-card border-white/10 p-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-green-500/20 rounded-lg">
|
||
<CheckCircle className="h-5 w-5 text-green-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">Одобренные</p>
|
||
<p className="text-xl font-bold text-white">{stats.approved}</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* В работе */}
|
||
<Card className="glass-card border-white/10 p-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-blue-500/20 rounded-lg">
|
||
<Settings className="h-5 w-5 text-blue-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">В работе</p>
|
||
<p className="text-xl font-bold text-white">{stats.inProgress}</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Готово к отправке / В пути */}
|
||
<Card className="glass-card border-white/10 p-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-orange-500/20 rounded-lg">
|
||
<Truck className="h-5 w-5 text-orange-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">Отгрузка/В пути</p>
|
||
<p className="text-xl font-bold text-white">{stats.shipping}</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Доставлено */}
|
||
<Card className="glass-card border-white/10 p-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-emerald-500/20 rounded-lg">
|
||
<Package className="h-5 w-5 text-emerald-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">Доставлено</p>
|
||
<p className="text-xl font-bold text-white">{stats.completed}</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Заявки за сегодня */}
|
||
<Card className="glass-card border-white/10 p-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-purple-500/20 rounded-lg">
|
||
<Calendar className="h-5 w-5 text-purple-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">За сегодня</p>
|
||
<p className="text-xl font-bold text-white">{stats.todayOrders}</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Общая выручка */}
|
||
<Card className="glass-card border-white/10 p-4 md:col-span-2">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-green-500/20 rounded-lg">
|
||
<DollarSign className="h-5 w-5 text-green-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">Выручка (завершенные)</p>
|
||
<p className="text-xl font-bold text-white">
|
||
{stats.totalRevenue.toLocaleString()}₽
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
|
||
{/* Всего товаров */}
|
||
<Card className="glass-card border-white/10 p-4 md:col-span-2">
|
||
<div className="flex items-center space-x-3">
|
||
<div className="p-2 bg-blue-500/20 rounded-lg">
|
||
<TrendingUp className="h-5 w-5 text-blue-400" />
|
||
</div>
|
||
<div>
|
||
<p className="text-white/60 text-sm">Всего товаров в заявках</p>
|
||
<p className="text-xl font-bold text-white">
|
||
{stats.totalItems.toLocaleString()} шт.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
</div>
|
||
);
|
||
}
|