Skip to content

Commit

Permalink
Make ReviewBox collapsible
Browse files Browse the repository at this point in the history
  • Loading branch information
ankith26 committed Dec 15, 2024
1 parent 3d75e41 commit 3787516
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 48 deletions.
96 changes: 64 additions & 32 deletions frontend/src/components/ReviewBox.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import {
Card,
CardContent,
Expand All @@ -15,6 +15,8 @@ import {
Button,
} from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';

import theme from '../theme';
import ReviewInput from './ReviewInput';
Expand Down Expand Up @@ -73,7 +75,7 @@ const Review = ({ review, endpoint, onUpdate }) => {
color="text.secondary"
sx={{ fontStyle: 'italic' }}
>
Your review (this is only visible to you)
Your review (this line is only visible to you)
</Typography>
<IconButton onClick={handleDialogOpen} color="error" size="small">
<DeleteIcon />
Expand Down Expand Up @@ -115,22 +117,40 @@ const Review = ({ review, endpoint, onUpdate }) => {
);
};

const ReviewBox = ({ children, endpoint }) => {
const ReviewBox = ({ children, title, endpoint, initExpanded }) => {
const [reviewsList, setReviewsList] = useState(null);
const [isExpanded, setIsExpanded] = useState(initExpanded);
const cache = useRef({}); // Cache for reviews data

const fetchReviews = async () => {
setReviewsList(null);
try {
const response = await api.get(endpoint);
cache.current[endpoint] = response.data;
setReviewsList(response.data);
} catch (error) {
// TODO: report error in frontend
console.error('Error during search:', error);
}
};

const toggleExpand = () => {
setIsExpanded(!isExpanded);
};

useEffect(() => {
fetchReviews();
}, [endpoint]);
if (isExpanded) {
if (cache.current[endpoint]) {
setReviewsList(cache.current[endpoint]);
}
else {
fetchReviews();
}
}
else {
setReviewsList(null);
}
}, [endpoint, isExpanded]);

return (
<Card
Expand All @@ -143,35 +163,47 @@ const ReviewBox = ({ children, endpoint }) => {
}}
>
<CardContent>
{children}
<Typography variant="h6" gutterBottom color="secondary" sx={{ mt: 1 }}>
Reviews
</Typography>
{reviewsList === null ? (
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '150px',
}}
>
<CircularProgress />
</Box>
) : !reviewsList || reviewsList.length === 0 ? (
<Typography variant="body1" color="text.secondary">
No reviews available.
<Box display="flex" justifyContent="space-between" alignItems="center">
<Typography variant="h5" color="primary">
{title}
</Typography>
) : (
reviewsList.map((review, index) => (
<Review
review={review}
endpoint={endpoint}
onUpdate={fetchReviews}
/>
))
<IconButton onClick={toggleExpand} size="small">
{isExpanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</IconButton>
</Box>
{isExpanded && (
<>
{children}
<Typography variant="h6" gutterBottom color="secondary" sx={{ mt: 1 }}>
Reviews
</Typography>
{reviewsList === null ? (
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '150px',
}}
>
<CircularProgress />
</Box>
) : !reviewsList || reviewsList.length === 0 ? (
<Typography variant="body1" color="text.secondary">
No reviews available.
</Typography>
) : (
reviewsList.map((review, index) => (
<Review
review={review}
endpoint={endpoint}
onUpdate={fetchReviews}
/>
))
)}
<ReviewInput endpoint={endpoint} onUpdate={fetchReviews} />
</>
)}
<ReviewInput endpoint={endpoint} onUpdate={fetchReviews} />
</CardContent>
</Card>
);
Expand Down
13 changes: 2 additions & 11 deletions frontend/src/pages/Courses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,13 @@ const Courses = ({ courseList, profMap }) => {
>
No match found for given filters.
</Typography>
) : filteredCourses.length > 50 ? (
<Typography
variant="body2"
color="text.primary"
sx={{ fontStyle: 'italic' }}
>
Too many matches for given filters, please narrow them down.
</Typography>
) : (
filteredCourses.map((course, index) => (
<ReviewBox
title={`[${course.code}] ${course.name} (${course.sem})`}
endpoint={`/courses/reviews/${course.sem}/${course.code}`}
initExpanded={filteredCourses.length < 10}
>
<Typography variant="h5" gutterBottom color="primary">
[{course.code}] {course.name} ({course.sem})
</Typography>
{course.profs.map((email) => {
const prof = profMap.get(email);
return prof ? (
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/pages/Profs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ const Profs = ({ profList }) => {
</Tooltip>
</Box>
{reviewProf ? (
<ReviewBox endpoint={`/members/reviews/${reviewProf.email}`}>
<Typography variant="h5" gutterBottom color="primary">
{reviewProf.name} &lt;{reviewProf.email}&gt;
</Typography>
</ReviewBox>
<ReviewBox
title={`${reviewProf.name} <${reviewProf.email}>`}
endpoint={`/members/reviews/${reviewProf.email}`}
initExpanded={true}
/>
) : (
<Typography
variant="body2"
Expand Down

0 comments on commit 3787516

Please sign in to comment.