@@ -3,27 +3,117 @@ export default function EventList({ events }) {
33 return < p className = " mt3 text-gray-500 italic" > Check back soon for events! < a href = "https://www.meetup.com/ja-JP/kyoto-tech-meetup" > Join our meetup group here to get updates.</ a > </ p > ;
44 }
55
6+ // Group by month string (using Tokyo timezone for consistency)
7+ const groups = events . reduce ( ( acc , evt ) => {
8+ const d = new Date ( evt . start ) ;
9+ const monthLabel = d . toLocaleString ( "en-US" , {
10+ timeZone : "Asia/Tokyo" ,
11+ month : "long" ,
12+ year : "numeric"
13+ } ) ;
14+ acc [ monthLabel ] = acc [ monthLabel ] || [ ] ;
15+ acc [ monthLabel ] . push ( evt ) ;
16+ return acc ;
17+ } , { } ) ;
18+
19+ const orderedMonths = events
20+ . map ( evt => {
21+ const d = new Date ( evt . start ) ;
22+ const monthLabel = d . toLocaleString ( "en-US" , {
23+ timeZone : "Asia/Tokyo" ,
24+ month : "long" ,
25+ year : "numeric"
26+ } ) ;
27+ return { monthLabel, date : d } ;
28+ } )
29+ . reduce ( ( seen , curr ) => {
30+ if ( ! seen . find ( item => item . monthLabel === curr . monthLabel ) ) {
31+ seen . push ( curr ) ;
32+ }
33+ return seen ;
34+ } , [ ] )
35+ . sort ( ( a , b ) => a . date - b . date )
36+ . map ( item => item . monthLabel ) ;
37+
638 return (
7- < ul className = "space-y-6" >
8- { events . map ( event => (
9- < li key = { event . link } className = "p-4 border rounded-xl shadow-sm" >
10- < a
11- href = { event . link }
12- target = "_blank"
13- rel = "noopener noreferrer"
14- className = "text-xl font-semibold text-blue-600 hover:underline"
15- >
16- { event . title }
17- </ a >
18- < p className = "text-sm text-gray-500 mt-1" >
19- { new Date ( event . pubDate ) . toLocaleString ( ) }
20- </ p >
21- < div
22- className = "prose prose-sm mt-2"
23- dangerouslySetInnerHTML = { { __html : event . description } }
24- />
25- </ li >
39+ < div className = "space-y-8" >
40+ { orderedMonths . map ( monthLabel => (
41+ < div key = { monthLabel } className = "space-y-4" >
42+ < h3 className = "text-2xl font-semibold text-slate-900" > { monthLabel } </ h3 >
43+ < ul className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
44+ { groups [ monthLabel ] . map ( event => (
45+ < li key = { event . link } >
46+ < a
47+ href = { event . link }
48+ target = "_blank"
49+ rel = "noopener noreferrer"
50+ className = "p-4 border rounded-xl shadow-sm flex gap-4 items-start md:items-center block hover:shadow-md transition-shadow no-underline h-full"
51+ style = { {
52+ color : "var(--accent)" ,
53+ textDecoration : "none" ,
54+ borderColor : "var(--accent)"
55+ } }
56+ >
57+ { event . image ? (
58+ < div className = "w-1/3 min-w-[120px]" >
59+ < img
60+ src = { event . image }
61+ alt = { event . title }
62+ className = "w-full h-full max-h-32 rounded-lg object-cover"
63+ loading = "lazy"
64+ />
65+ </ div >
66+ ) : null }
67+ < div className = "flex-1 min-w-0" >
68+ < div className = "text-xl font-semibold" >
69+ { event . title }
70+ </ div >
71+ < p className = "text-sm text-gray-500 mt-1 space-x-2" >
72+ < span >
73+ { new Date ( event . start ) . toLocaleString ( "en-US" , {
74+ timeZone : "Asia/Tokyo" ,
75+ month : "long" ,
76+ day : "numeric" ,
77+ year : "numeric"
78+ } ) }
79+ </ span >
80+ < span className = "text-gray-400" > •</ span >
81+ < span >
82+ { new Date ( event . start ) . toLocaleTimeString ( "en-US" , {
83+ timeZone : "Asia/Tokyo" ,
84+ hour12 : false ,
85+ hour : "2-digit" ,
86+ minute : "2-digit"
87+ } ) }
88+ { event . endTime
89+ ? ` – ${ new Date ( event . endTime ) . toLocaleTimeString ( "en-US" , {
90+ timeZone : "Asia/Tokyo" ,
91+ hour12 : false ,
92+ hour : "2-digit" ,
93+ minute : "2-digit"
94+ } ) } `
95+ : "" }
96+ </ span >
97+ </ p >
98+ < div className = "text-sm text-gray-700 mt-2 space-y-1" >
99+ < div className = "font-medium text-slate-900" >
100+ { event . venue ?. name ?? "Venue TBA" }
101+ </ div >
102+ { event . venue ?. address ? (
103+ < div className = "text-gray-600" > { event . venue . address } </ div >
104+ ) : null }
105+ </ div >
106+ < div className = "flex flex-wrap items-center gap-3 mt-3 text-sm text-gray-600" >
107+ < span > { event . goingCount ?? 0 } going</ span >
108+ < span > · { event . interestedCount ?? 0 } interested</ span >
109+ </ div >
110+ </ div >
111+ </ a >
112+ </ li >
113+ ) ) }
114+ </ ul >
115+ </ div >
26116 ) ) }
27- </ ul >
117+ </ div >
28118 ) ;
29119}
0 commit comments