(null)
+
+ useEffect(() => {
+ const element = viewport.current
+ if (!element) return
+ const observer = new ResizeObserver(([entry]) => {
+ if (entry) setWidth(Math.max(1, entry.contentRect.width - 32))
+ })
+ observer.observe(element)
+ return () => observer.disconnect()
+ }, [])
+
+ return (
+
+
+
+
+
+
+
+
+
{document.title}
+
+
+ setZoom((value) => Math.max(0.5, value - 0.25))}
+ >
+
+
+ setZoom(1)}
+ >
+ {Math.round(zoom * 100)}%
+
+ = 3 || !pageCount || failed}
+ onClick={() => setZoom((value) => Math.min(3, value + 0.25))}
+ >
+
+
+
+
+
+
+
+
+
+ PDF dimostrativo, non ufficiale.
+
+ {width > 0 && (
+ {
+ setPageCount(numPages)
+ setFailed(false)
+ }}
+ onLoadError={() => setFailed(true)}
+ loading={Caricamento del PDF… }
+ error={
+
+ Impossibile visualizzare il PDF. Puoi scaricarlo con il pulsante in alto.
+
+ }
+ className="flex min-w-full justify-start p-4"
+ >
+ setFailed(true)}
+ loading={Caricamento della pagina… }
+ error={
+
+ Impossibile visualizzare questa pagina. Puoi scaricare il PDF con il pulsante in alto.
+
+ }
+ className="mx-auto shrink-0 shadow-sm"
+ />
+
+ )}
+
+ {pageCount > 0 && !failed && (
+
+ setPage((value) => value - 1)}
+ >
+
+
+
+ Pagina {page} di {pageCount}
+
+ = pageCount}
+ onClick={() => {
+ setPage((value) => value + 1)
+ viewport.current?.scrollTo(0, 0)
+ }}
+ >
+
+
+
+ )}
+
+ )
+}
diff --git a/src/components/documents/types.ts b/src/components/documents/types.ts
new file mode 100644
index 00000000..d265e037
--- /dev/null
+++ b/src/components/documents/types.ts
@@ -0,0 +1,12 @@
+export type DocumentItem = {
+ title: string
+ description?: string
+ href: string
+}
+
+export type DocumentCategory = {
+ id: string
+ title: string
+ description: string
+ documents: DocumentItem[]
+}
diff --git a/src/components/documents/utils.ts b/src/components/documents/utils.ts
new file mode 100644
index 00000000..77dd3e10
--- /dev/null
+++ b/src/components/documents/utils.ts
@@ -0,0 +1,9 @@
+import type { DocumentItem } from "./types"
+
+export function getDocumentSlug(document: DocumentItem) {
+ return document.href.slice(document.href.lastIndexOf("/") + 1).replace(/\.pdf$/, "")
+}
+
+export function getDocumentViewerHref(document: DocumentItem) {
+ return `/documents/view/${getDocumentSlug(document)}`
+}
diff --git a/src/components/header/constants.ts b/src/components/header/constants.ts
index 7cb314e9..c97f7672 100644
--- a/src/components/header/constants.ts
+++ b/src/components/header/constants.ts
@@ -8,6 +8,7 @@ export const headerMenuItems: HeaderMenuItem[] = [
{ title: "Progetti", href: "/projects", icon: FiChevronRight },
{ title: "Appunti", href: "https://polinetwork.org/it/materials/view/", icon: FiChevronRight },
{ title: "Guide", href: "/guides", icon: FiChevronRight },
+ { title: "Documenti", href: "/documents", icon: FiChevronRight },
{ title: "FAQs", href: "/faqs", icon: FiChevronRight },
],
},
diff --git a/src/components/ui/hero.tsx b/src/components/ui/hero.tsx
index bcd563e3..a254ceef 100644
--- a/src/components/ui/hero.tsx
+++ b/src/components/ui/hero.tsx
@@ -22,17 +22,24 @@ export function Hero({
description,
gradientDescription = false,
className,
+ titleClassName,
}: {
title: string
description: string
gradientDescription?: boolean
className?: string
+ titleClassName?: string
}) {
return (
{/* Figma "lightheme-XLarge text effect": #020618 → #6e6e6e at 82.69% */}
{/* The gradient is drawn per line (box-decoration-clone), so a title that wraps keeps the full effect on each line */}
-
+
{title}
diff --git a/tsconfig.json b/tsconfig.json
index ca124295..326e81a0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -46,6 +46,7 @@
".next/dev/types/**/*.ts"
],
"exclude": [
- "node_modules"
+ "node_modules",
+ "public/pdfjs"
]
}