diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 8cab8cbf..f3ec29e5 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -3,6 +3,7 @@ import Link from "next/link" import { FiArrowUpRight } from "react-icons/fi" import { AssociationBodies } from "@/components/structure/association-bodies" import { BoardGallery } from "@/components/structure/board-gallery" +import { CONTAINER } from "@/components/structure/constants" import { LegalStatus } from "@/components/structure/legal-status" import { OrganizationChart } from "@/components/structure/organization-chart" import { Participation } from "@/components/structure/participation" @@ -15,14 +16,14 @@ export const metadata: Metadata = { "Un’organizzazione pensata per durare: scopri l’organigramma, il Direttivo, gli organi associativi e i ruoli di PoliNetwork APS.", } -const containerClass = "mx-auto flex w-full max-w-330 flex-col gap-10 px-6 md:gap-14" +const containerClass = `${CONTAINER} flex flex-col gap-10 md:gap-14` const titleClass = "typo-headline-medium sm:typo-display-medium text-balance bg-linear-to-b from-text-primary to-text-secondary bg-clip-text text-center text-transparent" export default function StructurePage() { return (
-
+
@@ -49,7 +50,7 @@ export default function StructurePage() {
-
+

Tutto ciò che c’è da sapere su PoliNetwork.

@@ -63,7 +64,7 @@ export default function StructurePage() {
-
+
diff --git a/src/app/chi-siamo/page.tsx b/src/app/chi-siamo/page.tsx index 0fdae581..d96a6022 100644 --- a/src/app/chi-siamo/page.tsx +++ b/src/app/chi-siamo/page.tsx @@ -14,7 +14,7 @@ export const metadata: Metadata = { export default function ChiSiamoPage() { return ( -
+
diff --git a/src/app/storia/page.tsx b/src/app/storia/page.tsx index dc4fc1cf..7846e788 100644 --- a/src/app/storia/page.tsx +++ b/src/app/storia/page.tsx @@ -1,10 +1,9 @@ import type { Metadata } from "next" -import { FiMessageCircle, FiUserCheck } from "react-icons/fi" -import telegram from "@/assets/icons/telegram-gradient.svg" -import { CardCaption } from "@/components/card-caption" -import { CardIcon } from "@/components/card-icon" +import { FiMessageCircle } from "react-icons/fi" +import { GradientIcon } from "@/components/gradient-icon" import TextOnlyLayout from "@/components/layout/TextOnlySection" import { Boards } from "@/components/storia/boards" +import { CONTAINER } from "@/components/storia/constants" import { Continuation } from "@/components/storia/continuation" import { HistoryHero } from "@/components/storia/hero" import { Organization } from "@/components/storia/organization" @@ -20,10 +19,12 @@ export const metadata: Metadata = { export default function HistoryPage() { return ( -
+
-
+
+ {/* Figma reserves the right column for an archive photo that doesn't exist yet: until then the text stands alone. + The two milestone cards that filled it repeated the timeline right below. */} } classNames={{ - section: "mx-auto max-w-330 gap-12 px-6 md:px-6 xl:flex-row xl:items-center [&>div>h2]:typo-title-large", - textDiv: "min-w-0 xl:w-1/2 xl:items-start", - title: "text-balance text-blue-secondary xl:text-start", - descriptionDiv: "xl:text-start", - contentDiv: "min-w-0 xl:w-1/2", + section: `${CONTAINER} items-start [&>div>h2]:typo-title-large`, + textDiv: "max-w-180 items-start", + title: "text-balance text-start text-blue-secondary", + descriptionDiv: "text-start", + contentDiv: "hidden", }} - > -
- - -
-
+ /> @@ -92,25 +74,23 @@ export default function HistoryPage() { } classNames={{ - section: "mx-auto max-w-330 gap-12 px-6 md:px-6 xl:flex-row xl:items-center [&>div>h2]:typo-title-large", - title: "text-balance text-blue-secondary xl:text-start", - textDiv: "min-w-0 xl:w-1/2 xl:items-start", - descriptionDiv: "xl:text-start", + section: `${CONTAINER} gap-12 xl:flex-row xl:items-center xl:gap-16 [&>div>h2]:typo-title-large`, + title: "text-balance text-start text-blue-secondary", + textDiv: "min-w-0 items-start xl:w-1/2", + descriptionDiv: "text-start", contentDiv: "min-w-0 xl:w-1/2", }} > - - Se anche un solo studente ha trovato casa grazie a un nostro gruppo, o si è laureato in tempo perché - qualcuno gli ha risposto. -

- } - className="h-auto w-full gap-6 p-6 sm:p-10" - /> +
+ +

+ L’obiettivo è raggiunto. +

+

+ Se anche un solo studente ha trovato casa grazie a un nostro gruppo, o si è laureato in tempo perché + qualcuno gli ha risposto. +

+
diff --git a/src/components/chi-siamo/answer-section.tsx b/src/components/chi-siamo/answer-section.tsx index 0e718fc6..d87e0862 100644 --- a/src/components/chi-siamo/answer-section.tsx +++ b/src/components/chi-siamo/answer-section.tsx @@ -1,5 +1,6 @@ import { FiAward, FiBookOpen, FiUsers } from "react-icons/fi" import { CardIcon } from "@/components/card-icon" +import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "./constants" const cards = [ { @@ -23,12 +24,10 @@ const cards = [ export function AnswerSection() { return ( -
+
-

- La nostra risposta -

-

+

La nostra risposta

+

Costruiamo e manteniamo la rete di comunicazione studentesca del Politecnico di Milano.

@@ -40,7 +39,7 @@ export function AnswerSection() { {...card} size="compact" align="start" - className="h-full p-0 [&_h3]:text-balance" + className="h-full p-0 [&_h3]:text-balance [&_p]:max-w-none" /> ))}
diff --git a/src/components/chi-siamo/constants.ts b/src/components/chi-siamo/constants.ts new file mode 100644 index 00000000..9df0bebf --- /dev/null +++ b/src/components/chi-siamo/constants.ts @@ -0,0 +1,7 @@ +/** Same content column and gutters as /storia and the homepage. */ +export const CONTAINER = "mx-auto w-full max-w-350 px-6 sm:px-10 lg:px-16" + +export const SECTION_TITLE = + "typo-headline-medium sm:typo-display-medium text-balance bg-linear-to-b from-text-primary to-text-secondary bg-clip-text text-transparent" + +export const SECTION_LEAD = "typo-body-large sm:typo-headline-extrasmall text-pretty" diff --git a/src/components/chi-siamo/history-section.tsx b/src/components/chi-siamo/history-section.tsx index 4a2fbf46..f8ae3201 100644 --- a/src/components/chi-siamo/history-section.tsx +++ b/src/components/chi-siamo/history-section.tsx @@ -1,20 +1,17 @@ import Link from "next/link" -import { FiArrowUpRight, FiClock, FiUsers } from "react-icons/fi" -import { Glass } from "@/components/glass" -import { GradientIcon } from "@/components/gradient-icon" +import { FiArrowUpRight } from "react-icons/fi" import { Button } from "@/components/ui/button" +import { CONTAINER, SECTION_TITLE } from "./constants" const blocks = [ { title: "Da dove veniamo", description: "Dal primo gruppo Telegram, nel 2016, a una rete costruita dagli studenti, per gli studenti.", - icon: FiClock, cta: "La nostra storia", href: "/storia", }, { title: "Come siamo organizzati", - icon: FiUsers, description: "Direttivo, team operativi, admin e soci. Guarda come funziona la macchina dall'interno.", cta: "La nostra struttura", href: "/about", @@ -23,21 +20,18 @@ const blocks = [ export function HistorySection() { return ( -
+
{blocks.map((block) => ( - - -

- {block.title} -

-

{block.description}

+
+

{block.title}

+

{block.description}

- +
))}
) diff --git a/src/components/chi-siamo/numbers-section.tsx b/src/components/chi-siamo/numbers-section.tsx index 947591b0..9d7b2cce 100644 --- a/src/components/chi-siamo/numbers-section.tsx +++ b/src/components/chi-siamo/numbers-section.tsx @@ -1,6 +1,7 @@ import { FiBook, FiBookOpen, FiHeadphones, FiSend, FiUser, FiUsers } from "react-icons/fi" import { GradientIcon } from "@/components/gradient-icon" -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { Card } from "@/components/ui/card" +import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "./constants" const stats = [ { value: "500+", label: "gruppi Telegram e WhatsApp attivi", icon: FiSend }, @@ -13,35 +14,30 @@ const stats = [ export function NumbersSection() { return ( -
+
-

- I numeri -

-

+

I numeri

+

Un network in continua crescita, costruito dagli studenti, per gli studenti.

-
+
    {stats.map((stat) => ( - - - - {stat.value} - - - - {stat.label} - +
  • + + +
    +

    {stat.value}

    +

    {stat.label}

    +
    +
    +
  • ))} -
+ -

+

Dal 2016 al fianco degli studenti del PoliMi

diff --git a/src/components/chi-siamo/path-section.tsx b/src/components/chi-siamo/path-section.tsx index 2b835347..d5d3fe97 100644 --- a/src/components/chi-siamo/path-section.tsx +++ b/src/components/chi-siamo/path-section.tsx @@ -2,6 +2,7 @@ import { FiBook, FiClipboard, FiFileText, FiGift, FiUser, FiUserCheck } from "re import { Glass } from "@/components/glass" import { GradientIcon } from "@/components/gradient-icon" import { cn } from "@/lib/utils" +import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "./constants" const steps = [ { title: "TOL", description: "Simulazioni, guide e consigli per affrontarlo al meglio.", icon: FiBook }, @@ -18,10 +19,8 @@ const steps = [ export function PathSection() { return ( -
-

- Il tuo percorso, sempre al tuo fianco -

+
+

Il tuo percorso, sempre al tuo fianco

    {steps.map((step, index) => ( @@ -46,7 +45,7 @@ export function PathSection() { ))}
-

+

Dalla prima simulazione del TOL fino alla laurea, ogni studente ha sempre{" "} una risposta a portata di mano e{" "} qualcuno a cui chiederla. diff --git a/src/components/chi-siamo/problem-section.tsx b/src/components/chi-siamo/problem-section.tsx index d2bb57df..2902a4ab 100644 --- a/src/components/chi-siamo/problem-section.tsx +++ b/src/components/chi-siamo/problem-section.tsx @@ -1,5 +1,6 @@ import { FiEdit, FiFileText, FiUsers } from "react-icons/fi" -import { Card, CardAction, CardContent } from "@/components/ui/card" +import { GradientIcon } from "@/components/gradient-icon" +import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "./constants" const questions = [ { text: "Dove trovo il gruppo del mio corso?", icon: FiUsers }, @@ -9,23 +10,22 @@ const questions = [ export function ProblemSection() { return ( -

+
-

- Il problema -

-

- Il PoliMi è complesso. Le informazioni non dovrebbero esserlo. -

+

Il problema

+

Il PoliMi è complesso. Le informazioni non dovrebbero esserlo.

-
+
    {questions.map((question) => ( - - {question.text} - - +
  • + + {question.text} +
  • ))} -
+
) } diff --git a/src/components/chi-siamo/support-section.tsx b/src/components/chi-siamo/support-section.tsx index 8f3493ca..46423793 100644 --- a/src/components/chi-siamo/support-section.tsx +++ b/src/components/chi-siamo/support-section.tsx @@ -1,31 +1,25 @@ -import { FiHeart } from "react-icons/fi" -import { Glass } from "@/components/glass" -import { GradientIcon } from "@/components/gradient-icon" +import { CONTAINER, SECTION_TITLE } from "./constants" export function SupportSection() { return ( -
- -
- -

Sostieni PoliNetwork

-

- Se vuoi supportare PoliNetwork economicamente, puoi destinarci il 5x1000 nella dichiarazione dei redditi. Si - tratta di una quota IRPEF che verseresti comunque, e che puoi scegliere di indirizzare a noi senza alcun - costo aggiuntivo. -

-
- -

5x1000

-

Il tuo sostegno può fare la differenza

-

- Nella sezione dedicata agli Enti del Terzo Settore, indica il nostro codice fiscale: -

-

- 97927490157 -

-
-
+
+
+

Sostieni PoliNetwork

+

+ Se vuoi supportare PoliNetwork economicamente, puoi destinarci il 5x1000 nella dichiarazione dei redditi. Si + tratta di una quota IRPEF che verseresti comunque, e che puoi scegliere di indirizzare a noi senza alcun costo + aggiuntivo. +

+
+
+

+ Il tuo 5x1000 può fare la differenza +

+

+ Nella sezione dedicata agli Enti del Terzo Settore, indica il nostro codice fiscale: +

+

97927490157

+
) } diff --git a/src/components/chi-siamo/vision-section.tsx b/src/components/chi-siamo/vision-section.tsx index ec6ba6d9..e3f522fd 100644 --- a/src/components/chi-siamo/vision-section.tsx +++ b/src/components/chi-siamo/vision-section.tsx @@ -1,10 +1,9 @@ -import Link from "next/link" -import { FiArrowDown, FiArrowUpRight } from "react-icons/fi" -import { Button } from "@/components/ui/button" +import { CONTAINER } from "./constants" export function VisionSection() { return ( -
+
+

La nostra visione

Un Politecnico in cui nessuno studente resti indietro per mancanza di{" "} informazioni. @@ -12,18 +11,6 @@ export function VisionSection() {

Rendiamo le informazioni sul PoliMi più accessibili, comprensibili e facili da trovare.

-
- - -

) } diff --git a/src/components/storia/boards.tsx b/src/components/storia/boards.tsx index 1beca4d5..23a43fbe 100644 --- a/src/components/storia/boards.tsx +++ b/src/components/storia/boards.tsx @@ -1,17 +1,14 @@ "use client" -import Image from "next/image" -import { Glass } from "@/components/glass" +import { BoardMemberCard } from "@/components/structure/board-member-card" import TabsNavigation from "@/components/tabs" import { Tabs } from "@/components/tabs/tabs" import { TabsContent } from "@/components/tabs/tabs-content" -import { Card, CardContent } from "@/components/ui/card" -import { cn } from "@/lib/utils" -import { boardMembers, boardTerms } from "./constants" +import { boardMembers, boardTerms, CONTAINER } from "./constants" export function Boards() { return ( -
+

I nostri direttivi

Ogni mandato, un nuovo capitolo @@ -25,39 +22,26 @@ export function Boards() {

{boardMembers.map((member) => ( - - {member.name} -
- -

{member.name}

- {member.role &&

{member.role}

} -
- + member={member} + sizes="(max-width: 639px) 45vw, (max-width: 1279px) 30vw, 224px" + className="sm:w-[calc((100%-48px)/3)] xl:w-[calc((100%-72px)/4)] min-[360px]:w-[calc((100%-24px)/2)]" + /> ))}

Il Direttivo viene eletto ogni due anni dall’Assemblea dei Soci tra i soci dell’associazione.

- +

{term}

Il Direttivo

Si concentra sul rafforzamento della struttura, sull’evoluzione dei servizi e sullo sviluppo di nuovi progetti per la community.

- +
) : (
diff --git a/src/components/storia/constants.ts b/src/components/storia/constants.ts index 78b1325d..59dc9ab5 100644 --- a/src/components/storia/constants.ts +++ b/src/components/storia/constants.ts @@ -1,3 +1,5 @@ +import { FiUser, FiUserCheck, FiUsers } from "react-icons/fi" +import telegram from "@/assets/icons/telegram-gradient.svg" import ale from "@/assets/images/storia/ale-he.jpg" import alessandro from "@/assets/images/storia/alessandro-gabbini.jpg" import elia from "@/assets/images/storia/elia-falzoni.jpg" @@ -6,23 +8,34 @@ import gabriele from "@/assets/images/storia/gabriele-vigano.jpg" import lorenzo from "@/assets/images/storia/lorenzo-corallo.jpg" import tommaso from "@/assets/images/storia/tommaso-morganti.jpg" +/** Shared section container: Figma's 1272px content column, with the homepage's 24/40/64px gutters (md:px-10 overrides TextOnlyLayout's md:px-36). */ +export const CONTAINER = "mx-auto w-full max-w-350 px-6 sm:px-10 md:px-10 lg:px-16" + // Contenuti del design Figma “La nostra storia”, nodo 5368:5885. export const milestones = [ { year: "2016", + href: "#capitolo-1", + icon: FiUser, description: "Nasce il primo gruppo per rispondere a una necessità semplice: trovare informazioni e parlare con i compagni di corso.", }, { year: "2017", + href: "#capitolo-1", + icon: telegram.src, description: "I gruppi si moltiplicano su Telegram e WhatsApp e iniziamo a coprire tutti i corsi di laurea.", }, { year: "2022", + href: "#capitolo-5", + icon: FiUserCheck, description: "PoliNetwork diventa un’APS-ETS, con un direttivo eletto e una struttura ancora più democratica.", }, { year: "OGGI", + href: "#direttivi", + icon: FiUsers, description: "Oltre 200 admin volontari e una community che accompagna ogni giorno migliaia di studenti del Politecnico di Milano.", }, diff --git a/src/components/storia/continuation.tsx b/src/components/storia/continuation.tsx index 1b417174..9ce9b04c 100644 --- a/src/components/storia/continuation.tsx +++ b/src/components/storia/continuation.tsx @@ -1,53 +1,60 @@ import Link from "next/link" import { FiArrowUpRight } from "react-icons/fi" -import { Glass } from "@/components/glass" import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" +import { CONTAINER } from "./constants" +const years = ["2016", "2022", "2026", "?"] + +// Figma: text on the left, the years on a line on the right. No panel or gradient behind it, and the "?" is a +// quiet open slot rather than a filled pill that looks like a button. export function Continuation() { return ( -
- -
-

- La storia continua. -

-

- Ogni anno qualcuno arriva, qualcuno si laurea e qualcun altro raccoglie il testimone. La missione rimane la - stessa: rendere la vita universitaria più semplice, accessibile e umana. -

- -
-
-
    - {["2016", "2022", "2026", "?"].map((year) => ( -
  1. - - {year} - -
  2. - ))} -
-

Nuove persone, nuove idee, nuovi progetti.

-

- Il prossimo capitolo lo scriviamo insieme. -

-
-
+
+
+

+ La storia continua. +

+

+ Ogni anno qualcuno arriva, qualcuno si laurea e qualcun altro raccoglie il testimone. Nuove persone, nuove + idee, nuovi progetti. La missione rimane la stessa: rendere la vita universitaria più semplice, accessibile e + umana. +

+
+ +
+
    + {years.map((year, index) => ( +
  1. 0 && "flex-1")}> + {index > 0 && } + + {year} + +
  2. + ))} +
+

+ Il prossimo capitolo lo scriviamo insieme. +

+ +
) } diff --git a/src/components/storia/hero.tsx b/src/components/storia/hero.tsx index 6c260137..d35e2681 100644 --- a/src/components/storia/hero.tsx +++ b/src/components/storia/hero.tsx @@ -1,76 +1,30 @@ -import Image from "next/image" import Link from "next/link" -import { FiArrowDown, FiUsers } from "react-icons/fi" -import { Glass } from "@/components/glass" -import { GradientIcon } from "@/components/gradient-icon" +import { FiArrowDown } from "react-icons/fi" import { Button } from "@/components/ui/button" -import { Card, CardContent } from "@/components/ui/card" import { Hero } from "@/components/ui/hero" -import { cn } from "@/lib/utils" -import { boardMembers } from "./constants" - -const portraits = [ - { member: boardMembers[1], position: "top-12 left-0 -rotate-6" }, - { - member: boardMembers[0], - position: "-translate-x-1/2 top-0 left-1/2 z-10", - }, - { member: boardMembers[3], position: "top-12 right-0 rotate-6 sm:top-16" }, -] +import { CONTAINER } from "./constants" +// Figma: a centred XL title and nothing else. The board portraits appear further down, under "I nostri direttivi". export function HistoryHero() { return ( -
-
- -
- - -
-
-
-
- {portraits.map(({ member, position }) => ( - - {member.name} -
- - {member.role} - - - ))} -
- - -
-

200+

-

admin volontari, oggi

-
-
+
+ +
+ +
) diff --git a/src/components/storia/organization.tsx b/src/components/storia/organization.tsx index 7780ee4c..3927b64e 100644 --- a/src/components/storia/organization.tsx +++ b/src/components/storia/organization.tsx @@ -1,182 +1,12 @@ import Link from "next/link" import { FiArrowDown } from "react-icons/fi" -import { - LuBookUser, - LuCodeXml, - LuCrown, - LuGlobe, - LuHandshake, - LuPencilRuler, - LuShield, - LuShieldCheck, - LuUserCog, - LuUsersRound, -} from "react-icons/lu" -import { CardIcon } from "@/components/card-icon" -import { GradientIcon } from "@/components/gradient-icon" +import { OrganizationDiagram } from "@/components/structure/organization-chart" import { Button } from "@/components/ui/button" -import { Card, CardTitle } from "@/components/ui/card" -import { cn } from "@/lib/utils" - -const teamLeads = [ - { title: "Team lead HR", icon: LuBookUser }, - { title: "Team lead IT", icon: LuCodeXml }, - { title: "Team lead Design & Marketing", icon: LuPencilRuler }, - { title: "Team lead International", icon: LuGlobe }, - { title: "Team lead Eventi & Partnership", icon: LuHandshake }, -] - -const nodeClassName = "[&_h3]:text-text-primary" -const mainNodeClassName = "[&_h3]:typo-title-large w-fit px-4 [&_h3]:whitespace-nowrap" - -type BranchPosition = "first" | "middle" | "last" | "only" - -/** Horizontal rail and arrow above one child of a branch: the rail runs from the first child's center to the last's. */ -function BranchArrow({ position }: { position: BranchPosition }) { - return ( -
- {position !== "only" && ( - - )} - -
- ) -} - -function branchPosition(index: number, count: number): BranchPosition { - if (count === 1) return "only" - if (index === 0) return "first" - return index === count - 1 ? "last" : "middle" -} - -function Stem() { - return -} - -function DesktopChart() { - return ( -
- - -
- {/* Rail from the center of the admin column (1/12) to the center of the Team growth columns (7/12) */} -
- - - -
-
- - - -
-
- - -
    - {teamLeads.map((lead, index) => ( -
  • - -
    - -
    - -
  • - ))} -
-
- - - - Membri dei team - - -
-
-
-
- ) -} - -function MobileChart() { - return ( -
- - -
-
- - - -
-
- - - -
-
- - -
    - {teamLeads.map((lead) => ( -
  • - - - - {lead.title} - - -
  • - ))} -
- - -
-
-
- ) -} +import { CONTAINER } from "./constants" export function Organization() { return ( -
+

Come è organizzata PoliNetwork @@ -190,15 +20,8 @@ export function Organization() {

- + {/* From xl the diagram rises beside the intro: its narrow top (the Direttivo node) fits next to the text */} +
) } diff --git a/src/components/storia/projects.tsx b/src/components/storia/projects.tsx index ee42bc09..0a5a4019 100644 --- a/src/components/storia/projects.tsx +++ b/src/components/storia/projects.tsx @@ -4,9 +4,9 @@ import { FiAirplay, FiArrowUpRight, FiBarChart, FiBook, FiCheck, FiHeadphones } import telegram from "@/assets/icons/telegram-gradient.svg" import projectsImage from "@/assets/images/storia/progetti.png" import { CardIcon } from "@/components/card-icon" -import { Glass } from "@/components/glass" import TextOnlyLayout from "@/components/layout/TextOnlySection" import { Button } from "@/components/ui/button" +import { CONTAINER } from "./constants" const projects = [ { @@ -35,7 +35,7 @@ const projects = [ export function HistoryProjects() { return ( -
+
div>h2]:typo-title-large", - textDiv: "min-w-0 xl:w-1/2 xl:items-start", - title: "text-blue-secondary xl:text-start", - descriptionDiv: "xl:text-start", + textDiv: "min-w-0 items-start xl:w-1/2", + title: "text-start text-blue-secondary", + descriptionDiv: "text-start", contentDiv: "min-w-0 xl:w-1/2", }} > Il sito PoliNetwork su computer e smartphone -
-
+ {/* Figma: the six tools on the left, the note about where they come from beside them, without a panel */} +
+
{projects.map((project) => ( ))}
- -
-

- Molti dei progetti di PoliNetwork sono nati da idee individuali: studenti che hanno - creato autonomamente uno strumento utile e che, nel tempo, sono entrati a far parte del network. -

-

Da un’idea di uno studente a uno strumento per migliaia di studenti.

-
- -
+
) diff --git a/src/components/storia/thanks.tsx b/src/components/storia/thanks.tsx index faf9b32e..73c6dbdd 100644 --- a/src/components/storia/thanks.tsx +++ b/src/components/storia/thanks.tsx @@ -2,13 +2,12 @@ import { useState } from "react" import { FiSearch } from "react-icons/fi" -import { Glass } from "@/components/glass" import TextOnlyLayout from "@/components/layout/TextOnlySection" import TabsNavigation from "@/components/tabs" import { Tabs } from "@/components/tabs/tabs" import { TabsContent } from "@/components/tabs/tabs-content" import { Input } from "@/components/ui/input" -import { contributors } from "./constants" +import { CONTAINER, contributors } from "./constants" const categories = ["Tutti", "Direttivi", "Admin", "Collaboratori"] @@ -35,14 +34,14 @@ export function Thanks() { } classNames={{ - section: "mx-auto max-w-330 gap-12 px-6 md:px-6 xl:flex-row [&>div>h2]:typo-title-large", - textDiv: "xl:w-1/2 xl:items-start xl:text-start", - title: "text-blue-secondary xl:text-start", - descriptionDiv: "xl:text-start", + section: `${CONTAINER} gap-12 xl:flex-row xl:gap-16 [&>div>h2]:typo-title-large`, + textDiv: "items-start text-start xl:w-1/2", + title: "text-start text-blue-secondary", + descriptionDiv: "text-start", contentDiv: "min-w-0 xl:w-1/2", }} > - +
} @@ -80,7 +79,7 @@ export function Thanks() { ) })} - +
) } diff --git a/src/components/storia/timeline.tsx b/src/components/storia/timeline.tsx index 63b93047..0b56fc9e 100644 --- a/src/components/storia/timeline.tsx +++ b/src/components/storia/timeline.tsx @@ -1,48 +1,66 @@ +import Image from "next/image" import Link from "next/link" -import { - FiArrowDown, - FiCheckCircle, - FiClipboard, - FiClock, - FiLayers, - FiUser, - FiUserCheck, - FiUsers, -} from "react-icons/fi" +import type { ReactNode } from "react" +import { FiArrowDown, FiArrowRight, FiCheck, FiClipboard, FiClock, FiUser, FiUserCheck, FiUsers } from "react-icons/fi" import telegram from "@/assets/icons/telegram-gradient.svg" -import { CardCaption } from "@/components/card-caption" -import { CardIcon } from "@/components/card-icon" -import { Glass } from "@/components/glass" +import { GradientIcon, type GradientIconType } from "@/components/gradient-icon" import { Button } from "@/components/ui/button" -import { chapters, milestones } from "./constants" +import { cn } from "@/lib/utils" +import { CONTAINER, chapters, milestones } from "./constants" -const milestoneLinks = ["#capitolo-1", "#capitolo-1", "#capitolo-5", "#direttivi"] - -const milestoneIcons = [FiUser, telegram.src, FiUserCheck, FiUsers] +/** The small icon tile Figma uses for timeline nodes and diagram steps. */ +function IconTile({ icon, className }: { icon: GradientIconType | string; className?: string }) { + return ( + + {typeof icon === "string" ? ( + + ) : ( + + )} + + ) +} export function Timeline() { return ( -
+

Da un semplice gruppo a una rete costruita dagli studenti,{" "} per gli studenti.

-
    - {milestones.map((milestone, index) => ( -
  1. - + + {/* Nodes on a line: vertical below lg, horizontal from lg (Figma) */} +
      + {milestones.map((milestone) => ( +
    1. + + + {milestone.year} + +

      + {milestone.description} +

    2. ))}
    +

    Dieci anni di crescita, persone e progetti. La nostra storia{" "} @@ -58,122 +76,128 @@ export function Timeline() { ) } -const chapterVisuals = [ -

    - {[ - { icon: telegram.src, title: "Il primo gruppo" }, - { icon: FiUser, title: "I primi admin e volontari" }, - { icon: FiUserCheck, title: "Test su Informatica" }, - { icon: FiUsers, title: "Tutti i corsi" }, - ].map((item) => ( - - ))} -
    , -
    - {[ - { icon: FiClipboard, title: "Regole interne" }, - { icon: FiUserCheck, title: "Comunicazioni selezionate" }, - { icon: FiUsers, title: "Una community indipendente" }, - ].map((item) => ( - - ))} -
    , -
    +function Arrow({ className }: { className?: string }) { + return +} + +/** A left-to-right sequence of steps, joined by arrows. */ +function Steps({ items }: { items: { label: string; icon?: GradientIconType | string; value?: string }[] }) { + return ( +
      + {items.map((item, index) => ( +
    1. + {index > 0 && } +
      + {item.icon && } + {item.value && {item.value}} + {item.label} +
      +
    2. + ))} +
    + ) +} + +/** Two columns read as "before → after". */ +function BeforeAfter({ before, after }: { before: { title: string; items: string[] }; after: typeof before }) { + return ( +
    + {[before, after].map((column, index) => ( +
    +

    {column.title}

    +
      + {column.items.map((item) => ( +
    • {item}
    • + ))} +
    +
    + ))} + +
    + ) +} + +const chapterVisuals: ReactNode[] = [ + , + , + , + , + , +
      {[ - { title: "5", caption: "persone", icon: FiUser }, - { title: "~25", caption: "rappresentanti", icon: FiUsers }, - { title: "4", caption: "composizioni", icon: FiLayers }, + { title: "APS-ETS", status: "Riconosciuto dallo Stato", done: true }, + { title: "RUNTS", status: "Iscritta come ETS", done: true }, + { title: "Albo PoliMi", status: "Ancora da raggiungere", done: false }, ].map((item) => ( - +
    • + {item.done ? ( + + ) : ( + + )} + {item.title} + {item.status} +
    • ))} -
    , -
    - - -
    , -
    - - -
    , -
    - - - -
    , + , ] export function Chapters() { return ( -
    -
      +
      +
        {chapters.map((chapter, index) => (
      1. -
        - - {String(index + 1).padStart(2, "0")} - -

        - {chapter.title} -

        -

        + + {String(index + 1).padStart(2, "0")} + +

        +

        {chapter.title}

        +

        {chapter.subtitle}

        -

        +

        {chapter.description}

        -
        {chapterVisuals[index]}
        +
        + {chapterVisuals[index]} +
      2. ))}
      diff --git a/src/components/structure/association-bodies.tsx b/src/components/structure/association-bodies.tsx index 4249de00..a808421e 100644 --- a/src/components/structure/association-bodies.tsx +++ b/src/components/structure/association-bodies.tsx @@ -4,7 +4,6 @@ import { Accordion } from "@/components/accordion-association/accordion" import { AccordionContent } from "@/components/accordion-association/accordion-content" import { AccordionItem } from "@/components/accordion-association/accordion-item" import { AccordionTrigger } from "@/components/accordion-association/accordion-trigger" -import { GradientIcon } from "@/components/gradient-icon" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { associationBodies } from "./constants" @@ -26,9 +25,10 @@ export function AssociationBodies() {
      {associationBodies.map((body) => ( - - - {body.title} + + + {body.title} + {body.description} diff --git a/src/components/structure/board-gallery.tsx b/src/components/structure/board-gallery.tsx index d28bd40a..6193ba05 100644 --- a/src/components/structure/board-gallery.tsx +++ b/src/components/structure/board-gallery.tsx @@ -1,34 +1,22 @@ -import Image from "next/image" import { boardMembers } from "@/components/storia/constants" -import { Card, CardContent } from "@/components/ui/card" +import { BoardMemberCard } from "@/components/structure/board-member-card" import { Carousel, CarouselContent, CarouselDots, CarouselItem } from "@/components/ui/carousel" -import { cn } from "@/lib/utils" export function BoardGallery() { return ( - + {boardMembers.map((member) => ( - - - {member.name} -
      - -

      {member.name}

      - {member.role &&

      {member.role}

      } -
      - + + ))} diff --git a/src/components/structure/board-member-card.tsx b/src/components/structure/board-member-card.tsx new file mode 100644 index 00000000..3d96b274 --- /dev/null +++ b/src/components/structure/board-member-card.tsx @@ -0,0 +1,34 @@ +import Image from "next/image" +import type { boardMembers } from "@/components/storia/constants" +import { Card, CardContent } from "@/components/ui/card" +import { cn } from "@/lib/utils" + +/** A Direttivo member's portrait, with name and role over a gradient. */ +export function BoardMemberCard({ + member, + sizes, + className, +}: { + member: (typeof boardMembers)[number] + sizes: string + className?: string +}) { + return ( + + {member.name} +
      + +

      {member.name}

      + {member.role &&

      {member.role}

      } +
      + + ) +} diff --git a/src/components/structure/constants.ts b/src/components/structure/constants.ts index 716ce349..36bf0edb 100644 --- a/src/components/structure/constants.ts +++ b/src/components/structure/constants.ts @@ -1,42 +1,30 @@ import { FiBriefcase, FiCompass, FiFlag, FiUsers } from "react-icons/fi" -import { - LuBookUser, - LuCodeXml, - LuCrown, - LuGlobe, - LuHandshake, - LuPencilRuler, - LuScale, - LuShield, - LuUserCog, - LuUsersRound, -} from "react-icons/lu" +import { LuBookUser, LuCodeXml, LuGlobe, LuHandshake, LuPencilRuler, LuShield, LuUsersRound } from "react-icons/lu" + +/** Same content column and 24/40/64px gutters as /storia and /chi-siamo. */ +export const CONTAINER = "mx-auto w-full max-w-350 px-6 sm:px-10 lg:px-16" export const associationBodies = [ { id: "assemblea", - icon: FiUsers, title: "Assemblea dei Soci", description: "È l’organo sovrano di PoliNetwork. Si riunisce almeno una volta l’anno per approvare il bilancio consuntivo e, ogni due anni, per eleggere il Consiglio Direttivo e il Collegio dei Probiviri. Approva eventuali modifiche allo Statuto. Ogni socio ha diritto di voto e può candidarsi direttamente a entrambi gli organi.", }, { id: "consiglio", - icon: LuCrown, title: "Consiglio Direttivo", description: "È l’organo esecutivo e di garanzia dell’associazione. Vigila sulle attività di PoliNetwork per preservare i valori dello Statuto, gestisce le finanze e i rapporti istituzionali con partner esterni, emana i regolamenti interni. Approva o respinge le linee d’azione proposte dai singoli team e le strategie delineate dal Team Growth, senza gestire direttamente le attività quotidiane dei team.", }, { id: "probiviri", - icon: LuScale, title: "Collegio dei Probiviri", description: "È l’organo di garanzia interna, indipendente dal Consiglio Direttivo. Interviene in caso di controversie tra membri o organi dell’associazione, contestazioni sulle elezioni, e vigila sul rispetto dello Statuto e dei regolamenti quando è in gioco l’imparzialità del Direttivo stesso. Viene eletto dall’Assemblea dei Soci con lo stesso mandato biennale del Direttivo, in modo indipendente da esso.", }, { id: "growth", - icon: LuUserCog, title: "Team Growth", description: "È il livello di coordinamento tra i cinque team operativi: riunisce i Capi Dipartimento e alcuni membri del Direttivo per allineare le priorità comuni, le nomine, il recruiting e le decisioni che coinvolgono più team contemporaneamente. Non è un team a sé e non si aprono candidature dirette: si entra in Team Growth diventando Capo Dipartimento di uno dei cinque team.", diff --git a/src/components/structure/legal-status.tsx b/src/components/structure/legal-status.tsx index 02df69a9..92da3e3d 100644 --- a/src/components/structure/legal-status.tsx +++ b/src/components/structure/legal-status.tsx @@ -24,7 +24,7 @@ export function LegalStatus() { ))}
      -

      +

      Consulta Statuto e Regolamenti

      diff --git a/src/components/structure/organization-chart.tsx b/src/components/structure/organization-chart.tsx index 917b6a05..a10658f1 100644 --- a/src/components/structure/organization-chart.tsx +++ b/src/components/structure/organization-chart.tsx @@ -1,42 +1,63 @@ -import Image from "next/image" -import { FiArrowDown, FiUsers } from "react-icons/fi" +import type { IconType } from "react-icons" +import { FiArrowDown, FiArrowLeft, FiUsers } from "react-icons/fi" import { LuCrown, LuShield, LuShieldCheck, LuUserCog, LuUsersRound } from "react-icons/lu" -import arrow from "@/assets/icons/structure/arrow.svg" -import branch from "@/assets/icons/structure/branch.svg" -import { CardIcon } from "@/components/card-icon" import { Glass } from "@/components/glass" import { GradientIcon } from "@/components/gradient-icon" -import { Card, CardTitle } from "@/components/ui/card" import { cn } from "@/lib/utils" -import { teamLeads } from "./constants" +import { CONTAINER, teamLeads } from "./constants" -function DownArrow() { +const teamNames = new Intl.ListFormat("it").format(teamLeads.map((lead) => lead.title.replace("Team lead ", ""))) +const CHART_LABEL = `Il Direttivo coordina i Capi admin e il Team growth. I Capi admin coordinano gli Admin. Il Team growth coordina i team lead ${teamNames}, con i rispettivi membri.` + +// Nodes are not links, so they have no hover state +const tileClassName = "rounded-rectangles border-white/50 bg-background-blur text-text-primary" + +/** `fill` stretches the node to its column instead of sizing it by its label. */ +function Node({ icon, label, fill = false }: { icon: IconType; label: string; fill?: boolean }) { return ( -
      - -
      + + + {label} + ) } -const nodeClassName = "[&_h3]:text-text-primary" -// The admin column is one sixth of the chart: a smaller title and padding keep "Capi admin" on one line -const adminNodeClassName = "[&_h3]:typo-headline-small [&>*]:px-4 [&_h3]:whitespace-nowrap" +function LeadNode({ icon, label }: { icon: IconType; label: string }) { + return ( + + + {label} + + ) +} + +function Arrow({ className }: { className?: string }) { + return +} /** Horizontal rail and arrow above one child of a branch: the rail runs from the first child's center to the last's. */ function BranchArrow({ position }: { position: "first" | "middle" | "last" | "only" }) { return ( -
      +
      {position !== "only" && ( )} - +
      ) } @@ -48,58 +69,45 @@ function branchPosition(index: number, count: number) { } function Stem() { - return + return } function DesktopChart() { return ( -
      - +
      + -
      - {/* Rail from the center of the admin column (1/12) to the center of the Team Growth columns (7/12) */} -
      - - - +
      + {/* Rail from the center of the admin column (1/12) to the center of the Team growth columns (7/12) */} +
      + + +
      -
      -
      - - - -
      +
      + + +
      -
      - +
      + -
        +
          {teamLeads.map((lead, index) => (
        • - +
        • ))}
        -
        - +
        + - - Membri Team - - + Membri Team +
      @@ -107,92 +115,94 @@ function DesktopChart() { ) } -export function OrganizationChart() { +/** Figma mobile "Sezione organigramma": two columns, team leads hanging off a vertical rail, Membri Team balancing the admin column. */ +function MobileChart() { return ( -
      - -
      - -
      -
      - -
      -
      - -
      +
      + + +
      +
      + + +
      -
      -
      - - - +
      + + + +
      + + {/* Arrow from the team leads' rail, across the column gap */} + + + +
      -
      - - -
        - {teamLeads.map((lead) => ( -
      • - - - - {lead.title} - - -
      • - ))} -
      - - +
      +
      + + {/* Down from the node, then left to the rail the team leads hang from */} +
      + +
      +
        + {teamLeads.map((lead) => ( +
      • + + + + {lead.title} + +
      • + ))} +
      - -
      - -

      Soci

      -
      -
      -

      Soci

      -

      - Essere socio è una condizione trasversale, compatibile con qualsiasi ruolo all’interno di PoliNetwork. Ogni - persona può ricoprire più ruoli contemporaneamente. -

      -
      -
      +
      + ) +} + +/** The organisation diagram, shared by /about and /storia. */ +export function OrganizationDiagram({ id, className }: { id?: string; className?: string }) { + return ( + + ) +} + +export function OrganizationChart() { + return ( +
      +
      + + + +
      +
      +

      + + Soci +

      + + Ruolo trasversale + +
      +

      + Essere socio è una condizione trasversale, compatibile con qualsiasi ruolo all’interno di PoliNetwork. + Ogni persona può ricoprire più ruoli contemporaneamente. +

      +
      +
      +
      ) } diff --git a/src/components/structure/participation.tsx b/src/components/structure/participation.tsx index e5331189..c8648b21 100644 --- a/src/components/structure/participation.tsx +++ b/src/components/structure/participation.tsx @@ -12,7 +12,10 @@ export function Participation() { - + {path.title}