Vendaweb-portal/components/OrderItemsModal.tsx

208 lines
7.0 KiB
TypeScript

import React, { useState, useEffect } from "react";
import { formatCurrency } from "../utils/formatters";
import NoData from "./NoData";
interface OrderItem {
productId: number;
description: string;
package: string;
color?: string;
local: string;
quantity: number;
price: number;
subTotal: number;
}
interface OrderItemsModalProps {
isOpen: boolean;
onClose: () => void;
orderId: number;
orderItems: OrderItem[];
}
/**
* OrderItemsModal Component
* Modal para exibir os itens de um pedido
* Segue o padrão de estilização do ConfirmDialog
*/
const OrderItemsModal: React.FC<OrderItemsModalProps> = ({
isOpen,
onClose,
orderId,
orderItems,
}) => {
const [isAnimating, setIsAnimating] = useState(false);
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
if (isOpen) {
setShouldRender(true);
setTimeout(() => setIsAnimating(true), 10);
} else {
setIsAnimating(false);
const timer = setTimeout(() => setShouldRender(false), 300);
return () => clearTimeout(timer);
}
}, [isOpen]);
if (!shouldRender) return null;
const handleClose = () => {
setIsAnimating(false);
setTimeout(() => {
onClose();
}, 300);
};
return (
<div className="fixed inset-0 z-[200] flex items-center justify-center">
{/* Overlay */}
<div
className={`absolute inset-0 bg-[#001f3f]/60 backdrop-blur-sm transition-opacity duration-300 ${
isAnimating ? "opacity-100" : "opacity-0"
}`}
onClick={handleClose}
></div>
{/* Dialog */}
<div
className={`relative bg-white rounded-3xl shadow-2xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-hidden flex flex-col transform transition-all duration-300 ${
isAnimating ? "scale-100 opacity-100" : "scale-95 opacity-0"
}`}
>
{/* Header */}
<div className="p-6 bg-[#002147] text-white rounded-t-3xl relative overflow-hidden">
<div className="relative z-10">
<div className="flex items-center gap-3 mb-2">
<div className="w-12 h-12 bg-blue-500/20 rounded-2xl flex items-center justify-center">
<svg
className="w-6 h-6 text-blue-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
</div>
<div className="flex-1">
<h3 className="text-xl font-black">
Itens do pedido {orderId.toString()}
</h3>
<p className="text-xs text-blue-400 font-bold uppercase tracking-wider mt-0.5">
Detalhes
</p>
</div>
<button
onClick={handleClose}
className="p-2 text-white/70 hover:text-white hover:bg-white/10 rounded-lg transition-colors"
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
</div>
<div className="absolute right-[-10%] top-[-10%] w-32 h-32 bg-blue-400/10 rounded-full blur-2xl"></div>
</div>
{/* Content */}
<div className="p-6 overflow-y-auto flex-1">
{orderItems.length > 0 ? (
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-slate-50">
<tr>
{[
"Código",
"Descrição",
"Embalagem",
"Cor",
"Ambiente",
"P.Venda",
"Qtde",
"Valor Total",
].map((h) => (
<th
key={h}
className="px-4 py-3 text-[9px] font-black text-slate-400 uppercase tracking-widest text-left"
>
{h}
</th>
))}
</tr>
</thead>
<tbody className="divide-y divide-slate-50">
{orderItems.map((item, idx) => (
<tr key={idx} className="hover:bg-slate-50/50">
<td className="px-4 py-3 text-xs text-slate-600">
{item.productId}
</td>
<td className="px-4 py-3 text-xs text-slate-600">
{item.description}
</td>
<td className="px-4 py-3 text-xs text-slate-600">
{item.package}
</td>
<td className="px-4 py-3 text-xs text-slate-600">
{item.color || "-"}
</td>
<td className="px-4 py-3 text-xs text-slate-600">
{item.local}
</td>
<td className="px-4 py-3 text-xs text-slate-600 text-right">
{formatCurrency(item.price)}
</td>
<td className="px-4 py-3 text-xs text-slate-600 text-right">
{item.quantity.toFixed(3)}
</td>
<td className="px-4 py-3 text-xs font-bold text-slate-800 text-right">
{formatCurrency(item.subTotal)}
</td>
</tr>
))}
</tbody>
</table>
</div>
) : (
<div className="bg-white rounded-2xl border border-slate-100 overflow-hidden">
<NoData
title="Nenhum item encontrado"
description={`Não foram encontrados itens para o pedido #${orderId}. Verifique se o pedido possui itens cadastrados.`}
icon="file"
variant="outline"
/>
</div>
)}
</div>
{/* Actions */}
<div className="p-6 pt-0">
<button
onClick={handleClose}
className="w-full py-3 px-4 text-white font-black uppercase text-xs tracking-wider rounded-xl transition-all shadow-lg bg-blue-500 hover:bg-blue-600 shadow-blue-500/20 active:scale-95"
>
Fechar
</button>
</div>
</div>
</div>
);
};
export default OrderItemsModal;