Обновлен компонент SuppliesDashboard: изменены активные вкладки на "Все" и "Товары", добавлены новые компоненты для отображения всех поставок и товаров. Оптимизирована логика отображения уведомлений о количестве ожидающих заказов. В компоненте RealSupplyOrdersTab добавлены функции фильтрации и сортировки заказов, улучшен интерфейс для отображения статистики и информации о заказах.

This commit is contained in:
Veronika Smirnova
2025-07-28 14:38:17 +03:00
parent ac67b1e1ec
commit 37049d21c6
4 changed files with 819 additions and 390 deletions

View File

@ -8,10 +8,19 @@ import { Sidebar } from "@/components/dashboard/sidebar";
import { useSidebar } from "@/hooks/useSidebar";
import { useSearchParams } from "next/navigation";
import { useQuery } from "@apollo/client";
import { Plus, Package, Wrench, ChevronDown, AlertTriangle } from "lucide-react";
import {
Plus,
Package,
Wrench,
ChevronDown,
AlertTriangle,
} from "lucide-react";
import { GET_PENDING_SUPPLIES_COUNT } from "@/graphql/queries";
import { FulfillmentSuppliesTab } from "./fulfillment-supplies/fulfillment-supplies-tab";
import { MarketplaceSuppliesTab } from "./marketplace-supplies/marketplace-supplies-tab";
import { FulfillmentGoodsTab } from "./fulfillment-supplies/fulfillment-goods-tab";
import { RealSupplyOrdersTab } from "./fulfillment-supplies/real-supply-orders-tab";
import { SellerSupplyOrdersTab } from "./fulfillment-supplies/seller-supply-orders-tab";
import { AllSuppliesTab } from "./fulfillment-supplies/all-supplies-tab";
import { useAuth } from "@/hooks/useAuth";
import {
DropdownMenu,
DropdownMenuContent,
@ -22,13 +31,14 @@ import {
export function SuppliesDashboard() {
const { getSidebarMargin } = useSidebar();
const searchParams = useSearchParams();
const [activeTab, setActiveTab] = useState("fulfillment");
const [activeTab, setActiveTab] = useState("all");
const { user } = useAuth();
// Загружаем счетчик поставок, требующих одобрения
const { data: pendingData } = useQuery(GET_PENDING_SUPPLIES_COUNT, {
pollInterval: 30000, // Обновляем каждые 30 секунд
fetchPolicy: 'cache-first',
errorPolicy: 'ignore',
fetchPolicy: "cache-first",
errorPolicy: "ignore",
});
const pendingCount = pendingData?.pendingSuppliesCount;
@ -38,10 +48,15 @@ export function SuppliesDashboard() {
useEffect(() => {
const tab = searchParams.get("tab");
if (tab === "consumables") {
setActiveTab("fulfillment"); // Устанавливаем основную вкладку "Поставки на ФФ"
setActiveTab("supplies");
} else if (tab === "goods") {
setActiveTab("goods");
}
}, [searchParams]);
// Определяем тип организации для выбора правильного компонента
const isWholesale = user?.organization?.type === "WHOLESALE";
return (
<div className="h-screen flex overflow-hidden">
<Sidebar />
@ -54,41 +69,73 @@ export function SuppliesDashboard() {
<Alert className="mb-4 bg-blue-500/20 border-blue-400/30 text-blue-300 animate-pulse">
<AlertTriangle className="h-4 w-4" />
<AlertDescription>
У вас есть {pendingCount.total} элемент{pendingCount.total > 1 ? (pendingCount.total < 5 ? 'а' : 'ов') : ''}, требующ{pendingCount.total > 1 ? 'их' : 'ий'} одобрения:
{pendingCount.supplyOrders > 0 && ` ${pendingCount.supplyOrders} заказ${pendingCount.supplyOrders > 1 ? (pendingCount.supplyOrders < 5 ? 'а' : 'ов') : ''} поставок`}
{pendingCount.incomingRequests > 0 && pendingCount.supplyOrders > 0 && ', '}
{pendingCount.incomingRequests > 0 && ` ${pendingCount.incomingRequests} заявк${pendingCount.incomingRequests > 1 ? (pendingCount.incomingRequests < 5 ? 'и' : '') : 'а'} на партнерство`}
У вас есть {pendingCount.total} элемент
{pendingCount.total > 1
? pendingCount.total < 5
? "а"
: "ов"
: ""}
, требующ{pendingCount.total > 1 ? "их" : "ий"} одобрения:
{pendingCount.supplyOrders > 0 &&
` ${pendingCount.supplyOrders} заказ${
pendingCount.supplyOrders > 1
? pendingCount.supplyOrders < 5
? "а"
: "ов"
: ""
} поставок`}
{pendingCount.incomingRequests > 0 &&
pendingCount.supplyOrders > 0 &&
", "}
{pendingCount.incomingRequests > 0 &&
` ${pendingCount.incomingRequests} заявк${
pendingCount.incomingRequests > 1
? pendingCount.incomingRequests < 5
? "и"
: ""
: "а"
} на партнерство`}
</AlertDescription>
</Alert>
)}
{/* Главные вкладки с кнопкой создания */}
{/* Основные вкладки с кнопкой создания */}
<Tabs
value={activeTab}
onValueChange={setActiveTab}
className="w-full h-full flex flex-col"
>
<div className="flex items-center justify-between mb-1 flex-wrap gap-2">
<TabsList className={`grid grid-cols-2 bg-white/10 backdrop-blur border-white/20 w-fit text-sm ${hasPendingItems ? 'ring-2 ring-blue-400/50' : ''}`}>
<TabsList
className={`grid grid-cols-3 bg-white/10 backdrop-blur border-white/20 w-fit text-sm ${
hasPendingItems ? "ring-2 ring-blue-400/50" : ""
}`}
>
<TabsTrigger
value="fulfillment"
className={`data-[state=active]:bg-gradient-to-r data-[state=active]:from-purple-500 data-[state=active]:to-pink-500 data-[state=active]:text-white text-white/60 px-3 sm:px-6 relative ${pendingCount?.supplyOrders > 0 ? 'animate-pulse' : ''}`}
value="all"
className="data-[state=active]:bg-gradient-to-r data-[state=active]:from-purple-500 data-[state=active]:to-pink-500 data-[state=active]:text-white text-white/60 px-3 sm:px-6"
>
<span className="hidden sm:inline">Поставки на ФФ</span>
<span className="sm:hidden">ФФ</span>
Все
</TabsTrigger>
<TabsTrigger
value="goods"
className="data-[state=active]:bg-gradient-to-r data-[state=active]:from-purple-500 data-[state=active]:to-pink-500 data-[state=active]:text-white text-white/60 px-3 sm:px-6"
>
Товар
</TabsTrigger>
<TabsTrigger
value="supplies"
className={`data-[state=active]:bg-gradient-to-r data-[state=active]:from-purple-500 data-[state=active]:to-pink-500 data-[state=active]:text-white text-white/60 px-3 sm:px-6 relative ${
pendingCount?.supplyOrders > 0 ? "animate-pulse" : ""
}`}
>
Расходники
{pendingCount?.supplyOrders > 0 && (
<div className="absolute -top-1 -right-1 w-5 h-5 bg-blue-500 rounded-full flex items-center justify-center text-xs font-bold text-white">
{pendingCount.supplyOrders}
</div>
)}
</TabsTrigger>
<TabsTrigger
value="marketplace"
className="data-[state=active]:bg-gradient-to-r data-[state=active]:from-purple-500 data-[state=active]:to-pink-500 data-[state=active]:text-white text-white/60 px-3 sm:px-6"
>
<span className="hidden sm:inline">Поставки на Маркетплейсы</span>
<span className="sm:hidden">МП</span>
</TabsTrigger>
</TabsList>
<DropdownMenu>
@ -129,25 +176,25 @@ export function SuppliesDashboard() {
</DropdownMenu>
</div>
<TabsContent
value="fulfillment"
className="mt-0 flex-1 overflow-hidden"
>
<FulfillmentSuppliesTab
defaultSubTab={
searchParams.get("tab") === "consumables"
? "supplies"
: undefined
}
<TabsContent value="all" className="mt-0 flex-1 overflow-hidden">
<AllSuppliesTab
pendingSupplyOrders={pendingCount?.supplyOrders || 0}
/>
</TabsContent>
<TabsContent value="goods" className="mt-0 flex-1 overflow-hidden">
<FulfillmentGoodsTab />
</TabsContent>
<TabsContent
value="marketplace"
value="supplies"
className="mt-0 flex-1 overflow-hidden"
>
<MarketplaceSuppliesTab />
{isWholesale ? (
<RealSupplyOrdersTab />
) : (
<SellerSupplyOrdersTab />
)}
</TabsContent>
</Tabs>
</div>