/* ========================================================= CONFIGURACIÓN CENTRAL DEL SITIO — PURELABS MÉXICO ----------------------------------------------------------- Edita SOLO este archivo para actualizar los datos de contacto/negocio en TODO el sitio (header, footer, botón flotante de WhatsApp, checkout por WhatsApp, etc.). Los valores marcado con [ ] son placeholders: reemplázalos por tus datos reales antes de publicar el sitio. ========================================================= */ const SITE_CONFIG = { // Identidad brandName: "Purelabs México", tagline: "Péptidos de grado investigación, calidad certificada", // Contacto — reemplaza con tus datos reales whatsappNumber: "5215655653224", // formato: 52 + 10 dígitos, sin espacios ni signos whatsappDisplay: "+52 56 5565 3224", // ej. +52 55 0000 0000 email: "atencionaclientes@purelabs.mx", city: "Monterrey, Nuevo León", addressLine: "[DIRECCIÓN FISCAL / CENTRO DE OPERACIONES]", // Datos fiscales — persona moral (para sección de facturación) razonSocial: "[RAZÓN SOCIAL S.A. DE C.V.]", rfc: "[RFC DE LA EMPRESA]", regimenFiscal: "[RÉGIMEN FISCAL]", // Mensajes de WhatsApp whatsappGreeting: "Hola, bienvenido a Purelabs México. ¿Podemos ayudarte con información de catálogo, COA o tu pedido?", // Métodos de pago que se muestran en el sitio (edítalos según lo que actives) paymentMethods: ["Transferencia SPEI", "Tarjeta de crédito/débito (próximamente vía pasarela)", "Mercado Pago (por integrar)", "USDT / BTC (opcional)"], }; // ---- Helpers para construir enlaces de WhatsApp ---- function buildWhatsAppLink(message){ const base = "https://wa.me/" + SITE_CONFIG.whatsappNumber; return message ? base + "?text=" + encodeURIComponent(message) : base; } /* ========================================================= PURELABS MÉXICO — Catálogo base (7 SKU estrella) ----------------------------------------------------------- Todos los precios son PLACEHOLDER en MXN — ajústalos a tu costo real antes de publicar. Las rutas "img" apuntan a /img/productos/ — ver img/productos/LEEME.txt para los nombres y tamaños exactos de imagen que debes subir. ========================================================= */ const PRODUCTS = [ { id: "bpc-157", name: "BPC-157", tag: "Más vendido", category: "Reparación / Recuperación", short: "Péptido sintético de investigación estudiado por su rol en modelos de reparación tisular y recuperación.", purity: "99.2%", presentations: [ { label: "5 mg", price: 990 }, { label: "10 mg", price: 1690 }, ], img: "img/productos/bpc-157.jpg", }, { id: "tb-500", name: "TB-500", tag: "Popular", category: "Reparación / Recuperación", short: "Fragmento sintético de Timosina Beta-4, utilizado en investigación de modelos de regeneración tisular.", purity: "99.1%", presentations: [ { label: "5 mg", price: 1050 }, { label: "10 mg", price: 1790 }, ], img: "img/productos/tb-500.jpg", }, { id: "cjc-1295-ipamorelin", name: "CJC-1295 / Ipamorelin Blend", tag: "Combo", category: "Eje GH / Secretagogos", short: "Combinación de análogo de GHRH y secretagogo selectivo de GH, ampliamente referenciada en literatura de investigación.", purity: "99.3%", presentations: [ { label: "5 mg blend", price: 1290 }, { label: "10 mg blend", price: 2190 }, ], img: "img/productos/cjc-1295-ipamorelin.jpg", }, { id: "semaglutida", name: "Semaglutida", tag: "Alta demanda", category: "Metabólico", short: "Análogo de GLP-1 de uso extendido en estudios de investigación metabólica.", purity: "99.4%", presentations: [ { label: "5 mg", price: 1590 }, { label: "10 mg", price: 2690 }, ], img: "img/productos/semaglutida.jpg", }, { id: "tirzepatida", name: "Tirzepatida", tag: "Nuevo", category: "Metabólico", short: "Agonista dual GIP/GLP-1 empleado en protocolos de investigación metabólica avanzada.", purity: "99.2%", presentations: [ { label: "10 mg", price: 2390 }, { label: "20 mg", price: 3990 }, ], img: "img/productos/tirzepatida.jpg", }, { id: "ghk-cu", name: "GHK-Cu (Péptido de cobre)", tag: "Piel / Dérmico", category: "Estética / Dérmico", short: "Complejo péptido-cobre estudiado en investigación dérmica y de matriz extracelular.", purity: "99.0%", presentations: [ { label: "50 mg", price: 890 }, { label: "100 mg", price: 1490 }, ], img: "img/productos/ghk-cu.jpg", }, { id: "retatrutide", name: "Retatrutide", tag: "Tendencia", category: "Metabólico", short: "Triple agonista (GIP/GLP-1/glucagón) de interés creciente en investigación metabólica.", purity: "99.1%", presentations: [ { label: "10 mg", price: 2790 }, { label: "20 mg", price: 4590 }, ], img: "img/productos/retatrutide.jpg", }, ]; function getProductById(id) { return PRODUCTS.find(function (p) { return p.id === id; }); } /* ========================================================= PURELABS MÉXICO — cart.js Carrito de compras basado en localStorage + checkout vía WhatsApp. Cuando conectes una pasarela real (Mercado Pago, Stripe, etc.) sustituye la función checkoutWhatsApp() por tu integración de pago. ========================================================= */ const CART_KEY = "plmx_cart"; function getCart() { try { return JSON.parse(localStorage.getItem(CART_KEY)) || []; } catch (e) { return []; } } function saveCart(cart) { localStorage.setItem(CART_KEY, JSON.stringify(cart)); updateCartBadge(); } function addToCart(productId, presentationLabel, price, qty) { const cart = getCart(); const existing = cart.find(function (i) { if (i.productId !== productId) return false; return i.presentation === presentationLabel; }); if (existing) { existing.qty += qty; } else { const product = getProductById(productId); cart.push({ productId: productId, name: product ? product.name : productId, img: product ? product.img : "", presentation: presentationLabel, price: price, qty: qty, }); } saveCart(cart); if (typeof showToast === "function") showToast("Agregado al carrito ✓"); } function removeFromCart(index) { const cart = getCart(); cart.splice(index, 1); saveCart(cart); if (typeof renderCartPage === "function") renderCartPage(); } function changeQty(index, delta) { const cart = getCart(); if (!cart[index]) return; cart[index].qty = Math.max(1, cart[index].qty + delta); saveCart(cart); if (typeof renderCartPage === "function") renderCartPage(); } function cartTotal() { return getCart().reduce(function (sum, item) { return sum + item.price * item.qty; }, 0); } function formatMXN(n) { return "$" + n.toLocaleString("es-MX") + " MXN"; } /* ---------- Render de la página carrito.html ---------- */ function renderCartPage() { const wrap = document.getElementById("cart-wrap"); if (!wrap) return; const cart = getCart(); if (cart.length === 0) { wrap.innerHTML = '
' + "

Tu carrito está vacío

" + '

Explora el catálogo y agrega péptidos de investigación.

' + 'Ver catálogo' + "
"; return; } let rows = ""; cart.forEach(function (item, idx) { rows += "" + '
' + '
' + item.name + '' + '
' + "
" + item.name + "
" + item.presentation + "
" + "
" + "" + formatMXN(item.price) + "" + '
' + '' + '' + '' + "
" + "" + formatMXN(item.price * item.qty) + "" + '' + ""; }); const total = cartTotal(); wrap.innerHTML = '
' + '' + rows + "
ProductoPrecioCantidadSubtotal
" + '
' + '
Subtotal' + formatMXN(total) + "
" + '
EnvíoSe cotiza por WhatsApp
' + '
Total estimado' + formatMXN(total) + "
" + '' + '

Al enviar tu pedido, un asesor confirmará disponibilidad, forma de pago (SPEI, tarjeta o cripto) y tiempos de envío.

' + "
"; // Actualiza contenedores de grid a una sola columna en móvil const gridEl = wrap.querySelector(".grid"); if (window.innerWidth < 800) { if (gridEl) gridEl.style.gridTemplateColumns = "1fr"; } } function checkoutWhatsApp() { const cart = getCart(); if (cart.length === 0) return; let msg = "Hola, quiero hacer un pedido en " + (typeof SITE_CONFIG !== "undefined" ? SITE_CONFIG.brandName : "Purelabs México") + ":\n\n"; cart.forEach(function (item) { msg += "• " + item.name + " (" + item.presentation + ") x" + item.qty + " — " + formatMXN(item.price * item.qty) + "\n"; }); msg += "\nTotal estimado: " + formatMXN(cartTotal()); msg += "\n\nQuedo atento para confirmar disponibilidad, forma de pago y envío."; window.open(buildWhatsAppLink(msg), "_blank"); } document.addEventListener("DOMContentLoaded", function () { if (document.getElementById("cart-wrap")) renderCartPage(); }); /* ========================================================= PURELABS MÉXICO — main.js Lógica compartida en todas las páginas: nav móvil, FAQ, age-gate, inyección de datos de contacto, toast, WhatsApp. ========================================================= */ document.addEventListener("DOMContentLoaded", function () { injectContactData(); setupNavToggle(); setupFaqAccordion(); setupAgeGate(); setupWhatsAppFloat(); updateCartBadge(); }); /* ---------- Inyecta datos de SITE_CONFIG en el DOM ---------- */ function injectContactData() { if (typeof SITE_CONFIG === "undefined") return; document.querySelectorAll("[data-cfg]").forEach(function (el) { const key = el.getAttribute("data-cfg"); if (SITE_CONFIG[key] !== undefined) el.textContent = SITE_CONFIG[key]; }); document.querySelectorAll("[data-cfg-href]").forEach(function (el) { const key = el.getAttribute("data-cfg-href"); if (key === "whatsapp") el.setAttribute("href", buildWhatsAppLink()); else if (key === "email") el.setAttribute("href", "mailto:" + SITE_CONFIG.email); }); document.querySelectorAll("[data-cfg-brand]").forEach(function (el) { el.textContent = SITE_CONFIG.brandName; }); } /* ---------- Nav móvil ---------- */ function setupNavToggle() { const toggle = document.querySelector(".nav-toggle"); const nav = document.querySelector(".main-nav"); if (!toggle || !nav) return; toggle.addEventListener("click", function () { nav.classList.toggle("open"); toggle.textContent = nav.classList.contains("open") ? "✕" : "☰"; }); nav.querySelectorAll("a").forEach(function (a) { a.addEventListener("click", function () { nav.classList.remove("open"); toggle.textContent = "☰"; }); }); } /* ---------- Acordeón de FAQ ---------- */ function setupFaqAccordion() { document.querySelectorAll(".faq-item").forEach(function (item) { const q = item.querySelector(".faq-q"); if (!q) return; q.addEventListener("click", function () { const wasOpen = item.classList.contains("open"); item.parentElement.querySelectorAll(".faq-item").forEach(function (i) { i.classList.remove("open"); }); if (!wasOpen) item.classList.add("open"); }); }); } /* ---------- Age gate / aviso de uso exclusivo de investigación ---------- */ function setupAgeGate() { const overlay = document.getElementById("age-gate"); if (!overlay) return; const KEY = "plmx_age_confirmed_at"; const last = localStorage.getItem(KEY); const DAY = 24 * 60 * 60 * 1000; if (last) { if (Date.now() - Number(last) < DAY) { overlay.classList.add("hidden"); return; } } overlay.classList.remove("hidden"); document.body.style.overflow = "hidden"; const enterBtn = document.getElementById("age-gate-enter"); const exitBtn = document.getElementById("age-gate-exit"); if (enterBtn) { enterBtn.addEventListener("click", function () { localStorage.setItem(KEY, String(Date.now())); overlay.classList.add("hidden"); document.body.style.overflow = ""; }); } if (exitBtn) { exitBtn.addEventListener("click", function () { window.location.href = "https://www.google.com"; }); } } /* ---------- Botón flotante de WhatsApp ---------- */ function setupWhatsAppFloat() { const btn = document.querySelector(".wa-float"); if (!btn || typeof SITE_CONFIG === "undefined") return; btn.setAttribute("href", buildWhatsAppLink(SITE_CONFIG.whatsappGreeting)); btn.setAttribute("target", "_blank"); btn.setAttribute("rel", "noopener"); } /* ---------- Toast genérico ---------- */ function showToast(message) { let toast = document.getElementById("toast"); if (!toast) { toast = document.createElement("div"); toast.id = "toast"; document.body.appendChild(toast); } toast.textContent = message; toast.classList.add("show"); clearTimeout(window.__toastTimer); window.__toastTimer = setTimeout(function () { toast.classList.remove("show"); }, 2600); } /* ---------- Badge del carrito (definido a fondo en cart.js) ---------- */ function updateCartBadge() { const el = document.querySelector(".cart-count"); if (!el || typeof getCart !== "function") return; const cart = getCart(); const count = cart.reduce(function (sum, item) { return sum + item.qty; }, 0); el.textContent = count; el.style.display = count > 0 ? "flex" : "none"; } /* ========================================================= PURELABS MÉXICO — catalog.js Renderiza la cuadrícula de productos en index.html (destacados) y catalogo.html (catálogo completo con filtros por categoría). ========================================================= */ function productCardHTML(p) { const minPrice = Math.min.apply(null, p.presentations.map(function (x) { return x.price; })); return ( '' + '
' + '' + p.tag + "" + '
' + p.name + '' + '
" + "
" + '
' + "

" + p.name + "

" + '
Pureza ' + p.purity + "" + p.category + "COA incluido
" + "

" + p.short + "

" + '
' + '
' + formatMXN(minPrice) + '
desde / por presentación
' + 'Ver producto' + "
" ); } function renderProductGrid(targetId, limit) { const el = document.getElementById(targetId); if (!el) return; const list = limit ? PRODUCTS.slice(0, limit) : PRODUCTS; el.innerHTML = list.map(productCardHTML).join(""); } function renderCatalogWithFilters() { const grid = document.getElementById("catalog-grid"); if (!grid) return; const categories = ["Todos"].concat( PRODUCTS.reduce(function (acc, p) { if (acc.indexOf(p.category) === -1) acc.push(p.category); return acc; }, []) ); const chipRow = document.getElementById("catalog-filters"); if (chipRow) { chipRow.innerHTML = categories .map(function (c, i) { return '"; }) .join(""); chipRow.querySelectorAll(".chip").forEach(function (chip) { chip.addEventListener("click", function () { chipRow.querySelectorAll(".chip").forEach(function (c) { c.classList.remove("active"); }); chip.classList.add("active"); const cat = chip.getAttribute("data-cat"); const filtered = cat === "Todos" ? PRODUCTS : PRODUCTS.filter(function (p) { return p.category === cat; }); grid.innerHTML = filtered.map(productCardHTML).join(""); }); }); } grid.innerHTML = PRODUCTS.map(productCardHTML).join(""); } document.addEventListener("DOMContentLoaded", function () { renderProductGrid("featured-grid", 4); renderCatalogWithFilters(); }); /* ========================================================= PURELABS MÉXICO — product-detail.js Rellena la página de producto individual (producto-*.html) a partir de PRODUCTS (products.js), usando el atributo data-product-id del . ========================================================= */ let __selectedPresIndex = 0; function renderProductDetail() { const root = document.getElementById("pd-root"); if (!root) return; const id = document.body.getAttribute("data-product-id"); const p = getProductById(id); if (!p) { root.innerHTML = "

Producto no encontrado.

"; return; } document.title = p.name + " — " + (typeof SITE_CONFIG !== "undefined" ? SITE_CONFIG.brandName : "Purelabs México"); const crumbEl = document.getElementById("pd-crumb-name"); if (crumbEl) crumbEl.textContent = p.name; root.innerHTML = '" + '
' + '
Pureza ' + p.purity + '' + p.category + 'HPLC verificado
' + '

' + p.name + "

" + "

" + p.short + "

" + '
' + formatMXN(p.presentations[0].price) + "
" + '
' + "" + '
' + p.presentations .map(function (pres, i) { return '"; }) .join("") + "
" + '
' + '' + "
" + '
' + '' + 'Preguntar por WhatsApp' + "
" + '
📄Certificado de análisis (COA) por lote disponible bajo solicitud, indicando el número de lote de tu pedido.
' + "
"; // Tabs (Descripción / Uso en investigación / Envío y almacenamiento) const tabsWrap = document.getElementById("pd-tabs"); if (tabsWrap) { tabsWrap.innerHTML = '
' + '' + '' + '' + "
" + '

' + p.short + ' Producto de grado investigación, sintetizado y analizado bajo control de calidad, con verificación de pureza mediante HPLC en cada lote. La ficha técnica completa y el COA correspondiente se comparten junto con el pedido cuando están disponibles.

' + '

Este producto se comercializa exclusivamente para fines de investigación científica y de laboratorio. No está destinado para consumo humano, uso médico, veterinario, diagnóstico o tratamiento. El manejo debe realizarse únicamente por personal calificado dentro de entornos adecuados de investigación, siguiendo los protocolos y normativas aplicables.

' + '

Se envía liofilizado en polvo, estable a temperatura ambiente durante el traslado. Empaque sellado y protegido para conservar la integridad del producto. Una vez recibido, se recomienda almacenar según la ficha técnica específica (generalmente refrigerado y protegido de la luz tras la reconstitución).

'; tabsWrap.querySelectorAll(".pd-tab-nav button").forEach(function (btn) { btn.addEventListener("click", function () { tabsWrap.querySelectorAll(".pd-tab-nav button").forEach(function (b) { b.classList.remove("active"); }); tabsWrap.querySelectorAll(".pd-tab-panel").forEach(function (pnl) { pnl.classList.remove("active"); }); btn.classList.add("active"); tabsWrap.querySelector('[data-panel="' + btn.getAttribute("data-tab") + '"]').classList.add("active"); }); }); } // Interactividad de presentación / cantidad / carrito __selectedPresIndex = 0; const presRow = document.getElementById("pd-pres-row"); const priceEl = document.getElementById("pd-price"); const qtyEl = document.getElementById("pd-qty"); presRow.querySelectorAll(".pres-btn").forEach(function (btn) { btn.addEventListener("click", function () { presRow.querySelectorAll(".pres-btn").forEach(function (b) { b.classList.remove("active"); }); btn.classList.add("active"); __selectedPresIndex = Number(btn.getAttribute("data-idx")); priceEl.textContent = formatMXN(p.presentations[__selectedPresIndex].price); }); }); document.getElementById("pd-qty-minus").addEventListener("click", function () { qtyEl.value = Math.max(1, Number(qtyEl.value) - 1); }); document.getElementById("pd-qty-plus").addEventListener("click", function () { qtyEl.value = Number(qtyEl.value) + 1; }); document.getElementById("pd-add-cart").addEventListener("click", function () { const pres = p.presentations[__selectedPresIndex]; addToCart(p.id, pres.label, pres.price, Number(qtyEl.value)); }); const waBtn = document.getElementById("pd-wa-btn"); if (waBtn) { if (typeof buildWhatsAppLink === "function") { waBtn.setAttribute("href", buildWhatsAppLink("Hola, tengo una pregunta sobre " + p.name + ".")); } } // Productos relacionados const relatedGrid = document.getElementById("related-grid"); if (relatedGrid) { const related = PRODUCTS.filter(function (x) { return x.id !== p.id; }).slice(0, 3); relatedGrid.innerHTML = related.map(productCardHTML).join(""); } } document.addEventListener("DOMContentLoaded", renderProductDetail); /* ========================================================= PURELABS MÉXICO — calculadora.js Calculadora de reconstitución para fines de documentación de investigación. NO constituye indicación de dosis, uso humano ni consejo médico — ver aviso en calculadora.html. ========================================================= */ function calcReconstitucion() { const mg = parseFloat(document.getElementById("calc-mg").value); const water = parseFloat(document.getElementById("calc-water").value); const doseMcg = parseFloat(document.getElementById("calc-dose").value); const resultBox = document.getElementById("calc-result"); if (!mg || !water || !doseMcg || mg <= 0 || water <= 0 || doseMcg <= 0) { resultBox.classList.add("hidden"); return; } const concentrationMcgPerMl = (mg * 1000) / water; // mcg/mL const volumePerDoseMl = doseMcg / concentrationMcgPerMl; // mL const unitsOnSyringe100 = volumePerDoseMl * 100; // jeringa de insulina de 100 UI = 1 mL const dosesPerVial = (mg * 1000) / doseMcg; document.getElementById("calc-concentration").textContent = concentrationMcgPerMl.toFixed(1) + " mcg/mL"; document.getElementById("calc-volume").textContent = volumePerDoseMl.toFixed(3) + " mL"; document.getElementById("calc-units").textContent = unitsOnSyringe100.toFixed(1) + " UI (jeringa 100 UI)"; document.getElementById("calc-doses").textContent = Math.floor(dosesPerVial) + " dosis por vial"; resultBox.classList.remove("hidden"); } document.addEventListener("DOMContentLoaded", function () { const form = document.getElementById("calc-form"); if (!form) return; form.querySelectorAll("input").forEach(function (input) { input.addEventListener("input", calcReconstitucion); }); });