// components/ModalSearch.js import { $, watch, h, each } from "sigpro"; import { db } from "sigpro/utils"; import { Modal, Input, Button, Loading, Table } from "sigpro-ui"; export const ModalSearch = ({ open, onSelect }) => { const search = $(''); const results = $([]); const loading = $(false); const error = $(null); const debounceTimer = $(null); // Búsqueda con debounce de 500ms watch(search, (query) => { const currentTimer = debounceTimer(); if (currentTimer) { clearTimeout(currentTimer); debounceTimer(null); } if (!query || query.length < 3) { results([]); error(null); return; } loading(true); error(null); const timer = setTimeout(async () => { try { const data = await db('/proxy/3000/api/db/search', { q: query }); console.log(data) results(data.results || []); } catch (err) { error(err.message); results([]); } finally { loading(false); } }, 500); debounceTimer(timer); }); // Columnas de la tabla const columns = [ { label: 'Código', key: 'CodigoPoliza', class: 'font-mono text-xs' }, { label: 'Mediador', key: 'CodigoMediador', class: 'text-xs' }, { label: 'Nombre', key: 'Nombre', class: 'font-medium text-xs' }, { label: 'Apellidos', key: 'Apellidos', class: 'text-xs' }, { label: 'Documento', key: 'Documento', class: 'text-xs' }, { label: 'Riesgo', key: 'Riesgo', class: 'text-xs' }, { label: 'Ramo', key: 'Ramo', class: 'text-xs' }, { label: 'Localidad', key: 'Localidad', class: 'text-xs' }, { label: '', key: 'action', class: 'w-0 p-0', render: (item) => Button({ class: 'btn btn-ghost btn-xs', onclick: (e) => { e.stopPropagation(); handleSelect(item); } }, 'Seleccionar') } ]; const handleSelect = (item) => { onSelect?.(item); closeModal(); }; const closeModal = () => { open(false); search(''); results([]); error(null); }; return Modal({ open, title: 'Buscar Pólizas', class: 'max-w-1024px max-h-612px', actions: [ Button({ class: 'btn btn-ghost', onclick: closeModal }, 'Cerrar') ] }, [ h('div', { class: 'space-y-4' }, [ // Campo de búsqueda Input({ type: "search", class: "w-full", placeholder: "Buscar por cualquier campo (mín. 3 caracteres)...", value: search, left: h('span', { class: "icon-[lucide--search]" }), right: () => loading() ? Loading({ class: "loading-sm" }) : (search() ? Button({ class: "btn btn-ghost btn-xs btn-circle -mr-2", onclick: (e) => { e.preventDefault(); e.stopPropagation(); search(''); } }, h('span', { class: "icon-[lucide--x] opacity-50" })) : null), oninput: (e) => search(e.target.value), autofocus: true }), // Estado de carga () => loading() ? h('div', { class: 'flex justify-center items-center py-8' }, [ Loading({ class: 'loading-md' }), h('span', { class: 'ml-2 text-sm opacity-70' }, 'Buscando...') ]) : null, // Error () => !loading() && error() ? h('div', { class: 'alert alert-error py-2 px-3 text-sm' }, [ h('span', { class: 'icon-[lucide--alert-circle]' }), h('span', {}, error()) ]) : null, // Contador de resultados () => !loading() && !error() && results().length > 0 ? h('div', { class: 'text-xs opacity-60 px-1' }, `${results().length} resultado${results().length !== 1 ? 's' : ''}` ) : null, // Tabla de resultados () => !loading() && !error() && results().length > 0 ? h('div', { class: 'overflow-x-auto max-h-96' }, [ h('table', { class: 'table table-xs table-zebra table-pin-rows w-full' }, [ h('thead', {}, [ h('tr', {}, columns.map(col => h('th', { class: col.class || '' }, col.label) )) ]), h('tbody', {}, each(results, (item) => h('tr', { class: 'hover cursor-pointer', onclick: () => handleSelect(item) }, columns.map(col => h('td', { class: col.class || '' }, col.render ? col.render(item) : (item[col.key] || '') ) )) ) ) ]) ]) : null, // Sin resultados () => !loading() && !error() && search().length >= 3 && results().length === 0 ? h('div', { class: 'text-center py-8 text-base-content/50' }, [ h('span', { class: 'icon-[lucide--search-x] text-2xl mb-2 block' }), h('span', { class: 'text-sm' }, 'No se encontraron resultados') ]) : null, // Estado inicial () => !loading() && !error() && search().length < 3 ? h('div', { class: 'text-center py-8 text-base-content/40 text-sm' }, 'Escribe al menos 3 caracteres para buscar' ) : null ]) ]); };