# Действия в виджетах: добавить в корзину и другое

Если вы используете рекомендательные виджеты с действиями (например, добавление в корзину или в избранное), необходимо реализовать соответствующие методы в `window`. Это часть стандартной фронтенд-интеграции: платформа Gravity Field вызывает эти методы внутри шаблона кампании, а поведение реализуется на стороне сайта.

Gravity Field не реализует эти методы — они должны быть определены клиентской стороной заранее.

## Как это работает
Gravity Field вставляет HTML-шаблон виджета в слот на странице. Если в этом шаблоне есть кнопки действий (например, "Добавить в корзину"), вы можете навесить на них обработчики и вызывать нужные методы через `window`.

Ниже — пример подключения логики к кнопкам добавления в корзину. Скрипт ищет все кнопки с классом `.gf-recs__add-to-cart`, получает SKU из `data-атрибута` и вызывает `window.addToCart(sku)`

```js
function initWidgetActions(container) {
  container.querySelectorAll('.gf-recs__add-to-cart').forEach((button) => {
    button.addEventListener('click', async (e) => {
      e.preventDefault();
      const sku = button.dataset.sku;
      if (!sku || typeof window.addToCart !== 'function') return;

      button.disabled = true;
      try {
        await window.addToCart(sku);
        button.classList.add('_added');
        button.textContent = 'В корзине';
      } finally {
        button.disabled = false;
      }
    });
  });
}
```

> Такой код обычно размещается в JS-блоке шаблона вариации

## Ожидаемые методы

Gravity Field ожидает, что следующие методы будут определены в `window`:

| Назначение                     | Метод в `window`             | Аргументы             | Возвращаемое значение  |
|-------------------------------|------------------------------|-----------------------|------------------------|
| Добавление товара в корзину   | `addToCart(sku: string)`     | SKU товара            | `Promise` или `void`   |
| Удаление товара из корзины    | `removeFromCart(sku: string)`| SKU товара            | `Promise` или `void`   |
| Получение состава корзины     | `getCart()`                  | —                     | `Array<{ sku, qty }>`  |
| Добавление в избранное        | `addToWishlist(sku: string)` | SKU товара            | `Promise` или `void`   |
| Удаление из избранного        | `removeFromWishlist(sku: string)` | SKU товара      | `Promise` или `void`   |
| Получение состава избранного  | `getWishlist()`              | —                     | `Array<string>`        |

> Методы могут быть асинхронными, главное — чтобы они были определены до запуска кампаний Gravity Field.

## Пример реализации

```js
window.addToCart = function (sku) {
  return fetch('/api/cart/add', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ sku })
  }).then(() => {
    console.log('Добавлен в корзину:', sku);
  });
};

window.getCart = async function () {
  const res = await fetch('/api/cart');
  const data = await res.json();
  return data.items.map(item => ({ sku: item.sku, qty: item.quantity }));
};
```

## Рекомендации для frontend-интеграции

### Когда методы должны быть доступны

Кампании Gravity Field запускаются автоматически после загрузки скрипта платформы. Все методы должны быть определены в `window` заранее — до загрузки платформы или гарантированно доступны к моменту показа виджетов.

### Возвращаемые данные

- `getCart()` → `[{ sku: 'sku_1', qty: 2 }, { sku: 'sku_2', qty: 1 }]`
- `getWishlist()` → `['sku_1', 'sku_3']`

> Это используется, например, для отображения текущего состояния товаров (уже в корзине или нет).

### Как протестировать

- Вызовите `window.addToCart('sku_test')` в консоли;
- Добавьте лог внутри метода для отладки;
- Проверьте работу кнопок в режиме предпросмотра кампании.

### Если элементы появляются динамически

Если кнопки или карточки товаров рендерятся после загрузки страницы:

```js
GF.waitForElement('.gf-recs__add-to-cart', (buttons) => {
  initWidgetActions(document);
});
```

Или используйте `MutationObserver` для отслеживания DOM-изменений.

## FAQ

### Нужно ли отправлять события в Gravity Field?

Нет. Эти методы — часть клиентской логики. Трекинг действий через SSAPI обсуждается отдельно и настраивается при необходимости.

### Что если метод не определён?

Ничего не произойдёт. Рекомендуется логировать ошибки в шаблоне кампании (`console.warn(...)`).

### Можно ли использовать другие имена методов?

Да, если вы контролируете шаблон. Главное — синхронизировать имена с логикой, используемой в шаблоне.
