+ {/* Хлебные крошки и заголовок */}
+
+
+
+
+
+
+
+
+ Расходники фулфилмента
+
+
+ Управление расходными материалами и инвентарем
+
+
+
+
+
+ {/* Переключатель режимов просмотра */}
+
+
+
+
+
+
+ {/* Группировка */}
+
+
+ {/* Экспорт */}
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Статистические карточки */}
+
+
+
+
+
+
Всего
+
{stats.total}
+
+
+
+
+
+
+
+
+
+
+
Доступно
+
+ {stats.available}
+
+
+
+
+
+
+
+
+
+
Мало
+
+ {stats.lowStock}
+
+
+
+
+
+
+
+
+
+
Нет в наличии
+
+ {stats.outOfStock}
+
+
+
+
+
+
+
+
+
+
+
+
В пути
+
+ {stats.inTransit}
+
+
+
+
+
+
+
+
+
+
+
+
Стоимость
+
+ {formatCurrency(stats.totalValue)}
+
+
+
+
+
+
+
+
+
+
+
+
Категории
+
+ {stats.categories}
+
+
+
+
+
+
+
+
+
+
+
+
Поставщики
+
+ {stats.suppliers}
+
+
+
+
+
+
+ {/* Панель фильтров и поиска */}
+
+
+ {/* Основная строка поиска и кнопок */}
+
+
+
+
+ handleFilterChange("search", e.target.value)
+ }
+ className="pl-10 bg-white/5 border-white/10 text-white placeholder:text-white/40"
+ />
+
+
+
+
+
+
+
+ {/* Расширенные фильтры */}
+ {showFilters && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
+
+ {/* Заголовки сортировки для списочного вида */}
+ {viewMode === "list" && (
+
+
+
+
+
+
+
+
+
+ Действия
+
+
+ )}
+
+ {/* Список расходников */}
+ {loading ? (
+
+ {Array.from({ length: 8 }).map((_, i) => (
+
+
+
+
+
+ ))}
+
+ ) : filteredAndSortedSupplies.length === 0 ? (
+
+
+
+ Расходники не найдены
+
+
+ Попробуйте изменить параметры поиска или фильтрации
+
+
+ ) : viewMode === "analytics" ? (
+ // Аналитический режим с графиками
+
+ {/* Графики аналитики */}
+
+ {/* Распределение по категориям */}
+
+
+
+ {analyticsData.categoryStats.map((item, index) => {
+ const colors = [
+ "bg-blue-500",
+ "bg-green-500",
+ "bg-yellow-500",
+ "bg-purple-500",
+ "bg-pink-500",
+ ];
+ const color = colors[index % colors.length];
+ const percentage =
+ stats.total > 0 ? (item.count / stats.total) * 100 : 0;
+
+ return (
+
+
+ {item.name}
+
+ {item.count}
+
+
+
+
+ {percentage.toFixed(1)}%
+ {formatCurrency(item.value)}
+
+
+ );
+ })}
+
+
+
+ {/* Распределение по статусам */}
+
+
+
+
+
+
+ По статусам
+
+
+
+ {analyticsData.statusStats.map((item, index) => {
+ const colors = [
+ "bg-green-500",
+ "bg-yellow-500",
+ "bg-red-500",
+ "bg-blue-500",
+ "bg-purple-500",
+ ];
+ const color = colors[index % colors.length];
+ const percentage =
+ stats.total > 0 ? (item.count / stats.total) * 100 : 0;
+
+ return (
+
+
+ {item.name}
+
+ {item.count}
+
+
+
+
+ {percentage.toFixed(1)}%
+ {formatCurrency(item.value)}
+
+
+ );
+ })}
+
+
+
+ {/* ТОП поставщики */}
+
+
+
+
+
+
+ ТОП поставщики
+
+
+
+ {analyticsData.supplierStats
+ .sort((a, b) => b.value - a.value)
+ .slice(0, 5)
+ .map((item, index) => {
+ const colors = [
+ "bg-gold-500",
+ "bg-silver-500",
+ "bg-bronze-500",
+ "bg-blue-500",
+ "bg-green-500",
+ ];
+ const color = colors[index] || "bg-gray-500";
+ const maxValue = Math.max(
+ ...analyticsData.supplierStats.map((s) => s.value)
+ );
+ const percentage =
+ maxValue > 0 ? (item.value / maxValue) * 100 : 0;
+
+ return (
+
+
+
+
+ #{index + 1}
+
+
+ {item.name}
+
+
+
+ {item.count}
+
+
+
+
+ {formatCurrency(item.value)}
+
+
+ );
+ })}
+
+
+
+
+ {/* Дополнительные метрики */}
+
+
+
+
+
+
+
+
Средняя цена
+
+ {consolidatedSupplies.length > 0
+ ? formatCurrency(
+ consolidatedSupplies.reduce(
+ (sum, s) => sum + s.price,
+ 0
+ ) / consolidatedSupplies.length
+ )
+ : "0 ₽"}
+
+
+
+
+
+
+
+
+
+
Средний остаток
+
+ {consolidatedSupplies.length > 0
+ ? Math.round(
+ consolidatedSupplies.reduce(
+ (sum, s) => sum + s.currentStock,
+ 0
+ ) / consolidatedSupplies.length
+ )
+ : 0}
+
+
+
+
+
+
+
+
+
+
+ Критический остаток
+
+
+ {
+ consolidatedSupplies.filter(
+ (s) => s.currentStock === 0
+ ).length
+ }
+
+
+
+
+
+
+
+
+
+
+
+
Оборачиваемость
+
+ {((stats.available / stats.total) * 100).toFixed(1)}%
+
+
+
+
+
+
+ ) : groupBy !== "none" ? (
+ // Группированный вид
+
+ {Object.entries(groupedSupplies).map(
+ ([groupName, groupSupplies]) => (
+
+
+
+
+
+ {groupName}
+
+ {groupSupplies.length}
+
+
+
+ Общая стоимость:{" "}
+ {formatCurrency(
+ groupSupplies.reduce(
+ (sum, s) => sum + s.price * s.currentStock,
+ 0
+ )
+ )}
+
+
+
+
+
+ {groupSupplies.map((supply) => {
+ const statusConfig = getStatusConfig(supply.status);
+ 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 (
+
+
toggleSupplyExpansion(supply.id)}
+ >
+
+
+
+ {expandedSupplies.has(supply.id) ? (
+
+ ) : (
+
+ )}
+
+
+
+ {supply.name}
+
+
+ {supply.description}
+
+
+
+
+
+ {getSupplyDeliveries(supply).length}
+
+
+
+ {statusConfig.label}
+
+
+
+
+
+
+
+ Остаток:
+
+
+ {formatNumber(supply.currentStock)}{" "}
+ {supply.unit}
+
+
+
+
+ Цена:
+
+ {formatCurrency(supply.price)}
+
+
+
+
+
+ {/* Развернутые поставки для группированного режима */}
+ {expandedSupplies.has(supply.id) && (
+
+
+
+ Поставки
+
+
+ {getSupplyDeliveries(supply).map((delivery, deliveryIndex) => {
+ const deliveryStatusConfig = getStatusConfig(delivery.status);
+ const DeliveryStatusIcon = deliveryStatusConfig.icon;
+
+ return (
+
+
+
+
+
+ {deliveryStatusConfig.label}
+
+
+ {new Date(delivery.createdAt).toLocaleDateString("ru-RU", {
+ month: "short",
+ day: "numeric"
+ })}
+
+
+
+
+ {formatNumber(delivery.currentStock)} {delivery.unit}
+
+
+ {formatCurrency(delivery.price * delivery.currentStock)}
+
+
+
+
+ );
+ })}
+
+ )}
+
+ );
+ })}
+
+
+
+ )
+ )}
+
+ ) : viewMode === "grid" ? (
+
const statusConfig = getStatusConfig(supply.status);
+ 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 (
+
+ {/* Основная карточка расходника */}
+
toggleSupplyExpansion(supply.id)}
+ >
+ {/* Заголовок карточки */}
+
+
+
+ {expandedSupplies.has(supply.id) ? (
+
+ ) : (
+
+ )}
+
+
+
+ {supply.name}
+
+
+ {supply.description}
+
+
+
+
+
+ {getSupplyDeliveries(supply).length} поставок
+
+
+
+ {statusConfig.label}
+
+
+
+
+ {/* Статистика остатков */}
+
+
+ Остаток:
+
+ {formatNumber(supply.currentStock)} {supply.unit}
+
+
+
+ {/* Прогресс-бар остатков */}
+
+
+
+ Мин. остаток:
+
+ {formatNumber(supply.minStock)} {supply.unit}
+
+
+
+
+ {/* Дополнительная информация */}
+
+
+ Категория:
+
+ {supply.category}
+
+
+
+ Цена:
+
+ {formatCurrency(supply.price)}
+
+
+
+ Поставщик:
+
+ {supply.supplier}
+
+
+
+
+ {/* Действия */}
+
+
+
+
+
+
+ {/* Развернутые поставки */}
+ {expandedSupplies.has(supply.id) && (
+
+
+
+ История поставок
+
+
+ {getSupplyDeliveries(supply).map(
+ (delivery, deliveryIndex) => {
+ const deliveryStatusConfig = getStatusConfig(
+ delivery.status
+ );
+ const DeliveryStatusIcon =
+ deliveryStatusConfig.icon;
+
+ return (
+
+
+
+
+
+
+ {deliveryStatusConfig.label}
+
+
+ {new Date(
+ delivery.createdAt
+ ).toLocaleDateString("ru-RU", {
+ year: "numeric",
+ month: "short",
+ day: "numeric",
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+
+
+
+
+
+
Остаток
+
+ {formatNumber(delivery.currentStock)}{" "}
+ {delivery.unit}
+
+
+
+
+ Заказано
+
+
+ {formatNumber(delivery.quantity)}{" "}
+ {delivery.unit}
+
+
+
+
Цена
+
+ {formatCurrency(delivery.price)}
+
+
+
+
+ Стоимость
+
+
+ {formatCurrency(
+ delivery.price *
+ delivery.currentStock
+ )}
+
+
+
+
+ {delivery.description &&
+ delivery.description !==
+ supply.description && (
+
+
+ Описание
+
+
+ {delivery.description}
+
+
+ )}
+
+
+
+ );
+ }
+ )}
+
+ {/* Итоговая статистика по поставкам */}
+
+
+
+
Всего поставок
+
+ {getSupplyDeliveries(supply).length}
+
+
+
+
Общая стоимость
+
+ {formatCurrency(
+ getSupplyDeliveries(supply).reduce(
+ (sum, d) => sum + d.price * d.currentStock,
+ 0
+ )
+ )}
+
+
+
+
+
+ )}
+
+ );
+ })}
+
+ ) : (
+ // Списочный вид
+
+ {filteredAndSortedSupplies.map((supply) => {
+ const statusConfig = getStatusConfig(supply.status);
+ const StatusIcon = statusConfig.icon;
+ const isLowStock =
+ supply.currentStock <= supply.minStock &&
+ supply.currentStock > 0;
+
+ return (
+
+
toggleSupplyExpansion(supply.id)}
+ >
+
+
+
+ {expandedSupplies.has(supply.id) ? (
+
+ ) : (
+
+ )}
+
+
+
{supply.name}
+
+ {supply.description}
+
+
+
+
+
+
+ {supply.category}
+
+
+
+
+
+ {getSupplyDeliveries(supply).length}
+
+
+
+ {statusConfig.label}
+
+
+
+
+ {formatNumber(supply.currentStock)} {supply.unit}
+
+
+
+ {formatNumber(supply.minStock)} {supply.unit}
+
+
+
+ {formatCurrency(supply.price)}
+
+
+
+ {supply.supplier}
+
+
+
+
+
+
+ {/* Развернутые поставки для списочного режима */}
+ {expandedSupplies.has(supply.id) && (
+
+
+
+ История поставок
+
+
+ {getSupplyDeliveries(supply).map((delivery, deliveryIndex) => {
+ const deliveryStatusConfig = getStatusConfig(delivery.status);
+ const DeliveryStatusIcon = deliveryStatusConfig.icon;
+
+ return (
+
+
+
+
+
+ {deliveryStatusConfig.label}
+
+
+
+
+
Дата
+
+ {new Date(delivery.createdAt).toLocaleDateString("ru-RU", {
+ month: "short",
+ day: "numeric",
+ hour: "2-digit",
+ minute: "2-digit"
+ })}
+
+
+
+
+
Остаток
+
+ {formatNumber(delivery.currentStock)} {delivery.unit}
+
+
+
+
+
Заказано
+
+ {formatNumber(delivery.quantity)} {delivery.unit}
+
+
+
+
+
Цена
+
+ {formatCurrency(delivery.price)}
+
+
+
+
+
Стоимость
+
+ {formatCurrency(delivery.price * delivery.currentStock)}
+
+
+
+
+ {delivery.description && delivery.description !== supply.description && (
+
+
Описание: {delivery.description}
+
+ )}
+
+ );
+ })}
+
+ )}
+
+ );
+ })}
+
+ )}
+
+ {/* Пагинация (если нужна) */}
+ {filteredAndSortedSupplies.length > 0 && (
+
+
+ Показано {filteredAndSortedSupplies.length} из{" "}
+ {consolidatedSupplies.length} расходников (объединено из{" "}
+ {supplies.length} записей)
+
+
+ )}
+
+