Skip to content

Commit

Permalink
Merge pull request #270 from icssc/advay/show-users-reviews
Browse files Browse the repository at this point in the history
Add page where users reviews are displayed
  • Loading branch information
advayanand authored Jun 9, 2023
2 parents cedc558 + 830e4b0 commit 35b0177
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 2 deletions.
14 changes: 12 additions & 2 deletions api/src/controllers/reviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,17 @@ router.post("/", async function (req, res, next) {
* Delete a review
*/
router.delete('/', async (req, res, next) => {
if (req.session.passport?.admin) {

const checkUser = async () => {

let review = await getDocuments(COLLECTION_NAMES.REVIEWS, {
_id: new ObjectID(req.body.id)
});

return review.length > 0 && review[0].userID === req.session.passport?.user.id;
}

if (req.session.passport?.admin || await checkUser()) {
console.log(`Deleting review ${req.body.id}`);

let status = await deleteDocument(COLLECTION_NAMES.REVIEWS, {
Expand All @@ -179,7 +189,7 @@ router.delete('/', async (req, res, next) => {
res.json(status);
}
else {
res.json({ error: 'Must be an admin to delete reviews!' });
res.json({ error: 'Must be an admin or review author to delete reviews!' });
}
})

Expand Down
2 changes: 2 additions & 0 deletions site/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import ErrorPage from './pages/ErrorPage';
import RoadmapPage from './pages/RoadmapPage';
import ZotisticsPage from './pages/ZotisticsPage';
import AdminPage from './pages/AdminPage';
import ReviewsPage from './pages/ReviewsPage';
import SideBar from './component/SideBar/SideBar';

import { useAppSelector } from './store/hooks';
Expand Down Expand Up @@ -51,6 +52,7 @@ export default function App() {
<Route path='/course/:id+' component={CoursePage} />
<Route path='/professor/:id' component={ProfessorPage} />
<Route path='/admin' component={AdminPage} />
<Route path='/reviews' component={ReviewsPage} />
<Route component={ErrorPage} />
</Switch>
<Footer />
Expand Down
12 changes: 12 additions & 0 deletions site/src/component/SideBar/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ const SideBar: FC = ({ children }) => {
</span>
</NavLink>
</li>
{isLoggedIn &&
<li>
<NavLink to='/reviews' activeClassName='sidebar-active' onClick={closeSidebar}>
<div>
<Icon name='sticky note outline' size='large' />
</div>
<span>
Reviews
</span>
</NavLink>
</li>
}
{isAdmin && <>
<li>
<NavLink to='/admin/verify' activeClassName='sidebar-active' onClick={closeSidebar}>
Expand Down
17 changes: 17 additions & 0 deletions site/src/component/UserReviews/UserReviews.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.user-reviews-container {
padding: 2rem;
background-color: white;
border-radius: var(--border-radius);
}

.user-reviews {
background-color: white;
border-radius: var(--border-radius);
margin-bottom: 3vh;

.user-reviews-footer {
flex-direction: row;
width: 100%;
align-items: flex-end;
}
}
51 changes: 51 additions & 0 deletions site/src/component/UserReviews/UserReviews.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import axios, { AxiosResponse } from "axios";
import React, { FC, useEffect, useState } from "react";
import SubReview from '../../component/Review/SubReview';
import Button from 'react-bootstrap/Button';
import { Divider } from 'semantic-ui-react';
import { ReviewData } from "src/types/types";
import './UserReviews.scss';
import { useCookies } from "react-cookie";

const UserReviews: FC = () => {
const [reviews, setReviews] = useState<ReviewData[]>([]);
const [loaded, setLoaded] = useState<boolean>(false);
const [cookies, setCookie] = useCookies(['user']);

const getUserReviews = async () => {
const response: AxiosResponse<ReviewData[]> = await axios.get(`/api/reviews?userID=${cookies.user.id}`);
setReviews(response.data);
setLoaded(true);
}

useEffect(() => {
getUserReviews();
}, []);

const deleteReview = async (reviewID: string) => {
await axios.delete('/api/reviews', { data: { id: reviewID } });
setReviews(reviews.filter(review => review._id !== reviewID));
}

if (!loaded) {
return <p>Loading...</p>;
} else if (reviews.length === 0) {
return <p>No reviews to display at the moment.</p>;
} else {
return <div className='user-reviews-container'>
<h1>Your Reviews</h1>
<p>Deleting a review will remove it permanently.</p>
{
reviews.map((review, i) => <div key={`user-reviews-${i}`} className='user-reviews'>
<Divider />
<SubReview review={review}></SubReview>
<div className='user-reviews-footer'>
<Button variant='danger' className='mr-3' onClick={() => deleteReview(review._id!)}>Delete</Button>
</div>
</div>)
}
</div>
}
};

export default UserReviews;
Empty file.
41 changes: 41 additions & 0 deletions site/src/pages/ReviewsPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { FC, useEffect, useState } from "react";
import UserReviews from '../../component/UserReviews/UserReviews';
import Error from '../../component/Error/Error';
import './ReviewsPage.scss';
import { useLocation } from "react-router-dom";
import { useCookies } from "react-cookie";

const ReviewsPage: FC = () => {
const location = useLocation();
const [loaded, setLoaded] = useState<boolean>(false);
const [cookies, setCookie] = useCookies(['user']);
const [authorized, setAuthorized] = useState<boolean>(false);

// user has to be logged in to view this page
const checkLoggedIn = async () => {
const loggedIn: boolean = cookies.hasOwnProperty('user');
setAuthorized(loggedIn);
setLoaded(true);
}

useEffect(() => {
checkLoggedIn();
}, []);

if (!loaded) {
return <p>Loading...</p>;
}
else if (!authorized) {
return (
<Error message='Access Denied: Log in to view this page.'></Error>
);
}
else {
if (location.pathname.includes('reviews')) {
return <UserReviews />
}
}
return <Error message='Invalid Reviews Page'></Error>
};

export default ReviewsPage;

0 comments on commit 35b0177

Please sign in to comment.