1
- import { wrap } from '@suspensive/react'
2
- import React from "react"
3
- import Markdown from 'react-markdown'
4
- import * as R from 'remeda'
5
-
6
- import { SloganShort } from 'assets/icons'
7
- import { FallbackImg } from 'components/common/FallbackImg'
8
- import Page from "components/common/Page"
9
- import { APIPretalxSessions } from 'models/api/session'
10
- import { useNavigate , useParams } from 'react-router'
11
- import styled from 'styled-components'
12
- import { useRetriveSessionQuery } from 'utils/hooks/useAPI'
13
- import useTranslation from "utils/hooks/useTranslation"
14
-
15
- const SessionSpeakerItem : React . FC < { speaker : APIPretalxSessions [ 0 ] [ 'speakers' ] [ 0 ] } > = ( { speaker } ) => {
1
+ import { wrap } from "@suspensive/react" ;
2
+ import React from "react" ;
3
+ import Markdown from "react-markdown" ;
4
+ import * as R from "remeda" ;
5
+
6
+ import { SloganShort } from "assets/icons" ;
7
+ import { FallbackImg } from "components/common/FallbackImg" ;
8
+ import Page from "components/common/Page" ;
9
+ import { APIPretalxSessions } from "models/api/session" ;
10
+ import { useNavigate , useParams } from "react-router" ;
11
+ import styled from "styled-components" ;
12
+ import { useRetrieveSessionQuery } from "utils/hooks/useAPI" ;
13
+ import useTranslation from "utils/hooks/useTranslation" ;
14
+
15
+ const SessionSpeakerItem : React . FC < { speaker : APIPretalxSessions [ 0 ] [ "speakers" ] [ 0 ] } > = ( {
16
+ speaker,
17
+ } ) => {
16
18
return (
17
19
< SessionSpeakerItemStyled >
18
20
< SessionSpeakerImageContainerStyled >
19
- < FallbackImg src = { speaker . avatar ?? '' } alt = { speaker . name } errorFallback = { < SloganShort /> } />
21
+ < FallbackImg
22
+ src = { speaker . avatar ?? "" }
23
+ alt = { speaker . name }
24
+ errorFallback = { < SloganShort /> }
25
+ />
20
26
</ SessionSpeakerImageContainerStyled >
21
27
< div >
22
28
< h3 > { speaker . name } </ h3 >
23
29
< Markdown > { speaker . biography } </ Markdown >
24
30
</ div >
25
31
</ SessionSpeakerItemStyled >
26
- )
27
- }
32
+ ) ;
33
+ } ;
28
34
29
35
const SessionDetail : React . FC < { session : APIPretalxSessions [ 0 ] } > = ( { session } ) => {
30
- const t = useTranslation ( )
36
+ const t = useTranslation ( ) ;
31
37
32
- let locale = ' 알 수 없음'
38
+ let locale = " 알 수 없음" ;
33
39
switch ( session . content_locale ) {
34
- case 'ko' :
35
- locale = ' 한국어'
40
+ case "ko" :
41
+ locale = " 한국어" ;
36
42
break ;
37
- case 'en' :
38
- locale = '영어'
43
+ case "en" :
44
+ locale = "영어" ;
39
45
break ;
40
- case 'ja' :
41
- locale = ' 일본어'
46
+ case "ja" :
47
+ locale = " 일본어" ;
42
48
break ;
43
49
default :
44
- locale = ' 알 수 없음'
50
+ locale = " 알 수 없음" ;
45
51
}
46
52
47
53
return (
@@ -50,61 +56,75 @@ const SessionDetail: React.FC<{ session: APIPretalxSessions[0] }> = ({ session }
50
56
< h4 > { session . abstract } </ h4 >
51
57
< hr />
52
58
< SessionInfoContainerStyled >
53
- < p > { t ( '언어' ) } : { t ( locale ) } </ p >
54
- < p > { t ( '발표 시간' ) } : { session . duration } { t ( '분' ) } </ p >
55
- < p > { t ( '발표 장소' ) } : { t ( session . slot ?. room [ Object . keys ( session . slot ?. room ?? { } ) [ 0 ] ] ?? '알 수 없음' ) } </ p >
59
+ < p >
60
+ { t ( "언어" ) } : { t ( locale ) }
61
+ </ p >
62
+ < p >
63
+ { t ( "발표 시간" ) } : { session . duration }
64
+ { t ( "분" ) }
65
+ </ p >
66
+ < p >
67
+ { t ( "발표 장소" ) } :{ " " }
68
+ { t ( session . slot ?. room [ Object . keys ( session . slot ?. room ?? { } ) [ 0 ] ] ?? "알 수 없음" ) }
69
+ </ p >
56
70
< p >
57
71
< TagContainer >
58
- < div style = { { margin : 0 } } > { t ( '태그' ) } :</ div >
59
- { session . tags . map ( tag => < Tag key = { tag } > { t ( tag ) } </ Tag > ) }
60
- { session . do_not_record && < Tag > { t ( '녹화 불가' ) } </ Tag > }
72
+ < div style = { { margin : 0 } } > { t ( "태그" ) } :</ div >
73
+ { session . tags . map ( ( tag ) => (
74
+ < Tag key = { tag } > { t ( tag ) } </ Tag >
75
+ ) ) }
76
+ { session . do_not_record && < Tag > { t ( "녹화 불가" ) } </ Tag > }
61
77
</ TagContainer >
62
78
</ p >
63
79
</ SessionInfoContainerStyled >
64
80
< hr />
65
- < h3 > { t ( '설명' ) } </ h3 >
81
+ < h3 > { t ( "설명" ) } </ h3 >
66
82
< Markdown > { session . description } </ Markdown >
67
83
< hr />
68
- < h3 > { t ( '발표자 소개' ) } </ h3 >
69
- { session . speakers . map ( speaker => < SessionSpeakerItem speaker = { speaker } key = { speaker . code } /> ) }
84
+ < h3 > { t ( "발표자 소개" ) } </ h3 >
85
+ { session . speakers . map ( ( speaker ) => (
86
+ < SessionSpeakerItem speaker = { speaker } key = { speaker . code } />
87
+ ) ) }
70
88
< hr />
71
89
</ SessionDetailStyled >
72
- )
73
- }
90
+ ) ;
91
+ } ;
74
92
75
93
export const SessionDetailPage : React . FC = ( ) => {
76
- const t = useTranslation ( )
77
- const { code } = useParams < { code : string } > ( )
78
- const navigate = useNavigate ( )
94
+ const t = useTranslation ( ) ;
95
+ const { code } = useParams < { code : string } > ( ) ;
96
+ const navigate = useNavigate ( ) ;
79
97
80
- React . useEffect ( ( ) => window . scrollTo ( 0 , 0 ) , [ ] )
98
+ React . useEffect ( ( ) => window . scrollTo ( 0 , 0 ) , [ ] ) ;
81
99
82
100
if ( ! ( R . isString ( code ) && ! R . isEmpty ( code ) ) ) {
83
- navigate ( ' /session' )
84
- return null
101
+ navigate ( " /session" ) ;
102
+ return null ;
85
103
}
86
104
87
105
const SessionDetailWrapper = wrap
88
106
. ErrorBoundary ( { fallback : < h4 > { t ( "세션 정보를 불러오는 중 에러가 발생했습니다." ) } </ h4 > } )
89
107
. Suspense ( { fallback : < h4 > { t ( "세션 정보를 불러오는 중 입니다." ) } </ h4 > } )
90
108
. on ( ( ) => {
91
109
// eslint-disable-next-line react-hooks/rules-of-hooks
92
- const { data } = useRetriveSessionQuery ( code )
93
- return < SessionDetail session = { data } />
94
- } )
110
+ const { data } = useRetrieveSessionQuery ( code ) ;
111
+ return < SessionDetail session = { data } /> ;
112
+ } ) ;
95
113
96
114
return (
97
115
< Page >
98
- < ReturnToSessionList onClick = { ( ) => navigate ( - 1 ) } > ⬅️ { t ( '세션 목록으로 돌아가기' ) } </ ReturnToSessionList >
116
+ < ReturnToSessionList onClick = { ( ) => navigate ( - 1 ) } >
117
+ ⬅️ { t ( "세션 목록으로 돌아가기" ) }
118
+ </ ReturnToSessionList >
99
119
< SessionDetailWrapper />
100
120
</ Page >
101
- )
102
- }
121
+ ) ;
122
+ } ;
103
123
104
124
const ReturnToSessionList = styled . small `
105
125
color: rgba(255, 255, 255, 0.4);
106
126
cursor: pointer;
107
- `
127
+ ` ;
108
128
109
129
const SessionDetailStyled = styled . div `
110
130
h1 {
@@ -126,13 +146,13 @@ const SessionDetailStyled = styled.div`
126
146
font-size: 1rem;
127
147
}
128
148
}
129
- `
149
+ ` ;
130
150
131
151
const SessionInfoContainerStyled = styled . div `
132
152
* {
133
153
margin: 0.5rem 0;
134
154
}
135
- `
155
+ ` ;
136
156
137
157
const SessionSpeakerItemStyled = styled . div `
138
158
display: flex;
@@ -145,7 +165,7 @@ const SessionSpeakerItemStyled = styled.div`
145
165
margin-top: 0;
146
166
color: #fff;
147
167
}
148
- `
168
+ ` ;
149
169
150
170
const SessionSpeakerImageContainerStyled = styled . div `
151
171
flex: 0 0 auto;
@@ -170,17 +190,17 @@ const SessionSpeakerImageContainerStyled = styled.div`
170
190
171
191
border-radius: 50%;
172
192
}
173
- `
193
+ ` ;
174
194
175
195
const TagContainer = styled . div `
176
196
display: flex;
177
197
align-items: center;
178
198
justify-content: flex-start;
179
199
gap: 0.5rem;
180
- `
200
+ ` ;
181
201
182
202
const Tag = styled . kbd `
183
203
margin: 0;
184
204
background-color: #b0a8fe;
185
205
font-family: var(--pico-font-family);
186
- `
206
+ ` ;
0 commit comments