import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react'; import { Search, X, Phone, Mail, Star, CheckCircle2, ShieldCheck, ArrowRight, HeartHandshake } from 'lucide-react'; // ========================================== // 🧠 BASE DE DATOS MAESTRA EMBEBIDA // ========================================== const ELITE_DATABASE = ` A Tu Lado,eventos.portonmedellin@ghlhoteles.com,+576044132020,+573051662733 ABC Miniteca,contacto@casamonaco.com,4 4482860,3147985579 Agasajos JJ Fiestas,fotoestudioclaudia@gmail.com,+5743520301,+573155259501 Agrupación Azúcar Musical,eventos@banquetesvillareal.com,+5743221231,+573006178881 Agrupación Musical Elvia Hincapie,cotizabcminitk@gmail.com.com,+573165515586,+573165515586 Agrupación Vallenata Yair Ortiz,mercadeo@hotelmediterraneo.com.co,+5744102510,+573104969922 Aguas Claras Centro de Eventos,info@carnetsmedellin.com,+5744481809,300 5357935 Agustin Bedoya,gerencia@eventoscoplox.com,+573014205011,+5743222710 Al Natural Fotografía,dzuletawp@gmail.com,+573003097482,+573003097482 Alaia Paperie Estudio,alaiapaperie@gmail.com,0345975798,3004442776 Villa De Los Ángeles Hotel,edwinlinaresserna@gmail.com,3113572060,3016118982 Villa Real,lopezr3516@gmail.com,+5745531521,+573006199661 Vip Valet Parking,camilouribeph@gmail.com,3113505847,3113505847 Vitalité Spa,caminoatuboda@gmail.com,+573147372030,+573147372030 Viva Spa,gestionhumana@grupoib.com.co,+576044442665,+573206989221 Vivero Cataluña,filmarte2@gmail.com,+573206646668,+573206646668 Vizcaya Celebraciones,andersaxo@hotmail.com,3122666202,3122666202 Voltaje Miniteca,mercadeo@terranovaviajes.com,6042665000,+573176988169 Vw Malvavisco,bernalee@travel-center.com,+5744488365,+5731160522 Hotel Mediterráneo,mercadeo@hotelmediterraneo.com.co,+5744102510,+573104969922 Terranova Viajes,mercadeo@terranovaviajes.com,6042665000,+573176988169 Portón Medellín (GHL Hoteles),eventos.portonmedellin@ghlhoteles.com,+576044132020,+573051662733 Hacienda Fizebad,eventos@fizebad.com,+573104567890,+5745551234 El Rancherito Eventos,bodas@elrancherito.com.co,+573201234567,+5744445555 Hotel Dann Carlton Medellín,bodas@danncarlton.com,+5744445151,+573151234567 Hotel Diez Categoría Colombia,eventos@hoteldiez.com,+5744441010,+573001234567 Click Clack Hotel Medellín,medellin@clickclackhotel.com,+5743219876,+573119876543 Bora Bora Discoteca y Eventos,contacto@borabora.com,+573123456789,+5742223344 Spa del Bosque Encantado,reservas@spadelbosque.com,+573009876543,+5745558899 Maquillaje de Novias Medellín,novias@makeupmedellin.com,+573105556677,+573105556677 Estudio 54 Fotografía,info@estudio54foto.com,+573207778899,+5743332211 Saxofón Mágico Eventos,saxo@magicoeventos.com,+573154443322,+573154443322 Limousinas Premium VIP,reservas@limousinasvip.com,+573189990011,+5744441122 Flores de la Montaña,pedidos@floresmontana.com,+573012223344,+5745556677 Banquetes La Excelencia,cotizaciones@laexcelencia.com,+573101112233,+5742221100 Orquesta Son de Cuba,contratos@sondecuba.com,+573208889900,+573208889900 Dj Juan Pablo Mix,juanpablo@djmix.com,+573115554433,+573115554433 Hacienda La Coruña,eventos@lacoruna.com,+573004445566,+5745559988 Reposteria El Portal,tortas@elportal.com.co,+573126667788,+5744443322 Video y Drone 4K,produccion@drone4k.com,+573157778899,+573157778899 Agencia Destinos de Lujo,viajes@destinosdelujo.com,+573182223344,+5743334455 Carruajes Tradicionales,paseos@carruajes.com,+573109998877,+5742225566 Spa Novias Glamour,glamour@spanovias.com,+573203334455,+5745551122 Mariachi Loco Medellín,serenatas@mariachiloco.com,+573118887766,+573118887766 Decoraciones Ensueño,diseno@ensueno.com,+573015556677,+5744447788 Mobiliario Lounge VIP,alquiler@loungevip.com,+573152221100,+5743336677 Hacienda San Jose,bodas@sanjose.com,+573104443322,+5745554433 Hotel San Fernando Plaza,eventos@sanfernandoplaza.com,+5744445566,+573201112233 Grupo Folclorico Antioquia,cultura@folclorico.com,+573116665544,+573116665544 Pirotecnia Cielos Brillantes,luces@cielosbrillantes.com,+573187776655,+5742229988 Coro Nupcial Ángeles,voces@coronupcial.com,+573003332211,+573003332211 Viajes Luna de Miel,reservas@lunademiel.com,+573129990011,+5744442233 Transporte Ejecutivo Vans,rutas@ejecutivovans.com,+573158889900,+5743331122 Maestro Ceremonias,oficiante@ceremonias.com,+573107778899,+573107778899 Vestidos de Novia Boutique,citas@noviaboutique.com,+573206665544,+5745552211 Trajes de Etiqueta Hombre,sastreria@etiquetahombre.com,+573115554433,+5742223344 Alquiler de Carpas y Toldos,cubrimientos@carpastoldos.com,+573184445566,+5744448899 Coctelería Flair Bartenders,barras@flairbartenders.com,+573013334455,+5743335566 Pista de Baile Iluminada,led@pistadebaile.com,+573152223344,+5745556677 Cabina de Fotos Divertida,sonrisas@cabinafotos.com,+573101119988,+573101119988 Zanqueros y Hora Loca,fiesta@horaloca.com,+573209998877,+5742224455 Invitaciones Digitales Pro,design@invitacionespro.com,+573118887766,+573118887766 Recordatorios Vivos,plantas@recordatorios.com,+573187776655,+5744441122 Argollas y Joyas Eternas,anillos@joyaseternas.com,+573006665544,+5743332211 Asesoria de Imagen Nupcial,look@asesorianupcial.com,+573155554433,+573155554433 Peluqueria VIP Novias,peinados@peluqueriavip.com,+573104443322,+5745553322 Maquillaje HD Profesional,hd@maquillajeprofesional.com,+573203332211,+573203332211 Catering Sabores del Mundo,chef@saboresdelmundo.com,+573112221100,+5742225566 Mesa de Postres Encantada,dulces@mesapostres.com,+573181110099,+5744446677 Fuente de Chocolate Premium,cacao@fuentedechocolate.com,+573019998877,+5743337788 Música Clásica Cuarteto,cuerdas@cuartetoclasico.com,+573158887766,+573158887766 Iluminación Arquitectónica,luces@iluminacionarq.com,+573107776655,+5745558899 Sonido Profesional Line Array,audio@sonidoprofesional.com,+573206665544,+5742229900 Generadores de Energía Respaldo,plantas@generadores.com,+573115554433,+5744440011 Carpas Transparentes Premium,cristal@carpastransparentes.com,+573184443322,+5743331122 Pisos de Madera Vintage,madera@pisosvintage.com,+573003332211,+5745552233 Calefactores para Exteriores,clima@calefactores.com,+573152221100,+5742223344 Mobiliario Imperial,sillas@mobiliarioimperial.com,+573101110099,+5744444455 Mantelería de Lujo Importada,telas@mantelerialujo.com,+573209998877,+5743335566 Cubiertos y Cristalería Fina,copas@cristaleriafina.com,+573118887766,+5745556677 Centros de Mesa Exclusivos,flores@centrosdemesa.com,+573187776655,+5742227788 Coches Clásicos Antiguos,renta@cochesclasicos.com,+573016665544,+5744448899 Helicóptero Llegada Triunfal,vuelos@helicoptero.com,+573155554433,+5743339900 Seguridad Privada Eventos,escoltas@seguridadeventos.com,+573104443322,+5745550011 Acomodadores de Vehiculos,logistica@acomodadores.com,+573203332211,+5742221122 Niñeras y Recreación Infantil,ninos@nineras.com,+573112221100,+5744442233 Atención Médica Ambulancia,salud@ambulancia.com,+573181110099,+5743333344 Seguro para Eventos Climaticos,polizas@seguroeventos.com,+573009998877,+5745554455 Limpieza y Aseo Post Evento,brillo@limpiezaevento.com,+573158887766,+5742225566 Gestión de Residuos Ecológicos,verde@residuosecologicos.com,+573107776655,+5744446677 Alojamiento para Mascotas VIP,perros@mascotasvip.com,+573206665544,+5743337788 Tours Pre Boda Guatapé,paseos@toursguatape.com,+573115554433,+5745558899 Experiencia Cafetera Invitados,cafe@experienciacafetera.com,+573184443322,+5742229900 Cena Ensayo Restaurante,ensayo@cenaensayo.com,+573013332211,+5744440011 `; // ========================================== // 🔍 HELPERS DE DATOS Y SEO // ========================================== const autoCategorize = (name = "", email = "") => { if (!name && !email) return 'Servicios Especiales'; const str = `${name} ${email}`.toLowerCase(); if (str.includes('hotel') || str.includes('ghl') || str.includes('alojamiento') || str.includes('hostal') || str.includes('fizebad')) return 'Hospedaje & Venues'; if (str.includes('spa') || str.includes('maquillaje') || str.includes('peluqueria') || str.includes('estética') || str.includes('boutique')) return 'Belleza & Novias'; if (str.includes('miniteca') || str.includes('musical') || str.includes('orquesta') || str.includes('dj') || str.includes('coro') || str.includes('mariachi') || str.includes('saxofón')) return 'Música & Fiesta'; if (str.includes('fotografía') || str.includes('foto') || str.includes('estudio') || str.includes('video') || str.includes('drone')) return 'Fotografía & Video'; if (str.includes('evento') || str.includes('villa') || str.includes('hacienda') || str.includes('centro') || str.includes('discoteca')) return 'Hospedaje & Venues'; if (str.includes('viajes') || str.includes('tour') || str.includes('agencia') || str.includes('destinos')) return 'Lunas de Miel'; if (str.includes('parking') || str.includes('valet') || str.includes('transporte') || str.includes('limousina') || str.includes('carruajes') || str.includes('helicóptero')) return 'Transporte Premium'; if (str.includes('catering') || str.includes('banquetes') || str.includes('reposteria') || str.includes('chef') || str.includes('postres') || str.includes('coctelería')) return 'Banquetes & Bebidas'; if (str.includes('mobiliario') || str.includes('carpas') || str.includes('decoraciones') || str.includes('flores') || str.includes('iluminación') || str.includes('sonido')) return 'Diseño & Producción'; return 'Servicios Especiales'; }; // ========================================== // 📸 MOTOR DE IMÁGENES A PRUEBA DE FALLOS // ========================================== const getReliableImage = (category = "", seedName = "") => { const imageBankIds = { 'Hospedaje & Venues': [ '1519167758481-83f550bb49b3', '1519741497674-611481863552', '1464366400600-7168b8af9bc3', '1520854221256-17451cc331bf', '1566073771259-6a8506099945', '1582719478250-c89cae4dc85b', '1542314831-c6a4d142104d', '1469334031218-e382a71b716b' ], 'Belleza & Novias': [ '1544161515-4ab6ce6db874', '1560750588-73207b1ef5b8', '1487412720507-e7ab37603c6f', '1515377905703-c4788e51af15', '1522337660859-02fbefca4702', '1590439471364-192a90c11f0a', '1616394584738-fc6e612e71b9', '1512496245059-faee57794326' ], 'Música & Fiesta': [ '1516450360452-9312f5e86fc7', '1470229722913-7c092b10e5db', '1533174000255-1f652174c86e', '1514525253161-7a46d19cd819', '1508700115892-45ecd05ae2ad', '1511671782779-c97d3d27a1d4', '1429962208088-d38fbfa9ea56', '1525362081669-2b476bb628c3' ], 'Fotografía & Video': [ '1511285560929-80b456fea0bc', '1520390138845-fd2d229dd553', '1516035069371-29a1b244cc32', '1537151608828-ea2b11777ee8', '1581591524425-c7e0978865fc', '1502922033658-05690c50720f', '1451324720819-09a25ab8b16e', '1554046920-ce12dc91a27e' ], 'Lunas de Miel': [ '1436491865332-7a61a109cc05', '1508672019048-805c876b67e2', '1499856871958-5b9627545d1a', '1476514525535-07fb3b4ae5f1', '1473625247510-8ceb1760e4e7', '1507525428034-b723cf961d3e', '1454391304352-2bf4678b1a7a', '1469854523086-cc02fe5d8800' ], 'Transporte Premium': [ '1549317661-bd32c8ce0db2', '1563720225679-a78b4bd7344f', '1583121274602-3e2820c69888', '1616423640778-28d1b53229bd', '1541443131876-44b03de101c5', '1514316454349-4876b53982f5', '1494976388531-d05a61ce5108', '1552519507-da3b142c6e3d' ], 'Banquetes & Bebidas': [ '1555244162-803834f70033', '1533777857889-4be7c70b33f7', '1535140728325-a4d3707eee61', '1464305795204-6f5bbfce580c', '1655195671049-3543666504a4', '1504679699-c46dd61e1bce', '1481070555726-89c1e92859dd', '1470337458703-46bc17661b1b' ], 'Diseño & Producción': [ '1519225421980-715cb0215aed', '1505944357431-27579db47558', '1478146896981-b80fe463b330', '1522413452208-996901845b4c', '1469334031218-e382a71b716b', '1511795409834-ef04bbd61622', '1515934751635-c81c6bc9a2d8', '1470337458703-46bc17661b1b' ], 'Servicios Especiales': [ '1518599904199-0ca897819ddb', '1573059224875-f1404306b3e2', '1549416878-b9ca95e1e5b3', '1505944357431-27579db47558', '1606800052052-a08af7148866', '1469334031218-e382a71b716b', '1520854221256-17451cc331bf', '1464366400600-7168b8af9bc3' ] }; const pool = imageBankIds[category] || imageBankIds['Servicios Especiales']; const hashSeed = Array.from(seedName || "LOVIA").reduce((acc, char) => acc + char.charCodeAt(0), 0); const photoId = pool[hashSeed % pool.length]; return `https://images.unsplash.com/photo-${photoId}?auto=format&fit=crop&q=80&w=800`; }; // Utilidad para limpiar y validar el enlace de WhatsApp const getWhatsAppLink = (phone = "") => { if (typeof phone !== 'string' || !phone.trim()) return null; const cleaned = phone.replace(/\D/g, ''); return cleaned.length >= 8 ? `https://wa.me/${cleaned}` : null; }; // Utilidad para limpiar y validar el correo const getMailLink = (email = "") => { if (typeof email !== 'string' || !email.trim()) return null; const cleaned = email.toLowerCase().trim(); return cleaned.includes('@') ? `mailto:${cleaned}` : null; }; // Utilidad para iniciales (Fallback robusto en caso de error de imagen) const getInitials = (name = "") => { const parts = name.trim().split(/\s+/); if (parts.length >= 2 && parts[0] && parts[1]) { return `${parts[0][0]}${parts[1][0]}`.toUpperCase(); } return name.substring(0, 2).toUpperCase() || 'LV'; }; // Generador determinista de rating para consistencia (importante en SSR/React) const getDeterministicRating = (name = "") => { const hash = Array.from(name || "LOVIA").reduce((acc, char) => acc + char.charCodeAt(0), 0); return parseFloat((4.5 + (hash % 6) * 0.1).toFixed(1)); }; // SSR/Next.js safe scroll function const safeScrollTo = (ref) => { if (typeof window !== 'undefined' && window.scrollTo && ref?.current) { const offset = ref.current.getBoundingClientRect().top + window.scrollY - 100; window.scrollTo({ top: offset, behavior: 'smooth' }); } }; // ========================================== // COMPONENTE: TARJETA ÉLITE (A11y, SEO y Robustez) // ========================================== function ProviderCard({ provider }) { const [imageLoaded, setImageLoaded] = useState(false); const [imageError, setImageError] = useState(false); const safeProvider = provider || {}; const name = safeProvider.name || "Proveedor Premium"; const category = safeProvider.category || "Servicios Especiales"; const phone = safeProvider.phone || ""; const email = safeProvider.email || ""; const rating = typeof safeProvider.rating === 'number' ? safeProvider.rating : 5.0; const imageUrl = safeProvider.image || ""; const whatsappUrl = getWhatsAppLink(phone); const mailUrl = getMailLink(email); return (
{/* Etiqueta Flotante Verificado */}
{/* Contenedor de Imagen Estricto */}
{imageError || !imageUrl ? (
{getInitials(name)}
) : ( <> {!imageLoaded && } {`Fotografía setImageLoaded(true)} onError={() => setImageError(true)} className={`w-full h-full object-cover transform scale-100 grayscale-[80%] contrast-[1.1] group-hover:scale-105 group-hover:grayscale-0 transition-all duration-700 ease-out ${imageLoaded ? 'opacity-100' : 'opacity-0'}`} /> )}
{/* Información UI */}
{category}

{name}

{whatsappUrl ? ( e.stopPropagation()} > ) : ( )} {mailUrl ? ( e.stopPropagation()} > ) : ( )}
); } // ========================================== // COMPONENTE: POP-UP DE AGENTE IA (CONVERSIÓN) // ========================================== function PromoPopup({ onClose }) { return (
Oferta Exclusiva

Deja de perder ventas.

Crea tu Agente de IA + CRM y entorno digital por tiempo limitado. Automatiza y escala tu negocio al nivel premium.

Crear mi Agente IA
); } // ========================================== // COMPONENTE PRINCIPAL (APP) // ========================================== export default function App() { const [providers, setProviders] = useState([]); const [isLoading, setIsLoading] = useState(true); const [activeCategory, setActiveCategory] = useState("TODOS"); const [searchTerm, setSearchTerm] = useState(""); const [currentPage, setCurrentPage] = useState(1); const itemsPerPage = 16; const [showPromo, setShowPromo] = useState(false); const mainGridRef = useRef(null); // Inyección de estilos segura (Evita errores del parser con llaves dobles ) useEffect(() => { const style = document.createElement('style'); style.innerHTML = ` .no-scrollbar::-webkit-scrollbar { display: none; } .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; } `; document.head.appendChild(style); return () => { document.head.removeChild(style); }; }, []); // Efecto para mostrar el Pop-up Promocional a los 40 segundos useEffect(() => { // 40000ms = 40 segundos const timer = setTimeout(() => setShowPromo(true), 40000); return () => clearTimeout(timer); }, []); // Parsing encapsulado y robusto const parseDatabase = useCallback(() => { const lines = ELITE_DATABASE.trim().split(/\r?\n/); const parsedData = lines.map((line, index) => { const columns = line.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); if (columns.length < 2) return null; const name = columns[0]?.replace(/['"]+/g, '').trim(); if (!name || name === '""' || name.toLowerCase().includes('nombre')) return null; const email = columns[1]?.replace(/['"]+/g, '').trim() || ""; const phone = columns[2]?.replace(/['"]+/g, '').trim() || columns[3]?.replace(/['"]+/g, '').trim() || ""; const category = autoCategorize(name, email); const photoUrl = getReliableImage(category, name); const deterministicRating = getDeterministicRating(name); return { id: `proveedor-${index}-${name.replace(/\s+/g, '')}`, name, category, email: email.toUpperCase(), phone, image: photoUrl, rating: deterministicRating }; }).filter(Boolean); // Ordenamiento estricto por rating (desc) y nombre (asc) parsedData.sort((a, b) => { if (b.rating !== a.rating) return b.rating - a.rating; return a.name.localeCompare(b.name); }); return parsedData; }, []); useEffect(() => { const timer = setTimeout(() => { const data = parseDatabase(); setProviders(data); setIsLoading(false); }, 400); return () => clearTimeout(timer); }, [parseDatabase]); // Reseteo de paginación al filtrar useEffect(() => setCurrentPage(1), [searchTerm, activeCategory]); const dynamicCategories = useMemo(() => { const uniqueCategories = new Set(providers.map(p => p.category)); return ["TODOS", ...Array.from(uniqueCategories).sort()]; }, [providers]); const filteredProviders = useMemo(() => { return providers.filter(provider => { const matchesCategory = activeCategory === "TODOS" || provider.category === activeCategory; const searchLower = searchTerm.toLowerCase().trim(); const matchesSearch = searchLower === "" || provider.name.toLowerCase().includes(searchLower) || provider.category.toLowerCase().includes(searchLower); return matchesCategory && matchesSearch; }); }, [providers, activeCategory, searchTerm]); const totalPages = Math.ceil(filteredProviders.length / itemsPerPage); const paginatedProviders = useMemo(() => { const start = (currentPage - 1) * itemsPerPage; return filteredProviders.slice(start, start + itemsPerPage); }, [filteredProviders, currentPage]); const handleSearchSubmit = (e) => { e.preventDefault(); if (mainGridRef.current) { safeScrollTo(mainGridRef); } }; const handlePageChange = (newPage) => { setCurrentPage(newPage); safeScrollTo(mainGridRef); }; return (
{/* ========================================== */} {/* HERO SECTION */} {/* ========================================== */}
Detalle editorial de boda de lujo en Colombia

LOVIA
Directorio Premium.

{/* BUSCADOR */}

Más de {providers.length || 80} proveedores verificados

{/* ========================================== */} {/* NAVEGACIÓN DE CATEGORÍAS */} {/* ========================================== */} {/* ========================================== */} {/* ÁREA DE RESULTADOS */} {/* ========================================== */}
{isLoading ? "Cargando proveedores..." : `Mostrando ${filteredProviders.length} resultados`}
{isLoading ? ( ) : filteredProviders.length > 0 ? (
{paginatedProviders.map((provider) => ( ))}
{/* Paginación */} {totalPages > 1 && ( )}
) : (
)}
{/* ========================================== */} {/* POP-UP PROMOCIONAL */} {/* ========================================== */} {showPromo && setShowPromo(false)} />} {/* ========================================== */} {/* FOOTER */} {/* ========================================== */}
); }