# API dos locais — Mapa Santa Mônica

Base: `https://servicos2.santamonica.rec.br/mapa-online-smcc`

Não precisa de token, login nem cabeçalho especial. A resposta vem em JSON.

Só entram locais com `ativo = true`. A lista fica em cache por até 1 hora e atualiza quando um local, categoria, horário ou planta é salvo no admin.

---

## 1. Listar locais

`GET /api/mapa`

URL completa:

`https://servicos2.santamonica.rec.br/mapa-online-smcc/api/mapa`

### O que você envia

Nada. Sem query string, sem body e sem `Authorization`.

```http
GET /mapa-online-smcc/api/mapa HTTP/1.1
Host: servicos2.santamonica.rec.br
Accept: application/json
```

```bash
curl -s "https://servicos2.santamonica.rec.br/mapa-online-smcc/api/mapa"
```

### O que você recebe

`200` com `Content-Type: application/json`. O corpo é um objeto com seis chaves.

| Chave | Tipo | Conteúdo |
| --- | --- | --- |
| `locais` | array | Um objeto por local ativo, na ordem do campo `ordem` |
| `categorias` | array | Filtros. O primeiro item é sempre `todos` |
| `base` | string | Prefixo da pasta no servidor: `/mapa-online-smcc` |
| `origemPadrao` | objeto | Ponto de referência da portaria (`lat`, `lng`, `nome`) |
| `contato` | objeto | Telefone, endereço e link geral do clube |
| `reservas` | objeto | Como reservar um local marcável |
| `logo` | string | URL da logo |

Exemplo reduzido:

```json
{
  "locais": [
    {
      "id": "secretaria",
      "nome": "Secretaria",
      "categoria": "servicos",
      "categoriaLabel": "Serviços",
      "area": "Área Administrativa",
      "imagem": "https://servicos2.santamonica.rec.br/mapa-online-smcc/storage/locais/secretaria.png",
      "imagemThumb": "https://servicos2.santamonica.rec.br/mapa-online-smcc/storage/locais/secretaria.png",
      "icon": "M12 21s7-6.4 7-11a7 7 0 1 0-14 0c0 4.6 7 11 7 11z",
      "x": 44.4,
      "y": 50.2,
      "latitude": -25.3826981,
      "longitude": -49.1478898,
      "destaque": "Aqui começa sua experiência no clube!",
      "descricao": "Nossa equipe está pronta para atender você com cordialidade e eficiência.",
      "resumo": "Atendimento ao associado, carteirinhas e convites.",
      "telefone": "(41) 3675-4200",
      "googleMapsUrl": "https://www.google.com/maps/dir/?api=1&destination=-25.3826981,-49.1478898&travelmode=walking",
      "horarios": [
        { "dias": "Terça a sexta", "horas": "10h às 20h" },
        { "dias": "Sábado", "horas": "08h às 18h" }
      ],
      "reservavel": false
    }
  ],
  "categorias": [
    {
      "id": "todos",
      "label": "Todos os locais",
      "icon": "M12 21s7-6.4 7-11a7 7 0 1 0-14 0c0 4.6 7 11 7 11z",
      "count": 47
    },
    {
      "id": "esportes",
      "label": "Esportes",
      "icon": "M4 7h16v13H4z",
      "count": 4
    }
  ],
  "base": "/mapa-online-smcc",
  "origemPadrao": {
    "lat": -25.3826,
    "lng": -49.1478,
    "nome": "da portaria"
  },
  "contato": {
    "telefone": "(41) 3675-4200",
    "telefone_link": "+554136754200",
    "endereco": "Rodovia Régis Bittencourt, nº 5000",
    "rodape": "Terça a sábado das 10h às 20h",
    "rodape2": "Sábado das 08h às 18h",
    "copyright": "Santa Mônica Clube de Campo",
    "google_maps": "https://www.google.com/maps/dir/?api=1&destination=-25.3826981,-49.1478898&travelmode=walking"
  },
  "reservas": {
    "url": null,
    "telefone": "(41) 3675-4200",
    "telefone_link": "+554136754200",
    "aviso": "Reservas pela secretaria, presencialmente ou por telefone."
  },
  "logo": "https://santamonica.rec.br/wp-content/uploads/2023/02/logo-santa-monica.png"
}
```

### Campos de cada local

| Campo | Tipo | Pode ser nulo | Significado |
| --- | --- | --- | --- |
| `id` | string | não | Slug. É o identificador na URL (`/locais/secretaria`) |
| `nome` | string | não | Nome exibido |
| `categoria` | string | não | Slug da categoria (`esportes`, `lazer`, `churrasqueiras`…) |
| `categoriaLabel` | string | não | Nome da categoria |
| `area` | string | sim | Setor ou “onde fica”. Vazio: a ficha não mostra essa linha |
| `imagem` | string | não | URL da foto. Sem foto, cai no placeholder |
| `imagemThumb` | string | não | URL da miniatura. Sem miniatura, repete `imagem` |
| `icon` | string | não | Atributo `d` de um SVG 24×24, não uma URL |
| `x` | number | sim | Posição horizontal na planta, em porcentagem |
| `y` | number | sim | Posição vertical na planta, em porcentagem |
| `latitude` | number | sim | Latitude, quando a planta já foi ancorada |
| `longitude` | number | sim | Longitude, quando a planta já foi ancorada |
| `destaque` | string | não | Frase curta da ficha |
| `descricao` | string | não | Texto longo da ficha |
| `resumo` | string | não | Uma linha, usada no card |
| `telefone` | string | sim | Telefone formatado do local |
| `googleMapsUrl` | string | sim | Link “Como chegar” deste local. Se vier `null`, use `contato.google_maps` |
| `horarios` | array | não | Lista de `{ "dias", "horas" }`. Pode vir vazia |
| `reservavel` | boolean | não | `true` mostra o botão Reservar. Churrasqueira é sempre `false` |

### Campos de cada categoria

| Campo | Tipo | Significado |
| --- | --- | --- |
| `id` | string | Slug. `todos` não é categoria do banco |
| `label` | string | Nome do filtro |
| `icon` | string | Atributo `d` do SVG |
| `count` | number | Quantidade de locais ativos naquele filtro |

### Como ler a resposta

Não há paginação nem filtro no servidor. Você recebe a lista inteira e filtra no cliente.

```javascript
const resposta = await fetch(
  "https://servicos2.santamonica.rec.br/mapa-online-smcc/api/mapa"
);
const dados = await resposta.json();

const esportes = dados.locais.filter((local) => local.categoria === "esportes");
const secretaria = dados.locais.find((local) => local.id === "secretaria");
```

Para abrir o “Como chegar”:

```javascript
const url = local.googleMapsUrl || dados.contato.google_maps;
```

Para reservar, se `local.reservavel` for `true`:

- `reservas.url` preenchida: abra esse link.
- `reservas.url` nula: ligue para `reservas.telefone_link`.

---

## 2. Registrar uma visualização

`POST /locais/{slug}/view`

URL completa de exemplo:

`https://servicos2.santamonica.rec.br/mapa-online-smcc/locais/secretaria/view`

Conta uma abertura da ficha daquele local no dia. O site chama isso com `navigator.sendBeacon` depois de 2 segundos com a ficha aberta.

### O que você envia

Só o slug na URL. Sem body.

```http
POST /mapa-online-smcc/locais/secretaria/view HTTP/1.1
Host: servicos2.santamonica.rec.br
```

```bash
curl -i -X POST "https://servicos2.santamonica.rec.br/mapa-online-smcc/locais/secretaria/view"
```

Limite: 60 chamadas por minuto por IP.

### O que você recebe

`204` sem corpo. Sucesso é a ausência de conteúdo, não um JSON.

| Situação | Status | Corpo |
| --- | --- | --- |
| Slug existe | `204` | vazio |
| Slug não existe | `404` | página ou JSON de erro, se o cliente pedir `Accept: application/json` |
| Acima de 60 por minuto | `429` | erro de limite |

---

## O que não é API

Estas rotas devolvem HTML, não JSON:

| Método | Caminho | Resposta |
| --- | --- | --- |
| `GET` | `/` | Página com todos os cards |
| `GET` | `/locais` | Redireciona `301` para `/` |
| `GET` | `/locais/{slug}` | A mesma página, abrindo a ficha daquele local. Local inativo responde `404` |

Não existe endpoint para criar, editar ou apagar local por esta API. Isso fica no admin.
