- public/guida.html, index-en.html, service-continuity.html - public/js/ai-assistant.js, bug-reporter.js (FAB supporto) - public/mobile-conversion.css/js - index.html, common.js, help.js, risks.html: aggiornamenti UI/help Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
193 lines
7.4 KiB
JavaScript
193 lines
7.4 KiB
JavaScript
/* ════════════════════════════════════════════════════════════════
|
|
* Mobile Conversion Layer — Agile Technology suite
|
|
* Versione 1.0 — 2026-05-18
|
|
*
|
|
* Si attiva solo su mobile (≤768px).
|
|
* Configurabile via <script data-*>:
|
|
*
|
|
* <script src="mobile-conversion.js"
|
|
* data-primary-text="Prenota demo"
|
|
* data-primary-action="agilehub-open"
|
|
* data-primary-href="#contact"
|
|
* data-phone="+390000000000"
|
|
* data-whatsapp="390000000000"
|
|
* data-wa-message="Buongiorno, vorrei info su…"
|
|
* data-show-wa-fab="false"
|
|
* data-trust-items='["12 moduli","4 anni","AI"]'
|
|
* data-trust-after="section.hero"
|
|
* data-trust-theme="dark"
|
|
* data-accent="#E31E24"
|
|
* data-accent2="#B71518"
|
|
* data-scroll-trigger="400"
|
|
* defer></script>
|
|
*
|
|
* data-primary-action:
|
|
* - "agilehub-open" → apre la modale AgileHubApplet (se presente)
|
|
* - "anchor" → smooth scroll a data-primary-href
|
|
* - "external" → location.assign(data-primary-href)
|
|
* ════════════════════════════════════════════════════════════════ */
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
/* ── Config dal <script data-*> ── */
|
|
var script = document.currentScript || (function () {
|
|
var s = document.getElementsByTagName('script');
|
|
for (var i = s.length - 1; i >= 0; i--) {
|
|
if (s[i].src && s[i].src.indexOf('mobile-conversion') > -1) return s[i];
|
|
}
|
|
return s[s.length - 1];
|
|
})();
|
|
var ds = script.dataset || {};
|
|
var CFG = {
|
|
primaryText: ds.primaryText || 'Contattaci',
|
|
primaryAction: ds.primaryAction || 'anchor',
|
|
primaryHref: ds.primaryHref || '#contact',
|
|
primaryIcon: ds.primaryIcon || '→',
|
|
phone: ds.phone || '',
|
|
whatsapp: ds.whatsapp || '',
|
|
waMessage: ds.waMessage || '',
|
|
showWaFab: ds.showWaFab === 'true',
|
|
trustItems: ds.trustItems || null, // JSON array
|
|
trustAfter: ds.trustAfter || null, // CSS selector
|
|
trustTheme: ds.trustTheme || 'light', // 'light' | 'dark'
|
|
accent: ds.accent || '#E31E24',
|
|
accent2: ds.accent2 || '#B71518',
|
|
scrollTrigger: parseInt(ds.scrollTrigger || '400', 10)
|
|
};
|
|
|
|
/* ── Bail-out se desktop o se siamo in un iframe ── */
|
|
if (window.innerWidth > 768) return;
|
|
|
|
/* ── Inject CSS variables override (se accent custom) ── */
|
|
if (CFG.accent !== '#E31E24' || CFG.accent2 !== '#B71518') {
|
|
var st = document.createElement('style');
|
|
st.textContent = ':root{--mobconv-accent:'+CFG.accent+';--mobconv-accent2:'+CFG.accent2+'}';
|
|
document.head.appendChild(st);
|
|
}
|
|
|
|
/* ── Parse trust items ── */
|
|
var trustList = null;
|
|
if (CFG.trustItems) {
|
|
try { trustList = JSON.parse(CFG.trustItems); } catch (e) { trustList = null; }
|
|
}
|
|
|
|
/* ── Costruisci WhatsApp URL ── */
|
|
function waUrl() {
|
|
if (!CFG.whatsapp) return null;
|
|
var msg = CFG.waMessage ? '?text=' + encodeURIComponent(CFG.waMessage) : '';
|
|
return 'https://wa.me/' + CFG.whatsapp + msg;
|
|
}
|
|
|
|
/* ── Render sticky bar ── */
|
|
function buildSticky() {
|
|
var html = ['<div class="mobconv-sticky" id="mobconv-sticky"><div class="mobconv-sticky-row">'];
|
|
|
|
if (CFG.phone) {
|
|
html.push('<a class="mobconv-pill" href="tel:' + CFG.phone.replace(/\s/g,'') + '" aria-label="Telefono">📞</a>');
|
|
}
|
|
var wa = waUrl();
|
|
if (wa) {
|
|
html.push('<a class="mobconv-pill wa" href="' + wa + '" target="_blank" rel="noopener" aria-label="WhatsApp">💬</a>');
|
|
}
|
|
|
|
// Primary CTA
|
|
var ctaAttrs = 'class="mobconv-cta" id="mobconv-primary"';
|
|
if (CFG.primaryAction === 'agilehub-open') {
|
|
ctaAttrs += ' href="#" data-agilehub-open';
|
|
} else if (CFG.primaryAction === 'external') {
|
|
ctaAttrs += ' href="' + CFG.primaryHref + '" target="_blank" rel="noopener"';
|
|
} else {
|
|
ctaAttrs += ' href="' + CFG.primaryHref + '"';
|
|
}
|
|
html.push('<a ' + ctaAttrs + '>' + CFG.primaryText + ' <span style="opacity:.85">' + CFG.primaryIcon + '</span></a>');
|
|
|
|
html.push('</div></div>');
|
|
return html.join('');
|
|
}
|
|
|
|
/* ── Render WhatsApp FAB ── */
|
|
function buildFab() {
|
|
if (!CFG.showWaFab || !CFG.whatsapp) return '';
|
|
return '<a class="mobconv-wa-fab" data-enabled="true" href="' + waUrl() + '" target="_blank" rel="noopener" aria-label="Scrivici su WhatsApp">' +
|
|
'<i class="fab fa-whatsapp"></i>' +
|
|
'</a>';
|
|
}
|
|
|
|
/* ── Render trust ribbon ── */
|
|
function buildTrust() {
|
|
if (!trustList || !trustList.length) return null;
|
|
var dark = CFG.trustTheme === 'dark' ? ' dark' : '';
|
|
var items = trustList.map(function (t) {
|
|
return '<span class="mobconv-trust-item">' + t + '</span>';
|
|
}).join('');
|
|
return '<div class="mobconv-trust' + dark + '"><div class="mobconv-trust-row">' + items + '</div></div>';
|
|
}
|
|
|
|
/* ── Mount on DOM ready ── */
|
|
function mount() {
|
|
// Inject sticky bar at end of body
|
|
var stickyHtml = buildSticky();
|
|
var fabHtml = buildFab();
|
|
var wrap = document.createElement('div');
|
|
wrap.innerHTML = stickyHtml + fabHtml;
|
|
while (wrap.firstChild) document.body.appendChild(wrap.firstChild);
|
|
|
|
// Inject trust ribbon after hero (or specified selector)
|
|
var trustHtml = buildTrust();
|
|
if (trustHtml && CFG.trustAfter) {
|
|
var anchor = document.querySelector(CFG.trustAfter);
|
|
if (anchor) {
|
|
var t = document.createElement('div');
|
|
t.innerHTML = trustHtml;
|
|
anchor.parentNode.insertBefore(t.firstChild, anchor.nextSibling);
|
|
}
|
|
}
|
|
|
|
// Padding body bottom per non coprire CTA esistenti in fondo pagina
|
|
document.body.classList.add('mobconv-padded');
|
|
|
|
// Smooth scroll per anchor primary
|
|
if (CFG.primaryAction === 'anchor') {
|
|
var btn = document.getElementById('mobconv-primary');
|
|
if (btn) {
|
|
btn.addEventListener('click', function (e) {
|
|
var href = btn.getAttribute('href');
|
|
if (href && href.charAt(0) === '#') {
|
|
var tgt = document.querySelector(href);
|
|
if (tgt) {
|
|
e.preventDefault();
|
|
tgt.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
// agilehub-open: il modulo agilehub-applet.js auto-binda [data-agilehub-open]
|
|
// quindi nessun bind manuale serve qui.
|
|
|
|
// Scroll listener: show sticky bar dopo X px
|
|
var stickyEl = document.getElementById('mobconv-sticky');
|
|
var triggered = false;
|
|
function onScroll() {
|
|
var y = window.scrollY || document.documentElement.scrollTop;
|
|
if (!triggered && y >= CFG.scrollTrigger) {
|
|
stickyEl.classList.add('show');
|
|
triggered = true;
|
|
} else if (triggered && y < CFG.scrollTrigger - 60) {
|
|
// Reset solo se scrolla MOLTO in alto (-60 hysteresis)
|
|
stickyEl.classList.remove('show');
|
|
triggered = false;
|
|
}
|
|
}
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|
onScroll(); // check iniziale
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', mount);
|
|
} else {
|
|
mount();
|
|
}
|
|
})();
|