Skip to content

Commit 1725e52

Browse files
authored
Merge pull request #17 from kyoto-tech/calendar
Created a calendar section pulling RSS
2 parents 469d9db + 6663484 commit 1725e52

File tree

5 files changed

+95
-2
lines changed

5 files changed

+95
-2
lines changed

package-lock.json

Lines changed: 14 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"react": "^19.2.0",
2727
"react-dom": "^19.2.0",
2828
"react-icons": "^5.5.0",
29-
"tailwindcss": "^4.1.17"
29+
"tailwindcss": "^4.1.17",
30+
"xml-js": "^1.6.11"
3031
},
3132
"devDependencies": {
3233
"@eslint/js": "^9.39.1",

src/components/Calendar.astro

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
import EventList from '../components/EventList.jsx';
3+
const RSS_URL = "https://www.meetup.com/Kyoto-Tech-Meetup/events/rss/";
4+
5+
const rssResponse = await fetch(RSS_URL);
6+
const rssText = await rssResponse.text();
7+
8+
// Minimal XML → JS parser
9+
import { xml2js } from "xml-js";
10+
const parsed = xml2js(rssText, { compact: true });
11+
let eventNames = [];
12+
13+
if (Array.isArray(parsed.rss.channel.item)) {
14+
console.log(parsed.rss.channel.item[0]);
15+
const items = parsed.rss.channel.item.map(evt => ({
16+
title: evt.title._cdata,
17+
link: evt.link._text,
18+
pubDate: evt.pubDate._text,
19+
description: evt.description?._text ?? "",
20+
}));
21+
22+
23+
eventNames = items;
24+
25+
} else {
26+
// handle the case where it's a single item object
27+
console.log(parsed.rss.channel.item.title);
28+
}
29+
30+
console.log(eventNames);
31+
32+
---
33+
34+
<section class="p-6">
35+
36+
<EventList client:load events={eventNames} />
37+
38+
</section>
39+

src/components/EventList.jsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export default function EventList({ events }) {
2+
return (
3+
<ul className="space-y-6">
4+
{events.map(event => (
5+
<li key={event.link} className="p-4 border rounded-xl shadow-sm">
6+
<a
7+
href={event.link}
8+
target="_blank"
9+
rel="noopener noreferrer"
10+
className="text-xl font-semibold text-blue-600 hover:underline"
11+
>
12+
{event.title}
13+
</a>
14+
<p className="text-sm text-gray-500 mt-1">
15+
{new Date(event.pubDate).toLocaleString()}
16+
</p>
17+
<div
18+
className="prose prose-sm mt-2"
19+
dangerouslySetInnerHTML={{ __html: event.description }}
20+
/>
21+
</li>
22+
))}
23+
</ul>
24+
);
25+
}

src/pages/index.astro

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import Layout from "../layouts/Layout.astro";
33
import WhyJoin from "../components/WhyJoin.astro";
44
import WhatWeDo from "../components/WhatWeDo.astro";
5+
import Calendar from "../components/Calendar.astro";
6+
import EventList from "../components/EventList.jsx";
57
import { FaGithub, FaDiscord, FaMeetup } from "react-icons/fa";
68
import { useTranslations } from '../i18n/utils';
79
import LanguagePicker from '../components/LanguagePicker.astro';
@@ -132,6 +134,19 @@ const activities: Activity[] = [
132134
</div>
133135
</section>
134136

137+
<section id="calendar" class="bg-white px-6 py-16 md:px-12">
138+
<div class="mx-auto max-w-5xl">
139+
<p class="text-sm font-semibold uppercase tracking-[0.3em] text-slate-500">
140+
Upcoming Meetups
141+
</p>
142+
<h2 class="mt-3 text-3xl font-semibold text-slate-900">
143+
Kyoto Tech Meetup Calendar
144+
</h2>
145+
146+
<Calendar />
147+
</div>
148+
</section>
149+
135150
<section id="who-comes" class="bg-white/95 px-6 py-16 md:px-12">
136151
<div class="mx-auto flex max-w-5xl flex-col gap-10 lg:flex-row">
137152
<div class="flex-1">

0 commit comments

Comments
 (0)