# 🌐 Integração Site / Catálogo com Sistema de Estoque

## 📋 Visão Geral

O site de catálogo (`/site/`) foi completamente integrado com o sistema de estoque, permitindo:

- ✅ **Sincronização automática** com produtos do painel admin
- ✅ **Controle de visibilidade** através do campo `visivel_catalogo`
- ✅ **Galeria de fotos** com bucket `catalogo` do Supabase
- ✅ **Configurações centralizadas** no painel admin
- ✅ **Upload de múltiplas fotos** por produto

## 🔧 Modificações Realizadas

### 1. Site (`/site/`)

#### `script.js` - Alterações Principais

**Adicionado carregamento de configurações:**
```javascript
let catalogoConfig = {
    catalogoAtivo: false,
    exibirPrecos: true,
    exibirEstoque: false
};

async function carregarConfiguracoesCatalogo() {
    // Busca configurações do painel admin
    // Aplica classes CSS baseado nas configurações
}
```

**Filtro por visibilidade:**
```javascript
.eq('ativo', true)
.eq('visivel_catalogo', true)  // ← NOVO
```

**Carregamento de fotos do bucket `catalogo`:**
```javascript
// Para cada produto, busca fotos adicionais
const { data: fotosAdicionais } = await supabaseClient
    .storage
    .from('catalogo')
    .list(`produto_${produto.id}`);
```

**Galeria de fotos no modal:**
```javascript
// Construir galeria: foto principal + variações + bucket
const galeriaFotos = [
    produto.foto_principal,
    ...fotosDasVariacoes,
    ...fotosAdicionais
].filter(Boolean);
```

#### `styles.css` - Novos Estilos

**Galeria de miniaturas:**
```css
.produto-modal-galeria {
    display: flex;
    gap: 8px;
    overflow-x: auto;
}

.galeria-miniatura {
    width: 60px;
    height: 60px;
    border: 2px solid transparent;
}

.galeria-miniatura.active {
    border-color: var(--color-primary);
}
```

**Ocultar preços (configurável):**
```css
.hide-prices .produto-preco-minimal,
.hide-prices .produto-modal-preco {
    display: none !important;
}
```

### 2. Painel Admin

#### `SiteCatalogo.js` - Novo Componente

**Gerenciamento de fotos adicionais:**
```jsx
// Modal para upload de fotos no bucket 'catalogo'
const handleUploadFoto = async (event) => {
    const formData = new FormData();
    formData.append('foto', file);
    
    await fetch(`/api/produtos/${produto.id}/fotos-catalogo`, {
        method: 'POST',
        body: formData
    });
};
```

**Listagem e exclusão:**
```jsx
// Listar fotos do bucket
await fetch(`/api/produtos/${produtoId}/fotos-catalogo`);

// Deletar foto específica
await fetch(`/api/produtos/${produto.id}/fotos-catalogo/${fileName}`, {
    method: 'DELETE'
});
```

#### `site-catalogo.css` - Estilos do Modal

- Modal responsivo com overlay
- Grid de fotos com hover effects
- Botão de upload estilizado
- Animações suaves

### 3. Backend (`server-supabase.js`)

#### Novos Endpoints

**1. Listar fotos do produto**
```javascript
GET /api/produtos/:id/fotos-catalogo

Response: {
    success: true,
    fotos: [
        {
            name: "foto.jpg",
            url: "https://...",
            created_at: "...",
            size: 12345
        }
    ]
}
```

**2. Upload de foto adicional**
```javascript
POST /api/produtos/:id/fotos-catalogo
Content-Type: multipart/form-data

Body: {
    foto: <file>
}

Response: {
    success: true,
    message: "Foto adicional enviada com sucesso!",
    foto: {
        path: "produto_123/foto.jpg",
        url: "https://..."
    }
}
```

**3. Deletar foto**
```javascript
DELETE /api/produtos/:id/fotos-catalogo/:fileName

Response: {
    success: true,
    message: "Foto removida com sucesso!"
}
```

## 📁 Estrutura do Bucket `catalogo`

```
catalogo/
├── produto_1/
│   ├── 1234567890-foto1.jpg
│   ├── 1234567891-foto2.jpg
│   └── 1234567892-foto3.jpg
├── produto_2/
│   ├── 1234567893-foto1.jpg
│   └── 1234567894-foto2.jpg
└── produto_3/
    └── 1234567895-foto1.jpg
```

**Organização:**
- Pasta por produto: `produto_{id}`
- Nome único: `timestamp-nome_original.jpg`
- Acesso público para visualização
- Upload apenas autenticado

## 🎯 Fluxo de Uso

### Para o Administrador

1. **Gerenciar Visibilidade**
   - Acesse **Site / Catalogo** no painel admin
   - Clique em "Visível" / "Oculto" para cada produto
   - Apenas produtos visíveis aparecem no site público

2. **Adicionar Fotos Extras**
   - Clique no botão "Fotos" de um produto
   - Clique em "Adicionar Nova Foto"
   - Selecione a imagem (máx 5MB)
   - Foto aparece automaticamente no catálogo

3. **Remover Fotos**
   - Abra o gerenciador de fotos
   - Passe o mouse sobre a foto
   - Clique no botão "×" vermelho

4. **Configurar Catálogo**
   - Defina URL do site
   - Ative/Desative o catálogo
   - Configure exibição de preços
   - Configure exibição de estoque

### Para o Cliente (Site Público)

1. **Visualizar Produtos**
   - Apenas produtos com `visivel_catalogo = true`
   - Ordenados por data de cadastro (mais recentes primeiro)

2. **Ver Fotos**
   - Foto principal aparece no card
   - Clique para ver todas as fotos
   - Galeria com miniaturas
   - Clique para trocar foto principal

3. **Informações**
   - Preços: conforme configuração admin
   - Estoque: conforme configuração admin
   - Variações: sempre visível

## 🔄 Sincronização

### Automática

- ✅ Produtos novos aparecem automaticamente (se `visivel_catalogo = true`)
- ✅ Alterações de preço refletem imediatamente
- ✅ Alterações de estoque em tempo real
- ✅ Fotos novas aparecem na galeria

### Manual

- ⚙️ Toggle de visibilidade no painel admin
- 📸 Upload de fotos adicionais
- 🗑️ Remoção de fotos

## 🎨 Galeria de Fotos - Ordem de Prioridade

1. **Foto Principal** (`foto_principal` da tabela `produtos`)
2. **Fotos das Variações** (array `fotos` em `produto_variacoes`)
3. **Fotos Adicionais** (bucket `catalogo`)

**Resultado:** Todas as fotos disponíveis em uma única galeria, sem duplicatas.

## 🔐 Segurança

### Bucket `catalogo`

**Políticas RLS:**
```sql
-- Leitura pública
CREATE POLICY "Permitir leitura pública"
ON storage.objects FOR SELECT
USING (bucket_id = 'catalogo');

-- Upload apenas autenticado
CREATE POLICY "Permitir upload autenticado"
ON storage.objects FOR INSERT
WITH CHECK (
    bucket_id = 'catalogo' AND
    auth.role() = 'authenticated'
);

-- Delete apenas autenticado
CREATE POLICY "Permitir delete autenticado"
ON storage.objects FOR DELETE
USING (
    bucket_id = 'catalogo' AND
    auth.role() = 'authenticated'
);
```

### Validações

- ✅ Apenas imagens (jpeg, png, gif, webp)
- ✅ Máximo 5MB por foto
- ✅ Validação de tipo MIME no backend
- ✅ Sanitização de nomes de arquivo

## 🚀 Deploy e Configuração

### 1. Criar Bucket no Supabase

```sql
-- Executar no SQL Editor
INSERT INTO storage.buckets (id, name, public)
VALUES ('catalogo', 'catalogo', true);
```

### 2. Configurar Políticas

Execute as políticas RLS acima no SQL Editor.

### 3. Testar Upload

```bash
# Via painel admin
1. Acesse Site / Catalogo
2. Clique em "Fotos" em qualquer produto
3. Faça upload de uma imagem de teste
4. Verifique no Supabase Storage se apareceu
```

### 4. Verificar Site Público

```bash
# Abra o site de catálogo
open http://localhost:5000/site/

# Verifique se:
# - Produtos aparecem corretamente
# - Fotos carregam
# - Galeria funciona
```

## 📊 Monitoramento

### Verificar Produtos Visíveis

```sql
SELECT 
    id, 
    nome, 
    visivel_catalogo, 
    ativo
FROM produtos
WHERE visivel_catalogo = true
ORDER BY created_at DESC;
```

### Verificar Fotos no Bucket

```sql
SELECT 
    name,
    created_at,
    metadata
FROM storage.objects
WHERE bucket_id = 'catalogo'
ORDER BY created_at DESC
LIMIT 20;
```

### Estatísticas

```sql
-- Produtos por status
SELECT 
    CASE 
        WHEN visivel_catalogo = true THEN 'Visível'
        ELSE 'Oculto'
    END as status,
    COUNT(*) as total
FROM produtos
WHERE ativo = true
GROUP BY visivel_catalogo;
```

## 🐛 Troubleshooting

### Fotos não aparecem no site

**Verificar:**
1. Bucket `catalogo` existe e é público
2. Políticas RLS configuradas
3. Caminho correto: `produto_{id}/arquivo.jpg`
4. Console do navegador para erros

### Upload falha

**Possíveis causas:**
- Arquivo muito grande (> 5MB)
- Tipo não suportado
- Falta de autenticação
- Políticas RLS incorretas

**Solução:**
```javascript
// Verificar no console do navegador
console.log('Erro de upload:', error);

// Verificar no servidor
tail -f server.log | grep "upload"
```

### Produtos não aparecem

**Verificar:**
```sql
SELECT 
    nome,
    ativo,
    visivel_catalogo
FROM produtos
WHERE id = X;
```

Certifique-se que:
- `ativo = true`
- `visivel_catalogo = true`

## 📱 Responsividade

### Desktop (> 768px)
- Grid de produtos: 3-4 colunas
- Galeria: miniaturas horizontais
- Modal: 800px largura

### Mobile (< 768px)
- Grid de produtos: 1 coluna
- Galeria: scroll horizontal
- Modal: 95% altura da tela

## 🎯 Próximas Melhorias

### Curto Prazo
- [ ] Arrastar e soltar fotos para reordenar
- [ ] Crop de imagens no upload
- [ ] Comprimir imagens automaticamente
- [ ] Preview antes do upload

### Médio Prazo
- [ ] Editor de fotos integrado
- [ ] Marcas d'água automáticas
- [ ] Galeria em fullscreen
- [ ] Zoom nas fotos

### Longo Prazo
- [ ] CDN para fotos
- [ ] Lazy loading otimizado
- [ ] WebP conversion automática
- [ ] PWA com cache de imagens

## 📝 Checklist de Implementação

- [x] Script.js atualizado com filtro `visivel_catalogo`
- [x] Carregamento de fotos do bucket `catalogo`
- [x] Galeria de fotos no modal do site
- [x] Configurações integradas do admin
- [x] Componente SiteCatalogo com gerenciador
- [x] Endpoints de upload/delete de fotos
- [x] Estilos CSS para modal de fotos
- [x] Validações de upload
- [x] Tratamento de erros
- [x] Documentação completa

## ✅ Resumo

**Antes:**
- Site e admin separados
- Produtos fixos no código
- Sem sincronização
- Fotos limitadas

**Depois:**
- 🔄 Sincronização automática
- 👁️ Controle de visibilidade
- 📸 Galeria ilimitada de fotos
- ⚙️ Configurações centralizadas
- 🎨 Interface moderna
- 📱 Totalmente responsivo

---

**Data de Integração:** 24 de outubro de 2025  
**Versão:** v1.1.0  
**Desenvolvido para:** Liberi Kids - Moda Infantil 👶✨
