@@ -6,6 +6,7 @@ export function ReviewView(props) {
66 const { formData, setFormData } = props ;
77 const [ showGradeOptions , setShowGradeOptions ] = useState ( false ) ;
88 const [ showRecommendOptions , setShowRecommendOptions ] = useState ( false ) ;
9+ const [ expandedReviews , setExpandedReviews ] = useState ( { } ) ;
910 const gradeRef = useRef ( null ) ;
1011 const recommendRef = useRef ( null ) ;
1112
@@ -25,6 +26,14 @@ export function ReviewView(props) {
2526 } ;
2627 } , [ ] ) ;
2728
29+ // Function to toggle expanded state for a review
30+ const toggleExpanded = ( index ) => {
31+ setExpandedReviews ( ( prev ) => ( {
32+ ...prev ,
33+ [ index ] : ! prev [ index ] ,
34+ } ) ) ;
35+ } ;
36+
2837 return (
2938 < div className = "max-w-3xl mx-auto" >
3039 < div className = "mt-6" >
@@ -50,7 +59,6 @@ export function ReviewView(props) {
5059 />
5160 </ div >
5261
53-
5462 { /* Professor Rating */ }
5563 < div className = "text-center" >
5664 < p className = "font-semibold text-gray-700 text-sm mb-1" > Professor Rating</ p >
@@ -73,7 +81,7 @@ export function ReviewView(props) {
7381 { formData . grade || "Select" }
7482 </ div >
7583 { showGradeOptions && (
76- < div className = "absolute left-1/2 -translate-x-1/2 mt-2 bg-white p-2 rounded-md shadow-lg Disturbance shadow-lg z-10 flex space-x-2 animate-fadeIn" >
84+ < div className = "absolute left-1/2 -translate-x-1/2 mt-2 bg-white p-2 rounded-md shadow-lg z-10 flex space-x-2 animate-fadeIn" >
7785 { grades . map ( ( grade ) => (
7886 < button
7987 key = { grade }
@@ -139,14 +147,14 @@ export function ReviewView(props) {
139147 </ div >
140148
141149 < div className = "mt-4" >
142- < input
143- type = "text"
144- placeholder = "Enter professor name"
145- maxLength = { 100 }
146- className = "w-full border border-gray-300 rounded-md p-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors duration-200"
147- value = { formData . professorName }
148- onChange = { ( e ) => setFormData ( { ...formData , professorName : e . target . value } ) }
149- />
150+ < input
151+ type = "text"
152+ placeholder = "Enter professor name"
153+ maxLength = { 100 }
154+ className = "w-full border border-gray-300 rounded-md p-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors duration-200"
155+ value = { formData . professorName }
156+ onChange = { ( e ) => setFormData ( { ...formData , professorName : e . target . value } ) }
157+ />
150158 </ div >
151159
152160 < div className = "relative mt-4" >
@@ -173,92 +181,102 @@ export function ReviewView(props) {
173181 < div className = "mt-6" >
174182 < h3 className = "text-lg font-semibold text-gray-800 mb-4" > Previous Reviews</ h3 >
175183 < div className = "space-y-6" >
176- { /* {props.reviews.map((rev, i) => ( */ }
177- { [ ...props . reviews ] . sort ( ( a , b ) => new Date ( b . timestamp ) - new Date ( a . timestamp ) ) . map ( ( rev , i ) => (
178- < div key = { i } className = "bg-white shadow-md rounded-lg p-4" >
179- < div className = "flex justify-between items-center mb-2" >
180- < p className = "font-semibold text-gray-800" > { rev . userName } </ p >
181- < p className = "text-sm text-gray-500" >
182- Posted on { new Date ( rev . timestamp ) . toLocaleDateString ( "en-US" , {
183- month : "long" ,
184- day : "numeric" ,
185- year : "numeric" ,
186- } ) }
187- </ p >
188- </ div >
189- < div className = "grid grid-cols-2 md:grid-cols-3 gap-4 mb-2" >
190- < div >
191- < p className = "text-sm font-semibold text-gray-700" > Overall Rating</ p >
192- { /* <RatingComponent
193- className="flex space-x-1 text-sm"
194- value={rev.overallRating}
195- readOnly={true}
196- /> */ }
197- { rev . overallRating > 0 ? (
198- < RatingComponent
199- className = "flex space-x-1 text-sm"
200- value = { rev . overallRating }
201- readOnly = { true }
202- />
203- ) : (
204- < p className = "text-sm text-gray-600" > N/A</ p >
205- ) }
206-
207- </ div >
208- < div >
209- < p className = "text-sm font-semibold text-gray-700" > Difficulty Rating</ p >
210- { rev . difficultyRating > 0 ? (
211- < RatingComponent
212- className = "flex space-x-1 text-sm"
213- value = { rev . difficultyRating }
214- readOnly = { true }
215- />
216- ) : (
217- < p className = "text-sm text-gray-600" > N/A</ p >
218- ) }
219-
220- </ div >
221- < div >
222- < p className = "text-sm font-semibold text-gray-700" > Professor Rating</ p >
223- { rev . professorRating > 0 ? (
224- < RatingComponent
225- className = "flex space-x-1 text-sm"
226- value = { rev . professorRating }
227- readOnly = { true }
228- />
229- ) : (
230- < p className = "text-sm text-gray-600" > N/A</ p >
231- ) }
232-
233- </ div >
234- < div >
235- < p className = "text-sm font-semibold text-gray-700" > Professor</ p >
236- { /* <p className="text-sm text-gray-600">{rev.professorName}</p> */ }
237- < p className = "text-sm text-gray-600" > { rev . professorName || "N/A" } </ p >
238-
239- </ div >
240- < div >
241- < p className = "text-sm font-semibold text-gray-700" > Grade</ p >
242- { /* <p className="text-sm text-gray-600">{rev.grade}</p> */ }
243- < p className = "text-sm text-gray-600" > { rev . grade || "N/A" } </ p >
244-
245- </ div >
246- < div >
247- < p className = "text-sm font-semibold text-gray-700" > Recommended</ p >
248- { /* <p className="text-sm text-gray-600">{rev.recommend ? "Yes" : "No"}</p> */ }
249- < p className = "text-sm text-gray-600" >
250- { rev . recommend === true ? "Yes" : rev . recommend === false ? "No" : "N/A" }
251- </ p >
184+ { [ ...props . reviews ]
185+ . sort ( ( a , b ) => new Date ( b . timestamp ) - new Date ( a . timestamp ) )
186+ . map ( ( rev , i ) => {
187+ const maxLength = 200 ;
188+ const isLongReview = rev . text . length > maxLength ;
189+ const isExpanded = expandedReviews [ i ] || false ;
252190
191+ return (
192+ < div key = { i } className = "bg-white shadow-md rounded-lg p-4" >
193+ < div className = "flex justify-between items-center mb-2" >
194+ < p className = "font-semibold text-gray-800" > { rev . userName } </ p >
195+ < p className = "text-sm text-gray-500" >
196+ Posted on{ " " }
197+ { new Date ( rev . timestamp ) . toLocaleDateString ( "en-US" , {
198+ month : "long" ,
199+ day : "numeric" ,
200+ year : "numeric" ,
201+ } ) }
202+ </ p >
203+ </ div >
204+ < div className = "grid grid-cols-2 md:grid-cols-3 gap-4 mb-2" >
205+ < div >
206+ < p className = "text-sm font-semibold text-gray-700" > Overall Rating</ p >
207+ { rev . overallRating > 0 ? (
208+ < RatingComponent
209+ className = "flex space-x-1 text-sm"
210+ value = { rev . overallRating }
211+ readOnly = { true }
212+ />
213+ ) : (
214+ < p className = "text-sm text-gray-600" > N/A</ p >
215+ ) }
216+ </ div >
217+ < div >
218+ < p className = "text-sm font-semibold text-gray-700" > Difficulty Rating</ p >
219+ { rev . difficultyRating > 0 ? (
220+ < RatingComponent
221+ className = "flex space-x-1 text-sm"
222+ value = { rev . difficultyRating }
223+ readOnly = { true }
224+ />
225+ ) : (
226+ < p className = "text-sm text-gray-600" > N/A</ p >
227+ ) }
228+ </ div >
229+ < div >
230+ < p className = "text-sm font-semibold text-gray-700" > Professor Rating</ p >
231+ { rev . professorRating > 0 ? (
232+ < RatingComponent
233+ className = "flex space-x-1 text-sm"
234+ value = { rev . professorRating }
235+ readOnly = { true }
236+ />
237+ ) : (
238+ < p className = "text-sm text-gray-600" > N/A</ p >
239+ ) }
240+ </ div >
241+ < div >
242+ < p className = "text-sm font-semibold text-gray-700" > Professor</ p >
243+ < p className = "text-sm text-gray-600" > { rev . professorName || "N/A" } </ p >
244+ </ div >
245+ < div >
246+ < p className = "text-sm font-semibold text-gray-700" > Grade</ p >
247+ < p className = "text-sm text-gray-600" > { rev . grade || "N/A" } </ p >
248+ </ div >
249+ < div >
250+ < p className = "text-sm font-semibold text-gray-700" > Recommended</ p >
251+ < p className = "text-sm text-gray-600" >
252+ { rev . recommend === true ? "Yes" : rev . recommend === false ? "No" : "N/A" }
253+ </ p >
254+ </ div >
255+ </ div >
256+ < div >
257+ < p className = "text-sm font-semibold text-gray-700" > Review</ p >
258+ < div
259+ className = { `text-sm text-gray-600 transition-all duration-300 ${
260+ isExpanded || ! isLongReview ? "" : "max-h-10 overflow-hidden"
261+ } `}
262+ >
263+ { isExpanded || ! isLongReview
264+ ? rev . text
265+ : `${ rev . text . slice ( 0 , maxLength ) } ...` }
266+ </ div >
267+ { isLongReview && (
268+ < button
269+ onClick = { ( ) => toggleExpanded ( i ) }
270+ className = "mt-1 text-blue-600 hover:text-blue-800 text-sm font-semibold focus:outline-none"
271+ >
272+ { isExpanded ? "Read Less" : "Read More" }
273+ </ button >
274+ ) }
275+ </ div >
253276 </ div >
254- </ div >
255- < div >
256- < p className = "text-sm font-semibold text-gray-700" > Review</ p >
257- < p className = "text-sm text-gray-600" > { rev . text } </ p >
258- </ div >
259- </ div >
260- ) ) }
261- { props . reviews . length === 0 && < p className = "text-gray-600" > No reviews yet.</ p > }
277+ ) ;
278+ } ) }
279+ { props . reviews . length === 0 && < p className = "text-sm text-gray-600" > No reviews yet.</ p > }
262280 </ div >
263281 </ div >
264282 </ div >
0 commit comments