# Cart Added Snackbar — Design Spec

**Date:** 2026-05-25

## Goal

При добавлении товара в корзину показывать глобальное уведомление (Snackbar) с кнопкой «Перейти в корзину».

## Scope

- `AddToCartButton` (каталог, карточки товаров)
- `ToggleCartIcon` (страница товара, toggle add/remove)
- Глобальный Snackbar, рендерится один раз

## Architecture

### 1. Effector store — `shared/model/cart-notifications.ts`

Минимальный стор: только булев флаг открытия.

```ts
import { createEvent, createStore } from 'effector'

export const cartAdded = createEvent()
export const cartDismissed = createEvent()

export const $cartSnackOpen = createStore(false)
  .on(cartAdded, () => true)
  .on(cartDismissed, () => false)
```

### 2. UI Component — `shared/ui/CartSnackbar.tsx`

Компонент подписывается на `$cartSnackOpen` через `useUnit`.

- **Текст:** «Товар добавлен в корзину»
- **Кнопка действия:** «Перейти в корзину» → `navigate('/cart')` + `cartDismissed()`
- **Закрытие (крестик):** `cartDismissed()`
- **Авто-закрытие:** 4 секунды через `setTimeout`
- **Позиция:** `anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}`
- **Стиль:** MUI `<Snackbar>` + `<Alert severity="success">`

Если пользователь быстро добавит несколько товаров — каждый `cartAdded()` перезапускает таймер. Очередь не нужна.

### 3. Интеграция в `AddToCartButton`

В `onSuccess` мутации добавляется `cartAdded()`:

```ts
const addMut = useMutation({
  mutationFn: () => addToCart({ productId, qty }),
  onSuccess: () => {
    void qc.invalidateQueries({ queryKey: ['me', 'cart'] })
    cartAdded()
  },
})
```

`productTitle` не передаётся — текст уведомления универсальный.

### 4. Интеграция в `ToggleCartIcon`

Только add-мутация:

```ts
const addMut = useMutation({
  mutationFn: () => addToCart({ productId, qty: 1 }),
  onSuccess: () => {
    void qc.invalidateQueries({ queryKey: ['me', 'cart'] })
    cartAdded()
  },
})
```

Remove-мутация без уведомления.

### 5. Mount point — `app/AppProviders.tsx`

`<CartSnackbar />` рендерится один раз в `AppProviders.tsx` (или `App.tsx`), чтобы быть доступным во всём приложении.

## Dependencies

- effector / effector-react (уже используется)
- @mui/material — Snackbar, Alert (уже используется)
- react-router-dom — useNavigate (уже используется)

## Testing

- Unit-тест `CartSnackbar`: открывается по `cartAdded()`, закрывается по `cartDismissed()`
- Unit-тест `AddToCartButton`: вызывает `cartAdded()` в `onSuccess`
- Unit-тест `ToggleCartIcon`: вызывает `cartAdded()` только для add-мутации
