@@ -616,6 +548,157 @@
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 data = await res.json();
+ // Response is [{ data: [...] }]
+ allExperts = (data[0] && data[0].data) || [];
+ renderExperts(allExperts);
+ } catch (err) {
+ document.getElementById('expertGridLoading').innerHTML = '
Error al cargar expertos. Intenta de nuevo más tarde.
';
+ }
+ }
+
+ function renderExperts(experts) {
+ const grid = document.getElementById('expertGrid');
+ const loading = document.getElementById('expertGridLoading');
+ if (loading) loading.remove();
+
+ if (!experts || experts.length === 0) {
+ grid.innerHTML = '
No hay expertos disponibles actualmente.
';
+ return;
+ }
+
+ grid.innerHTML = experts.map(ex => {
+ 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 tags = [...skills, ...modules].filter(Boolean).slice(0, 6);
+ const certified = ex.certified === 'yes' || ex.certified === true;
+ const hasRefs = ex.references && ex.references.length > 0;
+
+ // 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 `
+
+ ${ex.image
+ ? `

`
+ : `
${initials}
`
+ }
+ ${certified ? '
Certificado' : ''}
+
+
${ex.name || 'Sin nombre'}
+ ${ex.languages ? `
${ex.languages.split(',').map(l => l.trim() === 'spanish' ? 'Español' : l.trim() === 'english' ? 'Inglés' : l.trim()).join(' / ')}
` : ''}
+
${ex.summary || 'Sin descripción disponible.'}
+ ${tags.length > 0 ? `
${tags.map(t => `${t}`).join('')}
` : ''}
+
+ ${hasRefs ? `
` : ''}
+
+
+
`;
+ }).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 FILTERS =====
+ function filterExperts(filter) {
+ document.querySelectorAll('.filter-chip').forEach(chip => {
+ chip.classList.toggle('active', chip.dataset.filter === filter);
+ });
+ if (filter === 'all') {
+ renderExperts(allExperts);
+ } else if (filter === 'certified') {
+ renderExperts(allExperts.filter(ex => ex.certified === 'yes' || ex.certified === true));
+ } else {
+ // Filter by skills/modules containing the filter term
+ renderExperts(allExperts.filter(ex => {
+ const skills = (ex.skills || '').toLowerCase();
+ const modules = (ex.modules || '').toLowerCase();
+ const combined = skills + ' ' + modules;
+ // No way to programmatically determine funcional vs developer from API data
+ // Show all for now
+ return true;
+ }));
+ }
+ }
+
+ // Load experts on page load
+ loadExperts();
+
// ===== FORM SUBMISSION → n8n webhook =====
document.getElementById('expertSignupForm').addEventListener('submit', async function(e) {
e.preventDefault();