Vendaweb-portal/components/checkout/DeliveryTaxModal.tsx

202 lines
8.4 KiB
TypeScript
Raw Normal View History

2026-01-08 12:09:16 +00:00
import React, { useState, useEffect } from "react";
import { X, Truck } from "lucide-react";
import { DeliveryTaxTable } from "../../src/services/order.service";
interface DeliveryTaxModalProps {
isOpen: boolean;
onClose: () => void;
onSelect: (deliveryTax: DeliveryTaxTable) => void;
deliveryTaxOptions: DeliveryTaxTable[];
isLoading: boolean;
}
const DeliveryTaxModal: React.FC<DeliveryTaxModalProps> = ({
isOpen,
onClose,
onSelect,
deliveryTaxOptions,
isLoading,
}) => {
const [selectedRow, setSelectedRow] = useState<number | null>(null);
useEffect(() => {
if (!isOpen) {
setSelectedRow(null);
}
}, [isOpen]);
if (!isOpen) return null;
const handleSelect = () => {
if (selectedRow !== null) {
const selected = deliveryTaxOptions[selectedRow];
onSelect(selected);
onClose();
}
};
const formatCurrency = (value: number) => {
return new Intl.NumberFormat("pt-BR", {
style: "currency",
currency: "BRL",
}).format(value);
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
<div className="bg-white rounded-3xl shadow-2xl w-full max-w-4xl max-h-[90vh] flex flex-col overflow-hidden">
{/* Header */}
<div className="p-6 bg-[#002147] text-white rounded-t-3xl relative overflow-hidden flex-shrink-0">
<div className="relative z-10 flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-12 h-12 bg-orange-500/20 rounded-2xl flex items-center justify-center">
<Truck className="w-6 h-6 text-orange-400" />
</div>
<div>
<h3 className="text-xl font-black">Opções de entrega para o endereço</h3>
<p className="text-xs text-orange-400 font-bold uppercase tracking-wider mt-0.5">
Selecione uma opção
</p>
</div>
</div>
<button
onClick={onClose}
className="w-10 h-10 flex items-center justify-center rounded-xl hover:bg-white/10 transition-colors"
>
<X className="w-5 h-5" />
</button>
</div>
<div className="absolute right-[-10%] top-[-10%] w-32 h-32 bg-orange-400/10 rounded-full blur-2xl"></div>
</div>
{/* Content */}
<div className="flex-1 overflow-hidden flex flex-col p-6">
{isLoading ? (
<div className="flex-1 flex items-center justify-center">
<div className="w-12 h-12 border-4 border-[#002147] border-t-transparent rounded-full animate-spin"></div>
</div>
) : deliveryTaxOptions.length === 0 ? (
<div className="flex-1 flex items-center justify-center">
<p className="text-slate-500 font-bold">Sem registros para serem exibidos.</p>
</div>
) : (
<>
{/* Desktop Table */}
<div className="hidden md:block flex-1 overflow-auto">
<table className="w-full border-collapse">
<thead className="bg-slate-50 sticky top-0">
<tr>
<th className="px-4 py-3 text-left text-xs font-black uppercase text-slate-600 tracking-wider border-b border-slate-200">
Filial
</th>
<th className="px-4 py-3 text-left text-xs font-black uppercase text-slate-600 tracking-wider border-b border-slate-200">
Transportadora
</th>
<th className="px-4 py-3 text-left text-xs font-black uppercase text-slate-600 tracking-wider border-b border-slate-200">
Cidade de Entrega
</th>
<th className="px-4 py-3 text-left text-xs font-black uppercase text-slate-600 tracking-wider border-b border-slate-200">
Prazo de Entrega
</th>
<th className="px-4 py-3 text-right text-xs font-black uppercase text-slate-600 tracking-wider border-b border-slate-200">
Valor Frete
</th>
</tr>
</thead>
<tbody>
{deliveryTaxOptions.map((option, index) => (
<tr
key={option.id}
onClick={() => setSelectedRow(index)}
className={`cursor-pointer transition-colors ${
selectedRow === index
? "bg-orange-50 border-l-4 border-orange-500"
: "hover:bg-slate-50"
}`}
>
<td className="px-4 py-3 text-sm font-bold text-slate-700 border-b border-slate-100">
{option.store}
</td>
<td className="px-4 py-3 text-sm font-bold text-slate-700 border-b border-slate-100">
{option.carrierName}
</td>
<td className="px-4 py-3 text-sm font-bold text-slate-700 border-b border-slate-100">
{option.cityName}
</td>
<td className="px-4 py-3 text-sm font-bold text-slate-700 border-b border-slate-100">
{option.deliveryTime}
</td>
<td className="px-4 py-3 text-right text-sm font-black text-[#002147] border-b border-slate-100">
{formatCurrency(option.deliveryValue)}
</td>
</tr>
))}
</tbody>
</table>
</div>
{/* Mobile Cards */}
<div className="md:hidden flex-1 overflow-auto space-y-3">
{deliveryTaxOptions.map((option, index) => (
<div
key={option.id}
onClick={() => setSelectedRow(index)}
className={`p-4 rounded-2xl border-2 transition-all cursor-pointer ${
selectedRow === index
? "bg-orange-50 border-orange-500"
: "bg-slate-50 border-slate-200 hover:border-orange-300"
}`}
>
<div className="flex items-start justify-between mb-2">
<div>
<h4 className="font-black text-slate-800">{option.carrierName}</h4>
<p className="text-xs text-slate-500">{option.cityName}</p>
</div>
<div className="text-right">
<p className="text-lg font-black text-[#002147]">
{formatCurrency(option.deliveryValue)}
</p>
</div>
</div>
<div className="grid grid-cols-2 gap-2 text-xs">
<div>
<span className="text-slate-500">Filial: </span>
<span className="font-bold text-slate-700">{option.store}</span>
</div>
<div>
<span className="text-slate-500">Prazo: </span>
<span className="font-bold text-slate-700">{option.deliveryTime}</span>
</div>
</div>
</div>
))}
</div>
</>
)}
</div>
{/* Footer */}
<div className="p-6 border-t border-slate-200 flex-shrink-0 flex items-center justify-end gap-3">
<button
onClick={onClose}
className="px-6 py-3 rounded-xl font-bold text-slate-700 hover:bg-slate-100 transition-colors"
>
Cancelar
</button>
<button
onClick={handleSelect}
disabled={selectedRow === null || isLoading}
className="px-6 py-3 rounded-xl font-black bg-[#002147] text-white hover:bg-[#001a36] transition-all shadow-lg shadow-[#002147]/20 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed"
>
Selecionar
</button>
</div>
</div>
</div>
);
};
export default DeliveryTaxModal;