156 lines
4.9 KiB
JavaScript
156 lines
4.9 KiB
JavaScript
import React, { useEffect, useMemo, useState } from 'react';
|
|
import {
|
|
FiRefreshCw,
|
|
FiClipboard,
|
|
FiClock,
|
|
FiPhone,
|
|
FiMapPin,
|
|
FiPackage
|
|
} from 'react-icons/fi';
|
|
import toast from 'react-hot-toast';
|
|
import '../styles/pedidos-catalogo.css';
|
|
|
|
const formatarMoeda = (valor) => {
|
|
return (Number(valor) || 0).toLocaleString('pt-BR', {
|
|
style: 'currency',
|
|
currency: 'BRL'
|
|
});
|
|
};
|
|
|
|
const formatarData = (dataISO) => {
|
|
if (!dataISO) return '-';
|
|
try {
|
|
return new Date(dataISO).toLocaleString('pt-BR', {
|
|
dateStyle: 'short',
|
|
timeStyle: 'short'
|
|
});
|
|
} catch (error) {
|
|
return dataISO;
|
|
}
|
|
};
|
|
|
|
const PedidosCatalogo = () => {
|
|
const [pedidos, setPedidos] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
|
|
const carregarPedidos = async () => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const response = await fetch('/api/catalogo/pedidos');
|
|
if (!response.ok) {
|
|
throw new Error('Erro ao carregar pedidos');
|
|
}
|
|
const data = await response.json();
|
|
setPedidos(Array.isArray(data) ? data : []);
|
|
} catch (err) {
|
|
console.error('Erro ao carregar pedidos:', err);
|
|
setError('Não foi possível carregar os pedidos.');
|
|
toast.error('Erro ao carregar pedidos do catálogo.');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
carregarPedidos();
|
|
}, []);
|
|
|
|
const pedidosOrdenados = useMemo(() => {
|
|
return [...pedidos].sort((a, b) => new Date(b.createdAt || 0) - new Date(a.createdAt || 0));
|
|
}, [pedidos]);
|
|
|
|
return (
|
|
<div className="pedidos-catalogo-page fade-in">
|
|
<div className="page-header">
|
|
<div>
|
|
<h1>Pedidos do Catálogo</h1>
|
|
<p>Pedidos registrados automaticamente através do catálogo online</p>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="btn btn-secondary"
|
|
onClick={carregarPedidos}
|
|
disabled={loading}
|
|
>
|
|
<FiRefreshCw />
|
|
{loading ? 'Atualizando...' : 'Atualizar'}
|
|
</button>
|
|
</div>
|
|
|
|
{error && (
|
|
<div className="alert alert-error">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
{pedidosOrdenados.length === 0 && !loading ? (
|
|
<div className="empty-state">
|
|
<FiClipboard size={48} />
|
|
<p>Nenhum pedido registrado ainda</p>
|
|
<span>Assim que um cliente finalizar uma compra no catálogo, o pedido aparecerá aqui.</span>
|
|
</div>
|
|
) : (
|
|
<div className="pedidos-lista">
|
|
{pedidosOrdenados.map((pedido) => (
|
|
<div key={pedido.id} className="pedido-card">
|
|
<header className="pedido-card-header">
|
|
<div className="pedido-id">
|
|
<FiClipboard />
|
|
<span>{pedido.codigo || pedido.id || 'Pedido sem ID'}</span>
|
|
</div>
|
|
<div className="pedido-data">
|
|
<FiClock />
|
|
<span>{formatarData(pedido.createdAt)}</span>
|
|
</div>
|
|
</header>
|
|
|
|
<section className="pedido-cliente">
|
|
<div className="cliente-nome">{pedido.cliente?.nome || 'Cliente não informado'}</div>
|
|
<div className="cliente-info">
|
|
<span><FiPhone /> {pedido.cliente?.whatsapp || 'Sem contato'}</span>
|
|
{pedido.cliente?.endereco && (
|
|
<span><FiMapPin /> {pedido.cliente.endereco}</span>
|
|
)}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="pedido-itens">
|
|
<h4>Itens</h4>
|
|
<div className="pedido-itens-lista">
|
|
{(pedido.itens || []).map((item, index) => (
|
|
<div key={`${pedido.id}-item-${index}`} className="pedido-item">
|
|
<div className="pedido-item-info">
|
|
<strong>{item.nome}</strong>
|
|
<div className="pedido-item-meta">
|
|
<span><FiPackage /> {item.codigo || 'Sem ID'}</span>
|
|
<span>Tam: {item.tamanho || '-'}</span>
|
|
<span>Cor: {item.cor || '-'}</span>
|
|
</div>
|
|
</div>
|
|
<div className="pedido-item-valores">
|
|
<span>{item.quantidade || 0} x {formatarMoeda(item.preco)}</span>
|
|
<strong>{formatarMoeda(item.subtotal)}</strong>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
<footer className="pedido-footer">
|
|
<div className="pedido-total">
|
|
<span>Total do pedido</span>
|
|
<strong>{formatarMoeda(pedido.total)}</strong>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PedidosCatalogo;
|