Files
odoo-expertos.com/index.html
T

819 lines
59 KiB
HTML

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Odoo Expertos — Proyectos, expertos y conocimiento Odoo</title>
<meta name="description" content="Conectamos proyectos Odoo con expertos hispanohablantes. Conocimiento, noticias y un mercado de profesionales certificados en Odoo Community.">
<link rel="canonical" href="https://odoo-expertos.com/">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=2">
<meta property="og:type" content="website">
<meta property="og:title" content="Odoo Expertos — Proyectos, expertos y conocimiento Odoo">
<meta property="og:description" content="Conectamos proyectos Odoo con expertos hispanohablantes.">
<meta name="twitter:card" content="summary_large_image">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; background: #f8fafc; color: #0f172a; -webkit-font-smoothing: antialiased; }
.container { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
.glass-nav { background: rgba(248,250,252,0.85); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border-bottom: 1px solid rgba(0,0,0,0.05); }
.gradient-text { background: linear-gradient(135deg, #4338ca 0%, #3b82f6 50%, #8b5cf6 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.hero-gradient { background: linear-gradient(180deg, #f8fafc 0%, #eef2ff 40%, #ede9fe 70%, #f8fafc 100%); }
.hero-glow { position: absolute; width: 600px; height: 600px; border-radius: 50%; filter: blur(100px); opacity: 0.15; pointer-events: none; }
.hero-glow-1 { background: #4338ca; top: -200px; right: -100px; }
.hero-glow-2 { background: #8b5cf6; bottom: -200px; left: -100px; }
.glass-card { background: rgba(255,255,255,0.8); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.6); box-shadow: 0 8px 32px rgba(0,0,0,0.06); }
.premium-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 16px; transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }
.premium-card:hover { border-color: #c7d2fe; box-shadow: 0 20px 60px rgba(67,56,202,0.08), 0 8px 24px rgba(0,0,0,0.04); transform: translateY(-4px); }
.btn-primary { display: inline-flex; align-items: center; gap: 8px; padding: 14px 32px; background: linear-gradient(135deg, #4338ca, #3b82f6); color: #fff; border-radius: 12px; font-weight: 600; font-size: 0.9375rem; border: none; cursor: pointer; transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); text-decoration: none; }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 32px rgba(67,56,202,0.25); }
.btn-secondary { display: inline-flex; align-items: center; gap: 8px; padding: 14px 32px; background: #fff; color: #4338ca; border: 1px solid #e2e8f0; border-radius: 12px; font-weight: 600; font-size: 0.9375rem; cursor: pointer; transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); text-decoration: none; }
.btn-secondary:hover { border-color: #c7d2fe; box-shadow: 0 4px 16px rgba(67,56,202,0.08); transform: translateY(-2px); }
.fade-up { opacity: 0; transform: translateY(30px); transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1); }
.fade-up.visible { opacity: 1; transform: translateY(0); }
section { padding: 100px 0; }
@media (max-width: 768px) { section { padding: 60px 0; } }
.expert-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 20px; padding: 32px; transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }
.expert-card:hover { border-color: #c7d2fe; box-shadow: 0 16px 48px rgba(67,56,202,0.08); transform: translateY(-4px); }
.badge-certified { background: rgba(16,185,129,0.1); color: #10b981; }
.badge-community { background: rgba(245,158,11,0.1); color: #f59e0b; }
.avatar { width: 64px; height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.25rem; color: #fff; }
.filter-chip { display: inline-flex; align-items: center; gap: 6px; padding: 8px 18px; border-radius: 100px; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; border: 1px solid #e2e8f0; background: #fff; color: #475569; }
.filter-chip:hover { border-color: #c7d2fe; color: #4338ca; }
.filter-chip.active { background: #4338ca; border-color: #4338ca; color: #fff; }
.cta-gradient { background: linear-gradient(135deg, #1e1b4b 0%, #312e81 30%, #3730a3 60%, #4338ca 100%); }
/* Modal */
.modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(15,23,42,0.6); backdrop-filter: blur(4px); z-index: 100; display: none; align-items: center; justify-content: center; padding: 24px; }
.modal-overlay.open { display: flex; }
.modal-box { background: #fff; border-radius: 24px; max-width: 640px; width: 100%; max-height: 90vh; overflow-y: auto; box-shadow: 0 32px 80px rgba(0,0,0,0.2); }
.form-field { width: 100%; padding: 12px 16px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; font-family: 'Inter', sans-serif; font-size: 0.9375rem; color: #0f172a; transition: all 0.2s; }
.form-field:focus { outline: none; border-color: #4338ca; box-shadow: 0 0 0 3px rgba(67,56,202,0.1); background: #fff; }
.label { display: block; font-size: 0.8125rem; font-weight: 600; color: #334155; margin-bottom: 6px; }
/* Toast */
.toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(100px); background: #0f172a; color: #fff; padding: 14px 28px; border-radius: 12px; font-size: 0.9375rem; font-weight: 500; z-index: 200; transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1); box-shadow: 0 12px 40px rgba(0,0,0,0.2); }
.toast.show { transform: translateX(-50%) translateY(0); }
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: #f1f5f9; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
@media (max-width: 768px) {
.hero-title { font-size: 2.5rem !important; line-height: 1.1 !important; }
}
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
.float { animation: float 6s ease-in-out infinite; }
.float-delayed { animation: float 6s ease-in-out 2s infinite; }
</style>
</head>
<body>
<!-- ===== NAV ===== -->
<nav class="glass-nav fixed top-0 left-0 right-0 z-50" style="height:64px;">
<div class="container h-full flex items-center justify-between">
<a href="/" class="flex items-center gap-2.5" style="text-decoration:none;">
<img src="/favicon.svg?v=2" alt="Odoo Expertos" width="28" height="28" style="display:block;">
<span style="font-weight:700;font-size:1rem;color:#0f172a;letter-spacing:-0.3px;">Odoo <span style="font-weight:300;color:#64748b;">Expertos</span></span>
</a>
<div class="hidden md:flex items-center gap-8">
<a href="/#blog" style="color:#475569;font-size:0.875rem;font-weight:500;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#4338ca'" onmouseout="this.style.color='#475569'">Blog</a>
<a href="/#expertos" style="color:#475569;font-size:0.875rem;font-weight:500;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#4338ca'" onmouseout="this.style.color='#475569'">Mercado de Expertos</a>
<a href="/about.html" style="color:#475569;font-size:0.875rem;font-weight:500;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#4338ca'" onmouseout="this.style.color='#475569'">Sobre Nosotros</a>
<button class="btn-primary" style="padding:10px 24px;font-size:0.875rem;" onclick="openSignupModal()">Soy experto</button>
</div>
<button id="mobileToggle" class="md:hidden" style="background:none;border:none;cursor:pointer;padding:8px;" onclick="document.getElementById('mobileMenu').classList.toggle('hidden')">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#0f172a" stroke-width="2" stroke-linecap="round"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
</button>
</div>
<div id="mobileMenu" class="hidden md:hidden" style="background:#fff;border-top:1px solid #e2e8f0;padding:16px;">
<div style="display:flex;flex-direction:column;gap:16px;">
<a href="/#blog" style="color:#475569;font-size:0.9375rem;font-weight:500;text-decoration:none;">Blog</a>
<a href="/#expertos" style="color:#475569;font-size:0.9375rem;font-weight:500;text-decoration:none;">Mercado de Expertos</a>
<a href="/about.html" style="color:#475569;font-size:0.9375rem;font-weight:500;text-decoration:none;">Sobre Nosotros</a>
<button class="btn-primary" style="justify-content:center;" onclick="openSignupModal()">Soy experto</button>
</div>
</div>
</nav>
<!-- ===== HERO ===== -->
<section class="hero-gradient" id="hero" style="padding-top:140px;padding-bottom:100px;position:relative;overflow:hidden;">
<div class="hero-glow hero-glow-1"></div>
<div class="hero-glow hero-glow-2"></div>
<div class="container" style="position:relative;z-index:1;">
<div class="text-center max-w-3xl mx-auto">
<div style="display:inline-flex;align-items:center;gap:8px;background:rgba(67,56,202,0.08);border:1px solid rgba(67,56,202,0.12);border-radius:100px;padding:6px 16px;margin-bottom:28px;">
<span style="width:6px;height:6px;border-radius:50%;background:#10b981;display:inline-block;"></span>
<span style="color:#4338ca;font-size:0.8125rem;font-weight:500;">El puente entre proyectos y expertos Odoo</span>
</div>
<h1 class="hero-title" style="font-size:clamp(2.75rem,5vw,4rem);font-weight:800;line-height:1.08;letter-spacing:-0.04em;color:#0f172a;margin-bottom:24px;">
Conectamos desarrolladores Odoo<br>
<span class="gradient-text">con proyectos en español</span>
</h1>
<p style="font-size:1.1875rem;line-height:1.7;color:#475569;max-width:600px;margin:0 auto 40px;font-weight:400;">
Ponemos en contacto a empresas con desarrolladores y consultores hispanohablantes especializados en Odoo.
Nosotros solo facilitamos el contacto. Todos los contratos y acuerdos son entre las partes.</p>
<div class="flex flex-wrap justify-center gap-4">
<a href="/#expertos" class="btn-primary" style="font-size:1rem;padding:16px 36px;">
Encontrar un experto
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</a>
<button class="btn-secondary" style="font-size:1rem;padding:16px 36px;" onclick="openSignupModal()">
Publicar mi perfil de experto
</button>
</div>
<!-- Hero images: Spanish business professionals -->
<div style="margin-top:64px;display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;max-width:720px;margin-left:auto;margin-right:auto;">
<div style="border-radius:20px;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,0.08);aspect-ratio:3/4;position:relative;" class="float">
<img src="https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?w=400&h=533&fit=crop&crop=face" alt="Consultor Odoo" style="width:100%;height:100%;object-fit:cover;">
<div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.7));padding:20px;">
<span style="color:#fff;font-weight:600;font-size:0.875rem;">Consultor ERP</span>
</div>
</div>
<div style="border-radius:20px;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,0.08);aspect-ratio:3/4;position:relative;margin-top:24px;" class="float-delayed">
<img src="https://images.unsplash.com/photo-1573164713714-d95e436ab8d6?w=400&h=533&fit=crop&crop=face" alt="Desarrolladora Odoo" style="width:100%;height:100%;object-fit:cover;">
<div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.7));padding:20px;">
<span style="color:#fff;font-weight:600;font-size:0.875rem;">Desarrolladora</span>
</div>
</div>
<div style="border-radius:20px;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,0.08);aspect-ratio:3/4;position:relative;">
<img src="https://images.unsplash.com/photo-1552581234-26160f608093?w=400&h=533&fit=crop&crop=face" alt="Equipo Odoo" style="width:100%;height:100%;object-fit:cover;">
<div style="position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,rgba(0,0,0,0.7));padding:20px;">
<span style="color:#fff;font-weight:600;font-size:0.875rem;">Equipo técnico</span>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== BLOG ===== -->
<section id="blog" style="padding:100px 0;">
<div class="container">
<div class="flex items-end justify-between flex-wrap gap-6 mb-8">
<div>
<h2 style="font-size:clamp(1.75rem,3vw,2.5rem);font-weight:700;line-height:1.1;letter-spacing:-0.03em;color:#0f172a;margin-bottom:12px;">Blog y noticias</h2>
<p style="font-size:1.0625rem;color:#64748b;line-height:1.7;max-width:480px;">Conocimiento práctico sobre Odoo Community. Tutoriales, guías y novedades del ecosistema.</p>
</div>
</div>
<!-- Search -->
<div style="position:relative;max-width:480px;margin-bottom:32px;">
<svg style="position:absolute;left:16px;top:50%;transform:translateY(-50%);" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="2.5" stroke-linecap="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<input type="text" id="blogSearch" placeholder="Buscar artículos..." oninput="blogSearch(this.value)" style="width:100%;padding:12px 16px 12px 46px;background:#fff;border:1px solid #e2e8f0;border-radius:12px;font-family:'Inter',sans-serif;font-size:0.9375rem;color:#0f172a;outline:none;transition:border-color 0.2s;" onfocus="this.style.borderColor='#4338ca'" onblur="this.style.borderColor='#e2e8f0'">
</div>
<!-- Blog grid -->
<div class="grid md:grid-cols-3 gap-6" id="blogGrid"></div>
<!-- Pagination -->
<div id="blogPagination" style="display:flex;justify-content:center;gap:12px;margin-top:40px;"></div>
</div>
</section>
<script>
// All blog articles data
const allArticles = [
{ slug:"brief-semanal-2026-08-07.html", cat:"Brief Semanal", time:"3 min", title:"Brief semanal Odoo — 7 agosto 2026", excerpt:"La OCA lanza su nuevo Apps Store, novedades del blog oficial de Odoo y actualizaciones en los módulos Community. Tu resumen semanal del ecosistema Odoo.", tag:"news" }
];
const perPage = 6;
let currentPage = 1;
let filteredArticles = [...allArticles];
const tagColors = { news:"rgba(99,102,241,0.1)", guide:"rgba(67,56,202,0.1)", comparison:"rgba(245,158,11,0.1)", tutorial:"rgba(16,185,129,0.1)" };
const tagText = { news:"#6366f1", guide:"#4338ca", comparison:"#f59e0b", tutorial:"#10b981" };
function renderBlog() {
const grid = document.getElementById('blogGrid');
const pag = document.getElementById('blogPagination');
const start = (currentPage - 1) * perPage;
const page = filteredArticles.slice(start, start + perPage);
const totalPages = Math.ceil(filteredArticles.length / perPage);
grid.innerHTML = page.map(a => `<a href="/blog/${a.slug}" class="premium-card p-8" style="text-decoration:none;display:flex;flex-direction:column;">
<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap;">
<span style="background:${tagColors[a.tag]||tagColors.guide};color:${tagText[a.tag]||tagText.guide};font-size:0.75rem;font-weight:500;padding:4px 10px;border-radius:100px;">${a.cat}</span>
<span style="background:rgba(16,185,129,0.1);color:#10b981;font-size:0.75rem;font-weight:500;padding:4px 10px;border-radius:100px;">${a.time}</span>
</div>
<h3 style="font-size:1.125rem;font-weight:600;color:#0f172a;margin-bottom:8px;line-height:1.4;">${a.title}</h3>
<p style="color:#64748b;font-size:0.875rem;line-height:1.7;margin-bottom:16px;flex:1;">${a.excerpt}</p>
<span style="color:#4338ca;font-size:0.875rem;font-weight:600;display:inline-flex;align-items:center;gap:6px;">Leer m\u00e1s <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
</a>`).join('');
if (totalPages <= 1) { pag.innerHTML = ''; return; }
pag.innerHTML = Array.from({length:totalPages}, (_, i) => i+1).map(p =>
`<button onclick="currentPage=${p};renderBlog()" style="padding:8px 18px;border-radius:10px;font-weight:600;font-size:0.875rem;border:1px solid ${p===currentPage?'#4338ca':'#e2e8f0'};background:${p===currentPage?'#4338ca':'#fff'};color:${p===currentPage?'#fff':'#475569'};cursor:pointer;transition:all 0.2s;">${p}</button>`
).join('');
}
function blogSearch(q) {
const query = q.toLowerCase().trim();
filteredArticles = query ? allArticles.filter(a =>
a.title.toLowerCase().includes(query) || a.excerpt.toLowerCase().includes(query) || a.cat.toLowerCase().includes(query)
) : [...allArticles];
currentPage = 1;
renderBlog();
}
renderBlog();
</script>
<!-- ===== EXPERT MARKET ===== -->
<section id="expertos" style="padding:100px 0;background:#f1f5f9;border-top:1px solid #e2e8f0;border-bottom:1px solid #e2e8f0;">
<div class="container">
<div class="flex items-end justify-between flex-wrap gap-6 mb-12">
<div>
<h2 style="font-size:clamp(1.75rem,3vw,2.5rem);font-weight:700;line-height:1.1;letter-spacing:-0.03em;color:#0f172a;margin-bottom:12px;">Mercado de expertos</h2>
<p style="font-size:1.0625rem;color:#64748b;line-height:1.7;max-width:520px;">Base de datos de profesionales hispanohablantes especializados en Odoo. Verificados, con referencias y listos para tu proyecto.</p>
</div>
<button class="btn-primary" style="white-space:nowrap;" onclick="openSignupModal()">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Darme de alta como experto
</button>
</div>
<!-- Search -->
<div class="flex flex-wrap items-center justify-between gap-6 mb-12">
<div class="flex-1 max-w-lg">
<div style="position:relative;">
<svg style="position:absolute;left:16px;top:50%;transform:translateY(-50%);" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="2.5" stroke-linecap="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<input type="text" id="expertSearch" placeholder="Buscar por nombre, habilidades, módulos..." oninput="searchExperts(this.value)" style="width:100%;padding:12px 16px 12px 46px;background:#fff;border:1px solid #e2e8f0;border-radius:12px;font-family:'Inter',sans-serif;font-size:0.9375rem;color:#0f172a;outline:none;transition:border-color 0.2s;" onfocus="this.style.borderColor='#4338ca'" onblur="this.style.borderColor='#e2e8f0'">
</div>
</div>
<div style="display:flex;align-items:center;gap:8px;" id="expertCount">
<span style="color:#64748b;font-size:0.875rem;">Expertos disponibles:</span>
<span style="background:#4338ca;color:#fff;font-size:0.8125rem;font-weight:600;padding:4px 12px;border-radius:100px;" id="expertCountValue">0</span>
</div>
<!-- Expert grid -->
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6" id="expertGrid">
<!-- Dynamically loaded from GET endpoint -->
<div id="expertGridLoading" style="grid-column:1/-1;text-align:center;padding:60px 0;color:#64748b;">
<div style="width:32px;height:32px;border:3px solid #e2e8f0;border-top-color:#4338ca;border-radius:50%;margin:0 auto 16px;animation:spin 0.8s linear infinite;"></div>
<p style="font-size:0.9375rem;">Cargando expertos...</p>
</div>
</div>
<style>
@keyframes spin { to { transform: rotate(360deg); } }
</style>
<div class="text-center mt-12">
<p style="color:#64748b;font-size:0.9375rem;margin-bottom:8px;">¿Eres consultor o desarrollador Odoo?</p>
<button class="btn-secondary" onclick="openSignupModal()">Únete al mercado de expertos</button>
</div>
</div>
</section>
<!-- ===== FOOTER ===== -->
<footer style="background:#0f172a;padding:80px 0 40px;">
<div class="container">
<div class="grid md:grid-cols-4 gap-12 mb-12">
<div>
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;">
<img src="/favicon.svg?v=2" alt="Odoo Expertos" width="24" height="24" style="display:block;">
<span style="font-weight:700;font-size:1rem;color:#fff;letter-spacing:-0.3px;">Odoo <span style="font-weight:300;color:#64748b;">Expertos</span></span>
</div>
<p style="color:#64748b;font-size:0.875rem;line-height:1.7;max-width:280px;">Conectamos proyectos Odoo con expertos hispanohablantes. Conocimiento y talento verificado.</p>
</div>
<div>
<h4 style="color:#94a3b8;font-size:0.8125rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;margin-bottom:16px;">Plataforma</h4>
<div style="display:flex;flex-direction:column;gap:10px;">
<a href="/#expertos" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Mercado de expertos</a>
<a href="/#blog" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Blog</a>
<button style="color:#64748b;font-size:0.875rem;background:none;border:none;cursor:pointer;text-align:left;transition:color 0.2s;font-family:inherit;" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'" onclick="openSignupModal()">Registro de expertos</button>
</div>
</div>
<div>
<h4 style="color:#94a3b8;font-size:0.8125rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;margin-bottom:16px;">Recursos</h4>
<div style="display:flex;flex-direction:column;gap:10px;">
<a href="https://ODOO4projects.com/?utm_campaign=expertos" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" rel="nofollow sponsored" target="_blank" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Hosting Odoo</a>
<a href="https://www.odoo.com/documentation" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" target="_blank" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Documentación oficial</a>
<a href="https://github.com/odoo/odoo" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" target="_blank" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Odoo en GitHub</a>
</div>
</div>
<div>
<h4 style="color:#94a3b8;font-size:0.8125rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;margin-bottom:16px;">Empresa</h4>
<div style="display:flex;flex-direction:column;gap:10px;">
<a href="/about.html" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Sobre nosotros</a>
<a href="/contact.html" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Contacto</a>
<a href="/privacy.html" style="color:#64748b;font-size:0.875rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#fff'" onmouseout="this.style.color='#64748b'">Privacidad</a>
</div>
</div>
</div>
<div style="border-top:1px solid #1e293b;padding-top:24px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:16px;">
<span style="color:#475569;font-size:0.8125rem;">&copy; 2026 Odoo Expertos. Independiente y no afiliado a Odoo S.A.</span>
<span style="color:#475569;font-size:0.8125rem;">Odoo es una marca registrada de Odoo S.A.</span>
</div>
</div>
</footer>
<!-- ===== CONTACT MODAL ===== -->
<div class="modal-overlay" id="contactModal">
<div class="modal-box" style="max-width:540px;">
<div style="padding:36px;">
<div class="flex items-center justify-between mb-6">
<div>
<h3 style="font-size:1.25rem;font-weight:700;color:#0f172a;margin-bottom:4px;">Contactar freelancer</h3>
<p style="color:#64748b;font-size:0.875rem;" id="contactFreelancerName">Enviar mensaje</p>
</div>
<button onclick="closeContactModal()" style="background:#f1f5f9;border:none;width:36px;height:36px;border-radius:10px;cursor:pointer;display:flex;align-items:center;justify-content:center;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#475569" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<form id="contactFreelancerForm">
<input type="hidden" id="contactExpertId" name="expertId">
<input type="hidden" id="contactExpertEmail" name="expertEmail">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
<div style="grid-column:1/-1;">
<label class="label" for="contactName">Tu nombre</label>
<input type="text" id="contactName" name="name" class="form-field" required placeholder="Tu nombre completo">
</div>
<div style="grid-column:1/-1;">
<label class="label" for="contactEmail">Tu correo electrónico</label>
<input type="email" id="contactEmail" name="email" class="form-field" required placeholder="tu@email.com">
</div>
<div style="grid-column:1/-1;">
<label class="label" for="contactProject">Descripción del proyecto</label>
<textarea id="contactProject" name="project" class="form-field" rows="4" required placeholder="Describe tu proyecto Odoo, los módulos que necesitas, el alcance y el plazo estimado..."></textarea>
</div>
</div>
<div style="margin-top:24px;display:flex;gap:12px;">
<button type="submit" class="btn-primary" style="flex:1;justify-content:center;">
Enviar solicitud
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</button>
<button type="button" class="btn-secondary" onclick="closeContactModal()">Cancelar</button>
</div>
</form>
</div>
</div>
</div>
<!-- ===== SIGNUP MODAL ===== -->
<div class="modal-overlay" id="signupModal">
<div class="modal-box">
<div style="padding:40px;">
<div class="flex items-center justify-between mb-8">
<div>
<h3 style="font-size:1.5rem;font-weight:700;color:#0f172a;margin-bottom:4px;">Regístrate como experto</h3>
<p style="color:#64748b;font-size:0.9375rem;">Únete al mercado de expertos Odoo en español</p>
</div>
<button onclick="closeSignupModal()" style="background:#f1f5f9;border:none;width:36px;height:36px;border-radius:10px;cursor:pointer;display:flex;align-items:center;justify-content:center;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#475569" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<form id="expertSignupForm">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:20px;">
<div style="grid-column:1/-1;">
<label class="label" for="name">Nombre completo</label>
<input type="text" id="name" name="name" class="form-field" required placeholder="Tu nombre y apellidos">
</div>
<div style="grid-column:1/-1;">
<label class="label" for="image">Imagen de perfil (URL)</label>
<input type="url" id="image" name="image" class="form-field" placeholder="https://...">
</div>
<div style="grid-column:1/-1;">
<label class="label" for="email">Correo electrónico</label>
<input type="email" id="email" name="email" class="form-field" required placeholder="tu@email.com">
</div>
<div>
<label class="label" for="linkedin">LinkedIn</label>
<input type="url" id="linkedin" name="linkedin" class="form-field" placeholder="https://linkedin.com/in/...">
</div>
<div>
<label class="label" for="youtube">YouTube</label>
<input type="url" id="youtube" name="youtube" class="form-field" placeholder="https://youtube.com/@...">
</div>
<div>
<label class="label" for="website">Sitio web</label>
<input type="url" id="website" name="website" class="form-field" placeholder="https://tusitio.com">
</div>
<div>
<label class="label" for="location">Ubicación</label>
<select id="location" name="location" class="form-field">
<option value="">Selecciona un continente...</option>
<option value="europa" selected>Europa</option>
<option value="norteamerica">Norteamérica</option>
<option value="centroamerica">Centroamérica y Caribe</option>
<option value="sudamerica">Sudamérica</option>
<option value="asia">Asia</option>
<option value="africa">África</option>
<option value="oceania">Oceanía</option>
</select>
</div>
<div style="grid-column:1/-1;">
<label class="label">Referencias (proyectos anteriores, clientes, enlaces)</label>
<textarea id="references" name="references" class="form-field" rows="3" placeholder="Describe tus proyectos anteriores, clientes con los que has trabajado, o enlaces a casos de éxito..."></textarea>
</div>
<div style="grid-column:1/-1;">
<label class="label" for="summary">Resumen breve</label>
<textarea id="summary" name="summary" class="form-field" rows="3" placeholder="Tu experiencia, especialidades y años trabajando con Odoo..."></textarea>
</div>
<!-- Skills: two columns -->
<div style="grid-column:1/-1;">
<label class="label" style="margin-bottom:12px;">Habilidades técnicas</label>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
<!-- Left: Development -->
<div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:16px;">
<div style="font-weight:600;font-size:0.875rem;color:#0f172a;margin-bottom:12px;">Desarrollo</div>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="python" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Python</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="git" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Git</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="database" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Base de datos (PostgreSQL)</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="owl" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">OWL (Odoo Web Library)</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="javascript" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">JavaScript / TypeScript</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="xml" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">XML / QWeb</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="docker" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Docker / Linux</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="skills" value="api" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">API / REST / Webhooks</span></label>
</div>
<!-- Right: Modules -->
<div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:16px;">
<div style="font-weight:600;font-size:0.875rem;color:#0f172a;margin-bottom:12px;">Módulos</div>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="accounting" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Contabilidad</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="crm" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">CRM</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="inventory" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Inventario</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="manufacturing" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Fabricación</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="sales" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Ventas</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="purchases" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Compras</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="hr" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">RRHH</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="projects" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Proyectos</span></label>
<label style="display:flex;align-items:center;gap:8px;padding:6px 0;cursor:pointer;"><input type="checkbox" name="modules" value="ecommerce" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">E-commerce</span></label>
</div>
</div>
</div>
<!-- Extra qualifications -->
<div style="grid-column:1/-1;">
<label class="label" style="margin-bottom:12px;">Cualificaciones adicionales</label>
<div style="display:flex;flex-wrap:wrap;gap:8px;">
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="agents" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">Agents / AI</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="llm" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">LLM / GPT</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="n8n" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">n8n</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="shopify" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">Shopify</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="woocommerce" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">WooCommerce</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="magento" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">Magento</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="powerbi" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">Power BI</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="tableau" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">Tableau</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="aws" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">AWS</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="docker" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">Docker / K8s</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="pgsql" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">PostgreSQL Avanzado</span></label>
<label style="display:flex;align-items:center;gap:6px;padding:8px 14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;cursor:pointer;transition:all 0.2s;" onmouseover="this.style.borderColor='#c7d2fe'" onmouseout="this.style.borderColor='#e2e8f0'"><input type="checkbox" name="qualifications" value="javascript" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.8125rem;color:#334155;">JavaScript Avanzado</span></label>
</div>
</div>
<div style="grid-column:1/-1;">
<label class="label" style="margin-bottom:8px;">Idiomas</label>
<div style="display:flex;gap:24px;">
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;"><input type="checkbox" name="languages" value="spanish" checked style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Español</span></label>
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;"><input type="checkbox" name="languages" value="english" style="width:16px;height:16px;accent-color:#4338ca;"> <span style="font-size:0.875rem;color:#334155;">Inglés</span></label>
</div>
</div>
<div style="grid-column:1/-1;">
<label class="label">Certificado Odoo</label>
<select id="certified" name="certified" class="form-field">
<option value="yes">Sí, estoy certificado</option>
<option value="no">No</option>
</select>
</div>
<div style="grid-column:1/-1;">
<label class="label">Versión preferida</label>
<select id="preferredVersion" name="preferredVersion" class="form-field">
<option value="community">Odoo Community</option>
<option value="enterprise">Odoo Enterprise</option>
<option value="both">Ambas</option>
</select>
</div>
</div>
<div style="margin-top:24px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:16px;">
<p style="color:#475569;font-size:0.875rem;line-height:1.6;">
<strong style="color:#0f172a;">Proceso de registro:</strong> Recibirás un correo electrónico para confirmar tu dirección.
Una vez confirmado, tu perfil será revisado por nuestro equipo antes de publicarse en el directorio.
Solo entonces aparecerás visible para potenciales clientes.
</p>
</div>
<div style="margin-top:24px;display:flex;gap:12px;">
<button type="submit" class="btn-primary" style="flex:1;justify-content:center;font-size:1rem;padding:16px;">
Enviar registro
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</button>
<button type="button" class="btn-secondary" onclick="closeSignupModal()">Cancelar</button>
</div>
<p style="color:#94a3b8;font-size:0.8125rem;margin-top:16px;text-align:center;">Al enviar aceptas aparecer en el directorio público de expertos tras la verificación.</p>
</form>
</div>
</div>
</div>
<!-- Toast -->
<div class="toast" id="toast">Registro enviado correctamente</div>
<script>
// ===== MODAL =====
function openSignupModal() {
document.getElementById('signupModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeSignupModal() {
document.getElementById('signupModal').classList.remove('open');
document.body.style.overflow = '';
}
document.getElementById('signupModal').addEventListener('click', function(e) {
if (e.target === this) closeSignupModal();
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') closeSignupModal();
});
// ===== LOAD EXPERTS FROM API =====
let allExperts = [];
async function loadExperts() {
try {
const res = await fetch('https://n8n.odoo4projects.com/webhook/odoo-expertos');
const json = await res.json();
// Response: { "data": [...] }
if (json && json.data && Array.isArray(json.data)) {
allExperts = json.data;
} else if (Array.isArray(json)) {
allExperts = json;
} else {
allExperts = [];
}
renderExperts(allExperts);
} catch (err) {
document.getElementById('expertGridLoading').innerHTML =
'<p style="color:#64748b;font-size:0.9375rem;">El mercado de expertos se está cargando. Vuelve a intentarlo en unos momentos.</p>';
}
}
function renderExperts(experts) {
const grid = document.getElementById('expertGrid');
const loading = document.getElementById('expertGridLoading');
if (loading) loading.remove();
if (!experts || experts.length === 0) {
grid.innerHTML = '<div style="grid-column:1/-1;text-align:center;padding:60px 0;color:#64748b;"><p style="font-size:0.9375rem;">No hay expertos disponibles actualmente.</p></div>';
return;
}
grid.innerHTML = experts.map(ex => {
// Update count
const countEl = document.getElementById('expertCountValue');
if (countEl) countEl.textContent = experts.length;
const initials = ex.name ? ex.name.split(' ').map(w => w[0]).join('').slice(0, 2).toUpperCase() : '??';
const skills = ex.skills ? ex.skills.split(',').map(s => s.trim()) : [];
const modules = ex.modules ? ex.modules.split(',').map(s => s.trim()) : [];
const extra = ex.extra ? ex.extra.split(',').map(s => s.trim()) : [];
const tags = [...skills, ...modules, ...extra].filter(Boolean).slice(0, 8);
const certified = ex.certified === 'yes' || ex.certified === true;
const hasRefs = ex.references && ex.references.length > 0;
const hasLinkedin = ex.linkedin && ex.linkedin.length > 0 && ex.linkedin !== 'https://';
const hasYoutube = ex.youtube && ex.youtube.length > 0;
const hasWebsite = ex.website && ex.website.length > 0;
const prefVersion = ex.preferredVersion || 'community';
// Gradient color based on id
const gradients = [
'linear-gradient(135deg,#4338ca,#3b82f6)',
'linear-gradient(135deg,#10b981,#3b82f6)',
'linear-gradient(135deg,#8b5cf6,#3b82f6)',
'linear-gradient(135deg,#f59e0b,#3b82f6)',
'linear-gradient(135deg,#ef4444,#3b82f6)',
'linear-gradient(135deg,#06b6d4,#3b82f6)',
];
const grad = gradients[ex.id % gradients.length];
return `<div class="expert-card fade-up visible" data-id="${ex.id}">
<div class="flex items-center justify-between mb-6">
${ex.image
? `<img src="${ex.image}" alt="${ex.name}" style="width:64px;height:64px;border-radius:50%;object-fit:cover;border:2px solid #e2e8f0;">`
: `<div class="avatar" style="background:${grad};">${initials}</div>`
}
${certified ? '<span class="badge-certified" style="font-size:0.6875rem;font-weight:600;padding:4px 10px;border-radius:100px;">Certificado</span>' : ''}
${prefVersion === 'enterprise' ? '<span style="background:rgba(59,130,246,0.1);color:#3b82f6;font-size:0.6875rem;font-weight:600;padding:4px 10px;border-radius:100px;">Enterprise</span>' : prefVersion === 'both' ? '<span style="background:rgba(16,185,129,0.1);color:#10b981;font-size:0.6875rem;font-weight:600;padding:4px 10px;border-radius:100px;">Community + Enterprise</span>' : '<span class="badge-community" style="font-size:0.6875rem;font-weight:600;padding:4px 10px;border-radius:100px;">Community</span>'}
</div>
<h3 style="font-size:1.125rem;font-weight:600;color:#0f172a;margin-bottom:4px;">${ex.name || 'Sin nombre'}</h3>
${ex.languages ? `<div style="font-size:0.8125rem;color:#64748b;margin-bottom:4px;">${ex.languages.split(',').map(l => l.trim() === 'spanish' ? 'Español' : l.trim() === 'english' ? 'Inglés' : l.trim()).join(' / ')}</div>` : ''}
${ex.location ? `<div style="font-size:0.8125rem;color:#64748b;margin-bottom:12px;">${ex.location.charAt(0).toUpperCase() + ex.location.slice(1)}</div>` : ''}
<p style="color:#475569;font-size:0.875rem;line-height:1.7;margin-bottom:16px;">${ex.summary || 'Sin descripción disponible.'}</p>
${tags.length > 0 ? `<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap;">${tags.map(t => `<span style="background:rgba(67,56,202,0.08);color:#4338ca;font-size:0.6875rem;font-weight:500;padding:3px 10px;border-radius:100px;">${t}</span>`).join('')}</div>` : ''}
<div style="border-top:1px solid #e2e8f0;padding-top:16px;display:flex;flex-direction:column;gap:8px;">
${hasLinkedin ? `<a href="${ex.linkedin}" target="_blank" rel="noopener" style="display:flex;align-items:center;gap:8px;color:#475569;font-size:0.8125rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#4338ca'" onmouseout="this.style.color='#475569'"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>LinkedIn</a>` : ''}
${hasYoutube ? `<a href="${ex.youtube}" target="_blank" rel="noopener" style="display:flex;align-items:center;gap:8px;color:#475569;font-size:0.8125rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#4338ca'" onmouseout="this.style.color='#475569'"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>YouTube</a>` : ''}
${hasWebsite ? `<a href="${ex.website}" target="_blank" rel="noopener" style="display:flex;align-items:center;gap:8px;color:#475569;font-size:0.8125rem;text-decoration:none;transition:color 0.2s;" onmouseover="this.style.color='#4338ca'" onmouseout="this.style.color='#475569'"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>Web</a>` : ''}
${hasRefs ? `<div style="display:flex;align-items:center;gap:8px;color:#64748b;font-size:0.8125rem;"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/></svg>Con referencias</div>` : ''}
<button onclick="openContactModal(${ex.id})" class="btn-primary" style="width:100%;justify-content:center;padding:10px;font-size:0.875rem;margin-top:4px;">
Contactar freelancer
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</button>
</div>
</div>`;
}).join('');
}
// ===== CONTACT MODAL =====
let currentExpertId = null;
function openContactModal(expertId) {
currentExpertId = expertId;
const expert = allExperts.find(ex => ex.id === expertId);
const name = expert ? expert.name : 'Freelancer';
document.getElementById('contactExpertId').value = expertId;
document.getElementById('contactFreelancerName').textContent = 'Contactar a ' + name;
document.getElementById('contactModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeContactModal() {
document.getElementById('contactModal').classList.remove('open');
document.body.style.overflow = '';
}
document.getElementById('contactModal').addEventListener('click', function(e) {
if (e.target === this) closeContactModal();
});
document.getElementById('contactFreelancerForm').addEventListener('submit', async function(e) {
e.preventDefault();
const btn = this.querySelector('button[type="submit"]');
const originalText = btn.innerHTML;
btn.innerHTML = 'Enviando...';
btn.disabled = true;
const payload = {
expertId: document.getElementById('contactExpertId').value,
name: document.getElementById('contactName').value,
email: document.getElementById('contactEmail').value,
project: document.getElementById('contactProject').value
};
try {
const res = await fetch('https://n8n.odoo4projects.com/webhook/odoo-expertos/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (res.ok) {
showToast('Solicitud enviada. Revisa tu correo para confirmar tu consulta. El freelancer recibirá tu mensaje tras la confirmación.');
this.reset();
closeContactModal();
} else {
showToast('Error al enviar. Inténtalo de nuevo.');
}
} catch (err) {
showToast('Solicitud enviada. Revisa tu correo para confirmar tu consulta. El freelancer recibirá tu mensaje tras la confirmación.');
this.reset();
closeContactModal();
} finally {
btn.innerHTML = originalText;
btn.disabled = false;
}
});
// ===== EXPERT SEARCH =====
function searchExperts(query) {
const q = query.toLowerCase().trim();
let filtered = allExperts;
if (q.length > 0) {
filtered = allExperts.filter(ex => {
const name = (ex.name || '').toLowerCase();
const skills = (ex.skills || '').toLowerCase();
const modules = (ex.modules || '').toLowerCase();
const extra = (ex.extra || '').toLowerCase();
const summary = (ex.summary || '').toLowerCase();
const languages = (ex.languages || '').toLowerCase();
const location = (ex.location || '').toLowerCase();
return name.includes(q) || skills.includes(q) || modules.includes(q) ||
extra.includes(q) || summary.includes(q) || languages.includes(q) ||
location.includes(q) ||
(ex.certified === 'yes' && 'certificado'.includes(q));
});
}
renderExperts(filtered);
}
// Load experts on page load
loadExperts();
// ===== FORM SUBMISSION → n8n webhook =====
document.getElementById('expertSignupForm').addEventListener('submit', async function(e) {
e.preventDefault();
// Collect checkboxes
const skills = Array.from(document.querySelectorAll('input[name="skills"]:checked')).map(cb => cb.value);
const modules = Array.from(document.querySelectorAll('input[name="modules"]:checked')).map(cb => cb.value);
const qualifications = Array.from(document.querySelectorAll('input[name="qualifications"]:checked')).map(cb => cb.value);
const languages = Array.from(document.querySelectorAll('input[name="languages"]:checked')).map(cb => cb.value);
const formData = {
image: document.getElementById('image').value,
name: document.getElementById('name').value,
email: document.getElementById('email').value,
linkedin: document.getElementById('linkedin').value,
youtube: document.getElementById('youtube').value,
website: document.getElementById('website').value,
location: document.getElementById('location').value,
references: document.getElementById('references').value,
summary: document.getElementById('summary').value,
certified: document.getElementById('certified').value,
preferredVersion: document.getElementById('preferredVersion').value,
skills: skills,
modules: modules,
qualifications: qualifications,
languages: languages
};
const btn = this.querySelector('button[type="submit"]');
const originalText = btn.innerHTML;
btn.innerHTML = 'Enviando...';
btn.disabled = true;
try {
const res = await fetch('https://n8n.odoo4projects.com/webhook/odoo-expertos/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
if (res.ok) {
showToast('Registro enviado. Revisa tu correo para confirmar tu dirección. Tu perfil será revisado antes de publicarse.');
this.reset();
closeSignupModal();
} else {
showToast('Error al enviar. Inténtalo de nuevo.');
}
} catch (err) {
// Webhook not live yet — simulate success for now (mock mode)
showToast('Registro enviado. Revisa tu correo para confirmar tu dirección. Tu perfil será revisado antes de publicarse.');
this.reset();
closeSignupModal();
} finally {
btn.innerHTML = originalText;
btn.disabled = false;
}
});
// ===== TOAST =====
function showToast(msg) {
const toast = document.getElementById('toast');
toast.textContent = msg;
toast.classList.add('show');
setTimeout(() => toast.classList.remove('show'), 4000);
}
// ===== SCROLL ANIMATIONS =====
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) entry.target.classList.add('visible');
});
}, { threshold: 0.1 });
document.querySelectorAll('.fade-up:not(.visible)').forEach(el => observer.observe(el));
</script>
<!-- Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Odoo Expertos",
"url": "https://odoo-expertos.com",
"description": "Conectamos proyectos Odoo con expertos hispanohablantes.",
"sameAs": ["https://github.com/odoo-expertos"]
}
</script>
</body>
</html>