Skip to content

Commit e044c6b

Browse files
committed
feat: add agenda mobile component
1 parent 2d7732d commit e044c6b

File tree

5 files changed

+220
-24
lines changed

5 files changed

+220
-24
lines changed

src/components/agenda/Agenda.astro

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@
22
import { useI18n } from '~/i18n/utils'
33
import Layout from '~/layouts/Layout.astro'
44
import Desktop from './Desktop.astro'
5+
import Mobile from './Mobile.astro'
56
67
const { t } = useI18n(Astro.url.pathname)
78
const { title, date } = Astro.props
89
---
910

1011
<Layout pageName={t('nav.agenda')}>
1112
<Desktop title={title} date={date} />
13+
<Mobile title={title} date={date} />
1214
</Layout>
15+
16+
<style is:global>
17+
#navbar {
18+
position: static;
19+
}
20+
</style>

src/components/agenda/Desktop.astro

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,31 @@ schedule.sessions.forEach(session => {
2121
})
2222
---
2323

24-
<div class="agenda">
25-
<div class="sticky top-0 z-30 flex flex-col justify-center bg-white" style="height: var(--agenda-header-height);">
26-
<div class="mb-5 flex justify-center gap-4 font-bold">
27-
<a class={title === 'Day 1' ? 'text-info-dark' : 'text-info'} href={getRelativeLocaleUrl(locale, 'agenda/day1')}>Day 1</a>
28-
<a class={title === 'Day 2' ? 'text-info-dark' : 'text-info'} href={getRelativeLocaleUrl(locale, 'agenda/day2')}>Day 2</a>
29-
</div>
30-
31-
<div class="agenda-grid grid text-center">
32-
<div></div>
33-
<div class="bg-primary mx-3 py-2 text-white">{t('room.R0')}</div>
34-
<div class="bg-primary mx-3 py-2 text-white">{t('room.R1')}</div>
35-
<div class="bg-primary mx-3 py-2 text-white">{t('room.R2')}</div>
36-
<div class="bg-primary mx-3 py-2 text-white">{t('room.RH')}</div>
24+
<div class="agenda hidden lg:block">
25+
<div class="sticky top-0 z-30 flex flex-col justify-center bg-white shadow" style="height: var(--agenda-header-height);">
26+
<div class="container">
27+
<div class="mb-5 flex justify-center gap-4 font-bold">
28+
<a class={title === 'Day 1' ? 'text-info-dark' : 'text-info'} href={getRelativeLocaleUrl(locale, 'agenda/day1')}>Day 1</a>
29+
<a class={title === 'Day 2' ? 'text-info-dark' : 'text-info'} href={getRelativeLocaleUrl(locale, 'agenda/day2')}>Day 2</a>
30+
</div>
31+
32+
<div class="agenda-grid grid text-center">
33+
<div></div>
34+
<div class="bg-primary mx-3 py-2 text-white">{t('room.R0')}</div>
35+
<div class="bg-primary mx-3 py-2 text-white">{t('room.R1')}</div>
36+
<div class="bg-primary mx-3 py-2 text-white">{t('room.R2')}</div>
37+
<div class="bg-primary mx-3 py-2 text-white">{t('room.RH')}</div>
38+
</div>
3739
</div>
3840
</div>
3941

40-
<h2 class="mt-8 mb-12">{title}</h2>
42+
<div class="container">
43+
<h2 class="mt-8 mb-12">{title}</h2>
4144

42-
<div class="agenda-grid relative grid">
43-
{Array.from(times).map(time => <Time at={time} />)}
44-
{sessions.map(session => <Session session={session} />)}
45+
<div class="agenda-grid relative grid">
46+
{Array.from(times).map(time => <Time at={time} />)}
47+
{sessions.map(session => <Session session={session} />)}
48+
</div>
4549
</div>
4650
</div>
4751

src/components/agenda/Mobile.astro

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
import { getRelativeLocaleUrl } from 'astro:i18n'
3+
import { getLocaleFromPath } from '~/i18n/utils'
4+
import schedule from '~/data/schedule.json'
5+
import { extractHHmm } from '~/utils/build/agenda/extractHHmm'
6+
import Session from '~/components/agenda/Session.astro'
7+
8+
const locale = getLocaleFromPath(Astro.url.pathname)
9+
const { title, date } = Astro.props
10+
11+
const sessions = schedule.sessions.filter(session => session.start.startsWith(date)).sort(session => session.start.localeCompare(session.end))
12+
13+
const allSessions = sessions.reduce((acc, session) => {
14+
const key = extractHHmm(session.start)
15+
if (!acc[key]) acc[key] = []
16+
acc[key].push(session)
17+
return acc
18+
}, {})
19+
const allTimes = Object.keys(allSessions).sort((a, b) => a.localeCompare(b))
20+
21+
const r0Sessions = sessions
22+
.filter(session => session.room === 'R0' || session.broadcast.includes('R0'))
23+
.reduce((acc, session) => {
24+
const key = extractHHmm(session.start)
25+
if (!acc[key]) acc[key] = []
26+
acc[key].push(session)
27+
return acc
28+
}, {})
29+
const r0Times = Object.keys(r0Sessions).sort((a, b) => a.localeCompare(b))
30+
31+
const r1Sessions = sessions
32+
.filter(session => session.room === 'R1' || session.broadcast.includes('R1'))
33+
.reduce((acc, session) => {
34+
const key = extractHHmm(session.start)
35+
if (!acc[key]) acc[key] = []
36+
acc[key].push(session)
37+
return acc
38+
}, {})
39+
const r1Times = Object.keys(r1Sessions).sort((a, b) => a.localeCompare(b))
40+
41+
const r2Sessions = sessions
42+
.filter(session => session.room === 'R2' || session.broadcast.includes('R2'))
43+
.reduce((acc, session) => {
44+
const key = extractHHmm(session.start)
45+
if (!acc[key]) acc[key] = []
46+
acc[key].push(session)
47+
return acc
48+
}, {})
49+
const r2Times = Object.keys(r2Sessions).sort((a, b) => a.localeCompare(b))
50+
51+
const rhSessions = sessions
52+
.filter(session => session.room === 'RH' || session.broadcast.includes('RH'))
53+
.reduce((acc, session) => {
54+
const key = extractHHmm(session.start)
55+
if (!acc[key]) acc[key] = []
56+
acc[key].push(session)
57+
return acc
58+
}, {})
59+
const rhTimes = Object.keys(rhSessions).sort((a, b) => a.localeCompare(b))
60+
---
61+
62+
<div class="lg:hidden">
63+
<div class="sticky top-0 z-30 bg-white py-3 shadow">
64+
<div class="container">
65+
<div class="mb-3 flex justify-center gap-4 font-bold">
66+
<a class={title === 'Day 1' ? 'text-info-dark' : 'text-info'} href={getRelativeLocaleUrl(locale, 'agenda/day1')}>Day 1</a>
67+
<a class={title === 'Day 2' ? 'text-info-dark' : 'text-info'} href={getRelativeLocaleUrl(locale, 'agenda/day2')}>Day 2</a>
68+
</div>
69+
<div class="grid grid-cols-5 text-center">
70+
<button id="allBtn">ALL</button>
71+
<button id="r0Btn">R0</button>
72+
<button id="r1Btn">R1</button>
73+
<button id="r2Btn">R2</button>
74+
<button id="rhBtn">RH</button>
75+
</div>
76+
</div>
77+
</div>
78+
79+
<div class="container">
80+
<h2 class="mt-8 mb-12">{title}</h2>
81+
82+
<div id="allSessions">
83+
{
84+
allTimes.map(time => (
85+
<div>
86+
<div>{time}</div>
87+
{allSessions[time].map(session => (
88+
<Session session={session} />
89+
))}
90+
</div>
91+
))
92+
}
93+
</div>
94+
95+
<div id="r0Sessions" style="display: none;">
96+
{
97+
r0Times.map(time => (
98+
<div>
99+
<div>{time}</div>
100+
{r0Sessions[time].map(session => (
101+
<Session session={session} />
102+
))}
103+
</div>
104+
))
105+
}
106+
</div>
107+
108+
<div id="r1Sessions" style="display: none;">
109+
{
110+
r1Times.map(time => (
111+
<div>
112+
<div>{time}</div>
113+
{r1Sessions[time].map(session => (
114+
<Session session={session} />
115+
))}
116+
</div>
117+
))
118+
}
119+
</div>
120+
121+
<div id="r2Sessions" style="display: none;">
122+
{
123+
r2Times.map(time => (
124+
<div>
125+
<div>{time}</div>
126+
{r2Sessions[time].map(session => (
127+
<Session session={session} />
128+
))}
129+
</div>
130+
))
131+
}
132+
</div>
133+
134+
<div id="rhSessions" style="display: none;">
135+
{
136+
rhTimes.map(time => (
137+
<div>
138+
<div>{time}</div>
139+
{rhSessions[time].map(session => (
140+
<Session session={session} />
141+
))}
142+
</div>
143+
))
144+
}
145+
</div>
146+
</div>
147+
</div>
148+
149+
<script>
150+
import $ from 'jquery'
151+
152+
const $allSessions = $('#allSessions')
153+
const $r0Sessions = $('#r0Sessions')
154+
const $r1Sessions = $('#r1Sessions')
155+
const $r2Sessions = $('#r2Sessions')
156+
const $rhSessions = $('#rhSessions')
157+
158+
$('#allBtn').on('click', function () {
159+
hideAll()
160+
$allSessions.css('display', '')
161+
})
162+
163+
$('#r0Btn').on('click', function () {
164+
hideAll()
165+
$r0Sessions.css('display', '')
166+
})
167+
168+
$('#r1Btn').on('click', function () {
169+
hideAll()
170+
$r1Sessions.css('display', '')
171+
})
172+
173+
$('#r2Btn').on('click', function () {
174+
hideAll()
175+
$r2Sessions.css('display', '')
176+
})
177+
178+
$('#rhBtn').on('click', function () {
179+
hideAll()
180+
$rhSessions.css('display', '')
181+
})
182+
183+
function hideAll() {
184+
$allSessions.css('display', 'none')
185+
$r0Sessions.css('display', 'none')
186+
$r1Sessions.css('display', 'none')
187+
$r2Sessions.css('display', 'none')
188+
$rhSessions.css('display', 'none')
189+
}
190+
</script>

src/components/agenda/Session.astro

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,3 @@ function typeToDetail(type) {
6767
</div>
6868
</div>
6969
</div>
70-
71-
<style is:global>
72-
#navbar {
73-
position: static;
74-
}
75-
</style>

src/layouts/Layout.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const { pageName } = Astro.props
1717
<body>
1818
<div class="flex min-h-screen flex-col">
1919
<Navbar />
20-
<div class="container mb-auto py-8">
20+
<div class="mb-auto">
2121
<slot />
2222
</div>
2323
<Footer />

0 commit comments

Comments
 (0)