diff --git a/.gitignore b/.gitignore index c15f9c0..ae74e3d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ apps/infoalloggi/fic_cities.json apps/infoalloggi/fic_nations.json apps/infoalloggi/gi_comuni_cap.json apps/infoalloggi/gi_nazioni.json +apps/infoalloggi/tmp/ + diff --git a/apps/infoalloggi/.dockerignore b/apps/infoalloggi/.dockerignore index f3bf231..c744718 100644 --- a/apps/infoalloggi/.dockerignore +++ b/apps/infoalloggi/.dockerignore @@ -27,3 +27,4 @@ docs biome_plugins vitest.config.mts tsconfig.tsbuildinfo +tmp diff --git a/apps/infoalloggi/.vscode/settings.json b/apps/infoalloggi/.vscode/settings.json index 4a560f2..56a92f8 100644 --- a/apps/infoalloggi/.vscode/settings.json +++ b/apps/infoalloggi/.vscode/settings.json @@ -21,4 +21,5 @@ ], "js/ts.tsdk.path": "node_modules\\typescript\\lib", "biome.lsp.trace.server": "verbose", + "tinymist.fontPaths": ["${workspaceFolder}/typst/fonts"] } \ No newline at end of file diff --git a/apps/infoalloggi/Dockerfile b/apps/infoalloggi/Dockerfile index b697650..4d7ae93 100644 --- a/apps/infoalloggi/Dockerfile +++ b/apps/infoalloggi/Dockerfile @@ -88,7 +88,7 @@ ENV STORAGE_TOKEN=$STORAGE_TOKEN ARG BROWSER_WS_URL ENV BROWSER_WS_URL=$BROWSER_WS_URL -RUN apk add --no-cache curl +RUN apk add --no-cache curl pandoc typst RUN addgroup -g 1001 -S nodejs RUN adduser -S nextjs -u 1001 @@ -97,6 +97,9 @@ COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder --chown=nextjs:nodejs /app/typst ./typst + +RUN mkdir -p /app/tmp && chown nextjs:nodejs /app/tmp USER nextjs diff --git a/apps/infoalloggi/src/server/api/routers/test.ts b/apps/infoalloggi/src/server/api/routers/test.ts index c63eb86..5077ad6 100644 --- a/apps/infoalloggi/src/server/api/routers/test.ts +++ b/apps/infoalloggi/src/server/api/routers/test.ts @@ -3,6 +3,7 @@ import { protectedApiProcedure, publicProcedure, } from "~/server/api/trpc"; +import { TypstRunner, TypstRunner2 } from "~/server/services/typst.service"; export const testRouter = createTRPCRouter({ testApi: protectedApiProcedure.query(async () => { @@ -14,6 +15,9 @@ export const testRouter = createTRPCRouter({ console.error("test console.error"); throw new Error("This is a test error"); }), + testTypst: publicProcedure.query(async () => { + return await TypstRunner2(); + }), }); /* PROTECTED API CALL EXAMPLE diff --git a/apps/infoalloggi/src/server/services/typst.service.ts b/apps/infoalloggi/src/server/services/typst.service.ts new file mode 100644 index 0000000..afa5529 --- /dev/null +++ b/apps/infoalloggi/src/server/services/typst.service.ts @@ -0,0 +1,167 @@ +import { exec, execSync } from "node:child_process"; +import fs from "node:fs/promises"; +import path from "node:path"; +import { promisify } from "node:util"; +import { TRPCError } from "@trpc/server"; +import type { TestiEStringheStingaId } from "~/schemas/public/TestiEStringhe"; +import { db } from "~/server/db"; +import { getStringa } from "~/server/services/testi_stringhe.service"; + +const execPromise = promisify(exec); +const projectRoot = path.resolve("."); +const fontsPath = path.join(projectRoot, "typst", "fonts"); + +const tmpDir = path.join(projectRoot, "tmp"); + +type RicevutaProps = { + ordineId: string; + date: string; + datetime: string; + nominativo: string; + codicefiscale: string; + indirizzo: string; + nazione: string; + items: { + title: string; + desc: string | null; + discount: number | null; + amount: number; + strike: boolean; + }[]; + total: number; + vat: number; + method: string; +}; + +export const TypstRunner = async () => { + const timestamp = Date.now(); + await fs.mkdir(tmpDir, { recursive: true }); + const jsonFileName = `data-${timestamp}.json`; + const jsonPath = path.join(tmpDir, jsonFileName); + const templatePath = path.join(projectRoot, "typst", "receipt.typ"); + const pdfPath = path.join(tmpDir, `receipt-${timestamp}.pdf`); + + const props: RicevutaProps = { + ordineId: "dniuawndiandioawmodmawodmawdaw", + date: "10 gennaio 2026", + datetime: "14:55", + nominativo: "Di Grigoli Angelo Damiano", + codicefiscale: "DGRNLD97C13B602Z", + indirizzo: "Via Aldo Fantina 15, PIEVE DEL GRAPPA (TV) 31017,", + nazione: "Italia", + items: [ + { + title: "Acconto Cerco Transitorio", + desc: null, + discount: null, + amount: 3500, + strike: false, + }, + { + title: "Saldo Cerco Affitto Transitorio (6 mesi)", + desc: "Pagamento differito, non è dovuto in questo momento", + discount: null, + amount: 37500, + strike: true, + }, + ], + total: 3500, + vat: 3500 * 0.22, + method: "Carta di credito", + }; + + await fs.writeFile(jsonPath, JSON.stringify(props)); + + try { + const command = `typst compile --input data_path=/tmp/${jsonFileName} --root "${projectRoot}" --font-path "${fontsPath}" "${templatePath}" "${pdfPath}"`; + + await execPromise(command); + + const pdfBuffer = await fs.readFile(pdfPath); + return new Response(pdfBuffer, { + headers: { "Content-Type": "application/pdf" }, + }); + } catch (err) { + console.error("typst compile failed:", err); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to generate PDF with Typst", + cause: err instanceof Error ? err : undefined, + }); + } finally { + // Cleanup — runs even on failure + await Promise.all([ + fs.unlink(jsonPath).catch(() => {}), + //fs.unlink(pdfFile).catch(() => {}), + ]); + } +}; + +export const TypstRunner2 = async () => { + const s = await getStringa({ + db: db, + stringaId: "CONDIZIONI_CERCHI" as TestiEStringheStingaId, + }); + if (!s || !s.stringa_value) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Stringa non trovata", + }); + } + const timestamp = Date.now(); + await fs.mkdir(tmpDir, { recursive: true }); + const jsonFileName = `tmp-${timestamp}.json`; + const jsonPath = path.join(tmpDir, jsonFileName); + const templatePath = path.join(projectRoot, "typst", "testi.typ"); + const pdfFile = path.join(tmpDir, `doc-${timestamp}.pdf`); + + const p = convertHtmlToTypst(s.stringa_value); + + await fs.writeFile(jsonPath, JSON.stringify({ stringa: p })); + + try { + const command = `typst compile --input data_path=/tmp/${jsonFileName} --root "${projectRoot}" --font-path "${fontsPath}" "${templatePath}" "${pdfFile}"`; + await execPromise(command); + const pdfBuffer = await fs.readFile(pdfFile); + return new Response(pdfBuffer, { + headers: { "Content-Type": "application/pdf" }, + }); + } catch (err) { + console.error("typst compile failed:", err); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to generate PDF with Typst", + cause: err instanceof Error ? err : undefined, + }); + } finally { + // Cleanup — runs even on failure + await Promise.all([ + fs.unlink(jsonPath).catch(() => {}), + //fs.unlink(pdfFile).catch(() => {}), + ]); + } +}; + +/** + * Converts HTML to Typst markup using Pandoc. + * works on Windows & Linux. + */ +function convertHtmlToTypst(html: string): string { + try { + // We pass the HTML via 'input' which writes to the process stdin + const output = execSync( + "pandoc -f html -t typst --syntax-highlighting=none", + { + input: html, + encoding: "utf-8", + }, + ); + return output; + } catch (error) { + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to convert HTML to Typst", + cause: error instanceof Error ? error : undefined, + }); + } +} diff --git a/apps/infoalloggi/typst/annuncio.typ b/apps/infoalloggi/typst/annuncio.typ new file mode 100644 index 0000000..2fe3cf9 --- /dev/null +++ b/apps/infoalloggi/typst/annuncio.typ @@ -0,0 +1,139 @@ +#import "@preview/iconic-salmon-fa:1.1.0": fa-location-pin, fa-whatsapp +#set page( + paper: "a4", + margin: (bottom: 1.5cm, rest: 1cm), + footer: [ + #line(length: 100%, stroke: 0.5pt + luma(200)) + #set text(size: 8pt, fill: luma(100)) + #grid( + columns: (1fr, auto), + [Arcenia Srl. Tel. +39 0424529869 | Email: arca\@infoalloggi.it], [Documento generato in data: 31/3/2026], + ) + ], +) + +#set text(font: "Inter 18pt", size: 10pt, lang: "it", fill: rgb("#1f1f1f")) +#set par(justify: true, leading: 0.65em) + +// --- HEADER --- +#grid( + columns: (1fr, 1fr), + align: (left, right), + image("../public/Infoalloggi.png", width: 150pt, height: auto), + + [ + *Arcenia Srl* \ + Via Beata Giovanna, 1 a Bassano del Grappa (VI) \ + Tel. +39 0424529869 \ + Email: arca\@infoalloggi.it + ], +) +#v(1em) +#line(length: 100%, stroke: 0.5pt + luma(200)) +#v(1em) + +// --- TITLE & REFERENCE --- +#align(center)[#text( + size: 16pt, + weight: "bold", + fill: rgb("#63493f"), +)[BASSANO S. VITO MONOLOCALE A USO TRANSITORIO - 01/06/26]] +#v(0.5em) + +#align(center)[#text( + size: 14pt, +)[Riferimento: *3786B*]] + +#v(1.5em) + +#box(stroke: (paint: rgb("#25d366"), thickness: 1.5pt), width: 100%, inset: 16pt, radius: 10pt)[ + #grid( + columns: 1fr, + gutter: 14pt, + [#fa-whatsapp(size: 20pt, fill: rgb("#25d366"))#h(1em)#text( + size: 16pt, + weight: "bold", + fill: rgb("#63493f"), + )[Contatti]#h(.5em)#text(size: 12pt, fill: rgb("#63493f"))[(mandare un messaggio WhatsApp prima di chiamare)]], + [INFOALLOGGI (delegato)], + [*Tel. +393453944827*] + ) +] +#v(1.5em) +#grid( + columns: 1fr, + gutter: 10pt, [ + #text(size: 10pt, weight: "bold")[Indirizzo]], [ + #line(length: 100%, stroke: 0.5pt + luma(200))], [ + #text(weight: "bold", size: 12pt)[VIA MONTE ASOLONE, 21 int 1 Bassano del Grappa 36061 (VI)]#h(3em)#link( + "https://maps.google.com", + )[#fa-location-pin(size: 20pt, fill: red)#text(fill: blue)[Apri in Google Maps]] + ] +) + +#v(0.5em) + +#v(0.5em) + + +#v(1.5em) + +// --- KEY DETAILS TABLE --- +#table( + columns: (1fr, 1fr, 1fr), + stroke: 0.5pt + luma(200), + inset: 10pt, + [*Tipologia* \ Affitto Transitorio], [*Canone Mensile* \ 540,00 €], [*Disponibile da* \ 31/05/2026], +) +#v(1.5em) + +// --- FEATURES --- +#text(size: 12pt, weight: "bold")[Dotazioni e Servizi] +#v(0.5em) +#grid( + columns: (1fr, 1fr, 1fr), + gutter: 10pt, + [- *Tipo Impianto:* Radiatori], [- *Riscaldamento:* Autonomo], [- *Arredi:* Arredato], + [- *Piani Edificio:* Uno], [- *Internet:* No], +) +#v(1.5em) + +// --- DESCRIPTION --- +#text(size: 12pt, weight: "bold")[Descrizione] +#v(0.5em) +CODICE: 3786B LIBERO DA GIUGNO AFFITTO TRANSITORIO - Confortevole monolocale situato nella tranquilla zona di San Vito, a Bassano del Grappa. Libero da giugno, questo appartamento è la soluzione ideale per chi cerca un affitto transitorio. + +Completamente ammobiliato e arredato con gusto, il monolocale si trova al piano terra e offre un soggiorno luminoso con un angolo cottura recente. La camera, dotata di un comodo letto alla francese, è separata da una parete per garantire privacy. Classe energetica F. + +Il bagno è completo di doccia e lavatrice nuova, perfetto per le esigenze quotidiane. Inoltre, è disponibile un posto auto scoperto riservato, rendendo la vita ancora più comoda. Le utenze sono attive, e il contratto di affitto prevede una permanenza da 6 a 12 mesi, con un canone mensile di 540,00 € e spese condominiali di 80,00 €/mese. + +Questo monolocale è ideale per single e si trova in un contesto tranquillo, lontano dal caos cittadino. Non è consentito fumare all'interno dei locali e si preferiscono inquilini senza animali. Non perdere l'occasione di vivere in un ambiente accogliente e funzionale! Contattaci per maggiori informazioni e per organizzare una visita. +#v(1.5em) + +// --- OWNER REQUESTS --- +#rect(fill: rgb("#f5f5f5"), width: 100%, inset: 15pt, stroke: none)[ + #text(size: 12pt, weight: "bold")[RICHIESTE DEL PROPRIETARIO:] + #v(0.5em) + #list( + [*Tipologia contratto di locazione:* TRANSITORIO (No stabile)], + [*Regime fiscale:* CEDOLARE SECCA (Senza imposte di registro e bolli)], + [*Data disponibilità:* 1 GIUGNO], + [*Permanenza:* DA 6 a 12 MESI], + [*Preferenza:* SINGLE], + [*Contratto di lavoro:* A TEMPO DETERMINATO (o altra motivazione prevista per legge)], + [*Canone mensile:* 540,00 €], + [*Spese condominiali e accessorie:* 80,00 €/MESE], + [*Deposito cauzionale:* IN BASE ALLA PERMANENZA], + [*Consumi utenze:* Gas/Riscaldamento - Luce Acqua (Rimborso a CONSUMO)], + [*Fumatori:* NON E' CONSENTITO FUMARE ALL'INTERNO DEI LOCALI], + [*Animali:* NON E' CONSENTITO], + ) +] +#v(1.5em) + +// --- HOW TO VISIT --- +#text(size: 12pt, weight: "bold")[COSA FARE PER VISITARE L'IMMOBILE] +#v(0.5em) +Infoalloggi.it è una piattaforma immobiliare che ti consente di avere un contatto diretto con i proprietari previa attivazione del servizio. La piattaforma e i nostri referenti sono a tua disposizione per assisterti nella tua ricerca. + +La geo-localizzazione indica la zona dell'immobile, l'indirizzo esatto lo ricevi con l'attivazione del servizio. Informazione strettamente riservata ed indirizzata all'Utente Arca-Infoalloggi nel rispetto dell' Art. F. Precisazione dei Tuoi Obblighi e responsabilità delle Condizioni Generali di Contratto (CGC) accettate. diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Black.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Black.ttf new file mode 100644 index 0000000..89673de Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Black.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-BlackItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-BlackItalic.ttf new file mode 100644 index 0000000..b33602f Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-BlackItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Bold.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Bold.ttf new file mode 100644 index 0000000..57704d1 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Bold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-BoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-BoldItalic.ttf new file mode 100644 index 0000000..d53a199 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-BoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraBold.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraBold.ttf new file mode 100644 index 0000000..e71c601 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraBold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraBoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraBoldItalic.ttf new file mode 100644 index 0000000..df45062 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraBoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraLight.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraLight.ttf new file mode 100644 index 0000000..f9c6cfc Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraLight.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraLightItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraLightItalic.ttf new file mode 100644 index 0000000..275f305 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-ExtraLightItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Italic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Italic.ttf new file mode 100644 index 0000000..14d3595 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Italic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Light.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Light.ttf new file mode 100644 index 0000000..acae361 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Light.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-LightItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-LightItalic.ttf new file mode 100644 index 0000000..f69e18b Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-LightItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Medium.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Medium.ttf new file mode 100644 index 0000000..71d9017 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Medium.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-MediumItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-MediumItalic.ttf new file mode 100644 index 0000000..5c8c8b1 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-MediumItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Regular.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Regular.ttf new file mode 100644 index 0000000..ce097c8 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Regular.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-SemiBold.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-SemiBold.ttf new file mode 100644 index 0000000..053185e Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-SemiBold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-SemiBoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-SemiBoldItalic.ttf new file mode 100644 index 0000000..d9c9896 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-SemiBoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-Thin.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-Thin.ttf new file mode 100644 index 0000000..e68ec47 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-Thin.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_18pt-ThinItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_18pt-ThinItalic.ttf new file mode 100644 index 0000000..134e837 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_18pt-ThinItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Black.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Black.ttf new file mode 100644 index 0000000..dbb1b3b Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Black.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-BlackItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-BlackItalic.ttf new file mode 100644 index 0000000..b89d61c Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-BlackItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Bold.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Bold.ttf new file mode 100644 index 0000000..e974d96 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Bold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-BoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-BoldItalic.ttf new file mode 100644 index 0000000..1c3d251 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-BoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraBold.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraBold.ttf new file mode 100644 index 0000000..b775c08 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraBold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraBoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraBoldItalic.ttf new file mode 100644 index 0000000..3461a92 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraBoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraLight.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraLight.ttf new file mode 100644 index 0000000..2ec6ca3 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraLight.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraLightItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraLightItalic.ttf new file mode 100644 index 0000000..c634a5d Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-ExtraLightItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Italic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Italic.ttf new file mode 100644 index 0000000..1048b07 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Italic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Light.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Light.ttf new file mode 100644 index 0000000..1a2a6f2 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Light.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-LightItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-LightItalic.ttf new file mode 100644 index 0000000..ded5a75 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-LightItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Medium.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Medium.ttf new file mode 100644 index 0000000..5c88739 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Medium.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-MediumItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-MediumItalic.ttf new file mode 100644 index 0000000..be091b1 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-MediumItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Regular.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Regular.ttf new file mode 100644 index 0000000..6b088a7 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Regular.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-SemiBold.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-SemiBold.ttf new file mode 100644 index 0000000..ceb8576 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-SemiBold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-SemiBoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-SemiBoldItalic.ttf new file mode 100644 index 0000000..6921df2 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-SemiBoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-Thin.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-Thin.ttf new file mode 100644 index 0000000..3505b35 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-Thin.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_24pt-ThinItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_24pt-ThinItalic.ttf new file mode 100644 index 0000000..a3e6feb Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_24pt-ThinItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Black.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Black.ttf new file mode 100644 index 0000000..66a252f Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Black.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-BlackItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-BlackItalic.ttf new file mode 100644 index 0000000..3c8fdf9 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-BlackItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Bold.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Bold.ttf new file mode 100644 index 0000000..14db994 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Bold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-BoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-BoldItalic.ttf new file mode 100644 index 0000000..704b12b Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-BoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraBold.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraBold.ttf new file mode 100644 index 0000000..6d87cae Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraBold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraBoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraBoldItalic.ttf new file mode 100644 index 0000000..1a56735 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraBoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraLight.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraLight.ttf new file mode 100644 index 0000000..d42b3f5 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraLight.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraLightItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraLightItalic.ttf new file mode 100644 index 0000000..90e2f20 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-ExtraLightItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Italic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Italic.ttf new file mode 100644 index 0000000..c2a143a Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Italic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Light.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Light.ttf new file mode 100644 index 0000000..5eeff3a Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Light.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-LightItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-LightItalic.ttf new file mode 100644 index 0000000..6b90b76 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-LightItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Medium.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Medium.ttf new file mode 100644 index 0000000..00120fe Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Medium.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-MediumItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-MediumItalic.ttf new file mode 100644 index 0000000..7481e7b Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-MediumItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Regular.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Regular.ttf new file mode 100644 index 0000000..855b6f4 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Regular.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-SemiBold.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-SemiBold.ttf new file mode 100644 index 0000000..8b84efc Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-SemiBold.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-SemiBoldItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-SemiBoldItalic.ttf new file mode 100644 index 0000000..2e22c5a Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-SemiBoldItalic.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-Thin.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-Thin.ttf new file mode 100644 index 0000000..94e6108 Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-Thin.ttf differ diff --git a/apps/infoalloggi/typst/fonts/Inter_28pt-ThinItalic.ttf b/apps/infoalloggi/typst/fonts/Inter_28pt-ThinItalic.ttf new file mode 100644 index 0000000..d3d44cd Binary files /dev/null and b/apps/infoalloggi/typst/fonts/Inter_28pt-ThinItalic.ttf differ diff --git a/apps/infoalloggi/typst/receipt.typ b/apps/infoalloggi/typst/receipt.typ new file mode 100644 index 0000000..3956554 --- /dev/null +++ b/apps/infoalloggi/typst/receipt.typ @@ -0,0 +1,168 @@ +#import "utils.typ": format-price + +#let data_file = sys.inputs.at("data_path", default: "none") + +#let data = if data_file != "none" { json(data_file) } else { + ( + "ordineId": "3df6bd0d-2d2d-4687-b4b9-87f2aecc297c", + "date": "1 gennaio 2026", + "datetime": "14:55", + "nominativo": "Di Grigoli Angelo Damiano", + "codicefiscale": "DGRNLD97C13B602Z", + "indirizzo": "Via Aldo Fantina 15, PIEVE DEL GRAPPA (TV) 31017", + "nazione": "Italia", + "items": ( + ( + "title": "Acconto Cerco Transitorio", + "desc": none, + "discount": none, + "amount": 3500, + "strike": false, + ), + ( + "title": "Saldo Cerco Affitto Transitorio (6 mesi)", + "desc": "Pagamento differito, non è dovuto in questo momento", + "discount": none, + "amount": 37500, + "strike": true, + ), + ), + "total": 3500, + "vat": 770, + "method": "Carta di credito", + ) +} + + +#set page( + paper: "a4", + margin: (x: 1cm, y: 1cm), + footer: [ + #set align(center) + #set text(size: 9pt, fill: luma(100)) + Arcenia Srl.| P.IVA 00924740244 | Tel. +39 0424529869 | Email: arca\@infoalloggi.it + ], +) + +#set text(font: "Inter 18pt", size: 10pt) + +// --- Header --- +#grid( + columns: (1fr, auto), + [ + #text(size: 14pt, weight: "bold", fill: rgb("1a202c"))[Arcenia S.r.l.] \ + Via Beata Giovanna 1 \ + Bassano del Grappa (VI) 36061 \ + Italia + ], + [ + #image("/public/favicon/favicon.png", width: 80pt) + ], +) + +#v(2.5em) + +// --- Title --- +#align(center)[ + #text(size: 16pt, weight: "bold", fill: rgb("1a202c"))[Ricevuta di cortesia] +] + +#v(2em) + +#grid( + columns: (1fr, auto), + [ + #text(fill: luma(120), size: 9pt)[ID Ordine] \ + #data.ordineId + ], + align(right)[ + #text(fill: luma(120), size: 9pt)[Data] \ + #data.date \ + #data.datetime + ], +) + +#v(0.5em) +#line(length: 100%, stroke: 0.5pt + luma(200)) +#v(1em) + + +#text(weight: "bold")[Intestatario:] \ +#v(0.2em) +#data.nominativo \ +#data.codicefiscale \ +#data.indirizzo \ +#data.nazione +#v(2.5em) + + +#table( + columns: (1fr, auto, auto), + stroke: none, + align: (left, right, right), + inset: (x: 5pt, y: 10pt), + + // Header row + [*Oggetto*], [*Sconto applicato*], [*Importo*], + table.hline(stroke: 0.5pt + luma(200)), + + ..data + .items + .map(item => { + ( + item.title + if item.desc != none { "\n" + text(size: 9pt, fill: luma(100))[#item.desc] } else { "" }, + if item.at("discount", default: none) != none { [#item.discount %] } else [], + if item.at("strike", default: false) { + strike(stroke: 1pt + luma(100))[#text(fill: luma(100))[#format-price(item.amount)]] + } else { + [#format-price(item.amount)] + }, + table.hline(stroke: 0.5pt + luma(200)), + ) + }) + .flatten(), +) + +// --- Totals --- +#v(0.5em) +#align(right)[ + #grid( + columns: (1fr, auto), + align: (right, right), + gutter: 1.5em, + [*Totale:*], [*#format-price(data.total)*], + [#text(fill: luma(100))[di cui IVA (22%):]], [#text(fill: luma(100))[#format-price(data.vat)]], + ) +] + +#v(2em) +#line(length: 100%, stroke: 0.5pt + luma(200)) +#v(0.5em) + + +#grid( + columns: (1fr, auto), + [ + #text(weight: "bold")[Metodo di pagamento] \ + #v(0.2em) + #data.method + ], + align(right)[ + #text(weight: "bold")[Status pagamento] \ + #v(0.2em) + // Custom hex color for the success text + #text(fill: rgb("00A650"), weight: "bold")[Pagato] + ], +) + +#v(0.5em) +#line(length: 100%, stroke: 0.5pt + luma(200)) +#v(1em) + + +#text(weight: "bold")[Note] \ +#v(0.2em) +#text(size: 9pt, fill: rgb("4a5568"))[ + La presente non costituisce ricevuta o fattura fiscale ai sensi dell'Art.21, DPR 633/72.\ + Seguirà fattura elettronica direttamente al tuo indirizzo di posta. +] diff --git a/apps/infoalloggi/typst/testi.typ b/apps/infoalloggi/typst/testi.typ new file mode 100644 index 0000000..43099ff --- /dev/null +++ b/apps/infoalloggi/typst/testi.typ @@ -0,0 +1,23 @@ + + + +#let data = sys.inputs.at("data", default: none) + +#set page(paper: "a4", margin: 1cm) +#set text(font: "Inter 18pt", size: 10pt, lang: "it") +#show heading: set text(fill: rgb("#1a202c")) +#show heading.where(level: 2): set text(size: 14pt) +#show heading.where(level: 3): set text(size: 12pt) +#set par(justify: true, leading: 0.65em) + +#let data_file = sys.inputs.at("data_path", default: "none") +#let data = if data_file != "none" { json(data_file) } else { + ( + "stringa": "none", + ) +} + +#eval(data.stringa, mode: "markup") + + + diff --git a/apps/infoalloggi/typst/utils.typ b/apps/infoalloggi/typst/utils.typ new file mode 100644 index 0000000..1d7cc86 --- /dev/null +++ b/apps/infoalloggi/typst/utils.typ @@ -0,0 +1,15 @@ +#import "@preview/oxifmt:1.0.0": strfmt + + +#let format-price(cents) = { + // Handle case where cents might be null or not a number + if cents == none { return "0,00 €" } + + let euros = int(cents / 100) + let decimal = calc.rem(cents, 100) + + // Create the decimal string and pad with a leading zero if needed (e.g., 5 cents -> "05") + let decimal-str = if decimal < 10 { "0" + str(decimal) } else { str(decimal) } + + return str(euros) + "," + decimal-str + " €" +}