1+ ---
2+ import { Title } from " ../typography/title" ;
3+ import Ribbon from " ./ribbon.astro" ;
4+
5+ interface SponsorTierProps {
6+ title: string ;
7+ totalSlots? : number | null | string ;
8+ price: number | string ;
9+ features: string [];
10+ }
11+
12+ const tiers: SponsorTierProps [] = [
13+ {
14+ title: " Keystone" ,
15+ totalSlots: 1 ,
16+ price: " Please ask" ,
17+ features: [
18+ " Keynote (plenary) room named after your company" ,
19+ " Central sizable booth in exhibit hall" ,
20+ " 12 complimentary session passes" ,
21+ " Logo on room lecterns, banners, videos, website, signage" ,
22+ " Blog post on conference website" ,
23+ " Access to recruiting session" ,
24+ " 1 sponsored workshop (3 hours)" ,
25+ " 1 sponsored talk (30 minutes)" ,
26+ " Private organisers support" ,
27+ " And more!" ,
28+ ],
29+ },
30+ {
31+ title: " Diamond" ,
32+ totalSlots: 2 ,
33+ price: undefined ,
34+ features: [
35+ " 30 sqm booth in exhibit hall" ,
36+ " 8 complimentary session passes" ,
37+ " Logo on room lecterns, banners, videos, website, signage" ,
38+ " Blog post on conference website" ,
39+ " Access to recruiting session" ,
40+ " 1 sponsored talk (30 minutes)" ,
41+ " And more!" ,
42+ ],
43+ },
44+ {
45+ title: " Platinum" ,
46+ totalSlots: 3 ,
47+ price: undefined ,
48+ features: [
49+ " 16 sqm booth in exhibit hall" ,
50+ " 6 complimentary session passes" ,
51+ " Logo on banners, videos, website, signage" ,
52+ " PDF brochure on virtual swag webpage" ,
53+ " Access to recruiting session" ,
54+ " 1 sponsored talk (30 minutes)" ,
55+ " And more!" ,
56+ ],
57+ },
58+ {
59+ title: " Platinum X" ,
60+ totalSlots: 3 ,
61+ price: undefined ,
62+ features: [
63+ " 6 complimentary session passes" ,
64+ " Logo on banners, videos, website, signage" ,
65+ " PDF brochure on virtual swag webpage" ,
66+ " Access to recruiting session" ,
67+ " 1 sponsored talk (30 minutes)" ,
68+ " And more!" ,
69+ ],
70+ },
71+ {
72+ title: " Gold" ,
73+ price: undefined ,
74+ totalSlots: " limited" ,
75+ features: [
76+ " 9 sqm booth in exhibit hall" ,
77+ " 3 complimentary session passes" ,
78+ " Logo on banners, videos, website, signage" ,
79+ " PDF brochure on virtual swag webpage" ,
80+ " Access to recruiting session" ,
81+ " And more!" ,
82+ ],
83+ },
84+ {
85+ title: " Gold X" ,
86+ price: undefined ,
87+ totalSlots: " limited" ,
88+ features: [
89+ " 3 complimentary session passes" ,
90+ " Logo on banners, videos, website, signage" ,
91+ " PDF brochure on virtual swag webpage" ,
92+ " Access to recruiting session" ,
93+ " And more!" ,
94+ ],
95+ },
96+ {
97+ title: " Silver" ,
98+ price: undefined ,
99+ totalSlots: " limited" ,
100+ features: [
101+ " 6 sqm booth in exhibit hall" ,
102+ " 2 complimentary session passes" ,
103+ " Logo on website, signage" ,
104+ " And more!" ,
105+ ],
106+ },
107+ {
108+ title: " Bronze" ,
109+ price: undefined ,
110+ totalSlots: " unlimited" ,
111+ features: [" Logo & recruiting ad on EuroPython website and more!" ],
112+ },
113+ {
114+ title: " Patron" ,
115+ price: undefined ,
116+ totalSlots: " unlimited" ,
117+ features: [" Logo on EuroPython website, welcome tweet and more!" ],
118+ },
119+ ];
120+
121+ const getRibbonClass = (title : string ) => {
122+ const classes = {
123+ Keystone: " text-sponsor-keystone" ,
124+ Diamond: " text-sponsor-diamond" ,
125+ Platinum: " text-sponsor-platinum" ,
126+ " Platinum X" : " text-sponsor-platinum" ,
127+ Gold: " text-sponsor-gold" ,
128+ " Gold X" : " text-sponsor-gold" ,
129+
130+ Silver: " text-sponsor-silver" ,
131+ Bronze: " text-sponsor-bronze" ,
132+ Patron: " text-sponsor-patron" ,
133+ };
134+ return classes [title as keyof typeof classes ] || " " ;
135+ };
136+
137+ const formatPrice = (price : number | string ) => {
138+ if (typeof price === " string" ) return price ;
139+ return new Intl .NumberFormat (" en" , {
140+ style: " currency" ,
141+ currency: " EUR" ,
142+ maximumFractionDigits: 0 ,
143+ minimumFractionDigits: 0 ,
144+ }).format (price );
145+ };
146+ ---
147+
148+ <div class =" grid grid-cols-1 sm:grid-cols-2 gap-10" >
149+ {
150+ tiers .map ((tier ) => (
151+ <div class = " bg-white text-black rounded-2xl p-6 relative not-prose z-0" >
152+ <div class = " h-[160px]" >
153+ <Ribbon
154+ className = { ` absolute -right-6 -top-8 ${getRibbonClass (tier .title )} ` }
155+ style = { { zIndex: " -1" }}
156+ />
157+
158+ <Title level = { 3 } className = " mt-0 !mb-2" >
159+ { tier .title }
160+ </Title >
161+
162+ <div class = " font-bold text-3xl" >{ formatPrice (tier .price )} </div >
163+ <div class = " text-xl" >
164+ { tier .totalSlots ? (
165+ <>
166+ <span >{ tier .totalSlots } </span > slot{ tier .totalSlots == 1 ? " " : " s" } { " " }
167+ available
168+ </>
169+ ) : (
170+ <>No slot available</>
171+ )}
172+ </div >
173+ </div >
174+
175+ <p class = " font-bold text-base" >This tier includes:</p >
176+ <ul class = " text-base" >
177+ { tier .features .map ((feature ) => (
178+ <li >✔️ { feature } </li >
179+ ))}
180+ </ul >
181+ </div >
182+ ))
183+ }
184+ </div >
0 commit comments