diff --git a/package.json b/package.json index 863890a..0f3635c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "muicss": "^0.9.12", "react": "^15.4.2", "react-dom": "^15.4.2", - "react-rating": "^0.6.5" + "react-rating": "^0.6.5", + "axios": "^0.16.1" }, "devDependencies": { "gh-pages": "^0.12.0", diff --git a/src/App.css b/src/App.css index c61bc6e..3668cc2 100644 --- a/src/App.css +++ b/src/App.css @@ -164,3 +164,9 @@ .App .overlay .add-movie-container .add-movie-form .mui-textfield>textarea:focus~label { color: #FF424F; } + +.fit { + object-fit: cover; + object-position: top; + width: 100%; +} diff --git a/src/App.js b/src/App.js index 1c4d9b8..105fb28 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,6 @@ import React, { Component } from 'react'; import Flexbox from 'flexbox-react'; -import Form from 'muicss/lib/react/form'; -import Input from 'muicss/lib/react/input'; -import Button from 'muicss/lib/react/button'; -import Rating from 'react-rating'; +import AddMovie from './components/addMovie/addMovie'; import './App.css'; @@ -12,8 +9,6 @@ class App extends Component { super(props); this.state = { movies: {}, - showAddMovie: false, - addMovie: {}, }; } @@ -24,41 +19,8 @@ class App extends Component { }); } - addMovie() { - this.setState({ - showAddMovie: true, - }); - } - - addAttr(type, obj) { - const update = {}; - update[type] = obj.currentTarget.value; - this.setState({ - addMovie: Object.assign({}, this.state.addMovie, update) - }); - } - - setRating(rating) { - this.addAttr('rating', { - currentTarget: { - value: rating, - }, - }); - } - - submitNewMovie(e) { - e.preventDefault(); - const updateMovie = {}; - updateMovie[Object.keys(this.state.movies).length + 1] = this.state.addMovie; - const movies = Object.assign({}, this.state.movies, updateMovie); - this.setState({ - movies: movies, - addMovie: {}, - showAddMovie: false, - }); - window.localStorage.setItem('movie-collection', JSON.stringify({ - movies: movies - })); + update(movies) { + this.setState({ movies }) } render() { @@ -74,7 +36,13 @@ class App extends Component { movies.push( {movie.rating} - + + {movie.poster && + + } + {movie.title} @@ -99,12 +67,12 @@ class App extends Component { { + className="add-movie" + onClick={(e) => { e.preventDefault(); - this.addMovie(); + this.child.addMovie(); }} - > + > add @@ -124,40 +92,11 @@ class App extends Component { - - - - Add Movie - - - - - Rating - - - - { - e.preventDefault(); - this.setState({ - showAddMovie: false, - }); - }} - > - Cancel - - Submit - - - - + { this.child = instance; }} + movies={this.state.movies} + update={this.update.bind(this)} + /> ); } diff --git a/src/components/addMovie/addMovie.js b/src/components/addMovie/addMovie.js new file mode 100644 index 0000000..a3fcb81 --- /dev/null +++ b/src/components/addMovie/addMovie.js @@ -0,0 +1,153 @@ +import React, { Component } from 'react'; +import Flexbox from 'flexbox-react'; +import Form from 'muicss/lib/react/form'; +import Input from 'muicss/lib/react/input'; +import Button from 'muicss/lib/react/button'; +import Rating from 'react-rating'; +import axios from 'axios'; + +class AddMovie extends Component { + constructor(props) { + super(props); + this.state = { + showAddMovie: false, + addMovie: {}, + options: [], + }; + } + + submitNewMovie(e) { + e.preventDefault(); + const updateMovie = {}; + updateMovie[Object.keys(this.props.movies).length + 1] = this.state.addMovie; + const movies = Object.assign({}, this.props.movies, updateMovie); + this.setState({ + addMovie: {}, + showAddMovie: false, + }); + this.props.update(movies); + window.localStorage.setItem('movie-collection', JSON.stringify({ + movies: movies + })); + } + + addAttr(type, obj) { + const update = {}; + update[type] = obj.currentTarget.value; + this.setState({ + addMovie: Object.assign({}, this.state.addMovie, update) + }); + + if (type === "title" && update[type].length > 2) { + this.autoComplete(update); + } + } + + autoComplete(update) { + axios.get('https://api.themoviedb.org/3/search/movie', { + params: { + api_key: 'd4b2e5e0e5a46c592a05101bdc4d70fe', + page: 1, + query: update.title, + } + }) + .then((response) => { + this.setState({ + options: response.data.results + }); + + const movie = (response.data.results.length > 0) ? response.data.results[0] : false; + + if (movie) { + update.year = (movie.release_date) ? movie.release_date.split("-")[0] : ""; + update.director = (movie.director) ? movie.director : "No director in DB"; + update.rating = (movie.vote_average) ? movie.vote_average * 5 / 10 : 0; + update.poster = (movie.poster_path) ? 'http://image.tmdb.org/t/p/w185/' + movie.poster_path : 0; + + this.setState({ + addMovie: Object.assign({}, this.state.addMovie, update) + }); + } + }) + .catch((error) => { + console.log(error); + }); + } + + addMovie() { + this.setState({ + showAddMovie: true, + options: [], + }); + } + + setRating(rating) { + this.addAttr('rating', { + currentTarget: { + value: rating, + }, + }); + } + + render() { + let options = []; + if (this.state.options.length > 0) { + this.state.options.forEach((option, id) => { + options.push( + + ); + }) + } + + return ( + + + + Add Movie + + + {options} + + + + + + Rating + + + + { + e.preventDefault(); + this.setState({ + showAddMovie: false, + }); + }} + > + Cancel + + Submit + + + + + ); + } +} + +export default AddMovie; diff --git a/src/components/addMovie/addMovie.test.js b/src/components/addMovie/addMovie.test.js new file mode 100644 index 0000000..dc71aae --- /dev/null +++ b/src/components/addMovie/addMovie.test.js @@ -0,0 +1,31 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import TestUtils from 'react-dom/test-utils'; +import AddMovie from './addMovie'; + +it('Component rendering', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); +}); + +it('Component autocomplete rendering', () => { + const state = { + options: [ + {title: "Movie 1"}, + {title: "Movie 2"}, + ] + }; + const testHTML = ''; + const component = TestUtils.renderIntoDocument( + + ); + component.setState({ + options: state.options, + }); + const options = TestUtils.findRenderedDOMComponentWithTag( + component, 'datalist' + ); + const datalistHTML = ReactDOM.findDOMNode(options).innerHTML; + + expect(datalistHTML).toEqual(testHTML); +});