1
- import React , { useState , useEffect } from 'react' ;
1
+ import React , { useState , useEffect , useRef } from 'react' ;
2
2
import {
3
3
Card ,
4
4
CardContent ,
@@ -15,6 +15,8 @@ import {
15
15
Button ,
16
16
} from '@mui/material' ;
17
17
import DeleteIcon from '@mui/icons-material/Delete' ;
18
+ import ExpandMoreIcon from '@mui/icons-material/ExpandMore' ;
19
+ import ExpandLessIcon from '@mui/icons-material/ExpandLess' ;
18
20
19
21
import theme from '../theme' ;
20
22
import ReviewInput from './ReviewInput' ;
@@ -73,7 +75,7 @@ const Review = ({ review, endpoint, onUpdate }) => {
73
75
color = "text.secondary"
74
76
sx = { { fontStyle : 'italic' } }
75
77
>
76
- Your review (this is only visible to you)
78
+ Your review (this line is only visible to you)
77
79
</ Typography >
78
80
< IconButton onClick = { handleDialogOpen } color = "error" size = "small" >
79
81
< DeleteIcon />
@@ -115,22 +117,40 @@ const Review = ({ review, endpoint, onUpdate }) => {
115
117
) ;
116
118
} ;
117
119
118
- const ReviewBox = ( { children, endpoint } ) => {
120
+ const ReviewBox = ( { children, title , endpoint, initExpanded } ) => {
119
121
const [ reviewsList , setReviewsList ] = useState ( null ) ;
122
+ const [ isExpanded , setIsExpanded ] = useState ( initExpanded ) ;
123
+ const cache = useRef ( { } ) ; // Cache for reviews data
124
+
120
125
const fetchReviews = async ( ) => {
121
126
setReviewsList ( null ) ;
122
127
try {
123
128
const response = await api . get ( endpoint ) ;
129
+ cache . current [ endpoint ] = response . data ;
124
130
setReviewsList ( response . data ) ;
125
131
} catch ( error ) {
126
132
// TODO: report error in frontend
127
133
console . error ( 'Error during search:' , error ) ;
128
134
}
129
135
} ;
130
136
137
+ const toggleExpand = ( ) => {
138
+ setIsExpanded ( ! isExpanded ) ;
139
+ } ;
140
+
131
141
useEffect ( ( ) => {
132
- fetchReviews ( ) ;
133
- } , [ endpoint ] ) ;
142
+ if ( isExpanded ) {
143
+ if ( cache . current [ endpoint ] ) {
144
+ setReviewsList ( cache . current [ endpoint ] ) ;
145
+ }
146
+ else {
147
+ fetchReviews ( ) ;
148
+ }
149
+ }
150
+ else {
151
+ setReviewsList ( null ) ;
152
+ }
153
+ } , [ endpoint , isExpanded ] ) ;
134
154
135
155
return (
136
156
< Card
@@ -143,35 +163,47 @@ const ReviewBox = ({ children, endpoint }) => {
143
163
} }
144
164
>
145
165
< CardContent >
146
- { children }
147
- < Typography variant = "h6" gutterBottom color = "secondary" sx = { { mt : 1 } } >
148
- Reviews
149
- </ Typography >
150
- { reviewsList === null ? (
151
- < Box
152
- sx = { {
153
- display : 'flex' ,
154
- alignItems : 'center' ,
155
- justifyContent : 'center' ,
156
- height : '150px' ,
157
- } }
158
- >
159
- < CircularProgress />
160
- </ Box >
161
- ) : ! reviewsList || reviewsList . length === 0 ? (
162
- < Typography variant = "body1" color = "text.secondary" >
163
- No reviews available.
166
+ < Box display = "flex" justifyContent = "space-between" alignItems = "center" >
167
+ < Typography variant = "h5" color = "primary" >
168
+ { title }
164
169
</ Typography >
165
- ) : (
166
- reviewsList . map ( ( review , index ) => (
167
- < Review
168
- review = { review }
169
- endpoint = { endpoint }
170
- onUpdate = { fetchReviews }
171
- />
172
- ) )
170
+ < IconButton onClick = { toggleExpand } size = "small" >
171
+ { isExpanded ? < ExpandLessIcon /> : < ExpandMoreIcon /> }
172
+ </ IconButton >
173
+ </ Box >
174
+ { isExpanded && (
175
+ < >
176
+ { children }
177
+ < Typography variant = "h6" gutterBottom color = "secondary" sx = { { mt : 1 } } >
178
+ Reviews
179
+ </ Typography >
180
+ { reviewsList === null ? (
181
+ < Box
182
+ sx = { {
183
+ display : 'flex' ,
184
+ alignItems : 'center' ,
185
+ justifyContent : 'center' ,
186
+ height : '150px' ,
187
+ } }
188
+ >
189
+ < CircularProgress />
190
+ </ Box >
191
+ ) : ! reviewsList || reviewsList . length === 0 ? (
192
+ < Typography variant = "body1" color = "text.secondary" >
193
+ No reviews available.
194
+ </ Typography >
195
+ ) : (
196
+ reviewsList . map ( ( review , index ) => (
197
+ < Review
198
+ review = { review }
199
+ endpoint = { endpoint }
200
+ onUpdate = { fetchReviews }
201
+ />
202
+ ) )
203
+ ) }
204
+ < ReviewInput endpoint = { endpoint } onUpdate = { fetchReviews } />
205
+ </ >
173
206
) }
174
- < ReviewInput endpoint = { endpoint } onUpdate = { fetchReviews } />
175
207
</ CardContent >
176
208
</ Card >
177
209
) ;
0 commit comments