Добавлены модели и функциональность для управления администраторами, включая авторизацию через JWT, запросы и мутации для получения информации об администраторах и управления пользователями. Обновлены стили и логика работы с токенами в Apollo Client. Улучшен интерфейс взаимодействия с пользователем.
This commit is contained in:
527
src/components/admin/ui-kit/forms-demo.tsx
Normal file
527
src/components/admin/ui-kit/forms-demo.tsx
Normal file
@ -0,0 +1,527 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from 'react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
import { Slider } from '@/components/ui/slider'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { PhoneInput } from '@/components/ui/phone-input'
|
||||
import {
|
||||
Eye,
|
||||
EyeOff,
|
||||
Search,
|
||||
Calendar,
|
||||
Mail,
|
||||
User,
|
||||
Lock
|
||||
} from 'lucide-react'
|
||||
|
||||
export function FormsDemo() {
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
const [switchValue, setSwitchValue] = useState(false)
|
||||
const [sliderValue, setSliderValue] = useState([50])
|
||||
const [checkboxValue, setCheckboxValue] = useState(false)
|
||||
|
||||
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">
|
||||
{/* Обычный инпут */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="basic-input" className="text-white/90">
|
||||
Обычное поле
|
||||
</Label>
|
||||
<Input
|
||||
id="basic-input"
|
||||
type="text"
|
||||
placeholder="Введите текст..."
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Инпут с иконкой */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="icon-input" className="text-white/90">
|
||||
Поле с иконкой
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-white/50 h-4 w-4" />
|
||||
<Input
|
||||
id="icon-input"
|
||||
type="text"
|
||||
placeholder="Поиск..."
|
||||
className="pl-10 glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Пароль */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="password-input" className="text-white/90">
|
||||
Пароль
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-1/2 transform -translate-y-1/2 text-white/50 h-4 w-4" />
|
||||
<Input
|
||||
id="password-input"
|
||||
type={showPassword ? "text" : "password"}
|
||||
placeholder="Введите пароль"
|
||||
className="pl-10 pr-10 glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 h-6 w-6 text-white/70 hover:text-white hover:bg-white/10"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{showPassword ? (
|
||||
<EyeOff className="h-4 w-4" />
|
||||
) : (
|
||||
<Eye className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Email */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email-input" className="text-white/90">
|
||||
Email
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 text-white/50 h-4 w-4" />
|
||||
<Input
|
||||
id="email-input"
|
||||
type="email"
|
||||
placeholder="example@domain.com"
|
||||
className="pl-10 glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Телефон */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="phone-input" className="text-white/90">
|
||||
Телефон
|
||||
</Label>
|
||||
<PhoneInput
|
||||
id="phone-input"
|
||||
placeholder="+7 (999) 999-99-99"
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Дата */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="date-input" className="text-white/90">
|
||||
Дата
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Calendar className="absolute left-3 top-1/2 transform -translate-y-1/2 text-white/50 h-4 w-4" />
|
||||
<Input
|
||||
id="date-input"
|
||||
type="date"
|
||||
className="pl-10 glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Число */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="number-input" className="text-white/90">
|
||||
Число
|
||||
</Label>
|
||||
<Input
|
||||
id="number-input"
|
||||
type="number"
|
||||
placeholder="0"
|
||||
min="0"
|
||||
max="100"
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Отключенное поле */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="disabled-input" className="text-white/90">
|
||||
Отключенное поле
|
||||
</Label>
|
||||
<Input
|
||||
id="disabled-input"
|
||||
type="text"
|
||||
placeholder="Недоступно для редактирования"
|
||||
disabled
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Селекты и выпадающие списки */}
|
||||
<Card className="glass-card border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Селекты и выпадающие списки</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Label className="text-white/90">
|
||||
Выберите опцию
|
||||
</Label>
|
||||
<Select>
|
||||
<SelectTrigger className="glass-input text-white">
|
||||
<SelectValue placeholder="Выберите..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="glass-card border-white/10">
|
||||
<SelectItem value="option1">Опция 1</SelectItem>
|
||||
<SelectItem value="option2">Опция 2</SelectItem>
|
||||
<SelectItem value="option3">Опция 3</SelectItem>
|
||||
<SelectItem value="option4">Опция 4</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label className="text-white/90">
|
||||
Тип организации
|
||||
</Label>
|
||||
<Select>
|
||||
<SelectTrigger className="glass-input text-white">
|
||||
<SelectValue placeholder="Выберите тип..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="glass-card border-white/10">
|
||||
<SelectItem value="fulfillment">Фулфилмент</SelectItem>
|
||||
<SelectItem value="seller">Селлер</SelectItem>
|
||||
<SelectItem value="logist">Логистика</SelectItem>
|
||||
<SelectItem value="wholesale">Оптовик</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Чекбоксы и переключатели */}
|
||||
<Card className="glass-card border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Чекбоксы и переключатели</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
{/* Чекбоксы */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-white/90 text-sm font-medium">Чекбоксы</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="checkbox1"
|
||||
checked={checkboxValue}
|
||||
onCheckedChange={setCheckboxValue}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="checkbox1"
|
||||
className="text-white/90 text-sm cursor-pointer"
|
||||
>
|
||||
Согласие с условиями
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox id="checkbox2" />
|
||||
<Label
|
||||
htmlFor="checkbox2"
|
||||
className="text-white/90 text-sm cursor-pointer"
|
||||
>
|
||||
Получать уведомления
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox id="checkbox3" disabled />
|
||||
<Label
|
||||
htmlFor="checkbox3"
|
||||
className="text-white/60 text-sm"
|
||||
>
|
||||
Отключенный чекбокс
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Переключатели */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-white/90 text-sm font-medium">Переключатели (Switch)</h4>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch
|
||||
id="switch1"
|
||||
checked={switchValue}
|
||||
onCheckedChange={setSwitchValue}
|
||||
/>
|
||||
<Label
|
||||
htmlFor="switch1"
|
||||
className="text-white/90 text-sm cursor-pointer"
|
||||
>
|
||||
Включить уведомления
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch id="switch2" />
|
||||
<Label
|
||||
htmlFor="switch2"
|
||||
className="text-white/90 text-sm cursor-pointer"
|
||||
>
|
||||
Темная тема
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch id="switch3" disabled />
|
||||
<Label
|
||||
htmlFor="switch3"
|
||||
className="text-white/60 text-sm"
|
||||
>
|
||||
Отключенный переключатель
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Слайдеры */}
|
||||
<Card className="glass-card border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Слайдеры</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<div className="space-y-4">
|
||||
<Label className="text-white/90 text-sm font-medium">
|
||||
Значение: {sliderValue[0]}
|
||||
</Label>
|
||||
<Slider
|
||||
value={sliderValue}
|
||||
onValueChange={setSliderValue}
|
||||
max={100}
|
||||
min={0}
|
||||
step={1}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<Label className="text-white/90 text-sm font-medium">
|
||||
Диапазон цен: 1000 - 5000 ₽
|
||||
</Label>
|
||||
<Slider
|
||||
defaultValue={[1000, 5000]}
|
||||
max={10000}
|
||||
min={0}
|
||||
step={100}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Состояния полей */}
|
||||
<Card className="glass-card border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Состояния полей</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
{/* Обычное состояние */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="normal-state" className="text-white/90">
|
||||
Обычное состояние
|
||||
</Label>
|
||||
<Input
|
||||
id="normal-state"
|
||||
type="text"
|
||||
placeholder="Введите текст..."
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Фокус */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="focus-state" className="text-white/90">
|
||||
Состояние фокуса
|
||||
</Label>
|
||||
<Input
|
||||
id="focus-state"
|
||||
type="text"
|
||||
placeholder="Кликните для фокуса"
|
||||
className="glass-input text-white placeholder:text-white/50 focus:border-primary focus:ring-2 focus:ring-primary/20"
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Ошибка */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="error-state" className="text-white/90">
|
||||
Состояние ошибки
|
||||
</Label>
|
||||
<Input
|
||||
id="error-state"
|
||||
type="text"
|
||||
placeholder="Неверные данные"
|
||||
className="glass-input text-white placeholder:text-white/50 border-red-500 focus:border-red-500 focus:ring-2 focus:ring-red-500/20"
|
||||
/>
|
||||
<p className="text-red-400 text-xs">Это поле обязательно для заполнения</p>
|
||||
</div>
|
||||
|
||||
{/* Успех */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="success-state" className="text-white/90">
|
||||
Состояние успеха
|
||||
</Label>
|
||||
<Input
|
||||
id="success-state"
|
||||
type="text"
|
||||
value="Правильно заполнено"
|
||||
className="glass-input text-white placeholder:text-white/50 border-green-500 focus:border-green-500 focus:ring-2 focus:ring-green-500/20"
|
||||
readOnly
|
||||
/>
|
||||
<p className="text-green-400 text-xs">Данные сохранены успешно</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Примеры форм */}
|
||||
<Card className="glass-card border-white/10">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-white">Примеры форм</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-8">
|
||||
{/* Форма входа */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-white/90 text-sm font-medium">Форма входа</h4>
|
||||
<div className="space-y-4 max-w-sm">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="login-email" className="text-white/90">
|
||||
Email
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<User className="absolute left-3 top-1/2 transform -translate-y-1/2 text-white/50 h-4 w-4" />
|
||||
<Input
|
||||
id="login-email"
|
||||
type="email"
|
||||
placeholder="example@domain.com"
|
||||
className="pl-10 glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="login-password" className="text-white/90">
|
||||
Пароль
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-1/2 transform -translate-y-1/2 text-white/50 h-4 w-4" />
|
||||
<Input
|
||||
id="login-password"
|
||||
type="password"
|
||||
placeholder="Введите пароль"
|
||||
className="pl-10 glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox id="remember" />
|
||||
<Label htmlFor="remember" className="text-white/90 text-sm cursor-pointer">
|
||||
Запомнить меня
|
||||
</Label>
|
||||
</div>
|
||||
<Button variant="glass" className="w-full">
|
||||
Войти
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Форма регистрации */}
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-white/90 text-sm font-medium">Форма регистрации</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 max-w-2xl">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reg-name" className="text-white/90">
|
||||
Имя
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-name"
|
||||
type="text"
|
||||
placeholder="Ваше имя"
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reg-surname" className="text-white/90">
|
||||
Фамилия
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-surname"
|
||||
type="text"
|
||||
placeholder="Ваша фамилия"
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2 md:col-span-2">
|
||||
<Label htmlFor="reg-email" className="text-white/90">
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-email"
|
||||
type="email"
|
||||
placeholder="example@domain.com"
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2 md:col-span-2">
|
||||
<Label htmlFor="reg-phone" className="text-white/90">
|
||||
Телефон
|
||||
</Label>
|
||||
<PhoneInput
|
||||
id="reg-phone"
|
||||
placeholder="+7 (999) 999-99-99"
|
||||
className="glass-input text-white placeholder:text-white/50"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2 md:col-span-2">
|
||||
<Label className="text-white/90">
|
||||
Тип организации
|
||||
</Label>
|
||||
<Select>
|
||||
<SelectTrigger className="glass-input text-white">
|
||||
<SelectValue placeholder="Выберите тип..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="glass-card border-white/10">
|
||||
<SelectItem value="fulfillment">Фулфилмент</SelectItem>
|
||||
<SelectItem value="seller">Селлер</SelectItem>
|
||||
<SelectItem value="logist">Логистика</SelectItem>
|
||||
<SelectItem value="wholesale">Оптовик</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 md:col-span-2">
|
||||
<Checkbox id="reg-terms" />
|
||||
<Label htmlFor="reg-terms" className="text-white/90 text-sm cursor-pointer">
|
||||
Согласен с условиями использования
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex gap-2 md:col-span-2">
|
||||
<Button variant="outline" className="flex-1">
|
||||
Отмена
|
||||
</Button>
|
||||
<Button variant="glass" className="flex-1">
|
||||
Зарегистрироваться
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user