npm package: @olostecnologia/olosmaps
Description: Olos Maps is a React component library for displaying maps with customizable markers and popups.
Author: Giovanni Spolidorio Sabino
Latest version: 1.0.6

# Olos Maps

Uma biblioteca React para exibição de mapas com marcadores customizáveis e popups. Suporta múltiplos provedores de mapas (Google Maps, Mapbox, MapLibre e Leaflet).

## 📋 Índice

- [Provedores Disponíveis](#-provedores-disponíveis)
- [Instalação](#-instalação)
- [Configuração](#-configuração)
- [Uso Básico](#-uso-básico)
- [API Reference](#-api-reference)
- [Exemplos](#-exemplos)
- [Desenvolvimento](#-desenvolvimento)

## 🗺️ Provedores Disponíveis

A biblioteca suporta 4 provedores de mapas:

| Provedor | Valor | Requer API Key | Características |
|----------|-------|----------------|-----------------|
| Google Maps | `"google"` | ✅ Sim | Rico em recursos, clustering nativo |
| Mapbox | `"mapbox"` | ✅ Sim | Visual moderno, alta customização |
| MapLibre | `"maplibre"` | ❌ Não | Open source, baseado em Mapbox |
| Leaflet | `"leaflet"` | ❌ Não | Leve, simples, open source |

## 📦 Instalação

### Instale a biblioteca via npm ou yarn

```bash
npm install @olostecnologia/olosmaps
```

ou

```bash
yarn add @olostecnologia/olosmaps
```

## ⚙️ Configuração

### Google Maps

Para usar o Google Maps, você precisa de uma chave de API do Google Cloud Platform:

1. Acesse o [Google Cloud Console](https://console.cloud.google.com/)
2. Crie um novo projeto ou selecione um existente
3. Ative a API do Maps JavaScript
4. Crie uma chave de API em "Credenciais"

### Mapbox

Para usar o Mapbox, você precisa de um token de acesso:

1. Crie uma conta em [Mapbox](https://www.mapbox.com/)
2. Acesse o [painel de tokens](https://account.mapbox.com/access-tokens/)
3. Copie seu token de acesso público

### MapLibre e Leaflet

MapLibre e Leaflet não requerem chaves de API e podem ser usados gratuitamente.

## 🚀 Uso Básico

### Exemplo com Google Maps

```tsx
import { Map } from '@olostecnologia/olosmaps';
import type { Marker } from '@olostecnologia/olosmaps';

function App() {
  const markers: Marker[] = [
    {
      id: '1',
      position: { lat: -23.5505, lng: -46.6333 },
      label: 'São Paulo',
    },
    {
      id: '2',
      position: { lat: -22.9068, lng: -43.1729 },
      label: 'Rio de Janeiro',
    },
  ];

  return (
    <Map
      provider="google"
      apiKey="SUA_CHAVE_API_GOOGLE"
      center={{ lat: -23.5505, lng: -46.6333 }}
      zoom={10}
      markers={markers}
      theme="light"
      onMarkerClick={(marker) => console.log('Marcador clicado:', marker)}
      mapContainerStyle={{ height: '600px', width: '100%' }}
    />
  );
}
```

### Exemplo com Leaflet (sem API key)

```tsx
import { Map } from '@olostecnologia/olosmaps';

function App() {
  return (
    <Map
      provider="leaflet"
      center={{ lat: -23.5505, lng: -46.6333 }}
      zoom={10}
      theme="light"
      mapContainerStyle={{ height: '600px', width: '100%' }}
    />
  );
}
```

### Exemplo com Mapbox

```tsx
import { Map } from '@olostecnologia/olosmaps';

function App() {
  return (
    <Map
      provider="mapbox"
      apiKey="SEU_TOKEN_MAPBOX"
      center={{ lat: -23.5505, lng: -46.6333 }}
      zoom={10}
      theme="dark"
      mapContainerStyle={{ height: '600px', width: '100%' }}
    />
  );
}
```
## 📖 API Reference

### Propriedades do Componente Map

#### Propriedades Comuns (todos os provedores)

| Propriedade | Tipo | Obrigatório | Padrão | Descrição |
|------------|------|-------------|--------|-----------|
| `provider` | `"google" \| "mapbox" \| "maplibre" \| "leaflet"` | ✅ | - | Provedor de mapa a ser usado |
| `center` | `LatLng` | ❌ | `{ lat: 0, lng: 0 }` | Centro inicial do mapa |
| `zoom` | `number` | ❌ | `10` | Nível de zoom inicial |
| `markers` | `Marker[]` | ❌ | `[]` | Array de marcadores a serem exibidos |
| `theme` | `"light" \| "dark" \| "satellite" \| "retro"` | ❌ | `"light"` | Tema visual do mapa |
| `mapContainerStyle` | `CSSProperties` | ❌ | - | Estilos CSS para o container do mapa |
| `onMarkerClick` | `(marker?: Marker) => void` | ❌ | - | Callback quando um marcador é clicado |

#### Propriedades Específicas por Provedor

##### Google Maps

```typescript
interface GoogleMapProps {
  provider: "google";
  apiKey: string; // ✅ Obrigatório
  providerProps?: {
    customTheme?: MapTypeStyle;
    clusterer?: ClustererOptions;
    markerIcon?: string;
  };
  onClusterClick?: (cluster?: Marker[]) => void;
}
```

##### Mapbox

```typescript
interface MapboxMapProps {
  provider: "mapbox";
  apiKey: string; // ✅ Obrigatório
  providerProps?: {
    customTheme?: string;
    clusters?: LayerProps;
    clusterCount?: LayerProps;
    unclusteredPoint?: LayerProps;
  };
  onClusterClick?: (cluster?: Marker[]) => void;
}
```

##### MapLibre

```typescript
interface MaplibreMapProps {
  provider: "maplibre";
  providerProps?: {
    customTheme?: string;
    clusters?: LayerProps;
    clusterCount?: LayerProps;
    unclusteredPoint?: LayerProps;
  };
  onClusterClick?: (cluster?: Marker[]) => void;
}
```

##### Leaflet

```typescript
interface LeafletMapProps {
  provider: "leaflet";
  providerProps?: {
    customTheme?: string;
    clusters?: L.DivIconOptions;
    marker?: L.DivIconOptions;
  };
  onClusterClick?: (totalPoints?: number) => void;
}
```

### Tipo Marker

```typescript
type Marker<T = any> = {
  id: string;
  position: LatLng;
  label?: string;
  data?: T; // Dados customizados associados ao marcador
};
```

### Tipo LatLng

```typescript
interface LatLng {
  lat: number;
  lng: number;
  city?: string;
}
```

## 💡 Exemplos

### Exemplo com Clustering (Google Maps)

```tsx
import { Map } from '@olostecnologia/olosmaps';

function App() {
  const markers = [
    { id: '1', position: { lat: -23.5505, lng: -46.6333 }, label: 'Ponto 1' },
    { id: '2', position: { lat: -23.5510, lng: -46.6340 }, label: 'Ponto 2' },
    { id: '3', position: { lat: -23.5520, lng: -46.6350 }, label: 'Ponto 3' },
    // ... mais marcadores
  ];

  return (
    <Map
      provider="google"
      apiKey="SUA_CHAVE_API"
      markers={markers}
      center={{ lat: -23.5505, lng: -46.6333 }}
      zoom={12}
      onClusterClick={(cluster) => {
        console.log(`Cluster com ${cluster?.length} marcadores`);
      }}
    />
  );
}
```

### Exemplo com Dados Customizados

```tsx
interface StoreData {
  name: string;
  address: string;
  phone: string;
}

function StoresMap() {
  const stores: Marker<StoreData>[] = [
    {
      id: '1',
      position: { lat: -23.5505, lng: -46.6333 },
      label: 'Loja Centro',
      data: {
        name: 'Loja Centro',
        address: 'Av. Paulista, 1000',
        phone: '(11) 1234-5678',
      },
    },
  ];

  return (
    <Map
      provider="leaflet"
      markers={stores}
      onMarkerClick={(marker) => {
        if (marker?.data) {
          alert(`${marker.data.name}\n${marker.data.address}\n${marker.data.phone}`);
        }
      }}
      mapContainerStyle={{ height: '100vh', width: '100%' }}
    />
  );
}
```

### Exemplo com Tema Customizado

```tsx
import { Map } from '@olostecnologia/olosmaps';

function DarkModeMap() {
  return (
    <Map
      provider="mapbox"
      apiKey="SEU_TOKEN"
      theme="dark"
      center={{ lat: -23.5505, lng: -46.6333 }}
      zoom={10}
      mapContainerStyle={{ height: '600px', width: '100%' }}
    />
  );
}
```

### Exemplo com Utilidades

A biblioteca também exporta funções utilitárias para trabalhar com dados de telefone e localização:

```tsx
import {
  Map,
  extracDDDFromDNIS,
  phoneToLatLong,
  calculateZoomLevel,
  calculateMapCenter,
} from '@olostecnologia/olosmaps';

function AnalyticsMap({ calls }) {
  // Extrai coordenadas dos números de telefone
  const markers = calls.map((call, index) => ({
    id: String(index),
    position: phoneToLatLong(call.phone),
    label: call.customerName,
    data: call,
  }));

  // Calcula o centro do mapa baseado nos marcadores
  const center = calculateMapCenter(markers);
  
  // Calcula o zoom ideal
  const zoom = calculateZoomLevel(markers);

  return (
    <Map
      provider="google"
      apiKey="SUA_CHAVE_API"
      markers={markers}
      center={center}
      zoom={zoom}
      onMarkerClick={(marker) => {
        console.log('Chamada:', marker?.data);
      }}
    />
  );
}
```

## 🛠️ Desenvolvimento

### Requisitos

- Node.js 16+
- npm ou yarn

### Instalação para Desenvolvimento

```bash
# Clone o repositório
git clone https://github.com/OlosCore/olos-maps.git
cd olos-maps

# Instale as dependências
npm install

# Inicie o modo de desenvolvimento
npm run dev

# Em outro terminal, inicie o playground
npm run playground
```

### Scripts Disponíveis

- `npm run dev` - Modo de desenvolvimento com watch
- `npm run build` - Gera o build de produção
- `npm run playground` - Inicia o playground para testes
- `npm run clear` - Limpa a pasta dist

### Estrutura do Projeto

```
olos-maps/
├── src/
│   ├── components/        # Componentes React
│   │   └── Map/          # Componente principal do mapa
│   ├── providers/        # Implementações dos provedores
│   │   ├── google/       # Google Maps
│   │   ├── mapbox/       # Mapbox
│   │   ├── maplibre/     # MapLibre
│   │   └── leaflet/      # Leaflet
│   ├── styles/           # Temas e estilos
│   ├── utils/            # Funções utilitárias
│   └── @types/           # Definições TypeScript
├── playground/           # Aplicação de exemplo
└── dist/                # Build de produção
```

## 📄 Licença

Este projeto é mantido por Olos Tecnologia.

## 🤝 Contribuindo

Contribuições são bem-vindas! Por favor, abra uma issue ou pull request no repositório.

## 📞 Suporte

Para suporte, entre em contato através do repositório GitHub ou visite [Olos Tecnologia](https://olostecnologia.com.br).