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

733 lines
32 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 { 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>
)
}