Files
SIG-CM/frontend/counter-panel/src/components/POS/ShortcutAddModal.tsx

100 lines
4.1 KiB
TypeScript

import { useState } from 'react';
import { X, Search, Plus } from 'lucide-react';
import { motion } from 'framer-motion';
import type { Product } from '../../types/Product';
interface Props {
catalog: Product[];
onClose: () => void;
onAdd: (productId: number) => void;
existingIds: number[];
}
export default function ShortcutAddModal({ catalog, onClose, onAdd, existingIds }: Props) {
const [searchTerm, setSearchTerm] = useState('');
// Filtrar productos que no estén ya anclados
const filtered = catalog.filter(p =>
!existingIds.includes(p.id) &&
p.name.toLowerCase().includes(searchTerm.toLowerCase())
);
const getProductTypeLabel = (typeCode?: string) => {
switch (typeCode) {
case 'BUNDLE': return 'Combo / Paquete';
case 'CLASSIFIED_AD': return 'Aviso Clasificado';
case 'PHYSICAL': return 'Producto Físico';
case 'SERVICE': return 'Servicio';
case 'GRAPHIC': return 'Publicidad Gráfica';
case 'RADIO': return 'Publicidad Radial';
default: return 'Producto';
}
};
return (
<div className="fixed inset-0 bg-slate-900/60 backdrop-blur-sm z-[250] flex items-center justify-center p-4">
<motion.div
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
className="bg-white w-full max-w-lg rounded-[2.5rem] shadow-2xl overflow-hidden flex flex-col max-h-[80vh] border border-slate-200"
>
<div className="p-8 border-b border-slate-100 flex justify-between items-center bg-slate-50">
<div>
<h3 className="text-xl font-black text-slate-800 uppercase tracking-tight">Anclar Producto</h3>
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Añadir a accesos rápidos</p>
</div>
<button onClick={onClose} className="p-2 hover:bg-white rounded-xl text-slate-400 transition-colors">
<X size={20} />
</button>
</div>
<div className="p-8 space-y-6 flex-1 flex flex-col min-h-0">
<div className="relative">
<Search className="absolute left-4 top-1/2 -translate-y-1/2 text-slate-400" size={18} />
<input
type="text"
autoFocus
className="w-full pl-12 pr-4 py-4 bg-slate-50 border-2 border-slate-100 rounded-2xl outline-none focus:border-blue-500 font-bold text-sm transition-all"
placeholder="Buscar producto o combo..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
<div className="flex-1 overflow-y-auto custom-scrollbar space-y-2 pr-2">
{filtered.length === 0 ? (
<div className="text-center py-12 text-slate-400">
<p className="text-sm font-bold italic">No se encontraron productos disponibles</p>
</div>
) : (
filtered.map(p => (
<button
key={p.id}
onClick={() => onAdd(p.id)}
className="w-full p-4 rounded-2xl border border-slate-100 hover:border-blue-400 hover:bg-blue-50/30 transition-all flex justify-between items-center group"
>
<div className="text-left">
<div className="text-sm font-black text-slate-700 group-hover:text-blue-700">{p.name}</div>
<div className="text-[10px] font-bold text-slate-400 uppercase tracking-tight">
{getProductTypeLabel(p.typeCode)}
</div>
</div>
<div className="bg-white p-2 rounded-xl text-blue-500 shadow-sm group-hover:bg-blue-600 group-hover:text-white transition-all">
<Plus size={16} />
</div>
</button>
))
)}
</div>
</div>
<div className="p-6 bg-slate-50 border-t border-slate-100 text-center">
<p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
Selecciona un producto para anclarlo a tu grilla
</p>
</div>
</motion.div>
</div>
);
}