Primeiro commit

This commit is contained in:
2025-10-14 14:04:17 -03:00
commit 33d8645eb4
109 changed files with 55424 additions and 0 deletions

163
site/README.md Normal file
View File

@@ -0,0 +1,163 @@
# 🛍️ Catálogo Web - Liberi Kids
Catálogo online da **Liberi Kids - Moda Infantil** com carrinho de compras integrado ao WhatsApp.
## 🎯 Funcionalidades
### ✅ Catálogo de Produtos
- **Carregamento automático** dos produtos cadastrados no sistema
- **Filtros inteligentes** por categoria, tamanho e gênero
- **Design responsivo** para desktop e mobile
- **Imagens otimizadas** com fallback para produtos sem foto
### 🛒 Carrinho de Compras
- **Adicionar/remover produtos** com animações suaves
- **Controle de quantidade** individual por item
- **Cálculo automático** do total
- **Persistência visual** do estado do carrinho
### 📱 Integração WhatsApp
- **Envio automático** do pedido para a vendedora Maiara
- **Formatação profissional** da mensagem
- **Detalhes completos** do pedido (produtos, quantidades, valores)
- **Timestamp** e informações de origem
### 🎨 Interface Moderna
- **Design gradient** com cores atrativas
- **Animações CSS** suaves e profissionais
- **Tipografia** Google Fonts (Poppins)
- **Ícones** Font Awesome
- **Layout responsivo** para todos os dispositivos
## 🚀 Como Usar
### 1. Acesso ao Catálogo
```
http://localhost:5000/catalogo
```
### 2. Configuração do WhatsApp
Edite o arquivo `script.js` e altere o número da vendedora:
```javascript
const CONFIG = {
WHATSAPP_NUMBER: '5511999999999', // Número da Maiara
VENDEDORA_NOME: 'Maiara'
};
```
### 3. Fluxo de Compra
1. **Navegar** pelos produtos no catálogo
2. **Filtrar** por categoria, tamanho ou gênero
3. **Adicionar** produtos ao carrinho
4. **Revisar** itens no carrinho lateral
5. **Finalizar** pedido via WhatsApp
## 📋 Estrutura de Arquivos
```
site/
├── index.html # Página principal do catálogo
├── styles.css # Estilos CSS responsivos
├── script.js # JavaScript com todas as funcionalidades
└── README.md # Esta documentação
```
## 🔧 Integração com o Sistema
### API Utilizada
- **Endpoint:** `/api/catalogo/produtos`
- **Método:** GET
- **Retorna:** Produtos em estoque formatados para o catálogo
### Dados dos Produtos
```json
{
"id": 1,
"nome": "Camiseta Infantil",
"preco_venda": 29.90,
"tamanho": "M",
"genero": "unissex",
"estacao": "verao",
"categoria": "camiseta",
"imagem": "/uploads/produto1.jpg",
"estoque": 5,
"descricao": "Camiseta confortável..."
}
```
## 🎨 Personalização
### Cores do Tema
- **Primária:** `#667eea` (Azul gradient)
- **Secundária:** `#764ba2` (Roxo gradient)
- **Sucesso:** `#10b981` (Verde)
- **Erro:** `#ef4444` (Vermelho)
- **WhatsApp:** `#25d366` (Verde WhatsApp)
### Responsividade
- **Desktop:** Layout completo com 3-4 colunas
- **Tablet:** Layout adaptado com 2-3 colunas
- **Mobile:** Layout single-column otimizado
## 📱 Funcionalidades do WhatsApp
### Formato da Mensagem
```
🛍️ NOVO PEDIDO - LIBERI KIDS
👋 Olá Maiara! Gostaria de fazer um pedido:
📦 ITENS DO PEDIDO:
1. Camiseta Infantil
• Tamanho: M
• Gênero: Unissex
• Quantidade: 2x
• Preço unitário: R$ 29,90
• Subtotal: R$ 59,80
📊 RESUMO DO PEDIDO:
• Total de itens: 2
• Valor total: R$ 59,80
📱 Pedido feito através do catálogo online
🕐 07/10/2024 17:30:15
Aguardo retorno para confirmar o pedido! 😊
```
## 🔄 Sincronização Automática
### Produtos Novos
- **Automático:** Novos produtos aparecem no catálogo imediatamente
- **Estoque:** Apenas produtos com estoque > 0 são exibidos
- **Ordem:** Produtos mais recentes aparecem primeiro
### Atualizações em Tempo Real
- **Preços:** Atualizados automaticamente
- **Estoque:** Produtos sem estoque são ocultados
- **Imagens:** Carregamento otimizado com fallback
## 🛡️ Segurança e Performance
### Otimizações
- **Lazy loading** de imagens
- **Debounce** nos filtros
- **Cache** de produtos carregados
- **Compressão** de imagens
### Tratamento de Erros
- **Fallback** para produtos sem imagem
- **Retry** automático em caso de erro de rede
- **Mensagens** de erro amigáveis
- **Loading states** informativos
## 📞 Suporte
Para dúvidas ou problemas com o catálogo:
- **WhatsApp:** (11) 99999-9999
- **E-mail:** contato@liberikids.com.br
---
**Liberi Kids - Moda Infantil** 👶✨

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

129
site/index.html Normal file
View File

@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Liberi Kids - Moda Infantil | Catálogo Online</title>
<meta name="description" content="Descubra as melhores roupas infantis na Liberi Kids. Moda moderna, confortável e estilosa para crianças.">
<!-- Favicon -->
<link rel="icon" type="image/png" href="assets/LogoLiberiKids.png">
<!-- CSS -->
<link rel="stylesheet" href="styles.css">
<!-- Font Awesome para ícones -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
</head>
<body>
<div class="page-wrapper">
<!-- Header Simples -->
<header class="header">
<div class="container">
<div class="header-content">
<div class="logo">
<img src="assets/LogoLiberiKids.png" alt="Liberi Kids" class="logo-img">
</div>
<div class="header-actions">
<button class="cart-btn" onclick="toggleCart()">
<i class="fas fa-shopping-cart"></i>
<span class="cart-count">0</span>
</button>
</div>
</div>
</div>
<!-- Filtros Simples -->
<section class="filters">
<div class="container">
<div class="filter-options">
<select id="marcaFilter">
<option value="">Todas as Marcas</option>
</select>
<select id="tamanhoFilter">
<option value="">Todos os Tamanhos</option>
<option value="P">P (2-4 anos)</option>
<option value="M">M (4-6 anos)</option>
<option value="GG">GG (8-10 anos)</option>
</select>
<select id="generoFilter">
<option value="">Todos</option>
<option value="menino">Menino</option>
<option value="menina">Menina</option>
<option value="unissex">Unissex</option>
</select>
</div>
</div>
</section>
<!-- Produtos -->
<section id="produtos" class="produtos">
<div class="container">
<h2>Nossos Produtos</h2>
<div class="loading" id="loading">
<i class="fas fa-spinner fa-spin"></i>
<p>Carregando produtos...</p>
</div>
<div class="produtos-grid" id="produtosGrid">
<!-- Produtos serão carregados dinamicamente -->
</div>
<div class="no-products" id="noProducts" style="display: none;">
<i class="fas fa-search"></i>
<h3>Nenhum produto encontrado</h3>
<p>Tente ajustar os filtros ou volte mais tarde para ver novos produtos.</p>
</div>
</div>
</section>
</div>
<!-- Carrinho Lateral -->
<div class="cart-sidebar" id="cartSidebar">
<h3><i class="fas fa-shopping-cart"></i> Seu Carrinho</h3>
<button onclick="toggleCart()" class="close-cart">
<i class="fas fa-times"></i>
</button>
</div>
<div class="cart-content" id="cartContent">
<div class="empty-cart">
<i class="fas fa-shopping-cart"></i>
<p>Seu carrinho está vazio</p>
<span>Adicione produtos para começar!</span>
</div>
</div>
<div class="cart-footer" id="cartFooter" style="display: none;">
<div class="cart-total">
<strong>Total: R$ <span id="cartTotal">0,00</span></strong>
</div>
<button class="checkout-btn" onclick="finalizarPedido()">
<i class="fab fa-whatsapp"></i>
Finalizar Pedido
</button>
</div>
</div>
<!-- Overlay -->
<div class="overlay" id="overlay" onclick="toggleCart()"></div>
<!-- WhatsApp Flutuante -->
<div class="whatsapp-float" onclick="abrirWhatsApp()">
<i class="fab fa-whatsapp"></i>
<div class="whatsapp-tooltip">
<strong>Maiara</strong><br>
Fale conosco!
</div>
</div>
<!-- JavaScript -->
<script src="script.js"></script>
</body>
</html>

17
site/logo.svg Normal file
View File

@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
<!-- Fundo circular -->
<circle cx="200" cy="200" r="180" fill="#f8f9fa" stroke="#333" stroke-width="8"/>
<!-- Lupa -->
<circle cx="200" cy="180" r="120" fill="none" stroke="#333" stroke-width="6"/>
<line x1="290" y1="270" x2="340" y2="320" stroke="#8B4513" stroke-width="12" stroke-linecap="round"/>
<!-- Texto Liberi -->
<text x="200" y="160" text-anchor="middle" font-family="Arial, sans-serif" font-size="36" font-weight="bold" fill="#FF69B4">Liberi</text>
<!-- Texto KIDS -->
<text x="200" y="200" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="bold" fill="#87CEEB">KIDS</text>
<!-- Texto "moda infantil" -->
<text x="200" y="320" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-style="italic" fill="#333">moda infantil</text>
</svg>

After

Width:  |  Height:  |  Size: 895 B

802
site/script.js Normal file
View File

@@ -0,0 +1,802 @@
// Configurações
const CONFIG = {
API_BASE_URL: 'http://localhost:5000/api',
WHATSAPP_NUMBER: '5543999762754', // Número da Maiara
VENDEDORA_NOME: 'Maiara',
EVOLUTION_API: {
BASE_URL: 'https://criadordigital-evolution.jesdfs.easypanel.host',
INSTANCE_NAME: 'Tiago',
API_KEY: 'DBDF609168B1-48A3-8A4A-5E50D0300F2C'
}
};
// Estado global
let produtos = [];
let carrinho = [];
let filtros = {
marca: '',
tamanho: '',
genero: ''
};
// Inicialização
document.addEventListener('DOMContentLoaded', function() {
carregarProdutos();
inicializarEventListeners();
atualizarContadorCarrinho();
});
// Event Listeners
function inicializarEventListeners() {
// Filtros
document.getElementById('marcaFilter').addEventListener('change', aplicarFiltros);
document.getElementById('tamanhoFilter').addEventListener('change', aplicarFiltros);
document.getElementById('generoFilter').addEventListener('change', aplicarFiltros);
// Smooth scroll para links de navegação
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
}
// Função para carregar produtos do banco de dados
async function carregarProdutos() {
const loading = document.getElementById('loading');
const grid = document.getElementById('produtosGrid');
const noProducts = document.getElementById('noProducts');
try {
loading.style.display = 'block';
// Buscar produtos da API
const response = await fetch(`${CONFIG.API_BASE_URL}/catalogo/produtos`);
if (!response.ok) {
throw new Error('Erro ao buscar produtos');
}
const data = await response.json();
console.log('Dados recebidos da API:', data); // Debug
produtos = data.data || data || [];
loading.style.display = 'none';
if (produtos.length === 0) {
noProducts.style.display = 'block';
grid.innerHTML = '';
} else {
noProducts.style.display = 'none';
popularFiltros();
renderizarProdutos();
}
} catch (error) {
console.error('Erro ao carregar produtos:', error);
loading.style.display = 'none';
noProducts.style.display = 'block';
grid.innerHTML = '';
} finally {
mostrarLoading(false);
}
}
// Mostrar/ocultar loading
function mostrarLoading(show) {
const loading = document.getElementById('loading');
const grid = document.getElementById('produtosGrid');
if (show) {
loading.style.display = 'block';
grid.style.display = 'none';
} else {
loading.style.display = 'none';
grid.style.display = 'grid';
}
}
// Mostrar erro
function mostrarErro(mensagem) {
const grid = document.getElementById('produtosGrid');
grid.innerHTML = `
<div style="grid-column: 1 / -1; text-align: center; padding: 3rem; color: #dc3545;">
<i class="fas fa-exclamation-triangle" style="font-size: 3rem; margin-bottom: 1rem;"></i>
<h3>Ops! Algo deu errado</h3>
<p>${mensagem}</p>
<button onclick="carregarProdutos()" style="margin-top: 1rem; padding: 0.5rem 1rem; background: #667eea; color: white; border: none; border-radius: 5px; cursor: pointer;">
Tentar Novamente
</button>
</div>
`;
}
// Renderizar produtos
function renderizarProdutos(produtosList = produtos) {
const grid = document.getElementById('produtosGrid');
const noProducts = document.getElementById('noProducts');
console.log('Renderizando produtos:', produtosList); // Debug
if (!produtosList || produtosList.length === 0) {
grid.style.display = 'none';
noProducts.style.display = 'block';
return;
}
grid.style.display = 'grid';
noProducts.style.display = 'none';
grid.innerHTML = produtosList.map(produto => {
console.log('Renderizando produto individual:', produto); // Debug
// Pegar a primeira variação disponível para mostrar
const variacao = produto.variacoes && produto.variacoes.length > 0 ? produto.variacoes[0] : null;
const temEstoque = produto.estoque_total > 0 || (variacao && variacao.quantidade > 0);
const preco = produto.valor_revenda || produto.preco_venda || 0;
return `
<div class="produto-card" data-id="${produto.id || ''}">
<div class="produto-image">
${produto.foto_url ?
`<img src="http://localhost:5000${produto.foto_url}" alt="${produto.nome || 'Produto'}" onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';">
<div class="placeholder-img" style="display: none;"><i class="fas fa-tshirt"></i></div>` :
variacao && variacao.foto_url ?
`<img src="http://localhost:5000${variacao.foto_url}" alt="${produto.nome || 'Produto'}" onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';">
<div class="placeholder-img" style="display: none;"><i class="fas fa-tshirt"></i></div>` :
`<div class="placeholder-img"><i class="fas fa-tshirt"></i></div>`
}
${!temEstoque ? '<div class="produto-sem-estoque">Sem Estoque</div>' : ''}
</div>
<div class="produto-info">
<div class="produto-header">
<h3 class="produto-nome">${produto.marca ? produto.marca + ' - ' : ''}${produto.nome || 'Produto sem nome'}</h3>
${produto.id_produto ? `<span class="produto-codigo">Cód: ${produto.id_produto}</span>` : ''}
</div>
<div class="produto-badges">
${variacao && variacao.tamanho ? `<span class="produto-badge badge-tamanho">${variacao.tamanho}</span>` : ''}
${variacao && variacao.cor ? `<span class="produto-badge badge-cor" style="background-color: ${getCorBadge(variacao.cor)}">${variacao.cor}</span>` : ''}
${produto.genero ? `<span class="produto-badge badge-genero">${formatarGenero(produto.genero)}</span>` : ''}
${produto.estacao ? `<span class="produto-badge badge-estacao">${formatarEstacao(produto.estacao)}</span>` : ''}
</div>
<div class="produto-detalhes">
${produto.fornecedor ? `<small>Fornecedor: ${produto.fornecedor}</small>` : ''}
${produto.estoque_total ? `<small>Estoque: ${produto.estoque_total} unidades</small>` : ''}
${variacao && !produto.estoque_total ? `<small>Estoque: ${variacao.quantidade || 0} unidades</small>` : ''}
</div>
<div class="produto-preco">R$ ${formatarPreco(preco)}</div>
<button class="add-to-cart" onclick="adicionarAoCarrinho(${produto.id || 0})" ${!temEstoque ? 'disabled' : ''}>
<i class="fas fa-cart-plus"></i> ${temEstoque ? 'Adicionar ao Carrinho' : 'Sem Estoque'}
</button>
</div>
</div>
`;
}).join('');
}
// Formatadores
function formatarPreco(preco) {
return parseFloat(preco || 0).toLocaleString('pt-BR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
function formatarGenero(genero) {
const generos = {
'masculino': 'Menino',
'feminino': 'Menina',
'unissex': 'Unissex'
};
return generos[genero] || genero || 'Unissex';
}
function formatarEstacao(estacao) {
const estacoes = {
'verao': 'Verão',
'inverno': 'Inverno',
'outono': 'Outono',
'primavera': 'Primavera'
};
return estacoes[estacao] || estacao || 'Meia Estação';
}
function getCorBadge(cor) {
const cores = {
'azul': '#c0daf3',
'rosa': '#ecbad7',
'amarelo': '#f9f295',
'verde': '#90ee90',
'vermelho': '#ffb3ba',
'branco': '#f6f4e6',
'preto': '#464444'
};
return cores[cor?.toLowerCase()] || '#ddd9c7';
}
function formatarGenero(genero) {
const generos = {
'menino': 'Menino',
'menina': 'Menina',
'unissex': 'Unissex'
};
return generos[genero] || 'Unissex';
}
function formatarEstacao(estacao) {
const estacoes = {
'verao': 'Verão',
'inverno': 'Inverno',
'meia-estacao': 'Meia Estação'
};
return estacoes[estacao] || 'Meia Estação';
}
// Filtros
function aplicarFiltros() {
filtros.categoria = document.getElementById('categoriaFilter').value;
filtros.tamanho = document.getElementById('tamanhoFilter').value;
filtros.genero = document.getElementById('generoFilter').value;
let produtosFiltrados = produtos.filter(produto => {
const matchCategoria = !filtros.categoria ||
produto.nome.toLowerCase().includes(filtros.categoria.toLowerCase()) ||
(produto.categoria && produto.categoria.toLowerCase().includes(filtros.categoria.toLowerCase()));
const matchTamanho = !filtros.tamanho || produto.tamanho === filtros.tamanho;
const matchGenero = !filtros.genero || produto.genero === filtros.genero;
return matchCategoria && matchTamanho && matchGenero;
});
renderizarProdutos(produtosFiltrados);
}
function limparFiltros() {
document.getElementById('categoriaFilter').value = '';
document.getElementById('tamanhoFilter').value = '';
document.getElementById('generoFilter').value = '';
filtros = { categoria: '', tamanho: '', genero: '' };
renderizarProdutos(produtos);
}
// Carrinho de Compras
function adicionarAoCarrinho(produtoId) {
const produto = produtos.find(p => p.id === produtoId);
if (!produto) return;
const itemExistente = carrinho.find(item => item.id === produtoId);
if (itemExistente) {
itemExistente.quantidade += 1;
} else {
carrinho.push({
id: produto.id,
nome: produto.nome,
preco: parseFloat(produto.preco_venda),
tamanho: produto.tamanho,
genero: produto.genero,
imagem: produto.imagem,
quantidade: 1
});
}
atualizarCarrinho();
mostrarNotificacao('Produto adicionado ao carrinho!', 'success');
// Animação do botão
const btn = event.target.closest('.add-to-cart');
btn.style.transform = 'scale(0.95)';
setTimeout(() => {
btn.style.transform = 'scale(1)';
}, 150);
}
function removerDoCarrinho(produtoId) {
carrinho = carrinho.filter(item => item.id !== produtoId);
atualizarCarrinho();
mostrarNotificacao('Produto removido do carrinho', 'info');
}
function alterarQuantidade(produtoId, novaQuantidade) {
if (novaQuantidade <= 0) {
removerDoCarrinho(produtoId);
return;
}
const item = carrinho.find(item => item.id === produtoId);
if (item) {
item.quantidade = novaQuantidade;
atualizarCarrinho();
}
}
function atualizarCarrinho() {
atualizarContadorCarrinho();
renderizarCarrinho();
atualizarTotalCarrinho();
}
function atualizarContadorCarrinho() {
const contador = document.querySelector('.cart-count');
const totalItens = carrinho.reduce((total, item) => total + item.quantidade, 0);
contador.textContent = totalItens;
// Animação do contador
if (totalItens > 0) {
contador.style.display = 'flex';
contador.style.animation = 'pulse 0.3s ease';
} else {
contador.style.display = 'none';
}
}
function renderizarCarrinho() {
const cartContent = document.getElementById('cartContent');
const cartFooter = document.getElementById('cartFooter');
if (carrinho.length === 0) {
cartContent.innerHTML = `
<div class="empty-cart">
<i class="fas fa-shopping-cart"></i>
<p>Seu carrinho está vazio</p>
<span>Adicione produtos para começar!</span>
</div>
`;
cartFooter.style.display = 'none';
return;
}
cartContent.innerHTML = carrinho.map(item => `
<div class="cart-item">
<div class="cart-item-image">
${item.imagem ?
`<img src="${item.imagem}" alt="${item.nome}" style="width: 100%; height: 100%; object-fit: cover; border-radius: 8px;">` :
`<i class="fas fa-tshirt"></i>`
}
</div>
<div class="cart-item-info">
<div class="cart-item-name">${item.nome}</div>
<div class="cart-item-details">${item.tamanho}${formatarGenero(item.genero)}</div>
<div class="cart-item-price">R$ ${formatarPreco(item.preco)}</div>
</div>
<div class="cart-item-actions">
<button class="qty-btn" onclick="alterarQuantidade(${item.id}, ${item.quantidade - 1})">
<i class="fas fa-minus"></i>
</button>
<span style="margin: 0 0.5rem; font-weight: 600;">${item.quantidade}</span>
<button class="qty-btn" onclick="alterarQuantidade(${item.id}, ${item.quantidade + 1})">
<i class="fas fa-plus"></i>
</button>
<button class="remove-item" onclick="removerDoCarrinho(${item.id})">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
`).join('');
cartFooter.style.display = 'block';
}
function atualizarTotalCarrinho() {
const total = carrinho.reduce((sum, item) => sum + (item.preco * item.quantidade), 0);
const totalElement = document.getElementById('cartTotal');
if (totalElement) {
totalElement.textContent = formatarPreco(total);
}
}
function toggleCart() {
const sidebar = document.getElementById('cartSidebar');
const overlay = document.getElementById('overlay');
sidebar.classList.toggle('active');
overlay.classList.toggle('active');
if (sidebar.classList.contains('active')) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'auto';
}
}
// Finalizar Pedido - WhatsApp
function finalizarPedido() {
if (carrinho.length === 0) {
mostrarNotificacao('Seu carrinho está vazio!', 'warning');
return;
}
const total = carrinho.reduce((sum, item) => sum + (item.preco * item.quantidade), 0);
const totalItens = carrinho.reduce((sum, item) => sum + item.quantidade, 0);
let mensagem = `🛍️ *NOVO PEDIDO - LIBERI KIDS*\n\n`;
mensagem += `👋 Olá ${CONFIG.VENDEDORA_NOME}! Gostaria de fazer um pedido:\n\n`;
mensagem += `📦 *ITENS DO PEDIDO:*\n`;
carrinho.forEach((item, index) => {
mensagem += `${index + 1}. *${item.nome}*\n`;
mensagem += ` • Tamanho: ${item.tamanho}\n`;
mensagem += ` • Gênero: ${formatarGenero(item.genero)}\n`;
mensagem += ` • Quantidade: ${item.quantidade}x\n`;
mensagem += ` • Preço unitário: R$ ${formatarPreco(item.preco)}\n`;
mensagem += ` • Subtotal: R$ ${formatarPreco(item.preco * item.quantidade)}\n\n`;
});
mensagem += `📊 *RESUMO DO PEDIDO:*\n`;
mensagem += `• Total de itens: ${totalItens}\n`;
mensagem += `• *Valor total: R$ ${formatarPreco(total)}*\n\n`;
mensagem += `📱 Pedido feito através do catálogo online da Liberi Kids\n`;
mensagem += `🕐 ${new Date().toLocaleString('pt-BR')}\n\n`;
mensagem += `Aguardo retorno para confirmar o pedido e combinar a entrega! 😊`;
// Codificar mensagem para URL
const mensagemCodificada = encodeURIComponent(mensagem);
const urlWhatsApp = `https://wa.me/${CONFIG.WHATSAPP_NUMBER}?text=${mensagemCodificada}`;
// Abrir WhatsApp
window.open(urlWhatsApp, '_blank');
// Limpar carrinho após envio
setTimeout(() => {
if (confirm('Pedido enviado! Deseja limpar o carrinho?')) {
carrinho = [];
atualizarCarrinho();
toggleCart();
mostrarNotificacao('Pedido enviado com sucesso!', 'success');
}
}, 1000);
}
// Notificações
function mostrarNotificacao(mensagem, tipo = 'info') {
// Remover notificação existente
const existente = document.querySelector('.notification');
if (existente) {
existente.remove();
}
const notification = document.createElement('div');
notification.className = `notification notification-${tipo}`;
notification.innerHTML = `
<div style="display: flex; align-items: center; gap: 0.5rem;">
<i class="fas fa-${getIconeNotificacao(tipo)}"></i>
<span>${mensagem}</span>
</div>
`;
// Estilos da notificação
Object.assign(notification.style, {
position: 'fixed',
top: '100px',
right: '20px',
background: getCorNotificacao(tipo),
color: 'white',
padding: '1rem 1.5rem',
borderRadius: '8px',
boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
zIndex: '3000',
animation: 'slideInRight 0.3s ease',
maxWidth: '300px'
});
document.body.appendChild(notification);
// Remover após 3 segundos
setTimeout(() => {
notification.style.animation = 'slideOutRight 0.3s ease';
setTimeout(() => notification.remove(), 300);
}, 3000);
}
function getIconeNotificacao(tipo) {
const icones = {
'success': 'check-circle',
'error': 'exclamation-circle',
'warning': 'exclamation-triangle',
'info': 'info-circle'
};
return icones[tipo] || 'info-circle';
}
function getCorNotificacao(tipo) {
const cores = {
'success': '#10b981',
'error': '#ef4444',
'warning': '#f59e0b',
'info': '#3b82f6'
};
return cores[tipo] || '#3b82f6';
}
// Adicionar animações CSS dinamicamente
const style = document.createElement('style');
style.textContent = `
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOutRight {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
`;
document.head.appendChild(style);
// Fechar carrinho ao clicar fora
document.addEventListener('click', function(e) {
const sidebar = document.getElementById('cartSidebar');
const cartBtn = document.querySelector('.cart-btn');
if (sidebar.classList.contains('active') &&
!sidebar.contains(e.target) &&
!cartBtn.contains(e.target)) {
toggleCart();
}
});
// Scroll suave para seções
function scrollToSection(sectionId) {
const section = document.getElementById(sectionId);
if (section) {
section.scrollIntoView({ behavior: 'smooth' });
}
}
// Função para abrir WhatsApp
async function abrirWhatsApp() {
const numero = CONFIG.WHATSAPP_NUMBER;
const nome = CONFIG.VENDEDORA_NOME;
const mensagem = `Olá ${nome}! Vim através do catálogo online da Liberi Kids e gostaria de saber mais sobre os produtos. Pode me ajudar?`;
try {
// Tentar enviar via Evolution API primeiro
await enviarMensagemEvolution(mensagem);
mostrarNotificacao('Mensagem enviada via WhatsApp!');
} catch (error) {
console.error('Erro ao enviar via Evolution API:', error);
// Fallback para WhatsApp Web
const mensagemCodificada = encodeURIComponent(mensagem);
const urlWhatsApp = `https://wa.me/${numero}?text=${mensagemCodificada}`;
window.open(urlWhatsApp, '_blank');
}
}
// Popular filtros dinamicamente
function popularFiltros() {
// Marcas únicas
const marcas = [...new Set(produtos.map(p => p.marca).filter(Boolean))];
const marcaSelect = document.getElementById('marcaFilter');
marcaSelect.innerHTML = '<option value="">Todas as Marcas</option>';
marcas.forEach(marca => {
marcaSelect.innerHTML += `<option value="${marca}">${marca}</option>`;
});
// Tamanhos únicos das variações
const tamanhos = [...new Set(produtos.flatMap(p =>
p.variacoes?.map(v => v.tamanho) || []
).filter(Boolean))];
const tamanhoSelect = document.getElementById('tamanhoFilter');
tamanhoSelect.innerHTML = '<option value="">Todos os Tamanhos</option>';
tamanhos.forEach(tamanho => {
tamanhoSelect.innerHTML += `<option value="${tamanho}">${tamanho}</option>`;
});
// Gêneros únicos
const generos = [...new Set(produtos.map(p => p.genero).filter(Boolean))];
const generoSelect = document.getElementById('generoFilter');
generoSelect.innerHTML = '<option value="">Todos</option>';
generos.forEach(genero => {
generoSelect.innerHTML += `<option value="${genero}">${formatarGenero(genero)}</option>`;
});
}
// Aplicar filtros
function aplicarFiltros() {
filtros.marca = document.getElementById('marcaFilter').value;
filtros.tamanho = document.getElementById('tamanhoFilter').value;
filtros.genero = document.getElementById('generoFilter').value;
const produtosFiltrados = produtos.filter(produto => {
// Filtro por marca
if (filtros.marca && produto.marca !== filtros.marca) {
return false;
}
// Filtro por gênero
if (filtros.genero && produto.genero !== filtros.genero) {
return false;
}
// Filtro por tamanho (verifica nas variações)
if (filtros.tamanho) {
const temTamanho = produto.variacoes?.some(v => v.tamanho === filtros.tamanho);
if (!temTamanho) {
return false;
}
}
return true;
});
renderizarProdutos(produtosFiltrados);
}
// Funções do carrinho
function adicionarAoCarrinho(produtoId) {
const produto = produtos.find(p => p.id === produtoId);
if (!produto) return;
const itemExistente = carrinho.find(item => item.id === produtoId);
if (itemExistente) {
itemExistente.quantidade++;
} else {
carrinho.push({
id: produto.id,
nome: `${produto.marca} - ${produto.nome}`,
preco: produto.valor_revenda,
quantidade: 1,
foto: produto.foto_url || (produto.variacoes?.[0]?.foto_url)
});
}
atualizarContadorCarrinho();
mostrarNotificacao('Produto adicionado ao carrinho!');
}
function atualizarContadorCarrinho() {
const contador = document.querySelector('.cart-count');
const totalItens = carrinho.reduce((total, item) => total + item.quantidade, 0);
contador.textContent = totalItens;
}
function mostrarNotificacao(mensagem) {
const notificacao = document.createElement('div');
notificacao.className = 'notificacao';
notificacao.textContent = mensagem;
notificacao.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #25d366;
color: white;
padding: 1rem 1.5rem;
border-radius: 10px;
z-index: 9999;
animation: slideIn 0.3s ease;
`;
document.body.appendChild(notificacao);
setTimeout(() => {
notificacao.remove();
}, 3000);
}
function toggleCart() {
const cartSidebar = document.getElementById('cartSidebar');
const overlay = document.getElementById('overlay');
cartSidebar.classList.toggle('active');
overlay.classList.toggle('active');
if (cartSidebar.classList.contains('active')) {
renderizarCarrinho();
}
}
function renderizarCarrinho() {
const cartContent = document.querySelector('.cart-content');
const cartTotal = document.querySelector('.cart-total');
if (carrinho.length === 0) {
cartContent.innerHTML = `
<div style="text-align: center; padding: 2rem; color: #666;">
<i class="fas fa-shopping-cart" style="font-size: 3rem; margin-bottom: 1rem; opacity: 0.3;"></i>
<p>Seu carrinho está vazio</p>
</div>
`;
cartTotal.innerHTML = '<strong>Total: R$ 0,00</strong>';
return;
}
const total = carrinho.reduce((sum, item) => sum + (item.preco * item.quantidade), 0);
cartContent.innerHTML = carrinho.map(item => `
<div class="cart-item">
<div class="item-info">
<h4>${item.nome}</h4>
<p>R$ ${formatarPreco(item.preco)} x ${item.quantidade}</p>
</div>
<button class="remove-item" onclick="removerDoCarrinho('${item.id}')">
<i class="fas fa-trash"></i>
</button>
</div>
`).join('');
cartTotal.innerHTML = `<strong>Total: R$ ${formatarPreco(total)}</strong>`;
}
function removerDoCarrinho(produtoId) {
const index = carrinho.findIndex(item => item.id === produtoId);
if (index > -1) {
carrinho.splice(index, 1);
atualizarContadorCarrinho();
renderizarCarrinho();
}
}
async function finalizarPedido() {
if (carrinho.length === 0) {
mostrarNotificacao('Adicione produtos ao carrinho primeiro!');
return;
}
const total = carrinho.reduce((sum, item) => sum + (item.preco * item.quantidade), 0);
const itens = carrinho.map(item => `${item.quantidade}x ${item.nome} - R$ ${formatarPreco(item.preco)}`).join('\n');
const mensagem = `🛍️ *Pedido Liberi Kids*\n\n${itens}\n\n💰 *Total: R$ ${formatarPreco(total)}*\n\nGostaria de finalizar este pedido!`;
try {
// Tentar enviar via Evolution API primeiro
await enviarMensagemEvolution(mensagem);
mostrarNotificacao('Pedido enviado via WhatsApp!');
// Limpar carrinho após envio
carrinho = [];
atualizarContadorCarrinho();
renderizarCarrinho();
toggleCart();
} catch (error) {
console.error('Erro ao enviar via Evolution API:', error);
// Fallback para WhatsApp Web
const mensagemCodificada = encodeURIComponent(mensagem);
const urlWhatsApp = `https://wa.me/${CONFIG.WHATSAPP_NUMBER}?text=${mensagemCodificada}`;
window.open(urlWhatsApp, '_blank');
}
}
async function enviarMensagemEvolution(mensagem) {
const response = await fetch(`${CONFIG.EVOLUTION_API.BASE_URL}/message/sendText/${CONFIG.EVOLUTION_API.INSTANCE_NAME}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': CONFIG.EVOLUTION_API.API_KEY
},
body: JSON.stringify({
number: CONFIG.WHATSAPP_NUMBER,
text: mensagem
})
});
if (!response.ok) {
throw new Error('Falha ao enviar mensagem via Evolution API');
}
return await response.json();
}

1033
site/styles.css Normal file

File diff suppressed because it is too large Load Diff