almeira-web/dripzone-app/src/app/admin/pedidos/page.tsx

1235 lines
61 KiB
TypeScript

'use client';
import React, { useState, useEffect } from 'react';
import {
ShoppingBag,
Truck,
CheckCircle2,
Clock,
Phone,
MapPin,
Search,
MessageCircle,
Send,
ShieldCheck,
Building2,
Navigation,
ExternalLink,
DollarSign,
Layers,
Sparkles,
Compass,
Check,
AlertCircle,
Edit3,
Trash2,
Plus,
X,
CreditCard,
User,
FileText,
Globe
} from 'lucide-react';
import { Order, OrderItem, Supplier, City } from '@/types';
import { formatCOP } from '@/lib/pricing-engine';
import { initClientTemplates, renderClientTemplate } from '@/lib/templates-client';
import { OptimizedImage } from '@/components/ui/OptimizedImage';
export default function AdminOrdersPage() {
const [orders, setOrders] = useState<Order[]>([]);
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
const [cities, setCities] = useState<City[]>([]);
const [activeTab, setActiveTab] = useState<'individual' | 'suppliers' | 'routes'>('individual');
const [search, setSearch] = useState('');
const [statusFilter, setStatusFilter] = useState<string>('all');
const [sourceFilter, setSourceFilter] = useState<'all' | 'whatsapp' | 'web'>('all');
const [toastMessage, setToastMessage] = useState<string | null>(null);
// Edit Order Modal State
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [editingOrder, setEditingOrder] = useState<Order | null>(null);
const [editCustomerName, setEditCustomerName] = useState('');
const [editCustomerPhone, setEditCustomerPhone] = useState('');
const [editAddress, setEditAddress] = useState('');
const [editCityId, setEditCityId] = useState('city-cali');
const [editCityName, setEditCityName] = useState('Cali');
const [editStatus, setEditStatus] = useState<Order['status']>('pending');
const [editPaymentMethodName, setEditPaymentMethodName] = useState('');
const [editTotalAmount, setEditTotalAmount] = useState(0);
const [editDepositAmount, setEditDepositAmount] = useState(10000);
const [editShippingCost, setEditShippingCost] = useState(0);
const [editNotes, setEditNotes] = useState('');
const [editItems, setEditItems] = useState<OrderItem[]>([]);
const [isSavingOrder, setIsSavingOrder] = useState(false);
// Delete Order Confirmation Modal State
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [orderToDelete, setOrderToDelete] = useState<Order | null>(null);
useEffect(() => {
fetchOrders();
fetchSuppliers();
fetchCities();
initClientTemplates();
}, []);
const fetchOrders = async () => {
try {
const r = await fetch('/api/orders');
const d = await r.json();
if (d.success && d.orders) {
setOrders(d.orders);
}
} catch (e) {
console.error('Error loading orders:', e);
}
};
const fetchSuppliers = async () => {
try {
const r = await fetch('/api/suppliers?all=true');
const d = await r.json();
if (d.success && d.suppliers) {
setSuppliers(d.suppliers);
}
} catch (e) {
console.error('Error loading suppliers:', e);
}
};
const fetchCities = async () => {
try {
const r = await fetch('/api/cities');
const d = await r.json();
if (d.success && d.cities) {
setCities(d.cities);
}
} catch (e) {
console.error('Error loading cities:', e);
}
};
const handleStatusChange = async (orderId: string, newStatus: Order['status']) => {
setOrders((prev) =>
prev.map((o) => (o.id === orderId ? { ...o, status: newStatus } : o))
);
try {
await fetch('/api/orders', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: orderId, status: newStatus }),
});
setToastMessage(`Estado de la orden #${orderId} actualizado a "${newStatus}".`);
setTimeout(() => setToastMessage(null), 4000);
} catch (e) {
console.error(e);
}
};
// Open Edit Order Modal
const handleOpenEditModal = (order: Order) => {
setEditingOrder(order);
setEditCustomerName(order.customerName);
setEditCustomerPhone(order.customerPhone);
setEditAddress(order.address);
setEditCityId(order.cityId);
setEditCityName(order.cityName);
setEditStatus(order.status);
setEditPaymentMethodName(order.paymentMethodName || 'Contraentrega');
setEditTotalAmount(order.totalAmount);
setEditDepositAmount(order.depositAmount);
setEditShippingCost(order.shippingCost || 0);
setEditNotes(order.notes || '');
setEditItems([...order.items]);
setIsEditModalOpen(true);
};
// Handle Edit Item in Modal
const handleItemChange = (index: number, field: keyof OrderItem, value: any) => {
const updated = [...editItems];
updated[index] = { ...updated[index], [field]: value };
// If changing supplierId, auto update supplierName and supplierPhone
if (field === 'supplierName') {
const foundSup = suppliers.find((s) => s.name === value || s.id === value);
if (foundSup) {
updated[index].supplierName = foundSup.name;
updated[index].supplierPhone = foundSup.phone;
}
}
setEditItems(updated);
// Auto update total amount if prices/quantities change
if (field === 'price' || field === 'quantity') {
const newSubtotal = updated.reduce((acc, curr) => acc + (curr.price || 0) * (curr.quantity || 1), 0);
setEditTotalAmount(newSubtotal + editShippingCost);
}
};
const handleRemoveItemFromEdit = (index: number) => {
const updated = editItems.filter((_, idx) => idx !== index);
setEditItems(updated);
const newSubtotal = updated.reduce((acc, curr) => acc + (curr.price || 0) * (curr.quantity || 1), 0);
setEditTotalAmount(newSubtotal + editShippingCost);
};
const handleAddItemToEdit = () => {
const defaultSup = suppliers[0] || { name: 'DIFUSIÓN JOVIC STORE', phone: '573167455877' };
const newItem: OrderItem = {
productId: `prod-manual-${Date.now()}`,
productName: 'Nuevo Modelo / Zapatilla',
brand: 'Nike',
size: '39',
quantity: 1,
price: 125000,
supplierPrice: 90000,
supplierName: defaultSup.name,
supplierPhone: defaultSup.phone,
image: 'https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?auto=format&fit=crop&w=800&q=80',
};
const updated = [...editItems, newItem];
setEditItems(updated);
const newSubtotal = updated.reduce((acc, curr) => acc + (curr.price || 0) * (curr.quantity || 1), 0);
setEditTotalAmount(newSubtotal + editShippingCost);
};
// Save Order Updates
const handleSaveOrderEdits = async (e: React.FormEvent) => {
e.preventDefault();
if (!editingOrder) return;
setIsSavingOrder(true);
const balanceDue = editTotalAmount - editDepositAmount;
const payload: Partial<Order> = {
id: editingOrder.id,
customerName: editCustomerName,
customerPhone: editCustomerPhone,
address: editAddress,
cityId: editCityId,
cityName: editCityName,
status: editStatus,
paymentMethodName: editPaymentMethodName,
totalAmount: editTotalAmount,
depositAmount: editDepositAmount,
shippingCost: editShippingCost,
balanceDue: balanceDue > 0 ? balanceDue : 0,
items: editItems,
notes: editNotes,
};
try {
const res = await fetch('/api/orders', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const data = await res.json();
if (data.success) {
setOrders((prev) =>
prev.map((o) => (o.id === editingOrder.id ? { ...o, ...payload } as Order : o))
);
setToastMessage(`✅ Orden #${editingOrder.id} modificada y guardada correctamente.`);
setTimeout(() => setToastMessage(null), 4000);
setIsEditModalOpen(false);
}
} catch (err) {
console.error('Error saving order edits:', err);
} finally {
setIsSavingOrder(false);
}
};
// Delete Order
const handleOpenDeleteModal = (order: Order) => {
setOrderToDelete(order);
setIsDeleteModalOpen(true);
};
const handleConfirmDeleteOrder = async () => {
if (!orderToDelete) return;
const targetId = orderToDelete.id;
try {
const res = await fetch(`/api/orders?id=${targetId}`, {
method: 'DELETE',
});
const data = await res.json();
if (data.success) {
setOrders((prev) => prev.filter((o) => o.id !== targetId));
setToastMessage(`🗑️ Orden #${targetId} eliminada correctamente.`);
setTimeout(() => setToastMessage(null), 4000);
}
} catch (err) {
console.error('Error deleting order:', err);
} finally {
setIsDeleteModalOpen(false);
setOrderToDelete(null);
}
};
// 1. Notificar separación individual a proveedor
const handleNotifySingleSupplier = (order: Order, item: OrderItem) => {
const supplierPhone = item.supplierPhone || '573167455877';
const supplierName = item.supplierName || 'Proveedor Mayorista';
const supplierCost = item.supplierPrice ? formatCOP(item.supplierPrice) : 'Precio Mayorista';
const message = renderClientTemplate('supplier_single_separation', {
proveedor_nombre: supplierName,
zapatilla_nombre: item.productName,
talla: item.size,
cantidad: item.quantity,
costo_proveedor: supplierCost,
orden_id: order.id,
ciudad_destino: order.cityName,
});
const url = `https://wa.me/${supplierPhone}?text=${encodeURIComponent(message)}`;
window.open(url, '_blank');
if (order.status === 'pending' || order.status === 'deposit_received') {
handleStatusChange(order.id, 'supplier_notified');
}
};
// 2. Enviar Manifiesto Consolidado por Proveedor vía WhatsApp
const handleSendSupplierBatchManifest = (supplierName: string, supplierPhone: string, itemsList: { order: Order; item: OrderItem }[]) => {
const totalPairs = itemsList.reduce((acc, curr) => acc + curr.item.quantity, 0);
const totalCost = itemsList.reduce((acc, curr) => acc + (curr.item.supplierPrice || 0) * curr.item.quantity, 0);
const itemsSummary = itemsList.map((entry, idx) =>
`${idx + 1}. *${entry.item.productName}*\n • Talla: *${entry.item.size}* (x${entry.item.quantity})\n • Costo Base: ${formatCOP(entry.item.supplierPrice || 0)}\n • Orden Cliente: #${entry.order.id} (${entry.order.cityName})`
).join('\n\n');
const text = renderClientTemplate('supplier_batch_manifest', {
proveedor_nombre: supplierName,
fecha: new Date().toLocaleDateString('es-CO'),
total_pares: totalPairs,
total_costo_proveedor: formatCOP(totalCost),
lista_pares_separacion: itemsSummary,
});
const cleanPhone = supplierPhone.startsWith('57') ? supplierPhone : `57${supplierPhone}`;
window.open(`https://wa.me/${cleanPhone}?text=${encodeURIComponent(text)}`, '_blank');
setToastMessage(`📲 Manifiesto de ${totalPairs} pares enviado a ${supplierName}.`);
};
const handleOpenWaze = (address: string, city: string) => {
const query = encodeURIComponent(`${address}, ${city}, Colombia`);
const wazeUrl = `https://waze.com/ul?q=${query}&navigate=yes`;
window.open(wazeUrl, '_blank');
};
const handleOpenGoogleMaps = (address: string, city: string) => {
const query = encodeURIComponent(`${address}, ${city}, Colombia`);
const mapsUrl = `https://www.google.com/maps/search/?api=1&query=${query}`;
window.open(mapsUrl, '_blank');
};
const handleNotifyCustomerOnTheWay = (order: Order) => {
const cleanPhone = order.customerPhone.startsWith('57') ? order.customerPhone : `57${order.customerPhone}`;
const text = renderClientTemplate('order_on_the_way', {
cliente_nombre: order.customerName,
orden_id: order.id,
cliente_direccion: order.address,
cliente_ciudad: order.cityName,
saldo_contraentrega: formatCOP(order.balanceDue),
metodo_pago: order.paymentMethodName || 'Contraentrega',
tienda_nombre: 'DripZone Luxury',
});
window.open(`https://wa.me/${cleanPhone}?text=${encodeURIComponent(text)}`, '_blank');
handleStatusChange(order.id, 'dispatched');
};
const getStatusBadge = (status: Order['status']) => {
switch (status) {
case 'pending':
return <span className="bg-amber-500/20 text-amber-400 border border-amber-500/30 font-bold px-2.5 py-1 rounded-full text-[10px]">Pendiente Confirmar</span>;
case 'deposit_received':
return <span className="bg-blue-500/20 text-blue-400 border border-blue-500/30 font-bold px-2.5 py-1 rounded-full text-[10px]">Separación $10k Pagada</span>;
case 'supplier_notified':
return <span className="bg-purple-500/20 text-purple-300 border border-purple-500/30 font-bold px-2.5 py-1 rounded-full text-[10px] flex items-center gap-1"><CheckCircle2 className="w-3 h-3 text-purple-400" /> Proveedor Notificado</span>;
case 'dispatched':
return <span className="bg-fuchsia-500/20 text-fuchsia-400 border border-fuchsia-500/30 font-bold px-2.5 py-1 rounded-full text-[10px] flex items-center gap-1"><Truck className="w-3 h-3" /> En Ruta con Mensajero</span>;
case 'delivered':
return <span className="bg-emerald-500/20 text-emerald-400 border border-emerald-500/30 font-bold px-2.5 py-1 rounded-full text-[10px]">Entregado & Cobrado</span>;
case 'cancelled':
return <span className="bg-red-500/20 text-red-400 border border-red-500/30 font-bold px-2.5 py-1 rounded-full text-[10px]">Cancelado</span>;
}
};
const filteredOrders = orders.filter((o) => {
const matchesSearch =
o.customerName.toLowerCase().includes(search.toLowerCase()) ||
o.customerPhone.includes(search) ||
o.address.toLowerCase().includes(search.toLowerCase()) ||
o.cityName.toLowerCase().includes(search.toLowerCase()) ||
o.id.toLowerCase().includes(search.toLowerCase());
if (!matchesSearch) return false;
if (statusFilter !== 'all' && o.status !== statusFilter) return false;
const isWa = o.source === 'whatsapp' || o.id.includes('WA') || (o.notes && /whatsapp|catálogo/i.test(o.notes));
if (sourceFilter === 'whatsapp' && !isWa) return false;
if (sourceFilter === 'web' && isWa) return false;
return true;
});
// Consolidado por Proveedor
const supplierGroups = orders.reduce((acc, order) => {
order.items.forEach((item) => {
const suppName = item.supplierName || '💎 DIFUSIÓN JOVIC STORE COLOMBIA';
const suppPhone = item.supplierPhone || '573167455877';
const matchingSupplier = suppliers.find((s) => s.name.toLowerCase() === suppName.toLowerCase());
const isActiveSup = matchingSupplier ? matchingSupplier.isActive !== false : true;
if (!acc[suppName]) {
acc[suppName] = {
name: suppName,
phone: suppPhone,
isActive: isActiveSup,
entries: [],
totalPairs: 0,
totalCost: 0,
};
}
acc[suppName].entries.push({ order, item });
acc[suppName].totalPairs += item.quantity;
acc[suppName].totalCost += (item.supplierPrice || 0) * item.quantity;
});
return acc;
}, {} as Record<string, { name: string; phone: string; isActive: boolean; entries: { order: Order; item: OrderItem }[]; totalPairs: number; totalCost: number }>);
const pendingDeliveries = orders.filter((o) => o.status !== 'delivered' && o.status !== 'cancelled');
const totalBalanceToCollect = pendingDeliveries.reduce((acc, curr) => acc + curr.balanceDue, 0);
return (
<div className="space-y-6">
{/* Header */}
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
<div>
<h1 className="text-2xl font-black text-white flex items-center gap-2">
<ShoppingBag className="w-6 h-6 text-purple-400" />
<span>Centro Logístico: Pedidos, Proveedores & Rutas Waze</span>
</h1>
<p className="text-xs text-neutral-400 mt-1">
Gestión completa de pedidos (<strong>editar datos, cambiar tallas, precios o eliminar</strong>), consolidación con proveedores y <strong>navegación Waze en 1 clic</strong>.
</p>
</div>
</div>
{toastMessage && (
<div className="bg-purple-950/80 border border-purple-500 text-purple-200 px-4 py-3 rounded-2xl text-xs flex items-center justify-between animate-in fade-in shadow-md">
<span>{toastMessage}</span>
<button onClick={() => setToastMessage(null)} className="font-bold text-white cursor-pointer ml-3">
✕
</button>
</div>
)}
{/* Main Tabs Navigation */}
<div className="grid grid-cols-1 sm:grid-cols-3 p-1 bg-neutral-900 border border-neutral-800 rounded-2xl gap-1">
<button
onClick={() => setActiveTab('individual')}
className={`py-3 px-4 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 cursor-pointer ${
activeTab === 'individual'
? 'bg-gradient-to-r from-purple-600 to-fuchsia-600 text-white shadow-lg shadow-purple-500/30'
: 'text-neutral-400 hover:text-white'
}`}
>
<Layers className="w-4 h-4" />
<span>1. Todos los Pedidos ({orders.length})</span>
</button>
<button
onClick={() => setActiveTab('suppliers')}
className={`py-3 px-4 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 cursor-pointer ${
activeTab === 'suppliers'
? 'bg-gradient-to-r from-purple-600 to-fuchsia-600 text-white shadow-lg shadow-purple-500/30'
: 'text-neutral-400 hover:text-white'
}`}
>
<Building2 className="w-4 h-4 text-purple-300" />
<span>2. Consolidado por Proveedor ({Object.keys(supplierGroups).length})</span>
</button>
<button
onClick={() => setActiveTab('routes')}
className={`py-3 px-4 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 cursor-pointer ${
activeTab === 'routes'
? 'bg-gradient-to-r from-purple-600 to-emerald-500 text-white shadow-lg shadow-emerald-500/30'
: 'text-neutral-400 hover:text-white'
}`}
>
<Compass className="w-4 h-4 text-emerald-300" />
<span>3. Rutas de Entrega & Waze ({pendingDeliveries.length})</span>
</button>
</div>
{/* TAB 1: INDIVIDUAL ORDERS LIST */}
{activeTab === 'individual' && (
<div className="space-y-4">
{/* Canales de Venta Filter */}
<div className="flex flex-wrap items-center gap-2 bg-neutral-900/60 border border-neutral-800/80 p-2 rounded-2xl">
<span className="text-xs text-neutral-400 font-bold ml-1">Canal de Pedido:</span>
<div className="flex flex-wrap items-center gap-1.5">
<button
onClick={() => setSourceFilter('all')}
className={`text-xs font-bold px-3 py-1.5 rounded-xl cursor-pointer transition-all ${
sourceFilter === 'all'
? 'bg-purple-600 text-white shadow-md shadow-purple-500/20'
: 'bg-neutral-800 text-neutral-400 hover:text-white'
}`}
>
Todos ({orders.length})
</button>
<button
onClick={() => setSourceFilter('whatsapp')}
className={`text-xs font-bold px-3 py-1.5 rounded-xl cursor-pointer transition-all flex items-center gap-1.5 ${
sourceFilter === 'whatsapp'
? 'bg-emerald-600 text-white shadow-md shadow-emerald-500/20'
: 'bg-neutral-800 text-neutral-400 hover:text-white'
}`}
>
<MessageCircle className="w-3.5 h-3.5 text-emerald-300" />
<span>💬 WhatsApp & Catálogo ({orders.filter(o => o.source === 'whatsapp' || o.id.includes('WA') || (o.notes && /whatsapp|catálogo/i.test(o.notes))).length})</span>
</button>
<button
onClick={() => setSourceFilter('web')}
className={`text-xs font-bold px-3 py-1.5 rounded-xl cursor-pointer transition-all flex items-center gap-1.5 ${
sourceFilter === 'web'
? 'bg-blue-600 text-white shadow-md shadow-blue-500/20'
: 'bg-neutral-800 text-neutral-400 hover:text-white'
}`}
>
<Globe className="w-3.5 h-3.5 text-blue-300" />
<span>🌐 Tienda Web ({orders.filter(o => !(o.source === 'whatsapp' || o.id.includes('WA') || (o.notes && /whatsapp|catálogo/i.test(o.notes)))).length})</span>
</button>
</div>
</div>
<div className="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3">
<div className="flex items-center space-x-1.5 bg-neutral-900 border border-neutral-800 p-1 rounded-2xl overflow-x-auto">
{['all', 'pending', 'deposit_received', 'supplier_notified', 'dispatched', 'delivered'].map((st) => (
<button
key={st}
onClick={() => setStatusFilter(st)}
className={`text-xs font-bold px-3 py-1.5 rounded-xl cursor-pointer transition-all ${
statusFilter === st ? 'bg-white text-neutral-950 shadow' : 'text-neutral-400 hover:text-white'
}`}
>
{st === 'all' ? 'Todos' : st === 'pending' ? 'Pendientes' : st === 'deposit_received' ? 'Anticipo Pagado' : st === 'supplier_notified' ? 'Prov. Notificado' : st === 'dispatched' ? 'En Ruta' : 'Entregados'}
</button>
))}
</div>
<div className="max-w-xs w-full">
<input
type="text"
placeholder="Buscar por cliente, celular, ciudad o #..."
value={search}
onChange={(e) => setSearch(e.target.value)}
className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3.5 py-2 text-xs text-white outline-hidden focus:border-purple-400"
/>
</div>
</div>
<div className="space-y-4">
{filteredOrders.length === 0 ? (
<div className="bg-neutral-900 border border-neutral-800 rounded-3xl p-12 text-center text-neutral-500">
No hay pedidos que coincidan con los filtros.
</div>
) : (
filteredOrders.map((order) => (
<div
key={order.id}
className="bg-neutral-900 border border-neutral-800 hover:border-purple-500/40 rounded-3xl p-5 shadow-xl transition-all space-y-4"
>
{/* Top bar */}
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2 border-b border-neutral-800 pb-3">
<div className="flex flex-wrap items-center gap-2">
<span className="font-black text-white text-base">Orden #{order.id}</span>
{order.source === 'whatsapp' || order.id.includes('WA') || (order.notes && /whatsapp|catálogo/i.test(order.notes)) ? (
<span className="bg-emerald-500/20 text-emerald-300 border border-emerald-500/40 font-bold px-2.5 py-0.5 rounded-full text-[10px] flex items-center gap-1 shadow-sm shadow-emerald-950/30">
<MessageCircle className="w-3 h-3 text-emerald-400" />
{order.id.includes('CAT') || (order.notes && /catálogo/i.test(order.notes)) ? '🛍️ Catálogo WA' : '💬 WhatsApp'}
</span>
) : (
<span className="bg-blue-500/20 text-blue-300 border border-blue-500/40 font-bold px-2.5 py-0.5 rounded-full text-[10px] flex items-center gap-1 shadow-sm shadow-blue-950/30">
<Globe className="w-3 h-3 text-blue-400" />
🌐 Tienda Web
</span>
)}
{getStatusBadge(order.status)}
<span className="text-[11px] text-neutral-500 font-mono">{order.createdAt}</span>
</div>
<div className="flex items-center space-x-2">
<button
onClick={() => handleOpenEditModal(order)}
className="bg-neutral-800 hover:bg-neutral-700 text-purple-300 font-bold text-xs px-3 py-1.5 rounded-xl border border-neutral-700 flex items-center gap-1.5 cursor-pointer transition-all active:scale-95"
title="Modificar o editar datos de este pedido"
>
<Edit3 className="w-3.5 h-3.5" />
<span>Editar Pedido</span>
</button>
<button
onClick={() => handleOpenDeleteModal(order)}
className="bg-red-500/10 hover:bg-red-500/20 text-red-400 font-bold text-xs px-2.5 py-1.5 rounded-xl border border-red-500/30 flex items-center gap-1 cursor-pointer transition-all active:scale-95"
title="Eliminar este pedido"
>
<Trash2 className="w-3.5 h-3.5" />
</button>
<select
value={order.status}
onChange={(e) => handleStatusChange(order.id, e.target.value as any)}
className="bg-neutral-950 border border-neutral-800 text-xs text-white rounded-xl px-3 py-1.5 outline-hidden font-bold cursor-pointer"
>
<option value="pending">⏳ Pendiente Confirmar</option>
<option value="deposit_received">💳 Anticipo Pagado</option>
<option value="supplier_notified">🏢 Proveedor Notificado</option>
<option value="dispatched">🛵 En Ruta con Mensajero</option>
<option value="delivered">✅ Entregado & Cobrado</option>
<option value="cancelled">❌ Cancelado por Cliente</option>
<option value="rejected">🚫 Rechazado en Entrega (Activa Garantía de Flete)</option>
</select>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 text-xs">
<div className="space-y-1 bg-neutral-950/60 p-3 rounded-2xl border border-neutral-800/80">
<p className="font-bold text-neutral-400 uppercase text-[10px]">Cliente & Destino</p>
<p className="text-white font-bold text-sm">{order.customerName}</p>
<p className="text-emerald-400 font-mono font-semibold flex items-center gap-1">
<Phone className="w-3 h-3" /> {order.customerPhone}
</p>
<p className="text-neutral-300 flex items-start gap-1">
<MapPin className="w-3 h-3 shrink-0 text-purple-400 mt-0.5" />
<span>{order.address} ({order.cityName})</span>
</p>
{order.notes && (
<p className="text-amber-300 text-[11px] italic bg-amber-500/10 p-1.5 rounded-lg border border-amber-500/20 mt-1">
Nota: {order.notes}
</p>
)}
</div>
<div className="space-y-1.5 bg-neutral-950/60 p-3 rounded-2xl border border-neutral-800/80">
<p className="font-bold text-neutral-400 uppercase text-[10px]">Resumen de Cobro</p>
<div className="flex justify-between text-neutral-300">
<span>Total Venta:</span>
<strong className="text-white font-mono">{formatCOP(order.totalAmount)}</strong>
</div>
<div className="flex justify-between items-center text-neutral-300">
<span>Anticipo Separación:</span>
<div className="flex items-center gap-1.5">
<strong className="text-purple-300 font-mono">{formatCOP(order.depositAmount || 10000)}</strong>
{(order.depositPaid || order.status === 'deposit_received') ? (
<span className="text-[10px] font-bold px-1.5 py-0.5 rounded-md bg-emerald-500/20 text-emerald-400 border border-emerald-500/30">
✅ Pagado
</span>
) : (
<span className="text-[10px] font-bold px-1.5 py-0.5 rounded-md bg-amber-500/20 text-amber-300 border border-amber-500/30">
🔴 Pendiente
</span>
)}
</div>
</div>
<div className="flex justify-between text-neutral-300 pt-1.5 border-t border-neutral-800 font-bold">
<span className="text-purple-300">Saldo Contraentrega:</span>
<span className="text-emerald-400 text-sm font-mono">{formatCOP(order.balanceDue)}</span>
</div>
</div>
<div className="space-y-2 bg-neutral-950/60 p-3 rounded-2xl border border-neutral-800/80 flex flex-col justify-center">
<button
onClick={() => handleOpenWaze(order.address, order.cityName)}
className="w-full bg-purple-600 hover:bg-purple-500 text-white font-bold py-1.5 px-3 rounded-xl flex items-center justify-center gap-1.5 cursor-pointer shadow transition-all text-xs"
>
<Compass className="w-3.5 h-3.5" />
<span>Navegar con Waze</span>
</button>
<button
onClick={() => handleNotifyCustomerOnTheWay(order)}
className="w-full bg-emerald-600 hover:bg-emerald-500 text-white font-bold py-1.5 px-3 rounded-xl flex items-center justify-center gap-1.5 cursor-pointer shadow transition-all text-xs"
>
<MessageCircle className="w-3.5 h-3.5" />
<span>Avisar "Voy en camino"</span>
</button>
</div>
</div>
<div className="space-y-2 pt-2">
<p className="font-bold text-neutral-400 uppercase text-[10px]">Pares en esta orden:</p>
<div className="space-y-2">
{order.items.map((item, idx) => (
<div
key={idx}
className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 bg-neutral-950 p-3 rounded-2xl border border-neutral-800"
>
<div className="flex items-center space-x-3">
<OptimizedImage
src={item.image}
alt=""
width={100}
height={100}
quality={75}
className="w-12 h-12 rounded-xl object-cover border border-neutral-800 shrink-0"
containerClassName="w-12 h-12 rounded-xl shrink-0"
/>
<div>
<p className="font-bold text-white text-xs">{item.productName}</p>
<p className="text-[11px] text-neutral-400">
Talla: <strong className="text-purple-400">{item.size}</strong> | Cant: <strong>{item.quantity}</strong> | Precio Unitario: <strong className="text-white font-mono">{formatCOP(item.price || 0)}</strong> | Subtotal: <strong className="text-emerald-400 font-mono">{formatCOP((item.price || 0) * (item.quantity || 1))}</strong> | Costo: <strong className="font-mono text-neutral-400">{formatCOP(item.supplierPrice || 0)}</strong>
</p>
</div>
</div>
<button
onClick={() => handleNotifySingleSupplier(order, item)}
className="bg-gradient-to-r from-purple-600 to-fuchsia-600 hover:from-purple-500 hover:to-fuchsia-500 text-white font-bold text-xs px-3.5 py-2 rounded-xl flex items-center space-x-1.5 shadow cursor-pointer shrink-0 self-end sm:self-auto"
>
<Send className="w-3.5 h-3.5" />
<span>Separar con Proveedor</span>
</button>
</div>
))}
</div>
</div>
</div>
))
)}
</div>
</div>
)}
{/* TAB 2: CONSOLIDADO AGRUPADO POR PROVEEDOR */}
{activeTab === 'suppliers' && (
<div className="space-y-6 animate-in fade-in">
<div className="bg-purple-950/40 border border-purple-500/30 rounded-3xl p-5 text-xs text-neutral-300 space-y-2 shadow-lg">
<div className="flex items-center space-x-2 text-purple-300 font-bold text-sm">
<Building2 className="w-5 h-5 text-purple-400" />
<span>Consolidado Automático de Compras & Separaciones</span>
</div>
<p>
Agrupación automática por <strong>Proveedor Mayorista</strong>. Si un proveedor ha sido desactivado, sus pedidos y cuentas permanecen 100% calculados e intactos en el historial.
</p>
</div>
<div className="grid grid-cols-1 gap-6">
{Object.values(supplierGroups).map((group) => (
<div
key={group.name}
className="bg-neutral-900 border border-neutral-800 rounded-3xl p-6 shadow-xl space-y-4"
>
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-neutral-800 pb-4">
<div>
<div className="flex items-center gap-2">
<span className="bg-purple-500/20 text-purple-300 border border-purple-500/40 text-[10px] font-bold px-2.5 py-0.5 rounded-full uppercase tracking-wider">
Proveedor Mayorista
</span>
{!group.isActive && (
<span className="bg-amber-500/20 text-amber-300 border border-amber-500/40 text-[10px] font-bold px-2 py-0.5 rounded-full uppercase">
⚪ Inactivo / Histórico
</span>
)}
</div>
<h3 className="text-xl font-black text-white mt-1">{group.name}</h3>
<p className="text-xs text-neutral-400 flex items-center gap-1 mt-0.5">
<Phone className="w-3.5 h-3.5 text-emerald-400" />
<span>WhatsApp Proveedor: <strong>{group.phone}</strong></span>
</p>
</div>
<div className="flex items-center gap-3">
<div className="bg-neutral-950 border border-neutral-800 px-4 py-2 rounded-2xl text-right">
<p className="text-[10px] text-neutral-400 uppercase font-bold">Total Pares</p>
<p className="text-lg font-black text-purple-400">{group.totalPairs} par(es)</p>
</div>
<div className="bg-neutral-950 border border-neutral-800 px-4 py-2 rounded-2xl text-right">
<p className="text-[10px] text-neutral-400 uppercase font-bold">Total a Pagar</p>
<p className="text-lg font-black text-emerald-400">{formatCOP(group.totalCost)}</p>
</div>
</div>
</div>
<div className="overflow-x-auto">
<table className="w-full text-left text-xs text-neutral-300">
<thead className="bg-neutral-950 text-neutral-400 font-bold uppercase text-[10px]">
<tr>
<th className="py-2.5 px-3">Modelo / Zapatilla</th>
<th className="py-2.5 px-3">Talla</th>
<th className="py-2.5 px-3">Cant.</th>
<th className="py-2.5 px-3">Costo Base</th>
<th className="py-2.5 px-3">Orden Cliente</th>
<th className="py-2.5 px-3">Destino</th>
<th className="py-2.5 px-3">Estado Orden</th>
</tr>
</thead>
<tbody className="divide-y divide-neutral-800">
{group.entries.map((entry, idx) => (
<tr key={idx} className="hover:bg-neutral-800/40">
<td className="py-2.5 px-3 font-bold text-white flex items-center gap-2">
<OptimizedImage
src={entry.item.image}
alt=""
width={64}
height={64}
quality={70}
className="w-8 h-8 rounded-lg object-cover border border-neutral-800 shrink-0"
containerClassName="w-8 h-8 rounded-lg shrink-0"
showSkeleton={false}
/>
<span>{entry.item.productName}</span>
</td>
<td className="py-2.5 px-3 font-bold text-purple-400 font-mono">{entry.item.size}</td>
<td className="py-2.5 px-3 font-bold">{entry.item.quantity}</td>
<td className="py-2.5 px-3 font-mono font-semibold">{formatCOP(entry.item.supplierPrice || 0)}</td>
<td className="py-2.5 px-3 font-mono text-neutral-400">#{entry.order.id}</td>
<td className="py-2.5 px-3">{entry.order.cityName}</td>
<td className="py-2.5 px-3">{getStatusBadge(entry.order.status)}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="pt-2 flex justify-end">
<button
onClick={() => handleSendSupplierBatchManifest(group.name, group.phone, group.entries)}
className="bg-gradient-to-r from-purple-600 to-fuchsia-600 hover:from-purple-500 hover:to-fuchsia-500 text-white font-black text-xs px-5 py-3 rounded-2xl shadow-lg flex items-center gap-2 cursor-pointer transition-all active:scale-95"
>
<MessageCircle className="w-4 h-4" />
<span>Enviar Manifiesto de {group.totalPairs} Pares por WhatsApp a {group.name}</span>
</button>
</div>
</div>
))}
</div>
</div>
)}
{/* TAB 3: RUTAS DE ENTREGA ORGANIZADAS POR DIRECCIONES & WAZE */}
{activeTab === 'routes' && (
<div className="space-y-6 animate-in fade-in">
<div className="bg-gradient-to-r from-neutral-900 via-neutral-900 to-purple-950/60 border border-purple-500/30 rounded-3xl p-6 shadow-xl flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<div className="flex items-center space-x-2 text-purple-300 font-bold text-sm">
<Compass className="w-5 h-5 text-purple-400" />
<span>Hoja de Ruta & Navegación GPS (Waze / Google Maps)</span>
</div>
<p className="text-xs text-neutral-300 mt-1 max-w-xl">
Entregas contraentrega secuenciadas por zona geográfica. Presiona <strong>"Abrir en Waze"</strong> para iniciar la navegación instantánea.
</p>
</div>
<div className="flex items-center gap-3">
<div className="bg-neutral-950 border border-neutral-800 p-3 rounded-2xl text-right">
<p className="text-[10px] text-neutral-400 uppercase font-bold">Paradas / Entregas</p>
<p className="text-xl font-black text-white">{pendingDeliveries.length} Paradas</p>
</div>
<div className="bg-neutral-950 border border-emerald-500/30 p-3 rounded-2xl text-right">
<p className="text-[10px] text-emerald-400 uppercase font-bold">Total a Recaudar</p>
<p className="text-xl font-black text-emerald-400">{formatCOP(totalBalanceToCollect)}</p>
</div>
</div>
</div>
<div className="space-y-3">
{pendingDeliveries.length === 0 ? (
<div className="bg-neutral-900 border border-neutral-800 rounded-3xl p-12 text-center text-neutral-500">
🎉 No hay entregas pendientes por despachar en este momento.
</div>
) : (
pendingDeliveries.map((delivery, index) => (
<div
key={delivery.id}
className="bg-neutral-900 border border-neutral-800 hover:border-purple-500/40 rounded-3xl p-5 shadow-lg transition-all flex flex-col lg:flex-row lg:items-center justify-between gap-4"
>
<div className="flex items-start space-x-4">
<div className="w-12 h-12 rounded-2xl bg-purple-500/20 border border-purple-500/40 flex flex-col items-center justify-center text-purple-300 font-black shrink-0 shadow-sm">
<span className="text-[10px] uppercase font-bold text-neutral-400 leading-none">Parada</span>
<span className="text-lg leading-tight">#{index + 1}</span>
</div>
<div className="space-y-1">
<div className="flex items-center space-x-2">
<span className="font-black text-white text-base">{delivery.customerName}</span>
<span className="text-xs text-neutral-400">• Orden #{delivery.id}</span>
{getStatusBadge(delivery.status)}
</div>
<p className="text-xs font-bold text-white flex items-center gap-1.5 bg-neutral-950 px-3 py-1 rounded-xl border border-neutral-800 w-fit">
<MapPin className="w-4 h-4 text-purple-400 shrink-0" />
<span>{delivery.address} ({delivery.cityName})</span>
</p>
<div className="flex items-center space-x-3 text-xs text-neutral-400 pt-0.5">
<span className="flex items-center gap-1 text-emerald-400 font-semibold">
<Phone className="w-3 h-3" /> {delivery.customerPhone}
</span>
<span>•</span>
<span>
{delivery.items.map((i) => `${i.productName} (Talla ${i.size})`).join(', ')}
</span>
</div>
{delivery.notes && (
<p className="text-[11px] text-amber-300/90 italic bg-amber-500/10 px-2.5 py-0.5 rounded-lg border border-amber-500/20 w-fit">
Nota: {delivery.notes}
</p>
)}
</div>
</div>
<div className="flex items-center gap-3 self-end lg:self-auto shrink-0">
<div className="bg-neutral-950 border border-neutral-800 px-3.5 py-2 rounded-2xl text-right">
<p className="text-[10px] text-neutral-400 font-bold uppercase">Cobrar Contraentrega</p>
<p className="text-base font-black text-emerald-400">{formatCOP(delivery.balanceDue)}</p>
</div>
<button
onClick={() => handleOpenEditModal(delivery)}
className="bg-neutral-800 hover:bg-neutral-700 text-purple-300 font-bold text-xs p-3 rounded-2xl shadow cursor-pointer transition-all"
title="Editar datos de este pedido"
>
<Edit3 className="w-4 h-4" />
</button>
<button
onClick={() => handleOpenWaze(delivery.address, delivery.cityName)}
className="bg-purple-600 hover:bg-purple-500 text-white font-black text-xs px-4 py-3 rounded-2xl shadow-lg flex items-center gap-1.5 cursor-pointer active:scale-95 transition-all"
title="Abrir ubicación directamente en Waze"
>
<Compass className="w-4 h-4" />
<span>Waze</span>
</button>
<button
onClick={() => handleOpenGoogleMaps(delivery.address, delivery.cityName)}
className="bg-neutral-800 hover:bg-neutral-700 text-white font-bold text-xs p-3 rounded-2xl shadow cursor-pointer transition-all"
title="Abrir en Google Maps"
>
<Navigation className="w-4 h-4 text-emerald-400" />
</button>
<button
onClick={() => handleNotifyCustomerOnTheWay(delivery)}
className="bg-emerald-600 hover:bg-emerald-500 text-white font-bold text-xs px-3.5 py-3 rounded-2xl shadow flex items-center gap-1.5 cursor-pointer active:scale-95 transition-all"
title="Enviar mensaje de WhatsApp notificando que el mensajero va en camino"
>
<MessageCircle className="w-4 h-4" />
<span className="hidden sm:inline">En Camino</span>
</button>
</div>
</div>
))
)}
</div>
</div>
)}
{/* MODAL: EDITAR / MODIFICAR PEDIDO */}
{isEditModalOpen && editingOrder && (
<div className="fixed inset-0 z-50 bg-black/80 backdrop-blur-xs flex items-center justify-center p-4 animate-in fade-in overflow-y-auto">
<div className="bg-neutral-900 border border-neutral-800 rounded-3xl max-w-2xl w-full p-6 space-y-4 shadow-2xl my-8 max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between border-b border-neutral-800 pb-3">
<div className="flex items-center space-x-2">
<Edit3 className="w-5 h-5 text-purple-400" />
<h3 className="font-black text-white text-base">Modificar Orden #{editingOrder.id}</h3>
</div>
<button
onClick={() => setIsEditModalOpen(false)}
className="text-neutral-400 hover:text-white cursor-pointer"
>
✕
</button>
</div>
<form onSubmit={handleSaveOrderEdits} className="space-y-4 text-xs">
{/* Customer details */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 bg-neutral-950/60 p-3.5 rounded-2xl border border-neutral-800">
<div>
<label className="block text-neutral-400 font-bold mb-1">Nombre del Cliente *</label>
<input
type="text"
required
value={editCustomerName}
onChange={(e) => setEditCustomerName(e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400 font-bold"
/>
</div>
<div>
<label className="block text-emerald-400 font-bold mb-1">Celular WhatsApp *</label>
<input
type="tel"
required
value={editCustomerPhone}
onChange={(e) => setEditCustomerPhone(e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-emerald-300 outline-hidden focus:border-emerald-400 font-mono font-bold"
/>
</div>
<div className="sm:col-span-2">
<label className="block text-neutral-400 font-bold mb-1">Dirección de Entrega *</label>
<input
type="text"
required
value={editAddress}
onChange={(e) => setEditAddress(e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400"
/>
</div>
<div>
<label className="block text-neutral-400 font-bold mb-1">Ciudad Destino</label>
<select
value={editCityName}
onChange={(e) => {
const cityName = e.target.value;
setEditCityName(cityName);
const foundCity = cities.find((c) => c.name === cityName);
if (foundCity) setEditCityId(foundCity.id);
}}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden font-semibold"
>
{cities.map((c) => (
<option key={c.id} value={c.name}>
{c.name} ({c.department})
</option>
))}
</select>
</div>
<div>
<label className="block text-purple-400 font-bold mb-1">Estado de la Orden</label>
<select
value={editStatus}
onChange={(e) => setEditStatus(e.target.value as any)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden font-bold"
>
<option value="pending">⏳ Pendiente Confirmar</option>
<option value="deposit_received">💳 Separación $10k Pagada</option>
<option value="supplier_notified">🏢 Proveedor Notificado</option>
<option value="dispatched">🛵 En Ruta con Mensajero</option>
<option value="delivered">✅ Entregado & Cobrado</option>
<option value="cancelled">❌ Cancelado</option>
</select>
</div>
</div>
{/* Items Management */}
<div className="space-y-2 bg-neutral-950/60 p-3.5 rounded-2xl border border-neutral-800">
<div className="flex items-center justify-between">
<p className="font-bold text-white uppercase text-[11px]">Zapatillas & Proveedores en la Orden</p>
<button
type="button"
onClick={handleAddItemToEdit}
className="text-[11px] text-purple-400 hover:text-purple-300 font-bold flex items-center gap-1 cursor-pointer"
>
<Plus className="w-3.5 h-3.5" />
<span>Agregar Par</span>
</button>
</div>
<div className="space-y-3">
{editItems.map((item, idx) => (
<div key={idx} className="bg-neutral-900 border border-neutral-800 p-3 rounded-xl space-y-2">
<div className="flex items-center justify-between">
<span className="font-bold text-white text-xs">Par #{idx + 1}</span>
{editItems.length > 1 && (
<button
type="button"
onClick={() => handleRemoveItemFromEdit(idx)}
className="text-red-400 hover:text-red-300 text-[10px] font-bold cursor-pointer"
>
Eliminar Par
</button>
)}
</div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-2">
<div className="sm:col-span-2">
<label className="block text-[10px] text-neutral-400 font-bold">Modelo / Nombre</label>
<input
type="text"
value={item.productName}
onChange={(e) => handleItemChange(idx, 'productName', e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-lg px-2.5 py-1.5 text-white outline-hidden"
/>
</div>
<div>
<label className="block text-[10px] text-purple-400 font-bold">Talla</label>
<input
type="text"
value={item.size}
onChange={(e) => handleItemChange(idx, 'size', e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-lg px-2.5 py-1.5 text-white font-mono font-bold outline-hidden"
/>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-2">
<div>
<label className="block text-[10px] text-neutral-400 font-bold">Cantidad</label>
<input
type="number"
min="1"
value={item.quantity}
onChange={(e) => handleItemChange(idx, 'quantity', parseInt(e.target.value, 10) || 1)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-lg px-2.5 py-1.5 text-white outline-hidden"
/>
</div>
<div>
<label className="block text-[10px] text-neutral-400 font-bold">Precio Venta (COP)</label>
<input
type="number"
value={item.price}
onChange={(e) => handleItemChange(idx, 'price', parseInt(e.target.value, 10) || 0)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-lg px-2.5 py-1.5 text-white font-mono outline-hidden"
/>
</div>
<div>
<label className="block text-[10px] text-emerald-400 font-bold">Costo Proveedor</label>
<input
type="number"
value={item.supplierPrice || 0}
onChange={(e) => handleItemChange(idx, 'supplierPrice', parseInt(e.target.value, 10) || 0)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-lg px-2.5 py-1.5 text-emerald-300 font-mono outline-hidden"
/>
</div>
</div>
<div>
<label className="block text-[10px] text-purple-300 font-bold">Proveedor Asignado</label>
<select
value={item.supplierName}
onChange={(e) => handleItemChange(idx, 'supplierName', e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-lg px-2.5 py-1.5 text-white outline-hidden text-xs"
>
{suppliers.map((s) => (
<option key={s.id} value={s.name}>
{s.name} {s.isActive === false ? '(⚪ Inactivo)' : ''}
</option>
))}
</select>
</div>
</div>
))}
</div>
</div>
{/* Financial calculations */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 bg-neutral-950/60 p-3.5 rounded-2xl border border-neutral-800">
<div>
<label className="block text-neutral-400 font-bold mb-1">Total Venta ($ COP)</label>
<input
type="number"
value={editTotalAmount}
onChange={(e) => setEditTotalAmount(parseInt(e.target.value, 10) || 0)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white font-mono font-bold outline-hidden focus:border-purple-400"
/>
</div>
<div>
<label className="block text-purple-400 font-bold mb-1">Anticipo Pagado ($ COP)</label>
<input
type="number"
value={editDepositAmount}
onChange={(e) => setEditDepositAmount(parseInt(e.target.value, 10) || 0)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-purple-300 font-mono font-bold outline-hidden focus:border-purple-400"
/>
</div>
<div>
<label className="block text-emerald-400 font-bold mb-1">Saldo Contraentrega</label>
<div className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-emerald-400 font-mono font-bold text-sm">
{formatCOP(editTotalAmount - editDepositAmount)}
</div>
</div>
</div>
<div>
<label className="block text-neutral-400 font-bold mb-1">Notas Internas del Pedido</label>
<textarea
rows={2}
placeholder="Ej. Dejar en portería con el celador Juan..."
value={editNotes}
onChange={(e) => setEditNotes(e.target.value)}
className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3.5 py-2 text-white outline-hidden focus:border-purple-400"
/>
</div>
<div className="flex justify-end space-x-2 pt-2 border-t border-neutral-800">
<button
type="button"
onClick={() => setIsEditModalOpen(false)}
className="bg-neutral-800 hover:bg-neutral-700 text-neutral-300 font-bold py-2.5 px-4 rounded-xl cursor-pointer"
>
Cancelar
</button>
<button
type="submit"
disabled={isSavingOrder}
className="bg-gradient-to-r from-purple-600 to-fuchsia-600 hover:from-purple-500 hover:to-fuchsia-500 text-white font-bold py-2.5 px-5 rounded-xl shadow-lg cursor-pointer transition-all disabled:opacity-50"
>
{isSavingOrder ? 'Guardando Cambios...' : 'Guardar Modificaciones'}
</button>
</div>
</form>
</div>
</div>
)}
{/* MODAL: CONFIRMACIÓN DE ELIMINACIÓN DE PEDIDO */}
{isDeleteModalOpen && orderToDelete && (
<div className="fixed inset-0 z-50 bg-black/80 backdrop-blur-xs flex items-center justify-center p-4 animate-in fade-in">
<div className="bg-neutral-900 border border-red-500/30 rounded-3xl max-w-md w-full p-6 space-y-4 shadow-2xl">
<div className="flex items-center space-x-3 text-red-400">
<div className="w-10 h-10 rounded-2xl bg-red-500/20 border border-red-500/30 flex items-center justify-center">
<Trash2 className="w-5 h-5" />
</div>
<h3 className="font-black text-white text-base">¿Eliminar Pedido #{orderToDelete.id}?</h3>
</div>
<p className="text-xs text-neutral-300 leading-relaxed">
Estás a punto de eliminar permanentemente la orden del cliente <strong>{orderToDelete.customerName}</strong> ({orderToDelete.cityName}) por valor de <strong>{formatCOP(orderToDelete.totalAmount)}</strong>.
</p>
<div className="flex justify-end space-x-2 pt-2 border-t border-neutral-800">
<button
type="button"
onClick={() => setIsDeleteModalOpen(false)}
className="bg-neutral-800 hover:bg-neutral-700 text-neutral-300 font-bold text-xs py-2.5 px-4 rounded-xl cursor-pointer"
>
Cancelar
</button>
<button
type="button"
onClick={handleConfirmDeleteOrder}
className="bg-red-600 hover:bg-red-500 text-white font-bold text-xs py-2.5 px-5 rounded-xl shadow-lg cursor-pointer transition-all active:scale-95"
>
Sí, Eliminar Pedido
</button>
</div>
</div>
</div>
)}
</div>
);
}