@@ -10,145 +10,168 @@ import { CourseGQLData, ProfessorGQLData, ReviewData, VoteColorsRequest, VoteCol
10
10
import { Checkbox , Dropdown } from 'semantic-ui-react' ;
11
11
12
12
export interface ReviewProps {
13
- course ?: CourseGQLData ;
14
- professor ?: ProfessorGQLData ;
13
+ course ?: CourseGQLData ;
14
+ professor ?: ProfessorGQLData ;
15
15
}
16
16
17
17
enum SortingOption {
18
- MOST_RECENT ,
19
- TOP_REVIEWS ,
20
- CONTROVERSIAL
18
+ MOST_RECENT ,
19
+ TOP_REVIEWS ,
20
+ CONTROVERSIAL ,
21
21
}
22
22
23
23
const Review : FC < ReviewProps > = ( props ) => {
24
- const dispatch = useAppDispatch ( ) ;
25
- const reviewData = useAppSelector ( selectReviews ) ;
26
- const [ voteColors , setVoteColors ] = useState ( [ ] ) ;
27
- const [ sortingOption , setSortingOption ] = useState < SortingOption > ( SortingOption . MOST_RECENT ) ;
28
- const [ showOnlyVerifiedReviews , setShowOnlyVerifiedReviews ] = useState ( false ) ;
24
+ const dispatch = useAppDispatch ( ) ;
25
+ const reviewData = useAppSelector ( selectReviews ) ;
26
+ const [ voteColors , setVoteColors ] = useState ( [ ] ) ;
27
+ const [ sortingOption , setSortingOption ] = useState < SortingOption > ( SortingOption . MOST_RECENT ) ;
28
+ const [ showOnlyVerifiedReviews , setShowOnlyVerifiedReviews ] = useState ( false ) ;
29
29
30
- const getColors = async ( vote : VoteColorsRequest ) => {
31
- const res = await axios . patch ( '/api/reviews/getVoteColors' , vote ) ;
32
- return res . data ;
33
- }
30
+ const getColors = async ( vote : VoteColorsRequest ) => {
31
+ const res = await axios . patch ( '/api/reviews/getVoteColors' , vote ) ;
32
+ return res . data ;
33
+ } ;
34
34
35
- const getReviews = async ( ) => {
36
- interface paramsProps {
37
- courseID ?: string ;
38
- professorID ?: string ;
39
- }
40
- const params : paramsProps = { } ;
41
- if ( props . course ) params . courseID = props . course . id ;
42
- if ( props . professor ) params . professorID = props . professor . ucinetid ;
43
- axios . get ( `/api/reviews` , {
44
- params : params
45
- } )
46
- . then ( async ( res : AxiosResponse < ReviewData [ ] > ) => {
47
- const data = res . data . filter ( ( review ) => review !== null ) ;
48
- const reviewIDs = [ ] ;
49
- for ( let i = 0 ; i < data . length ; i ++ ) {
50
- reviewIDs . push ( data [ i ] . _id ) ;
51
- }
52
- const req = {
53
- ids : reviewIDs as string [ ]
54
- }
55
- const colors = await getColors ( req ) ;
56
- setVoteColors ( colors ) ;
57
- dispatch ( setReviews ( data ) ) ;
58
- } ) ;
35
+ const getReviews = async ( ) => {
36
+ interface paramsProps {
37
+ courseID ?: string ;
38
+ professorID ?: string ;
59
39
}
60
-
61
- const updateVoteColors = async ( ) => {
40
+ const params : paramsProps = { } ;
41
+ if ( props . course ) params . courseID = props . course . id ;
42
+ if ( props . professor ) params . professorID = props . professor . ucinetid ;
43
+ axios
44
+ . get ( `/api/reviews` , {
45
+ params : params ,
46
+ } )
47
+ . then ( async ( res : AxiosResponse < ReviewData [ ] > ) => {
48
+ const data = res . data . filter ( ( review ) => review !== null ) ;
62
49
const reviewIDs = [ ] ;
63
- for ( let i = 0 ; i < reviewData . length ; i ++ ) {
64
- reviewIDs . push ( reviewData [ i ] . _id ) ;
50
+ for ( let i = 0 ; i < data . length ; i ++ ) {
51
+ reviewIDs . push ( data [ i ] . _id ) ;
65
52
}
66
53
const req = {
67
- ids : reviewIDs as string [ ]
68
- }
54
+ ids : reviewIDs as string [ ] ,
55
+ } ;
69
56
const colors = await getColors ( req ) ;
70
57
setVoteColors ( colors ) ;
71
- }
58
+ dispatch ( setReviews ( data ) ) ;
59
+ } ) ;
60
+ } ;
72
61
73
- const getU = ( id : string | undefined ) => {
74
- const temp = voteColors as object ;
75
- const v = ( temp [ id as keyof typeof temp ] ) as unknown as number ;
76
- if ( v == 1 ) {
77
- return {
78
- colors : [ true , false ]
79
- }
80
- } else if ( v == - 1 ) {
81
- return {
82
- colors : [ false , true ]
83
- }
84
- }
85
- return {
86
- colors : [ false , false ]
87
- }
62
+ const updateVoteColors = async ( ) => {
63
+ const reviewIDs = [ ] ;
64
+ for ( let i = 0 ; i < reviewData . length ; i ++ ) {
65
+ reviewIDs . push ( reviewData [ i ] . _id ) ;
88
66
}
89
- useEffect ( ( ) => {
90
- // prevent reviews from carrying over
91
- dispatch ( setReviews ( [ ] ) ) ;
92
- getReviews ( ) ;
93
- } , [ props . course ?. id , props . professor ?. ucinetid ] ) ;
67
+ const req = {
68
+ ids : reviewIDs as string [ ] ,
69
+ } ;
70
+ const colors = await getColors ( req ) ;
71
+ setVoteColors ( colors ) ;
72
+ } ;
94
73
95
- let sortedReviews : ReviewData [ ] ;
96
- // filter verified if option is set
97
- if ( showOnlyVerifiedReviews ) {
98
- sortedReviews = reviewData . filter ( review => review . verified ) ;
99
- } else { // if not, clone reviewData since its const
100
- sortedReviews = reviewData . slice ( 0 ) ;
74
+ const getU = ( id : string | undefined ) => {
75
+ const temp = voteColors as object ;
76
+ const v = temp [ id as keyof typeof temp ] as unknown as number ;
77
+ if ( v == 1 ) {
78
+ return {
79
+ colors : [ true , false ] ,
80
+ } ;
81
+ } else if ( v == - 1 ) {
82
+ return {
83
+ colors : [ false , true ] ,
84
+ } ;
101
85
}
86
+ return {
87
+ colors : [ false , false ] ,
88
+ } ;
89
+ } ;
90
+ useEffect ( ( ) => {
91
+ // prevent reviews from carrying over
92
+ dispatch ( setReviews ( [ ] ) ) ;
93
+ getReviews ( ) ;
94
+ } , [ props . course ?. id , props . professor ?. ucinetid ] ) ;
102
95
103
- switch ( sortingOption ) {
104
- case SortingOption . MOST_RECENT :
105
- sortedReviews . sort ( ( a , b ) => new Date ( b . timestamp ) . getTime ( ) - new Date ( a . timestamp ) . getTime ( ) ) ;
106
- break ;
107
- case SortingOption . TOP_REVIEWS : // the right side of || will fall back to most recent when score is equal
108
- sortedReviews . sort ( ( a , b ) => b . score - a . score || new Date ( b . timestamp ) . getTime ( ) - new Date ( a . timestamp ) . getTime ( ) ) ;
109
- break ;
110
- case SortingOption . CONTROVERSIAL :
111
- sortedReviews . sort ( ( a , b ) => a . score - b . score || new Date ( b . timestamp ) . getTime ( ) - new Date ( a . timestamp ) . getTime ( ) ) ;
112
- break ;
113
- }
96
+ let sortedReviews : ReviewData [ ] ;
97
+ // filter verified if option is set
98
+ if ( showOnlyVerifiedReviews ) {
99
+ sortedReviews = reviewData . filter ( ( review ) => review . verified ) ;
100
+ } else {
101
+ // if not, clone reviewData since its const
102
+ sortedReviews = reviewData . slice ( 0 ) ;
103
+ }
114
104
115
- const openReviewForm = ( ) => {
116
- dispatch ( setFormStatus ( true ) ) ;
117
- document . body . style . overflow = 'hidden' ;
118
- }
119
- const closeForm = ( ) => {
120
- dispatch ( setFormStatus ( false ) ) ;
121
- document . body . style . overflow = 'visible' ;
122
- }
105
+ switch ( sortingOption ) {
106
+ case SortingOption . MOST_RECENT :
107
+ sortedReviews . sort ( ( a , b ) => new Date ( b . timestamp ) . getTime ( ) - new Date ( a . timestamp ) . getTime ( ) ) ;
108
+ break ;
109
+ case SortingOption . TOP_REVIEWS : // the right side of || will fall back to most recent when score is equal
110
+ sortedReviews . sort (
111
+ ( a , b ) => b . score - a . score || new Date ( b . timestamp ) . getTime ( ) - new Date ( a . timestamp ) . getTime ( ) ,
112
+ ) ;
113
+ break ;
114
+ case SortingOption . CONTROVERSIAL :
115
+ sortedReviews . sort (
116
+ ( a , b ) => a . score - b . score || new Date ( b . timestamp ) . getTime ( ) - new Date ( a . timestamp ) . getTime ( ) ,
117
+ ) ;
118
+ break ;
119
+ }
123
120
124
- if ( ! reviewData ) {
125
- return < p > Loading reviews..</ p > ;
126
- } else {
127
- return (
128
- < >
129
- < div className = 'reviews' >
130
- < div className = 'sorting-menu row' >
131
- < Dropdown
132
- placeholder = 'Sorting Option'
133
- scrolling
134
- selection
135
- options = { [ { text : 'Most Recent' , value : SortingOption . MOST_RECENT } ,
136
- { text : 'Top Reviews' , value : SortingOption . TOP_REVIEWS } ,
137
- { text : 'Controversial' , value : SortingOption . CONTROVERSIAL } ] }
138
- value = { sortingOption }
139
- onChange = { ( _ , s ) => setSortingOption ( s . value as SortingOption ) }
140
- />
141
- < div id = "checkbox" >
142
- < Checkbox label = "Show verified reviews only" checked = { showOnlyVerifiedReviews } onChange = { ( e ) => setShowOnlyVerifiedReviews ( e . currentTarget . checked ) } />
143
- </ div >
144
- </ div >
145
- { sortedReviews . map ( review => < SubReview review = { review } key = { review . _id } course = { props . course } professor = { props . professor } colors = { getU ( review . _id ) as VoteColor } colorUpdater = { updateVoteColors } /> ) }
146
- < button type = 'button' className = 'add-review-btn' onClick = { openReviewForm } > + Add Review</ button >
147
- </ div >
148
- < ReviewForm closeForm = { closeForm } { ...props } />
149
- </ >
150
- )
151
- }
152
- }
121
+ const openReviewForm = ( ) => {
122
+ dispatch ( setFormStatus ( true ) ) ;
123
+ document . body . style . overflow = 'hidden' ;
124
+ } ;
125
+ const closeForm = ( ) => {
126
+ dispatch ( setFormStatus ( false ) ) ;
127
+ document . body . style . overflow = 'visible' ;
128
+ } ;
129
+
130
+ if ( ! reviewData ) {
131
+ return < p > Loading reviews..</ p > ;
132
+ } else {
133
+ return (
134
+ < >
135
+ < div className = "reviews" >
136
+ < div className = "sorting-menu row" >
137
+ < Dropdown
138
+ placeholder = "Sorting Option"
139
+ scrolling
140
+ selection
141
+ options = { [
142
+ { text : 'Most Recent' , value : SortingOption . MOST_RECENT } ,
143
+ { text : 'Top Reviews' , value : SortingOption . TOP_REVIEWS } ,
144
+ { text : 'Controversial' , value : SortingOption . CONTROVERSIAL } ,
145
+ ] }
146
+ value = { sortingOption }
147
+ onChange = { ( _ , s ) => setSortingOption ( s . value as SortingOption ) }
148
+ />
149
+ < div id = "checkbox" >
150
+ < Checkbox
151
+ label = "Show verified reviews only"
152
+ checked = { showOnlyVerifiedReviews }
153
+ onChange = { ( ) => setShowOnlyVerifiedReviews ( ( state ) => ! state ) }
154
+ />
155
+ </ div >
156
+ </ div >
157
+ { sortedReviews . map ( ( review ) => (
158
+ < SubReview
159
+ review = { review }
160
+ key = { review . _id }
161
+ course = { props . course }
162
+ professor = { props . professor }
163
+ colors = { getU ( review . _id ) as VoteColor }
164
+ colorUpdater = { updateVoteColors }
165
+ />
166
+ ) ) }
167
+ < button type = "button" className = "add-review-btn" onClick = { openReviewForm } >
168
+ + Add Review
169
+ </ button >
170
+ </ div >
171
+ < ReviewForm closeForm = { closeForm } { ...props } />
172
+ </ >
173
+ ) ;
174
+ }
175
+ } ;
153
176
154
- export default Review ;
177
+ export default Review ;
0 commit comments