From 5a8a30df41accc2ba867e4f8c08b9256d23706e4 Mon Sep 17 00:00:00 2001 From: Bianca Date: Thu, 9 Apr 2026 17:30:11 +0200 Subject: [PATCH] feat: implement CardList component with accordion functionality --- src/app/page.tsx | 40 ++++++++++++++++ src/components/card-list/accordion-list.tsx | 49 ++++++++++++++++++++ src/components/card-list/index.tsx | 26 +++++++++++ src/components/card-list/section-content.tsx | 21 +++++++++ src/components/card-list/types.ts | 15 ++++++ 5 files changed, 151 insertions(+) create mode 100644 src/components/card-list/accordion-list.tsx create mode 100644 src/components/card-list/index.tsx create mode 100644 src/components/card-list/section-content.tsx create mode 100644 src/components/card-list/types.ts diff --git a/src/app/page.tsx b/src/app/page.tsx index 62c7213..684f4d8 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,6 @@ import { FiBook, FiBookOpen, FiClipboard, FiFileText, FiPenTool, FiTriangle, FiUploadCloud } from "react-icons/fi" import { CardIcon } from "@/components/card-icon" +import { CardList } from "@/components/card-list" import { Hero } from "@/components/home/hero" const schoolCards = [ @@ -31,10 +32,49 @@ const otherCards = [ { title: "Esami", icon: FiClipboard, size: "sm" }, ] as const +const cardListSections = [ + { + title: "Corsi a scelta Secondo Anno", + paragraphs: [ + `Questa guida è stata redatta dagli admin di Ingegneria Informatica di PoliNetwork, raccogliendo opinioni di diversi studenti che hanno frequentato il corso. Ogni paragrafo è un'opinione. Cliccate sul nome del corso per aprirne la pagina e leggere il programma dettagliato. Essendo, il secondo anno, in comune con Telecomunicazioni, è qui che, sulla base delle scelte tra i vari esami, si decide quale percorso intraprendere tra i due. + +In particolare, nel primo semestre è presente, nel piano, un gruppo da 10CFU da comporre nel seguente modo a seconda del percorso scelto : + +Informatica: LOGICA E ALGEBRA (5CFU) + (una a scelta tra CHIMICA GENERALE, ONDE ELETTROMAGNETICHE E MEZZI TRASMISSIVI e MISURE) (5CFU) + +Telecomunicazioni: ELETTROMAGNETISMO (10CFU)`, + ], + }, +] as const + +const cardListItems = [ + { + label: "Misure", + paragraphs: [ + "Dall'ultima riforma del Regolamento Didattico del Corso di Studio in Ingegneria Informatica (Laurea Di Primo Livello) l'esame di Chimica Generale NON è più l'unico corso che permette di accedere alla magistrale in CS (al Polimi) senza dover svolgere Fisica Tecnica al secondo semestre del terzo anno. Ora un qualsiasi corso del gruppo TABA soddisfa il vincolo, quindi si può scegliere liberamente tra Chimica Generale, Fisica Tecnica, Misure e Onde Elettromagnetiche e Mezzi Trasmissivi. Nel caso in cui al secondo anno si scegliesse Elettromagnetismo e Campi da 10 cfu, al terzo anno si ha l'obbligo di inserire Logica e Algebra (gruppo TABREC) siccome è un corso obbligatorio per l'indirizzo I3I (informatica).", + ], + }, + { + label: "Onde Elettromagnetiche e mezzi trasmissivi", + paragraphs: [ + "Dall'ultima riforma del Regolamento Didattico del Corso di Studio in Ingegneria Informatica (Laurea Di Primo Livello) l'esame di Chimica Generale NON è più l'unico corso che permette di accedere alla magistrale in CS (al Polimi) senza dover svolgere Fisica Tecnica al secondo semestre del terzo anno. Ora un qualsiasi corso del gruppo TABA soddisfa il vincolo, quindi si può scegliere liberamente tra Chimica Generale, Fisica Tecnica, Misure e Onde Elettromagnetiche e Mezzi Trasmissivi. Nel caso in cui al secondo anno si scegliesse Elettromagnetismo e Campi da 10 cfu, al terzo anno si ha l'obbligo di inserire Logica e Algebra (gruppo TABREC) siccome è un corso obbligatorio per l'indirizzo I3I (informatica).", + ], + }, + { + label: "Chimica Generale", + paragraphs: [ + "Dall'ultima riforma del Regolamento Didattico del Corso di Studio in Ingegneria Informatica (Laurea Di Primo Livello) l'esame di Chimica Generale NON è più l'unico corso che permette di accedere alla magistrale in CS (al Polimi) senza dover svolgere Fisica Tecnica al secondo semestre del terzo anno. Ora un qualsiasi corso del gruppo TABA soddisfa il vincolo, quindi si può scegliere liberamente tra Chimica Generale, Fisica Tecnica, Misure e Onde Elettromagnetiche e Mezzi Trasmissivi. Nel caso in cui al secondo anno si scegliesse Elettromagnetismo e Campi da 10 cfu, al terzo anno si ha l'obbligo di inserire Logica e Algebra (gruppo TABREC) siccome è un corso obbligatorio per l'indirizzo I3I (informatica).", + ], + }, +] as const + export default function Home() { return (
+
+ +
diff --git a/src/components/card-list/accordion-list.tsx b/src/components/card-list/accordion-list.tsx new file mode 100644 index 0000000..a7dd487 --- /dev/null +++ b/src/components/card-list/accordion-list.tsx @@ -0,0 +1,49 @@ +import { useState } from "react" +import { FiChevronRight } from "react-icons/fi" +import { cn } from "@/lib/utils" +import type { CardListAccordionItem } from "./types" + +export function CardListAccordionList({ items }: { items: readonly CardListAccordionItem[] }) { + const [openIndex, setOpenIndex] = useState(null) + + return ( +
+ {items.map((item, index) => { + const isOpen = openIndex === index + + return ( +
+ + + {isOpen ? ( +
+ {item.paragraphs.map((paragraph) => ( +

+ {paragraph} +

+ ))} +
+ ) : null} +
+ ) + })} +
+ ) +} diff --git a/src/components/card-list/index.tsx b/src/components/card-list/index.tsx new file mode 100644 index 0000000..85d3ebb --- /dev/null +++ b/src/components/card-list/index.tsx @@ -0,0 +1,26 @@ +"use client" + +import { Glass } from "@/components/glass" +import { cn } from "@/lib/utils" +import { CardListAccordionList } from "./accordion-list" +import { CardListSectionContent } from "./section-content" +import type { CardListProps } from "./types" + +export function CardList({ sections, items, className }: CardListProps) { + return ( + +
+ {sections.map((section) => ( + + ))} + + {items?.length ? : null} +
+
+ ) +} diff --git a/src/components/card-list/section-content.tsx b/src/components/card-list/section-content.tsx new file mode 100644 index 0000000..1507bf7 --- /dev/null +++ b/src/components/card-list/section-content.tsx @@ -0,0 +1,21 @@ +import type { CardListSection } from "./types" + +export function CardListSectionContent({ title, paragraphs }: CardListSection) { + return ( +
+ {title && ( +

+ {title} +

+ )} + +
+ {paragraphs.map((paragraph) => ( +

+ {paragraph} +

+ ))} +
+
+ ) +} diff --git a/src/components/card-list/types.ts b/src/components/card-list/types.ts new file mode 100644 index 0000000..43e48e8 --- /dev/null +++ b/src/components/card-list/types.ts @@ -0,0 +1,15 @@ +export type CardListSection = { + title?: string + paragraphs: readonly string[] +} + +export type CardListAccordionItem = { + label: string + paragraphs: readonly string[] +} + +export type CardListProps = { + sections: readonly CardListSection[] + items?: readonly CardListAccordionItem[] + className?: string +}