# Review package: 3f16283..6c13410 ## Commits 6c13410 PDF: UI pulsante con stati e polling (dettaglio + elenco) ## Files changed app/src/lib/components/PdfButton.svelte | 90 +++++++++++++++++++++++++++++ app/src/routes/agenzie/+page.svelte | 18 ++++-- app/src/routes/agenzie/[id]/+page.server.ts | 6 +- app/src/routes/agenzie/[id]/+page.svelte | 19 ++++-- 4 files changed, 122 insertions(+), 11 deletions(-) ## Diff diff --git a/app/src/lib/components/PdfButton.svelte b/app/src/lib/components/PdfButton.svelte new file mode 100644 index 0000000..84a1f7d --- /dev/null +++ b/app/src/lib/components/PdfButton.svelte @@ -0,0 +1,90 @@ + + +{#if state === 'ready'} + + Scarica PDF + + {#if generatoIl} + generato il {generatoIl.slice(0, 10)} + {/if} +{:else if state === 'generating'} + + ↻ + PDF in aggiornamento, pronto tra ~1 min… + + scarica versione precedente +{:else if state === 'stale'} + + scarica versione precedente +{:else if state === 'error'} + +{:else} + + +{/if} diff --git a/app/src/routes/agenzie/+page.svelte b/app/src/routes/agenzie/+page.svelte index 3644513..fb7c9ad 100644 --- a/app/src/routes/agenzie/+page.svelte +++ b/app/src/routes/agenzie/+page.svelte @@ -135,25 +135,33 @@ class="cursor-pointer hover:bg-brand-50" > {a.codiceImmobile ?? a.codiceFisico} {a.tipologia} {a.nomeAgenzia} {a.nomeSede} {a.citta} ({a.provincia}) - {#if a.hasDvr} - ✓ compilato - {:else} - vuoto - {/if} +
+ {#if a.hasDvr} + ✓ compilato + e.stopPropagation()} + >PDF + {:else} + vuoto + {/if} +
{:else} Nessuna sede trovata. {/each} {#if totalPages > 1} diff --git a/app/src/routes/agenzie/[id]/+page.server.ts b/app/src/routes/agenzie/[id]/+page.server.ts index f484d5e..8021620 100644 --- a/app/src/routes/agenzie/[id]/+page.server.ts +++ b/app/src/routes/agenzie/[id]/+page.server.ts @@ -3,20 +3,21 @@ import { createHash } from 'node:crypto'; import { db } from '$lib/server/db'; import { agenzie, dvr, agenzieAllegati, lookupRegioniAlleanza, lookupRegioniGeografiche } from '$lib/server/db/schema'; import { and, eq, asc } from 'drizzle-orm'; import { R2_AVAILABLE, putObject, deleteObject } from '$lib/server/r2'; +import { getPdfStatus } from '$lib/server/pdf/state'; const TIPI_VALIDI = [ 'planimetria_layout', 'planimetria_emergenza', 'luogo_sicuro_esterno', 'foto_immobile', 'altro' ] as const; type TipoAllegato = (typeof TIPI_VALIDI)[number]; @@ -84,27 +85,30 @@ export const load = async ({ params }) => { .orderBy(asc(agenzieAllegati.id)); const grouped = { planimetria_layout: allegati.filter((x) => x.tipo === 'planimetria_layout'), planimetria_emergenza: allegati.filter((x) => x.tipo === 'planimetria_emergenza'), luogo_sicuro_esterno: allegati.filter((x) => x.tipo === 'luogo_sicuro_esterno'), foto_immobile: allegati.filter((x) => x.tipo === 'foto_immobile'), altro: allegati.filter((x) => x.tipo === 'altro') }; + const pdfStatus = await getPdfStatus(dvrAgenziaId); + return { agenzia: a.a, regioneAlleanza: a.regioneAlleanza, regioneGeo: a.regioneGeo, dvr: dvrRow ?? null, dvrCondivisoDa, - allegati: grouped + allegati: grouped, + pdfStatus: { state: pdfStatus.state, generatoIl: pdfStatus.generatoIl } }; }; export const actions = { upload: async ({ params, request }) => { if (!R2_AVAILABLE) return fail(500, { error: 'Storage R2 non configurato.' }); const id = parseInt(params.id, 10); if (Number.isNaN(id)) throw error(400, 'ID agenzia non valido'); diff --git a/app/src/routes/agenzie/[id]/+page.svelte b/app/src/routes/agenzie/[id]/+page.svelte index b899370..42b87c5 100644 --- a/app/src/routes/agenzie/[id]/+page.svelte +++ b/app/src/routes/agenzie/[id]/+page.svelte @@ -1,12 +1,13 @@