Calendario: il PDF e' un file vero, generato dal server
"Scarica in PDF" non apre piu' la stampa del browser: e' un link a /calendario/<id>.pdf che restituisce un documento disegnato dal dato con PDFKit, con Content-Disposition attachment. Serve perche' il calendario si gira su WhatsApp, ed e' cosi' che questo centro parla coi clienti: chi lo riceve non ha il sito aperto davanti. Niente browser headless: Chromium in un container da 2 vCPU costa centinaia di megabyte e un processo per richiesta, per una griglia di sette colonne. Le linee della griglia si tracciano in una passata a parte, dopo i riempimenti: disegnandole riga per riga, il riempimento della riga seguente copriva quella appena fatta e due lezioni uguali in fasce consecutive si leggevano come un blocco unico lungo il doppio. Quattro test: intestazione %PDF- e coda %%EOF (un documento non chiuso arriva monco e il browser mostra una pagina bianca invece di un errore), una pagina sola, nomi di file distinti. Un id sconosciuto e' 404, non un PDF vuoto. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,7 @@ const presenti = cal
|
||||
)}
|
||||
</div>
|
||||
<div class="cal-dlg__azioni">
|
||||
<button type="button" class="cal-dlg__btn" data-stampa-calendario>{t('calendario.pdf-label')}</button>
|
||||
<a class="cal-dlg__btn" href={`/calendario/${cal.id}.pdf`} download>{t('calendario.pdf-label')}</a>
|
||||
<button type="button" class="cal-dlg__chiudi" data-chiudi-calendario aria-label={t('calendario.chiudi-label')}>×</button>
|
||||
</div>
|
||||
</header>
|
||||
@@ -93,10 +93,9 @@ const presenti = cal
|
||||
dlg.querySelector('[data-chiudi-calendario]')?.addEventListener('click', () => dlg.close());
|
||||
// Click sul fondale: il target è il dialog stesso solo quando si preme fuori dal riquadro.
|
||||
dlg.addEventListener('click', (e) => { if (e.target === dlg) dlg.close(); });
|
||||
// "Scarica in PDF" = stampa con la destinazione "Salva come PDF": la pagina di stampa è
|
||||
// già impaginata per la sola griglia (vedi @media print), quindi non serve generare nulla
|
||||
// lato server né caricare una libreria.
|
||||
dlg.querySelector('[data-stampa-calendario]')?.addEventListener('click', () => window.print());
|
||||
// "Scarica in PDF" è un link a `/calendario/<id>.pdf`, cioè un file vero generato dal
|
||||
// server: si salva sul telefono e si gira su WhatsApp. Il CSS di stampa più sotto resta
|
||||
// per chi preme Ctrl+P col popup aperto.
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -122,9 +121,10 @@ const presenti = cal
|
||||
}
|
||||
.cal-dlg__azioni { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
|
||||
.cal-dlg__btn {
|
||||
font-family: var(--font-heading); font-size: .68rem; font-weight: 600; letter-spacing: .2em;
|
||||
text-transform: uppercase; border: 0; cursor: pointer; padding: 13px 22px;
|
||||
background: var(--c-accent); color: #fff; transition: background .2s;
|
||||
display: inline-block; font-family: var(--font-heading); font-size: .68rem; font-weight: 600;
|
||||
letter-spacing: .2em; text-transform: uppercase; text-decoration: none; border: 0;
|
||||
cursor: pointer; padding: 13px 22px; background: var(--c-accent); color: #fff;
|
||||
transition: background .2s;
|
||||
}
|
||||
.cal-dlg__btn:hover { background: var(--c-accent-dark); }
|
||||
.cal-dlg__chiudi {
|
||||
|
||||
Reference in New Issue
Block a user