`; } async function loadEnquiries() { const [enquiriesData, partnersData] = await Promise.all([ api('/api/enquiries'), api('/api/partners') ]); const enquiries = enquiriesData.enquiries || []; const partners = partnersData.partners || []; document.getElementById('admin-content').innerHTML = `

Consultas (${enquiries.length})

${enquiries.length > 0 ? `
${enquiries.map(e => ` `).join('')}
Ref Nombre de Empresa Nombre de Contacto Cantidad Requerida Status Partner Acciones
${escapeHtml(e.enquiry_number || '-')} ${escapeHtml(e.company)} ${escapeHtml(e.contact_name)}
${escapeHtml(e.email)}
${e.quantity}
` : '
No se encontraron resultados
'}
`; } async function updateEnquiryStatus(id, status) { await api('/api/enquiries/' + id + '/status', { method: 'PUT', body: JSON.stringify({ status }) }); } async function assignEnquiry(id, partnerId) { await api('/api/enquiries/' + id + '/assign', { method: 'PUT', body: JSON.stringify({ partner_id: partnerId }) }); } async function loadProducts() { const data = await api('/api/products'); const products = data.products || []; document.getElementById('admin-content').innerHTML = `

Productos (${products.length})

${products.length > 0 ? `
${products.map(p => ` `).join('')}
Image Name Category Price Country Status Acciones
${p.image_url ? '' : '
'}
${escapeHtml(p.name)}${p.featured ? ' ' : ''} ${escapeHtml(p.category)} ${formatPrice(p.price_min || p.base_price, p.price_max) || '-'} ${escapeHtml(p.country)} ${p.status}
` : '
No se encontraron resultados
'}
`; } function showAddProductForm() { document.getElementById('product-form').style.display = 'block'; } function hideProductForm() { document.getElementById('product-form').style.display = 'none'; } function previewProductImage(url) { const preview = document.getElementById('prod-image-preview'); const img = document.getElementById('prod-image-preview-img'); if (!url) { preview.style.display = 'none'; return; } // Validate URL pattern const invalidPatterns = [ /^https:\/\/imgur\.com\/a\//, /^https:\/\/imgur\.com\/gallery\//, /^https:\/\/ibb\.co\/[^\/]+$/ ]; for (const pattern of invalidPatterns) { if (pattern.test(url)) { preview.style.display = 'block'; preview.innerHTML = '❌ This is a PAGE URL, not a direct image URL. Right-click the image and copy the image address.'; return; } } preview.style.display = 'block'; preview.innerHTML = ''; } async function saveProduct(e) { e.preventDefault(); const res = await api('/api/products', { method: 'POST', body: JSON.stringify({ name: document.getElementById('prod-name').value, description: document.getElementById('prod-description').value, category: document.getElementById('prod-category').value, country: document.getElementById('prod-country').value, price_min: document.getElementById('prod-price-min').value, price_max: document.getElementById('prod-price-max').value, moq: document.getElementById('prod-moq').value, image_url: document.getElementById('prod-image').value, featured: document.getElementById('prod-featured').checked }) }); if (res.success) { hideProductForm(); loadProducts(); } else { alert(res.error || 'Error'); } } async function deleteProduct(id) { if (!confirm('¿Está seguro de que desea eliminar?')) return; await api('/api/products/' + id, { method: 'DELETE' }); loadProducts(); } async function loadBanners() { const data = await api('/api/banners/all'); const banners = data.banners || []; document.getElementById('admin-content').innerHTML = `

Banners

${banners.length > 0 ? banners.map(b => `
${b.image_url ? '' : ''}
${escapeHtml(b.title)}

${escapeHtml(b.subtitle || '')}

${b.active ? 'Active' : 'Inactive'}
`).join('') : '
No se encontraron resultados
'}
`; } function showAddBannerForm() { document.getElementById('banner-form').style.display = 'block'; } async function saveBanner(e) { e.preventDefault(); const res = await api('/api/banners', { method: 'POST', body: JSON.stringify({ title: document.getElementById('banner-title').value, subtitle: document.getElementById('banner-subtitle').value, image_url: document.getElementById('banner-image').value }) }); if (res.success) { document.getElementById('banner-form').style.display = 'none'; loadBanners(); } } async function deleteBanner(id) { if (!confirm('¿Está seguro de que desea eliminar?')) return; await api('/api/banners/' + id, { method: 'DELETE' }); loadBanners(); } async function loadUsers() { const data = await api('/api/users'); const users = data.users || []; document.getElementById('admin-content').innerHTML = `

Usuarios (${users.length})

${users.map(u => ` `).join('')}
CorreoNombre de EmpresaRoleStatus
${escapeHtml(u.email)} ${escapeHtml(u.company || '-')} ${u.role} ${u.status}
`; } async function loadPartners() { const data = await api('/api/partners'); const partners = data.partners || []; document.getElementById('admin-content').innerHTML = `

Socios (${partners.length})

${partners.length > 0 ? `
${partners.map(p => ` `).join('')}
PartnerPaísCorreoEnquiriesStatusAcciones
${escapeHtml(p.name)} ${escapeHtml(p.country)} ${escapeHtml(p.email)} ${p.enquiry_count || 0}
` : '
No se encontraron resultados
'}
`; } function showAddPartnerForm() { document.getElementById('partner-form').style.display = 'block'; } async function savePartner(e) { e.preventDefault(); const res = await api('/api/partners', { method: 'POST', body: JSON.stringify({ name: document.getElementById('partner-name').value, country: document.getElementById('partner-country').value, email: document.getElementById('partner-email').value, password: document.getElementById('partner-password').value }) }); if (res.success) { document.getElementById('partner-form').style.display = 'none'; loadPartners(); } else { alert(res.error || 'Error'); } } async function updatePartnerStatus(id, status) { await api('/api/partners/' + id + '/status', { method: 'PUT', body: JSON.stringify({ status }) }); } async function deletePartner(id) { if (!confirm('¿Está seguro de que desea eliminar?')) return; await api('/api/partners/' + id, { method: 'DELETE' }); loadPartners(); } async function loadSettings() { const data = await api('/api/settings'); const settings = data.settings || {}; document.getElementById('admin-content').innerHTML = `

Configuración

Marca
Ingrese la URL de su logo (recomendado: 200x50px) - Use direct image URL (not page URL)
${settings.logo_url ? '' : ''}
Configuración de Email
Live Chat (Tawk.to)
Show Tawk.to chat widget on all pages
Find in Tawk.to Dashboard → Administration → Property Settings
Usually starts with "1" followed by letters/numbers
`; } async function saveSettings(e, type) { e.preventDefault(); let data = {}; if (type === 'branding') { data.platform_name = document.getElementById('setting-platform-name').value; data.logo_url = document.getElementById('setting-logo-url').value; } else if (type === 'email') { data.resend_api_key = document.getElementById('setting-resend-key').value; data.admin_email = document.getElementById('setting-admin-email').value; } else if (type === 'chat') { data.tawk_enabled = document.getElementById('setting-tawk-enabled').checked ? 'true' : 'false'; data.tawk_property_id = document.getElementById('setting-tawk-property').value; data.tawk_widget_id = document.getElementById('setting-tawk-widget').value; } const res = await api('/api/settings', { method: 'POST', body: JSON.stringify(data) }); if (res.success) { alert('Éxito'); loadSettings(); } } async function testEmail() { const res = await api('/api/settings/test-email', { method: 'POST' }); alert(res.success ? 'Email sent!' : (res.error || 'Failed')); } function formatPrice(min, max) { if (!min && !max) return null; min = parseFloat(min) || 0; max = parseFloat(max) || 0; if (min && max && min !== max) return '$' + min.toFixed(2) + ' - $' + max.toFixed(2); return '$' + (min || max).toFixed(2); } function escapeHtml(s) { return s ? String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"') : ''; } // Start loadAdminTab();
Confirm
Are you sure?