733 lines
45 KiB
JavaScript
733 lines
45 KiB
JavaScript
/**
|
||
* sales_help.js - Guida contestuale delle pagine statistiche vendite.
|
||
*
|
||
* Uso nelle pagine:
|
||
* <div class="chart-title" data-help="st.monthly">...</div> → aggiunge l'icona ⓘ in fondo all'elemento
|
||
* <button data-help-open="page.stats">...</button> → apre la guida al click (guida di pagina)
|
||
*
|
||
* I testi sono tutti qui sotto (SALES_HELP): per cambiarli basta modificare questo file.
|
||
* Funziona anche sugli elementi creati dopo (box disegnati via JavaScript).
|
||
*/
|
||
(function () {
|
||
"use strict";
|
||
|
||
const SALES_HELP = {
|
||
/* ===================== GUIDE DI PAGINA ===================== */
|
||
"page.stats": {
|
||
t: "Andamento ordini: come si usa",
|
||
b: `<p>Qui vedi <b>gli ordini clienti</b> del periodo scelto: quanti sono, quanto valgono, a che punto sono.</p>
|
||
<ul>
|
||
<li><b>In alto</b> scegli il periodo (mese, trimestre, anno…) e se vuoi cliente, agente, area o stato.</li>
|
||
<li><b>I box colorati</b> sono cliccabili: filtrano tutta la pagina (es. clic su <i>In ritardo</i> = solo ordini in ritardo).</li>
|
||
<li><b>I grafici</b> sono cliccabili: un mese, una fetta, un cliente diventano un filtro.</li>
|
||
<li><b>L'elenco in fondo</b>: clic su una riga per il dettaglio dell'ordine con le sue righe; si esporta in Excel.</li>
|
||
<li>Il selettore <b>N° ordini / Valore</b> cambia cosa misurano i grafici.</li>
|
||
</ul>
|
||
<p class="sh-note">Gli ordini con la parola "listino" sono esclusi. I filtri restano memorizzati quando torni sulla pagina; la gomma 🧽 li azzera.</p>`,
|
||
},
|
||
"page.years": {
|
||
t: "Confronto anni: come si usa",
|
||
b: `<p>Qui confronti <b>gli anni tra loro</b> e vedi <b>la situazione ad oggi</b>.</p>
|
||
<ul>
|
||
<li><b>Situazione ad oggi</b> (in alto): portafoglio, book-to-bill e previsioni. Non dipende dagli anni scelti.</li>
|
||
<li><b>Chip degli anni</b>: scegli quali anni confrontare (ognuno ha il suo colore in tutti i grafici).</li>
|
||
<li><b>A pari data</b>: acceso, ogni anno è contato solo fino al giorno di oggi → confronto giusto con l'anno in corso. Spento: anni interi.</li>
|
||
<li><b>Clienti da richiamare</b> e <b>Clienti a confronto</b>: clic su un cliente per filtrare tutta la pagina; l'icona verde apre la sua scheda.</li>
|
||
</ul>
|
||
<p class="sh-note">Cliente, agente e area filtrano tutto, anche il fatturato.</p>`,
|
||
},
|
||
"page.deliveries": {
|
||
t: "Consegne: come si usa",
|
||
b: `<p>Qui vedi <b>le righe d'ordine ancora da consegnare</b>, cioè il lavoro da spedire.</p>
|
||
<ul>
|
||
<li><b>Data ZIBO</b> (rossa quando scaduta) = la settimana di consegna che abbiamo comunicato: è la scadenza che conta. La riga è in ritardo solo quando quella settimana è finita; durante la settimana compare <span class="sh-chip sh-amber">IN SETTIMANA</span>.</li>
|
||
<li><b>Data cliente</b> (arancione quando superata) = quando il cliente l'avrebbe voluta: è un riferimento.</li>
|
||
<li><b>Scadenza</b> (chip in alto), box e grafici filtrano le righe; si combinano con cliente, articolo, agente, area.</li>
|
||
</ul>
|
||
<p class="sh-note">Cosa fare: parti dalle <b>scadute</b>, poi guarda <b>i prossimi giorni</b> e le settimane più cariche del grafico.</p>`,
|
||
},
|
||
"page.customer": {
|
||
t: "Scheda cliente: come si usa",
|
||
b: `<p>Tutto su <b>un cliente</b> in una pagina. Cercalo per nome o codice, oppure clicca l'icona verde accanto a un cliente nelle altre pagine.</p>
|
||
<ul>
|
||
<li><b>Profilo</b>: da quando è cliente, ultimo ordine, ogni quanto ordina di solito e il suo stato (attivo, attenzione, dormiente…).</li>
|
||
<li><b>Box</b>: quest'anno rispetto allo scorso, cosa gli dobbiamo consegnare, note di credito.</li>
|
||
<li><b>Tabelle</b> in fondo: righe da consegnare, ordini, articoli, fatture. Tutte esportabili in Excel.</li>
|
||
</ul>
|
||
<p class="sh-note">Utile prima di una telefonata o di una visita. I clienti visti di recente restano a portata di clic.</p>`,
|
||
},
|
||
|
||
"page.summary": {
|
||
t: "Sommario: come si legge",
|
||
b: `<p>Il <b>riepilogo per la direzione</b>: in un colpo d'occhio cosa va bene e cosa no.</p>
|
||
<ul>
|
||
<li><b>Semaforo in alto</b>: il giudizio complessivo. Il punteggio su 100 conta i verdi (100), i gialli (50) e i rossi (0).</li>
|
||
<li><b>Cosa va bene / Cosa non va</b>: gli stessi indicatori, scritti in frasi semplici; i rossi sono in cima.</li>
|
||
<li><b>Tessere</b>: ogni indicatore ha il suo colore. <span class="sh-chip sh-green">Bene</span> <span class="sh-chip sh-amber">Così così</span> <span class="sh-chip sh-red">Male</span>. Clic sulla tessera per andare alla pagina con i dettagli.</li>
|
||
<li><b>Clienti da guardare</b>: chi cresce, chi cala, chi richiamare subito. Clic sul nome per la scheda cliente.</li>
|
||
</ul>
|
||
<p class="sh-note">Il sommario guarda sempre <b>tutta l'azienda ad oggi</b>: non ha filtri. Per approfondire usa le altre pagine.</p>`,
|
||
},
|
||
|
||
/* ===================== SOMMARIO ===================== */
|
||
"sm.flow": {
|
||
t: "Nuovi ordini",
|
||
b: `<p>Quanti ordini sono entrati (per data ordine) e quanto valgono, annullati esclusi:</p>
|
||
<ul>
|
||
<li><b>Oggi</b>, confrontato con lo stesso giorno della settimana scorsa;</li>
|
||
<li><b>Ultimi 7 giorni</b>, confrontati con i 7 giorni prima;</li>
|
||
<li><b>Ultimi 30 giorni</b>, confrontati con i 30 giorni prima.</li>
|
||
</ul>
|
||
<p>▲ verde = più della volta prima · ▼ rosso = meno.</p>
|
||
<p class="sh-note">"Oggi" va letto a fine giornata: al mattino è normale che sia basso.</p>`,
|
||
},
|
||
"sm.invYtd": {
|
||
t: "Fatturato dell'anno",
|
||
b: `<p>Fatturato da gennaio a oggi rispetto allo <b>stesso periodo dell'anno scorso</b>.</p>
|
||
<p>🟢 almeno +3% · 🟡 tra −3% e +3% · 🔴 sotto −3%.</p>`,
|
||
},
|
||
"sm.ordYtd": {
|
||
t: "Ordinato dell'anno",
|
||
b: `<p>Ordini ricevuti da gennaio a oggi rispetto allo stesso periodo dell'anno scorso. È il fatturato dei prossimi mesi.</p>
|
||
<p>🟢 almeno +3% · 🟡 tra −3% e +3% · 🔴 sotto −3%.</p>`,
|
||
},
|
||
"sm.forecast": {
|
||
t: "Chiusura prevista",
|
||
b: `<p>Come chiuderà l'anno se si continua con lo stesso ritmo degli anni scorsi, confrontata con l'anno scorso intero.</p>
|
||
<p>🟢 almeno +3% · 🟡 tra −3% e +3% · 🔴 sotto −3%.</p>
|
||
<p class="sh-note">È una stima: diventa più affidabile man mano che l'anno avanza.</p>`,
|
||
},
|
||
"sm.b2b": {
|
||
t: "Book-to-bill",
|
||
b: `<p>Ordini entrati ÷ fatture emesse negli ultimi 90 giorni. Dice se il lavoro in arrivo tiene il passo con quello che consegniamo.</p>
|
||
<p>🟢 da 1,05 (il portafoglio cresce) · 🟡 tra 0,95 e 1,05 · 🔴 sotto 0,95 (lo stiamo consumando).</p>
|
||
<p class="sh-note">Il grafico mostra lo stesso valore mese per mese (su 3 mesi): la riga tratteggiata è 1.</p>`,
|
||
},
|
||
"sm.cover": {
|
||
t: "Lavoro in portafoglio",
|
||
b: `<p>Per quante <b>settimane di lavoro</b> basta quello che abbiamo da consegnare, al ritmo di fatturato degli ultimi 3 mesi.</p>
|
||
<p>🟢 almeno 8 settimane · 🟡 da 4 a 8 · 🔴 meno di 4.</p>`,
|
||
},
|
||
"sm.late": {
|
||
t: "Consegne in ritardo",
|
||
b: `<p>Quanta parte del portafoglio è già <b>oltre la settimana ZIBO</b> comunicata al cliente.</p>
|
||
<p>🟢 fino al 10% · 🟡 dal 10 al 25% · 🔴 oltre il 25%.</p>
|
||
<p class="sh-note">Cosa fare: apri Consegne e parti dalle righe scadute.</p>`,
|
||
},
|
||
"sm.risk": {
|
||
t: "Clienti a rischio",
|
||
b: `<p>Clienti abituali <b>dormienti</b> o <b>probabilmente persi</b> e quanto valevano in un anno, rispetto al giro d'affari totale.</p>
|
||
<p>🟢 fino al 3% · 🟡 dal 3 all'8% · 🔴 oltre l'8%.</p>
|
||
<p class="sh-note">Cosa fare: lista "Da richiamare subito" qui sotto, o quella completa in Confronto anni.</p>`,
|
||
},
|
||
"sm.top5": {
|
||
t: "Peso dei primi 5 clienti",
|
||
b: `<p>Quanto del fatturato degli ultimi 12 mesi viene dai 5 clienti più grandi. Più è alto, più dipendiamo da pochi nomi.</p>
|
||
<p>🟢 fino al 40% · 🟡 dal 40 al 60% · 🔴 oltre il 60%.</p>`,
|
||
},
|
||
"sm.customers": {
|
||
t: "Clienti attivi",
|
||
b: `<p>Clienti che hanno ordinato negli ultimi 12 mesi, confrontati con i 12 mesi prima. "Nuovi" = primo ordine nell'ultimo anno.</p>
|
||
<p>🟢 stabili o in crescita · 🟡 fino a −5% · 🔴 oltre −5%.</p>`,
|
||
},
|
||
"sm.cn": {
|
||
t: "Note di credito",
|
||
b: `<p>Note di credito degli ultimi 12 mesi in percentuale sul fatturato: misura resi, sconti e contestazioni.</p>
|
||
<p>🟢 fino all'1,5% · 🟡 dall'1,5 al 3% · 🔴 oltre il 3%.</p>`,
|
||
},
|
||
"sm.up": {
|
||
t: "Clienti che crescono",
|
||
b: `<p>I clienti che hanno aumentato di più (in euro) negli ultimi 12 mesi rispetto ai 12 precedenti. Da coltivare.</p>`,
|
||
},
|
||
"sm.down": {
|
||
t: "Clienti che calano",
|
||
b: `<p>I clienti che sono diminuiti di più (in euro) negli ultimi 12 mesi rispetto ai 12 precedenti.</p>
|
||
<p class="sh-note">Cosa fare: capire il motivo (concorrenza, prezzi, problemi di consegna) con una telefonata.</p>`,
|
||
},
|
||
"sm.call": {
|
||
t: "Da richiamare subito",
|
||
b: `<p>I clienti abituali più importanti che si sono fermati (dormienti o probabilmente persi), ordinati per valore.</p>`,
|
||
},
|
||
|
||
/* ===================== ANDAMENTO ORDINI ===================== */
|
||
"st.orders": {
|
||
t: "Ordini",
|
||
b: `<p>Numero di ordini del periodo e dei filtri scelti. Sotto: confronto con lo <b>stesso periodo dell'anno prima</b>.</p>
|
||
<p class="sh-note">Clic sul box: toglie il filtro di stato e mostra tutti gli ordini.</p>`,
|
||
},
|
||
"st.value": {
|
||
t: "Valore ordinato",
|
||
b: `<p>Somma dell'<b>imponibile</b> degli ordini del periodo (annullati esclusi), con il confronto con lo stesso periodo dell'anno prima.</p>`,
|
||
},
|
||
"st.toship": {
|
||
t: "Da evadere",
|
||
b: `<p>Valore degli ordini <b>ancora aperti</b> (non consegnati del tutto). In rosso la parte <b>già in ritardo</b>.</p>
|
||
<p class="sh-note">Cosa fare: se la quota in ritardo cresce, guarda la pagina Consegne.</p>`,
|
||
},
|
||
"st.open": {
|
||
t: "Aperti",
|
||
b: `<p>Ordini non ancora consegnati del tutto e non annullati. Clic per vederli.</p>`,
|
||
},
|
||
"st.late": {
|
||
t: "In ritardo",
|
||
b: `<p>Ordini con almeno <b>una riga aperta oltre la data ZIBO</b> (la settimana comunicata è finita).</p>
|
||
<ul>
|
||
<li><b>Righe in ritardo</b>: quante righe sono scadute; <b>parziali</b> = ordini dove è in ritardo solo una parte delle righe.</li>
|
||
<li><b>Oltre data cliente</b> (arancione): superata la data desiderata dal cliente, ma non ancora la nostra.</li>
|
||
<li>Striscia gialla <b>in consegna questa settimana</b>: ordini con righe da consegnare entro domenica, non ancora in ritardo. Cliccala per vederli.</li>
|
||
</ul>
|
||
<p class="sh-note">Cosa fare: clic sul box per la lista, poi apri gli ordini per vedere quali righe mancano.</p>`,
|
||
},
|
||
"st.done": {
|
||
t: "Evasi",
|
||
b: `<p>Ordini completamente consegnati nel periodo scelto (per data ordine).</p>`,
|
||
},
|
||
"st.toinvoice": {
|
||
t: "Da fatturare",
|
||
b: `<p>Ordini <b>consegnati ma non ancora fatturati</b>.</p>
|
||
<p class="sh-note">Cosa fare: segnalali all'amministrazione se restano qui a lungo.</p>`,
|
||
},
|
||
"st.customers": {
|
||
t: "Clienti attivi",
|
||
b: `<p>Quanti clienti diversi hanno ordinato nel periodo. Sotto: in media dopo quanti giorni dall'ordine è prevista la consegna.</p>`,
|
||
},
|
||
"st.monthly": {
|
||
t: "Andamento mensile",
|
||
b: `<p>Ordini (o valore) mese per mese nel periodo scelto. Clic su un mese per filtrare solo quel mese.</p>`,
|
||
},
|
||
"st.status": {
|
||
t: "Ripartizione per stato",
|
||
b: `<p>Come si dividono gli ordini: aperti, evasi, bloccati, annullati. Clic su una fetta per filtrare.</p>`,
|
||
},
|
||
"st.topcust": {
|
||
t: "Top 10 clienti",
|
||
b: `<p>I 10 clienti più importanti del periodo (per numero ordini o valore). Le barre sono divise tra ordini aperti e altri (evasi/annullati).</p>
|
||
<p class="sh-note">Clic su un cliente per vedere solo i suoi ordini.</p>`,
|
||
},
|
||
"st.due": {
|
||
t: "Scadenze ordini aperti",
|
||
b: `<p>Gli ordini aperti divisi per <b>quando vanno consegnati</b>: già scaduti, questa settimana, la prossima, entro 30 giorni, oltre, senza data.</p>`,
|
||
},
|
||
"st.items": {
|
||
t: "Top 10 articoli",
|
||
b: `<p>Gli articoli più ordinati nel periodo, calcolati dalle righe d'ordine. Passa sopra una barra per quantità e valore.</p>`,
|
||
},
|
||
"st.area": {
|
||
t: "Per area",
|
||
b: `<p>Ordini (o valore) divisi per area commerciale.</p>`,
|
||
},
|
||
"st.agent": {
|
||
t: "Per agente",
|
||
b: `<p>Ordini (o valore) divisi per agente.</p>`,
|
||
},
|
||
"st.list": {
|
||
t: "Elenco ordini",
|
||
b: `<p>Tutti gli ordini dei filtri scelti. Clic su una riga per il <b>dettaglio con le righe</b>, le date e cosa resta da consegnare.</p>
|
||
<ul>
|
||
<li><span class="sh-chip sh-red">IN RITARDO</span> data ZIBO superata · <span class="sh-chip sh-amber">PARZIALE</span> solo alcune righe in ritardo · <span class="sh-chip sh-orange">OLTRE DATA CLIENTE</span> superata solo la data del cliente.</li>
|
||
<li>Il pulsante Excel scarica l'elenco come lo vedi.</li>
|
||
</ul>`,
|
||
},
|
||
|
||
/* ===================== CONFRONTO ANNI ===================== */
|
||
"yr.dash": {
|
||
t: "Situazione ad oggi",
|
||
b: `<p>Una fotografia di <b>oggi</b>, che non cambia con gli anni scelti. Segue solo i filtri cliente, agente e area (così puoi vederla anche per un agente o un cliente).</p>`,
|
||
},
|
||
"yr.backlog": {
|
||
t: "Portafoglio da consegnare",
|
||
b: `<p>Valore di tutte le righe d'ordine <b>ancora da consegnare</b>.</p>
|
||
<ul>
|
||
<li><b>Settimane</b>: per quante settimane di lavoro basta, al ritmo medio di fatturato degli ultimi 3 mesi.</li>
|
||
<li>In rosso la parte <b>già oltre la data ZIBO</b>.</li>
|
||
</ul>
|
||
<p class="sh-note">Poche settimane = servono ordini nuovi. Tante settimane con molto in ritardo = c'è un problema di capacità o di consegne.</p>`,
|
||
},
|
||
"yr.b2b": {
|
||
t: "Book-to-bill",
|
||
b: `<p>Confronta <b>il lavoro che entra</b> (ordini) con <b>quello che esce</b> (fatture) negli ultimi 90 giorni.</p>
|
||
<ul>
|
||
<li><b>1,0</b> = equilibrio.</li>
|
||
<li><b>Sopra 1</b> (es. 1,20 → per ogni 100 € fatturati entrano 120 € di ordini): il portafoglio cresce 🟢</li>
|
||
<li><b>Sotto 1</b> (es. 0,80): stiamo consumando il portafoglio, tra qualche mese il fatturato rischia di calare 🔴</li>
|
||
</ul>
|
||
<p class="sh-note">È un segnale che arriva <b>prima</b> del calo di fatturato.</p>`,
|
||
},
|
||
"yr.fcInv": {
|
||
t: "Previsione fatturato",
|
||
b: `<p>Stima di come chiuderà l'anno. Si prende il fatturato <b>ad oggi</b> e lo si proietta con la stagionalità degli ultimi 3 anni (es. se negli anni scorsi a questa data eravamo al 78% dell'anno, oggi siamo probabilmente al 78%).</p>
|
||
<p class="sh-note">La <b>forbice</b> va dall'anno più favorevole a quello meno favorevole. Diventa più precisa man mano che l'anno avanza.</p>`,
|
||
},
|
||
"yr.fcOrd": {
|
||
t: "Previsione ordinato",
|
||
b: `<p>Come la previsione del fatturato, ma sugli <b>ordini ricevuti</b>: quanto ordinato porteremo a casa entro fine anno se si continua così.</p>`,
|
||
},
|
||
"yr.b2bchart": {
|
||
t: "Ordinato vs fatturato · 24 mesi",
|
||
b: `<p>Barre viola = ordini ricevuti nel mese · barre verdi = fatturato del mese.</p>
|
||
<p>La <b>linea arancione</b> è il book-to-bill su 3 mesi: sopra la riga tratteggiata dell'1 il portafoglio cresce, sotto si consuma.</p>
|
||
<p class="sh-note">Se la linea resta sotto 1 per diversi mesi, è il momento di spingere sugli ordini.</p>`,
|
||
},
|
||
"yr.cards": {
|
||
t: "Anni a confronto",
|
||
b: `<p>Una carta per ogni anno scelto: valore ordinato (numero grande), numero ordini, ordine medio, clienti, fatturato e variazione rispetto all'anno prima.</p>
|
||
<p class="sh-note">Con <b>A pari data</b> acceso ogni anno è contato fino a oggi: il confronto con l'anno in corso è corretto.</p>`,
|
||
},
|
||
"yr.monthly": {
|
||
t: "Ordinato per mese",
|
||
b: `<p>Una linea per anno, mese per mese: mostra la <b>stagionalità</b> e in quali mesi quest'anno va meglio o peggio.</p>`,
|
||
},
|
||
"yr.cumul": {
|
||
t: "Progressivo dell'anno",
|
||
b: `<p>Somma da gennaio a ogni mese. Se la linea dell'anno in corso è <b>sopra</b> quelle degli anni scorsi, siamo avanti; se è sotto, siamo indietro.</p>`,
|
||
},
|
||
"yr.invMonthly": {
|
||
t: "Fatturato per mese",
|
||
b: `<p>Fatturato vero per <b>data della fattura</b>: fatture + fatture d'acconto − note di credito (imponibile).</p>
|
||
<p class="sh-note">È sempre in €, anche se in alto è selezionato "N° ordini".</p>`,
|
||
},
|
||
"yr.invCumul": {
|
||
t: "Fatturato progressivo",
|
||
b: `<p>Fatturato sommato da gennaio, anno su anno: dice se stiamo fatturando più o meno degli anni scorsi alla stessa data.</p>`,
|
||
},
|
||
"yr.invTable": {
|
||
t: "Tabella dati fatturato",
|
||
b: `<p>Gli stessi numeri dei grafici in tabella: <b>per mese</b> (con progressivo e variazione) oppure <b>l'elenco delle fatture</b> e note di credito.</p>
|
||
<p class="sh-note">Pulsante Excel per scaricarli: il titolo del file riporta i filtri usati.</p>`,
|
||
},
|
||
"yr.dormant": {
|
||
t: "Clienti da richiamare",
|
||
b: `<p>Clienti che ordinavano <b>con regolarità</b> (almeno 4 volte negli ultimi 3 anni) e che ora <b>tardano</b> rispetto al loro solito.</p>
|
||
<ul>
|
||
<li><b>Ritmo abituale</b>: ogni quanti giorni ordina di solito.</li>
|
||
<li><b>Ritardo</b>: giorni dall'ultimo ordine ÷ ritmo. Es. ordina ogni 30 giorni e sono passati 60 → 2×.</li>
|
||
<li><span class="sh-chip sh-yellow">Attenzione</span> da 1,5× · <span class="sh-chip sh-orange">Dormiente</span> da 2× · <span class="sh-chip sh-red">Probabilmente perso</span> da 4× o oltre un anno.</li>
|
||
<li>In cima quelli che <b>valgono di più</b> (ordinato dei 12 mesi prima dell'ultimo ordine).</li>
|
||
</ul>
|
||
<p class="sh-note">Cosa fare: chiamare partendo dall'alto. Esporta in Excel per dividerli tra i commerciali.</p>`,
|
||
},
|
||
"yr.custcmp": {
|
||
t: "Clienti a confronto",
|
||
b: `<p>Ogni cliente con il suo valore (o numero ordini) negli anni scelti e la variazione tra gli ultimi due.</p>
|
||
<ul>
|
||
<li><b>Nuovi</b>: non c'erano l'anno prima · <b>Persi</b>: non ci sono quest'anno.</li>
|
||
<li><b>In crescita / in calo</b>: oltre ±10%.</li>
|
||
</ul>
|
||
<p class="sh-note">Clic su un cliente per filtrare la pagina; l'icona verde apre la sua scheda.</p>`,
|
||
},
|
||
"yr.ytd": {
|
||
t: "A pari data",
|
||
b: `<p><b>Acceso</b>: ogni anno è contato solo fino al giorno di oggi (es. 1 gennaio – 15 ottobre). È il modo giusto per confrontare l'anno in corso con i precedenti.</p>
|
||
<p><b>Spento</b>: anni interi (l'anno in corso sembrerà sempre più basso finché non finisce).</p>`,
|
||
},
|
||
|
||
/* ===================== CONSEGNE ===================== */
|
||
"dl.horizon": {
|
||
t: "Scadenza",
|
||
b: `<p>Filtra le righe per quando vanno consegnate: scadute (data ZIBO o data cliente), questa settimana, la prossima, entro 30 giorni, senza data.</p>`,
|
||
},
|
||
"dl.total": {
|
||
t: "Da consegnare",
|
||
b: `<p>Tutte le righe ancora da consegnare (con i filtri scelti) e il loro <b>valore residuo</b> (solo la parte non ancora consegnata).</p>`,
|
||
},
|
||
"dl.lateZibo": {
|
||
t: "Scadute (data ZIBO)",
|
||
b: `<p>Righe la cui <b>settimana ZIBO è finita</b> senza consegna: sono i ritardi veri verso il cliente.</p>
|
||
<p class="sh-note">Cosa fare: sono la priorità. Clic sul box per vederle tutte.</p>`,
|
||
},
|
||
"dl.lateClient": {
|
||
t: "Oltre data cliente",
|
||
b: `<p>Righe dove è superata la <b>data desiderata dal cliente</b>. Non sono necessariamente in ritardo per noi, ma il cliente potrebbe sollecitare.</p>`,
|
||
},
|
||
"dl.next7": {
|
||
t: "Prossimi 7 giorni",
|
||
b: `<p>Righe da consegnare da oggi ai prossimi 7 giorni. Clic per vederle.</p>`,
|
||
},
|
||
"dl.nodate": {
|
||
t: "Senza data",
|
||
b: `<p>Righe senza nessuna data di consegna in Mago.</p>
|
||
<p class="sh-note">Cosa fare: vanno completate in Mago, altrimenti non si possono pianificare.</p>`,
|
||
},
|
||
"dl.weekly": {
|
||
t: "Carico consegne per settimana",
|
||
b: `<p>Quanto c'è da consegnare settimana per settimana (per data ZIBO; se manca, data cliente). La prima barra rossa raccoglie tutto lo scaduto.</p>
|
||
<p class="sh-note">Serve a vedere le settimane troppo cariche. Clic su una barra per filtrare quella settimana.</p>`,
|
||
},
|
||
"dl.lateCust": {
|
||
t: "Clienti con più ritardo",
|
||
b: `<p>I clienti con più valore <b>scaduto</b> (data ZIBO superata). Clic per vedere solo le loro righe.</p>
|
||
<p class="sh-note">Utile per sapere chi avvisare per primo.</p>`,
|
||
},
|
||
"dl.rows": {
|
||
t: "Righe da consegnare",
|
||
b: `<p>Ogni riga: ordine, cliente, articolo, quantità ancora da consegnare, valore e date.</p>
|
||
<ul>
|
||
<li><b>ZIBO sett.</b> = settimana comunicata: rossa quando è finita, <span class="sh-chip sh-amber">IN SETTIMANA</span> mentre è in corso.</li>
|
||
<li><b>Cliente</b> = data desiderata dal cliente (arancione se superata).</li>
|
||
</ul>
|
||
<p class="sh-note">Pulsante Excel per scaricare l'elenco filtrato.</p>`,
|
||
},
|
||
|
||
/* ===================== SCHEDA CLIENTE ===================== */
|
||
"sc.status": {
|
||
t: "Stato del cliente",
|
||
b: `<p>Calcolato sul suo <b>ritmo d'ordine</b> degli ultimi 3 anni:</p>
|
||
<ul>
|
||
<li><span class="sh-chip sh-green">Cliente attivo</span> ordina con il suo ritmo normale.</li>
|
||
<li><span class="sh-chip sh-yellow">Attenzione</span> sta tardando (1,5 volte il suo solito).</li>
|
||
<li><span class="sh-chip sh-orange">Dormiente</span> 2 volte il suo solito: da chiamare.</li>
|
||
<li><span class="sh-chip sh-red">Probabilmente perso</span> 4 volte o più di un anno senza ordini.</li>
|
||
<li><span class="sh-chip sh-grey">Ordini occasionali</span> troppo pochi ordini per stimare un ritmo.</li>
|
||
</ul>`,
|
||
},
|
||
"sc.inv": {
|
||
t: "Fatturato dell'anno",
|
||
b: `<p>Fatturato del cliente da gennaio <b>ad oggi</b>, confrontato con lo stesso periodo dell'anno scorso. Sotto: l'anno scorso intero.</p>`,
|
||
},
|
||
"sc.ord": {
|
||
t: "Ordinato dell'anno",
|
||
b: `<p>Ordini ricevuti dal cliente da gennaio <b>ad oggi</b>, confrontati con lo stesso periodo dell'anno scorso.</p>
|
||
<p class="sh-note">Ordinato in calo e fatturato ancora alto = il fatturato calerà nei prossimi mesi.</p>`,
|
||
},
|
||
"sc.open": {
|
||
t: "Da consegnare",
|
||
b: `<p>Valore di quello che gli dobbiamo ancora consegnare e quante righe sono <b>in ritardo</b> (data ZIBO superata).</p>
|
||
<p class="sh-note">Prima di chiamarlo, guarda la scheda "Da consegnare" qui sotto.</p>`,
|
||
},
|
||
"sc.cn": {
|
||
t: "Note di credito",
|
||
b: `<p>Note di credito degli ultimi 12 mesi e quanto pesano sul fatturato. Diventa rosso dal 3%.</p>
|
||
<p class="sh-note">Una percentuale alta indica resi, contestazioni o problemi di qualità ricorrenti.</p>`,
|
||
},
|
||
"sc.years": {
|
||
t: "Ordinato e fatturato per anno",
|
||
b: `<p>Come è cresciuto (o calato) il cliente negli anni. L'anno in corso è <b>ad oggi</b>, quindi più basso finché l'anno non finisce.</p>`,
|
||
},
|
||
"sc.months": {
|
||
t: "Ultimi 24 mesi",
|
||
b: `<p>Ordini (viola) e fatture (verde) mese per mese: mostra se il cliente ordina con regolarità o a picchi, e se si sta fermando.</p>`,
|
||
},
|
||
"sc.tables": {
|
||
t: "Le tabelle",
|
||
b: `<ul>
|
||
<li><b>Da consegnare</b>: righe aperte con quantità mancante e date (ZIBO e cliente). Righe molto vecchie spesso sono da chiudere in Mago.</li>
|
||
<li><b>Ordini</b>: gli ordini del cliente; clic sul numero per aprirlo.</li>
|
||
<li><b>Articoli</b>: cosa compra, quanto, e il <b>prezzo medio</b> degli ultimi 12 mesi rispetto ai 12 precedenti: utile per verificare gli aumenti di listino.</li>
|
||
<li><b>Matrici</b>: le matrici che ordina, con il prezzo per metro o per kg e la variazione sull'anno prima. Clic sul nome per confrontarlo con gli altri clienti.</li>
|
||
<li><b>Fatture</b>: fatture, acconti e note di credito degli ultimi 3 anni.</li>
|
||
</ul>
|
||
<p class="sh-note">Ogni tabella ha il suo pulsante Excel.</p>`,
|
||
},
|
||
|
||
/* ===================== MATRICI ===================== */
|
||
"page.matrici": {
|
||
t: "Matrici: come si legge",
|
||
b: `<p>A che prezzo vendiamo <b>ogni matrice</b>, nell'unità in cui la vendiamo: <b>€/metro</b> se a metri, <b>€/kg</b> se a chili. E quanta <b>mescola</b> consuma.</p>
|
||
<ul>
|
||
<li>I dati vengono dalle <b>righe degli ordini</b>: prezzo = imponibile della riga ÷ quantità.</li>
|
||
<li>Esclusi: righe con quantità 0 o 1 (servizi), spese, ordini annullati e "listino".</li>
|
||
<li><b>Clienti</b> in alto: scegline uno per vedere <b>cosa ordina</b> e a che prezzo.</li>
|
||
<li>Clic su una matrice (tabella, bolla o elenco) per <b>prezzi nel tempo cliente per cliente</b>, mescole e righe d'ordine.</li>
|
||
</ul>
|
||
<p class="sh-note">Le mescole sono una stima dall'ultima scheda di lavoro, senza scarto. Le righe a pezzi aspettano la conversione pezzi → metri.</p>`,
|
||
},
|
||
"mx.types": {
|
||
t: "Tipo",
|
||
b: `<p>Il tipo viene dalla lettera iniziale del campo <b>Matrice/Misura</b> di Mago:</p>
|
||
<ul>
|
||
<li><span class="sh-chip" style="background:#ede9fe;color:#5b21b6">Matrice</span> M + codice (anche in mezzo, es. Q8X8M00936P). Si cerca in anagrafica <b>senza la M</b>, con e senza revisione.</li>
|
||
<li><span class="sh-chip" style="background:#e0f2fe;color:#075985">Tubo</span> T + misura (es. T 10X15)</li>
|
||
<li><span class="sh-chip" style="background:#dcfce7;color:#166534">Rettangolo</span> R + misura (es. R 110X2)</li>
|
||
<li><span class="sh-chip" style="background:#fce7f3;color:#9d174d">Diametro</span> D + misura (es. D 3,3)</li>
|
||
<li><b>Altri</b>: Q quadrato, S, valori non riconosciuti.</li>
|
||
</ul>
|
||
<p>Avvisi accanto alle matrici: <span class="sh-chip sh-orange">non in anagrafica</span> codice che non esiste in anagrafica · <span class="sh-chip sh-orange">altra revisione</span> revisione diversa da quella in anagrafica · <span class="sh-chip sh-orange">abbinata a mano</span> da "Ricorda corrispondenza".</p>
|
||
<p class="sh-note"><b>Da sistemare</b> raccoglie matrici non in anagrafica, altre revisioni e valori non riconosciuti.</p>`,
|
||
},
|
||
"mx.k.value": {
|
||
t: "Venduto con matrice",
|
||
b: `<p>Imponibile delle righe d'ordine del periodo che hanno il campo <b>Matrice/Misura</b> compilato, con il numero di matrici dell'anagrafica e di clienti.</p>`,
|
||
},
|
||
"mx.k.qty": {
|
||
t: "Venduto a metri / a chili",
|
||
b: `<p>Quantità venduta nel periodo e <b>prezzo medio</b> (imponibile ÷ quantità) su tutte le righe in quell'unità.</p>
|
||
<p class="sh-note">Clic sul box per vedere solo le matrici vendute in quell'unità.</p>`,
|
||
},
|
||
"mx.k.mix": {
|
||
t: "Mescola consumata",
|
||
b: `<p>Kg di mescola stimati per le righe vendute nel periodo.</p>
|
||
<p><b>Ancora da produrre</b>: kg necessari per le righe ancora da consegnare (qualsiasi data). È la base per gli acquisti di mescola.</p>`,
|
||
},
|
||
"mx.k.pz": {
|
||
t: "Venduto a pezzi",
|
||
b: `<p>Righe vendute a pezzi (UM N.). Il prezzo al pezzo c'è, ma la mescola non si può stimare finché non c'è la conversione pezzi → metri.</p>`,
|
||
},
|
||
"mx.k.cover": {
|
||
t: "Copertura anagrafica",
|
||
b: `<p>Quanta parte del venduto è collegata a una <b>matrice dell'anagrafica</b> (verde), quanta è tubi, rettangoli, diametri e altri profili (viola), quanta resta da sistemare (arancio).</p>
|
||
<p class="sh-note">Cosa fare: clic sul box per la lista "Da sistemare" e completare l'anagrafica matrici o le corrispondenze.</p>`,
|
||
},
|
||
"mx.k.margin": {
|
||
t: "Margine sul grezzo",
|
||
b: `<p>Quanto resta del prezzo di vendita dopo il <b>costo della sola mescola</b>, sulle matrici dove il costo è completo.</p>
|
||
<ul>
|
||
<li>Costo mescola = g/m della scheda di lavoro × €/kg pagato in Mago (media degli ultimi 3 mesi).</li>
|
||
<li><b>Calcolato sul</b>: quota del venduto che ha un costo completo (scheda con g/m e prezzo di tutte le mescole).</li>
|
||
<li><span class="sh-chip sh-orange">da verificare</span> mescole il cui prezzo potrebbe non comprendere le materie prime (es. Der-Gom).</li>
|
||
</ul>
|
||
<p class="sh-note">Non comprende scarto, lavorazione, energia e trasporto: è il margine "lordo di mescola".</p>`,
|
||
},
|
||
"mx.margin": {
|
||
t: "Margine sul costo mescola",
|
||
b: `<p><b>Margine più basso</b>: le matrici dove il prezzo copre meno il costo della mescola. Sono le prime da rivedere nei listini.</p>
|
||
<p><b>Più margine in euro</b>: le matrici che portano più margine nel periodo (margine unitario × quantità).</p>
|
||
<p>🟢 da 60% · 🟡 da 40 a 60% · 🔴 sotto 40%.</p>
|
||
<p class="sh-note">Contano solo le matrici con costo completo. Clic su una matrice per il dettaglio con la linea del costo nel grafico.</p>`,
|
||
},
|
||
/* ===================== PREVENTIVO ===================== */
|
||
"page.quote": {
|
||
t: "Preventivo: come si usa",
|
||
b: `<ol class="ps-3">
|
||
<li>Scegli la <b>matrice</b>, il <b>cliente</b> (facoltativo) e se vendi <b>al metro o al kg</b>.</li>
|
||
<li><b>Costo</b>: le mescole della scheda di lavoro con g/m ed €/kg pagati in Mago. Puoi correggere i numeri (diventano gialli) e aggiungere scarto e altri costi.</li>
|
||
<li><b>Prezzo</b>: scegli il ricarico sul costo. Il prezzo suggerito si calcola da solo; il <b>prezzo proposto</b> si può arrotondare a mano.</li>
|
||
<li>Confronta con <b>ultimo prezzo al cliente</b>, media di mercato e forbice, poi scrivi un commento e <b>Salva</b>.</li>
|
||
</ol>
|
||
<p class="sh-note">I preventivi salvati restano in fondo alla pagina e si riaprono con un clic. Stampa per avere un foglio pulito.</p>`,
|
||
},
|
||
"pv.cost": {
|
||
t: "Costo",
|
||
b: `<ul>
|
||
<li><b>€/metro</b> = somma di g/m × €/kg ÷ 1000 di ogni mescola della scheda di lavoro.</li>
|
||
<li><b>€/kg</b> (vendita a chili) = media dei €/kg pesata sui g/m.</li>
|
||
<li>€/kg = media pagata in Mago negli ultimi 3 mesi. <span class="sh-chip sh-amber">prezzo vecchio</span> = nessun acquisto recente, si usa l'ultimo. <span class="sh-chip sh-orange">da verificare</span> = fornitore in conto lavoro.</li>
|
||
</ul>
|
||
<p class="sh-note">Le correzioni valgono solo per questo preventivo e vengono salvate con lui.</p>`,
|
||
},
|
||
"pv.scrap": {
|
||
t: "Scarto %",
|
||
b: `<p>Percentuale di mescola persa in produzione (avvii, sfridi, scarti). Il costo della mescola viene aumentato di questa percentuale.</p>`,
|
||
},
|
||
"pv.other": {
|
||
t: "Altri costi",
|
||
b: `<p>Costi per metro o per kg da aggiungere alla mescola: lavorazioni esterne (biadesivo, giunzione, raspatura), imballo, trasporto, quota di lavorazione.</p>`,
|
||
},
|
||
"pv.price": {
|
||
t: "Prezzo suggerito",
|
||
b: `<p><b>Prezzo suggerito</b> = costo totale × (1 + ricarico %). Es. costo 0,50 €/m con ricarico 100% → 1,00 €/m.</p>
|
||
<p>Il pulsante <b>come mercato</b> usa il ricarico che oggi si ottiene con il prezzo medio di vendita della matrice.</p>
|
||
<p>🟢 margine da 60% · 🟡 da 40 a 60% · 🔴 sotto 40% (margine = (prezzo − costo) ÷ prezzo).</p>`,
|
||
},
|
||
"pv.offered": {
|
||
t: "Prezzo proposto",
|
||
b: `<p>È il prezzo che finisce nel preventivo: parte dal suggerito e si può arrotondare a mano. Accanto, il margine che ne risulta.</p>`,
|
||
},
|
||
"pv.refs": {
|
||
t: "Confronto",
|
||
b: `<ul>
|
||
<li><b>Ultimo prezzo al cliente</b> e <b>media cliente</b>: cosa ha pagato finora.</li>
|
||
<li><b>Media mercato</b>: prezzo medio di tutti i clienti negli ultimi 12 mesi.</li>
|
||
<li>La percentuale verde/rossa dice quanto il prezzo proposto è sopra o sotto.</li>
|
||
</ul>`,
|
||
},
|
||
"pv.chart": {
|
||
t: "Costo e prezzi nel tempo",
|
||
b: `<p>Mese per mese: <b>costo della mescola</b> (con i prezzi pagati in quel mese), <b>prezzo medio</b> di tutti i clienti e del cliente scelto. Le righe orizzontali sono il costo totale e il prezzo proposto.</p>
|
||
<p class="sh-note">Se la linea del costo sale e quella dei prezzi no, il margine si sta riducendo.</p>`,
|
||
},
|
||
"mx.map": {
|
||
t: "Mappa dei prezzi",
|
||
b: `<p>Ogni bolla è una matrice venduta nel periodo (le prime 150 per valore).</p>
|
||
<ul>
|
||
<li><b>Verso destra</b>: più quantità venduta (scala logaritmica).</li>
|
||
<li><b>Verso l'alto</b>: prezzo medio più alto.</li>
|
||
<li><b>Più grande</b>: più fatturato.</li>
|
||
</ul>
|
||
<p class="sh-note">Le bolle in basso a destra sono matrici molto vendute a prezzo basso: le prime da guardare per un aumento.</p>`,
|
||
},
|
||
"mx.moves": {
|
||
t: "Prezzi in movimento",
|
||
b: `<p>Prezzo medio degli <b>ultimi 12 mesi</b> rispetto ai <b>12 mesi precedenti</b>, per le matrici vendute in entrambi i periodi.</p>
|
||
<p class="sh-note">Serve a verificare che gli aumenti di listino siano stati applicati e a scoprire cali non voluti.</p>`,
|
||
},
|
||
"mx.table": {
|
||
t: "Classifica matrici",
|
||
b: `<ul>
|
||
<li><b>Prezzo medio</b>: imponibile ÷ quantità del periodo.</li>
|
||
<li><b>Forbice</b>: prezzo minimo e massimo praticato. Barra <span class="sh-chip sh-green">verde</span> fino al 10% di differenza, <span class="sh-chip sh-amber">gialla</span> fino al 25%, <span class="sh-chip sh-red">rossa</span> oltre.</li>
|
||
<li><b>12 mesi</b>: prezzo mese per mese e variazione sui 12 mesi precedenti.</li>
|
||
<li><b>Costo mescola</b>: €/m o €/kg della sola mescola. <span class="sh-chip sh-red">parziale</span> = manca il prezzo o il g/m di qualche mescola (costo sottostimato).</li>
|
||
<li><b>Margine</b>: (prezzo − costo mescola) ÷ prezzo.</li>
|
||
<li><b>Mescola</b>: kg stimati, oppure il motivo per cui mancano (<span class="sh-chip sh-amber">a pezzi</span>, <span class="sh-chip sh-red">g/m mancante</span>).</li>
|
||
</ul>
|
||
<p class="sh-note">La stessa matrice venduta a metri e a chili compare su due righe.</p>`,
|
||
},
|
||
"mx.mix": {
|
||
t: "Mescole consumate per mese",
|
||
b: `<p>Kg di mescola stimati dalle vendite, mese per mese.</p>
|
||
<ul>
|
||
<li>Si usa l'<b>ultima scheda di lavoro</b> della matrice (prima quelle attive).</li>
|
||
<li>Righe a metri: kg = metri × g/m di ciascuna mescola ÷ 1000.</li>
|
||
<li>Righe a chili: i kg si dividono tra le mescole in proporzione ai g/m; senza g/m in parti uguali (2 mescole 50/50, 3 mescole 33%).</li>
|
||
</ul>
|
||
<p class="sh-note">Per ora senza scarto.</p>`,
|
||
},
|
||
"mx.mixneed": {
|
||
t: "Fabbisogno mescole",
|
||
b: `<p><b>Venduto</b>: kg di mescola delle righe ordinate nel periodo.</p>
|
||
<p><b>Da produrre</b>: kg che servono per le righe <b>ancora da consegnare</b>, qualsiasi sia la data dell'ordine.</p>
|
||
<p class="sh-note">Quando avremo il costo delle mescole, da qui si calcolerà anche il costo grezzo.</p>`,
|
||
},
|
||
"mx.dprice": {
|
||
t: "Prezzo nel tempo",
|
||
b: `<p>Ogni punto è una <b>riga d'ordine</b>: altezza = prezzo, colore = cliente (i primi 8 per valore, gli altri insieme).</p>
|
||
<p>La linea scura è il <b>prezzo medio del mese</b>. Punti sotto la linea = clienti che pagano meno della media.</p>
|
||
<p>La <b>linea rossa tratteggiata</b> è il costo della mescola mese per mese (prezzi pagati in quel mese): la distanza dalla linea dei prezzi è il margine.</p>
|
||
<p class="sh-note">Nella tabella Clienti, "Rispetto alla media" mostra di quanto ognuno paga più o meno, "Margine" quanto resta dopo la mescola.</p>`,
|
||
},
|
||
};
|
||
|
||
/* ===================== STILE ===================== */
|
||
const CSS = `
|
||
.sh-btn{border:0;background:transparent;color:#94a3b8;padding:0 3px;margin-left:4px;font-size:.92em;line-height:1;cursor:pointer;vertical-align:baseline;text-transform:none;letter-spacing:0}
|
||
.sh-btn:hover,.sh-btn.open{color:#198754}
|
||
.sh-page{border:1px solid #d1fae5;background:#f0fdf4;color:#166534;border-radius:999px;padding:6px 14px;font-weight:700;font-size:.88rem;cursor:pointer;white-space:nowrap}
|
||
.sh-page:hover{background:#dcfce7}
|
||
.sh-pop{position:absolute;z-index:2000;width:340px;max-width:calc(100vw - 24px);background:#fff;border:1px solid #e2e8f0;border-radius:14px;
|
||
box-shadow:0 18px 40px rgba(15,23,42,.18);padding:14px 16px 12px;font-size:.9rem;color:#1f2d3d;line-height:1.45;text-transform:none;letter-spacing:0;font-weight:400}
|
||
.sh-pop.wide{width:460px}
|
||
.sh-pop h6{font-weight:800;font-size:.98rem;margin:0 26px 8px 0;display:flex;align-items:center;gap:8px}
|
||
.sh-pop h6 i{color:#198754}
|
||
.sh-pop p{margin:0 0 8px}
|
||
.sh-pop ul{margin:0 0 8px;padding-left:18px}
|
||
.sh-pop li{margin-bottom:4px}
|
||
.sh-pop .sh-note{background:#f0fdf4;border-left:3px solid #22c55e;padding:6px 10px;border-radius:6px;color:#14532d;margin:8px 0 0}
|
||
.sh-pop .sh-x{position:absolute;right:8px;top:8px;border:0;background:transparent;color:#94a3b8;font-size:1.1rem;cursor:pointer;line-height:1;padding:4px}
|
||
.sh-pop .sh-x:hover{color:#1f2d3d}
|
||
.sh-chip{display:inline-block;font-size:.72rem;font-weight:800;border-radius:999px;padding:1px 8px;white-space:nowrap}
|
||
.sh-red{background:#fee2e2;color:#991b1b}.sh-orange{background:#ffedd5;color:#9a3412}.sh-amber{background:#fef3c7;color:#b45309}
|
||
.sh-yellow{background:#fef9c3;color:#854d0e}.sh-green{background:#dcfce7;color:#166534}.sh-grey{background:#e2e8f0;color:#334155}`;
|
||
|
||
function injectCss() {
|
||
if (document.getElementById("sales-help-css")) return;
|
||
const st = document.createElement("style");
|
||
st.id = "sales-help-css";
|
||
st.textContent = CSS;
|
||
document.head.appendChild(st);
|
||
}
|
||
|
||
/* ===================== POPOVER ===================== */
|
||
let pop = null,
|
||
popBtn = null;
|
||
|
||
function close() {
|
||
if (pop) pop.remove();
|
||
if (popBtn) popBtn.classList.remove("open");
|
||
pop = null;
|
||
popBtn = null;
|
||
}
|
||
|
||
function open(btn, key, wide) {
|
||
const h = SALES_HELP[key];
|
||
if (!h) return;
|
||
if (popBtn === btn) {
|
||
close();
|
||
return;
|
||
}
|
||
close();
|
||
pop = document.createElement("div");
|
||
pop.className = "sh-pop" + (wide ? " wide" : "");
|
||
pop.setAttribute("role", "dialog");
|
||
pop.innerHTML = `<button type="button" class="sh-x" aria-label="Chiudi">×</button>
|
||
<h6><i class="fa-solid fa-circle-info"></i>${h.t}</h6>${h.b}`;
|
||
document.body.appendChild(pop);
|
||
popBtn = btn;
|
||
btn.classList.add("open");
|
||
|
||
// posizione: sotto l'icona, dentro lo schermo
|
||
const r = btn.getBoundingClientRect();
|
||
const pw = pop.offsetWidth,
|
||
ph = pop.offsetHeight;
|
||
let left = r.left + window.scrollX - 12;
|
||
left = Math.max(
|
||
window.scrollX + 12,
|
||
Math.min(
|
||
left,
|
||
window.scrollX + document.documentElement.clientWidth - pw - 12,
|
||
),
|
||
);
|
||
let top = r.bottom + window.scrollY + 8;
|
||
if (r.bottom + ph + 16 > window.innerHeight && r.top - ph - 8 > 0)
|
||
top = r.top + window.scrollY - ph - 8;
|
||
pop.style.left = left + "px";
|
||
pop.style.top = top + "px";
|
||
pop.querySelector(".sh-x").addEventListener("click", close);
|
||
}
|
||
|
||
/* ===================== ICONE ⓘ ===================== */
|
||
function decorate(root) {
|
||
// controllo il figlio (non un attributo): se la pagina riscrive il titolo con .text() l'icona viene rimessa
|
||
(root || document).querySelectorAll("[data-help]").forEach((el) => {
|
||
if (el.querySelector(":scope > .sh-btn")) return;
|
||
const b = document.createElement("button");
|
||
b.type = "button";
|
||
b.className = "sh-btn";
|
||
b.title = "Cosa vedo qui?";
|
||
b.setAttribute("aria-label", "Aiuto");
|
||
b.dataset.k = el.getAttribute("data-help");
|
||
b.innerHTML = '<i class="fa-solid fa-circle-info"></i>';
|
||
el.appendChild(b);
|
||
});
|
||
}
|
||
|
||
document.addEventListener(
|
||
"click",
|
||
function (e) {
|
||
const b = e.target.closest(".sh-btn");
|
||
if (b) {
|
||
// non far scattare il click del box/riga (filtri, ordinamento...)
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
open(b, b.dataset.k, false);
|
||
return;
|
||
}
|
||
const p = e.target.closest("[data-help-open]");
|
||
if (p) {
|
||
e.preventDefault();
|
||
open(p, p.getAttribute("data-help-open"), true);
|
||
return;
|
||
}
|
||
if (pop && !e.target.closest(".sh-pop")) close();
|
||
},
|
||
true,
|
||
);
|
||
|
||
document.addEventListener("keydown", (e) => {
|
||
if (e.key === "Escape") close();
|
||
});
|
||
window.addEventListener("resize", close);
|
||
|
||
function start() {
|
||
injectCss();
|
||
decorate(document);
|
||
// elementi disegnati dopo dal JavaScript della pagina
|
||
new MutationObserver((muts) => {
|
||
for (const m of muts) {
|
||
if (m.addedNodes.length) {
|
||
decorate(document);
|
||
break;
|
||
}
|
||
}
|
||
}).observe(document.body, {
|
||
childList: true,
|
||
subtree: true,
|
||
});
|
||
}
|
||
|
||
if (document.readyState === "loading")
|
||
document.addEventListener("DOMContentLoaded", start);
|
||
else start();
|
||
|
||
window.SALES_HELP = SALES_HELP;
|
||
})();
|