# UI КОМПОНЕНТЫ СИСТЕМЫ SFERA

## 🎯 ОБЗОР UI СИСТЕМЫ

SFERA использует современную дизайн-систему основанную на **Radix UI**, **Class Variance Authority (CVA)** и **Tailwind CSS** с уникальным **Glass Morphism** стилем. Система включает 36 специализированных UI компонентов с полной типизацией TypeScript.

### Архитектурные принципы:

- **Headless UI** - Radix UI для функциональности + кастомная стилизация
- **Variant-driven** - CVA для типизированных вариантов компонентов
- **Glass Morphism** - Современные полупрозрачные эффекты с backdrop-filter
- **Accessibility First** - Полная поддержка ARIA и клавиатурной навигации
- **TypeScript Native** - Строгая типизация всех props и вариантов

## 📦 ПОЛНЫЙ КАТАЛОГ КОМПОНЕНТОВ (36 компонентов)

### 🔘 1. BUTTON (button.tsx)

**Описание:** Основной интерактивный элемент с множественными вариантами дизайна.

```typescript
interface ButtonProps {
  variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' | 'glass' | 'glass-secondary'
  size?: 'default' | 'sm' | 'lg' | 'icon'
  asChild?: boolean
}
```

**Варианты стилей:**

- **`default`** - основная фиолетовая кнопка `bg-primary text-primary-foreground`
- **`destructive`** - красная кнопка для опасных действий `bg-destructive text-white`
- **`outline`** - кнопка с границей `border bg-background`
- **`secondary`** - вторичная кнопка `bg-secondary text-secondary-foreground`
- **`ghost`** - прозрачная кнопка `hover:bg-accent`
- **`link`** - текстовая ссылка `text-primary underline-offset-4`
- **`glass`** - Glass Morphism стиль с градиентом
- **`glass-secondary`** - полупрозрачная Glass кнопка

**Размеры:**

- **`default`** - `h-9 px-4 py-2` (36px высота)
- **`sm`** - `h-8 px-3` (32px высота)
- **`lg`** - `h-10 px-6` (40px высота)
- **`icon`** - `size-9` (36x36px квадрат)

**Пример использования:**

```typescript
<Button variant="glass" size="lg">
  Сохранить изменения
</Button>
```

### 🃏 2. CARD (card.tsx)

**Описание:** Контейнер для группировки связанного контента с составной архитектурой.

```typescript
// Составные компоненты
<Card>
  <CardHeader>
    <CardTitle>Заголовок карточки</CardTitle>
    <CardDescription>Описание содержимого</CardDescription>
    <CardAction>Действие</CardAction>
  </CardHeader>
  <CardContent>
    Основное содержимое
  </CardContent>
  <CardFooter>
    Нижняя часть
  </CardFooter>
</Card>
```

**CSS классы:**

- **Card**: `bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm`
- **CardHeader**: Использует CSS Grid для автоматического позиционирования
- **CardTitle**: `leading-none font-semibold`
- **CardDescription**: `text-muted-foreground text-sm`

### ⌨️ 3. INPUT (input.tsx)

**Описание:** Поле ввода текста с поддержкой Glass Morphism и состояний фокуса.

```typescript
interface InputProps extends React.ComponentProps<'input'> {
  // Стандартные HTML input props
}

// Два варианта стилизации
<Input placeholder="Стандартное поле" />
<GlassInput placeholder="Glass Morphism поле" />
```

**Стили Input:**

- Базовый класс: `h-9 w-full rounded-md border bg-transparent px-3 py-1`
- Фокус: `focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]`
- Ошибка: `aria-invalid:ring-destructive/20 aria-invalid:border-destructive`

**Стили GlassInput:**

- Базовый класс: `glass-input text-white placeholder:text-white/60`
- Размеры: `h-11 rounded-lg px-4 py-3` (больше обычного input)
- Эффекты: полупрозрачный фон с backdrop-filter

### 🏷️ 4. BADGE (badge.tsx)

**Описание:** Небольшие метки для отображения статуса, категорий или счетчиков.

```typescript
interface BadgeProps {
  variant?: 'default' | 'secondary' | 'destructive' | 'outline'
  asChild?: boolean
}
```

**Варианты:**

- **`default`** - `bg-primary text-primary-foreground`
- **`secondary`** - `bg-secondary text-secondary-foreground`
- **`destructive`** - `bg-destructive text-white`
- **`outline`** - `text-foreground border` (прозрачный фон)

**Базовые стили:**

- Размер: `px-2 py-0.5 text-xs font-medium`
- Форма: `rounded-md border`
- Поддержка иконок: `[&>svg]:size-3 gap-1`

### 📊 5. PROGRESS (progress.tsx)

**Описание:** Индикатор прогресса для отображения выполнения задач.

```typescript
<Progress value={75} className="w-full" />
```

### 📱 6. ALERT (alert.tsx)

**Описание:** Компонент для отображения важных сообщений пользователю.

```typescript
<Alert>
  <AlertTitle>Внимание</AlertTitle>
  <AlertDescription>Важное сообщение для пользователя</AlertDescription>
</Alert>
```

### 🗂️ 7. TABS (tabs.tsx)

**Описание:** Система вкладок для переключения между разными представлениями.

```typescript
<Tabs defaultValue="tab1">
  <TabsList>
    <TabsTrigger value="tab1">Вкладка 1</TabsTrigger>
    <TabsTrigger value="tab2">Вкладка 2</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">Содержимое 1</TabsContent>
  <TabsContent value="tab2">Содержимое 2</TabsContent>
</Tabs>
```

**Особенности стилизации:**

- Список вкладок: Glass Morphism фон `background: rgba(255, 255, 255, 0.12)`
- Активная вкладка: `background: rgba(255, 255, 255, 0.2)` с белым текстом
- Hover эффект: `background: rgba(255, 255, 255, 0.1)`

### 📝 8. TEXTAREA (textarea.tsx)

**Описание:** Многострочное поле ввода текста.

```typescript
<Textarea placeholder="Введите текст..." rows={4} />
```

### ☑️ 9. CHECKBOX (checkbox.tsx)

**Описание:** Чекбокс для выбора опций.

```typescript
<Checkbox checked={isChecked} onCheckedChange={setIsChecked} />
```

### 🎚️ 10. SWITCH (switch.tsx)

**Описание:** Переключатель для включения/выключения функций.

```typescript
<Switch checked={isEnabled} onCheckedChange={setIsEnabled} />
```

### 🎚️ 11. SLIDER (slider.tsx)

**Описание:** Ползунок для выбора числовых значений.

```typescript
<Slider defaultValue={[50]} max={100} step={1} />
```

### 📅 12. CALENDAR (calendar.tsx)

**Описание:** Компонент календаря для выбора дат.

```typescript
<Calendar mode="single" selected={date} onSelect={setDate} />
```

### 📅 13. DATE-PICKER (date-picker.tsx)

**Описание:** Поле выбора даты с календарем.

```typescript
<DatePicker value={date} onChange={setDate} />
```

### 📅 14. GLASS-DATE-PICKER (glass-date-picker.tsx)

**Описание:** Date picker в Glass Morphism стиле.

```typescript
<GlassDatePicker value={date} onChange={setDate} />
```

### 📋 15. SELECT (select.tsx)

**Описание:** Выпадающий список для выбора опций.

```typescript
<Select value={value} onValueChange={setValue}>
  <SelectTrigger>
    <SelectValue placeholder="Выберите опцию" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="option1">Опция 1</SelectItem>
    <SelectItem value="option2">Опция 2</SelectItem>
  </SelectContent>
</Select>
```

### 📋 16. GLASS-SELECT (glass-select.tsx)

**Описание:** Select в Glass Morphism стиле для темных фонов.

### 🏷️ 17. LABEL (label.tsx)

**Описание:** Метки для полей форм с accessibility.

```typescript
<Label htmlFor="email">Email адрес</Label>
<Input id="email" type="email" />
```

### 👤 18. AVATAR (avatar.tsx)

**Описание:** Отображение аватаров пользователей с fallback.

```typescript
<Avatar>
  <AvatarImage src="/avatar.jpg" alt="User" />
  <AvatarFallback>JD</AvatarFallback>
</Avatar>
```

### 🌐 19. DIALOG (dialog.tsx)

**Описание:** Модальные окна для важного контента.

```typescript
<Dialog>
  <DialogTrigger>Открыть диалог</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Заголовок</DialogTitle>
      <DialogDescription>Описание</DialogDescription>
    </DialogHeader>
    <DialogFooter>
      <Button>Сохранить</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>
```

### ⚠️ 20. ALERT-DIALOG (alert-dialog.tsx)

**Описание:** Критичные диалоги подтверждения.

```typescript
<AlertDialog>
  <AlertDialogTrigger>Удалить</AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Подтвердите удаление</AlertDialogTitle>
      <AlertDialogDescription>
        Это действие нельзя отменить.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Отмена</AlertDialogCancel>
      <AlertDialogAction>Удалить</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>
```

### 💬 21. POPOVER (popover.tsx)

**Описание:** Всплывающие элементы для дополнительного контента.

```typescript
<Popover>
  <PopoverTrigger>Показать информацию</PopoverTrigger>
  <PopoverContent>
    Дополнительная информация
  </PopoverContent>
</Popover>
```

### 📱 22. DROPDOWN-MENU (dropdown-menu.tsx)

**Описание:** Выпадающие меню для действий и навигации.

```typescript
<DropdownMenu>
  <DropdownMenuTrigger>Меню</DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>Действие 1</DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Действие 2</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>
```

### ➖ 23. SEPARATOR (separator.tsx)

**Описание:** Визуальные разделители контента.

```typescript
<Separator orientation="horizontal" />
<Separator orientation="vertical" />
```

### 📱 24. PHONE-INPUT (phone-input.tsx)

**Описание:** Специализированное поле для ввода номеров телефонов.

```typescript
<PhoneInput value={phone} onChange={setPhone} />
```

### 💀 25. SKELETON (skeleton.tsx)

**Описание:** Плейсхолдеры для загружающегося контента.

```typescript
<Skeleton className="h-4 w-full" />
<Skeleton className="h-8 w-8 rounded-full" />
```

### 🛒 26. PRODUCT-CARD-SKELETON (product-card-skeleton.tsx)

**Описание:** Специализированный скелетон для карточек товаров.

```typescript
<ProductCardSkeleton />
```

### ⏳ 27. LOADING-FALLBACK (loading-fallback.tsx)

**Описание:** Компонент загрузки для асинхронного контента.

```typescript
<LoadingFallback text="Загрузка данных..." />
```

## 🎵 МЕДИА КОМПОНЕНТЫ

### 🎤 28. VOICE-RECORDER (voice-recorder.tsx)

**Описание:** Запись голосовых сообщений с реального времени UI.

```typescript
<VoiceRecorder onRecordingComplete={handleRecording} />
```

### ▶️ 29. VOICE-PLAYER (voice-player.tsx)

**Описание:** Воспроизведение аудио сообщений с прогресс-баром.

```typescript
<VoicePlayer audioUrl="/audio.mp3" duration={30} />
```

### 🖼️ 30. IMAGE-MESSAGE (image-message.tsx)

**Описание:** Отображение изображений в сообщениях.

```typescript
<ImageMessage src="/image.jpg" alt="Сообщение" />
```

### 🔍 31. IMAGE-LIGHTBOX (image-lightbox.tsx)

**Описание:** Полноэкранный просмотр изображений.

```typescript
<ImageLightbox images={imageUrls} initialIndex={0} />
```

### 📄 32. FILE-MESSAGE (file-message.tsx)

**Описание:** Отображение файловых вложений.

```typescript
<FileMessage fileName="document.pdf" fileSize={1024000} fileUrl="/file.pdf" />
```

### 📤 33. FILE-UPLOADER (file-uploader.tsx)

**Описание:** Загрузка файлов с drag & drop.

```typescript
<FileUploader onFileSelect={handleFiles} accept=".pdf,.doc,.docx" />
```

### 😀 34. EMOJI-PICKER (emoji-picker.tsx)

**Описание:** Выбор эмодзи для сообщений.

```typescript
<EmojiPicker onEmojiSelect={handleEmojiSelect} />
```

### 📊 35. CHART (chart.tsx)

**Описание:** Компоненты для отображения графиков и диаграмм.

```typescript
<Chart data={chartData} type="line" />
```

### 🔔 36. SONNER (sonner.tsx)

**Описание:** Система toast уведомлений.

```typescript
import { toast } from 'sonner'

toast.success('Операция выполнена успешно')
toast.error('Произошла ошибка')
toast.info('Информационное сообщение')
```

## 📊 КАСТОМНЫЕ ТАБЛИЦЫ СИСТЕМЫ

### 🏷️ 37. MULTILEVEL SUPPLIES TABLE (multilevel-supplies-table.tsx)

**Описание:** Многоуровневая таблица поставок для кабинета селлера в разделе "Мои поставки".

**Интерфейсы:**

```typescript
interface MultiLevelSuppliesTableProps {
  supplies?: SupplyOrderFromGraphQL[]
  loading?: boolean
  userRole?: 'SELLER' | 'WHOLESALE' | 'FULFILLMENT' | 'LOGIST'
  onSupplyAction?: (supplyId: string, action: string) => void
}

interface SupplyOrderFromGraphQL {
  id: string
  organizationId: string
  partnerId: string
  partner: {
    id: string
    name?: string
    fullName?: string
    inn: string
    address?: string
    type: string
  }
  deliveryDate: string
  status: string
  totalAmount: number
  totalItems: number
  fulfillmentCenter?: {
    id: string
    name?: string
    address?: string
  }
  routes: Route[]
  items: SupplyItem[]
  createdAt: string
}
```

**Особенности:**

- Трехуровневая структура: Поставка → Маршруты → Товары
- Раскрываемые/сворачиваемые уровни
- Различные представления для разных ролей пользователей
- Glass morphism дизайн с полупрозрачными карточками

**Использование:**

```typescript
<MultiLevelSuppliesTable
  supplies={suppliesData}
  loading={isLoading}
  userRole="SELLER"
  onSupplyAction={(id, action) => handleSupplyAction(id, action)}
/>
```

### 📦 38. GOODS SUPPLIES TABLE (goods-supplies-table.tsx)

**Описание:** Таблица товарных поставок с детальной структурой.

**Интерфейсы:**

```typescript
interface GoodsSuppliesTableProps {
  supplies?: GoodsSupply[]
  loading?: boolean
  onActionClick?: (supplyId: string, action: string) => void
}

interface GoodsSupply {
  id: string
  number: string
  creationMethod: 'cards' | 'suppliers' // 📱 карточки / 🏢 поставщик
  date: string
  status: SupplyStatus
  totalAmount: number
  routes: GoodsSupplyRoute[]
}

interface GoodsSupplyRoute {
  id: string
  from: string
  fromAddress: string
  to: string
  toAddress: string
  wholesalers: GoodsSupplyWholesaler[]
  totalProductPrice: number
  fulfillmentServicePrice: number
  logisticsPrice: number
  totalAmount: number
}

interface GoodsSupplyProduct {
  id: string
  name: string
  sku: string
  category: string
  plannedQty: number
  actualQty: number
  defectQty: number
  productPrice: number
  parameters: ProductParameter[]
}
```

**Особенности:**

- Четырехуровневая структура: Поставка → Маршрут → Поставщик → Товар
- Детальная информация по каждому уровню
- Цветовая индикация статусов
- Расчет итоговых сумм на каждом уровне
- Поддержка параметров товаров

**Статусы поставок:**

```typescript
type SupplyStatus =
  | 'new' // Новая
  | 'confirmed' // Подтверждена
  | 'in_transit' // В пути
  | 'at_fulfillment' // На фулфилменте
  | 'in_processing' // В обработке
  | 'completed' // Завершена
  | 'cancelled' // Отменена
  | 'issue' // Проблема
```

**Использование:**

```typescript
<GoodsSuppliesTable
  supplies={goodsSupplies}
  loading={isLoading}
  onActionClick={(id, action) => {
    if (action === 'view') navigateToDetails(id)
    if (action === 'cancel') cancelSupply(id)
  }}
/>
```

## 🎨 ДИЗАЙН-СИСТЕМА КОМПОНЕНТОВ

### Унифицированные props:

```typescript
// Большинство компонентов поддерживают:
interface CommonProps {
  className?: string // Дополнительные CSS классы
  asChild?: boolean // Использование как Slot от Radix
  'data-slot'?: string // Автоматический слот для идентификации
}
```

### Паттерн CVA (Class Variance Authority):

```typescript
const componentVariants = cva(
  'базовые-классы', // Общие стили для всех вариантов
  {
    variants: {
      variant: {
        // Варианты дизайна
        default: 'стили-по-умолчанию',
        secondary: 'вторичные-стили',
      },
      size: {
        // Размеры
        sm: 'маленький-размер',
        lg: 'большой-размер',
      },
    },
    defaultVariants: {
      // Значения по умолчанию
      variant: 'default',
      size: 'default',
    },
  },
)
```

### Accessibility Features:

- **ARIA Support** - все компоненты поддерживают ARIA атрибуты
- **Keyboard Navigation** - полная навигация с клавиатуры
- **Focus Management** - логичное управление фокусом
- **Screen Reader** - совместимость с программами чтения экрана

### Glass Morphism Effects:

```css
.glass-card {
  background: rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 8px 32px rgba(168, 85, 247, 0.18);
}

.glass-input {
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.glass-button {
  background: linear-gradient(135deg, rgba(168, 85, 247, 0.9) 0%, rgba(59, 130, 246, 0.85) 100%);
  backdrop-filter: blur(20px);
}
```

## 🔧 ПРАВИЛА ИСПОЛЬЗОВАНИЯ

### 1. Типизация компонентов

```typescript
// ✅ Правильно - с типизацией
<Button variant="glass" size="lg" onClick={handleClick}>
  Действие
</Button>

// ❌ Неправильно - без типизации
<button className="some-custom-class">
  Действие
</button>
```

### 2. Композиция сложных компонентов

```typescript
// ✅ Правильно - составная структура
<Card>
  <CardHeader>
    <CardTitle>Заказ #1234</CardTitle>
    <CardAction>
      <Button size="sm">Детали</Button>
    </CardAction>
  </CardHeader>
  <CardContent>
    <p>Описание заказа</p>
  </CardContent>
</Card>

// ❌ Неправильно - плоская структура
<div className="card">
  <h3>Заказ #1234</h3>
  <p>Описание заказа</p>
</div>
```

### 3. Glass Morphism для темных фонов

```typescript
// ✅ Правильно - Glass компоненты на темном фоне
<div className="bg-gradient-cosmic">
  <GlassInput placeholder="Поиск..." />
  <Button variant="glass">Найти</Button>
</div>

// ❌ Неправильно - обычные компоненты на темном фоне
<div className="bg-black">
  <Input placeholder="Поиск..." />  {/* Не видно */}
</div>
```

### 4. Accessibility обязателен

```typescript
// ✅ Правильно - с accessibility
<Label htmlFor="email">Email</Label>
<Input
  id="email"
  type="email"
  aria-describedby="email-error"
  aria-invalid={hasError}
/>
{hasError && <span id="email-error">Неверный формат email</span>}

// ❌ Неправильно - без accessibility
<span>Email</span>
<input type="email" />
```

### 5. Состояния загрузки

```typescript
// ✅ Правильно - скелетоны для загрузки
{loading ? (
  <ProductCardSkeleton />
) : (
  <ProductCard data={product} />
)}

// ❌ Неправильно - пустая область
{loading ? null : <ProductCard data={product} />}
```

## 🏪 КОМПОНЕНТЫ КАБИНЕТА ПОСТАВЩИКА (WHOLESALE)

### АРХИТЕКТУРА КОМПОНЕНТОВ ПОСТАВЩИКА:

```typescript
src/components/
├── warehouse/              # Компоненты склада поставщика
│   ├── warehouse-dashboard.tsx      # Главный dashboard склада
│   ├── product-card.tsx            # Карточка товара
│   ├── product-form.tsx            # Форма создания/редактирования товара
│   └── warehouse-statistics.tsx    # Статистика склада
├── supplier-orders/        # Компоненты обработки заказов
│   ├── supplier-orders-dashboard.tsx  # Главный dashboard заказов
│   ├── supplier-order-card.tsx       # Карточка заказа
│   ├── supplier-orders-tabs.tsx      # Табы по статусам заказов
│   ├── supplier-orders-search.tsx    # Поиск и фильтры
│   └── supplier-order-stats.tsx      # Статистика заказов
└── economics/              # Экономическая аналитика
    └── wholesale-economics-page.tsx  # Финансовая отчетность
```

### 🏢 КАРТОЧКА ПОСТАВЩИКА В ИНТЕРФЕЙСЕ:

**Структура карточки:**

```jsx
<div className="supplier-card glass-card">
  <div className="flex items-start gap-2">
    {/* Аватар организации */}
    <OrganizationAvatar organization={supplier} size="sm" />

    <div className="flex-1 min-w-0">
      {/* Название поставщика */}
      <h4 className="text-white font-medium text-sm truncate">{supplier.name || supplier.fullName}</h4>

      {/* ИНН и рынок */}
      <div className="flex items-center gap-2 mt-1">
        <p className="text-white/60 text-xs font-mono">ИНН: {supplier.inn}</p>
        {supplier.market && <Badge className="market-badge">{getMarketLabel(supplier.market)}</Badge>}
      </div>
    </div>
  </div>
</div>
```

**Визуальные правила карточки поставщика:**

- **Аватар**: Размер `sm`, позиционирование слева от текста
- **Название**: Приоритет `name` над `fullName`, с усечением `truncate`
- **ИНН**: Моноширинный шрифт `font-mono`, цвет `text-white/60`
- **Рынок**: Badge компонент с индивидуальными цветовыми схемами
- **Glass эффект**: `glass-card` класс с полупрозрачным фоном

### 🔍 ПОИСКОВЫЙ ИНТЕРФЕЙС ПОСТАВЩИКОВ:

```jsx
<Input
  placeholder="Поиск поставщиков..."
  className="bg-white/5 border-white/10 text-white placeholder:text-white/50 pl-10 h-9"
  onChange={(e) => handleSupplierSearch(e.target.value)}
/>
```

**Особенности поиска:**

- Glass эффект: `bg-white/5 border-white/10`
- Плейсхолдер: `placeholder:text-white/50`
- Левый отступ для иконки: `pl-10`
- Высота: `h-9` (36px)

### 🎨 ЦВЕТОВЫЕ СХЕМЫ РЫНКОВ ПОСТАВЩИКОВ:

```typescript
// Примеры цветовых схем для физических рынков
const marketColors = {
  sadovod: 'bg-green-500/20 text-green-300 border-green-500/30',
  'tyak-moscow': 'bg-blue-500/20 text-blue-300 border-blue-500/30',
  default: 'bg-gray-500/20 text-gray-300 border-gray-500/30',
}

// Функция получения метки рынка
function getMarketLabel(market: string): string {
  const labels = {
    sadovod: 'Садовод',
    'tyak-moscow': 'ТЯК Москва',
    default: 'Рынок',
  }
  return labels[market] || labels.default
}
```

### 📦 БЛОКИ ПОСТАВЩИКОВ В СЕЛЛЕР ИНТЕРФЕЙСЕ:

**Правила горизонтальной прокрутки:**

```jsx
{
  /* Контейнер с горизонтальной прокруткой */
}
;<div className="flex gap-3 overflow-x-auto scrollbar-hide pb-2">
  {suppliers.map((supplier) => (
    <div
      key={supplier.id}
      className="flex-none w-64" // Фиксированная ширина 256px
    >
      <SupplierCard supplier={supplier} />
    </div>
  ))}
</div>
```

**Требования к горизонтальным блокам:**

- Фиксированная ширина карточек: `w-64` (256px)
- Отсутствие сжатия: `flex-none`
- Скрытие скроллбара: `scrollbar-hide`
- Отступ от низа: `pb-2` для визуального комфорта

### 🚨 CRITICAL UI RULES ДЛЯ ПОСТАВЩИКОВ:

#### **1. СТАТУСЫ vs КНОПКИ ДЕЙСТВИЙ:**

```jsx
{
  /* ❌ НЕПРАВИЛЬНО: Показывать статус поставщику */
}
{
  user.organization.type === 'WHOLESALE' && <StatusBadge status={order.status}>Ожидает подтверждения</StatusBadge>
}

{
  /* ✅ ПРАВИЛЬНО: Только кнопки действий для поставщика */
}
{
  user.organization.type === 'WHOLESALE' && order.status === 'PENDING' && (
    <div className="flex gap-2">
      <Button variant="glass" size="sm" onClick={() => approveOrder(order.id)}>
        Одобрить
      </Button>
      <Button variant="outline" size="sm" onClick={() => rejectOrder(order.id)}>
        Отклонить
      </Button>
    </div>
  )
}
```

#### **2. ОПЦИОНАЛЬНЫЕ ПАРАМЕТРЫ ПОСТАВКИ ПРИ ОДОБРЕНИИ:**

```jsx
{
  /* ОПЦИОНАЛЬНЫЕ параметры поставки для поставщика - отображаются при одобрении заказа */
}
;<div className="grid grid-cols-2 gap-4">
  <div>
    <Label htmlFor="packagesCount">Количество грузовых мест</Label>
    <Input
      id="packagesCount"
      type="number"
      placeholder="Введите количество (опционально)"
      aria-describedby="packages-help"
    />
    <p id="packages-help" className="text-xs text-white/60 mt-1">
      Параметр поставки для логистических расчетов
    </p>
  </div>

  <div>
    <Label htmlFor="volume">Объем груза (м³)</Label>
    <Input id="volume" type="number" step="0.01" placeholder="0.00 (опционально)" aria-describedby="volume-help" />
    <p id="volume-help" className="text-xs text-white/60 mt-1">
      Параметр поставки для планирования маршрутов
    </p>
  </div>

  <div>
    <Label htmlFor="deliveryDate">Дата поставки</Label>
    <GlassDatePicker
      id="deliveryDate"
      placeholder="Выберите дату поставки"
      aria-describedby="delivery-help"
    />
    <p id="delivery-help" className="text-xs text-white/60 mt-1">
      Основной параметр поставки - когда товары должны быть доставлены
    </p>
  </div>

  <div>
    <Label htmlFor="totalAmount">Общая стоимость товаров</Label>
    <Input id="totalAmount" type="number" readOnly className="bg-white/5" />
    <p className="text-xs text-white/60 mt-1">
      Ключевой параметр поставки - автоматически рассчитывается
    </p>
  </div>

  <div className="col-span-2">
    <Label htmlFor="readyDate">Дата готовности к отгрузке</Label>
    <GlassDatePicker
      id="readyDate"
      value={readyDate}
      onChange={setReadyDate}
      placeholder="Выберите дату (опционально)"
      aria-describedby="ready-date-help"
    />
    <p id="ready-date-help" className="text-xs text-white/60 mt-1">
      Когда товары будут готовы к передаче логистике
    </p>
  </div>

  <div className="col-span-2">
    <Label htmlFor="notes">Комментарии для логистики</Label>
    <Textarea id="notes" placeholder="Дополнительная информация (опционально)" aria-describedby="notes-help" />
    <p id="notes-help" className="text-xs text-white/60 mt-1">
      Особые требования к транспортировке или упаковке
    </p>
  </div>
</div>

{
  /* ВАЖНО: Поля показываются на 1-м уровне визуализации поставки */
}
;<div className="mt-4">
  <p className="text-sm text-white/80">ℹ️ Все поля опциональны, но рекомендуются для точного планирования логистики</p>
</div>
```

#### **3. ARIA LABELS ДЛЯ КОМПОНЕНТОВ ПОСТАВЩИКА:**

```jsx
// Кнопки действий с описательными ARIA-атрибутами
<Button
  variant="glass"
  aria-label={`Одобрить заказ №${order.number} от ${order.organization.name}`}
  onClick={() => approveOrder(order.id)}
>
  Одобрить
</Button>

// Поля ввода с полными описаниями
<Input
  aria-label="Количество грузовых мест для логистического расчета"
  aria-required="true"
  aria-describedby="packages-error packages-help"
/>
```

#### **4. СПЕЦИАЛЬНЫЕ РАЗМЕРЫ ДЛЯ КАБИНЕТА ПОСТАВЩИКА:**

```typescript
// Размеры карточек в кабинете поставщика
const wholesaleSizes = {
  supplierCard: 'h-[164px] w-64', // 164px высота, 256px ширина
  orderCard: 'min-h-[120px]', // Минимум 120px для заказов
  productCard: 'h-[180px]', // 180px для товарных карточек
  containerWithPadding: 'h-[196px]', // 164 + 32px отступы сверху/снизу
}
```

### 📐 ФОРМУЛА РАСЧЕТА РАЗМЕРОВ КОНТЕЙНЕРОВ:

```typescript
// ОБЯЗАТЕЛЬНАЯ формула для всех контейнеров поставщика
const containerHeight = {
  formula: 'Высота контента + padding-top + padding-bottom',
  example: {
    content: '164px', // Высота карточки поставщика
    paddingTop: '16px',
    paddingBottom: '16px',
    totalContainer: '196px' // 164 + 16 + 16 = 196px
  }
}

// ❌ ЗАПРЕЩЕНО: Произвольные размеры без расчета
<div className="h-200"> {/* Откуда 200px? */}

// ✅ ПРАВИЛЬНО: С математическим обоснованием
<div className="h-[196px]"> {/* 164px + 32px отступы */}
```

## 📱 АДАПТИВНОСТЬ

### Responsive Breakpoints:

- **`sm`** - `640px` и выше
- **`md`** - `768px` и выше
- **`lg`** - `1024px` и выше
- **`xl`** - `1280px` и выше

### Mobile-First подход:

```typescript
// ✅ Правильно
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
  {items.map(item => <Card key={item.id}>{item.name}</Card>)}
</div>

// ❌ Неправильно
<div className="grid-cols-3"> {/* Не адаптивно */}
```

## 🚀 ПРОИЗВОДИТЕЛЬНОСТЬ

### Lazy Loading компонентов:

```typescript
const HeavyComponent = lazy(() => import('./heavy-component'))

// Использование с Suspense
<Suspense fallback={<LoadingFallback />}>
  <HeavyComponent />
</Suspense>
```

### Мемоизация дорогих вычислений:

```typescript
const ExpensiveComponent = memo(({ data }) => {
  const processedData = useMemo(() =>
    processLargeDataset(data), [data]
  )

  return <Chart data={processedData} />
})
```

---

_UI компоненты задокументированы на основе анализа 36 файлов в src/components/ui/_  
_Версия документа: 2025-08-21_  
_Основа: Radix UI + CVA + Tailwind CSS + Glass Morphism_
