1
- import React , { FC , useCallback , useMemo , useRef } from 'react' ;
1
+ import React , { FC , useCallback , useMemo , useRef , useState } from 'react' ;
2
2
import { useSWRInfinite } from 'swr' ;
3
3
4
4
import { fetcher , ListResponse } from 'common/fetcher' ;
5
- import { getCourseListApiUrl } from 'common/urls' ;
5
+ import { getCourseListApiUrl , getDepartmentListApiUrl , getFacultyListApiUrl } from 'common/urls' ;
6
6
import { useQueryParam } from 'common/hooks/useQueryParam' ;
7
7
import { useIsomorphicLayoutEffect } from 'common/hooks/useIsomorphicLayoutEffect' ;
8
8
import { CourseListView } from 'views/CourseListView' ;
9
- import { Course } from 'models/Course' ;
9
+ import { Course , CourseSort , COURSE_ORDERING } from 'models/Course' ;
10
+ import { GetStaticProps } from 'next' ;
11
+ import { Department } from 'models/Department' ;
12
+ import { Faculty } from 'models/Faculty' ;
13
+
14
+ interface StaticProps {
15
+ departments : Department [ ] ;
16
+ faculties : Faculty [ ] ;
17
+ }
10
18
11
19
const PAGE_SIZE = 20 ;
12
20
13
- const getSearchUrlPaginatedGetter = ( query : string ) => (
14
- pageNumber : number ,
15
- previousPageData : ListResponse < Course > | null
16
- ) => {
21
+ const getSearchUrlPaginatedGetter = (
22
+ query : string ,
23
+ sortOrder : CourseSort ,
24
+ departmentFilter : number | null ,
25
+ facultyFilter : number | null
26
+ ) => ( pageNumber : number , previousPageData : ListResponse < Course > | null ) => {
17
27
if ( previousPageData && ! previousPageData ?. results . length ) return null ;
18
28
const offset = pageNumber * PAGE_SIZE ;
19
- const ordering = '-watson_rank,-attendee_count' ;
29
+ const ordering = COURSE_ORDERING [ sortOrder ] ?? COURSE_ORDERING [ 'ranking' ] ;
20
30
return getCourseListApiUrl ( {
21
31
limit : PAGE_SIZE ,
22
32
offset,
23
33
query,
24
34
ordering,
35
+ facultyId : facultyFilter ?? undefined ,
36
+ departmentId : departmentFilter ?? undefined ,
25
37
} ) ;
26
38
} ;
27
39
28
- const CourseListPage : FC = ( ) => {
40
+ const CourseListPage : FC < StaticProps > = ( { departments , faculties } ) => {
29
41
const searchBarRef = useRef < HTMLInputElement | null > ( null ) ;
30
42
const [ queryParam , setQuery ] = useQueryParam ( 'query' , '' ) ;
43
+ const [ sortOrder , setSortOrder ] = useState < CourseSort > ( 'ranking' ) ;
44
+ const [ departmentId , setDepartmentId ] = useState < number | null > ( null ) ;
45
+ const [ facultyId , setFacultyId ] = useState < number | null > ( null ) ;
31
46
const query = Array . isArray ( queryParam ) ? queryParam . join ( ',' ) : queryParam ;
32
- const getSearchUrl = useMemo ( ( ) => getSearchUrlPaginatedGetter ( query ) , [ query ] ) ;
47
+ const getSearchUrl = useMemo ( ( ) => getSearchUrlPaginatedGetter ( query , sortOrder , departmentId , facultyId ) , [
48
+ query ,
49
+ sortOrder ,
50
+ departmentId ,
51
+ facultyId ,
52
+ ] ) ;
33
53
const { data, isValidating, setSize } = useSWRInfinite < ListResponse < Course > > ( getSearchUrl , fetcher ) ;
34
54
35
55
const nextPage = useCallback ( ( ) => setSize ( ( currentSize ) => currentSize + 1 ) , [ ] ) ;
@@ -46,6 +66,14 @@ const CourseListPage: FC = () => {
46
66
return (
47
67
< CourseListView
48
68
searchBarRef = { searchBarRef }
69
+ onOrderingChange = { setSortOrder }
70
+ currentOrdering = { sortOrder }
71
+ onFacultyFilterChange = { setFacultyId }
72
+ onDepartmentFilterChange = { setDepartmentId }
73
+ departments = { departments }
74
+ currentDepartmentId = { departmentId }
75
+ faculties = { faculties }
76
+ currentFacultyId = { facultyId }
49
77
query = { query }
50
78
onSearchChange = { setQuery }
51
79
courses = { courses }
@@ -56,4 +84,20 @@ const CourseListPage: FC = () => {
56
84
) ;
57
85
} ;
58
86
87
+ export const getStaticProps : GetStaticProps < StaticProps > = async ( ) => {
88
+ const [ departmentsResponse , facultiesResponse ] = await Promise . all ( [
89
+ fetcher < ListResponse < Department > > ( getDepartmentListApiUrl ( ) ) ,
90
+ fetcher < ListResponse < Faculty > > ( getFacultyListApiUrl ( ) ) ,
91
+ ] ) ;
92
+ const departments = departmentsResponse . results ;
93
+ const faculties = facultiesResponse . results ;
94
+ return {
95
+ revalidate : 60 * 60 , // Revalidate once each hour.
96
+ props : {
97
+ departments,
98
+ faculties,
99
+ } ,
100
+ } ;
101
+ } ;
102
+
59
103
export default CourseListPage ;
0 commit comments