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

This commit is contained in:
Veronika Smirnova
2025-08-03 18:28:05 +03:00
parent 8407ca397c
commit 1d5d4906be
8 changed files with 480 additions and 129 deletions

View File

@ -15,21 +15,23 @@ export function MarketplaceSuppliesTab() {
onValueChange={setActiveSubTab}
className="w-full h-full flex flex-col"
>
{/* Подвкладки для Маркетплейсов */}
<TabsList className="grid grid-cols-2 bg-white/5 backdrop-blur border-white/10 mb-4 w-fit">
<TabsTrigger
value="wildberries"
className="data-[state=active]:bg-white/20 data-[state=active]:text-white text-white/60 px-6"
>
Поставки на Wildberries
</TabsTrigger>
<TabsTrigger
value="ozon"
className="data-[state=active]:bg-white/20 data-[state=active]:text-white text-white/60 px-6"
>
Поставки на Ozon
</TabsTrigger>
</TabsList>
{/* Подвкладки для Маркетплейсов - Уровень 2 иерархии */}
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-4 mb-4 ml-4">
<TabsList className="grid grid-cols-2 bg-transparent w-fit">
<TabsTrigger
value="wildberries"
className="h-9 font-medium bg-white/8 border-white/20 data-[state=active]:bg-white/15 data-[state=active]:text-white text-white/60 px-6 rounded-lg"
>
Поставки на Wildberries
</TabsTrigger>
<TabsTrigger
value="ozon"
className="h-9 font-medium bg-white/8 border-white/20 data-[state=active]:bg-white/15 data-[state=active]:text-white text-white/60 px-6 rounded-lg"
>
Поставки на Ozon
</TabsTrigger>
</TabsList>
</div>
<TabsContent value="wildberries" className="mt-0 flex-1">
<WildberriesSuppliesTab />

View File

@ -1,7 +1,7 @@
"use client";
import React, { useState, useEffect } from "react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
// Убираем Tabs - используем кнопочную логику как в fulfillment-supplies
import { Button } from "@/components/ui/button";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Sidebar } from "@/components/dashboard/sidebar";
@ -12,8 +12,10 @@ import {
Plus,
Package,
Wrench,
ChevronDown,
AlertTriangle,
Building2,
ShoppingCart,
FileText,
} from "lucide-react";
import { GET_PENDING_SUPPLIES_COUNT } from "@/graphql/queries";
import { FulfillmentGoodsTab } from "./fulfillment-supplies/fulfillment-goods-tab";
@ -21,17 +23,25 @@ import { RealSupplyOrdersTab } from "./fulfillment-supplies/real-supply-orders-t
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,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
// Убираем DropdownMenu - больше не используется
// Компонент для отображения бейджа с уведомлениями
function NotificationBadge({ count }: { count: number }) {
if (count === 0) return null;
return (
<div className="ml-1 bg-red-500 text-white text-xs font-bold rounded-full min-w-[16px] h-4 flex items-center justify-center px-1">
{count > 99 ? "99+" : count}
</div>
);
}
export function SuppliesDashboard() {
const { getSidebarMargin } = useSidebar();
const searchParams = useSearchParams();
const [activeTab, setActiveTab] = useState("all");
const [activeTab, setActiveTab] = useState("fulfillment");
const [activeSubTab, setActiveSubTab] = useState("goods");
const [activeThirdTab, setActiveThirdTab] = useState("cards");
const { user } = useAuth();
// Загружаем счетчик поставок, требующих одобрения
@ -120,104 +130,291 @@ export function SuppliesDashboard() {
</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-3 bg-white/10 backdrop-blur border-white/20 w-fit text-sm ${
hasPendingItems ? "ring-2 ring-blue-400/50" : ""
}`}
>
<TabsTrigger
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"
>
Все
</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" : ""
{/* БЛОК ВСЕХ ТАБОВ */}
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl p-6">
{/* УРОВЕНЬ 1: Главные табы */}
<div className="mb-4">
<div className="grid w-full grid-cols-2 bg-white/15 backdrop-blur border-white/30 rounded-xl h-11 p-2">
<button
onClick={() => {
setActiveTab("fulfillment");
setActiveSubTab("goods");
setActiveThirdTab("cards");
}}
className={`flex items-center gap-2 text-sm font-semibold transition-all duration-200 rounded-lg px-3 ${
activeTab === "fulfillment"
? "bg-gradient-to-r from-purple-500/40 to-pink-500/40 text-white shadow-lg"
: "text-white/80 hover:text-white"
}`}
>
Расходники
{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>
</TabsList>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="sm"
className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white shadow-lg"
>
<Plus className="h-3 w-3 mr-1" />
<span className="hidden sm:inline">Создать поставку</span>
<span className="sm:hidden">Создать</span>
<ChevronDown className="h-3 w-3 ml-1" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent
align="end"
className="bg-white/10 backdrop-blur border-white/20"
<Building2 className="h-4 w-4" />
<span className="hidden sm:inline">
Поставки на фулфилмент
</span>
<span className="sm:hidden">Фулфилмент</span>
<NotificationBadge count={pendingCount?.supplyOrders || 0} />
</button>
<button
onClick={() => {
setActiveTab("marketplace");
setActiveSubTab("wildberries");
}}
className={`flex items-center gap-2 text-sm font-semibold transition-all duration-200 rounded-lg px-3 ${
activeTab === "marketplace"
? "bg-gradient-to-r from-purple-500/40 to-pink-500/40 text-white shadow-lg"
: "text-white/80 hover:text-white"
}`}
>
<DropdownMenuItem
onClick={() => {
window.location.href = "/supplies/create";
}}
className="text-white hover:bg-white/10 cursor-pointer"
>
<Package className="h-4 w-4 mr-2" />
Поставка товаров
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
window.location.href = "/supplies/create-consumables";
}}
className="text-white hover:bg-white/10 cursor-pointer"
>
<Wrench className="h-4 w-4 mr-2" />
Поставка расходников
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<ShoppingCart className="h-4 w-4" />
<span className="hidden sm:inline">
Поставки на маркетплейсы
</span>
<span className="sm:hidden">Маркетплейсы</span>
</button>
</div>
</div>
<TabsContent value="all" className="mt-0 flex-1 overflow-hidden">
<AllSuppliesTab
pendingSupplyOrders={pendingCount?.supplyOrders || 0}
/>
</TabsContent>
{/* УРОВЕНЬ 2: Подтабы для фулфилмента - ТОЛЬКО когда активен фулфилмент */}
{activeTab === "fulfillment" && (
<div className="ml-4 mb-3">
<div className="flex w-full bg-white/8 backdrop-blur border-white/20 h-9 rounded-lg p-1">
{/* Табы товар и расходники */}
<div className="grid grid-cols-2 flex-1">
<button
onClick={() => setActiveSubTab("goods")}
className={`flex items-center gap-1 text-xs font-medium transition-all duration-150 rounded-md px-2 ${
activeSubTab === "goods"
? "bg-white/15 text-white border-white/20"
: "text-white/60 hover:text-white/80"
}`}
>
<Package className="h-3 w-3" />
<span className="hidden sm:inline">Товар</span>
<span className="sm:hidden">Т</span>
</button>
<button
onClick={() => setActiveSubTab("consumables")}
className={`flex items-center gap-1 text-xs font-medium transition-all duration-150 rounded-md px-2 relative ${
activeSubTab === "consumables"
? "bg-white/15 text-white border-white/20"
: "text-white/60 hover:text-white/80"
}`}
>
<Wrench className="h-3 w-3" />
<span className="hidden sm:inline">
Расходники селлера
</span>
<span className="sm:hidden">Р</span>
<NotificationBadge
count={pendingCount?.supplyOrders || 0}
/>
</button>
</div>
<TabsContent value="goods" className="mt-0 flex-1 overflow-hidden">
<FulfillmentGoodsTab />
</TabsContent>
{/* Кнопка создания для расходников селлера */}
{activeSubTab === "consumables" && (
<button
onClick={() => {
window.location.href = "/supplies/create-consumables";
}}
className="h-7 px-3 py-1 ml-2 bg-white/8 border border-white/20 hover:bg-white/12 text-xs font-medium text-white/80 hover:text-white rounded-lg transition-all duration-150 flex items-center gap-1"
>
<Plus className="h-3 w-3" />
<span className="hidden sm:inline">Создать поставку</span>
<span className="sm:hidden">Создать</span>
</button>
)}
</div>
</div>
)}
<TabsContent
value="supplies"
className="mt-0 flex-1 overflow-hidden"
>
{isWholesale ? (
<RealSupplyOrdersTab />
) : (
<SellerSupplyOrdersTab />
)}
</TabsContent>
</Tabs>
{/* УРОВЕНЬ 2: Подтабы для маркетплейсов - ТОЛЬКО когда активны маркетплейсы */}
{activeTab === "marketplace" && (
<div className="ml-4 mb-3">
<div className="flex w-full bg-white/8 backdrop-blur border-white/20 h-9 rounded-lg p-1">
{/* Табы маркетплейсов */}
<div className="grid grid-cols-2 flex-1">
<button
onClick={() => setActiveSubTab("wildberries")}
className={`flex items-center gap-1 text-xs font-medium transition-all duration-150 rounded-md px-2 ${
activeSubTab === "wildberries"
? "bg-white/15 text-white border-white/20"
: "text-white/60 hover:text-white/80"
}`}
>
<ShoppingCart className="h-3 w-3" />
<span className="hidden sm:inline">Wildberries</span>
<span className="sm:hidden">W</span>
</button>
<button
onClick={() => setActiveSubTab("ozon")}
className={`flex items-center gap-1 text-xs font-medium transition-all duration-150 rounded-md px-2 ${
activeSubTab === "ozon"
? "bg-white/15 text-white border-white/20"
: "text-white/60 hover:text-white/80"
}`}
>
<ShoppingCart className="h-3 w-3" />
<span className="hidden sm:inline">Ozon</span>
<span className="sm:hidden">O</span>
</button>
</div>
{/* Кнопка создания для Wildberries */}
{activeSubTab === "wildberries" && (
<button
onClick={() => {
window.location.href = "/supplies/create-wildberries";
}}
className="h-7 px-3 py-1 ml-2 bg-white/8 border border-white/20 hover:bg-white/12 text-xs font-medium text-white/80 hover:text-white rounded-lg transition-all duration-150 flex items-center gap-1"
>
<Plus className="h-3 w-3" />
<span className="hidden sm:inline">Создать поставку</span>
<span className="sm:hidden">Создать</span>
</button>
)}
{/* Кнопка создания для Ozon */}
{activeSubTab === "ozon" && (
<button
onClick={() => {
window.location.href = "/supplies/create-ozon";
}}
className="h-7 px-3 py-1 ml-2 bg-white/8 border border-white/20 hover:bg-white/12 text-xs font-medium text-white/80 hover:text-white rounded-lg transition-all duration-150 flex items-center gap-1"
>
<Plus className="h-3 w-3" />
<span className="hidden sm:inline">Создать поставку</span>
<span className="sm:hidden">Создать</span>
</button>
)}
</div>
</div>
)}
{/* УРОВЕНЬ 3: Подподтабы для товаров - ТОЛЬКО когда активен товар */}
{activeTab === "fulfillment" && activeSubTab === "goods" && (
<div className="ml-8">
<div className="flex w-full bg-white/5 backdrop-blur border-white/15 h-8 rounded-md p-1">
{/* Табы карточки и поставщики */}
<div className="grid grid-cols-2 flex-1">
<button
onClick={() => setActiveThirdTab("cards")}
className={`flex items-center gap-1 text-xs font-normal transition-all duration-150 rounded-sm px-2 ${
activeThirdTab === "cards"
? "bg-white/10 text-white"
: "text-white/50 hover:text-white/70"
}`}
>
<FileText className="h-2.5 w-2.5" />
<span className="hidden sm:inline">Карточки</span>
<span className="sm:hidden">К</span>
</button>
<button
onClick={() => setActiveThirdTab("suppliers")}
className={`flex items-center gap-1 text-xs font-normal transition-all duration-150 rounded-sm px-2 ${
activeThirdTab === "suppliers"
? "bg-white/10 text-white"
: "text-white/50 hover:text-white/70"
}`}
>
<Building2 className="h-2.5 w-2.5" />
<span className="hidden sm:inline">Поставщики</span>
<span className="sm:hidden">П</span>
</button>
</div>
{/* Кнопка создания для карточек */}
{activeThirdTab === "cards" && (
<button
onClick={() => {
window.location.href = "/supplies/create-cards";
}}
className="h-6 px-2 py-1 ml-2 bg-white/5 border border-white/15 hover:bg-white/8 text-xs font-normal text-white/60 hover:text-white/80 rounded-md transition-all duration-150 flex items-center gap-1"
>
<Plus className="h-3 w-3" />
<span className="hidden sm:inline">Создать поставку</span>
<span className="sm:hidden">Создать</span>
</button>
)}
{/* Кнопка создания для поставщиков */}
{activeThirdTab === "suppliers" && (
<button
onClick={() => {
window.location.href = "/supplies/create-suppliers";
}}
className="h-6 px-2 py-1 ml-2 bg-white/5 border border-white/15 hover:bg-white/8 text-xs font-normal text-white/60 hover:text-white/80 rounded-md transition-all duration-150 flex items-center gap-1"
>
<Plus className="h-3 w-3" />
<span className="hidden sm:inline">Создать поставку</span>
<span className="sm:hidden">Создать</span>
</button>
)}
</div>
</div>
)}
</div>
{/* РАБОЧЕЕ ПРОСТРАНСТВО */}
<div className="bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl flex-1 overflow-hidden p-6">
{/* СОДЕРЖИМОЕ ПОСТАВОК НА ФУЛФИЛМЕНТ */}
{activeTab === "fulfillment" && (
<div className="h-full">
{/* ТОВАР */}
{activeSubTab === "goods" && (
<div className="h-full">
{/* КАРТОЧКИ */}
{activeThirdTab === "cards" && <FulfillmentGoodsTab />}
{/* ПОСТАВЩИКИ */}
{activeThirdTab === "suppliers" && (
<AllSuppliesTab
pendingSupplyOrders={pendingCount?.supplyOrders || 0}
/>
)}
</div>
)}
{/* РАСХОДНИКИ СЕЛЛЕРА */}
{activeSubTab === "consumables" && (
<div className="h-full">
{isWholesale ? (
<RealSupplyOrdersTab />
) : (
<SellerSupplyOrdersTab />
)}
</div>
)}
</div>
)}
{/* СОДЕРЖИМОЕ ПОСТАВОК НА МАРКЕТПЛЕЙСЫ */}
{activeTab === "marketplace" && (
<div className="h-full">
{/* WILDBERRIES */}
{activeSubTab === "wildberries" && (
<div className="text-white/70 text-center py-8">
<Package className="h-16 w-16 mx-auto mb-4 text-white/30" />
<h3 className="text-xl font-semibold mb-2">
Поставки на Wildberries
</h3>
<p>Раздел находится в разработке</p>
</div>
)}
{/* OZON */}
{activeSubTab === "ozon" && (
<div className="text-white/70 text-center py-8">
<Package className="h-16 w-16 mx-auto mb-4 text-white/30" />
<h3 className="text-xl font-semibold mb-2">
Поставки на Ozon
</h3>
<p>Раздел находится в разработке</p>
</div>
)}
</div>
)}
</div>
</div>
</main>
</div>