# Integrar a avaliação +1 / −1 da TBBC

Você é um agente de código. Sua tarefa é adicionar a avaliação +1 / −1 da TBBC a este projeto. É um script pronto, servido por https://tbbc.app. Não recrie o componente, não copie o script para o projeto e não crie backend: o script já envia os votos para a TBBC.

Este guia é para **sites e apps web**, incluindo apps híbridos cuja tela é uma página web (Capacitor, Ionic, Cordova, WebView com HTML). Se o projeto é um app iOS, Android, React Native, Flutter, desktop, bot ou servidor, pare e siga o guia da API: https://tbbc.app/rating-widget/instrucoes-ia-api.md

## O que o widget faz

- Mostra "Esta tela foi útil?" com os botões +1 e −1.
- Depois do voto, abre um pequeno formulário opcional: comentário, nome e WhatsApp (ou e-mail).
- Cada voto é gravado com o domínio do site, a seção (`data-section`) e o caminho da página, sem os parâmetros da URL.
- Fica dentro de um Shadow DOM: o CSS do projeto não afeta o widget e o widget não afeta o projeto.

## Antes de começar

1. Descubra o framework do projeto (HTML puro, React, Next.js, Vue, Nuxt, Svelte, WordPress...).
2. Se a pessoa não disse em quais telas quer a avaliação, pergunte. Se ela não souber, sugira o fim das telas principais (por exemplo: resultado de uma busca, fim de um cadastro, checkout, página de ajuda) ou a barra flutuante em todas as páginas.
3. Escolha um nome curto para o app (`data-app`), em minúsculas e com hífens, por exemplo `meu-app`.
4. Peça à pessoa a chave do site (`data-site`, começa com `k_`). **Ela é obrigatória:** sem uma chave válida o widget não aparece e a TBBC recusa os votos. A pessoa cria a chave de graça em https://tbbc.app/feedbacks, num time dela, e as respostas vão para o painel desse time. Se ela não tiver a chave agora, use `SUA_CHAVE` e avise que o widget só aparece depois da troca.

## Passo 1: carregar o script uma vez, no layout global

```html
<script src="https://tbbc.app/rating-widget/rating.js" data-site="SUA_CHAVE" data-app="meu-app" async></script>
```

Para mostrar uma barra fixa no canto de todas as páginas (sem o passo 2), acrescente `data-floating`:

```html
<script src="https://tbbc.app/rating-widget/rating.js" data-site="SUA_CHAVE" data-app="meu-app" data-floating async></script>
```

## Passo 2: colocar a avaliação onde ela deve aparecer

```html
<div data-tbbc-rating data-section="checkout"></div>
```

Regras para `data-section`:

- Um nome estável por parte do app, em minúsculas: `home`, `busca`, `checkout`, `cadastro/fim`.
- Use só letras, números e `- _ . /`. Outros caracteres viram `-`.
- Não coloque dados da pessoa nem ids (nada de e-mail, número de pedido ou id de usuário).

## Por framework

### HTML puro, ou qualquer site com acesso ao HTML

Coloque o script antes de `</body>` em todas as páginas (ou no template comum) e as `<div data-tbbc-rating>` onde quiser.

### React, Next.js, Remix, Vite

Crie um componente cliente que carrega o script uma vez e monta o widget no próprio elemento:

```jsx
'use client' // Next.js App Router. Remova nos outros casos.
import { useEffect, useRef } from 'react'

const SRC = 'https://tbbc.app/rating-widget/rating.js'

export function TbbcRating({ section, site = 'SUA_CHAVE', app = 'meu-app' }) {
  const ref = useRef(null)

  useEffect(() => {
    const mount = () => window.TBBCRating && window.TBBCRating.mount(ref.current)
    if (window.TBBCRating) return mount()
    let script = document.querySelector(`script[src="${SRC}"]`)
    if (!script) {
      script = document.createElement('script')
      script.src = SRC
      script.async = true
      script.dataset.site = site
      script.dataset.app = app
      document.head.appendChild(script)
    }
    script.addEventListener('load', mount)
    return () => script.removeEventListener('load', mount)
  }, [site, app])

  return <div ref={ref} data-tbbc-rating data-section={section} />
}
```

Uso: `<TbbcRating section="checkout" />`. Com TypeScript, declare `TBBCRating?: { mount(el: Element | null): void; scan(): void }` em `Window`.

### Vue, Nuxt

```vue
<script setup>
import { onMounted, ref } from 'vue'
const props = defineProps({ section: String, site: { type: String, default: 'SUA_CHAVE' }, app: { type: String, default: 'meu-app' } })
const el = ref(null)
const SRC = 'https://tbbc.app/rating-widget/rating.js'

onMounted(() => {
  const mount = () => window.TBBCRating && window.TBBCRating.mount(el.value)
  if (window.TBBCRating) return mount()
  let script = document.querySelector(`script[src="${SRC}"]`)
  if (!script) {
    script = document.createElement('script')
    script.src = SRC
    script.async = true
    script.dataset.site = props.site
    script.dataset.app = props.app
    document.head.appendChild(script)
  }
  script.addEventListener('load', mount)
})
</script>

<template>
  <div ref="el" data-tbbc-rating :data-section="section"></div>
</template>
```

No Nuxt, use o componente dentro de `<ClientOnly>`.

### Svelte, Angular e outros

Mesma ideia: carregue o script uma vez e, depois que o elemento existir na tela, chame `window.TBBCRating.mount(elemento)`. Se preferir, chame `window.TBBCRating.scan()` depois de cada troca de rota: ele monta todos os `[data-tbbc-rating]` que ainda não foram montados.

### WordPress, Webflow, Wix, Framer e outros construtores

- O script vai no campo de código do rodapé ou do `<head>` do site (por exemplo, "Custom code", "Código personalizado", ou um plugin de inserir scripts).
- A `<div data-tbbc-rating data-section="...">` vai em um bloco de "HTML personalizado" na página.

## Opções e customização

Tudo é customizável por código. As opções vão no `<script>` (valem para todos os widgets da página), num bloco `data-tbbc-rating` (só aquele), ou em JavaScript. Use as opções para combinar com o visual e a voz do projeto: não altere o widget com CSS de fora.

| Atributo | Onde | O que faz |
|---|---|---|
| `data-site` | script | **Obrigatório.** Chave do app, criada em https://tbbc.app/feedbacks. Leva as respostas para o painel do time. |
| `data-app` | script | Nome do app, para separar projetos com a mesma chave. |
| `data-section` | div, ou script com `data-floating` | Parte do app. Sem ele: `default` (ou `floating` na barra fixa). |
| `data-floating` | script | Barra fixa no canto inferior direito. |
| `data-lang` | script ou div | `pt-BR` ou `en`. Sem ele, segue o `lang` da página. |
| `data-theme` | div ou script | `light` ou `dark`. Sem ele, segue o sistema. |
| `data-accent` | div ou script | Cor do botão escolhido, do Enviar e dos links. Qualquer cor CSS. |
| `data-layout` | div ou script | `inline` (padrão) ou `stacked` (pergunta em cima, botões embaixo). |
| `data-fields` | div ou script | Campos do formulário: `comment,name,contact` (padrão), qualquer parte deles, ou `none` para só votar. |
| `data-up-icon` / `data-down-icon` | div ou script | Emoji ou texto no lugar do polegar (ex.: `😍`), ou `none`. Ícones SVG só por JavaScript. |
| `data-question` | div ou script | Pergunta. Padrão: "Esta tela foi útil?". |
| `data-up-label` / `data-down-label` | div ou script | Rótulos dos botões. Padrão: `+1` / `−1`. Vazio (`""`) deixa só o ícone. |
| `data-title-up` / `data-title-down` | div ou script | Título do formulário depois de +1 / −1. |
| `data-placeholder`, `data-name-label`, `data-contact-label`, `data-contact-hint` | div ou script | Textos dos campos. |
| `data-send`, `data-skip`, `data-thanks`, `data-more`, `data-voted`, `data-leave-comment` | div ou script | Botões e mensagens: Enviar, Agora não, Recebido, obrigado!, Quer dizer mais alguma coisa?, Obrigado pelo voto!, Deixar um comentário. |

Variáveis CSS, no seletor `[data-tbbc-rating]`: `--tbbc-rating-accent`, `--tbbc-rating-accent-text`, `--tbbc-rating-bg`, `--tbbc-rating-text`, `--tbbc-rating-muted`, `--tbbc-rating-border`, `--tbbc-rating-radius`, `--tbbc-rating-font`, `--tbbc-rating-font-size`. Exemplo:

```css
[data-tbbc-rating] { --tbbc-rating-accent: #16a34a; --tbbc-rating-radius: 8px; }
```

Em JavaScript, as mesmas opções em camelCase. `TBBCRating.configure({...})` vale para todos os widgets montados depois; `TBBCRating.mount(elemento, {...})` monta um elemento com opções próprias. Só por JavaScript: `upIconHtml` e `downIconHtml` (HTML ou SVG).

```js
TBBCRating.mount(document.getElementById('avaliacao'), {
  section: 'checkout',
  question: 'Deu tudo certo com o pagamento?',
  upLabel: 'Sim',
  downLabel: 'Não',
  upIcon: 'none',
  downIcon: 'none',
  fields: 'comment',
  accent: '#16a34a',
})
```

## Como o widget se comporta

- O formulário abre no mesmo instante do clique; o voto vai em segundo plano.
- Ao enviar, aparece "Recebido, obrigado!" na hora, com "Quer dizer mais alguma coisa?" para continuar. Em "Agora não", a barra mantém "Deixar um comentário".
- A pessoa nunca vê erro de rede: votos e comentários ficam numa fila no navegador e são reenviados até a TBBC aceitar, inclusive depois de recarregar a página.

## Content-Security-Policy

Se o projeto tiver CSP, libere a TBBC:

- `script-src https://tbbc.app`
- `connect-src https://tbbc.app`

## Como verificar

1. Abra uma página com o widget. A pergunta e os botões +1 e −1 devem aparecer. Se não aparecerem, veja o console: sem `data-site` o widget avisa e não renderiza.
2. Clique em +1. No painel de rede, `POST https://tbbc.app/api/rating` deve responder `201`, e o formulário deve abrir.
3. Escreva um comentário e envie. `POST https://tbbc.app/api/rating/<id>` deve responder `200`, e aparece "Recebido, obrigado!".
4. Votos feitos em `localhost` também são gravados, com a origem `localhost`. Faça poucos testes.

## Não faça

- Não baixe nem copie o `rating.js` para o projeto: use sempre a URL da TBBC, para receber correções.
- Não chame a API diretamente nem crie um proxy: o script já faz isso.
- Não envie dados pessoais em `data-section`, `data-app` ou `data-question`.
- Não altere o comportamento do widget com CSS de fora; use as variáveis de cor acima.

## Ao terminar

Diga à pessoa onde o widget foi colocado (arquivos e telas), qual `data-app` e quais `data-section` foram usados, e que as respostas aparecem no painel: https://tbbc.app/feedbacks (o mesmo login onde ela criou a chave). Se ficou `SUA_CHAVE` no código, lembre que o widget só aparece depois que ela trocar pela chave real.

Documentação completa: https://tbbc.app/rating-widget/
Índice dos guias para agentes: https://tbbc.app/rating-widget/llms.txt
