Files
sfera-new/src/components/admin/ui-kit/supplies-demo.tsx

634 lines
30 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { useState } from "react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
ShoppingCart,
Plus,
Minus,
Eye,
Heart,
Package,
Building2,
Calendar,
Users,
Search,
Star,
Truck
} from "lucide-react";
export function SuppliesDemo() {
const [selectedQuantity, setSelectedQuantity] = useState(1);
const [cartItems, setCartItems] = useState(3);
const [cartTotal, setCartTotal] = useState(15750);
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
minimumFractionDigits: 0
}).format(amount);
};
const mockProduct = {
id: "1",
name: "Футболка мужская базовая хлопок 100%",
brand: "BASIC",
price: 1299,
discount: 15,
quantity: 47,
color: "Черный",
size: "L",
mainImage: "/api/placeholder/300/300",
isNew: true,
isBestseller: false
};
const mockWholesaler = {
id: "w1",
name: "ТекстильПром ООО",
rating: 4.8,
reviewsCount: 1247,
location: "Москва",
specialization: "Текстиль и одежда",
verified: true
};
const discountedPrice = mockProduct.discount
? mockProduct.price * (1 - mockProduct.discount / 100)
: mockProduct.price;
return (
<div className="space-y-8">
<div>
<h2 className="text-2xl font-bold text-white mb-4">Поставки - Компоненты</h2>
<p className="text-white/70 mb-6">
Демонстрация компонентов системы управления поставками
</p>
</div>
<Tabs defaultValue="product-cards" className="w-full">
<TabsList className="grid grid-cols-4 bg-white/5 backdrop-blur border-white/10 mb-6">
<TabsTrigger value="product-cards">Карточки товаров</TabsTrigger>
<TabsTrigger value="wholesaler-cards">Карточки поставщиков</TabsTrigger>
<TabsTrigger value="floating-cart">Плавающая корзина</TabsTrigger>
<TabsTrigger value="supply-types">Типы поставок</TabsTrigger>
</TabsList>
<TabsContent value="product-cards" className="space-y-6">
<div>
<h3 className="text-xl font-semibold text-white mb-4">Карточки товаров</h3>
<p className="text-white/60 mb-6">
Интерактивные карточки товаров с возможностью управления количеством
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Обычная карточка товара */}
<Card className="bg-white/10 backdrop-blur border-white/20 overflow-hidden group hover:bg-white/15 hover:border-white/30 transition-all duration-300 hover:scale-105 hover:shadow-2xl">
<div className="aspect-square relative bg-white/5 overflow-hidden">
<div className="w-full h-full bg-gradient-to-br from-purple-500/20 to-pink-500/20 flex items-center justify-center">
<Package className="h-16 w-16 text-white/40" />
</div>
{/* Количество в наличии */}
<div className="absolute top-2 right-2">
<Badge className={`${
mockProduct.quantity > 50
? 'bg-green-500/80'
: mockProduct.quantity > 10
? 'bg-yellow-500/80'
: 'bg-red-500/80'
} text-white border-0 backdrop-blur text-xs`}>
{mockProduct.quantity}
</Badge>
</div>
{/* Скидка */}
{mockProduct.discount && (
<div className="absolute top-2 left-2">
<Badge className="bg-red-500/80 text-white border-0 backdrop-blur text-xs">
-{mockProduct.discount}%
</Badge>
</div>
)}
{/* Overlay с кнопками */}
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
<div className="flex space-x-2">
<Button size="sm" variant="secondary" className="bg-white/20 backdrop-blur text-white border-white/30 hover:bg-white/30">
<Eye className="h-4 w-4" />
</Button>
<Button size="sm" variant="secondary" className="bg-white/20 backdrop-blur text-white border-white/30 hover:bg-white/30">
<Heart className="h-4 w-4" />
</Button>
</div>
</div>
</div>
<div className="p-3 space-y-3">
{/* Заголовок и бренд */}
<div>
<div className="flex items-center justify-between mb-1">
{mockProduct.brand && (
<Badge className="bg-gray-500/20 text-gray-300 border-gray-500/30 text-xs">
{mockProduct.brand}
</Badge>
)}
<div className="flex items-center space-x-1">
{mockProduct.isNew && (
<Badge className="bg-green-500/20 text-green-300 border-green-500/30 text-xs">
NEW
</Badge>
)}
{mockProduct.isBestseller && (
<Badge className="bg-orange-500/20 text-orange-300 border-orange-500/30 text-xs">
HIT
</Badge>
)}
</div>
</div>
<h3 className="text-white font-semibold text-sm mb-1 line-clamp-2 leading-tight">
{mockProduct.name}
</h3>
</div>
{/* Основная характеристика */}
<div className="text-white/60 text-xs">
{mockProduct.color && <span className="text-white">{mockProduct.color}</span>}
{mockProduct.size && <span className="text-white ml-2">{mockProduct.size}</span>}
</div>
{/* Цена */}
<div className="pt-2 border-t border-white/10">
<div className="flex items-center space-x-2">
<div className="text-white font-bold text-lg">
{formatCurrency(discountedPrice)}
</div>
{mockProduct.discount && (
<div className="text-white/40 text-sm line-through">
{formatCurrency(mockProduct.price)}
</div>
)}
</div>
</div>
{/* Управление количеством */}
<div className="flex items-center space-x-2">
<Button
variant="ghost"
size="sm"
onClick={() => setSelectedQuantity(Math.max(0, selectedQuantity - 1))}
disabled={selectedQuantity === 0}
className="h-8 w-8 p-0 text-white/60 hover:text-white hover:bg-white/10 border border-white/20"
>
<Minus className="h-3 w-3" />
</Button>
<Input
type="text"
value={selectedQuantity}
onChange={(e) => {
const value = e.target.value.replace(/[^0-9]/g, '');
const numValue = parseInt(value) || 0;
setSelectedQuantity(Math.min(mockProduct.quantity, numValue));
}}
className="h-8 w-12 text-center bg-white/10 border-white/20 text-white text-sm"
/>
<Button
variant="ghost"
size="sm"
onClick={() => setSelectedQuantity(Math.min(mockProduct.quantity, selectedQuantity + 1))}
disabled={selectedQuantity >= mockProduct.quantity}
className="h-8 w-8 p-0 text-white/60 hover:text-white hover:bg-white/10 border border-white/20"
>
<Plus className="h-3 w-3" />
</Button>
{selectedQuantity > 0 && (
<Badge className="bg-gradient-to-r from-purple-500 to-pink-500 text-white border-0 text-xs ml-auto">
<ShoppingCart className="h-3 w-3 mr-1" />
{selectedQuantity}
</Badge>
)}
</div>
{/* Сумма для выбранного товара */}
{selectedQuantity > 0 && (
<div className="bg-gradient-to-r from-green-500/20 to-emerald-500/20 border border-green-500/30 rounded p-2">
<div className="text-green-300 text-xs font-medium text-center">
{formatCurrency(discountedPrice * selectedQuantity)}
</div>
</div>
)}
</div>
</Card>
{/* Компактная карточка товара */}
<Card className="bg-white/10 backdrop-blur border-white/20 p-4 hover:bg-white/15 transition-colors">
<div className="flex items-center space-x-3">
<div className="w-16 h-16 bg-gradient-to-br from-blue-500/20 to-cyan-500/20 rounded flex items-center justify-center">
<Package className="h-8 w-8 text-white/40" />
</div>
<div className="flex-1 min-w-0">
<h4 className="text-white font-medium text-sm truncate">Товар компактно</h4>
<p className="text-white/60 text-xs">Краткое описание</p>
<div className="flex items-center justify-between mt-2">
<span className="text-white font-bold text-sm">{formatCurrency(1599)}</span>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30 text-xs">
В наличии
</Badge>
</div>
</div>
</div>
</Card>
{/* Карточка товара со статусом */}
<Card className="bg-white/10 backdrop-blur border-white/20 p-4">
<div className="space-y-3">
<div className="flex items-center justify-between">
<Badge className="bg-orange-500/20 text-orange-300 border-orange-500/30 text-xs">
Ожидается
</Badge>
<span className="text-white/60 text-xs">Арт: TB-001</span>
</div>
<h4 className="text-white font-medium text-sm">Товар с уведомлением</h4>
<div className="text-white/60 text-xs">
<p>Поступление: 15 марта</p>
<p>Количество: ~200 шт</p>
</div>
<div className="flex items-center justify-between">
<span className="text-white font-bold">{formatCurrency(899)}</span>
<Button size="sm" variant="outline" className="border-white/20 text-white text-xs">
Уведомить
</Button>
</div>
</div>
</Card>
</div>
</div>
</TabsContent>
<TabsContent value="wholesaler-cards" className="space-y-6">
<div>
<h3 className="text-xl font-semibold text-white mb-4">Карточки поставщиков</h3>
<p className="text-white/60 mb-6">
Информационные карточки поставщиков и поставщиков
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Главная карточка поставщика */}
<Card className="bg-white/10 backdrop-blur border-white/20 p-6 hover:bg-white/15 hover:border-white/30 transition-all duration-300 hover:scale-105">
<div className="space-y-4">
<div className="flex items-start justify-between">
<div className="flex items-center space-x-3">
<div className="w-12 h-12 bg-gradient-to-br from-purple-500 to-pink-500 rounded-full flex items-center justify-center">
<Building2 className="h-6 w-6 text-white" />
</div>
<div>
<h3 className="text-white font-semibold text-lg">
{mockWholesaler.name}
</h3>
<p className="text-white/60 text-sm">
{mockWholesaler.specialization}
</p>
</div>
</div>
{mockWholesaler.verified && (
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
Верифицирован
</Badge>
)}
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-white/60 text-sm">Рейтинг:</span>
<div className="flex items-center space-x-1">
<div className="flex">
{Array.from({ length: 5 }, (_, i) => (
<Star
key={i}
className={`h-4 w-4 ${
i < Math.floor(mockWholesaler.rating)
? 'text-yellow-400 fill-current'
: 'text-gray-400'
}`}
/>
))}
</div>
<span className="text-white text-sm font-medium">
{mockWholesaler.rating}
</span>
</div>
</div>
<div className="flex items-center justify-between">
<span className="text-white/60 text-sm">Отзывы:</span>
<span className="text-white text-sm">
{mockWholesaler.reviewsCount.toLocaleString('ru-RU')}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-white/60 text-sm">Местоположение:</span>
<span className="text-white text-sm">{mockWholesaler.location}</span>
</div>
</div>
<div className="flex space-x-2">
<Button
size="sm"
className="flex-1 bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white"
>
<Package className="h-4 w-4 mr-2" />
Товары
</Button>
<Button
size="sm"
variant="outline"
className="border-white/20 text-white hover:bg-white/10"
>
<Eye className="h-4 w-4" />
</Button>
</div>
</div>
</Card>
{/* Компактная карточка поставщика */}
<Card className="bg-white/10 backdrop-blur border-white/20 p-4 hover:bg-white/15 transition-colors">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-gradient-to-br from-green-500 to-emerald-500 rounded-full flex items-center justify-center">
<Truck className="h-5 w-5 text-white" />
</div>
<div className="flex-1 min-w-0">
<h4 className="text-white font-medium text-sm">Логистический партнер</h4>
<p className="text-white/60 text-xs">Быстрая доставка</p>
<div className="flex items-center mt-1">
<div className="flex">
{Array.from({ length: 5 }, (_, i) => (
<Star key={i} className="h-3 w-3 text-yellow-400 fill-current" />
))}
</div>
<span className="text-white/60 text-xs ml-1">(4.9)</span>
</div>
</div>
</div>
</Card>
{/* Карточка нового поставщика */}
<Card className="bg-gradient-to-br from-blue-500/10 to-cyan-500/10 backdrop-blur border-blue-500/30 p-4">
<div className="space-y-3">
<div className="flex items-center justify-between">
<Badge className="bg-blue-500/20 text-blue-300 border-blue-500/30 text-xs">
Новый партнер
</Badge>
<Users className="h-5 w-5 text-blue-400" />
</div>
<h4 className="text-white font-medium">ТехноТрейд ООО</h4>
<p className="text-white/60 text-sm">
Электроника и техника
</p>
<div className="flex items-center justify-between">
<span className="text-white/60 text-xs">Заявка на партнерство</span>
<Button size="sm" variant="outline" className="border-blue-500/30 text-blue-300 text-xs">
Рассмотреть
</Button>
</div>
</div>
</Card>
</div>
</div>
</TabsContent>
<TabsContent value="floating-cart" className="space-y-6">
<div>
<h3 className="text-xl font-semibold text-white mb-4">Плавающая корзина</h3>
<p className="text-white/60 mb-6">
Плавающий элемент для быстрого доступа к корзине
</p>
<div className="space-y-6">
{/* Демонстрация плавающей корзины */}
<div className="relative bg-gray-900/50 border border-white/10 rounded-lg p-8 min-h-[300px]">
<p className="text-white/60 text-center">
Область контента страницы
<br />
<span className="text-xs">Плавающая корзина появляется в правом нижнем углу</span>
</p>
{/* Демо плавающей корзины */}
<div className="absolute bottom-4 right-4">
<Button
size="lg"
className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white shadow-2xl"
onClick={() => {
setCartItems(cartItems + 1);
setCartTotal(cartTotal + 1299);
}}
>
<ShoppingCart className="h-5 w-5 mr-2" />
{cartItems} {formatCurrency(cartTotal)}
</Button>
</div>
</div>
{/* Различные варианты плавающих кнопок */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Card className="bg-white/10 backdrop-blur border-white/20 p-4">
<h4 className="text-white font-medium mb-3">Стандартная корзина</h4>
<Button
className="w-full bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white"
>
<ShoppingCart className="h-4 w-4 mr-2" />
3 {formatCurrency(cartTotal)}
</Button>
</Card>
<Card className="bg-white/10 backdrop-blur border-white/20 p-4">
<h4 className="text-white font-medium mb-3">Компактная</h4>
<Button size="sm" className="w-full bg-gradient-to-r from-green-500 to-emerald-500 text-white">
<ShoppingCart className="h-4 w-4 mr-1" />
{formatCurrency(cartTotal)}
</Button>
</Card>
<Card className="bg-white/10 backdrop-blur border-white/20 p-4">
<h4 className="text-white font-medium mb-3">С индикатором</h4>
<div className="relative">
<Button className="w-full bg-gradient-to-r from-orange-500 to-red-500 text-white">
<ShoppingCart className="h-4 w-4 mr-2" />
Корзина
</Button>
<Badge className="absolute -top-2 -right-2 bg-red-500 text-white text-xs">
{cartItems}
</Badge>
</div>
</Card>
</div>
{/* Кнопки управления демо */}
<div className="flex justify-center space-x-4">
<Button
variant="outline"
size="sm"
className="border-white/20 text-white"
onClick={() => {
setCartItems(Math.max(0, cartItems - 1));
setCartTotal(Math.max(0, cartTotal - 1299));
}}
>
<Minus className="h-4 w-4 mr-1" />
Убрать товар
</Button>
<Button
variant="outline"
size="sm"
className="border-white/20 text-white"
onClick={() => {
setCartItems(cartItems + 1);
setCartTotal(cartTotal + 1299);
}}
>
<Plus className="h-4 w-4 mr-1" />
Добавить товар
</Button>
<Button
variant="outline"
size="sm"
className="border-red-500/30 text-red-300"
onClick={() => {
setCartItems(0);
setCartTotal(0);
}}
>
Очистить корзину
</Button>
</div>
</div>
</div>
</TabsContent>
<TabsContent value="supply-types" className="space-y-6">
<div>
<h3 className="text-xl font-semibold text-white mb-4">Типы поставок</h3>
<p className="text-white/60 mb-6">
Различные варианты выбора типа поставки
</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Вариант 1: Карточки */}
<Card
className="bg-white/10 backdrop-blur border-white/20 p-6 cursor-pointer transition-all hover:bg-white/15 hover:border-white/30"
>
<div className="text-center space-y-4">
<div className="p-4 bg-blue-500/20 rounded-lg w-fit mx-auto">
<ShoppingCart className="h-8 w-8 text-blue-400" />
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Карточки</h3>
<p className="text-white/60 text-sm">
Создание поставки через выбор товаров по карточкам
</p>
</div>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
Доступно
</Badge>
</div>
</Card>
{/* Вариант 2: Поставщик */}
<Card
className="bg-white/10 backdrop-blur border-white/20 p-6 cursor-pointer transition-all hover:bg-white/15 hover:border-white/30"
>
<div className="text-center space-y-4">
<div className="p-4 bg-green-500/20 rounded-lg w-fit mx-auto">
<Users className="h-8 w-8 text-green-400" />
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Поставщик</h3>
<p className="text-white/60 text-sm">
Создание поставки через выбор товаров у поставщиков
</p>
</div>
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
Доступно
</Badge>
</div>
</Card>
{/* Дополнительные типы */}
<Card className="bg-white/10 backdrop-blur border-white/20 p-6 opacity-60">
<div className="text-center space-y-4">
<div className="p-4 bg-gray-500/20 rounded-lg w-fit mx-auto">
<Package className="h-8 w-8 text-gray-400" />
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Импорт</h3>
<p className="text-white/60 text-sm">
Массовый импорт товаров из файла
</p>
</div>
<Badge className="bg-gray-500/20 text-gray-300 border-gray-500/30">
Скоро
</Badge>
</div>
</Card>
<Card className="bg-white/10 backdrop-blur border-white/20 p-6 opacity-60">
<div className="text-center space-y-4">
<div className="p-4 bg-purple-500/20 rounded-lg w-fit mx-auto">
<Calendar className="h-8 w-8 text-purple-400" />
</div>
<div>
<h3 className="text-xl font-semibold text-white mb-2">Регулярные</h3>
<p className="text-white/60 text-sm">
Автоматические поставки по расписанию
</p>
</div>
<Badge className="bg-gray-500/20 text-gray-300 border-gray-500/30">
В разработке
</Badge>
</div>
</Card>
</div>
{/* Статусы поставок */}
<div className="mt-8">
<h4 className="text-lg font-semibold text-white mb-4">Статусы поставок</h4>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="text-center space-y-2">
<Badge className="bg-yellow-500/20 text-yellow-300 border-yellow-500/30">
Подготовка
</Badge>
<p className="text-white/60 text-xs">Сбор товаров</p>
</div>
<div className="text-center space-y-2">
<Badge className="bg-blue-500/20 text-blue-300 border-blue-500/30">
В пути
</Badge>
<p className="text-white/60 text-xs">Доставка</p>
</div>
<div className="text-center space-y-2">
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">
Доставлено
</Badge>
<p className="text-white/60 text-xs">Успешно</p>
</div>
<div className="text-center space-y-2">
<Badge className="bg-red-500/20 text-red-300 border-red-500/30">
Ошибка
</Badge>
<p className="text-white/60 text-xs">Требует внимания</p>
</div>
</div>
</div>
</div>
</TabsContent>
</Tabs>
</div>
);
}