Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/app/join/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AdminSection } from "@/components/join/admin"
import { Introduction } from "@/components/join/introduction"
import { MembershipSection } from "@/components/join/membership"
import { TeamsSection } from "@/components/join/teams"
import { CONTAINER } from "@/components/layout/page"
import { Hero } from "@/components/ui/hero"

export const metadata: Metadata = {
Expand All @@ -13,8 +14,8 @@ export const metadata: Metadata = {

export default function JoinPage() {
return (
<main className="flex w-full flex-col gap-24 pb-32 md:gap-36 md:pb-48">
<section className={"mx-auto w-full max-w-330 px-6 pt-52 md:pt-57.5"}>
<main className="flex w-full flex-col gap-24 pb-24 md:gap-36 md:pb-36 xl:gap-56 2xl:gap-72">
<section className={`${CONTAINER} pt-52 md:pt-57.5`}>
<Hero
title="Unisciti a Noi"
description="Nessuna simulazione, solo progetti reali. Scopri come fare la differenza per migliaia di studenti del PoliMi"
Expand Down
24 changes: 19 additions & 5 deletions src/components/collabora/info-card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Image, { type StaticImageData } from "next/image"
import Link from "next/link"
import type { ReactNode } from "react"
import { CardHoverBackground } from "@/components/card-icon/hover-background"
import { Glass } from "@/components/glass"
import { cn } from "@/lib/utils"

Expand All @@ -14,6 +16,8 @@ export type InfoCardData = {
iconClassName: string
/** Desktop description width: Figma wraps these copies at fixed widths (+1px, as Figma rounds text widths down). */
descriptionClassName?: string
/** Makes the whole card a link: only then does it react to hover. */
href?: string
}

/**
Expand All @@ -29,12 +33,22 @@ export function InfoCard({
className?: string
descriptionColorClassName?: string
}) {
const { title, description, mobileDescription, icon, iconClassName, descriptionClassName } = card
const { title, description, mobileDescription, icon, iconClassName, descriptionClassName, href } = card

return (
// Glass draws a 1px border inside the Figma box: padding is 1px less than in Figma (25px / 40px)
<Glass className={cn("rounded-rectangles border-white/50 bg-background-blur p-6 md:p-9.75", className)}>
<div className="flex items-center md:flex-col md:items-start">
<Glass
className={cn(
"rounded-rectangles border-white/50 bg-background-blur p-6 md:p-9.75",
href &&
"group/card relative overflow-hidden has-[>a:focus-visible]:ring-2 has-[>a:focus-visible]:ring-blue-secondary",
className
)}
>
{href && <CardHoverBackground />}
{href && <Link href={href} className="absolute inset-0 z-10 outline-none" aria-label={title} />}
{/* Positioned so the text stays above the hover background */}
<div className="relative flex items-center md:flex-col md:items-start">
<div className="flex shrink-0 md:h-17.25 md:items-start">
<Image src={icon} alt="" className={iconClassName} />
</div>
Expand All @@ -44,11 +58,11 @@ export function InfoCard({
</h3>
</div>
{mobileDescription !== undefined && (
<p className="typo-body-small -mr-2 mt-3 text-text-primary md:hidden">{mobileDescription}</p>
<p className="typo-body-small -mr-2 relative mt-3 text-text-primary md:hidden">{mobileDescription}</p>
)}
<p
className={cn(
"typo-body-small md:typo-body-large mt-3",
"typo-body-small md:typo-body-large relative mt-3",
descriptionColorClassName,
descriptionClassName,
mobileDescription !== undefined && "max-md:hidden"
Expand Down
14 changes: 7 additions & 7 deletions src/components/join/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import Image from "next/image"
import connectorFirst from "@/assets/icons/join/connector-first.svg"
import connectorSecond from "@/assets/icons/join/connector-second.svg"
import { InfoCard } from "@/components/collabora/info-card"
import { Highlight, SectionTitle } from "@/components/collabora/section"
import { SECTION_LEAD } from "@/components/layout/page"
import { Highlight } from "@/components/collabora/section"
import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page"
import { cn } from "@/lib/utils"
import { JoinCards } from "./cards"
import { adminCards, adminSteps } from "./constants"
Expand All @@ -12,11 +12,11 @@ const connectors = [connectorFirst, connectorSecond]

export function AdminSection() {
return (
<section id="admin" className={"mx-auto flex w-full max-w-330 scroll-mt-36 flex-col gap-12 px-6"}>
<section id="admin" className={cn(CONTAINER, "flex scroll-mt-36 flex-col gap-16 xl:gap-20")}>
<div className="grid min-w-0 items-start gap-10 xl:grid-cols-2 xl:gap-16">
<div className="flex min-w-0 flex-col gap-6 text-center md:text-start">
<SectionTitle>Diventa Admin</SectionTitle>
<div className={cn(SECTION_LEAD, "flex flex-col gap-5")}>
<div className="flex min-w-0 flex-col gap-6">
<h2 className={SECTION_TITLE}>Diventa Admin</h2>
<div className={cn(SECTION_LEAD, "flex max-w-200 flex-col gap-5")}>
<p>Un admin è la presenza di PoliNetwork nei gruppi ogni giorno.</p>
<p>
Non servono competenze specifiche ma solamente{" "}
Expand All @@ -33,7 +33,7 @@ export function AdminSection() {
<JoinCards cards={adminCards} carousel />
</div>
<div className="flex flex-col gap-6">
<h3 className="typo-title-large sm:typo-headline-medium text-balance bg-linear-to-b from-text-accent-lightbg to-[#41496b] bg-clip-text text-center text-transparent md:text-start">
<h3 className="typo-title-large sm:typo-headline-medium text-balance text-text-primary">
Ti interessano questi compiti?
</h3>
<ol className="grid gap-6 lg:grid-cols-3 lg:gap-12">
Expand Down
5 changes: 3 additions & 2 deletions src/components/join/cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ export function JoinCards({ cards, carousel = false }: { cards: InfoCardData[];
return (
<Carousel
opts={{ align: "start", breakpoints: { "(min-width: 768px)": { active: false } } }}
className="w-full min-w-0"
// Mobile: the carousel runs to the screen edges so the next card peeks in, as in the homepage
className="-mx-6 sm:-mx-10 min-w-0 md:mx-0"
>
<CarouselContent className="md:ml-0 md:grid md:grid-cols-2 md:gap-6">
<CarouselContent className="mr-6 ml-2 sm:mr-10 sm:ml-6 md:mx-0 md:grid md:grid-cols-2 md:gap-6">
{cards.map((card) => (
<CarouselItem key={card.title} className="basis-[90%] sm:basis-1/2 md:pl-0">
<InfoCard card={card} className={cardClassName} />
Expand Down
4 changes: 4 additions & 0 deletions src/components/join/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,28 @@ export const adminSteps: InfoCardData[] = [
export const teamCards: InfoCardData[] = [
{
title: "Sviluppo Tecnico",
href: "/team#it",
description: "Realizza prodotti digitali in produzione, usati da migliaia di persone",
icon: code,
iconClassName,
},
{
title: "Comunicazione",
href: "/team#design-marketing",
description: "Gestisce la comunicazione e l’identità visiva dell’associazione: Instagram, grafiche di eventi…",
icon: palette,
iconClassName,
},
{
title: "Gestione HR",
href: "/team#hr",
description: "Struttura i processi di recruiting e onboarding e gestisce i volontari del network",
icon: hr,
iconClassName,
},
{
title: "Eventi/Partnership",
href: "/team#events-partnership",
description: "Organizza eventi e costruisce collaborazioni con aziende e associazioni esterne",
icon: events,
iconClassName,
Expand Down
47 changes: 21 additions & 26 deletions src/components/join/introduction.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import Image from "next/image"
import { FiMessageCircle, FiUserCheck, FiUsers } from "react-icons/fi"
import networkLogo from "@/assets/images/join/network-logo.png"
import { CardIcon } from "@/components/card-icon"
import { Highlight, SectionTitle } from "@/components/collabora/section"
import { SECTION_LEAD } from "@/components/layout/page"
import { Highlight } from "@/components/collabora/section"
import { CONTAINER, INLINE_LINK, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page"
import { cn } from "@/lib/utils"

const paths = [
{ title: "Diventa Admin", icon: FiMessageCircle, href: "#admin" },
{ title: "Entra in un Team", icon: FiUsers, href: "#team" },
{ title: "Diventa Socio", icon: FiUserCheck, href: "#socio" },
]

export function Introduction() {
return (
<section className="mx-auto grid w-full max-w-330 items-center gap-x-16 gap-y-10 px-6 xl:grid-cols-[minmax(0,3fr)_minmax(0,1fr)]">
<div className="flex min-w-0 flex-col gap-6 text-center md:text-start">
<SectionTitle>Cosa significa far parte di PoliNetwork</SectionTitle>
<div className={cn(SECTION_LEAD, "flex flex-col gap-5")}>
<section
className={cn(CONTAINER, "grid items-center gap-x-16 gap-y-10 xl:grid-cols-[minmax(0,3fr)_minmax(0,1fr)]")}
>
<div className="flex min-w-0 flex-col gap-6">
<h2 className={SECTION_TITLE}>Cosa significa far parte di PoliNetwork</h2>
<div className={cn(SECTION_LEAD, "flex max-w-200 flex-col gap-5")}>
<p>
PoliNetwork è gestita interamente da <Highlight>studenti del Politecnico di Milano</Highlight>.
</p>
Expand All @@ -34,22 +28,23 @@ export function Introduction() {
</Highlight>
</p>
<p>
Ci sono tre modi per fare parte di PoliNetwork: diventare admin, entrare in uno dei team operativi o
diventare socio.
Ci sono tre modi per fare parte di PoliNetwork:{" "}
<a href="#admin" className={INLINE_LINK}>
diventare admin
</a>
,{" "}
<a href="#team" className={INLINE_LINK}>
entrare in uno dei team operativi
</a>{" "}
o{" "}
<a href="#socio" className={INLINE_LINK}>
diventare socio
</a>
.
</p>
</div>
</div>
<Image src={networkLogo} alt="" sizes="224px" className="hidden h-auto w-56 justify-self-center xl:block" />
<ul
aria-label="Tre modi per fare parte di PoliNetwork"
className="grid w-full gap-4 md:grid-cols-3 xl:col-span-2"
>
{paths.map((path) => (
<li key={path.href} className="min-w-0">
<CardIcon {...path} align="inline" size="inline-sm" className="h-full" />
</li>
))}
</ul>
</section>
)
}
29 changes: 14 additions & 15 deletions src/components/join/membership.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import Image from "next/image"
import externalLink from "@/assets/icons/join/external-link.svg"
import membersPhoto from "@/assets/images/join/members.webp"
import { Highlight, SectionTitle } from "@/components/collabora/section"
import { SECTION_LEAD } from "@/components/layout/page"
import { Highlight } from "@/components/collabora/section"
import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page"
import { PhotoShapes } from "@/components/shapes"
import { cn } from "@/lib/utils"
import { membershipSteps } from "./constants"

export function MembershipSection() {
return (
<section
id="socio"
className={"mx-auto grid w-full max-w-330 scroll-mt-36 items-start gap-10 px-6 xl:grid-cols-2 xl:gap-x-16"}
>
<div className="flex min-w-0 flex-col gap-6 text-center md:text-start xl:col-start-1">
<SectionTitle>
<section id="socio" className={cn(CONTAINER, "grid scroll-mt-36 items-start gap-10 xl:grid-cols-2 xl:gap-x-16")}>
<div className="flex min-w-0 flex-col gap-6 xl:col-start-1">
<h2 className={SECTION_TITLE}>
<span className="md:hidden">Diventa Socio</span>
<span className="hidden md:inline">Diventa Socio di PoliNetwork</span>
</SectionTitle>
<div className={cn(SECTION_LEAD, "flex flex-col gap-5")}>
</h2>
<div className={cn(SECTION_LEAD, "flex max-w-200 flex-col gap-5")}>
<p>
Il tesseramento è il modo per fare parte di PoliNetwork in modo formale, con{" "}
<Highlight>diritto di voto</Highlight> nelle Assemblee dei Soci, di candidarsi alle elezioni del direttivo e{" "}
Expand All @@ -44,13 +41,13 @@ export function MembershipSection() {
<div
className={cn("flex min-w-0 flex-col gap-3 pt-2 md:pt-3", index < membershipSteps.length - 1 && "pb-8")}
>
<h3 className="typo-title-medium sm:typo-title-large text-pretty text-blue-secondary">
<h3 className="typo-headline-extrasmall sm:typo-title-large text-pretty text-blue-secondary">
{"href" in step ? (
<a
href={step.href}
target={step.href.startsWith("https:") ? "_blank" : undefined}
rel={step.href.startsWith("https:") ? "noopener noreferrer" : undefined}
className="decoration-1 underline-offset-4 hover:underline focus-visible:underline"
className="rounded-sm decoration-1 underline-offset-4 outline-none hover:underline focus-visible:ring-2 focus-visible:ring-blue-secondary"
>
{step.title}
{step.href.startsWith("https:") && (
Expand All @@ -62,15 +59,15 @@ export function MembershipSection() {
)}
</h3>
{index === 3 && (
<ul className="typo-body-large list-disc space-y-1 text-pretty pl-5">
<ul className="typo-body-medium sm:typo-body-large list-disc space-y-1 text-pretty pl-5">
<li>Utilizza preferibilmente un indirizzo PoliMi valido.</li>
<li>Oggetto: “Richiesta ammissione sotto la qualifica di socio”.</li>
<li>Inserisci ogni informazione utile da avere, ad esempio il tuo username Telegram.</li>
<li>Se ricopri già ruoli in PoliNetwork, specificali.</li>
</ul>
)}
{index === 4 && (
<p className="typo-body-large text-pretty">
<p className="typo-body-medium sm:typo-body-large text-pretty">
Secondo le modalità descritte nella sezione “Ammissione” dello statuto.
</p>
)}
Expand All @@ -83,8 +80,10 @@ export function MembershipSection() {
<Image
src={membersPhoto}
alt="Un gruppo di volontari di PoliNetwork insieme all’aperto"
fill
sizes="(min-width: 1280px) 40vw, 100vw"
className="-top-[37.19%] absolute left-0 h-[137.25%] w-full max-w-none"
// Figma's crop keeps the bottom of the photo (the people), whatever the box's aspect ratio
className="object-cover object-bottom"
/>
</div>
<PhotoShapes
Expand Down
15 changes: 6 additions & 9 deletions src/components/join/teams.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import Link from "next/link"
import { FiArrowUpRight } from "react-icons/fi"
import { Highlight, SectionTitle } from "@/components/collabora/section"
import { SECTION_LEAD } from "@/components/layout/page"
import { Highlight } from "@/components/collabora/section"
import { CONTAINER, SECTION_LEAD, SECTION_TITLE } from "@/components/layout/page"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import { JoinCards } from "./cards"
import { teamCards } from "./constants"

export function TeamsSection() {
return (
<section
id="team"
className={"mx-auto grid w-full max-w-330 scroll-mt-36 items-start gap-10 px-6 xl:grid-cols-2 xl:gap-16"}
>
<div className="flex min-w-0 flex-col items-center gap-6 text-center md:items-start md:text-start">
<SectionTitle>Entra in un Team</SectionTitle>
<div className={cn(SECTION_LEAD, "flex flex-col gap-5")}>
<section id="team" className={cn(CONTAINER, "grid scroll-mt-36 items-start gap-10 xl:grid-cols-2 xl:gap-16")}>
<div className="flex min-w-0 flex-col items-start gap-6">
<h2 className={SECTION_TITLE}>Entra in un Team</h2>
<div className={cn(SECTION_LEAD, "flex max-w-200 flex-col gap-5")}>
<p>
Entrare in un team significa avere un <Highlight>ruolo operativo con deliverable reali</Highlight>, non
essere osservatori di un progetto altrui.
Expand Down
4 changes: 4 additions & 0 deletions src/components/layout/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ 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"

/** A link inside running text: always underlined, so it reads as a link without relying on colour. */
export const INLINE_LINK =
"rounded-sm text-blue-secondary underline decoration-1 decoration-blue-secondary/40 underline-offset-4 outline-none transition-colors hover:decoration-blue-secondary focus-visible:ring-2 focus-visible:ring-blue-secondary"
Loading