Удалены классы фона с градиентом из компонентов для улучшения производительности и упрощения стилей. Обновлены компоненты для более чистого и понятного кода, улучшена адаптивность интерфейса.

This commit is contained in:
Bivekich
2025-07-19 15:38:19 +03:00
parent de21a2241b
commit 47be3b38bb
21 changed files with 4232 additions and 46 deletions

View File

@ -0,0 +1,733 @@
"use client"
import { useState } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Slider } from '@/components/ui/slider'
import { Switch } from '@/components/ui/switch'
import { Checkbox } from '@/components/ui/checkbox'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Progress } from '@/components/ui/progress'
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
import {
ChevronDown,
ChevronUp,
Plus,
Minus,
Star,
Heart,
ThumbsUp,
Share,
Bookmark,
Flag,
MoreHorizontal,
Settings,
Filter,
Search,
Calendar,
Clock,
User,
Bell,
MessageCircle,
Mail,
Phone,
MapPin,
Globe,
Zap,
Shield,
Eye,
EyeOff,
Lock,
Unlock,
Copy,
Check,
X,
AlertTriangle,
Info,
HelpCircle,
ExternalLink,
Download,
Upload,
Trash2,
Edit3,
Save,
RefreshCw
} from 'lucide-react'
export function InteractiveDemo() {
const [rating, setRating] = useState(3)
const [liked, setLiked] = useState(false)
const [bookmarked, setBookmarked] = useState(false)
const [sliderValue, setSliderValue] = useState([50])
const [switchValue, setSwitchValue] = useState(false)
const [checkboxValue, setCheckboxValue] = useState(false)
const [counter, setCounter] = useState(5)
const [showPassword, setShowPassword] = useState(false)
const [notifications, setNotifications] = useState(true)
const [expandedCard, setExpandedCard] = useState<number | null>(null)
const [selectedItems, setSelectedItems] = useState<number[]>([])
const [copied, setCopied] = useState(false)
const handleCopy = () => {
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
const toggleItemSelection = (id: number) => {
setSelectedItems(prev =>
prev.includes(id) ? prev.filter(item => item !== id) : [...prev, id]
)
}
return (
<div className="space-y-6">
{/* Интерактивные кнопки */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Интерактивные кнопки</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Action Buttons */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Кнопки действий</h4>
<div className="grid grid-cols-4 gap-4">
<Button
variant={liked ? "glass" : "outline"}
onClick={() => setLiked(!liked)}
className={liked ? "text-red-300" : ""}
>
<Heart className={`h-4 w-4 mr-2 ${liked ? 'fill-current' : ''}`} />
{liked ? 'Понравилось' : 'Нравится'}
</Button>
<Button
variant={bookmarked ? "glass" : "outline"}
onClick={() => setBookmarked(!bookmarked)}
className={bookmarked ? "text-yellow-300" : ""}
>
<Bookmark className={`h-4 w-4 mr-2 ${bookmarked ? 'fill-current' : ''}`} />
{bookmarked ? 'Сохранено' : 'Сохранить'}
</Button>
<Button variant="outline">
<Share className="h-4 w-4 mr-2" />
Поделиться
</Button>
<Button variant="outline">
<Flag className="h-4 w-4 mr-2" />
Пожаловаться
</Button>
</div>
</div>
{/* Rating Stars */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Рейтинг звездами</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center space-x-4">
<span className="text-white text-sm">Оцените товар:</span>
<div className="flex items-center space-x-1">
{[1, 2, 3, 4, 5].map((star) => (
<button
key={star}
onClick={() => setRating(star)}
className="text-2xl transition-colors hover:scale-110 transform"
>
<Star
className={`h-6 w-6 ${
star <= rating
? 'text-yellow-400 fill-current'
: 'text-white/30'
}`}
/>
</button>
))}
</div>
<span className="text-white/60 text-sm">({rating} из 5)</span>
</div>
</div>
</div>
{/* Counter */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Счетчик</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center space-x-4">
<span className="text-white text-sm">Количество:</span>
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="icon"
onClick={() => setCounter(Math.max(0, counter - 1))}
disabled={counter <= 0}
>
<Minus className="h-4 w-4" />
</Button>
<div className="w-16 text-center">
<Input
value={counter}
onChange={(e) => setCounter(parseInt(e.target.value) || 0)}
className="text-center glass-input"
/>
</div>
<Button
variant="outline"
size="icon"
onClick={() => setCounter(counter + 1)}
>
<Plus className="h-4 w-4" />
</Button>
</div>
</div>
</div>
</div>
{/* Toggle Buttons */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Переключатели</h4>
<div className="grid grid-cols-3 gap-4">
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center justify-between">
<Label htmlFor="notifications" className="text-white">Уведомления</Label>
<Switch
id="notifications"
checked={notifications}
onCheckedChange={setNotifications}
/>
</div>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center space-x-2">
<Checkbox
id="agree"
checked={checkboxValue}
onCheckedChange={(checked) => setCheckboxValue(!!checked)}
/>
<Label htmlFor="agree" className="text-white text-sm">
Согласен с условиями
</Label>
</div>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="space-y-2">
<Label className="text-white text-sm">Громкость</Label>
<Slider
value={sliderValue}
onValueChange={setSliderValue}
max={100}
step={1}
className="w-full"
/>
<div className="text-white/60 text-xs text-center">{sliderValue[0]}%</div>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Формы и инпуты */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Интерактивные формы</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Search Input */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Поиск с фильтрами</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center space-x-3">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-white/40" />
<Input
placeholder="Поиск товаров..."
className="pl-10 glass-input"
/>
</div>
<Button variant="outline">
<Filter className="h-4 w-4 mr-2" />
Фильтры
</Button>
<Button variant="glass">
<Search className="h-4 w-4 mr-2" />
Найти
</Button>
</div>
</div>
</div>
{/* Password Input */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Ввод пароля</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="space-y-2">
<Label className="text-white">Пароль</Label>
<div className="relative">
<Input
type={showPassword ? "text" : "password"}
placeholder="Введите пароль"
className="glass-input pr-10"
/>
<Button
variant="ghost"
size="icon"
className="absolute right-0 top-0 h-full"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
</Button>
</div>
</div>
</div>
</div>
{/* Select Dropdown */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Выпадающие списки</h4>
<div className="grid grid-cols-3 gap-4">
<div className="space-y-2">
<Label className="text-white">Категория</Label>
<Select>
<SelectTrigger className="glass-input">
<SelectValue placeholder="Выберите категорию" />
</SelectTrigger>
<SelectContent>
<SelectItem value="electronics">Электроника</SelectItem>
<SelectItem value="clothing">Одежда</SelectItem>
<SelectItem value="books">Книги</SelectItem>
<SelectItem value="home">Дом и сад</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label className="text-white">Сортировка</Label>
<Select>
<SelectTrigger className="glass-input">
<SelectValue placeholder="По умолчанию" />
</SelectTrigger>
<SelectContent>
<SelectItem value="name">По названию</SelectItem>
<SelectItem value="price">По цене</SelectItem>
<SelectItem value="date">По дате</SelectItem>
<SelectItem value="rating">По рейтингу</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label className="text-white">Статус</Label>
<Select>
<SelectTrigger className="glass-input">
<SelectValue placeholder="Все статусы" />
</SelectTrigger>
<SelectContent>
<SelectItem value="active">Активные</SelectItem>
<SelectItem value="inactive">Неактивные</SelectItem>
<SelectItem value="pending">Ожидающие</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
{/* Copy to Clipboard */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Копирование в буфер</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center space-x-3">
<div className="flex-1">
<Input
value="https://sferav.com/product/12345"
readOnly
className="glass-input"
/>
</div>
<Button
variant={copied ? "glass" : "outline"}
onClick={handleCopy}
>
{copied ? (
<>
<Check className="h-4 w-4 mr-2" />
Скопировано
</>
) : (
<>
<Copy className="h-4 w-4 mr-2" />
Копировать
</>
)}
</Button>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Диалоги и модальные окна */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Диалоги и модальные окна</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Alert Dialog */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Диалоги подтверждения</h4>
<div className="flex items-center space-x-4">
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="outline" className="text-red-400 border-red-400/50">
<Trash2 className="h-4 w-4 mr-2" />
Удалить
</Button>
</AlertDialogTrigger>
<AlertDialogContent className="glass-card">
<AlertDialogHeader>
<AlertDialogTitle className="text-white">Подтвердите удаление</AlertDialogTitle>
<AlertDialogDescription className="text-white/70">
Это действие нельзя отменить. Товар будет окончательно удален из системы.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel className="glass-secondary">Отмена</AlertDialogCancel>
<AlertDialogAction className="bg-red-500 hover:bg-red-600">Удалить</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="glass">
<Save className="h-4 w-4 mr-2" />
Сохранить
</Button>
</AlertDialogTrigger>
<AlertDialogContent className="glass-card">
<AlertDialogHeader>
<AlertDialogTitle className="text-white">Сохранить изменения?</AlertDialogTitle>
<AlertDialogDescription className="text-white/70">
Все внесенные изменения будут сохранены в системе.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel className="glass-secondary">Отмена</AlertDialogCancel>
<AlertDialogAction className="bg-green-500 hover:bg-green-600">Сохранить</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="outline" className="text-yellow-400 border-yellow-400/50">
<AlertTriangle className="h-4 w-4 mr-2" />
Предупреждение
</Button>
</AlertDialogTrigger>
<AlertDialogContent className="glass-card">
<AlertDialogHeader>
<AlertDialogTitle className="text-white flex items-center">
<AlertTriangle className="h-5 w-5 text-yellow-400 mr-2" />
Внимание!
</AlertDialogTitle>
<AlertDialogDescription className="text-white/70">
Эта операция может повлиять на работу системы. Продолжить?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel className="glass-secondary">Отмена</AlertDialogCancel>
<AlertDialogAction className="bg-yellow-500 hover:bg-yellow-600">Продолжить</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
</div>
{/* Regular Dialog */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Информационные диалоги</h4>
<div className="flex items-center space-x-4">
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">
<Settings className="h-4 w-4 mr-2" />
Настройки
</Button>
</DialogTrigger>
<DialogContent className="glass-card max-w-md">
<DialogHeader>
<DialogTitle className="text-white">Настройки системы</DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label className="text-white">Темная тема</Label>
<Switch />
</div>
<div className="flex items-center justify-between">
<Label className="text-white">Уведомления</Label>
<Switch checked />
</div>
<div className="flex items-center justify-between">
<Label className="text-white">Автосохранение</Label>
<Switch checked />
</div>
</div>
<div className="flex justify-end space-x-2 mt-6">
<Button variant="ghost">Отмена</Button>
<Button variant="glass">Сохранить</Button>
</div>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">
<Info className="h-4 w-4 mr-2" />
Информация
</Button>
</DialogTrigger>
<DialogContent className="glass-card max-w-lg">
<DialogHeader>
<DialogTitle className="text-white">О системе SferaV</DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div className="text-white/80">
<p className="mb-4">
SferaV - современная система управления бизнесом для фулфилмент-центров,
селлеров, логистических компаний и оптовиков.
</p>
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-white/60">Версия:</span>
<span>1.0.0</span>
</div>
<div className="flex justify-between">
<span className="text-white/60">Сборка:</span>
<span>2024.01.15</span>
</div>
<div className="flex justify-between">
<span className="text-white/60">Лицензия:</span>
<span>MIT</span>
</div>
</div>
</div>
</div>
<div className="flex justify-end space-x-2 mt-6">
<Button variant="outline">
<ExternalLink className="h-4 w-4 mr-2" />
Сайт
</Button>
<Button variant="glass">Закрыть</Button>
</div>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">
<HelpCircle className="h-4 w-4 mr-2" />
Помощь
</Button>
</DialogTrigger>
<DialogContent className="glass-card max-w-2xl">
<DialogHeader>
<DialogTitle className="text-white">Справка</DialogTitle>
</DialogHeader>
<Tabs defaultValue="faq" className="w-full">
<TabsList className="grid w-full grid-cols-3 bg-white/5">
<TabsTrigger value="faq" className="data-[state=active]:bg-white/20">FAQ</TabsTrigger>
<TabsTrigger value="contact" className="data-[state=active]:bg-white/20">Контакты</TabsTrigger>
<TabsTrigger value="docs" className="data-[state=active]:bg-white/20">Документация</TabsTrigger>
</TabsList>
<TabsContent value="faq" className="space-y-4 mt-4">
<div className="space-y-3">
<div>
<h5 className="text-white font-medium">Как добавить товар?</h5>
<p className="text-white/70 text-sm">Перейдите в раздел &quot;Склад&quot; и нажмите кнопку &quot;Добавить товар&quot;.</p>
</div>
<div>
<h5 className="text-white font-medium">Как связаться с поддержкой?</h5>
<p className="text-white/70 text-sm">Используйте вкладку &quot;Контакты&quot; в этом окне.</p>
</div>
</div>
</TabsContent>
<TabsContent value="contact" className="space-y-4 mt-4">
<div className="space-y-3">
<div className="flex items-center space-x-3">
<Mail className="h-4 w-4 text-blue-400" />
<span className="text-white">support@sferav.com</span>
</div>
<div className="flex items-center space-x-3">
<Phone className="h-4 w-4 text-green-400" />
<span className="text-white">+7 (495) 123-45-67</span>
</div>
<div className="flex items-center space-x-3">
<MessageCircle className="h-4 w-4 text-purple-400" />
<span className="text-white">Telegram: @sferav_support</span>
</div>
</div>
</TabsContent>
<TabsContent value="docs" className="space-y-4 mt-4">
<div className="space-y-2">
<Button variant="ghost" className="w-full justify-start">
<ExternalLink className="h-4 w-4 mr-2" />
Руководство пользователя
</Button>
<Button variant="ghost" className="w-full justify-start">
<ExternalLink className="h-4 w-4 mr-2" />
API документация
</Button>
<Button variant="ghost" className="w-full justify-start">
<ExternalLink className="h-4 w-4 mr-2" />
Видео уроки
</Button>
</div>
</TabsContent>
</Tabs>
</DialogContent>
</Dialog>
</div>
</div>
</CardContent>
</Card>
{/* Расширяемые элементы */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Расширяемые элементы</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Expandable Cards */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Расширяемые карточки</h4>
<div className="space-y-3">
{[1, 2, 3].map((card) => (
<div key={card} className="glass-card rounded-lg border border-white/10 overflow-hidden">
<div
className="p-4 cursor-pointer flex items-center justify-between hover:bg-white/5 transition-colors"
onClick={() => setExpandedCard(expandedCard === card ? null : card)}
>
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-blue-500/20 rounded-lg flex items-center justify-center">
<Settings className="h-5 w-5 text-blue-400" />
</div>
<div>
<div className="text-white font-medium">Настройка {card}</div>
<div className="text-white/60 text-sm">Описание настройки {card}</div>
</div>
</div>
{expandedCard === card ? (
<ChevronUp className="h-5 w-5 text-white/60" />
) : (
<ChevronDown className="h-5 w-5 text-white/60" />
)}
</div>
{expandedCard === card && (
<div className="px-4 pb-4 border-t border-white/10">
<div className="mt-4 space-y-3">
<div className="flex items-center justify-between">
<Label className="text-white">Включить функцию</Label>
<Switch />
</div>
<div className="space-y-2">
<Label className="text-white">Уровень</Label>
<Slider defaultValue={[50]} max={100} step={1} />
</div>
<div className="flex justify-end space-x-2">
<Button variant="ghost" size="sm">Сбросить</Button>
<Button variant="glass" size="sm">Применить</Button>
</div>
</div>
</div>
)}
</div>
))}
</div>
</div>
{/* Selectable List */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Выбираемый список</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center justify-between mb-4">
<span className="text-white text-sm">
Выбрано: {selectedItems.length} из 5
</span>
<div className="flex items-center space-x-2">
<Button
variant="ghost"
size="sm"
onClick={() => setSelectedItems([])}
>
Очистить
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => setSelectedItems([1, 2, 3, 4, 5])}
>
Выбрать все
</Button>
</div>
</div>
<div className="space-y-2">
{[1, 2, 3, 4, 5].map((item) => (
<div
key={item}
className={`p-3 rounded-lg border cursor-pointer transition-all ${
selectedItems.includes(item)
? 'border-blue-500/50 bg-blue-500/10'
: 'border-white/10 hover:bg-white/5'
}`}
onClick={() => toggleItemSelection(item)}
>
<div className="flex items-center space-x-3">
<Checkbox
checked={selectedItems.includes(item)}
onCheckedChange={() => toggleItemSelection(item)}
/>
<div className="flex-1">
<div className="text-white font-medium">Элемент {item}</div>
<div className="text-white/60 text-sm">Описание элемента {item}</div>
</div>
{selectedItems.includes(item) && (
<Check className="h-4 w-4 text-blue-400" />
)}
</div>
</div>
))}
</div>
{selectedItems.length > 0 && (
<div className="mt-4 flex justify-end space-x-2">
<Button variant="outline" size="sm">
<Download className="h-4 w-4 mr-2" />
Экспорт
</Button>
<Button variant="glass" size="sm">
<Edit3 className="h-4 w-4 mr-2" />
Редактировать
</Button>
</div>
)}
</div>
</div>
</CardContent>
</Card>
</div>
)
}