1
1
import React , { useCallback , useEffect } from "react" ;
2
2
import { RouteComponentProps , withRouter } from "react-router" ;
3
- import { Card , Col , Container , Row } from "reactstrap" ;
3
+ import { Button , Card , Col , Container , Row } from "reactstrap" ;
4
4
import { TitleAndBreadcrumb } from "../elements/TitleAndBreadcrumb" ;
5
- import { getHumanContext , isDefinedContext , isSingleStageContext , useUrlPageTheme } from "../../services/pageContext" ;
5
+ import { getHumanContext , isFullyDefinedContext , isSingleStageContext , useUrlPageTheme } from "../../services/pageContext" ;
6
6
import { ListView , ListViewCards } from "../elements/list-groups/ListView" ;
7
7
import { getBooksForContext , getLandingPageCardsForContext } from "./subjectLandingPageComponents" ;
8
8
import { above , below , DOCUMENT_TYPE , EventStatusFilter , EventTypeFilter , STAGE , useDeviceSize } from "../../services" ;
@@ -50,7 +50,7 @@ const RandomQuestionBanner = ({context}: {context?: PageContextState}) => {
50
50
searchDebounce ( ) ;
51
51
} , [ searchDebounce ] ) ;
52
52
53
- if ( ! context || ! isDefinedContext ( context ) || ! isSingleStageContext ( context ) ) {
53
+ if ( ! context || ! isFullyDefinedContext ( context ) || ! isSingleStageContext ( context ) ) {
54
54
return null ;
55
55
}
56
56
@@ -106,18 +106,86 @@ const RandomQuestionBanner = ({context}: {context?: PageContextState}) => {
106
106
</ div > ;
107
107
} ;
108
108
109
- export const SubjectLandingPage = withRouter ( ( props : RouteComponentProps ) => {
110
- const pageContext = useUrlPageTheme ( ) ;
111
- const deviceSize = useDeviceSize ( ) ;
112
-
109
+ export const LandingPageFooter = ( { context} : { context : PageContextState } ) => {
113
110
const [ getEventsList , eventsQuery ] = useLazyGetEventsQuery ( ) ;
114
111
useEffect ( ( ) => {
115
112
getEventsList ( { startIndex : 0 , limit : 10 , typeFilter : EventTypeFilter [ "All events" ] , statusFilter : EventStatusFilter [ "Upcoming events" ] , stageFilter : [ STAGE . ALL ] } ) ;
116
113
} , [ ] ) ;
117
114
118
- const books = getBooksForContext ( pageContext ) ;
115
+ const books = getBooksForContext ( context ) ;
119
116
// TODO: are we going to make subject-specific news?
120
117
const { data : news } = useGetNewsPodListQuery ( { subject : "physics" } ) ;
118
+
119
+ return < Row className = { classNames ( "mt-5 py-4 row-cols-1 row-cols-md-2" ) } >
120
+ < div className = "d-flex flex-column mt-3" >
121
+ { /* if there are books, display books. otherwise, display news */ }
122
+ { books . length > 0
123
+ ? < >
124
+ < div className = "d-flex mb-3 align-items-center gap-4 white-space-pre" >
125
+ < h4 className = "m-0" > { getHumanContext ( context ) } books</ h4 >
126
+ < div className = "section-divider-bold" />
127
+ </ div >
128
+ < Col className = "d-flex flex-column" >
129
+ { books . slice ( 0 , 2 ) . map ( ( book , index ) => < Link key = { index } to = { book . path } className = "book-container d-flex p-2 gap-3" >
130
+ < div className = "book-image-container" >
131
+ < img src = { book . image } alt = { book . title } className = "h-100" />
132
+ </ div >
133
+ < div className = "d-flex flex-column" >
134
+ < h5 className = "pt-2 pt-2 pb-1 m-0" > { book . title } </ h5 >
135
+ < div className = "section-divider" />
136
+ < span className = "text-decoration-none" >
137
+ This is some explanatory text about the book. It could be a brief description of the book, or a list of topics covered.
138
+ </ span >
139
+ </ div >
140
+ </ Link > ) }
141
+ { books . length > 2 && < Button tag = { Link } color = "keyline" to = { `/publications` } className = "btn mt-4 mx-5" > View more books</ Button > }
142
+ </ Col >
143
+ </ >
144
+ : < >
145
+ < div className = "d-flex flex-column" >
146
+ < div className = "d-flex mb-3 align-items-center gap-4 white-space-pre" >
147
+ < h4 > News & Features </ h4 >
148
+ < div className = "section-divider-bold" />
149
+ </ div >
150
+ { news && < Row className = "h-100" >
151
+ { news . slice ( 0 , 2 ) . map ( newsItem => < Col xs = { 12 } key = { newsItem . id } >
152
+ < NewsCard newsItem = { newsItem } className = "force-horizontal p-2" />
153
+ </ Col > ) }
154
+ </ Row > }
155
+ </ div >
156
+ </ >
157
+ }
158
+ </ div >
159
+ < div className = "d-flex flex-column mt-3" >
160
+ < div className = "d-flex mb-3 align-items-center gap-4 white-space-pre" >
161
+ < h4 className = "m-0" > Events</ h4 >
162
+ < div className = "section-divider-bold" />
163
+ </ div >
164
+ < ShowLoadingQuery
165
+ query = { eventsQuery }
166
+ defaultErrorTitle = { "Error loading events list" }
167
+ thenRender = { ( { events} ) => {
168
+ // TODO: filter by audience, once that data is available
169
+ const relevantEvents = events . filter ( event => context ?. subject && event . tags ?. includes ( context . subject ) ) . slice ( 0 , 2 ) ;
170
+ return < Row className = "h-100" >
171
+ { relevantEvents . length
172
+ ? relevantEvents . map ( ( event , i ) =>
173
+ < Col xs = { 12 } key = { i } >
174
+ { event && < EventCard event = { event } className = "force-horizontal p-2" /> }
175
+ </ Col >
176
+ )
177
+ : < Col className = "pt-3 pb-5" > No events found for { getHumanContext ( context ) } . Check back soon!</ Col >
178
+ }
179
+ </ Row > ;
180
+ } }
181
+ />
182
+ </ div >
183
+ </ Row > ;
184
+ } ;
185
+
186
+ export const SubjectLandingPage = withRouter ( ( props : RouteComponentProps ) => {
187
+ const pageContext = useUrlPageTheme ( ) ;
188
+ const deviceSize = useDeviceSize ( ) ;
121
189
122
190
return < Container data-bs-theme = { pageContext ?. subject } >
123
191
< TitleAndBreadcrumb
@@ -133,69 +201,8 @@ export const SubjectLandingPage = withRouter((props: RouteComponentProps) => {
133
201
134
202
< ListViewCards cards = { getLandingPageCardsForContext ( pageContext , below [ 'md' ] ( deviceSize ) ) } showBlanks = { ! below [ 'md' ] ( deviceSize ) } className = "my-5" />
135
203
136
- < Row className = { classNames ( "mt-5 py-4 row-cols-1 row-cols-md-2" ) } >
137
- < div className = "d-flex flex-column mt-3" >
138
- { /* if there are books, display books. otherwise, display news */ }
139
- { books . length > 0
140
- ? < >
141
- < div className = "d-flex mb-3 align-items-center gap-4 white-space-pre" >
142
- < h4 className = "m-0" > { getHumanContext ( pageContext ) } books</ h4 >
143
- < div className = "section-divider-bold" />
144
- </ div >
145
- < Col className = "d-flex flex-column" >
146
- { books . slice ( 0 , 4 ) . map ( ( book , index ) => < Link key = { index } to = { book . path } className = "book-container d-flex p-2 gap-3" >
147
- < div className = "book-image-container" >
148
- < img src = { book . image } alt = { book . title } className = "h-100" />
149
- </ div >
150
- < div className = "d-flex flex-column" >
151
- < h5 className = "pt-2 pt-2 pb-1 m-0" > { book . title } </ h5 >
152
- < div className = "section-divider" />
153
- < span className = "text-decoration-none" >
154
- This is some explanatory text about the book. It could be a brief description of the book, or a list of topics covered.
155
- </ span >
156
- </ div >
157
- </ Link > ) }
158
- </ Col >
159
- </ >
160
- : < >
161
- < div className = "d-flex flex-column" >
162
- < div className = "d-flex mb-3 align-items-center gap-4 white-space-pre" >
163
- < h4 > News & Features </ h4 >
164
- < div className = "section-divider-bold" />
165
- </ div >
166
- { news && < Row className = "h-100" >
167
- { news . slice ( 0 , 2 ) . map ( newsItem => < Col xs = { 12 } key = { newsItem . id } >
168
- < NewsCard newsItem = { newsItem } className = "force-horizontal p-2" />
169
- </ Col > ) }
170
- </ Row > }
171
- </ div >
172
- </ >
173
- }
174
- </ div >
175
- < div className = "d-flex flex-column mt-3" >
176
- < div className = "d-flex mb-3 align-items-center gap-4 white-space-pre" >
177
- < h4 className = "m-0" > Events</ h4 >
178
- < div className = "section-divider-bold" />
179
- </ div >
180
- < ShowLoadingQuery
181
- query = { eventsQuery }
182
- defaultErrorTitle = { "Error loading events list" }
183
- thenRender = { ( { events} ) => {
184
- // TODO: filter by audience, once that data is available
185
- const relevantEvents = events . filter ( event => pageContext ?. subject && event . tags ?. includes ( pageContext . subject ) ) . slice ( 0 , 2 ) ;
186
- return < Row className = "h-100" >
187
- { relevantEvents . length
188
- ? relevantEvents . map ( ( event , i ) =>
189
- < Col key = { i } >
190
- { event && < EventCard event = { event } className = "force-horizontal p-2" /> }
191
- </ Col >
192
- )
193
- : < Col className = "pt-3 pb-5" > No events found for { getHumanContext ( pageContext ) } . Check back soon!</ Col >
194
- }
195
- </ Row > ;
196
- } }
197
- />
198
- </ div >
199
- </ Row >
204
+ < LandingPageFooter context = { pageContext } />
205
+
206
+
200
207
</ Container > ;
201
208
} ) ;
0 commit comments