1+ import { MOBILE_BREAKPOINT } from "../../../constants/BreakPoints" ;
2+ import { Color } from "../../../styles/colors" ;
3+ import React , { FC , useCallback , useEffect } from "react" ;
4+ import LessThanBlueIcon from "../../../assets/images/LessThanBlueIcon.svg" ;
5+ import MoreThanBlueIcon from "../../../assets/images/MoreThanBlueIcon.svg" ;
6+ import SectionWrapper from "../../../components/SectionWrapper/SectionWrapper" ;
7+ import TitleSection from "../../../components/SectionTitle/TitleSection" ;
8+ import { useWindowSize } from "react-use" ;
9+ import {
10+ SpeakersCardsContainer ,
11+ StyledContainerLeftSlash ,
12+ StyledContainerRightSlash ,
13+ StyledLessIcon ,
14+ StyledMoreIcon ,
15+ StyledSlash ,
16+ StyledSpeakersSection ,
17+ StyledWaveContainer ,
18+ } from "./Speakers.style" ;
19+ import Button from "../../../components/UI/Button" ;
20+ import { gaEventTracker } from "../../../components/analytics/Analytics" ;
21+ import { useFetchSpeakers } from "../../../hooks/useFetchSpeakers" ;
22+ import { ISpeaker } from "../../../types/speakers" ;
23+ import { SpeakerCard } from "../../../views/Speakers/components/SpeakersCard" ;
24+ import { useSentryErrorReport } from "../../../hooks/useSentryErrorReport" ;
25+
26+ const LessThanGreaterThan = ( ) => (
27+ < >
28+ < StyledLessIcon src = { LessThanBlueIcon } />
29+ < StyledMoreIcon src = { MoreThanBlueIcon } />
30+ </ >
31+ ) ;
32+
33+ interface SpeakersProps {
34+ year : string ;
35+ webData : any ;
36+ }
37+
38+ const Speakers : FC < SpeakersProps > = ( { year, webData } ) => {
39+ const { width } = useWindowSize ( ) ;
40+ const today = new Date ( ) ;
41+ const isBetween = ( startDay : Date , endDay : Date ) : boolean =>
42+ startDay < new Date ( ) && endDay > today ;
43+
44+ const { error, data, isLoading } = useFetchSpeakers ( year ) ;
45+
46+ useSentryErrorReport ( error ) ;
47+
48+ const trackCFP = useCallback ( ( ) => {
49+ gaEventTracker ( "CFP" , "CFP" ) ;
50+ } , [ ] ) ;
51+
52+ useEffect ( ( ) => {
53+ document . title = `Speakers — ${ webData . title } — ${ webData . edition } ` ;
54+ } , [ webData . title , webData . edition ] ) ;
55+
56+ const CFPStartDay = new Date ( webData . cfp . startDay ) ;
57+ const CFPEndDay = new Date ( webData . cfp . endDay ) ;
58+ return (
59+ < >
60+ < SectionWrapper color = { Color . DARK_BLUE } marginTop = { 5 } >
61+ < StyledSpeakersSection >
62+ < TitleSection
63+ title = "SPEAKERS"
64+ subtitle = "Speakers coming from all corners of the world join us to
65+ share their experience in various technologies and to
66+ invite everyone to participate in Open Source
67+ Technologies and in the JCP."
68+ color = { Color . WHITE }
69+ />
70+ { width > MOBILE_BREAKPOINT && < LessThanGreaterThan /> }
71+ < SpeakersCardsContainer >
72+ { isLoading && < p > Loading...</ p > }
73+ { isBetween ( CFPStartDay , CFPEndDay ) && (
74+ < div
75+ style = { {
76+ width : "100%" ,
77+ textAlign : "center" ,
78+ padding : "20px 30%" ,
79+ } }
80+ >
81+ < Button
82+ onClick = { trackCFP }
83+ text = "📢 Apply to be a Speaker"
84+ link = { webData . cfp . link }
85+ />
86+ </ div >
87+ ) }
88+ { webData . hideSpeakers ? (
89+ < p style = { { color : Color . WHITE } } >
90+ No selected speakers yet. Keep in touch in our social media for
91+ upcoming announcements
92+ </ p >
93+ ) : data ?. length === 0 ? (
94+ < p style = { { color : Color . WHITE } } >
95+ No selected speakers yet. Keep in touch in our social media for
96+ upcoming announcements
97+ </ p >
98+ ) : (
99+ data ?. map ( ( speaker : ISpeaker ) => (
100+ < SpeakerCard
101+ key = { speaker . id }
102+ year = { webData . edition }
103+ speaker = { speaker }
104+ />
105+ ) )
106+ ) }
107+ </ SpeakersCardsContainer >
108+ < StyledContainerRightSlash
109+ initial = { { x : "100%" } }
110+ animate = { { x : 0 } }
111+ transition = { { duration : 4 } }
112+ positionPercentage = "20%"
113+ >
114+ < StyledSlash color = { Color . YELLOW } >
115+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
116+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
117+ /{ " " }
118+ </ StyledSlash >
119+ </ StyledContainerRightSlash >
120+
121+ < StyledContainerLeftSlash
122+ initial = { { x : "-100%" } }
123+ animate = { { x : 0 } }
124+ transition = { { duration : 4 } }
125+ positionPercentage = "40%"
126+ >
127+ < StyledSlash color = { Color . DARK_BLUE } >
128+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
129+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
130+ /{ " " }
131+ </ StyledSlash >
132+ </ StyledContainerLeftSlash >
133+
134+ < StyledContainerRightSlash
135+ initial = { { x : "100%" } }
136+ animate = { { x : 0 } }
137+ transition = { { duration : 4 } }
138+ positionPercentage = "60%"
139+ >
140+ < StyledSlash color = { Color . BLUE } >
141+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
142+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
143+ /{ " " }
144+ </ StyledSlash >
145+ </ StyledContainerRightSlash >
146+
147+ < StyledContainerLeftSlash
148+ initial = { { x : "-100%" } }
149+ animate = { { x : 0 } }
150+ transition = { { duration : 4 } }
151+ positionPercentage = "80%"
152+ >
153+ < StyledSlash color = { Color . YELLOW } >
154+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
155+ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
156+ /{ " " }
157+ </ StyledSlash >
158+ </ StyledContainerLeftSlash >
159+ </ StyledSpeakersSection >
160+ </ SectionWrapper >
161+ < StyledWaveContainer >
162+ < svg
163+ viewBox = "0 0 500 150"
164+ preserveAspectRatio = "none"
165+ style = { { height : "100%" , width : "100%" } }
166+ >
167+ < path
168+ d = "M-8.17,75.50 C207.95,-129.75 329.85,202.80 500.27,5.45 L501.41,-5.41 L0.00,0.00 Z"
169+ style = { { stroke : "none" , fill : "#002454" } }
170+ > </ path >
171+ </ svg >
172+ </ StyledWaveContainer >
173+ </ >
174+ ) ;
175+ } ;
176+
177+ export default Speakers ;
0 commit comments