trial choice
This commit is contained in:
parent
91211ddfbf
commit
c7d6f049b0
@ -1,160 +0,0 @@
|
||||
# Trial Choice & Payment Integration
|
||||
|
||||
## Проблемы которые решены
|
||||
|
||||
### 1. Связь выбора Trial Choice → Payment
|
||||
**Проблема**: Пользователь выбирает вариант триала на экране TrialChoice, но на экране Payment всегда отображался первый вариант.
|
||||
|
||||
**Решение**:
|
||||
- Создан `TrialVariantSelectionContext` для хранения выбранного `variantId`
|
||||
- `TrialChoiceTemplate` сохраняет выбор пользователя в контекст
|
||||
- `TrialPaymentTemplate` читает выбранный вариант из контекста и использует его вместо первого
|
||||
|
||||
### 2. Общая логика загрузки и кеширование
|
||||
**Проблема**:
|
||||
- Каждый экран (TrialChoice, Payment) делал отдельный запрос к API
|
||||
- TrialChoice показывал неправильные данные до завершения загрузки
|
||||
- Payment уже имел loader, но TrialChoice — нет
|
||||
|
||||
**Решение**:
|
||||
- Создан `PaymentPlacementProvider` для кеширования загруженных placement данных
|
||||
- `usePaymentPlacement` hook теперь использует кеш из контекста
|
||||
- Повторные запросы к API не выполняются если данные уже загружены
|
||||
- `TrialChoiceTemplate` показывает loader (как Payment) до загрузки данных
|
||||
|
||||
## Архитектура
|
||||
|
||||
### Контексты
|
||||
|
||||
#### PaymentPlacementProvider
|
||||
- **Путь**: `src/entities/session/payment/PaymentPlacementProvider.tsx`
|
||||
- **Назначение**: Кеширует результаты `loadFunnelPaymentById` чтобы избежать повторных запросов
|
||||
- **Ключ кеша**: `${funnelKey}:${paymentId}`
|
||||
- **Состояние**: `{ placement, isLoading, error }`
|
||||
|
||||
#### TrialVariantSelectionProvider
|
||||
- **Путь**: `src/entities/session/payment/TrialVariantSelectionContext.tsx`
|
||||
- **Назначение**: Хранит выбранный пользователем `variantId` для передачи между экранами
|
||||
- **Состояние**: `{ selectedVariantId, setSelectedVariantId }`
|
||||
|
||||
### Обновленные компоненты
|
||||
|
||||
#### TrialChoiceTemplate
|
||||
- **Изменения**:
|
||||
- Добавлен loader (Spinner) до загрузки placement
|
||||
- Сохраняет выбор в `TrialVariantSelectionContext`
|
||||
- Использует `usePaymentPlacement` с кешированием
|
||||
- Инициализирует локальный `selectedId` из `selectedVariantId` контекста
|
||||
|
||||
#### TrialPaymentTemplate
|
||||
- **Изменения**:
|
||||
- Читает `selectedVariantId` из `TrialVariantSelectionContext`
|
||||
- Использует выбранный вариант, если доступен: `placement?.variants?.find((v) => v.id === selectedVariantId)`
|
||||
- Fallback на первый вариант если выбор отсутствует
|
||||
- Использует `usePaymentPlacement` с кешированием
|
||||
|
||||
#### SpecialOfferTemplate
|
||||
- **Изменения**: Нет (специально)
|
||||
- **Поведение**: Продолжает использовать первый вариант `placement?.variants?.[0]`
|
||||
- **Причина**: Использует другой `paymentId` (`"main_secret_discount"`) и не должен зависеть от выбора Trial
|
||||
|
||||
### usePaymentPlacement Hook
|
||||
- **Изменения**:
|
||||
- Теперь использует `PaymentPlacementContext` для получения/загрузки данных
|
||||
- Упрощена логика: нет локального state, все в контексте
|
||||
- Автоматически триггерит загрузку если данных нет
|
||||
|
||||
### Layout Integration
|
||||
- **Файл**: `src/app/[funnelId]/layout.tsx`
|
||||
- **Изменения**: Обернут в два новых провайдера:
|
||||
```tsx
|
||||
<PaymentPlacementProvider>
|
||||
<TrialVariantSelectionProvider>
|
||||
{children}
|
||||
</TrialVariantSelectionProvider>
|
||||
</PaymentPlacementProvider>
|
||||
```
|
||||
|
||||
## Потоки данных
|
||||
|
||||
### Поток 1: Воронка С экраном Trial Choice
|
||||
```
|
||||
1. User открывает Trial Choice
|
||||
→ PaymentPlacementProvider загружает "main" placement (если еще нет в кеше)
|
||||
→ TrialChoiceTemplate показывает loader
|
||||
→ После загрузки отображаются варианты
|
||||
|
||||
2. User выбирает вариант (например, id="plan-123")
|
||||
→ setSelectedVariantId("plan-123") в TrialVariantSelectionContext
|
||||
|
||||
3. User переходит на Payment
|
||||
→ PaymentPlacementProvider возвращает "main" placement из кеша (без запроса)
|
||||
→ TrialPaymentTemplate читает selectedVariantId="plan-123"
|
||||
→ Использует вариант с id="plan-123" вместо первого
|
||||
```
|
||||
|
||||
### Поток 2: Воронка БЕЗ экрана Trial Choice
|
||||
```
|
||||
1. User сразу открывает Payment
|
||||
→ PaymentPlacementProvider загружает "main" placement
|
||||
→ TrialPaymentTemplate показывает loader
|
||||
→ selectedVariantId === null
|
||||
→ Использует первый вариант (дефолт)
|
||||
```
|
||||
|
||||
### Поток 3: Special Offer
|
||||
```
|
||||
1. User открывает Special Offer
|
||||
→ PaymentPlacementProvider загружает "main_secret_discount" placement
|
||||
→ SpecialOfferTemplate показывает loader
|
||||
→ Всегда использует первый вариант (не зависит от Trial Choice)
|
||||
```
|
||||
|
||||
## Тестирование
|
||||
|
||||
### Сценарий 1: Trial Choice → Payment
|
||||
1. Открыть воронку с Trial Choice
|
||||
2. Дождаться загрузки вариантов
|
||||
3. Выбрать второй вариант (не первый)
|
||||
4. Нажать Continue
|
||||
5. **Ожидается**: На Payment отображается выбранный (второй) вариант
|
||||
|
||||
### Сценарий 2: Прямой переход на Payment
|
||||
1. Открыть воронку без Trial Choice или перейти прямо на Payment
|
||||
2. **Ожидается**: На Payment отображается первый вариант (дефолт)
|
||||
|
||||
### Сценарий 3: Кеширование
|
||||
1. Открыть Trial Choice → загрузка placement
|
||||
2. Перейти на Payment
|
||||
3. **Ожидается**: Payment загружается мгновенно (из кеша), без повторного API запроса
|
||||
|
||||
### Сценарий 4: Special Offer
|
||||
1. Открыть Special Offer
|
||||
2. **Ожидается**: Всегда показывается первый вариант, независимо от выбора в Trial Choice
|
||||
|
||||
## API изменения (Backend)
|
||||
|
||||
### session.controller.ts
|
||||
- **Изменения**: Добавлены `title` и `accent` поля в варианты
|
||||
- **Поведение**: Возвращает все планы (не ограничивает до 4)
|
||||
- **Дефолты**: `title` использует `["Basic", "Standard", "Popular", "Premium"]` с fallback `"Premium"`
|
||||
|
||||
## Файлы созданы/изменены
|
||||
|
||||
### Новые файлы
|
||||
- `src/entities/session/payment/PaymentPlacementProvider.tsx`
|
||||
- `src/entities/session/payment/TrialVariantSelectionContext.tsx`
|
||||
- `src/entities/session/payment/index.ts`
|
||||
|
||||
### Измененные файлы
|
||||
- `src/hooks/payment/usePaymentPlacement.ts` - использует контекст вместо локального state
|
||||
- `src/components/funnel/templates/TrialChoiceTemplate/TrialChoiceTemplate.tsx` - loader + сохранение выбора
|
||||
- `src/components/funnel/templates/TrialPaymentTemplate/TrialPaymentTemplate.tsx` - использует выбранный вариант
|
||||
- `src/app/[funnelId]/layout.tsx` - обернут в провайдеры
|
||||
|
||||
## Будущие улучшения
|
||||
|
||||
1. **Персистентность**: Сохранять выбор в localStorage/sessionStorage для сохранения при перезагрузке
|
||||
2. **Аналитика**: Трекинг выбора вариантов для A/B тестирования
|
||||
3. **Валидация**: Проверять что выбранный variant все еще существует в placement
|
||||
4. **Типизация**: Усилить типы для garantie что только валидные paymentId используются
|
||||
Loading…
Reference in New Issue
Block a user