Skip to content

Commit

Permalink
Do duplicate review check on frontend (#501)
Browse files Browse the repository at this point in the history
* frontend check for duplicate review in form

* remove explicit dup check on backend
  • Loading branch information
js0mmer authored Nov 13, 2024
1 parent 25a796e commit 49592ac
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
12 changes: 0 additions & 12 deletions api/src/controllers/reviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,6 @@ const reviewsRouter = router({
verified: verifiedCount >= 3, // auto-verify if use has 3+ verified reviews
};

/** @todo: do a check for existing review on the frontend, remove this for the sake of speed since constraints will already prevent duplicate reviews on insertion */
//check if review already exists for same professor, course, and user (do this before verifying captcha)
const existingReview = await db
.select({ count: count() })
.from(review)
.where(
and(eq(review.userId, userId), eq(review.courseId, input.courseId), eq(review.professorId, input.professorId)),
);
if (existingReview[0].count > 0) {
throw new TRPCError({ code: 'BAD_REQUEST', message: 'You have already reviewed this professor and course!' });
}

// Verify the captcha
const verifyResponse = await verifyCaptcha(reviewToAdd);
if (!verifyResponse?.success) throw new TRPCError({ code: 'BAD_REQUEST', message: 'ReCAPTCHA token is invalid' });
Expand Down
25 changes: 22 additions & 3 deletions site/src/component/ReviewForm/ReviewForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import RangeSlider from 'react-bootstrap-range-slider';
import Modal from 'react-bootstrap/Modal';
import ReCAPTCHA from 'react-google-recaptcha';
import { addReview, editReview } from '../../store/slices/reviewSlice';
import { useAppDispatch } from '../../store/hooks';
import { useAppDispatch, useAppSelector } from '../../store/hooks';
import { ReviewProps } from '../Review/Review';
import ThemeContext from '../../style/theme-context';
import { quarters } from '@peterportal/types';
Expand Down Expand Up @@ -63,6 +63,7 @@ const ReviewForm: FC<ReviewFormProps> = ({
const [anonymous, setAnonymous] = useState(reviewToEdit?.userDisplay === anonymousName);
const [validated, setValidated] = useState(false);
const { darkMode } = useContext(ThemeContext);
const reviews = useAppSelector((state) => state.review.reviews);
useEffect(() => {
if (show) {
// form opened
Expand Down Expand Up @@ -158,6 +159,12 @@ const ReviewForm: FC<ReviewFormProps> = ({
}
};

const alreadyReviewedCourseProf = (courseId: string, professorId: string) => {
return reviews.some(
(review) => review.courseId === courseId && review.professorId === professorId && review.authored,
);
};

// select instructor if in course context
const instructorSelect = courseProp && (
<Form.Group>
Expand All @@ -176,8 +183,14 @@ const ReviewForm: FC<ReviewFormProps> = ({
</option>
{Object.keys(courseProp?.instructors).map((ucinetid) => {
const name = courseProp?.instructors[ucinetid].name;
const alreadyReviewed = alreadyReviewedCourseProf(courseProp?.id, ucinetid);
return (
<option key={ucinetid} value={ucinetid}>
<option
key={ucinetid}
value={ucinetid}
title={alreadyReviewed ? 'You have already reviewed this professor' : undefined}
disabled={alreadyReviewed}
>
{name}
</option>
);
Expand Down Expand Up @@ -210,8 +223,14 @@ const ReviewForm: FC<ReviewFormProps> = ({
{Object.keys(professorProp?.courses).map((courseID) => {
const name =
professorProp?.courses[courseID].department + ' ' + professorProp?.courses[courseID].courseNumber;
const alreadyReviewed = alreadyReviewedCourseProf(courseID, professorProp?.ucinetid);
return (
<option key={courseID} value={courseID}>
<option
key={courseID}
value={courseID}
title={alreadyReviewed ? 'You have already reviewed this course' : undefined}
disabled={alreadyReviewed}
>
{name}
</option>
);
Expand Down

0 comments on commit 49592ac

Please sign in to comment.