202 lines
8.4 KiB
TypeScript
202 lines
8.4 KiB
TypeScript
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;
|
|
|
|
|