Добавлено обновление кэша для расходников фулфилмента в компонентах создания и отображения заказов. Реализованы новые GraphQL запросы для получения данных о расходниках. Удалены устаревшие компоненты уведомлений о непринятых поставках для упрощения интерфейса. Оптимизирована логика отображения и обновления данных о заказах.

This commit is contained in:
Veronika Smirnova
2025-07-29 17:45:29 +03:00
parent 7877f61d5a
commit 50438bb21f
18 changed files with 3693 additions and 191 deletions

View File

@ -0,0 +1,171 @@
"use client";
import React from "react";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Progress } from "@/components/ui/progress";
import {
Package,
TrendingUp,
TrendingDown,
Calendar,
MapPin,
User,
} from "lucide-react";
import { SupplyCardProps } from "./types";
export function SupplyCard({
supply,
isExpanded,
onToggleExpansion,
statusConfig,
getSupplyDeliveries,
}: SupplyCardProps) {
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB",
minimumFractionDigits: 0,
}).format(amount);
};
const formatNumber = (num: number) => {
return new Intl.NumberFormat("ru-RU").format(num);
};
const StatusIcon = statusConfig.icon;
const isLowStock =
supply.currentStock <= supply.minStock && supply.currentStock > 0;
const stockPercentage =
supply.minStock > 0 ? (supply.currentStock / supply.minStock) * 100 : 100;
return (
<div>
{/* Основная карточка расходника */}
<Card
className="glass-card p-4 hover:bg-white/15 transition-all duration-300 cursor-pointer group"
onClick={() => onToggleExpansion(supply.id)}
>
{/* Заголовок карточки */}
<div className="flex items-start justify-between mb-3">
<div className="flex-1 min-w-0">
<div className="flex items-center space-x-2 mb-1">
<h3 className="font-semibold text-white truncate group-hover:text-blue-300 transition-colors">
{supply.name}
</h3>
</div>
<p className="text-sm text-white/60 truncate">
{supply.description}
</p>
</div>
<div className="flex items-center space-x-2 ml-2">
<Badge className={`${statusConfig.color} text-xs`}>
<StatusIcon className="h-3 w-3 mr-1" />
{statusConfig.label}
</Badge>
</div>
</div>
{/* Основная информация */}
<div className="space-y-3">
{/* Остатки и прогресс-бар */}
<div>
<div className="flex items-center justify-between text-sm mb-1">
<span className="text-white/60">Остаток</span>
<span
className={`font-medium ${
isLowStock ? "text-yellow-300" : "text-white"
}`}
>
{formatNumber(supply.currentStock)} /{" "}
{formatNumber(supply.minStock)} {supply.unit}
</span>
</div>
<Progress
value={Math.min(stockPercentage, 100)}
className="h-2 bg-white/10"
style={{
background: `linear-gradient(to right, ${
stockPercentage > 50
? "#10b981"
: stockPercentage > 20
? "#f59e0b"
: "#ef4444"
} 0%, ${
stockPercentage > 50
? "#10b981"
: stockPercentage > 20
? "#f59e0b"
: "#ef4444"
} ${Math.min(
stockPercentage,
100
)}%, rgba(255,255,255,0.1) ${Math.min(stockPercentage, 100)}%)`,
}}
/>
</div>
{/* Метрики */}
<div className="grid grid-cols-2 gap-3 text-sm">
<div className="flex items-center space-x-2">
<div className="p-1 bg-blue-500/20 rounded">
<Package className="h-3 w-3 text-blue-300" />
</div>
<div>
<p className="text-white/60 text-xs">Цена</p>
<p className="text-white font-medium">
{formatCurrency(supply.price)}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<div className="p-1 bg-purple-500/20 rounded">
<TrendingUp className="h-3 w-3 text-purple-300" />
</div>
<div>
<p className="text-white/60 text-xs">Стоимость</p>
<p className="text-white font-medium">
{formatCurrency(
supply.totalCost || supply.price * supply.quantity
)}
</p>
</div>
</div>
</div>
{/* Дополнительная информация */}
<div className="flex items-center justify-between text-xs">
<div className="flex items-center space-x-1">
<Badge
variant="outline"
className="text-xs border-white/20 text-white/80"
>
{supply.category}
</Badge>
<Badge className="bg-blue-500/20 text-blue-300 text-xs">
{getSupplyDeliveries(supply).length} поставок
</Badge>
</div>
</div>
{/* Поставщик и дата */}
<div className="flex items-center justify-between text-xs text-white/60">
<div className="flex items-center space-x-1">
<User className="h-3 w-3" />
<span className="truncate max-w-[120px]" title={supply.supplier}>
{supply.supplier}
</span>
</div>
<div className="flex items-center space-x-1">
<Calendar className="h-3 w-3" />
<span>
{new Date(supply.createdAt).toLocaleDateString("ru-RU")}
</span>
</div>
</div>
</div>
</Card>
</div>
);
}