diff --git a/api/database.db b/api/database.db index e8c6e78e..62b6344c 100644 Binary files a/api/database.db and b/api/database.db differ diff --git a/api/views.py b/api/views.py index 4a47151a..5cc8a89a 100644 --- a/api/views.py +++ b/api/views.py @@ -34,9 +34,29 @@ def addnewreview(): db.session.commit() return jsonify () +@main.route('/removereview', methods=['POST']) +def removereview(): + details = request.get_json() + print(details) + REVIEW_DETAILS.query.filter(REVIEW_DETAILS.userId == details["userID"]).filter(REVIEW_DETAILS.movieId == details["movieId"]).delete() + db.session.commit() + return 'Done', 201 + @main.route('/movies') def movies(): - movie_list = MOVIE_DETAILS.query.all() + movie_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.title), + (MOVIE_DETAILS.release), + (MOVIE_DETAILS.description), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.movieLength), + (MOVIE_DETAILS.coverPhoto), + (MOVIE_DETAILS.pagePhoto), + (MOVIE_DETAILS.longDescription), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).all() + movies = [] for movie in movie_list: @@ -44,7 +64,7 @@ def movies(): 'title' : movie.title, 'release' : movie.release, 'description' : movie.description, - 'rating' : movie.rating, + 'rating' : movie.averageRating, 'movieLength' : movie.movieLength, 'category' : movie.category, 'coverPhoto' : movie.coverPhoto, @@ -117,44 +137,47 @@ def reviews(): -@main.route('/recommended') -def recommendeds(): +@main.route('/recommended', methods=['POST']) +def recommended(): id = request.get_json() print(id) - recommended_list = db.session.query((MOVIE_DETAILS.id),(MOVIE_DETAILS.category),(MOVIE_DETAILS.category), - (REVIEW_DETAILS.rating)).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).filter(REVIEW_DETAILS.userId==userId).all() + recommended_list = db.session.query((MOVIE_DETAILS.category)).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.category).filter(REVIEW_DETAILS.userId==id).all() moviesRecommended = [] for movie in recommended_list: - moviesRecommended.append({ 'movieId' : movie.id, - 'rating' : movie.rating, - 'category' : movie.category}) - - return jsonify ({'recommended': moviesRecommended}) + movie_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.title), + (MOVIE_DETAILS.release), + (MOVIE_DETAILS.description), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.movieLength), + (MOVIE_DETAILS.coverPhoto), + (MOVIE_DETAILS.pagePhoto), + (MOVIE_DETAILS.longDescription), + (REVIEW_DETAILS.rating), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(MOVIE_DETAILS.category==movie.category).all() - category = request.get_json() - print(category) - movie_list = MOVIE_DETAILS.query.filter(MOVIE_DETAILS.category==category).all() - movies = [] - print(movies) + movies = [] + for movie2 in movie_list: + movies.append({ 'id' : movie2.id, + 'title' : movie2.title, + 'release' : movie2.release, + 'description' : movie2.description, + 'rating' : movie2.averageRating, + 'movieLength' : movie2.movieLength, + 'category' : movie2.category, + 'coverPhoto' : movie2.coverPhoto, + 'pagePhoto' : movie2.pagePhoto, + 'longDescription' : movie2.longDescription}) + moviesRecommended.append({'category' : movie.category, 'movies' : movies}) - for movie in movie_list: - movies.append({ 'id' : movie.id, - 'title' : movie.title, - 'release' : movie.release, - 'description' : movie.description, - 'rating' : movie.rating, - 'movieLength' : movie.movieLength, - 'category' : movie.category, - 'coverPhoto' : movie.coverPhoto, - 'pagePhoto' : movie.pagePhoto, - 'longDescription' : movie.longDescription}) - - return jsonify ({'categories': movies}) + return jsonify ({'moviesRecommended': moviesRecommended}) @main.route('/myReviews') def myReviews(): - userID=None + userId=None token = request.headers.get('Authorization') [type,hash]=token.split() print(hash) @@ -163,26 +186,48 @@ def myReviews(): decryptedHashArray=((decryptedHash).decode('utf-8')).split(':') checkUserName = db.session.query((USER_DETAILS.id),(USER_DETAILS.userPassword)).filter(USER_DETAILS.userName==decryptedHashArray[0]).all() userId = checkUserName[0][0] - myReview_list = db.session.query((MOVIE_DETAILS.id),(MOVIE_DETAILS.category),(MOVIE_DETAILS.coverPhoto),(MOVIE_DETAILS.rating).label("movieRating"), - (REVIEW_DETAILS.rating),(REVIEW_DETAILS.review),(REVIEW_DETAILS.reviewDate),(REVIEW_DETAILS.userId)).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(REVIEW_DETAILS.userId==userId).all() + myReview_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.coverPhoto), + (REVIEW_DETAILS.rating).label('reviewRating'), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId)).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).filter(REVIEW_DETAILS.userId==userId).order_by(REVIEW_DETAILS.rating.desc()).all() myreviews = [] for review in myReview_list: - myreviews.append({ 'movieId' : review.id, - 'movieRating': review.movieRating, - 'rating' : review.rating, - 'review' : review.review, - 'userId' : review.userId, - 'reviewDate' : review.reviewDate, - 'coverPhoto' : review.coverPhoto}) - + averageRating = db.session.query((MOVIE_DETAILS.id),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(REVIEW_DETAILS.movieId==review.id).all() + print(averageRating) + print(userId,review.userId) + myreviews.append({ 'movieId' : review.id, + 'averageRating': averageRating[0][1], + 'reviewRating' : review.reviewRating, + 'review' : review.review, + 'userId' : review.userId, + 'reviewDate' : review.reviewDate, + 'coverPhoto' : review.coverPhoto}) + return jsonify ({'myReviews': myreviews}) @main.route('/categories', methods=['POST']) def categories(): category = request.get_json() print(category) - movie_list = MOVIE_DETAILS.query.filter(MOVIE_DETAILS.category==category).all() + movie_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.title), + (MOVIE_DETAILS.release), + (MOVIE_DETAILS.description), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.movieLength), + (MOVIE_DETAILS.coverPhoto), + (MOVIE_DETAILS.pagePhoto), + (MOVIE_DETAILS.longDescription), + (REVIEW_DETAILS.rating), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(MOVIE_DETAILS.category==category).all() + + movies = [] print(movies) @@ -191,7 +236,7 @@ def categories(): 'title' : movie.title, 'release' : movie.release, 'description' : movie.description, - 'rating' : movie.rating, + 'rating' : movie.averageRating, 'movieLength' : movie.movieLength, 'category' : movie.category, 'coverPhoto' : movie.coverPhoto, @@ -200,11 +245,60 @@ def categories(): return jsonify ({'categories': movies}) +@main.route('/search', methods=['POST']) +def search(): + searchTerm = request.get_json() + print(searchTerm) + movie_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.title), + (MOVIE_DETAILS.release), + (MOVIE_DETAILS.description), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.movieLength), + (MOVIE_DETAILS.coverPhoto), + (MOVIE_DETAILS.pagePhoto), + (MOVIE_DETAILS.longDescription), + (REVIEW_DETAILS.rating), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(MOVIE_DETAILS.title.contains(searchTerm)).all() + + movies = [] + print(movies) + + for movie in movie_list: + movies.append({ 'id' : movie.id, + 'title' : movie.title, + 'release' : movie.release, + 'description' : movie.description, + 'rating' : movie.averageRating, + 'movieLength' : movie.movieLength, + 'category' : movie.category, + 'coverPhoto' : movie.coverPhoto, + 'pagePhoto' : movie.pagePhoto, + 'longDescription' : movie.longDescription}) + + return jsonify ({'searchResults': movies}) + @main.route('/movieReviews', methods=['POST']) def movieReviews(): id = request.get_json() print(id) - movie_list = MOVIE_DETAILS.query.filter(MOVIE_DETAILS.id==id).all() + movie_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.title), + (MOVIE_DETAILS.release), + (MOVIE_DETAILS.description), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.movieLength), + (MOVIE_DETAILS.coverPhoto), + (MOVIE_DETAILS.pagePhoto), + (MOVIE_DETAILS.longDescription), + (REVIEW_DETAILS.rating), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(MOVIE_DETAILS.id==id).all() + + review_list = db.session.query((REVIEW_DETAILS.rating),(REVIEW_DETAILS.review),(REVIEW_DETAILS.reviewDate),(REVIEW_DETAILS.userId), (REVIEW_DETAILS.reviewId),(REVIEW_DETAILS.movieId),(USER_DETAILS.userName)).outerjoin(USER_DETAILS).filter(REVIEW_DETAILS.movieId==id).all() movies = [] @@ -214,7 +308,7 @@ def movieReviews(): 'title' : movie.title, 'release' : movie.release, 'description' : movie.description, - 'rating' : movie.rating, + 'rating' : movie.averageRating, 'movieLength' : movie.movieLength, 'category' : movie.category, 'coverPhoto' : movie.coverPhoto, @@ -240,18 +334,6 @@ def myaccount(): print(userID) user_list = USER_DETAILS.query.filter(USER_DETAILS.id==userID).all() - movie_list = db.session.query((MOVIE_DETAILS.id), - (MOVIE_DETAILS.title), - (MOVIE_DETAILS.release), - (MOVIE_DETAILS.description), - (MOVIE_DETAILS.movieLength),(MOVIE_DETAILS.category), - (MOVIE_DETAILS.coverPhoto), - (MOVIE_DETAILS.rating).label("movieRating"), - (REVIEW_DETAILS.rating), - (REVIEW_DETAILS.review), - (REVIEW_DETAILS.reviewDate), - (REVIEW_DETAILS.userId)).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).filter(REVIEW_DETAILS.userId==userID).all() - review_list = db.session.query((REVIEW_DETAILS.rating), (REVIEW_DETAILS.review), (REVIEW_DETAILS.reviewDate), @@ -259,6 +341,36 @@ def myaccount(): (REVIEW_DETAILS.reviewId), (REVIEW_DETAILS.movieId), (USER_DETAILS.userName)).outerjoin(USER_DETAILS).filter(REVIEW_DETAILS.userId==userID).all() + + reviews = [] + + for review in review_list: + reviews.append({ 'reviewId' : review.reviewId, + 'movieId' : review.movieId, + 'userId' : review.userId, + 'rating' : review.rating, + 'review' : review.review, + 'reviewDate' : review.reviewDate, + 'userName' : review.userName}) + + movieID=(reviews[-1])['movieId'] + print(movieID) + + movie_list = db.session.query((MOVIE_DETAILS.id), + (MOVIE_DETAILS.title), + (MOVIE_DETAILS.release), + (MOVIE_DETAILS.description), + (MOVIE_DETAILS.category), + (MOVIE_DETAILS.movieLength), + (MOVIE_DETAILS.coverPhoto), + (MOVIE_DETAILS.pagePhoto), + (MOVIE_DETAILS.longDescription), + (REVIEW_DETAILS.review), + (REVIEW_DETAILS.reviewDate), + (REVIEW_DETAILS.userId),db.func.avg(REVIEW_DETAILS.rating).label('averageRating'),).outerjoin(REVIEW_DETAILS).group_by(MOVIE_DETAILS.id).order_by(REVIEW_DETAILS.rating.desc()).filter(REVIEW_DETAILS.movieId==movieID).all() + + print(movieID) + users = [] for user in user_list: @@ -274,20 +386,12 @@ def myaccount(): 'title' : movie.title, 'release' : movie.release, 'description' : movie.description, - 'rating' : movie.rating, + 'rating' : movie.averageRating, 'movieLength' : movie.movieLength, 'category' : movie.category, 'coverPhoto' : movie.coverPhoto}) - reviews = [] - for review in review_list: - reviews.append({ 'reviewId' : review.reviewId, - 'movieId' : review.movieId, - 'userId' : review.userId, - 'rating' : review.rating, - 'review' : review.review, - 'reviewDate' : review.reviewDate, - 'userName' : review.userName}) + return jsonify ({'movieDetails': movies,'userDetails': users,'userReviews': reviews}) \ No newline at end of file diff --git a/flask-react/src/App.js b/flask-react/src/App.js index bfc0e7ca..76fb848f 100644 --- a/flask-react/src/App.js +++ b/flask-react/src/App.js @@ -13,6 +13,8 @@ import AddReview from './components/AddReview.js'; import MovieCoverPage from './components/MoviePage.js'; import Categories from './components/Categories.js'; import Account from './components/Account.js'; +import Recommended from './components/Recommended.js'; +import SearchResults from './components/SearchResults.js'; function App() { return ( @@ -24,8 +26,10 @@ function App() { + + diff --git a/flask-react/src/components/Account.js b/flask-react/src/components/Account.js index e705fc9e..e3d284b7 100644 --- a/flask-react/src/components/Account.js +++ b/flask-react/src/components/Account.js @@ -157,19 +157,18 @@ export default function Account() { const [userDetails, setUserDetails] = useState([]); const [userReviews, setUserReviews] = useState([]); const [movieDetails, setMovieDetails] = useState([]); + const [reviewCount, setReviewCount] = useState(0); const [myReviews] = useState([]); let { id } = useParams(); const userID=localStorage.getItem('userid') const token=localStorage.getItem('authorization') useEffect(()=> { - fetch('https://arthur-laura-5000.codio-box.uk/myaccount', { method: "POST", credentials: 'include', headers: {'Content-type': 'application/json','Authorization': token}, body: JSON.stringify(id) }).then(response =>response.json().then(data => {setUserDetails(data.userDetails[0]);setUserReviews(data.userReviews[0]);setMovieDetails(data.movieDetails[0]);})); + fetch('https://arthur-laura-5000.codio-box.uk/myaccount', { method: "POST", credentials: 'include', headers: {'Content-type': 'application/json','Authorization': token}, body: JSON.stringify(id) }).then(response =>response.json().then(data => {setUserDetails(data.userDetails[0]);setMovieDetails(data.movieDetails[0]);setReviewCount(data.userReviews.length);setUserReviews(data.userReviews.pop());})); },[]); console.log(userDetails) console.log(movieDetails) console.log(userReviews) - const reviewCount = myReviews.length; - console.log(reviewCount) - if (userID!==null){ + if (userID==id){ return (
@@ -206,6 +205,6 @@ export default function Account() { ); }else{ - {window.location.href='/login'} + {window.location.href='/'} } } \ No newline at end of file diff --git a/flask-react/src/components/AddReview.js b/flask-react/src/components/AddReview.js index 2acd6f2a..b3034e5c 100644 --- a/flask-react/src/components/AddReview.js +++ b/flask-react/src/components/AddReview.js @@ -163,7 +163,11 @@ const useStyles = makeStyles((theme) => ({ position: 'fixed', right: '40px', bottom: '40px', - cursor: 'pointer' + cursor: 'pointer', + '&:hover': { + transform: 'scale(1.8)', + transition:'transform .25s ease-in-out', + }, } })); @@ -174,7 +178,7 @@ export default function AddReview() { const [userReview,setUserReview] = useState(""); var today = new Date(); var dd = String(today.getDate()).padStart(2, '0'); - var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0! + var mm = String(today.getMonth() + 1).padStart(2, '0'); var yyyy = today.getFullYear(); today = dd + '/' + mm + '/' + yyyy; const userID=localStorage.getItem('userid') diff --git a/flask-react/src/components/MoviesRecommended.js b/flask-react/src/components/MoviesRecommended.js new file mode 100644 index 00000000..ee317ddc --- /dev/null +++ b/flask-react/src/components/MoviesRecommended.js @@ -0,0 +1,78 @@ +import React, {useEffect,useState} from 'react'; +import NavBar from './NavBar.js'; +import { List, Header, Rating } from "semantic-ui-react"; +import { fade, makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme) => ({ + title: { + color: 'red', + fontSize: '12pt', + position: 'relative', + top: '0px', + textAlign: 'center', + letterSpacing: '3px', + }, + container: { + width: 'auto', + height: '300px', + display: 'flex', + flexWrap: 'wrap', + marginLeft: '2.5px', + rowGap: '5px', + }, + cover: { + width:'200px', + height:'280px', + position: 'relative', + }, + movieCard: { + marginBottom: '40px', + marginRight: '2.5px', + marginLeft: '2.5px', + width: '200px', + height: '280px', + position: 'relative', + '&:hover>div': { + opacity:1, + transition:'opacity .25s ease-in-out', + }, + '&:hover>img': { + opacity:0.1, + transition:'opacity .25s ease-in-out', + }, + }, + movieCardHover: { + textAlign: 'justify', + position: 'absolute', + top: '3px', + color: 'white', + margin: '0px 10px', + fontSize: '10pt', + opacity: '0', + cursor:'pointer' + } +})); + +export const MoviesRecommended = ({ movies }) => { + const classes = useStyles(); + return ( +
+ {movies.map(movie => { + return ( +
{window.location.href='/movies/'+movie.id}}> +  +
+ +

Length: {movie.movieLength}

+

Release: {movie.release}

+

Category: {movie.category}

+

{movie.description}

+
+
+ + ) + })} +
+ + ) +} diff --git a/flask-react/src/components/NavBar.js b/flask-react/src/components/NavBar.js index fdd99d70..416ca627 100644 --- a/flask-react/src/components/NavBar.js +++ b/flask-react/src/components/NavBar.js @@ -100,7 +100,11 @@ const useStyles = makeStyles((theme) => ({ marginTop: '20px', fontSize: '15pt', textAlign: 'center', - cursor:'pointer' + cursor:'pointer', + '&:hover': { + textDecoration: 'underline', + transition:'backgroundColor color .25s ease-in-out', + }, }, categories: { fontSize: '17pt', @@ -127,6 +131,18 @@ const useStyles = makeStyles((theme) => ({ zIndex: '1', top: '0' }, + menuIcon: { + '&:hover': { + transform: 'scale(1.4)', + transition:'transform .25s ease-in-out', + }, + }, + accountIcon: { + '&:hover': { + transform: 'scale(1.4)', + transition:'transform .25s ease-in-out', + }, + }, sideAccountdiv: { width: '280px', height: '185px', @@ -134,14 +150,18 @@ const useStyles = makeStyles((theme) => ({ position: 'absolute', right: '0', zIndex: '1', - top: '0' + top: '0', }, accountOptions: { color: 'white', marginTop: '20px', fontSize: '15pt', textAlign: 'center', - cursor:'pointer' + cursor:'pointer', + '&:hover': { + textDecoration: 'underline', + transition:'textDecoration .25s ease-in-out', + }, }, closeIcon: { color: 'white', @@ -149,7 +169,11 @@ const useStyles = makeStyles((theme) => ({ marginTop: '20px', marginRight: '20px', transform: 'scale(1.8)', - cursor:'pointer' + cursor:'pointer', + '&:hover': { + transform: 'scale(2.4)', + transition:'transform .15s ease-in-out', + }, }, closeIconAccount: { color: 'white', @@ -157,7 +181,11 @@ const useStyles = makeStyles((theme) => ({ marginLeft: '20px', marginTop: '5px', transform: 'scale(1.8)', - cursor:'pointer' + cursor:'pointer', + '&:hover': { + transform: 'scale(2.4)', + transition:'transform .15s ease-in-out', + }, }, title: { '&:hover': { @@ -298,6 +326,9 @@ export default function NavBar() { input: classes.inputInput, }} inputProps={{ 'aria-label': 'search' }} + onKeyDown={(event) => { + if (event.key === 'Enter'){ + window.location=('/search/'+event.target.value)}}} />
@@ -308,7 +339,7 @@ export default function NavBar() { aria-haspopup="true" color="inherit" > -
@@ -327,7 +358,6 @@ export default function NavBar() { {renderMobileMenu} {(() => { - if(account){ return( @@ -353,8 +383,8 @@ export default function NavBar() {

{username} {setAccount(account => !account)}}/>

+

{window.location.href='/account/'+userID}}>Account

Logout

-

{window.location.href='/account/'+userID}}>My account

)} })()} diff --git a/flask-react/src/components/Recommended.js b/flask-react/src/components/Recommended.js index c0acf1e8..58cfc771 100644 --- a/flask-react/src/components/Recommended.js +++ b/flask-react/src/components/Recommended.js @@ -9,38 +9,96 @@ import Badge from '@material-ui/core/Badge'; import MenuItem from '@material-ui/core/MenuItem'; import Menu from '@material-ui/core/Menu'; import MenuIcon from '@material-ui/icons/Menu'; +import { List, Header, Rating } from "semantic-ui-react"; import SearchIcon from '@material-ui/icons/Search'; import AccountCircle from '@material-ui/icons/AccountCircle'; import MailIcon from '@material-ui/icons/Mail'; import NotificationsIcon from '@material-ui/icons/Notifications'; import MoreIcon from '@material-ui/icons/MoreVert'; import NavBar from './NavBar.js'; -import { Movies } from './Movies.js'; +import { MoviesRecommended } from './MoviesRecommended.js'; const useStyles = makeStyles((theme) => ({ title: { + color: 'white', + fontSize: '25pt', + marginTop: '9px', + marginBottom: '9px', + marginLeft: '5px', + letterSpacing: '3px' + }, + categoryTitle: { color: 'white', fontSize: '25pt', marginTop: '9px', marginBottom: '9px', marginLeft: '35px', letterSpacing: '3px' + }, + container: { + height: 'auto', + }, + cover: { + width:'220px', + height:'320px', + position: 'relative', + }, + movieCard: { + marginTop: '0px', + marginBottom: '10px', + marginRight: '10px', + marginLeft: '10px', + float: 'left', + width: '220px', + height: '320px', + position: 'relative', + '&:hover>div': { + opacity:1, + transition:'opacity .25s ease-in-out', + }, + '&:hover>img': { + opacity:0.1, + transition:'opacity .25s ease-in-out', + }, + }, + movieCardHover: { + textAlign: 'justify', + position: 'absolute', + top: '3px', + color: 'white', + margin: '0px 10px', + fontSize: '10pt', + opacity: '0', + cursor:'pointer' + }, + movieDetails: { + marginTop: '5px', + fontSize: '12pt' } })); export default function Recommended() { const classes = useStyles(); - const [movies, setMovies] = useState([]); + const [moviesRecommended, setMoviesRecommended] = useState([]); + const [copy, setCopy] = useState([]); + const userID=localStorage.getItem('userid') + const token=localStorage.getItem('authorization') useEffect(()=> { - fetch('https://arthur-laura-5000.codio-box.uk/movies', { credentials: 'include' }).then(response =>response.json().then(data => {setMovies(data.movies); + fetch('https://arthur-laura-5000.codio-box.uk/recommended', { method: "POST", credentials: 'include', headers: {'Content-type': 'application/json','Authorization': token}, body: JSON.stringify(userID) }).then(response =>response.json().then(data => {setMoviesRecommended(data.moviesRecommended); }) ); },[]); - console.log(movies) - return ( - -

Recommended

- -
- ); + console.log(moviesRecommended) + return ( +
+ {moviesRecommended.map(movie => { + return ( +
+

Because you like {movie.category} movies

+ +
+ ); + })} +
+ ); } \ No newline at end of file diff --git a/flask-react/src/components/Reviews.js b/flask-react/src/components/Reviews.js index b26ff7dc..e518d505 100644 --- a/flask-react/src/components/Reviews.js +++ b/flask-react/src/components/Reviews.js @@ -2,6 +2,8 @@ import React, {useEffect,useState} from 'react'; import NavBar from './NavBar.js'; import { List, Header, Rating } from "semantic-ui-react"; import { fade, makeStyles } from '@material-ui/core/styles'; +import DeleteForeverIcon from '@material-ui/icons/DeleteForever'; +import CloseIcon from '@material-ui/icons/Close'; const useStyles = makeStyles((theme) => ({ title: { @@ -69,13 +71,131 @@ const useStyles = makeStyles((theme) => ({ backgroundColor: '#0B0C0D', padding: '5px', fontSize: '13pt' + }, + deleteForeverIcon: { + color: 'white', + transform: 'scale(1.5)', + position: 'relative', + right: '2px', + float: 'right', + bottom: '38px', + cursor: 'pointer', + '&:hover': { + transform: 'scale(1.8)', + transition:'transform .25s ease-in-out', + }, + }, + confirmBox: { + width: '450px', + height: '220px', + backgroundColor: '#0B0C0D', + position: 'absolute', + left: '500px', + zIndex: '1', + top: '280px', + }, + topConfirmBox: { + backgroundColor: '#16161A', + width: '450px', + height: '60px', + }, + tintedBackground: { + backgroundColor: 'black', + opacity: '65%', + width: '100%', + height: '100%', + position: 'absolute', + zIndex: '1', + top: '0' + }, + option1: { + color: 'white', + marginTop: '20px', + marginLeft: '75px', + fontSize: '15pt', + textAlign: 'center', + lineHeight: '50px', + cursor:'pointer', + height: '50px', + width: '120px', + display: 'inline-block', + backgroundColor: 'black', + '&:hover': { + backgroundColor: 'white', + color: 'black', + transition:'backgroundColor color .25s ease-in-out', + }, + }, + option2: { + color: 'white', + marginTop: '60px', + marginLeft: '50px', + fontSize: '15pt', + textAlign: 'center', + lineHeight: '50px', + cursor:'pointer', + display: 'inline-block', + height: '50px', + width: '120px', + backgroundColor: '#16161A', + '&:hover': { + backgroundColor: 'white', + color: 'black', + transition:'backgroundColor color .25s ease-in-out', + }, + }, + text: { + color: 'white', + marginTop: '60px', + lineHeight: '60px', + marginLeft: '30px', + fontSize: '15pt', } })); export const Reviews = ({ myReviews }) => { const classes = useStyles(); + const userID=localStorage.getItem('userid') + const token=localStorage.getItem('authorization') + console.log(myReviews) + const [removeConfirm, setRemoveConfirm] = React.useState(false); + const [movieID, setMovieID] = React.useState(''); + async function removeReview(movieId){ + const details={userID,movieId} + console.log(details) + const response = await fetch('https://arthur-laura-5000.codio-box.uk/removereview', { + method: 'POST', + credentials: 'include', + headers: { + 'Content-type': 'application/json', + 'Authorization': token + }, + body: JSON.stringify(details), + }) + if(response.ok){ + alert("Your review has been removed") + window.location.reload() + } + } return (
+ {(() => { + if(removeConfirm){ + return( + +
+
+
+
+

Are you sure you want to delete you review?

+
+

{setRemoveConfirm(removeConfirm => !removeConfirm)}}>No

+

removeReview(movieID)}>Yes

+
+
+ ) + } + })()} {myReviews.map(review => { return (
@@ -86,14 +206,15 @@ export const Reviews = ({ myReviews }) => {

Your rating

Average rating



- - + +

Your review:

{review.title}

{review.review}

Date: {review.reviewDate}

+ {setRemoveConfirm(removeConfirm => !removeConfirm);setMovieID(review.movieId)}}/>
diff --git a/flask-react/src/components/SearchResults.js b/flask-react/src/components/SearchResults.js new file mode 100644 index 00000000..2a9972b6 --- /dev/null +++ b/flask-react/src/components/SearchResults.js @@ -0,0 +1,106 @@ +import React, {useEffect, useState} from 'react'; +import { fade, makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; +import InputBase from '@material-ui/core/InputBase'; +import Badge from '@material-ui/core/Badge'; +import MenuItem from '@material-ui/core/MenuItem'; +import Menu from '@material-ui/core/Menu'; +import MenuIcon from '@material-ui/icons/Menu'; +import SearchIcon from '@material-ui/icons/Search'; +import AccountCircle from '@material-ui/icons/AccountCircle'; +import MailIcon from '@material-ui/icons/Mail'; +import NotificationsIcon from '@material-ui/icons/Notifications'; +import MoreIcon from '@material-ui/icons/MoreVert'; +import NavBar from './NavBar.js'; +import { Movies } from './Movies.js'; +import { List, Header, Rating } from "semantic-ui-react"; +import { useParams } from "react-router-dom"; + +const useStyles = makeStyles((theme) => ({ + title: { + color: 'white', + height: '50px', + width: '100%', + fontSize: '25pt', + marginTop: '9px', + marginBottom: '0px', + marginLeft: '15px', + letterSpacing: '3px', + }, + container: { + width: 'auto', + height: '300px', + display: 'flex', + flexWrap: 'wrap', + marginLeft: 'auto', + rowGap: '5px', + }, + cover: { + width:'220px', + height:'320px', + position: 'relative', + }, + movieCard: { + marginTop: '0px', + marginBottom: '10px', + marginRight: '10px', + marginLeft: '10px', + float: 'left', + width: '220px', + height: '320px', + position: 'relative', + '&:hover>div': { + opacity:1, + transition:'opacity .25s ease-in-out', + }, + '&:hover>img': { + opacity:0.1, + transition:'opacity .25s ease-in-out', + }, + }, + movieCardHover: { + textAlign: 'justify', + position: 'absolute', + top: '3px', + color: 'white', + margin: '0px 10px', + fontSize: '10pt', + opacity: '0', + cursor:'pointer' + }, + movieDetails: { + marginTop: '5px', + fontSize: '12pt' + } +})); + +export default function SearchResults() { + const classes = useStyles(); + const [movies, setMovies] = useState([]); + let { searchTerm } = useParams(); + useEffect(()=> { + fetch('https://arthur-laura-5000.codio-box.uk/search', { credentials: 'include', method: 'POST', headers: { 'Content-type': 'application/json'}, body: JSON.stringify(searchTerm)}).then(response =>response.json().then(data => {setMovies(data.searchResults);})); + },[]); + console.log(movies) + return ( +
+

You have searched for: {searchTerm}

+ {movies.map(movie => { + return ( +
{window.location.href='/movies/'+movie.id}}> +  +
+ +

Length: {movie.movieLength}

+

Release: {movie.release}

+

Category: {movie.category}

+

{movie.description}

+
+
+ ) + })} +
+)} \ No newline at end of file diff --git a/flask-react/src/simpleAppBar.js b/flask-react/src/simpleAppBar.js deleted file mode 100644 index a597f2c9..00000000 --- a/flask-react/src/simpleAppBar.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import Button from '@material-ui/core/Button'; -import IconButton from '@material-ui/core/IconButton'; -import MenuIcon from '@material-ui/icons/Menu'; - -const useStyles = makeStyles((theme) => ({ - root: { - flexGrow: 1, - }, - menuButton: { - marginRight: theme.spacing(2), - }, - title: { - flexGrow: 1, - }, -})); - -export default function ButtonAppBar() { - const classes = useStyles(); - - return ( -
- - - - - - - News - - - - -
- ); -}