Files
App-Estoque-LiberiKids/client/src/pages/PedidosCatalogo.js
2025-11-29 21:31:52 -03:00

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;