From 236e364e993c833c40e43e407454ff1c8d08469d Mon Sep 17 00:00:00 2001
From: haavarhu <havard.hunshamar@ntnu.no>
Date: Sun, 11 Nov 2018 12:42:52 +0100
Subject: [PATCH 1/4] made component for moveidetailscontent #38

---
 .../src/components/MovieDetailsContent.js     | 431 ++++++++++++++++++
 1 file changed, 431 insertions(+)
 create mode 100644 moviesearch/src/components/MovieDetailsContent.js

diff --git a/moviesearch/src/components/MovieDetailsContent.js b/moviesearch/src/components/MovieDetailsContent.js
new file mode 100644
index 0000000..2e37a3e
--- /dev/null
+++ b/moviesearch/src/components/MovieDetailsContent.js
@@ -0,0 +1,431 @@
+import React, { Component } from "react";
+import Modal from "@material-ui/core/Modal";
+import { withStyles } from "@material-ui/core/styles";
+import PropTypes from "prop-types";
+import Grid from "@material-ui/core/Grid";
+import { connect } from "react-redux";
+import Button from "@material-ui/core/Button";
+import { updateMovie } from "../actions/updateMovieAction";
+import { nextMovie, prevMovie } from "../actions/browseMoviesAction";
+import MaterialIcon from "material-icons-react";
+import RatingComponent from "./RatingComponent";
+import ReviewsComponent from "./ReviewsComponent";
+import AddReviewComponent from "./AddReviewComponent";
+import StarRatings from "react-star-ratings";
+import { sortMovies } from "../actions/sortMoviesAction";
+
+class MovieDetailsContent extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { showMovieList: false };
+  }
+  searchByYear = () => {
+    this.props.dispatch({
+      type: "UPDATE_YEAR",
+      payload: this.props.selectedMovie.year
+    });
+
+    let sortBy = "vote_average";
+
+    this.props.dispatch(
+      sortMovies("None", this.props.selectedMovie.year, "None", sortBy)
+    );
+    this.props.dispatch({ type: "RESET" });
+    this.hideDetails();
+  };
+
+  searchByGenre = () => {
+    this.props.dispatch({ type: "UPDATE_GENRE", payload: "Drama" });
+
+    let sortBy = "vote_average";
+
+    this.props.dispatch(sortMovies("None", "None", "Drama", sortBy));
+    this.props.dispatch({ type: "RESET" });
+    this.hideDetails();
+  };
+
+  changeRating = rating => {
+    this.props.dispatch({
+      type: "UPDATE_RATING",
+      rating: Number(rating)
+    });
+  };
+
+  handleKeyPress = event => {
+    switch (event.key) {
+      case "ArrowRight": {
+        this.props.dispatch(
+          nextMovie(this.props.selectedMovie, this.props.movies)
+        );
+        break;
+      }
+      case "ArrowLeft": {
+        this.props.dispatch(
+          prevMovie(this.props.selectedMovie, this.props.movies)
+        );
+        break;
+      }
+      default:
+    }
+  };
+
+  hideDetails = () => {
+    this.props.dispatch({ type: "UNSELECT_MOVIE" });
+    this.props.dispatch({ type: "RESET_REVIEW_FIELDS" });
+    this.props.dispatch({ type: "SET_HOVER", payload: false });
+  };
+
+  hover = () => {
+    this.props.dispatch({ type: "SET_HOVER", payload: true });
+  };
+  unHover = () => {
+    this.props.dispatch({ type: "SET_HOVER", payload: false });
+  };
+
+  addRating = () => {
+    if (this.props.rating > 0) {
+      this.props.selectedMovie["feedbackList"].push({
+        name: "",
+        rating: this.props.rating,
+        review: ""
+      });
+      this.props.dispatch(updateMovie(this.props.selectedMovie));
+    } else {
+      console.log("error: cant rate movie zero stars");
+    }
+  };
+
+  addReview = () => {
+    if (this.props.openReview) {
+      if (this.props.rating > 0) {
+        this.props.selectedMovie["feedbackList"].push({
+          name: this.props.name.trim(),
+          rating: this.props.rating,
+          review: this.props.review.trim()
+        });
+        this.props.dispatch(updateMovie(this.props.selectedMovie));
+      } else {
+        console.log("feltene er ikke fylt ut");
+      }
+    } else {
+      this.props.dispatch({ type: "OPEN_REVIEW", payload: true });
+    }
+  };
+
+  render() {
+    let movie = this.props.selectedMovie;
+    const { classes } = this.props;
+
+    return (
+      <div>
+        <div
+          className={classes.exitButton}
+          onClick={this.hideDetails}
+          onMouseEnter={this.hover}
+          onMouseLeave={this.unHover}
+        >
+          <MaterialIcon
+            key={this.props.hover ? 1 : 2}
+            icon="close"
+            color={this.props.hover ? "white" : "rgb(50,50,50"}
+            size={20}
+          />
+        </div>
+        <img
+          src={"https://image.tmdb.org/t/p/original" + movie.backdrop_path}
+          width={"100%"}
+          alt={movie.title}
+          className={classes.backdrop}
+        />
+        <div className={classes.movieCard}>
+          <Grid container spacing={0} style={{ margin: 0 }}>
+            <Grid item xs={5}>
+              <img
+                src={"https://image.tmdb.org/t/p/w500" + movie.poster_path}
+                alt={movie.title}
+                className={classes.poster}
+              />
+            </Grid>
+            <Grid item xs style={{ padding: "24px" }}>
+              <span
+                className={classes.header}
+                style={{ display: "inline-block" }}
+              >
+                {String(movie.title).toUpperCase()}
+              </span>
+              <br />
+              <span
+                onClick={this.searchByYear}
+                className={classes.link}
+                style={{ cursor: "pointer" }}
+              >
+                {movie.year}
+              </span>
+              &nbsp; {"Directed by "}
+              {movie.director.map((director, index) => (
+                <span>
+                  <span
+                    className={classes.link}
+                    style={{ cursor: "pointer" }}
+                    onClick={() =>
+                      this.props.dispatch({
+                        type: "SHOW_MOVIE_LIST",
+                        showMovies: true
+                      })
+                    }
+                  >
+                    {director.name}
+                  </span>
+                  {movie.director.length !== index + 1 && ", "}
+                </span>
+              ))}
+              {averageRating(movie.feedbackList) > 0 && (
+                <span>
+                  <RatingComponent
+                    rating={averageRating(movie.feedbackList)}
+                    text1="User"
+                    text2={movie.feedbackList.length}
+                  />
+                </span>
+              )}
+              <RatingComponent
+                text1={"IMDb"}
+                text2={movie.vote_count}
+                rating={movie.vote_average}
+              />
+              <span className={classes.greenHeader}>{movie.tagline}</span>
+              <span> {movie.overview} </span>
+              <span className={classes.greenHeader}>
+                {printList(movie.genres)}
+              </span>
+              <span>{printList(movie.production_companies)}</span>
+              <span className={classes.greenHeader}> Cast </span>{" "}
+              {movie.cast.slice(0, 10).map((cast, index) => (
+                <span>
+                  <span className={classes.link}>{cast.name}</span>
+                  {index !== 9 && ", "}
+                </span>
+              ))}
+              <br />
+              <hr style={{ marginBottom: 3, marginTop: 30 }} size={1} />
+              {this.props.openReview && (
+                <AddReviewComponent classes={classes} />
+              )}
+              {!this.props.openReview && (
+                <span style={{ paddingRight: "5%" }}>
+                  <br />
+                  Rate {movie.title}
+                  <span>
+                    &nbsp;
+                    {"- User rating: "}
+                    {averageRating(movie.feedbackList) > 0 ? (
+                      <span>
+                        {averageRating(movie.feedbackList)}
+                        <span style={{ fontSize: "0.65em" }}>/10</span>
+                        <span
+                          style={{
+                            fontSize: "0.7em",
+                            color: "rgb(200,200,200)"
+                          }}
+                        >
+                          (votes: {movie.feedbackList.length})
+                        </span>
+                      </span>
+                    ) : (
+                      "No users have voted"
+                    )}
+                  </span>
+                  <br />
+                  <StarRatings
+                    id="rating-input"
+                    rating={this.props.rating}
+                    starRatedColor="#C39400"
+                    starHoverColor="#C39400"
+                    changeRating={this.changeRating}
+                    name="rating-input"
+                    numberOfStars={10}
+                    starDimension="25px"
+                    starSpacing="1px"
+                  />
+                  <br />
+                  <br />
+                  <Button onClick={this.addRating} variant="contained">
+                    rate
+                  </Button>
+                </span>
+              )}
+              <span>
+                <Button onClick={this.addReview} variant="contained">
+                  {this.props.openReview ? "post review" : "add review"}
+                </Button>
+              </span>
+              <br />
+              <br />
+              <ReviewsComponent
+                feedbackList={movie.feedbackList.filter(fb => fb.name !== "")}
+                averageUserScore={averageRating(
+                  movie.feedbackList.filter(fb => fb.name !== "")
+                )}
+              />
+            </Grid>
+          </Grid>
+        </div>
+      </div>
+    );
+  }
+}
+
+function printList(list) {
+  let string = "";
+  for (let i = 0; i < list.length; i++) {
+    string += list[i];
+    if (i !== list.length - 1) {
+      string += ", ";
+    }
+  }
+  return string;
+}
+
+function averageRating(feedbackList) {
+  let total = 0;
+  for (let i = 0; i < feedbackList.length; i++) {
+    total += feedbackList[i].rating;
+  }
+  return (total / feedbackList.length).toFixed(1);
+}
+
+MovieDetailsContent.propTypes = {
+  classes: PropTypes.object.isRequired
+};
+
+const styles = theme => ({
+  paper: {
+    position: "absolute",
+    top: "50%",
+    left: "50%",
+    transform: "translate(-50%, -50%) !important",
+    width: "85%",
+    height: "auto",
+    minHeight: "75%",
+    backgroundColor: "black",
+    boxShadow: theme.shadows[5],
+    margin: "0 auto",
+    outline: "none"
+  },
+  backdrop: {
+    opacity: "0.8",
+    filter: "blur(3px)"
+  },
+  movieCard: {
+    color: "white",
+    fontFamily: "Oswald",
+    fontSize: "1em",
+    backgroundColor: "rgba(0,0,0,0.75)",
+    position: "absolute",
+    top: "50%",
+    left: "50%",
+    transform: "translate(-50%, -50%) !important",
+    width: "60%",
+    height: "66%",
+    overflowY: "scroll",
+    outline: "none"
+  },
+  poster: {
+    width: "100%",
+    position: "-webkit-sticky",
+    position: "sticky",
+    top: 0
+  },
+  header: {
+    fontFamily: "Lato",
+    fontWeight: "bold",
+    fontSize: "2.2em",
+    margin: 0,
+    display: "inline"
+  },
+  greenHeader: {
+    display: "block",
+    marginTop: "1em",
+    color: "#02FB87",
+    fontSize: "1.3em",
+    fontFamily: "Oswald",
+    fontWeight: "normal"
+  },
+  textInput: {
+    color: "white"
+  },
+  bootstrapRoot: {
+    "label + &": {
+      marginTop: theme.spacing.unit * 3
+    }
+  },
+  bootstrapInput: {
+    borderRadius: 4,
+    backgroundColor: "rgb(200,200,200)",
+    border: "1px solid #ced4da",
+    fontSize: 16,
+    padding: "10px 12px",
+    transition: theme.transitions.create(["border-color", "box-shadow"])
+  },
+  bootstrapFormLabel: {
+    fontSize: 18,
+    color: "white",
+    "&:focus": {
+      color: "white"
+    }
+  },
+  margin: {
+    margin: theme.spacing.unit
+  },
+  link: {
+    color: "white",
+    textDecoration: "underline"
+  },
+
+  exitButton: {
+    cursor: "pointer",
+    height: "20px",
+    width: "20px",
+    zIndex: 5,
+    position: "absolute",
+    right: "20%",
+    top: "14%",
+    borderRadius: "50%",
+    textAlign: "center",
+    transform: "translate(30%, 80%) !important",
+    backgroundColor: "#02FB87",
+    boxShadow: "-2px 2px 3px"
+  },
+  exitForm: {
+    float: "right",
+    cursor: "pointer"
+  }
+});
+
+const mapStateToProps = state => ({
+  movies: state.search.movies,
+  selectedMovie: state.selectMovie.selectedMovie,
+  cachedImages: state.selectMovie.cachedImages,
+  name: state.textField.name,
+  rating: state.textField.rating,
+  review: state.textField.review,
+  hover: state.closeButton.hover,
+  openReview: state.textField.openReview,
+  searchText: state.textField.text,
+  movies: state.search.movies,
+  selectedYear: state.yearField.selectedYear,
+  years: state.yearField.years,
+  selectedGenre: state.genreField.selectedGenre,
+  genres: state.genreField.genres,
+  sortedMovies: state.sort.sortedMovies,
+  page: state.pageReducer,
+  fetching: state.search.fetching,
+  returnedNull: state.search.returnedNull,
+  sortAlph: state.sort.sortAlph,
+  sortYear: state.sort.sortYear,
+  sortRating: state.sort.sortRating
+});
+
+export default connect(mapStateToProps)(
+  withStyles(styles)(MovieDetailsContent)
+);
-- 
GitLab


From d2ca02223ab5779f5cb8f6ab2f0c8075647826d0 Mon Sep 17 00:00:00 2001
From: haavarhu <havard.hunshamar@ntnu.no>
Date: Sun, 11 Nov 2018 12:45:33 +0100
Subject: [PATCH 2/4] Choose year to search from moviedetails #43

---
 .../src/components/MovieDetailsComponent.js   | 241 +-----------------
 moviesearch/src/reducers/yearReducer.js       |   2 +-
 2 files changed, 12 insertions(+), 231 deletions(-)

diff --git a/moviesearch/src/components/MovieDetailsComponent.js b/moviesearch/src/components/MovieDetailsComponent.js
index 8c91f2d..db669ce 100644
--- a/moviesearch/src/components/MovieDetailsComponent.js
+++ b/moviesearch/src/components/MovieDetailsComponent.js
@@ -2,15 +2,10 @@ import React, { Component } from "react";
 import Modal from "@material-ui/core/Modal";
 import { withStyles } from "@material-ui/core/styles";
 import PropTypes from "prop-types";
-import Grid from "@material-ui/core/Grid";
 import { connect } from "react-redux";
-import Button from "@material-ui/core/Button";
-import { updateMovie } from "../actions/updateMovieAction";
 import { nextMovie, prevMovie } from "../actions/browseMoviesAction";
-import MaterialIcon from "material-icons-react";
-import RatingComponent from "./RatingComponent";
-import ReviewsComponent from "./ReviewsComponent";
-import AddReviewComponent from "./AddReviewComponent";
+import MovieDetailsContent from "./MovieDetailsContent";
+import MovieListComponent from "./MovieListComponent";
 
 class MovieDetailsComponent extends Component {
   handleKeyPress = event => {
@@ -35,30 +30,7 @@ class MovieDetailsComponent extends Component {
     this.props.dispatch({ type: "UNSELECT_MOVIE" });
     this.props.dispatch({ type: "RESET_REVIEW_FIELDS" });
     this.props.dispatch({ type: "SET_HOVER", payload: false });
-  };
-
-  hover = () => {
-    this.props.dispatch({ type: "SET_HOVER", payload: true });
-  };
-  unHover = () => {
-    this.props.dispatch({ type: "SET_HOVER", payload: false });
-  };
-
-  addReview = () => {
-    if (this.props.openReview) {
-      if (this.props.rating > 0) {
-        this.props.selectedMovie["feedbackList"].push({
-          name: this.props.name.trim(),
-          rating: this.props.rating,
-          review: this.props.review.trim()
-        });
-        this.props.dispatch(updateMovie(this.props.selectedMovie));
-      } else {
-        console.log("feltene er ikke fylt ut");
-      }
-    } else {
-      this.props.dispatch({ type: "OPEN_REVIEW", payload: true });
-    }
+    this.props.dispatch({ type: "SHOW_MOVIE_LIST", showMovieList: false });
   };
 
   render() {
@@ -71,116 +43,18 @@ class MovieDetailsComponent extends Component {
         onBackdropClick={this.hideDetails}
         onEscapeKeyDown={this.hideDetails}
       >
-        {movie != null && (
-          <div className={classes.paper} onKeyDown={this.handleKeyPress}>
-            <div
-              className={classes.exitButton}
-              onClick={this.hideDetails}
-              onMouseEnter={this.hover}
-              onMouseLeave={this.unHover}
-            >
-              <MaterialIcon
-                key={this.props.hover ? 1 : 2}
-                icon="close"
-                color={this.props.hover ? "white" : "rgb(50,50,50"}
-                size={20}
-              />
-            </div>
-            <img
-              src={"https://image.tmdb.org/t/p/original" + movie.backdrop_path}
-              width={"100%"}
-              alt={movie.title}
-              className={classes.backdrop}
-            />
-            <div className={classes.movieCard}>
-              <Grid container spacing={0} style={{ margin: 0 }}>
-                <Grid item xs={5}>
-                  <img
-                    src={"https://image.tmdb.org/t/p/w500" + movie.poster_path}
-                    alt={movie.title}
-                    className={classes.poster}
-                  />
-                </Grid>
-                <Grid item xs style={{ padding: "24px" }}>
-                  <span
-                    className={classes.header}
-                    style={{ display: "inline-block" }}
-                  >
-                    {String(movie.title).toUpperCase()}
-                  </span>
-                  <br />
-                  <span className={classes.link}>{movie.year}</span>
-                  &nbsp; {"Directed by "}
-                  {movie.director.map((director, index) => (
-                    <span>
-                      <span className={classes.link}>{director.name}</span>
-                      {movie.director.length !== index + 1 && ", "}
-                    </span>
-                  ))}
-                  <RatingComponent rating={movie.vote_average} />
-                  {averageRating(movie.feedbackList) > 0 && (
-                    <RatingComponent
-                      rating={averageRating(movie.feedbackList)}
-                    />
-                  )}
-                  <span className={classes.greenHeader}>{movie.tagline}</span>
-                  <span> {movie.overview} </span>
-                  <span className={classes.greenHeader}>
-                    {printList(movie.genres)}
-                  </span>
-                  <span>{printList(movie.production_companies)}</span>
-                  <span className={classes.greenHeader}> Cast </span>{" "}
-                  {movie.cast.slice(0, 10).map((cast, index) => (
-                    <span>
-                      <span className={classes.link}>{cast.name}</span>
-                      {index !== 9 && ", "}
-                    </span>
-                  ))}
-                  <br />
-                  {this.props.openReview && (
-                    <AddReviewComponent classes={classes} />
-                  )}
-                  <br />
-                  <Button onClick={this.addReview} variant="contained">
-                    {this.props.openReview ? "post review" : "add review"}
-                  </Button>
-                  <br />
-                  <br />
-                  <ReviewsComponent
-                    feedbackList={movie.feedbackList.filter(
-                      fb => fb.name !== ""
-                    )}
-                    averageUserScore={averageRating(movie.feedbackList)}
-                  />
-                </Grid>
-              </Grid>
-            </div>
-          </div>
-        )}
+        <div className={classes.paper} onKeyDown={this.handleKeyPress}>
+          {movie != null && !this.props.showMovies ? (
+            <MovieDetailsContent />
+          ) : (
+            <MovieListComponent />
+          )}
+        </div>
       </Modal>
     );
   }
 }
 
-function printList(list) {
-  let string = "";
-  for (let i = 0; i < list.length; i++) {
-    string += list[i];
-    if (i !== list.length - 1) {
-      string += ", ";
-    }
-  }
-  return string;
-}
-
-function averageRating(feedbackList) {
-  let total = 0;
-  for (let i = 0; i < feedbackList.length; i++) {
-    total += feedbackList[i].rating;
-  }
-  return (total / feedbackList.length).toFixed(1);
-}
-
 MovieDetailsComponent.propTypes = {
   classes: PropTypes.object.isRequired
 };
@@ -198,106 +72,13 @@ const styles = theme => ({
     boxShadow: theme.shadows[5],
     margin: "0 auto",
     outline: "none"
-  },
-  backdrop: {
-    opacity: "0.8",
-    filter: "blur(3px)"
-  },
-  movieCard: {
-    color: "white",
-    fontFamily: "Oswald",
-    fontSize: "1em",
-    backgroundColor: "rgba(0,0,0,0.75)",
-    position: "absolute",
-    top: "50%",
-    left: "50%",
-    transform: "translate(-50%, -50%) !important",
-    width: "60%",
-    height: "66%",
-    overflowY: "scroll",
-    outline: "none"
-  },
-  poster: {
-    width: "100%",
-    position: "-webkit-sticky",
-    position: "sticky",
-    top: 0
-  },
-  header: {
-    fontFamily: "Lato",
-    fontWeight: "bold",
-    fontSize: "2.2em",
-    margin: 0,
-    display: "inline"
-  },
-  greenHeader: {
-    display: "block",
-    marginTop: "1em",
-    color: "#02FB87",
-    fontSize: "1.3em",
-    fontFamily: "Oswald",
-    fontWeight: "normal"
-  },
-  textInput: {
-    color: "white"
-  },
-  bootstrapRoot: {
-    "label + &": {
-      marginTop: theme.spacing.unit * 3
-    }
-  },
-  bootstrapInput: {
-    borderRadius: 4,
-    backgroundColor: "rgb(200,200,200)",
-    border: "1px solid #ced4da",
-    fontSize: 16,
-    padding: "10px 12px",
-    transition: theme.transitions.create(["border-color", "box-shadow"])
-  },
-  bootstrapFormLabel: {
-    fontSize: 18,
-    color: "white",
-    "&:focus": {
-      color: "white"
-    }
-  },
-  margin: {
-    margin: theme.spacing.unit
-  },
-  link: {
-    color: "white",
-    textDecoration: "underline"
-  },
-
-  exitButton: {
-    cursor: "pointer",
-    height: "20px",
-    width: "20px",
-    zIndex: 5,
-    position: "absolute",
-    right: "20%",
-    top: "14%",
-    borderRadius: "50%",
-    textAlign: "center",
-    transform: "translate(30%, 80%) !important",
-    backgroundColor: "#02FB87",
-    boxShadow: "-2px 2px 3px"
-  },
-  exitForm: {
-    float: "right",
-    cursor: "pointer"
   }
 });
 
 const mapStateToProps = state => ({
   movies: state.search.movies,
   selectedMovie: state.selectMovie.selectedMovie,
-  cachedImages: state.selectMovie.cachedImages,
-  name: state.textField.name,
-  rating: state.textField.rating,
-  review: state.textField.review,
-  hover: state.closeButton.hover,
-  openReview: state.textField.openReview
+  showMovies: state.showMovies.showMovies
 });
 
 export default connect(mapStateToProps)(
diff --git a/moviesearch/src/reducers/yearReducer.js b/moviesearch/src/reducers/yearReducer.js
index 80c769a..59f8d7c 100644
--- a/moviesearch/src/reducers/yearReducer.js
+++ b/moviesearch/src/reducers/yearReducer.js
@@ -3,7 +3,7 @@ const initialState = {
   selectedYear: "None"
 };
 
-for (let i = 1980; i < 2019; i++) {
+for (let i = 2018; i > 1918; i--) {
   initialState.years.push(String(i));
 }
 
-- 
GitLab


From 141f812fbe124f9e98d2c889a04cbc9bcfefdb44 Mon Sep 17 00:00:00 2001
From: haavarhu <havard.hunshamar@ntnu.no>
Date: Sun, 11 Nov 2018 12:46:35 +0100
Subject: [PATCH 3/4] improved rating/reviewing #19

---
 .../src/components/AddReviewComponent.js      |  3 +-
 moviesearch/src/components/RatingComponent.js | 58 ++++++++++++++-----
 .../src/components/ReviewsComponent.js        | 31 ++++++----
 3 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/moviesearch/src/components/AddReviewComponent.js b/moviesearch/src/components/AddReviewComponent.js
index 5dd850a..8789891 100644
--- a/moviesearch/src/components/AddReviewComponent.js
+++ b/moviesearch/src/components/AddReviewComponent.js
@@ -14,7 +14,7 @@ class AddReviewComponent extends Component {
   updateName = event => {
     this.props.dispatch({
       type: "UPDATE_NAME",
-      name: event.target.value
+      name: event.target.value.trim()
     });
   };
 
@@ -32,7 +32,6 @@ class AddReviewComponent extends Component {
   render() {
     return (
       <div>
-        <hr style={{ marginBottom: 3, marginTop: 30 }} size={1} />
         <div className={this.props.classes.exitForm} onClick={this.hideReview}>
           <MaterialIcon key={1} icon="close" color={"white"} size={20} />
         </div>
diff --git a/moviesearch/src/components/RatingComponent.js b/moviesearch/src/components/RatingComponent.js
index 9046708..28d9412 100644
--- a/moviesearch/src/components/RatingComponent.js
+++ b/moviesearch/src/components/RatingComponent.js
@@ -7,22 +7,52 @@ class RatingComponent extends Component {
       <span
         style={{
           float: "right",
-          display: "inline-block"
+          display: "inline-block",
+          margin: "2%"
         }}
       >
-        <StarRatings
-          rating={1}
-          numberOfStars={1}
-          starDimension="1.2em"
-          starRatedColor="#C39400"
-        />{" "}
-        <span>
-          <span style={{ fontSize: "1.2em" }}>{this.props.rating}</span>
-          <span style={{ fontSize: "0.8em", color: "rgb(200,200,200)" }}>
-            /10
-          </span>
-          <br />
-        </span>
+        <div style={{ display: "flex" }}>
+          <div style={{ lineHeight: "1.8em" }}>
+            <StarRatings
+              rating={1}
+              numberOfStars={1}
+              starDimension="1.2em"
+              starRatedColor="#C39400"
+            />
+            {this.props.text1 && (
+              <div
+                style={{
+                  fontSize: "0.7em",
+                  textAlign: "center",
+                  position: "relative",
+                  top: "-1.2em"
+                }}
+              >
+                {this.props.text1}
+              </div>
+            )}
+          </div>
+          <div style={{ paddingLeft: "3px" }}>
+            <span>
+              <span style={{ fontSize: "1.2em" }}>{this.props.rating}</span>
+              <span style={{ fontSize: "0.8em", color: "rgb(200,200,200)" }}>
+                /10
+              </span>
+              <br />
+            </span>
+            <div
+              style={{
+                fontWeight: 50,
+                fontSize: "0.7em",
+                position: "relative",
+                top: "-0.5em",
+                color: "rgb(200,200,200)"
+              }}
+            >
+              <span>{this.props.text2}</span>
+            </div>
+          </div>
+        </div>
       </span>
     );
   }
diff --git a/moviesearch/src/components/ReviewsComponent.js b/moviesearch/src/components/ReviewsComponent.js
index 5938e15..eed1812 100644
--- a/moviesearch/src/components/ReviewsComponent.js
+++ b/moviesearch/src/components/ReviewsComponent.js
@@ -6,18 +6,25 @@ class ReviewsComponent extends Component {
     return (
       <div>
         <span>REVIEWS</span>
-        {this.props.feedbackList.length > 1 && (
-          <span style={{ float: "right" }}>
-            <span style={{ fontSize: "0.8em" }}>Score:</span>
-            &nbsp;
-            <StarRatings
-              rating={1}
-              numberOfStars={1}
-              starDimension="20px"
-              starRatedColor="#C39400"
-            />
-            {this.props.averageUserScore}
-            <span style={{ fontSize: "0.65em" }}>/10</span>
+        {this.props.feedbackList.length > 0 && (
+          <span>
+            <span style={{ color: "rgb(200,200,200)" }}>
+              {" (" + this.props.feedbackList.length})
+            </span>
+            <span style={{ float: "right" }}>
+              <span style={{ fontSize: "0.8em" }}>
+                Average reviewer rating:
+              </span>
+              &nbsp;
+              <StarRatings
+                rating={1}
+                numberOfStars={1}
+                starDimension="20px"
+                starRatedColor="#C39400"
+              />
+              {this.props.averageUserScore}
+              <span style={{ fontSize: "0.65em" }}>/10</span>
+            </span>
           </span>
         )}
         <hr style={{ marginTop: 3 }} size={2} />
-- 
GitLab


From 90d04b09544df12eb6fb92827a719d5b8d5ab781 Mon Sep 17 00:00:00 2001
From: haavarhu <havard.hunshamar@ntnu.no>
Date: Sun, 11 Nov 2018 12:48:59 +0100
Subject: [PATCH 4/4] Added list of movies by director in moviedetails #44

---
 controllers/movie.sort.controller.js          |  6 +-
 models/movie.server.model.js                  | 13 ++-
 moviesearch/public/index.html                 | 40 +++++---
 .../src/actions/getDirectorMoviesAction.js    | 20 ++++
 moviesearch/src/actions/sortMoviesAction.js   |  3 +-
 .../src/components/MovieListComponent.js      | 99 +++++++++++++++++++
 moviesearch/src/reducers/index.js             |  4 +-
 moviesearch/src/reducers/searchReducer.js     |  9 +-
 .../src/reducers/selectMovieReducer.js        | 73 +++++++-------
 routes/movie.search.route.js                  |  4 +-
 routes/movie.sort.route.js                    |  6 +-
 11 files changed, 218 insertions(+), 59 deletions(-)
 create mode 100644 moviesearch/src/actions/getDirectorMoviesAction.js
 create mode 100644 moviesearch/src/components/MovieListComponent.js

diff --git a/controllers/movie.sort.controller.js b/controllers/movie.sort.controller.js
index cf126ad..8d7bea1 100644
--- a/controllers/movie.sort.controller.js
+++ b/controllers/movie.sort.controller.js
@@ -6,7 +6,11 @@ export const sortMovies = (req, res) => {
   if (req.params.text !== "None") {
     console.log(req.params.text);
     let regex = new RegExp(req.params.text, "i");
-    request["original_title"] = regex;
+    request["title"] = regex;
+  }
+  if (req.params.director !== "None") {
+    let regex = new RegExp(req.params.director, "i");
+    request["director.name"] = regex;
   }
   if (req.params.year !== "None") {
     request["year"] = req.params.year;
diff --git a/models/movie.server.model.js b/models/movie.server.model.js
index df4c056..9935d2a 100644
--- a/models/movie.server.model.js
+++ b/models/movie.server.model.js
@@ -5,12 +5,15 @@ var movieSchema = mongoose.Schema({
   _id: Number,
   original_title: String,
   year: String,
+  director: [{ name: String, id: Number }],
   genres: [String],
-  feedbackList: [{
-    name: String,
-    rating: Number,
-    review: String,
-  }]
+  feedbackList: [
+    {
+      name: String,
+      rating: Number,
+      review: String
+    }
+  ]
 });
 
 var Movie = mongoose.model("movies", movieSchema);
diff --git a/moviesearch/public/index.html b/moviesearch/public/index.html
index 6edba60..9b59a77 100644
--- a/moviesearch/public/index.html
+++ b/moviesearch/public/index.html
@@ -1,22 +1,36 @@
 <!DOCTYPE html>
 <html lang="en">
   <head>
-    <meta charset="utf-8">
-    <link rel="shortcut icon" href="%PUBLIC_URL%/movie.png">
-    <link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
-    <link href="https://fonts.googleapis.com/css?family=Lato:700" rel="stylesheet">
-    <link href="https://fonts.googleapis.com/css?family=Oswald:300" rel="stylesheet">
-    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <meta name="theme-color" content="#000000">
-    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
+    <meta charset="utf-8" />
+    <link rel="shortcut icon" href="%PUBLIC_URL%/movie.png" />
+    <link
+      href="https://fonts.googleapis.com/css?family=Raleway"
+      rel="stylesheet"
+    />
+    <link
+      href="https://fonts.googleapis.com/css?family=Lato:700"
+      rel="stylesheet"
+    />
+    <link
+      href="https://fonts.googleapis.com/css?family=Oswald:300"
+      rel="stylesheet"
+    />
+    <link
+      rel="stylesheet"
+      href="https://use.fontawesome.com/releases/v5.4.2/css/all.css"
+      integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns"
+      crossorigin="anonymous"
+    />
+    <meta
+      name="viewport"
+      content="width=device-width, initial-scale=1, shrink-to-fit=no"
+    />
+    <meta name="theme-color" content="#000000" />
+    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
     <title>MovieSearch</title>
   </head>
   <body>
-    <noscript>
-      You need to enable JavaScript to run this app.
-    </noscript>
+    <noscript> You need to enable JavaScript to run this app. </noscript>
     <div id="root"></div>
-   
   </body>
 </html>
diff --git a/moviesearch/src/actions/getDirectorMoviesAction.js b/moviesearch/src/actions/getDirectorMoviesAction.js
new file mode 100644
index 0000000..eb2cdcc
--- /dev/null
+++ b/moviesearch/src/actions/getDirectorMoviesAction.js
@@ -0,0 +1,20 @@
+export function getDirectorMovies(director) {
+  return function(dispatch) {
+    fetch("http://localhost:3001/sort/vote_average/None/None/None/" + director)
+      .then(response => response.json())
+      .then(data => {
+        /*if (sortBy === "vote_average") {
+            data.movie = data.movie.filter(function(n) {
+              return n.vote_count > 1000;
+            });
+          }*/
+        dispatch({
+          type: "RECEIVE_DIRECTOR_MOVIES",
+          payload: data.movie
+        });
+      })
+      .catch(err => {
+        dispatch({ type: "FAILED_SORT", payload: err });
+      });
+  };
+}
diff --git a/moviesearch/src/actions/sortMoviesAction.js b/moviesearch/src/actions/sortMoviesAction.js
index 133bbc5..6ea370b 100644
--- a/moviesearch/src/actions/sortMoviesAction.js
+++ b/moviesearch/src/actions/sortMoviesAction.js
@@ -8,7 +8,8 @@ export function sortMovies(text, year, genre, sortBy) {
         "/" +
         year +
         "/" +
-        genre
+        genre +
+        "/None"
     )
       .then(response => response.json())
       .then(data => {
diff --git a/moviesearch/src/components/MovieListComponent.js b/moviesearch/src/components/MovieListComponent.js
new file mode 100644
index 0000000..3061083
--- /dev/null
+++ b/moviesearch/src/components/MovieListComponent.js
@@ -0,0 +1,99 @@
+import React, { Component } from "react";
+import { withStyles } from "@material-ui/core/styles";
+import { connect } from "react-redux";
+import MovieCardComponent from "./MovieCardComponent";
+import MaterialIcon from "material-icons-react";
+import { getDirectorMovies } from "../actions/getDirectorMoviesAction";
+
+class MovieListComponent extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {};
+  }
+
+  componentDidMount() {
+    this.props.dispatch(
+      getDirectorMovies(this.props.selectedMovie.director[0].name)
+    );
+  }
+
+  render() {
+    const { classes } = this.props;
+    return (
+      <div>
+        <div
+          className={classes.exitButton}
+          onClick={this.hideDetails}
+          onMouseEnter={this.hover}
+          onMouseLeave={this.unHover}
+        >
+          <MaterialIcon
+            key={this.props.hover ? 1 : 2}
+            icon="close"
+            color={this.props.hover ? "white" : "rgb(50,50,50"}
+            size={20}
+          />
+        </div>
+        <img
+          src={
+            "https://image.tmdb.org/t/p/original" +
+            this.props.selectedMovie.backdrop_path
+          }
+          width={"100%"}
+          alt={this.props.selectedMovie.title}
+          className={classes.backdrop}
+        />
+        <div className={classes.movieCard}>
+          {this.props.directorMovies.slice(0, 10).map(movie => (
+            <MovieCardComponent movie={movie} key={movie._id} />
+          ))}
+        </div>
+      </div>
+    );
+  }
+}
+
+MovieListComponent.propTypes = {};
+
+const styles = theme => ({
+  movieCard: {
+    color: "white",
+    fontFamily: "Oswald",
+    fontSize: "1em",
+    backgroundColor: "rgba(0,0,0,0.75)",
+    position: "absolute",
+    top: "50%",
+    left: "50%",
+    transform: "translate(-50%, -50%) !important",
+    width: "60%",
+    height: "66%",
+    overflowY: "scroll",
+    outline: "none"
+  },
+  backdrop: {
+    opacity: "0.8",
+    filter: "blur(3px)"
+  },
+  exitButton: {
+    cursor: "pointer",
+    height: "20px",
+    width: "20px",
+    zIndex: 5,
+    position: "absolute",
+    right: "20%",
+    top: "14%",
+    borderRadius: "50%",
+    textAlign: "center",
+    transform: "translate(30%, 80%) !important",
+    backgroundColor: "#02FB87",
+    boxShadow: "-2px 2px 3px"
+  }
+});
+
+const mapStateToProps = state => ({
+  movies: state.search.movies,
+  selectedMovie: state.selectMovie.selectedMovie,
+  directorMovies: state.search.directorMovies
+});
+
+export default connect(mapStateToProps)(withStyles(styles)(MovieListComponent));
diff --git a/moviesearch/src/reducers/index.js b/moviesearch/src/reducers/index.js
index 58fee7a..b61b2e5 100644
--- a/moviesearch/src/reducers/index.js
+++ b/moviesearch/src/reducers/index.js
@@ -7,7 +7,8 @@ import genreField from "./genreReducer";
 import selectMovie from "./selectMovieReducer";
 import cacheImages from "./selectMovieReducer";
 import pageReducer from "./pageReducer";
-import closeButton from "./closeButtonReducer"
+import closeButton from "./closeButtonReducer";
+import showMovies from "./selectMovieReducer";
 
 export default combineReducers({
   search,
@@ -19,4 +20,5 @@ export default combineReducers({
   genreField,
   pageReducer,
   closeButton,
+  showMovies
 });
diff --git a/moviesearch/src/reducers/searchReducer.js b/moviesearch/src/reducers/searchReducer.js
index 80384b4..643341d 100644
--- a/moviesearch/src/reducers/searchReducer.js
+++ b/moviesearch/src/reducers/searchReducer.js
@@ -3,7 +3,8 @@ const initialState = {
   fetched: false,
   movies: [],
   returnedNull: false,
-  error: null
+  error: null,
+  directorMovies: []
 };
 
 export default function reducer(state = initialState, action) {
@@ -33,6 +34,12 @@ export default function reducer(state = initialState, action) {
         };
       }
     }
+    case "RECEIVE_DIRECTOR_MOVIES": {
+      return {
+        ...state,
+        directorMovies: action.payload
+      };
+    }
     case "FAILED_FETCH": {
       return {
         ...state,
diff --git a/moviesearch/src/reducers/selectMovieReducer.js b/moviesearch/src/reducers/selectMovieReducer.js
index 2bcd018..a5677b6 100644
--- a/moviesearch/src/reducers/selectMovieReducer.js
+++ b/moviesearch/src/reducers/selectMovieReducer.js
@@ -1,37 +1,42 @@
 const initialState = {
-    selectedMovie : null,
-    cachedImages: null
-  };
-  
-  export default function reducer(state = initialState, action) {
-    switch (action.type) {
-      case "SELECT_MOVIE": {
-        return {
-          ...state,
-          selectedMovie: action.selectedMovie
-        }
-      }
-      case "UNSELECT_MOVIE": {
-        return {
-          ...state,
-          selectedMovie: null
-        }
-      }
-      case "ADD_FEEDBACK": {
-        
-        return {
-          ...state,
-          selectedMovie: action.updatedMovie,
-        }
-      }
-      case "CACHE_IMAGES": {
-        return {
-          ...state,
-          cachedImages: action.cachedImages
-        }
-      }
-      default:
-        return state
+  selectedMovie: null,
+  cachedImages: null,
+  showMovies: false
+};
+
+export default function reducer(state = initialState, action) {
+  switch (action.type) {
+    case "SELECT_MOVIE": {
+      return {
+        ...state,
+        selectedMovie: action.selectedMovie
+      };
     }
+    case "UNSELECT_MOVIE": {
+      return {
+        ...state,
+        selectedMovie: null
+      };
+    }
+    case "SHOW_MOVIE_LIST": {
+      return {
+        ...state,
+        showMovies: action.showMovies
+      };
+    }
+    case "ADD_FEEDBACK": {
+      return {
+        ...state,
+        selectedMovie: action.updatedMovie
+      };
+    }
+    case "CACHE_IMAGES": {
+      return {
+        ...state,
+        cachedImages: action.cachedImages
+      };
+    }
+    default:
+      return state;
   }
-  
\ No newline at end of file
+}
diff --git a/routes/movie.search.route.js b/routes/movie.search.route.js
index a42ab36..be7d2ee 100644
--- a/routes/movie.search.route.js
+++ b/routes/movie.search.route.js
@@ -3,6 +3,8 @@ import * as movieSearchController from "../controllers/movie.search.controller";
 
 // get an instance of express router and send request to movie controller functions
 const router = express.Router();
-router.route("/:text/:year/:genre").get(movieSearchController.getMovie);
+router
+  .route("/:text/:year/:genre/director")
+  .get(movieSearchController.getMovie);
 
 export default router;
diff --git a/routes/movie.sort.route.js b/routes/movie.sort.route.js
index a08f0dc..9a18c62 100644
--- a/routes/movie.sort.route.js
+++ b/routes/movie.sort.route.js
@@ -3,6 +3,8 @@ import * as movieSortController from "../controllers/movie.sort.controller";
 
 // get an instance of express router and send request to movie controller functions
 const router = express.Router();
-router.route("/:sortBy/:text/:year/:genre").get(movieSortController.sortMovies);
+router
+  .route("/:sortBy/:text/:year/:genre/:director")
+  .get(movieSortController.sortMovies);
 
-export default router;
\ No newline at end of file
+export default router;
-- 
GitLab