Files
food-ai/docs/Design.md
dbastrikin 24219b611e feat: implement Iteration 0 foundation (backend + Flutter client)
Backend (Go):
- Project structure with chi router, pgxpool, goose migrations
- JWT auth (access/refresh tokens) with Firebase token verification
- NoopTokenVerifier for local dev without Firebase credentials
- PostgreSQL user repository with atomic profile updates (transactions)
- Mifflin-St Jeor calorie calculation based on profile data
- REST API: POST /auth/login, /auth/refresh, /auth/logout, GET/PUT /profile, GET /health
- Middleware: auth, CORS (localhost wildcard), logging, recovery, request_id
- Unit tests (51 passing) and integration tests (testcontainers)
- Docker Compose setup with postgres healthcheck and graceful shutdown

Flutter client:
- Riverpod state management with GoRouter navigation
- Firebase Auth (email/password + Google sign-in with web popup support)
- Platform-aware API URLs (web/Android/iOS)
- Dio HTTP client with JWT auth interceptor and concurrent refresh handling
- Secure token storage
- Screens: Login, Register, Home (tabs: Menu, Recipes, Products, Profile)
- Unit tests (17 passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 13:14:58 +02:00

1736 lines
130 KiB
Markdown
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.
# FoodAI — Дизайн экранов (Wireframe-описания)
## Навигация
Приложение использует нижнюю панель навигации (Bottom Tab Bar) с 5 вкладками:
```
┌─────────────────────────────────────┐
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
Иконки вкладок: домик, корзина, календарь, книга, аватар.
Активная вкладка подсвечивается акцентным цветом. Над иконкой «Продукты» может отображаться badge с количеством продуктов с истекающим сроком.
---
## 0. Онбординг (первый запуск)
Пошаговый процесс при первом запуске. Знакомит пользователя с приложением и собирает данные для персонализации.
### Шаг 1 — Приветствие (23 карточки, свайп)
```
┌─────────────────────────────────────┐
│ │
│ [Иллюстрация] │
│ │
│ Управляйте питанием │
с помощью камеры │
│ │
│ Сфотографируйте чек или │
│ продукты — мы распознаем │
│ их и подберём рецепты │
│ │
│ ● ○ ○ │
│ │
│ ┌───────────────────────────────┐ │
│ │ Далее │ │
│ └───────────────────────────────┘ │
│ │
│ Пропустить │
│ │
└─────────────────────────────────────┘
```
### Шаг 2 — Параметры тела
```
┌─────────────────────────────────────┐
│ Расскажите о себе
├─────────────────────────────────────┤
│ │
│ Пол │
│ [Мужской] [Женский] │
│ │
│ Возраст │
│ ┌──────────────────────────┐ │
│ │ 28 │ │
│ └──────────────────────────┘ │
│ │
│ Рост (см) │
│ ┌──────────────────────────┐ │
│ │ 178 │ │
│ └──────────────────────────┘ │
│ │
Вес (кг) │
│ ┌──────────────────────────┐ │
│ │ 75 │ │
│ └──────────────────────────┘ │
│ │
│ Уровень активности │
│ [Низкая] [Средняя●] [Высокая] │
│ │
│ ┌───────────────────────────────┐ │
│ │ Далее │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
### Шаг 3 — Цель и расчёт
```
┌─────────────────────────────────────┐
│ Ваша цель │
├─────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ ○ Похудение │ │
│ │ Дефицит калорий │ │
│ ├───────────────────────────────┤ │
│ │ ● Поддержание веса │ │
│ │ Сбалансированное питание │ │
│ ├───────────────────────────────┤ │
│ │ ○ Набор массы │ │
│ │ Профицит калорий │ │
│ └───────────────────────────────┘ │
│ │
│ Ваша рекомендуемая норма: │
│ ┌───────────────────────────────┐ │
│ │ 2 100 ккал/день │ │
│ │ Б: 120г · Ж: 70г · У: 260г │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ Далее │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
### Шаг 4 — Ограничения и предпочтения кухонь
```
┌─────────────────────────────────────┐
│ Ограничения в питании │
├─────────────────────────────────────┤
│ │
│ Есть ли аллергии или ограничения? │
│ (можно выбрать несколько) │
│ │
│ [ ] Вегетарианство │
│ [ ] Без глютена │
│ [ ] Без лактозы │
│ [✓] Без орехов │
│ [ ] Халяль │
│ [ ] Кошерное │
│ │
│ Какая кухня вам нравится? │
│ (выберите 13) │
│ │
│ [Русская✓] [Азиатская✓] [Европ.] │
│ [Средизем.] [Американ.] [Кавказ.] │
│ │
│ ┌───────────────────────────────┐ │
│ │ Далее │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
### Шаг 5 — Добавить первые продукты
```
┌─────────────────────────────────────┐
│ Добавьте ваши продукты │
├─────────────────────────────────────┤
│ │
│ [Иллюстрация: │
│ холодильник] │
│ │
│ Сфотографируйте содержимое │
│ холодильника или чек из магазина, │
│ и мы подберём рецепты │
│ │
│ ┌───────────────────────────────┐ │
│ │ 📷 Сфотографировать продукты │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 🧾 Сканировать чек │ │
│ └───────────────────────────────┘ │
│ │
│ Пропустить │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Навигация:** «Далее» и «Пропустить» на каждом шаге. Индикатор прогресса (точки или прогресс-бар).
- **Шаг 2:** все поля необязательны, но при пропуске рекомендуемая калорийность не рассчитывается (предлагается средняя 2000 ккал).
- **Шаг 3:** норма пересчитывается при смене цели (формула Миффлина-Сан Жеора + коэффициент активности + поправка на цель).
- **Шаг 4:** предпочтения кухонь влияют на будущие рекомендации, ограничения — на фильтрацию рецептов.
- **Шаг 5:** при выборе фото/чека — переход к экрану камеры, затем к экрану корректировки распознанных продуктов, затем — к переходному экрану «Составить меню?». При «Пропустить» — переход на главный экран.
- **Повторный запуск:** онбординг показывается один раз. Все данные можно изменить позже в Профиле.
---
## 1. Главный экран (Главная)
Точка входа в приложение. Сводка текущего дня, рекомендации и быстрый доступ к ключевым действиям.
```
┌─────────────────────────────────────┐
│ FoodAI [аватар] │
│ Привет, Алексей! │
├─────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ Калории сегодня │ │
│ │ │ │
│ │ ◯◯◯◯◯◯◯◯◯ │ │
│ │ (круговой прогресс-бар) │ │
│ │ │ │
│ │ 1 240 / 2 100 ккал │ │
│ │ │ │
│ │ Б: 68/120г Ж: 45/70г У: 150/260г
│ └───────────────────────────────┘ │
│ │
│ Быстрые действия │
│ ┌─────────┐ ┌─────────┐ ┌───────┐ │
│ │ [📷] │ │ [📷] │ │ [🔍] │ │
│ │ Скан. │ │ Распозн.│ │ Найти │ │
│ │ чека │ │ еду │ │рецепт │ │
│ └─────────┘ └─────────┘ └───────┘ │
│ │
│ Рекомендуем приготовить │
│ ┌──────────┐ ┌──────────┐ → │
│ │ [фото] │ │ [фото] │ │
│ │ Стир-фрай│ │ Омлет с │ │
│ │ с курицей│ │ овощами │ │
│ │ 350 ккал │ │ 240 ккал │ │
│ │ Курица │ │ Яйца │ │
│ │ истекает ⚠│ │ истекают⚠│ │
│ └──────────┘ └──────────┘ │
│ │
│ Сегодня в меню │
│ ┌───────────────────────────────┐ │
│ │ Завтрак 320 ккал │ │
│ │ Овсянка с ягодами [✓] │ │
│ ├───────────────────────────────┤ │
│ │ Обед 540 ккал │ │
│ │ Куриная грудка с рисом [✓] │ │
│ ├───────────────────────────────┤ │
│ │ Ужин — ккал │ │
│ │ Не запланирован │ │
│ │ [+ Подобрать блюдо] │ │
│ ├───────────────────────────────┤ │
│ │ Перекус 180 ккал │ │
│ │ Греческий йогурт [✓] │ │
│ └───────────────────────────────┘ │
│ │
│ Готовили недавно │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │[фото] │ │[фото] │ │[фото] │ │
│ │Карбон. │ │Цезарь │ │Борщ │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ Скоро испортятся │
│ ┌───────────────────────────────┐ │
│ │ ⚠ Молоко — осталось 2 дня │ │
│ │ ⚠ Куриное филе — завтра │ │
│ └───────────────────────────────┘ │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Пустое состояние главного экрана (новый пользователь)
```
┌─────────────────────────────────────┐
│ FoodAI [аватар] │
│ Привет! │
├─────────────────────────────────────┤
│ │
│ [Иллюстрация] │
│ │
│ Начните с добавления продуктов, │
│ чтобы мы подобрали рецепты │
│ и составили меню для вас │
│ │
│ ┌───────────────────────────────┐ │
│ │ 📷 Сфотографировать продукты │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 🧾 Сканировать чек │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 🔍 Посмотреть рецепты │ │
│ └───────────────────────────────┘ │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** название приложения слева, аватар пользователя справа (тап — переход в профиль). Приветствие с именем пользователя.
- **Карточка калорий:** круговой прогресс-бар, показывающий отношение потреблённых калорий к цели. Под ним — три мини-прогресс-бара для БЖУ. Тап по карточке — переход в дневник питания. Если калории превышены — прогресс-бар красный.
- **Быстрые действия:** три кнопки в ряд, оформленные как квадратные карточки с иконкой и подписью. «Сканировать чек» — открывает камеру в режиме сканирования чека. «Распознать еду» — открывает камеру в режиме распознавания блюда/продуктов. «Найти рецепт» — переход в каталог рецептов.
- **Рекомендуем приготовить:** горизонтальная карусель из 35 карточек рецептов. Алгоритм приоритизации: (1) рецепты из продуктов с истекающим сроком, (2) рецепты, полностью покрываемые запасами, (3) рецепты по предпочтениям кухни пользователя. На карточке — пометка, какой продукт нужно использовать. Тап — переход в карточку рецепта. Секция не показывается, если нет продуктов в запасах.
- **Сегодня в меню:** список запланированных приёмов пищи. Каждый пункт — название приёма, название блюда, калорийность. Чекбокс справа — отметка «съедено» (данные добавляются в дневник). Если приём пищи не запланирован — кнопка «+ Подобрать блюдо» (открывает каталог рецептов с предустановленным фильтром по типу приёма и остатку калорий на день). Тап по блюду — переход в карточку рецепта.
- **Готовили недавно:** горизонтальный ряд из 35 последних приготовленных рецептов для быстрого повтора. Тап — переход в карточку рецепта. Секция не показывается, если нет истории.
- **Скоро испортятся:** предупреждения о продуктах с истекающим сроком. Показываются только при наличии таких продуктов. Тап — переход на экран «Мои продукты» с фильтром по сроку.
- **Пустое состояние:** для нового пользователя без продуктов и меню — мотивирующий экран с основными действиями для старта.
---
## 2. Мои продукты
Учёт всех имеющихся продуктов. Добавление через фото, чек или вручную.
```
┌─────────────────────────────────────┐
│ Мои продукты [+ ▾] [···] │
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐ │
│ │ 🔍 Поиск продуктов... │ │
│ └─────────────────────────────────┘ │
│ │
│ [Все] [Истекает срок] [Молочные] [Мясо] [Овощи]..│
│ │
│ Молочные продукты │
│ ┌───────────────────────────────┐ │
│ │ 🥛 Молоко 2.5% │ │
│ │ 1 л · осталось 2 дня ⚠ │ │
│ ├───────────────────────────────┤ │
│ │ 🧀 Сыр Гауда │ │
│ │ 300 г · осталось 10 дней │ │
│ ├───────────────────────────────┤ │
│ │ 🫙 Йогурт греческий │ │
│ │ 2 шт · осталось 5 дней │ │
│ └───────────────────────────────┘ │
│ │
│ Мясо и птица │
│ ┌───────────────────────────────┐ │
│ │ 🍗 Куриное филе │ │
│ │ 500 г · осталось 1 день ⚠ │ │
│ ├───────────────────────────────┤ │
│ │ 🥩 Говядина │ │
│ │ 400 г · осталось 13 дней │ │
│ └───────────────────────────────┘ │
│ │
│ Овощи и фрукты │
│ ┌───────────────────────────────┐ │
│ │ 🥕 Морковь │ │
│ │ 5 шт · без срока │ │
│ ├───────────────────────────────┤ │
│ │ 🍅 Помидоры │ │
│ │ 4 шт · осталось 4 дня │ │
│ └───────────────────────────────┘ │
│ │
│ ... │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Выпадающее меню добавления [+ ▾]
```
┌───────────────────────┐
│ 📷 Сфотографировать │
│ продукты │
├───────────────────────┤
│ 🧾 Сканировать чек │
├───────────────────────┤
│ ✏️ Добавить вручную │
└───────────────────────┘
```
### Контекстное меню экрана [···]
```
┌─────────────────────────────┐
│ 🔄 Очистить и перезаполнить │
├─────────────────────────────┤
│ ⚙️ Сроки хранения по │
│ умолчанию │
├─────────────────────────────┤
│ 🗑 Удалить все просроченные │
└─────────────────────────────┘
```
### Экран редактирования продукта (тап по элементу)
```
┌─────────────────────────────────────┐
│ [✕] Редактирование продукта │
├─────────────────────────────────────┤
│ │
│ Название │
│ ┌───────────────────────────────┐ │
│ │ Молоко 2.5% │ │
│ └───────────────────────────────┘ │
│ │
│ Количество Единица │
│ ┌─────────────────┐ ┌─────────┐ │
│ │ 1 │ │ л ▾ │ │
│ └─────────────────┘ └─────────┘ │
│ │
│ Категория │
│ ┌───────────────────────────────┐ │
│ │ Молочные продукты ▾ │ │
│ └───────────────────────────────┘ │
│ │
│ Срок хранения (дней после покупки) │
│ ┌───────────────────────────────┐ │
│ │ 5 │ │
│ └───────────────────────────────┘ │
│ Добавлено: 13.02.2026 │
│ Годен до: 18.02.2026 (2 дня) │
│ │
│ ┌───────────────────────────────┐ │
│ │ Сохранить │ │
│ └───────────────────────────────┘ │
│ │
│ [Использовано частично] │
│ [Удалить продукт] │
│ │
└─────────────────────────────────────┘
```
### Модальное окно «Использовано частично»
```
┌───────────────────────────────────┐
│ Сколько осталось? │
├───────────────────────────────────┤
│ │
│ Было: 1 л │
│ │
│ Осталось: │
│ ┌─────────────────┐ ┌───────┐ │
│ │ 0.5 │ │ л ▾ │ │
│ └─────────────────┘ └───────┘ │
│ │
│ ┌───────────────────────────┐ │
│ │ Сохранить │ │
│ └───────────────────────────┘ │
└───────────────────────────────────┘
```
### Подтверждение «Очистить и перезаполнить»
```
┌───────────────────────────────────┐
│ Очистить все продукты? │
├───────────────────────────────────┤
│ │
Все текущие продукты будут │
│ удалены. После этого вы сможете │
│ добавить продукты заново. │
│ │
│ ┌───────────────────────────────┐ │
│ │ Очистить и сфотографировать │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ Очистить и сканировать чек │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ Просто очистить │ │
│ └───────────────────────────────┘ │
│ │
│ Отмена │
│ │
└───────────────────────────────────┘
```
### Пустое состояние
```
┌─────────────────────────────────────┐
│ Мои продукты [+ ▾] │
├─────────────────────────────────────┤
│ │
│ │
│ [Иллюстрация: │
│ пустой холодильник] │
│ │
У вас пока нет продуктов │
│ │
│ Сфотографируйте холодильник │
│ или сканируйте чек, чтобы │
│ добавить первые продукты │
│ │
│ ┌───────────────────────────────┐ │
│ │ 📷 Сфотографировать продукты │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 🧾 Сканировать чек │ │
│ └───────────────────────────────┘ │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** заголовок «Мои продукты», кнопка «+» с выпадающим меню добавления, кнопка «···» с контекстным меню экрана.
- **Строка поиска:** фильтрация списка продуктов по названию.
- **Горизонтальный ряд фильтров:** скроллируемые chip-кнопки — «Все», «Истекает срок», категории продуктов. Chip «Истекает срок» выделен предупреждающим цветом при наличии таких продуктов.
- **Список продуктов:** сгруппирован по категориям с заголовками-разделителями. Каждый элемент — иконка/эмодзи категории, название, количество с единицей измерения, оставшийся срок хранения («осталось X дней»). Значок ⚠ — срок истекает в ближайшие 3 дня. Для продуктов без срока (крупы, макароны) — «без срока».
- **Модель срока годности:** используется «период хранения после покупки» вместо фиксированной даты. При добавлении продукта автоматически подставляется срок по умолчанию для категории (молоко — 5 дней, курица — 3 дня, и т.д.). Пользователь может скорректировать период для конкретного продукта. Дата окончания вычисляется: дата добавления + период хранения. Значения по умолчанию настраиваются в профиле.
- **Свайп по элементу влево:** открывает кнопки «Изменить» и «Удалить».
- **Тап по элементу:** открывает экран редактирования продукта с полями: название, количество, единица измерения (г/кг/мл/л/шт/пучок/упаковка), категория, период хранения. Отображается дата добавления и вычисленная дата окончания. Кнопка «Использовано частично» — открывает модальное окно для указания оставшегося количества. Кнопка «Удалить продукт» — удаляет с подтверждением.
- **Очистить и перезаполнить:** удаляет все продукты и сразу предлагает способ добавления заново (фото, чек или ручной ввод). Требует подтверждения. После фото/чека — стандартный флоу распознавания с корректировкой.
- **Сроки хранения по умолчанию:** переход к экрану настроек сроков (списком по категориям: молочные — 5 дней, мясо — 3 дня, и т.д.). Можно изменить значения.
- **Удалить все просроченные:** удаляет все продукты с истёкшим сроком (с подтверждением).
- **Дубликаты:** при добавлении продукта, который уже есть в списке, система показывает диалог: «Молоко 2.5% уже есть (1 л, осталось 2 дня). Объединить количество или добавить отдельно?»
---
## 3. Экран камеры (Сканирование чека)
Открывается при выборе «Сканировать чек».
```
┌─────────────────────────────────────┐
│ [✕] Сканирование чека │
├─────────────────────────────────────┤
│ │
│ │
│ ┌───────────────────┐ │
│ │ │ │
│ │ │ │
│ │ Область камеры │ │
│ │ │ │
│ │ Наведите камеру │ │
│ │ на чек │ │
│ │ │ │
│ │ │ │
│ └───────────────────┘ │
│ │
│ │
│ ┌──────────┐ │
│ │ ◉ │ │
│ │ Снять │ │
│ └──────────┘ │
│ │
│ [🖼 Из галереи] │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** кнопка закрытия «✕» слева, заголовок по центру.
- **Видоискатель:** занимает основную часть экрана. Рамка-подсказка для позиционирования чека.
- **Кнопка съёмки:** крупная круглая кнопка внизу по центру.
- **Кнопка «Из галереи»:** выбор уже сделанного фото из галереи телефона.
- После съёмки — экран загрузки с анимацией AI-распознавания, затем переход к экрану результатов.
- **Ошибка распознавания:** если фото слишком размытое или чек не читаем — сообщение «Не удалось распознать чек. Попробуйте сфотографировать ещё раз или добавьте продукты вручную» с кнопками «Переснять» и «Ввести вручную».
---
## 4. Результат распознавания чека / фото продуктов
Общий экран для результатов распознавания чека и фото продуктов. Каждый продукт можно детально скорректировать.
```
┌─────────────────────────────────────┐
│ [←] Распознанные продукты │
├─────────────────────────────────────┤
│ │
│ Найдено 6 продуктов │
│ │
│ ┌───────────────────────────────┐ │
│ │ [✓] Молоко 2.5% │ │
│ │ 1 [л ▾] · Молочные │ │
│ │ Хранение: 5 дн. [✎] │ │
│ ├───────────────────────────────┤ │
│ │ [✓] Куриное филе │ │
│ │ 500 [г ▾] · Мясо │ │
│ │ Хранение: 3 дн. [✎] │ │
│ ├───────────────────────────────┤ │
│ │ [✓] Помидоры │ │
│ │ 4 [шт ▾] · Овощи │ │
│ │ Хранение: 7 дн. [✎] │ │
│ ├───────────────────────────────┤ │
│ │ [✓] Рис Басмати │ │
│ │ 800 [г ▾] · Крупы │ │
│ │ Хранение: без срока [✎] │ │
│ ├───────────────────────────────┤ │
│ │ [✓] Сыр Гауда │ │
│ │ 300 [г ▾] · Молочные │ │
│ │ Хранение: 14 дн. [✎] │ │
│ ├───────────────────────────────┤ │
│ │ [?] Неизвестный товар → 49₽ │ │
│ │ Нажмите, чтобы указать │ │
│ └───────────────────────────────┘ │
│ │
│ ⚠ Молоко 2.5% уже есть в запасах │
│ (1 л, осталось 2 дня) │
│ [Объединить] [Добавить отдельно] │
│ │
│ + Добавить продукт вручную │
│ + Сделать ещё фото │
│ │
│ ┌───────────────────────────────┐ │
│ │ Добавить в мои продукты │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
### Инлайн-редактирование продукта (тап по [✎] или по строке)
```
┌───────────────────────────────────┐
│ Редактировать │
├───────────────────────────────────┤
│ │
│ Название │
│ ┌───────────────────────────────┐ │
│ │ Молоко 2.5% │ │
│ └───────────────────────────────┘ │
│ │
│ Количество Единица │
│ ┌────────────────┐ ┌───────────┐ │
│ │ 1 │ │ л ▾ │ │
│ └────────────────┘ └───────────┘ │
│ │
│ Категория │
│ ┌───────────────────────────────┐ │
│ │ Молочные продукты ▾ │ │
│ └───────────────────────────────┘ │
│ │
│ Хранение (дней после покупки) │
│ ┌───────────────────────────────┐ │
│ │ 5 │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ Сохранить │ │
│ └───────────────────────────────┘ │
│ │
│ [Удалить из списка] │
│ │
└───────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** кнопка «Назад», заголовок.
- **Счётчик:** «Найдено N продуктов» — сколько позиций распознано.
- **Список продуктов:** каждый элемент содержит:
- Чекбокс — для включения/исключения из добавления (по умолчанию вкл).
- Название — редактируемое поле (тап → inline edit или bottom sheet).
- Количество и единица измерения — рядом, оба редактируемые. Единица — выпадающий список (г, кг, мл, л, шт, пучок, упаковка). Система подставляет наиболее вероятную единицу по категории.
- Категория — автоматически определённая, можно сменить.
- Период хранения — автоподставлен по категории, можно скорректировать. Для крупных категорий (крупы, макароны, специи) — «без срока».
- Кнопка «✎» — открывает bottom sheet с полной формой редактирования.
- **Нераспознанные товары:** отмечены значком «?». Тап — открывает форму ручного ввода. Если из чека — рядом отображается цена для подсказки.
- **Предупреждение о дубликатах:** если распознанный продукт уже есть в запасах — жёлтое предупреждение с вариантами: «Объединить» (прибавить количество к существующему), «Добавить отдельно» (новая позиция).
- **«+ Добавить продукт вручную»:** добавляет пустую строку для ручного ввода.
- **«+ Сделать ещё фото»:** открывает камеру для дополнительного снимка (несколько полок, второй чек). Результаты добавляются в текущий список.
- **CTA-кнопка «Добавить в мои продукты»:** добавляет все отмеченные продукты в запасы. После подтверждения — переход к переходному экрану «Составить меню?» (а не возврат на «Мои продукты»).
---
## 5. Переходный экран «Составить меню?»
Появляется после добавления продуктов (чек/фото). Плавный переход к составлению меню.
```
┌─────────────────────────────────────┐
│ │
│ ✅ 6 продуктов добавлено │
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ [Иллюстрация: повар │ │
│ │ с тарелками] │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ Составить меню из ваших продуктов? │
│ │
На какой период? │
│ [На день] [На неделю●] │
│ │
│ Какая кухня? │
│ [Любая●] [Русская] [Азиатская] │
│ [Европейская] [Средиземноморская] │
│ │
│ Сложность │
│ [Попроще●] [Средняя] [Посложнее] │
│ │
│ ┌───────────────────────────────┐ │
│ │ Составить меню │ │
│ └───────────────────────────────┘ │
│ │
│ Пропустить │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Подтверждение:** сообщение об успешном добавлении продуктов.
- **Период:** выбор chip-кнопкой. «На день» — меню на сегодня. «На неделю» — на ближайшие 7 дней.
- **Кухня:** chip-кнопки с множественным выбором. «Любая» — выбрано по умолчанию. Остальные варианты отсортированы по предпочтениям из профиля.
- **Сложность:** три уровня. Влияет на время приготовления и количество шагов в рецептах.
- **«Составить меню»:** генерирует меню с учётом параметров и переходит на экран Меню с результатом (см. п.8, автогенерация).
- **«Пропустить»:** переход на экран «Мои продукты» (стандартное поведение).
- Экран НЕ показывается при добавлении продукта вручную — только при массовом добавлении через фото/чек.
---
## 6. Экран камеры (Распознавание еды)
Открывается при выборе «Распознать еду» — для определения блюда и калорийности по фото.
```
┌─────────────────────────────────────┐
│ [✕] Распознать еду │
├─────────────────────────────────────┤
│ │
│ ┌───────────────────┐ │
│ │ │ │
│ │ │ │
│ │ Область камеры │ │
│ │ │ │
│ │ Сфотографируйте │ │
│ │ блюдо или │ │
│ │ продукты │ │
│ │ │ │
│ └───────────────────┘ │
│ │
│ Режим: │
│ [ Готовое блюдо ] [ Продукты ] │
│ │
│ ┌──────────┐ │
│ │ ◉ │ │
│ │ Снять │ │
│ └──────────┘ │
│ │
│ [🖼 Из галереи] │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- Аналогично экрану сканирования чека, но с переключателем режима.
- **Режим «Готовое блюдо»:** после съёмки приложение определяет блюдо и показывает его калорийность (переход к экрану результата распознавания блюда).
- **Режим «Продукты»:** после съёмки приложение определяет продукты на фото и предлагает добавить их в запасы (переход к экрану корректировки, аналогичному п.4). Поддерживает мультифото (кнопка «+ Сделать ещё фото» на экране результатов).
- **Ошибка распознавания:** «Не удалось определить блюдо/продукты. Попробуйте ещё раз или введите вручную» с кнопками «Переснять» и «Ввести вручную».
---
## 7. Результат распознавания блюда
Отображается после фотографирования готового блюда.
```
┌─────────────────────────────────────┐
│ [←] Результат │
├─────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ [Фото сделанное юзером] │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ Паста Карбонара │
│ ~450 г
│ │
│ ┌───────────────────────────────┐ │
│ │ 580 ккал │ │
│ │ │ │
│ │ Б: 24 г Ж: 28 г У: 56 г │ │
│ └───────────────────────────────┘ │
│ │
│ Это верно? │
│ ┌────────────┐ ┌──────────────┐ │
│ │ Да, верно │ │ Нет, это... │ │
│ └────────────┘ └──────────────┘ │
│ │
│ Размер порции │
│ ○──────────────●───────────○ │
│ 0.5x [1x] 1.5x 2x │
│ 290 ккал 580 870 1160 │
│ │
│ Приём пищи: │
│ [Завтр.] [Обед●] [Ужин] [Перекус] │
│ │
│ ┌───────────────────────────────┐ │
│ │ Записать в дневник питания │ │
│ └───────────────────────────────┘ │
│ │
│ Похожие рецепты: │
│ ┌─────────┐ ┌─────────┐ │
│ │ [фото] │ │ [фото] │ → │
│ │ Карбон. │ │ Карбон. │ │
│ │ классич.│ │ с бекон.│ │
│ │ 520ккал │ │ 610ккал │ │
│ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Фото:** сделанный пользователем снимок блюда.
- **Название и вес:** определённое приложением название блюда и приблизительный вес порции.
- **Карточка калорийности:** калории и БЖУ крупным шрифтом.
- **Подтверждение:** «Да, верно» — подтверждает распознавание. «Нет, это...» — открывает поиск по названию блюда для ручной корректировки. После выбора — калорийность пересчитывается.
- **Размер порции:** слайдер от 0.5x до 2x с шагом 0.25. Калорийность и БЖУ пересчитываются при перемещении. Показывается числовое значение калорий для выбранного множителя.
- **Приём пищи:** chip-кнопки. Предвыбран ближайший по времени приём (до 10:00 — завтрак, 10:0014:00 — обед, 14:0017:00 — перекус, после 17:00 — ужин).
- **CTA-кнопка «Записать в дневник питания»:** добавляет блюдо в дневник выбранного дня и приёма пищи.
- **Похожие рецепты:** горизонтальная карусель карточек рецептов. Тап — переход в карточку рецепта. Полезно, если пользователь захочет приготовить это блюдо сам.
---
## 8. Меню (Планирование)
Календарное представление запланированных приёмов пищи.
```
┌─────────────────────────────────────┐
│ Меню [⚡▾] [Список пок.]│
├─────────────────────────────────────┤
│ │
│ ◁ 15 21 февраля 2026 ▷ │
│ │
│ Пн Вт Ср Чт Пт Сб Вс
│ 16 17 18 19 20 21 22 │
│ ● ● ● ○ ○ ○ ○ │
│ │
│ ─── Понедельник, 16 февраля ─────── │
│ │
│ Итого: 1 840 / 2 100 ккал │
│ ████████████████████░░░░ 88% │
│ │
│ Завтрак 320 ккал │
│ ┌───────────────────────────────┐ │
│ │ [фото] Овсянка с ягодами │ │
│ │ и мёдом [···] │ │
│ └───────────────────────────────┘ │
│ │
│ Обед 640 ккал │
│ ┌───────────────────────────────┐ │
│ │ [фото] Куриная грудка │ │
│ │ с рисом и овощами │ │
│ │ [···] │ │
│ └───────────────────────────────┘ │
│ │
│ Ужин │
│ ┌───────────────────────────────┐ │
│ │ + Подобрать блюдо │ │
│ │ Осталось 880 ккал на день │ │
│ │ Рекомендуем: ужин из курицы │ │
│ │ и овощей (срок курицы ⚠) │ │
│ └───────────────────────────────┘ │
│ │
│ Перекус 300 ккал │
│ ┌───────────────────────────────┐ │
│ │ [фото] Греческий йогурт │ │
│ │ с гранолой [···] │ │
│ └───────────────────────────────┘ │
│ │
│ [+ Добавить приём пищи] │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Кнопка автогенерации [⚡▾]
```
┌───────────────────────────────┐
│ ⚡ Сгенерировать меню │
├───────────────────────────────┤
│ 📋 Из шаблона │
├───────────────────────────────┤
│ 🕐 Из истории меню │
├───────────────────────────────┤
│ 💾 Сохранить как шаблон │
└───────────────────────────────┘
```
### Экран автогенерации меню
```
┌─────────────────────────────────────┐
│ [←] Генерация меню │
├─────────────────────────────────────┤
│ │
│ Период │
│ [Сегодня] [Неделя●] [2 недели] │
│ │
│ Кухня (можно несколько) │
│ [Любая] [Русская✓] [Азиатская✓] │
│ [Европ.] [Средизем.] [Кавказская] │
│ │
│ Сложность │
│ [Попроще] [Средняя●] [Посложнее] │
│ │
│ Учитывать мои продукты │
│ [Вкл ●] [Выкл] │
│ │
│ Калорий в день │
│ ┌───────────────────────────────┐ │
│ │ 2 100 (рекомендуемая) │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ Сгенерировать │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
### Контекстное меню блюда [···]
```
┌───────────────────────┐
│ 📖 Открыть рецепт │
├───────────────────────┤
│ 🔄 Заменить блюдо │
├───────────────────────┤
│ 📅 Перенести на др. │
│ день │
├───────────────────────┤
│ 🗑 Убрать из меню │
└───────────────────────┘
```
### Пустое состояние
```
┌───────────────────────────────────┐
│ │
│ [Иллюстрация: календарь] │
│ │
│ Меню пока не составлено │
│ │
│ ┌─────────────────────────────┐ │
│ │ ⚡ Сгенерировать на неделю │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ + Добавить блюда вручную │ │
│ └─────────────────────────────┘ │
│ │
└───────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** заголовок «Меню», кнопка «⚡» — автогенерация и шаблоны, кнопка «Список покупок» — переход к автоматически сформированному списку.
- **Навигация по неделям:** стрелки влево/вправо для переключения между неделями.
- **Дни недели:** горизонтальный ряд с датами. Точка под датой — есть запланированные блюда. Тап по дню — прокрутка к содержимому этого дня.
- **Суммарная калорийность дня:** прогресс-бар с числами. Если превышена цель — красный.
- **Приёмы пищи:** разделены заголовками (Завтрак, Обед, Ужин, Перекус). Каждое блюдо — карточка с миниатюрой фото и названием. Кнопка «···» — контекстное меню.
- **Пустые слоты:** вместо пустой строки — подсказка с рекомендацией: «+ Подобрать блюдо · Осталось N ккал на день» и контекстная рекомендация (если есть продукты с истекающим сроком). Тап — переход в каталог рецептов с фильтрами: тип приёма пищи + остаток калорий + продукты с истекающим сроком.
- **Long press по блюду:** активирует drag-and-drop для перетаскивания между приёмами пищи и днями.
- **«+ Добавить приём пищи»:** добавляет дополнительный слот (второй перекус и т.д.).
- **«Заменить блюдо»:** открывает каталог рецептов с предустановленными фильтрами (тот же тип приёма пищи, похожая калорийность).
- **Автогенерация:** экран с параметрами. После генерации — отображается сгенерированное меню, каждое блюдо можно заменить или сгенерировать заново (кнопка «Перегенерировать»).
- **Шаблоны:** сохранение текущего меню как шаблона с названием. Загрузка шаблона — перезаписывает меню на выбранный период.
- **История:** список прошлых меню по неделям. Тап — подгружает меню на текущую неделю.
---
## 9. Каталог рецептов
Поиск и просмотр рецептов с фильтрацией и персональными рекомендациями.
```
┌─────────────────────────────────────┐
│ Рецепты │
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐ │
│ │ 🔍 Найти рецепт... │ │
│ └─────────────────────────────────┘ │
│ │
│ [Из моих продуктов] [Фильтры ▾] │
│ │
│ Для вас │
│ ┌──────────┐ ┌──────────┐ → │
│ │ [фото] │ │ [фото] │ │
│ │ Том Ям │ │ Пад Тай │ │
│ │ ★4.8 │ │ ★4.6 │ │
│ │ 320 ккал │ │ 450 ккал │ │
│ │ Есть всё✓│ │ -2 прод. │ │
│ └──────────┘ └──────────┘ │
│ │
│ Готовили недавно │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │[фото] │ │[фото] │ │[фото] │ │
│ │Карбон. │ │Борщ │ │Цезарь │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
Все рецепты │
│ ┌──────────┐ ┌──────────┐ │
│ │ [фото] │ │ [фото] │ │
│ │ │ │ │ │
│ │ Ризотто │ │ Борщ │ │
│ │ ★4.5 │ │ ★4.9 │ │
│ │ 480 ккал │ │ 350 ккал │ │
│ │ 50 мин │ │ 90 мин │ │
│ │ Сложная │ │ Средняя │ │
│ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ ... │ │ ... │ │
│ └──────────┘ └──────────┘ │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Панель фильтров (раскрывается по тапу «Фильтры ▾»)
```
┌─────────────────────────────────────┐
│ Фильтры [Сброс]│
├─────────────────────────────────────┤
│ │
│ Приём пищи │
│ [Завтрак] [Обед] [Ужин] [Перекус] │
│ │
│ Кухня │
│ [Русская] [Азиатская] [Европейская] │
│ [Средиземноморская] [Американская] │
│ │
│ Сложность │
│ [Простая] [Средняя] [Сложная] │
│ │
│ Время приготовления │
│ [до 15 мин] [до 30 мин] [до 60 мин]│
│ [более 60 мин] │
│ │
│ Калорийность (на порцию) │
│ ○────────────● до 500 ккал │
│ │
│ Диета │
│ [Вегетар.] [Безглютен.] [Низкокал.] │
│ [Кето] [Без лактозы] │
│ │
│ ┌───────────────────────────────┐ │
│ │ Показать 24 рецепта │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Строка поиска:** текстовый поиск по названию рецепта и ингредиентам.
- **Кнопка «Из моих продуктов»:** toggle-фильтр. При включении показывает только рецепты, которые можно приготовить из имеющихся продуктов (полностью или частично). Рецепты сортируются по доле имеющихся ингредиентов. На каждой карточке — пометка: «Есть всё ✓» или «-N прод.».
- **Кнопка «Фильтры»:** раскрывает панель фильтров (bottom sheet). Фильтры — chip-кнопки с множественным выбором. Слайдер для калорийности. Кнопка «Показать N рецептов» — применяет фильтры и закрывает панель. Кнопка «Сброс» — очищает все фильтры.
- **Секция «Для вас»:** горизонтальная карусель. Персональные рекомендации на основе: предпочтений кухонь, истории оценок, имеющихся продуктов (особенно с истекающим сроком). Алгоритм: продукты с истекающим сроком > полное совпадение ингредиентов > предпочтения кухни > высокий рейтинг.
- **Секция «Готовили недавно»:** горизонтальный ряд из последних 5 приготовленных рецептов. Быстрый доступ для повтора. Не показывается, если нет истории.
- **Секция «Все рецепты»:** сетка 2 колонки. Каждая карточка — фото, название, рейтинг (звёзды), калорийность, время, сложность. Тап — переход в карточку рецепта.
- **Бесконечный скролл:** подгрузка рецептов по мере прокрутки.
---
## 10. Карточка рецепта
Детальная информация о рецепте.
```
┌─────────────────────────────────────┐
│ [←] [♡] [⤴] │
├─────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ [Фото блюда] │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ Паста Карбонара │
│ ★★★★☆ 4.6 (128 отзывов) │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 30 мин │ │Средняя │ │ Европ. │ │
│ │ Время │ │Сложн. │ │ Кухня │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 580 ккал на порцию │ │
│ │ Б: 24г · Ж: 28г · У: 56г │ │
│ └───────────────────────────────┘ │
│ │
│ Порций: [-] 2 [+] │
│ │
│ Ингредиенты │
│ ┌───────────────────────────────┐ │
│ │ ✅ Спагетти 200 г │ │
│ │ ✅ Бекон/панчетта 150 г │ │
│ │ ✅ Яйца 3 шт │ │
│ │ ✅ Пармезан 80 г │ │
│ │ 🔄 Пекорино 40 г │ │
│ │ → Замена: Пармезан (есть) │ │
│ │ ✅ Чёрный перец по вкусу │ │
│ └───────────────────────────────┘ │
│ Всё есть (с учётом замены) │
│ │
│ Описание │
│ Классическое итальянское блюдо │
│ из Рима. Настоящая карбонара │
│ готовится без сливок — только │
│ яйца, сыр и бекон. │
│ │
│ ┌───────────────────────────────┐ │
│ │ 🍳 Начать готовить │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 📅 Добавить в меню │ │
│ └───────────────────────────────┘ │
│ │
│ Отзывы (128) [Написать] │
│ ┌───────────────────────────────┐ │
│ │ Мария ★★★★★ │ │
│ │ Отличный рецепт! Готовила │ │
│ │ уже 3 раза, всегда получается.│ │
│ │ 2 дня назад │ │
│ ├───────────────────────────────┤ │
│ │ Дмитрий ★★★★☆ │ │
│ │ Вкусно, но сложно с яичной │ │
│ │ смесью — первый раз свернул. │ │
│ │ 1 неделю назад │ │
│ └───────────────────────────────┘ │
│ [Показать все отзывы →] │
│ │
└─────────────────────────────────────┘
```
### Модальное окно «Добавить в меню»
```
┌───────────────────────────────────┐
│ Добавить в меню │
├───────────────────────────────────┤
│ │
│ День: │
│ [Пн 16] [Вт 17] [Ср 18] ... │
│ │
│ Приём пищи: │
│ ○ Завтрак │
│ ○ Обед │
│ ● Ужин │
│ ○ Перекус │
│ │
│ ┌───────────────────────────────┐ │
│ │ Добавить │ │
│ └───────────────────────────────┘ │
└───────────────────────────────────┘
```
### Модальное окно «Написать отзыв»
```
┌───────────────────────────────────┐
│ Ваш отзыв [Отправить] │
├───────────────────────────────────┤
│ │
│ Оценка: │
│ ★ ★ ★ ★ ☆ │
│ │
│ ┌───────────────────────────────┐ │
│ │ Напишите ваш отзыв... │ │
│ │ │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ [📷 Добавить фото] │
│ │
└───────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** кнопка «Назад», кнопка «В избранное» (♡ / ♥), кнопка «Поделиться» (⤴).
- **Фото блюда:** крупное фото в верхней части, может быть каруселью из нескольких фото.
- **Рейтинг:** звёзды, средняя оценка, количество отзывов. Тап — скролл к секции отзывов.
- **Метаинформация:** три chip-блока — время приготовления, сложность, тип кухни.
- **Калорийность:** карточка с калориями и БЖУ на одну порцию.
- **Регулятор порций:** «−» и «+» изменяют количество порций. Вес ингредиентов и калорийность пересчитываются пропорционально.
- **Ингредиенты с заменами:** список с отметками наличия: ✅ — есть в запасах, ❌ — нет в запасах, 🔄 — нет, но есть замена. Для ингредиентов с заменой — под основным продуктом строка «→ Замена: [продукт] (есть/нет)». Список возможных замен формируется системой (пекорино → пармезан, сливки → сметана и т.д.). Итог: «Всё есть», «Всё есть (с учётом замены)», «Не хватает: N продуктов» + кнопка «Добавить в список покупок».
- **Описание:** текстовое описание рецепта.
- **CTA-кнопка «Начать готовить»:** основная, акцентного цвета. Переход в режим пошаговой готовки.
- **Кнопка «Добавить в меню»:** открывает модальное окно выбора дня и приёма пищи.
- **Отзывы:** последние 23 отзыва. Каждый — имя, звёзды, текст, дата. Кнопка «Написать» — открывает модальное окно. «Показать все отзывы» — переход к полному списку.
---
## 11. Режим готовки
Пошаговый интерфейс для приготовления блюда с таймерами.
```
┌─────────────────────────────────────┐
│ [✕] Паста Карбонара Шаг 3 из 7 │
├─────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ [Фото / иллюстрация │ │
│ │ текущего шага] │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ Отварите спагетти │
│ │
│ Вскипятите большую кастрюлю воды, │
│ посолите. Опустите спагетти и │
│ варите согласно инструкции на │
│ упаковке (обычно 810 минут) │
│ до состояния аль денте. │
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ ⏱ 10:00 │ │
│ │ │ │
│ │ [ Запустить таймер ] │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ │
│ │
│ ┌──────────┐ ┌─────────────┐ │
│ │ ◁ Назад │ │ Далее ▷ │ │
│ └──────────┘ └─────────────┘ │
│ │
│ ● ● ● ○ ○ ○ ○ (индикатор шагов) │
│ │
│ ┌───────────────────────────────────┐│
│ │ Активные таймеры: ││
│ │ ⏱ Бульон: 34:12 [⏸] ││
│ │ ⏱ Спагетти: 08:45 [⏸] ││
│ └───────────────────────────────────┘│
└─────────────────────────────────────┘
```
### Состояние таймера (запущен)
```
┌───────────────────────────────┐
│ │
│ ⏱ 07:23 │
│ (обратный отсчёт) │
│ │
│ [ ⏸ Пауза ] [ ■ Стоп ] │
│ │
└───────────────────────────────┘
```
### Уведомление о завершении таймера
```
┌─────────────────────────────────────┐
│ │
│ ┌───────────────────────────────┐ │
│ │ ✅ Спагетти готовы! │ │
│ │ │ │
│ │ Таймер «10 мин» завершён. │ │
│ │ │ │
│ │ [ Понятно ] │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────┘
```
### Экран завершения готовки (последний шаг → «Готово!»)
```
┌─────────────────────────────────────┐
│ Приятного аппетита! │
├─────────────────────────────────────┤
│ │
│ [Иллюстрация] │
│ │
│ Паста Карбонара готова! │
│ 580 ккал · 2 порции │
│ │
│ ┌───────────────────────────────┐ │
│ │ 📝 Записать в дневник │ │
│ └───────────────────────────────┘ │
│ │
│ Сколько порций вы съели? │
│ [-] 1 [+] │
│ │
│ ┌───────────────────────────────┐ │
│ │ ★ Оценить рецепт │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 📷 Поделиться фото │ │
│ └───────────────────────────────┘ │
│ │
│ [Закрыть] │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** кнопка закрытия «✕» (с подтверждением «Прервать готовку?»), название рецепта, текущий шаг из общего числа.
- **Фото/иллюстрация:** визуальная подсказка для текущего шага. Занимает верхнюю треть экрана.
- **Заголовок шага:** крупный жирный текст — краткое действие.
- **Описание шага:** подробная инструкция. Крупный шрифт для удобства чтения на кухне.
- **Блок таймера:** отображается только на шагах, где требуется ожидание. Показывает предустановленное время. Кнопка «Запустить таймер» — запускает обратный отсчёт. После запуска — кнопки «Пауза» и «Стоп». Таймер продолжает работать при переходе к другим шагам.
- **Навигация между шагами:** кнопки «Назад» и «Далее». Свайп влево/вправо для переключения. Точечный индикатор прогресса.
- **Панель активных таймеров:** фиксирована внизу экрана. Показывает все запущенные таймеры с оставшимся временем. Каждый таймер можно поставить на паузу. При завершении — push-уведомление + звуковой сигнал + модальное окно поверх текущего шага.
- **Экран не гаснет:** активен режим keep-screen-on.
- **Экран завершения:** после последнего шага кнопка «Далее» заменяется на «Готово!». По нажатию — экран завершения с действиями:
- «Записать в дневник» — добавляет блюдо в дневник. Можно выбрать количество съеденных порций.
- «Оценить рецепт» — открывает модалку отзыва.
- «Поделиться фото» — открывает камеру для фото результата, затем — системное меню «Поделиться».
- Ингредиенты автоматически списываются из запасов (если продукты были в списке «Мои продукты»).
---
## 12. Дневник питания
Учёт съеденного за день с подсчётом калорий и БЖУ.
```
┌─────────────────────────────────────┐
│ Дневник питания │
├─────────────────────────────────────┤
│ │
│ ◁ 15 февраля 2026 ▷ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 1 420 / 2 100 │ │
│ │ ◯◯◯◯◯◯◯◯◯◯◯◯◯◯ │ │
│ │ (круговой прогресс) │ │
│ │ │ │
│ │ Б: 82/120г Ж: 51/70г У: 178/260г
│ │ ████████░░ ███████░░ █████████░ │
│ └───────────────────────────────┘ │
│ │
│ Завтрак 320 ккал │
│ ┌───────────────────────────────┐ │
│ │ Овсянка с ягодами │ │
│ │ 1 порц. · 320 ккал │ │
│ │ Б:12 Ж:8 У:52 [···] │ │
│ └───────────────────────────────┘ │
│ │
│ Обед 640 ккал │
│ ┌───────────────────────────────┐ │
│ │ Куриная грудка с рисом │ │
│ │ 1 порц. · 640 ккал │ │
│ │ Б:45 Ж:18 У:72 [···] │ │
│ └───────────────────────────────┘ │
│ │
│ Перекус 280 ккал │
│ ┌───────────────────────────────┐ │
│ │ Йогурт греческий │ │
│ │ 1 порц. · 180 ккал │ │
│ │ Б:15 Ж:10 У:12 [···] │ │
│ ├───────────────────────────────┤ │
│ │ Банан │ │
│ │ 100 ккал │ │
│ │ Б:1 Ж:0 У:26 [···] │ │
│ └───────────────────────────────┘ │
│ │
│ Ужин │
│ ┌───────────────────────────────┐ │
│ │ + Добавить приём пищи │ │
│ └───────────────────────────────┘ │
│ │
│ Вода: 💧💧💧💧💧○○○ 5/8 стаканов │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Модальное окно «Добавить приём пищи»
```
┌───────────────────────────────────┐
│ Добавить │
├───────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ 📷 Сфотографировать блюдо │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 📅 Из сегодняшнего меню │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 📖 Из каталога рецептов │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ ⭐ Из избранного │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ 🔍 Быстрый поиск продукта │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ ✏️ Ввести вручную │ │
│ └───────────────────────────────┘ │
│ │
└───────────────────────────────────┘
```
### Модальное окно «Указать порцию» (при добавлении из рецепта)
```
┌───────────────────────────────────┐
│ Сколько вы съели? │
├───────────────────────────────────┤
│ │
│ Паста Карбонара │
│ 1 порция = 580 ккал │
│ │
│ Количество порций: │
│ ○──────────●──────────○ │
│ 0.5 [1] 1.5 2 │
│ │
│ = 580 ккал │
│ Б: 24г · Ж: 28г · У: 56г
│ │
│ ┌───────────────────────────────┐ │
│ │ Добавить │ │
│ └───────────────────────────────┘ │
└───────────────────────────────────┘
```
### Элементы и поведение
- **Навигация по дням:** стрелки влево/вправо, тап по дате — открывает календарь.
- **Карточка итогов:** круговой прогресс калорий, три линейных прогресс-бара для БЖУ. Если калории превышены — красный прогресс-бар.
- **Приёмы пищи:** разделены по типу (Завтрак, Обед, Ужин, Перекус). Каждая запись — название блюда, количество порций, калории, БЖУ. Кнопка «···» — редактировать порцию, удалить запись (с отменой через toast). Пустой приём — кнопка «+ Добавить».
- **«+ Добавить приём пищи»:** открывает модальное окно с вариантами добавления:
- «Сфотографировать блюдо» — камера → распознавание → результат.
- «Из сегодняшнего меню» — список блюд из меню на сегодня.
- «Из каталога рецептов» — переход в каталог.
- «Из избранного» — список избранных рецептов.
- **«Быстрый поиск продукта»** — строка поиска по базе отдельных продуктов (банан, хлеб, кофе с молоком и т.д.) для быстрого добавления без рецепта.
- «Ввести вручную» — форма: название, калории, БЖУ (необязательно).
- **Указание порции:** при добавлении блюда из рецепта — модальное окно со слайдером от 0.5 до 3 порций. Калории и БЖУ пересчитываются.
- **Трекер воды:** ряд из 8 значков стаканов. Тап по пустому — отмечает выпитый стакан. Тап по заполненному — снимает отметку. Количество стаканов (норма) настраивается в профиле.
- Дневник доступен из главного экрана через тап по карточке калорий.
---
## 13. Статистика
Графики и аналитика питания за период.
```
┌─────────────────────────────────────┐
│ Статистика │
├─────────────────────────────────────┤
│ │
│ [Неделя] [Месяц] [3 месяца] │
│ │
│ Калории │
│ ┌───────────────────────────────┐ │
│ │ 2500 ┤ │ │
│ │ ┤ ╭─╮ │ │
│ │ 2100 ┤─ ─ ─ ┤ ├─╮─ ─ (цель) │ │
│ │ ┤ ╭─╮ │ │ │ ╭─╮ │ │
│ │ 1500 ┤╭─┤ ├─┤ │ ├─┤ ├─╮ │ │
│ │ ┤│ │ │ │ │ │ │ │ │ │ │
│ │ 0 ┤┴─┴─┴─┴─┴─┴─┴─┴─┘ │ │
│ │ Пн Вт Ср Чт Пт Сб Вс │ │
│ └───────────────────────────────┘ │
│ │
│ Среднее: 1 920 ккал/день │
│ Цель: 2 100 ккал/день │
│ │
│ БЖУ (среднее за период) │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ ██████████████████████ │ │
│ │ Б: 28% Ж: 32% У: 40% │ │
│ │ │ │
│ │ Рекомендация: │ │
│ │ Б: 30% Ж: 25% У: 45% │ │
│ └───────────────────────────────┘ │
│ │
│ Тренды │
│ ┌───────────────────────────────┐ │
│ │ ↓ Калории: -5% к прошл. нед. │ │
│ │ ↑ Белок: +12% к прошл. нед. │ │
│ │ → Жиры: без изменений │ │
│ └───────────────────────────────┘ │
│ │
│ Самые частые блюда │
│ ┌───────────────────────────────┐ │
│ │ 1. Овсянка с ягодами — 5 раз │ │
│ │ 2. Куриная грудка — 4 раза │ │
│ │ 3. Греческий йогурт — 4 раза │ │
│ └───────────────────────────────┘ │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Переключатель периода:** chip-кнопки — «Неделя», «Месяц», «3 месяца».
- **График калорий:** столбчатая диаграмма. Пунктирная линия — цель. Столбцы выше цели выделены предупреждающим цветом. Тап по столбцу — показывает точное значение за день.
- **Средние значения:** числовые показатели — среднее потребление и цель.
- **Диаграмма БЖУ:** горизонтальный stacked bar. Показывает фактическое соотношение. Под ним — рекомендуемое соотношение для сравнения.
- **Тренды:** карточка с краткой аналитикой — изменения к предыдущему периоду. Стрелки вверх/вниз/вправо с цветовой кодировкой (зелёный — улучшение, красный — ухудшение, серый — без изменений).
- **Самые частые блюда:** рейтинг блюд за период. Тап — переход в карточку рецепта.
- Экран доступен из главного экрана через тап по прогресс-бару или из профиля.
- **Пустое состояние:** «Пока недостаточно данных для статистики. Записывайте приёмы пищи, и мы покажем аналитику» (показывается, если записей менее 3 дней).
---
## 14. Список покупок
Автоматически формируемый и вручную редактируемый список покупок.
```
┌─────────────────────────────────────┐
│ [←] Список покупок [···] │
├─────────────────────────────────────┤
│ │
На основе меню: 1622 февраля │
│ │
│ Молочные продукты │
│ ┌───────────────────────────────┐ │
│ │ [ ] Пекорино 40 г │ │
│ │ [ ] Сливки 20% 200 мл │ │
│ │ [✓] Молоко 2.5% 1 л │ │
│ └───────────────────────────────┘ │
│ │
│ Мясо и рыба │
│ ┌───────────────────────────────┐ │
│ │ [ ] Лосось 400 г │ │
│ │ [ ] Бекон/панчетта 300 г │ │
│ └───────────────────────────────┘ │
│ │
│ Овощи и фрукты │
│ ┌───────────────────────────────┐ │
│ │ [ ] Авокадо 2 шт │ │
│ │ [ ] Лайм 3 шт │ │
│ │ [ ] Кинза 1 пуч. │ │
│ │ [✓] Лук репчатый 3 шт │ │
│ └───────────────────────────────┘ │
│ │
│ Добавлено вручную │
│ ┌───────────────────────────────┐ │
│ │ [ ] Хлеб │ │
│ │ [ ] Вода 5л │ │
│ └───────────────────────────────┘ │
│ │
│ [+ Добавить продукт] │
│ │
│ Итого: 12 позиций (4 куплено) │
│ │
└─────────────────────────────────────┘
```
### Контекстное меню [···]
```
┌───────────────────────────────────┐
│ 🗑 Очистить купленные │
├───────────────────────────────────┤
│ 📤 Поделиться списком │
├───────────────────────────────────┤
│ 🔄 Пересчитать из меню │
└───────────────────────────────────┘
```
### Элементы и поведение
- **Шапка:** кнопка «Назад», заголовок, кнопка «···» с контекстным меню.
- **Подзаголовок:** указание, на основе какого периода меню сформирован список.
- **Группировка:** продукты сгруппированы по категориям. Отдельная секция «Добавлено вручную» — для позиций, добавленных пользователем.
- **Чекбоксы:** тап — отмечает продукт как купленный. Купленные элементы перечёркиваются и сдвигаются вниз группы.
- **Свайп влево:** удалить позицию.
- **Тап по элементу:** редактирование (название, количество).
- **«+ Добавить продукт»:** ручное добавление позиции.
- **Итоговая строка:** общее количество позиций и сколько уже куплено.
- **«Очистить купленные»:** удаляет все отмеченные позиции.
- **«Поделиться списком»:** формирует текстовый список и открывает системное меню «Поделиться» (мессенджеры, заметки и т.д.).
- **«Пересчитать из меню»:** заново формирует список на основе текущего меню и запасов (с подтверждением, если есть ручные позиции).
---
## 15. Профиль
Персональные настройки, цели и параметры пользователя.
```
┌─────────────────────────────────────┐
│ Профиль │
├─────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ [Аватар] │ │
│ └──────────┘ │
│ Алексей Иванов │
│ │
│ Мои параметры │
│ ┌───────────────────────────────┐ │
│ │ Рост 178 см │ │
│ │ Вес 75 кг │ │
│ │ Возраст 28 лет │ │
│ │ Пол Мужской │ │
│ │ Активность Средняя │ │
│ └───────────────────────────────┘ │
│ │
│ Цель │
│ ┌───────────────────────────────┐ │
│ │ ● Поддержание веса │ │
│ │ ○ Похудение │ │
│ │ ○ Набор массы │ │
│ └───────────────────────────────┘ │
│ │
│ Рекомендуемая норма: 2 100 ккал │
│ Б: 120г · Ж: 70г · У: 260г
│ │
│ Ограничения и предпочтения │
│ ┌───────────────────────────────┐ │
│ │ [ ] Вегетарианство │ │
│ │ [ ] Без глютена │ │
│ │ [ ] Без лактозы │ │
│ │ [✓] Без орехов (аллергия) │ │
│ │ [ ] Халяль │ │
│ │ [ ] Кошерное │ │
│ └───────────────────────────────┘ │
│ │
│ Любимые кухни │
│ ┌───────────────────────────────┐ │
│ │ [Русская✓] [Азиатская✓] │ │
│ │ [Европ.] [Средизем.] [Кавк.] │ │
│ └───────────────────────────────┘ │
│ │
│ ┌───────────────────────────────┐ │
│ │ 📊 Статистика │ │
│ ├───────────────────────────────┤ │
│ │ 📖 Избранные рецепты │ │
│ ├───────────────────────────────┤ │
│ │ 📝 Мои отзывы │ │
│ ├───────────────────────────────┤ │
│ │ ⏱ Сроки хранения продуктов │ │
│ ├───────────────────────────────┤ │
│ │ ⚙️ Настройки приложения │ │
│ ├───────────────────────────────┤ │
│ │ ❓ Помощь │ │
│ └───────────────────────────────┘ │
│ │
│ Версия 1.0.0 │
│ │
├─────────────────────────────────────┤
│ [Главная] [Продукты] [Меню] [Рецепты] [Профиль] │
└─────────────────────────────────────┘
```
### Экран «Сроки хранения продуктов»
```
┌─────────────────────────────────────┐
│ [←] Сроки хранения по умолчанию │
├─────────────────────────────────────┤
│ │
│ Укажите, сколько дней после │
│ покупки хранятся продукты │
│ каждой категории │
│ │
│ ┌───────────────────────────────┐ │
│ │ Молочные продукты [5] дн. │ │
│ │ Мясо и птица [3] дн. │ │
│ │ Рыба и морепродукты [2] дн. │ │
│ │ Овощи и фрукты [7] дн. │ │
│ │ Хлеб и выпечка [3] дн. │ │
│ │ Яйца [14] дн. │ │
│ │ Крупы и макароны [без срока] │
│ │ Консервы [без срока] │
│ │ Специи [без срока] │
│ │ Замороженные [30] дн. │ │
│ └───────────────────────────────┘ │
│ │
│ Значения будут подставляться │
│ при добавлении новых продуктов. │
│ Для каждого продукта срок можно │
│ скорректировать индивидуально. │
│ │
└─────────────────────────────────────┘
```
### Элементы и поведение
- **Аватар и имя:** фото пользователя (тап — смена фото), имя под ним.
- **Мои параметры:** карточка с физическими данными. Тап по любому полю — редактирование. Используются для расчёта нормы калорий.
- **Цель:** radio-кнопки. Смена цели пересчитывает рекомендуемую калорийность.
- **Рекомендуемая норма:** автоматически рассчитанные калории и БЖУ на основе параметров и цели. Формула Миффлина-Сан Жеора.
- **Ограничения и предпочтения:** чекбоксы. Влияют на фильтрацию рецептов — рецепты с запрещёнными ингредиентами помечаются предупреждением или скрываются.
- **Любимые кухни:** chip-кнопки. Влияют на порядок и приоритет рекомендаций.
- **Сроки хранения продуктов:** экран с настройками периодов хранения по категориям. Каждая категория — редактируемое числовое поле. Значения используются как умолчания при добавлении новых продуктов.
- **Список ссылок:** переходы на экраны статистики, избранных рецептов, отзывов, настроек, помощи.
- **Настройки приложения (отдельный экран):** уведомления (типы и время), тема (светлая/тёмная/системная), единицы измерения, норма воды (стаканов в день), язык, экспорт данных, удаление аккаунта.
---
## Общие паттерны UI
### Навигация
- **Bottom Tab Bar** — 5 вкладок, всегда видна (кроме режима готовки, камеры и онбординга).
- **Stack navigation** внутри каждой вкладки — с кнопкой «Назад» в шапке.
- **Модальные окна (bottom sheets)** — для фильтров, выбора, подтверждений.
### Жесты
- **Свайп влево** по элементам списков — действия (редактировать, удалить).
- **Long press** — drag-and-drop в меню.
- **Pull to refresh** — обновление данных на списках.
### Обратная связь
- **Toast/snackbar** — при успешных действиях (продукт добавлен, блюдо записано в дневник). Для необратимых действий (удалить запись из дневника) — toast с кнопкой «Отменить» (5 секунд).
- **Скелетоны (shimmer)** — при загрузке контента.
- **Анимация AI-распознавания** — при обработке фото. Текст: «Распознаём...» с анимированным индикатором. Среднее время — 35 сек.
### Пустые состояния
Каждый экран со списком данных имеет пустое состояние:
- **Иллюстрация** — лёгкий рисунок по теме экрана.
- **Текст** — что здесь будет отображаться и как начать.
- **CTA-кнопка** — основное действие для начала работы.
### Состояния ошибок
- **Нет сети:** баннер вверху экрана «Нет подключения к интернету». Кэшированные данные (продукты, меню, дневник) доступны оффлайн. Действия, требующие сети (распознавание фото, загрузка рецептов), показывают модалку с предложением повторить позже.
- **Ошибка распознавания:** «Не удалось распознать. Попробуйте ещё раз» + «Ввести вручную» как fallback.
- **Ошибка сервера:** «Что-то пошло не так» + «Повторить».
### Цветовая система
- **Акцентный цвет** — для CTA-кнопок и активных элементов.
- **Зелёный** — в пределах нормы, продукт в наличии, ингредиент есть.
- **Жёлтый/оранжевый** — предупреждение (скоро истечёт срок, калории приближаются к лимиту, есть замена ингредиента).
- **Красный** — превышение нормы, истёкший срок, отсутствующий ингредиент без замены.
### Типографика
- **Заголовки** — жирные, крупные.
- **Тело текста** — стандартный размер, с достаточным межстрочным интервалом.
- **В режиме готовки** — увеличенный шрифт для комфортного чтения на расстоянии.
### Уведомления
- **Срок годности:** «Молоко 2.5% — осталось 1 день. Используйте в рецепте?» (с ссылкой на рекомендации). Утром за 1 день и за 3 дня до истечения.
- **Таймер готовки:** звуковой сигнал + push «Таймер завершён: [название шага]».
- **Напоминание о приёме пищи:** «Время обеда! В меню: Куриная грудка с рисом» (если настроено).
- **Трекер воды:** вечернее напоминание «Вы выпили 5 из 8 стаканов воды сегодня» (если настроено).