Use redux in movie list

This commit is contained in:
Grégoire Delattre 2016-11-15 13:47:35 +01:00
parent 535727fdab
commit e13ec0a6ca
7 changed files with 88 additions and 55 deletions

View File

@ -1,7 +1,17 @@
export const ADD_MOVIES = 'ADD_MOVIES'
export const SELECT_MOVIE = 'SELECT_MOVIE'
// Select Movie // Select Movie
export function selectMovie(index) { export function selectMovie(index) {
return { return {
type: "SELECT_MOVIE", type: SELECT_MOVIE,
index index
} }
} }
export function addMovies(movies) {
return {
type: ADD_MOVIES,
movies
}
}

View File

@ -34,7 +34,7 @@ class Main extends React.Component {
function mapStateToProps(state) { function mapStateToProps(state) {
return { return {
movieStore: state.movieStore, movieStore: state.movieStore,
}; }
} }
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {

View File

@ -6,13 +6,17 @@ function MoviePosters(props) {
return ( return (
<div className="col-xs-5 col-md-8"> <div className="col-xs-5 col-md-8">
<div className="row"> <div className="row">
{movies.map((movie, index) => {movies.map(function(movie, index) {
const selected = (index === props.selectedMovieIndex) ? true : false;
return (
<MoviePoster <MoviePoster
data={movie} data={movie}
key={movie.ID} key={movie.ID}
onClick={ (e) => props.onClick(e, index) } selected={selected}
onClick={() => props.onClick(index)}
/> />
)} )}
)}
</div> </div>
</div> </div>
); );
@ -20,7 +24,7 @@ function MoviePosters(props) {
function MoviePoster(props) { function MoviePoster(props) {
const imgUrl = '/img/movies/' + props.data.imdb_id +'.jpg'; const imgUrl = '/img/movies/' + props.data.imdb_id +'.jpg';
const selected = props.data.selected ? ' thumbnail-selected' : ''; const selected = props.selected ? ' thumbnail-selected' : '';
const imgClass = 'thumbnail' + selected; const imgClass = 'thumbnail' + selected;
return ( return (
<div className="col-xs-12 col-md-3"> <div className="col-xs-12 col-md-3">
@ -52,55 +56,29 @@ function MovieDetails(props) {
} }
export default class MovieList extends React.Component { export default class MovieList extends React.Component {
constructor(props) {
super(props);
this.state = {
movies: [],
currentMovie: {},
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e,i) {
e.preventDefault();
let movies = this.state.movies.slice();
this.setMovies(movies, i);
}
setMovies(movies, index) {
let currentMovie = {};
movies.map(function(movie) {
movie.selected = false;
return {movie: movie};
});
if (!index && movies.length) {
index = 0;
currentMovie = movies[0];
}
if (index !== null) {
currentMovie = movies[index];
movies[index].selected = true;
}
this.setState({
movies: movies,
currentMovie: currentMovie,
});
}
componentDidMount() { componentDidMount() {
var _this = this; var _this = this;
this.serverRequest = this.serverRequest =
axios axios
.get("/movies/explore/popular") .get("/movies/explore/popular")
.then(function(result) { .then(function(result) {
_this.setMovies(result.data.Data.movies); _this.props.addMovies(result.data.Data.movies)
}) })
} }
componentWillUnmount() {
this.serverRequest.abort();
}
render() { render() {
const movies = this.props.movieStore.movies;
const index = this.props.movieStore.selectedMovieIndex;
const selectedMovie = movies[index];
return ( return (
<div className="row" id="movie-library"> <div className="row" id="movie-library">
<MoviePosters movies={this.state.movies} onClick={this.handleClick}/> <MoviePosters
<MovieDetails data={this.state.currentMovie} /> movies={this.props.movieStore.movies}
selectedMovieIndex={index}
onClick={this.props.selectMovie}
/>
{selectedMovie &&
<MovieDetails data={selectedMovie} />
}
</div> </div>
); );
} }

View File

@ -17,6 +17,7 @@ export default class NavBar extends React.Component {
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul className="nav navbar-nav"> <ul className="nav navbar-nav">
<li><Link to="/movies/popular">Movies</Link></li> <li><Link to="/movies/popular">Movies</Link></li>
<li><Link to="/users/login">Login</Link></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -0,0 +1,35 @@
import React from 'react'
export default class UserLoginForm extends React.Component {
render() {
return (
<div className="container">
<div className="content-fluid">
<div className="col-md-6 col-md-offset-3 col-xs-12">
<h2>Log in</h2>
<hr/>
<form acceptCharset="UTF-8" action="/users/login" method="POST" className="form-horizontal">
<div>
<label htmlFor="user_email">Username</label>
<br/>
<input className="form-control" id="username" name="Username" type="username" value=""/>
<p></p>
</div>
<div>
<label htmlFor="user_password">Password</label>
<br/>
<input autoComplete="off" className="form-control" id="password" name="Password" type="password"/>
<p></p>
</div>
<div>
<input className="btn btn-primary pull-right" type="submit" value="Log in"/>
<br/>
</div>
<a className="btn btn-default btn-sm pull-left" href="/movies/%3cnil%3e">Cancel</a>
</form>
</div>
</div>
</div>
);
}
}

View File

@ -1,3 +1,21 @@
export default function movieStore(state = {}, action) { import { ADD_MOVIES, SELECT_MOVIE } from '../actions/actionCreators'
return state;
const defaultState = {
movies: [],
selectedMovieIndex: 0,
};
export default function movieStore(state = defaultState, action) {
switch (action.type) {
case ADD_MOVIES:
return Object.assign({}, state, {
movies: action.movies,
})
case SELECT_MOVIE:
return Object.assign({}, state, {
selectedMovieIndex: action.index,
})
default:
return state
}
} }

View File

@ -5,17 +5,8 @@ import { browserHistory } from 'react-router'
// Import the root reducer // Import the root reducer
import rootReducer from './reducers/index' import rootReducer from './reducers/index'
// Set the default state
const defaultState = {
movieStore: {
movies: [],
selectedMovie: {},
selectedMovieIndex: 0,
},
};
// Export the store // Export the store
const store = createStore(rootReducer, defaultState); const store = createStore(rootReducer);
// Sync history with store // Sync history with store
export const history = syncHistoryWithStore(browserHistory, store); export const history = syncHistoryWithStore(browserHistory, store);