Добавлено обновление кэша для расходников фулфилмента в компонентах создания и отображения заказов. Реализованы новые GraphQL запросы для получения данных о расходниках. Удалены устаревшие компоненты уведомлений о непринятых поставках для упрощения интерфейса. Оптимизирована логика отображения и обновления данных о заказах.
This commit is contained in:
263
src/components/fulfillment-warehouse/supplies-header.tsx
Normal file
263
src/components/fulfillment-warehouse/supplies-header.tsx
Normal 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>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user