Skip to content

Commit e7509cc

Browse files
committed
타임테이블의 긴 휴식 시간을 단축 표현 및 키노트는 모든 컬럼을 다 사용하도록 수정
1 parent 05fc1bc commit e7509cc

File tree

1 file changed

+81
-34
lines changed

1 file changed

+81
-34
lines changed

src/pages/Session/timetable.tsx

Lines changed: 81 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { wrap } from '@suspensive/react'
22
import React from "react"
3+
import * as R from 'remeda'
34
import styled from 'styled-components'
45

56
import Page from "components/common/Page"
@@ -8,6 +9,12 @@ import { useNavigate } from 'react-router'
89
import { useListSessionsQuery } from 'utils/hooks/useAPI'
910
import useTranslation from "utils/hooks/useTranslation"
1011

12+
const ENABLE_DETAILS = false
13+
14+
const TD_HEIGHT = 2.5
15+
const TD_WIDTH = 12.5
16+
const TD_WIDTH_MOBILE = 20
17+
1118
type TimeTableData = {
1219
[date: string]: {
1320
[time: string]: {
@@ -83,10 +90,11 @@ const getTimeTableData: (data: APIPretalxSessions) => TimeTableData = (data) =>
8390
return timeTableData
8491
}
8592

86-
const SessionColumn: React.FC<{ rowSpan: number, session: APIPretalxSessions[0] }> = ({ rowSpan, session }) => {
93+
const SessionColumn: React.FC<{ rowSpan: number, colSpan?: number, session: APIPretalxSessions[0] }> = ({ rowSpan, colSpan, session }) => {
8794
const navigate = useNavigate()
88-
return <td rowSpan={rowSpan}>
89-
<SessionBox onClick={() => navigate(`/session/${session.code}`)}>
95+
const clickable = ENABLE_DETAILS && R.isArray(session.speakers) && !R.isEmpty(session.speakers)
96+
return <td rowSpan={rowSpan} colSpan={colSpan}>
97+
<SessionBox onClick={() => clickable && navigate(`/session/${session.code}`)} className={clickable ? 'clickable' : ''}>
9098
<h6>{session.title}</h6>
9199
<SessionSpeakerContainer>
92100
{session.speakers.map((speaker) => <kbd key={speaker.code}>{speaker.name}</kbd>)}
@@ -95,15 +103,6 @@ const SessionColumn: React.FC<{ rowSpan: number, session: APIPretalxSessions[0]
95103
</td>
96104
}
97105

98-
const BreakColumn: React.FC<{ colSpan: number, hideText?: boolean }> = ({ colSpan, hideText }) => {
99-
const t = useTranslation()
100-
return <td colSpan={colSpan}>
101-
<small style={{ color: 'rgba(255, 255, 255, 0.5)' }}>{!hideText && t('휴식')}</small>
102-
</td>
103-
}
104-
105-
const BlankColumn: React.FC = () => <td></td>
106-
107106
export const SessionTimeTablePage: React.FC = () => {
108107
const t = useTranslation()
109108

@@ -123,11 +122,13 @@ export const SessionTimeTablePage: React.FC = () => {
123122
const timeTableData = getTimeTableData(data)
124123
const dates = Object.keys(timeTableData).sort((a, b) => new Date(a).getTime() - new Date(b).getTime())
125124
const rooms: { [room: string]: number } = getRooms(data).reduce((acc, room) => ({ ...acc, [room]: 0 }), {})
126-
const sortedRoomList = Object.keys(rooms).sort()
127125
const roomCount = Object.keys(rooms).length
126+
const sortedRoomList = Object.keys(rooms).sort()
128127

129128
const selectedDate = confDate || dates[0]
130129
const selectedTableData = timeTableData[selectedDate]
130+
131+
let breakCount = 0
131132
return <>
132133
<hr />
133134
<SessionDateTabContainer>
@@ -151,24 +152,59 @@ export const SessionTimeTablePage: React.FC = () => {
151152
<tr><td colSpan={roomCount + 1}></td></tr>
152153
{
153154
Object.entries(selectedTableData).map(([time, roomData], i, a) => {
155+
const hasSession = Object.values(rooms).some((c) => c >= 1) || Object.values(roomData).some((room) => room !== undefined)
156+
157+
if (!hasSession) {
158+
if (breakCount > 1) {
159+
breakCount--
160+
return <tr></tr>
161+
} else {
162+
// 지금부터 다음 세션이 존재하기 전까지의 휴식 시간을 계산합니다.
163+
breakCount = 1
164+
for (let bi = i + 1; bi < a.length; bi++) {
165+
if (Object.values(a[bi][1]).some((room) => room !== undefined)) break
166+
breakCount += 1
167+
}
168+
169+
// I really hate this, but I can't think of a better way to do this.
170+
const height = TD_HEIGHT * breakCount / (breakCount <= 2 ? 1 : 3)
171+
return <tr>
172+
<td style={{ height: `${height}rem`, transform: `translateY(-${height / 2}rem)` }}>{time}</td>
173+
<td colSpan={roomCount + 1} rowSpan={breakCount} style={{ height: `${height}rem` }}>
174+
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
175+
{i !== a.length - 1 && <small style={{ color: 'rgba(255, 255, 255, 0.5)' }}>{t('휴식')}</small>}
176+
</div>
177+
</td>
178+
</tr>
179+
}
180+
}
181+
182+
// 만약 세션 타입이 아닌 발표가 존재하는 경우, 해당 줄에서는 colSpan이 roomCount인 column을 생성합니다.
183+
const nonSessionTypeData = Object.values(roomData).find((room) => room !== undefined && room.session.submission_type.en !== 'Session')
184+
if (nonSessionTypeData) {
185+
Object.keys(rooms).forEach((room) => rooms[room] = nonSessionTypeData.rowSpan - 1)
186+
return <tr>
187+
<td>{time}</td>
188+
<SessionColumn rowSpan={nonSessionTypeData.rowSpan} colSpan={roomCount} session={nonSessionTypeData.session} />
189+
</tr>
190+
}
191+
154192
return <tr>
155193
<td>{time}</td>
156194
{
157-
Object.values(rooms).some((c) => c >= 1) || Object.values(roomData).some((room) => room !== undefined)
158-
? sortedRoomList.map((room) => {
159-
const roomDatum = roomData[room]
160-
if (roomDatum === undefined) {
161-
// 진행 중인 세션이 없는 경우, 해당 줄에서는 해당 room의 빈 column을 생성합니다.
162-
if (rooms[room] <= 0) return <BlankColumn />
163-
// 진행 중인 세션이 있는 경우, 이번 줄에서는 해당 세션들만큼 column을 생성하지 않습니다.
164-
rooms[room] -= 1
165-
return null
166-
}
167-
// 세션이 여러 줄에 걸쳐있는 경우, n-1 줄만큼 해당 room에 column을 생성하지 않도록 합니다.
168-
if (roomDatum.rowSpan > 1) rooms[room] = roomDatum.rowSpan - 1
169-
return <SessionColumn key={room} rowSpan={roomDatum.rowSpan} session={roomDatum.session} />
170-
})
171-
: <BreakColumn colSpan={roomCount} hideText={i === a.length - 1} />
195+
sortedRoomList.map((room) => {
196+
const roomDatum = roomData[room]
197+
if (roomDatum === undefined) {
198+
// 진행 중인 세션이 없는 경우, 해당 줄에서는 해당 room의 빈 column을 생성합니다.
199+
if (rooms[room] <= 0) return <td></td>
200+
// 진행 중인 세션이 있는 경우, 이번 줄에서는 해당 세션들만큼 column을 생성하지 않습니다.
201+
rooms[room] -= 1
202+
return null
203+
}
204+
// 세션이 여러 줄에 걸쳐있는 경우, n-1 줄만큼 해당 room에 column을 생성하지 않도록 합니다.
205+
if (roomDatum.rowSpan > 1) rooms[room] = roomDatum.rowSpan - 1
206+
return <SessionColumn key={room} rowSpan={roomDatum.rowSpan} session={roomDatum.session} />
207+
})
172208
}
173209
</tr>
174210
})
@@ -189,9 +225,6 @@ export const SessionTimeTablePage: React.FC = () => {
189225
)
190226
}
191227

192-
const TD_HEIGHT = 2.5
193-
const TD_WIDTH = 12.5
194-
195228
const SessionDateTabContainer = styled.div`
196229
display: flex;
197230
gap: 2rem;
@@ -262,6 +295,17 @@ const SessionTable = styled.table`
262295
max-width: ${TD_WIDTH}vw;
263296
border-top: 1px solid rgba(255, 255, 255, 0.1);
264297
}
298+
299+
small {
300+
font-size: 0.8rem;
301+
}
302+
303+
@media only screen and (max-width: 810px) {
304+
td:not(:first-child) {
305+
width: ${TD_WIDTH_MOBILE}vw;
306+
max-width: ${TD_WIDTH_MOBILE}vw;
307+
}
308+
}
265309
`
266310

267311
const SessionBox = styled.div`
@@ -272,19 +316,21 @@ const SessionBox = styled.div`
272316
flex-direction: column;
273317
justify-content: center;
274318
align-items: center;
275-
border: 1px solid rgba(176, 168, 254, 0.75);
319+
border: 1px solid rgba(176, 168, 254, 0.3);
276320
border-radius: 0.5rem;
277321
278322
background-color: rgba(176, 168, 254, 0.1);
279323
font-size: 1rem;
280324
transition: all 0.25s ease;
281325
282-
cursor: pointer;
326+
&.clickable {
327+
cursor: pointer;
328+
}
283329
284330
h6 {
285331
margin: 0;
286332
color: rgba(255, 255, 255, 0.6);
287-
font-size: 0.9rem;
333+
font-size: 0.8rem;
288334
transition: all 0.25s ease;
289335
}
290336
@@ -300,6 +346,7 @@ const SessionBox = styled.div`
300346
}
301347
302348
&:hover {
349+
border: 1px solid rgba(176, 168, 254, 0.75);
303350
background-color: rgba(176, 168, 254, 0.25);
304351
transition: all 0.25s ease;
305352

0 commit comments

Comments
 (0)