# Eventos e inscrições

> Publique os eventos da associação no seu site, deixe os associados se inscreverem (e os convidados, nos eventos públicos), faça o check-in na entrada com o mesmo leitor das carteirinhas.

URL: https://developers.vimine.network/pt/guides/events/

Os eventos que uma associação publica pelo seu console estão na API com o mesmo princípio das carteirinhas:
**conteúdo headless** (título, resumo, descrição em markdown, imagens, local, datas, links) e **disponibilidade em
tempo real** por tipo de inscrição — nunca *quem* está inscrito. O vocabulário é o do terceiro setor italiano: uma
**inscrição** (*iscrizione*) e, quando há um valor, uma **contribuição** (*contributo*).

:::note[Antes de começar]
O seu cliente precisa das permissões `events:read`, `registrations:read` e `registrations:write` (veja
[Escopos, erros e limites](https://developers.vimine.network/pt/guides/scopes-and-errors/)). Para experimentar sem tocar em dados reais, use
o [sandbox](https://developers.vimine.network/pt/guides/sandbox/): a associação gêmea pode publicar eventos como a real.
:::

## Duas visibilidades

| `visibility` | Quem vê | Quem se inscreve |
|---|---|---|
| `members_only` (padrão) | só com um token de associado ou com o cliente da própria associação | associados com uma carteirinha válida |
| `public` | qualquer pessoa, sem login: `GET /v1/aps/{slug}/events` | associados e — quando o tipo de inscrição não exige carteirinha — **convidados** |

Um evento público mostra aos visitantes do seu site o conteúdo e os tipos de inscrição com as vagas restantes;
os eventos só para associados aparecem apenas depois do login.

## Mostrar os eventos

```js title="página pública, sem login"
import { publicApi } from '@vimine/sdk';
const api = publicApi();
const { items } = await api.events.list('your-slug', { filter: 'upcoming' });
const event = await api.events.get('your-slug', 'jazz-night');
```

```js title="depois do Entrar com Vimine (incluindo os eventos só para associados)"
const { items } = await vimine.events.list();           // events:read
const event = await vimine.events.get('jazz-night');
```

Cada evento traz `registration_types[]`: `amount` (0 = gratuito), `currency`, `remaining` (vagas restantes, `null` =
ilimitadas), `open` e — quando não está aberto — `reason` (`sold_out`, `registration_not_open`,
`registration_closed`). `status` é `published`, `completed` (a data já passou) ou `cancelled`.

Sem escrever código: o elemento [`<vimine-events>`](https://developers.vimine.network/pt/sdk/elements/) mostra a lista com os
botões de inscrição.

## Quem ainda não é associado

Um evento público também chega a quem não é associado: é o momento em que uma pessoa decide se tornar um.
A página de adesão da associação no Vimine se abre **com o evento**, e a pessoa se associa e reserva num
só passo:

```
https://app.vimine.network/enroll/your-slug?event=jazz-night
```

```js title="o mesmo endereço, a partir do seu código"
import { eventEnrollUrl } from '@vimine/sdk/elements';
const url = eventEnrollUrl('https://app.vimine.network', 'your-slug', 'jazz-night', 'en');
```

O que acontece com a vaga depende da situação da adesão, e a página informa a pessoa:

| A adesão | A vaga |
|---|---|
| fica ativa na hora (carteirinha gratuita, sem aprovação) | **confirmada**, quando a inscrição no evento é gratuita |
| aguarda a aprovação ou a taxa | para uma inscrição só para associados: **guardada** até a carteirinha ficar ativa, e então, quando é gratuita, confirmada sozinha. Para uma inscrição aberta a todos: confirmada na hora, como para quem não é associado |
| a inscrição no evento pede uma contribuição | **guardada** até o prazo definido pela associação: confirmada quando ela registra a contribuição |
| o endereço de e-mail ainda não foi confirmado | nada é guardado: a vaga é pedida quando a pessoa confirma o endereço pelo link do e-mail, e um e-mail conta a ela como foi |

Quem já é associado usa a mesma página: entra e reserva com um botão, sem nada para
preencher (`&signin=1` abre o login na hora). Isso vale para os eventos `public` publicados e que ainda não
aconteceram: com qualquer outro slug, a página é a página de adesão comum.

A página pública do evento no Vimine (`/agenda/your-slug/jazz-night`) e o `<vimine-events>` já oferecem
aos visitantes esse caminho: *Associe-se e reserve*.

## Inscrever um associado

Antes de mostrar o botão, pergunte à API se o associado pode se inscrever — a resposta diz por que não:

```js
const { can_register, types } = await vimine.events.eligibility('jazz-night');
// types[i].reasons: membership_required, membership_not_active, membership_not_yet_valid, sold_out, max_per_user, registration_closed, …
```

Depois faça a inscrição (`registrations:write`):

```js
const reg = await vimine.registrations.create('jazz-night', { registration_type: types[0].uid, note: 'Vou com a minha irmã' });
if (reg.status === 'confirmed') drawQr(reg.token);           // tipo gratuito: confirmada, QR pronto
if (reg.status === 'reserved') show(reg.payment_instructions); // com contribuição: reservada até o pagamento
```

- Um tipo **gratuito** confirma na hora e devolve `token`: o conteúdo do QR que o associado mostra na entrada
  (desenhe-o você mesmo, com a biblioteca que preferir).
- Um tipo **com contribuição** reserva a vaga (`reserved_until`) e devolve as instruções de pagamento da associação;
  a secretaria confirma quando registra a contribuição — o associado recebe um e-mail e a partir daí
  `vimine.registrations.get(id)` traz o `token`. Os pagamentos com cartão chegam com o Stripe.
- Se a carteirinha do associado ainda está aguardando a ativação, a inscrição fica `reserved` e se confirma sozinha
  quando a carteirinha fica ativa.
- `422 not_eligible` traz em `errors[]` os mesmos motivos da chamada de elegibilidade.

As inscrições do associado: `vimine.registrations.list({ filter: 'upcoming' })`; o cancelamento dentro da janela do
evento (`registration.cancellation_hours` horas antes do início): `vimine.registrations.cancel(id)` — depois,
`409 window_closed`.

## Convidados (eventos públicos)

Um visitante sem conta Vimine pode se inscrever num evento **público**, num tipo de inscrição que não exige
carteirinha, a partir do seu servidor (cliente confidencial, `registrations:write`):

```js title="servidor"
await srv.registrations.guest('jazz-night', { email, first_name, last_name, registration_type });
// → { status: 'accepted' }, sempre
```

Nenhuma conta é criada. O convidado recebe um e-mail com um link de confirmação (válido por 24 horas) que leva à
página do evento no Vimine: com um tipo gratuito a vaga é confirmada ali e o QR aparece na hora; com uma
contribuição a vaga fica reservada com as instruções de pagamento. Se preferir hospedar você mesmo a página de
confirmação, consuma o token do link com `api.confirmRegistration(token)`.

Quando a vaga é confirmada — na hora com um tipo gratuito, quando a contribuição é registrada nos outros casos — o
convidado recebe um segundo e-mail com um link próprio: ele abre a página do evento com o QR para mostrar na entrada, e
funciona até o fim do evento (um evento adiado o mantém). Um convidado não tem área pessoal: o link é a vaga dele,
nunca o QR em si (um e-mail encaminhado não é uma vaga). Se você hospedar essa página, leia a vaga com
`api.viewRegistration(token)` (SDK desde a 0.3.2).

A resposta é sempre `202 { status: 'accepted' }`: a API nunca revela se um endereço já está
cadastrado. Os problemas de elegibilidade (`sold_out`, `membership_required` para um tipo só para associados) são `422`.

:::caution[Impostos]
Pelo Código do Terceiro Setor italiano, as contribuições de **quem não é associado** são receitas comerciais: o console
avisa isso quando um evento se torna público, e cada contribuição é classificada automaticamente a partir da
carteirinha que a inscrição tinha no momento do pagamento.
:::

## Na entrada

O QR da inscrição é um token assinado como o da carteirinha: o mesmo leitor e a mesma chamada o aceitam.

```js title="servidor (catraca, leitor, balcão)"
const r = await srv.checkins.create(scannedToken);
if (r.kind === 'registration') {
    // r.verdict: valid | already_checked_in | not_confirmed | cancelled | event_cancelled | membership_invalid
    // r.first: true na primeira passagem; r.membership_verdict quando o tipo exige uma carteirinha
}
```

A verificação pública também responde a um token de inscrição: `GET /v1/verify/{token}` →
`{ status, kind: 'registration', event: { slug, starts_at } }`, sem dados pessoais.

## Pelo seu back office

As inscrições de um evento — id, status, tipo, carteirinha, check-in, **sem dados pessoais** — são
`srv.registrations.listForEvent(slug, { status, limit, cursor })` (`registrations:read`, planos com listas via API).
Os nomes ficam no console da associação.

## Referências

- [SDK do navegador](https://developers.vimine.network/pt/sdk/browser/#events) · [SDK de servidor](https://developers.vimine.network/pt/sdk/server/#events) ·
  [`<vimine-events>`](https://developers.vimine.network/pt/sdk/elements/) · [Tipos](https://developers.vimine.network/pt/sdk/types/)
- API HTTP: as operações com as tags `events` e `registrations` na [referência](https://developers.vimine.network/pt/api/console/).
