import React, { useState, useEffect } from ‘react’;
import {
Package,
ShoppingCart,
FileText,
Bell,
Plus,
Trash2,
Edit,
Search,
User,
Check,
X,
LogOut,
ChevronRight,
DollarSign,
Send,
Image as ImageIcon,
MessageCircle // Ícone do WhatsApp
} from ‘lucide-react’;
// — Dados Iniciais Mockados (Traduzidos) —
const INITIAL_PRODUCTS = [
];
export default function ProductCatalogApp() {
// — Estado —
const [role, setRole] = useState(‘admin’); // ‘admin’ | ‘customer’
const [activeTab, setActiveTab] = useState(‘products’);
// Configuração do WhatsApp do Admin (Para demonstração)
const ADMIN_PHONE_NUMBER = “5511999999999”; // Substitua pelo seu número real no formato internacional
// Estado dos Dados
const [products, setProducts] = useState(() => {
const saved = localStorage.getItem(‘mvp_products’);
return saved ? JSON.parse(saved) : INITIAL_PRODUCTS;
});
const [quotes, setQuotes] = useState(() => {
const saved = localStorage.getItem(‘mvp_quotes’);
return saved ? JSON.parse(saved) : [];
});
const [cart, setCart] = useState([]); // Array de { productId, quantity }
// Estado da UI
const [isModalOpen, setIsModalOpen] = useState(false);
const [currentProduct, setCurrentProduct] = useState(null); // Para edição
const [searchTerm, setSearchTerm] = useState(”);
const [notificationCount, setNotificationCount] = useState(0);
// — Efeitos —
useEffect(() => {
localStorage.setItem(‘mvp_products’, JSON.stringify(products));
}, [products]);
useEffect(() => {
localStorage.setItem(‘mvp_quotes’, JSON.stringify(quotes));
// Atualizar contagem de notificações (Orçamentos pendentes)
const pending = quotes.filter(q => q.status === ‘pending’).length;
setNotificationCount(pending);
}, [quotes]);
// — Ações: Produtos —
const handleSaveProduct = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const newProduct = {
id: currentProduct ? currentProduct.id : Date.now(),
name: formData.get(‘name’),
description: formData.get(‘description’),
image: formData.get(‘image’) || ‘https://placehold.co/400’, // Fallback
category: ‘Geral’
};
if (currentProduct) {
setProducts(products.map(p => p.id === newProduct.id ? newProduct : p));
} else {
setProducts([…products, newProduct]);
}
setIsModalOpen(false);
setCurrentProduct(null);
};
const handleDeleteProduct = (id) => {
if (confirm(‘Tem certeza que deseja excluir este produto?’)) {
setProducts(products.filter(p => p.id !== id));
}
};
// — Ações: Carrinho & Orçamentos —
const addToCart = (productId, qty) => {
const existing = cart.find(item => item.productId === productId);
if (existing) {
setCart(cart.map(item => item.productId === productId ? { …item, quantity: item.quantity + parseInt(qty) } : item));
} else {
setCart([…cart, { productId, quantity: parseInt(qty) }]);
}
alert(“Adicionado ao Pedido de Orçamento!”);
};
const submitQuoteRequest = () => {
if (cart.length === 0) return;
// 1. Criar o objeto do pedido internamente
const newQuote = {
id: Date.now(),
customerName: ‘Cliente Demo’,
status: ‘pending’, // pending -> priced -> sent
timestamp: new Date().toISOString(),
items: cart.map(c => {
const prod = products.find(p => p.id === c.productId);
return { …c, name: prod?.name, priceProposed: 0 };
})
};
// 2. Preparar Mensagem do WhatsApp
const whatsappMessage = `Olá! Gostaria de solicitar um orçamento:
*Cliente:* ${newQuote.customerName}
*ID do Pedido:* ${newQuote.id}
*Itens:*
${newQuote.items.map(item => `- ${item.quantity}x ${item.name}`).join(‘n’)}
Aguardo o retorno!`;
// 3. Gerar Link do WhatsApp
const whatsappUrl = `https://wa.me/${ADMIN_PHONE_NUMBER}?text=${encodeURIComponent(whatsappMessage)}`;
// 4. Salvar estado e abrir WhatsApp
setQuotes([newQuote, …quotes]);
setCart([]);
setActiveTab(‘my-quotes’);
// Abre o WhatsApp em nova aba
window.open(whatsappUrl, ‘_blank’);
alert(“Pedido registrado! Redirecionando para o WhatsApp…”);
};
// — Ações: Gestão de Orçamentos (Admin) —
const handlePriceUpdate = (quoteId, itemId, price) => {
setQuotes(quotes.map(q => {
if (q.id !== quoteId) return q;
return {
…q,
items: q.items.map(item => item.productId === itemId ? { …item, priceProposed: parseFloat(price) } : item)
};
}));
};
const submitPricing = (quoteId) => {
setQuotes(quotes.map(q => {
if (q.id !== quoteId) return q;
return { …q, status: ‘priced’, pricedAt: new Date().toISOString() };
}));
alert(“Orçamento enviado de volta para o cliente!”);
};
// — Auxiliares de Renderização —
const filteredProducts = products.filter(p =>
p.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
p.description.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
{/* Barra de Navegação Superior */}
{/* Navegação Lateral */}
{/* Área Principal de Conteúdo */}
{/* Alternador de Papel Mobile */}
{/* ADMIN: GESTÃO DE PRODUTOS */}
{role === ‘admin’ && activeTab === ‘products’ && (
setSearchTerm(e.target.value)}
/>
| Produto | Categoria | Ações |
|---|---|---|
|
{product.name} {product.description} |
{product.category} |
|
| Nenhum produto encontrado | ||
)}
{/* ADMIN: GESTÃO DE ORÇAMENTOS */}
{role === ‘admin’ && activeTab === ‘admin-quotes’ && (
{quotes.length === 0 ? (
Nenhum pedido de orçamento ainda.
) : (
quotes.map(quote => (
Solicitado em {new Date(quote.timestamp).toLocaleDateString(‘pt-BR’)}
{quote.status === ‘pending’ && (
)}
{quote.items.map(item => (
x{item.quantity}
{item.name}
Preço Unit.:
{quote.status === ‘pending’ ? (
R$
handlePriceUpdate(quote.id, item.productId, e.target.value)}
/>
) : (
R$ {item.priceProposed?.toFixed(2) || ‘0.00’}
)}
))}
{quote.status !== ‘pending’ && (
Valor Total Orçado
R$ {quote.items.reduce((acc, i) => acc + (i.priceProposed * i.quantity), 0).toFixed(2)}
)}
))
)}
)}
{/* CLIENTE: CATÁLOGO */}
{role === ‘customer’ && activeTab === ‘catalog’ && (
setSearchTerm(e.target.value)}
/>
{filteredProducts.map(product => (
))}
)}
{/* CLIENTE: CARRINHO */}
{role === ‘customer’ && activeTab === ‘cart’ && (
{cart.length === 0 ? (
Seu carrinho de orçamentos está vazio.
) : (
{cart.map((item, idx) => {
const prod = products.find(p => p.id === item.productId);
return (
{prod?.category}
Qtd: {item.quantity}
);
})}
Isso abrirá seu WhatsApp para enviar os detalhes ao vendedor.
)}
)}
{/* CLIENTE: STATUS DO ORÇAMENTO */}
{role === ‘customer’ && activeTab === ‘my-quotes’ && (
{quotes.filter(q => q.customerName === ‘Cliente Demo’).length === 0 ? (
Você ainda não enviou nenhum pedido.
) : (
quotes.filter(q => q.customerName === ‘Cliente Demo’).map(quote => (
ID PEDIDO: #{quote.id.toString().slice(-6)}
{new Date(quote.timestamp).toLocaleDateString(‘pt-BR’)}
{quote.items.map((item, i) => (
{item.quantity}x {item.name}
{quote.status === ‘priced’ ? (
R$ {(item.priceProposed * item.quantity).toFixed(2)}
) : (
—
)}
))}
{quote.status === ‘priced’ && (
Preço Total
R$ {quote.items.reduce((acc, i) => acc + (i.priceProposed * i.quantity), 0).toFixed(2)}
)}
))
)}
)}
{/* Modal Adicionar/Editar Produto */}
{isModalOpen && (
)}
);
}
// — Subcomponentes —
function SidebarItem({ icon: Icon, label, active, onClick, badge }) {
return (
);
}
function ProductCard({ product, onAdd }) {
const [qty, setQty] = useState(1);
return (
{product.category}
{product.description}
);
}
function StatusBadge({ status }) {
const styles = {
pending: ‘bg-yellow-100 text-yellow-700 border-yellow-200’,
priced: ‘bg-green-100 text-green-700 border-green-200’,
sent: ‘bg-blue-100 text-blue-700 border-blue-200’,
};
const labels = {
pending: ‘Aguardando Preço’,
priced: ‘Preço Disponível’,
sent: ‘Enviado’,
};
return (
{labels[status] || status}
);
}