Добавлено обновление кэша для расходников фулфилмента в компонентах создания и отображения заказов. Реализованы новые 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,263 @@
"use client";
import React from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import {
ArrowLeft,
Search,
Filter,
BarChart3,
Grid3X3,
List,
Download,
RotateCcw,
Layers,
} from "lucide-react";
import { SuppliesHeaderProps } from "./types";
export function SuppliesHeader({
viewMode,
onViewModeChange,
groupBy,
onGroupByChange,
filters,
onFiltersChange,
showFilters,
onToggleFilters,
onExport,
onRefresh,
}: SuppliesHeaderProps) {
const router = useRouter();
const handleFilterChange = (key: keyof typeof filters, value: any) => {
onFiltersChange({ ...filters, [key]: value });
};
return (
<div className="space-y-6">
{/* Заголовок страницы */}
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4">
<Button
variant="ghost"
size="sm"
onClick={() => router.back()}
className="text-white/70 hover:text-white hover:bg-white/10"
>
<ArrowLeft className="h-4 w-4 mr-2" />
Назад
</Button>
<div>
<h1 className="text-2xl font-bold text-white mb-1">
Расходники фулфилмента
</h1>
<p className="text-white/60 text-sm">
Управление расходными материалами фулфилмент-центра
</p>
</div>
</div>
<div className="flex items-center space-x-3">
{/* Экспорт данных */}
<Button
variant="outline"
size="sm"
onClick={onExport}
className="border-white/20 text-white/70 hover:text-white hover:bg-white/10"
>
<Download className="h-4 w-4 mr-2" />
Экспорт
</Button>
{/* Обновить */}
<Button
variant="outline"
size="sm"
onClick={onRefresh}
className="border-white/20 text-white/70 hover:text-white hover:bg-white/10"
>
<RotateCcw className="h-4 w-4" />
</Button>
</div>
</div>
{/* Панель управления */}
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4">
{/* Поиск */}
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-white/40" />
<Input
placeholder="Поиск расходников..."
value={filters.search}
onChange={(e) => handleFilterChange("search", e.target.value)}
className="pl-10 w-64 bg-white/5 border-white/20 text-white placeholder:text-white/40 focus:border-blue-400"
/>
</div>
{/* Фильтры */}
<Button
variant="outline"
size="sm"
onClick={onToggleFilters}
className={`border-white/20 ${
showFilters
? "bg-white/10 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
}`}
>
<Filter className="h-4 w-4 mr-2" />
Фильтры
{(filters.category ||
filters.status ||
filters.supplier ||
filters.lowStock) && (
<Badge className="ml-2 bg-blue-500/20 text-blue-300 text-xs">
{
[
filters.category,
filters.status,
filters.supplier,
filters.lowStock,
].filter(Boolean).length
}
</Badge>
)}
</Button>
</div>
<div className="flex items-center space-x-3">
{/* Переключатель режимов просмотра */}
<div className="flex items-center bg-white/5 rounded-lg p-1">
<Button
variant={viewMode === "grid" ? "default" : "ghost"}
size="sm"
onClick={() => onViewModeChange("grid")}
className={`h-8 px-3 ${
viewMode === "grid"
? "bg-blue-500 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
}`}
>
<Grid3X3 className="h-4 w-4" />
</Button>
<Button
variant={viewMode === "list" ? "default" : "ghost"}
size="sm"
onClick={() => onViewModeChange("list")}
className={`h-8 px-3 ${
viewMode === "list"
? "bg-blue-500 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
}`}
>
<List className="h-4 w-4" />
</Button>
<Button
variant={viewMode === "analytics" ? "default" : "ghost"}
size="sm"
onClick={() => onViewModeChange("analytics")}
className={`h-8 px-3 ${
viewMode === "analytics"
? "bg-blue-500 text-white"
: "text-white/70 hover:text-white hover:bg-white/10"
}`}
>
<BarChart3 className="h-4 w-4" />
</Button>
</div>
{/* Группировка */}
{viewMode !== "analytics" && (
<div className="flex items-center space-x-2">
<Layers className="h-4 w-4 text-white/60" />
<select
value={groupBy}
onChange={(e) => onGroupByChange(e.target.value as any)}
className="bg-white/5 border border-white/20 rounded-md px-3 py-1 text-sm text-white focus:border-blue-400 focus:outline-none"
>
<option value="none">Без группировки</option>
<option value="category">По категориям</option>
<option value="status">По статусу</option>
<option value="supplier">По поставщикам</option>
</select>
</div>
)}
</div>
</div>
{/* Развернутые фильтры */}
{showFilters && (
<div className="bg-white/5 rounded-lg p-4 space-y-4">
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<label className="block text-sm font-medium text-white/70 mb-2">
Категория
</label>
<select
value={filters.category}
onChange={(e) => handleFilterChange("category", e.target.value)}
className="w-full bg-white/5 border border-white/20 rounded-md px-3 py-2 text-sm text-white focus:border-blue-400 focus:outline-none"
>
<option value="">Все категории</option>
<option value="packaging">Упаковка</option>
<option value="tools">Инструменты</option>
<option value="maintenance">Обслуживание</option>
<option value="office">Офисные принадлежности</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-white/70 mb-2">
Статус
</label>
<select
value={filters.status}
onChange={(e) => handleFilterChange("status", e.target.value)}
className="w-full bg-white/5 border border-white/20 rounded-md px-3 py-2 text-sm text-white focus:border-blue-400 focus:outline-none"
>
<option value="">Все статусы</option>
<option value="available">Доступен</option>
<option value="low-stock">Мало на складе</option>
<option value="out-of-stock">Нет в наличии</option>
<option value="in-transit">В пути</option>
<option value="reserved">Зарезервирован</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-white/70 mb-2">
Поставщик
</label>
<Input
placeholder="Поставщик..."
value={filters.supplier}
onChange={(e) => handleFilterChange("supplier", e.target.value)}
className="bg-white/5 border-white/20 text-white placeholder:text-white/40 focus:border-blue-400"
/>
</div>
<div className="flex items-center space-x-2 pt-6">
<input
type="checkbox"
id="lowStock"
checked={filters.lowStock}
onChange={(e) =>
handleFilterChange("lowStock", e.target.checked)
}
className="rounded border-white/20 bg-white/5 text-blue-500 focus:ring-blue-400"
/>
<label htmlFor="lowStock" className="text-sm text-white/70">
Только с низким остатком
</label>
</div>
</div>
</div>
)}
</div>
);
}