⚡ Кратко
Команды установки, список компонентов и структура файлов проекта.
Подготовка проекта
npm create vite@latest dashboard -- --template react-ts
cd dashboard && npm install
npm install tailwindcss @tailwindcss/vite
npm install -D @types/node
# алиас @/ в vite.config.ts и tsconfig — см. урок 17
npx shadcn@latest init
Компоненты проекта
npx shadcn@latest add button card badge input label field
npx shadcn@latest add table tabs dialog sheet dropdown-menu select switch skeleton separator avatar
| Компонент | Где используется |
Card | метрики, график, блоки |
Table | список заказов |
Badge | статусы заказов, дельты метрик |
DropdownMenu | действия строки, меню профиля |
Dialog | создание заказа, подтверждение удаления |
Sheet | мобильное меню, фильтры |
Tabs | «Активные / Архив» |
Skeleton | состояние загрузки |
Field, Input, Select | формы |
Структура файлов
src/
├── components/
│ ├── ui/ ← компоненты реестра (не трогаем без нужды)
│ ├── app-shell.tsx ← каркас: сайдбар + шапка + контент
│ ├── app-sidebar.tsx
│ ├── app-header.tsx
│ ├── metric-card.tsx
│ ├── revenue-chart.tsx
│ ├── orders-table.tsx
│ ├── order-actions.tsx ← меню строки
│ ├── create-order-dialog.tsx
│ └── filters-sheet.tsx
├── lib/
│ ├── utils.ts ← cn()
│ └── schemas.ts ← схемы zod
├── routes/
│ └── dashboard.tsx
└── index.css ← тема
Раскладка каркаса
| Задача | Классы |
| Каркас на весь экран | grid min-h-svh grid-rows-[auto_1fr] lg:grid-cols-[16rem_1fr] |
| Сайдбар на всю высоту | lg:col-start-1 lg:row-span-2 |
| Прокрутка только контента | overflow-y-auto у main |
| Липкая шапка | sticky top-0 z-10 bg-background/95 |
| Сетка метрик | grid grid-cols-2 gap-4 lg:grid-cols-4 |
| График шире таблицы | lg:col-span-2 |
| Таблица на мобильном | overflow-x-auto у обёртки |
Проверка перед сдачей
| Что | Команда или действие |
| Сборка | npm run build |
| Размер CSS | ls -l dist/assets/*.css |
| Адаптив | ширины 320, 375, 768, 1024, 1440 |
| Клавиатура | обход всей страницы по Tab |
| Тёмная тема | переключатель на каждом экране |
| Контраст | DevTools на основном и приглушённом тексте |