From c98117c4f6263a5808771e63871e3baf1ac7da32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Delattre?= Date: Fri, 16 Dec 2016 22:42:49 +0100 Subject: [PATCH] Add show list --- src/public/js/actions/actionCreators.js | 55 ++++++++--- src/public/js/app.js | 7 ++ src/public/js/components/list/details.js | 24 +++++ src/public/js/components/list/filter.js | 22 +++++ src/public/js/components/list/poster.js | 16 +++ src/public/js/components/list/posters.js | 45 +++++++++ src/public/js/components/movies/list.js | 121 +++-------------------- src/public/js/components/navbar.js | 3 + src/public/js/components/shows/list.js | 49 +++++++++ src/public/js/reducers/index.js | 2 + src/public/js/reducers/shows.js | 32 ++++++ src/public/less/app.less | 6 +- 12 files changed, 261 insertions(+), 121 deletions(-) create mode 100644 src/public/js/components/list/details.js create mode 100644 src/public/js/components/list/filter.js create mode 100644 src/public/js/components/list/poster.js create mode 100644 src/public/js/components/list/posters.js create mode 100644 src/public/js/components/shows/list.js create mode 100644 src/public/js/reducers/shows.js diff --git a/src/public/js/actions/actionCreators.js b/src/public/js/actions/actionCreators.js index a3d41dc..3603633 100644 --- a/src/public/js/actions/actionCreators.js +++ b/src/public/js/actions/actionCreators.js @@ -1,18 +1,8 @@ import { configureAxios, request } from '../requests' -// Select Movie -export function selectMovie(imdbId) { - return { - type: 'SELECT_MOVIE', - imdbId - } -} - -export function isUserLoggedIn() { - return { - type: 'IS_USER_LOGGED_IN', - } -} +// ====================== +// Errors +// ====================== export function addError(message) { return { @@ -29,12 +19,22 @@ export function dismissError() { } } +// ====================== +// Users +// ====================== + export function userLogout() { return { type: 'USER_LOGOUT', } } +export function isUserLoggedIn() { + return { + type: 'IS_USER_LOGGED_IN', + } +} + export function loginUser(username, password) { return request( 'USER_LOGIN', @@ -69,6 +69,17 @@ export function getUserInfos() { ) } +// ====================== +// Movies +// ====================== + +export function selectMovie(imdbId) { + return { + type: 'SELECT_MOVIE', + imdbId + } +} + export function getMovieDetails(imdbId) { return request( 'MOVIE_GET_DETAILS', @@ -82,3 +93,21 @@ export function fetchMovies(url) { configureAxios().get(url) ) } + +// ====================== +// Shows +// ====================== + +export function fetchShows(url) { + return request( + 'SHOW_LIST_FETCH', + configureAxios().get(url) + ) +} + +export function selectShow(imdbId) { + return { + type: 'SELECT_SHOW', + imdbId + } +} diff --git a/src/public/js/app.js b/src/public/js/app.js index 7a0a242..c82d250 100644 --- a/src/public/js/app.js +++ b/src/public/js/app.js @@ -29,6 +29,7 @@ import store, { history } from './store' import NavBar from './components/navbar' import Error from './components/errors' import MovieList from './components/movies/list' +import ShowList from './components/shows/list' import UserLoginForm from './components/users/login' import UserEdit from './components/users/edit' import UserSignUp from './components/users/signup' @@ -53,6 +54,7 @@ class Main extends React.Component { function mapStateToProps(state) { return { movieStore: state.movieStore, + showStore: state.showStore, userStore: state.userStore, errors: state.errors, } @@ -81,6 +83,10 @@ const MovieListPolochon = (props) => ( ) +const ShowListPopular = (props) => ( + +) + ReactDOM.render(( @@ -91,6 +97,7 @@ ReactDOM.render(( + diff --git a/src/public/js/components/list/details.js b/src/public/js/components/list/details.js new file mode 100644 index 0000000..ef5945a --- /dev/null +++ b/src/public/js/components/list/details.js @@ -0,0 +1,24 @@ +import React from 'react' + +export default function ListDetails(props) { + return ( +
+
+

{props.data.title}

+

{props.data.title}

+ {props.data.runtime && +

+ +  {props.data.runtime} min +

+ } +

+ +  {props.data.rating} ({props.data.votes} counts) +

+

{props.data.plot}

+
+ {props.children} +
+ ); +} diff --git a/src/public/js/components/list/filter.js b/src/public/js/components/list/filter.js new file mode 100644 index 0000000..8396379 --- /dev/null +++ b/src/public/js/components/list/filter.js @@ -0,0 +1,22 @@ +import React from 'react' +import { Control, Form } from 'react-redux-form'; + +export default function ListFilter(props) { + return ( +
+
+
+ + + + + +
+
+ ); +} diff --git a/src/public/js/components/list/poster.js b/src/public/js/components/list/poster.js new file mode 100644 index 0000000..e5f8d57 --- /dev/null +++ b/src/public/js/components/list/poster.js @@ -0,0 +1,16 @@ +import React from 'react' + +export default function ListPoster(props) { + const selected = props.selected ? ' thumbnail-selected' : ''; + const imgClass = 'thumbnail' + selected; + return ( +
+ + + +
+ ); +} diff --git a/src/public/js/components/list/posters.js b/src/public/js/components/list/posters.js new file mode 100644 index 0000000..2514a56 --- /dev/null +++ b/src/public/js/components/list/posters.js @@ -0,0 +1,45 @@ +import React from 'react' +import fuzzy from 'fuzzy'; + +import ListFilter from './filter' +import ListPoster from './poster' + +export default function ListPosters(props) { + let elmts = props.data.slice(); + + // Filter the list of elements + if (props.filter !== "") { + const filtered = fuzzy.filter(props.filter, elmts, { + extract: (el) => el.title + }); + elmts = filtered.map((el) => el.original); + } + + // Limit the number of results + if (elmts.length > props.perPage) { + elmts = elmts.slice(0, props.perPage); + } + + return ( +
+ +
+ {elmts.map(function(el, index) { + const selected = (el.imdb_id === props.selectedImdbId) ? true : false; + return ( + props.onClick(el.imdb_id)} + /> + )} + )} +
+
+ ); +} diff --git a/src/public/js/components/movies/list.js b/src/public/js/components/movies/list.js index 4ec4dd0..c1b4731 100644 --- a/src/public/js/components/movies/list.js +++ b/src/public/js/components/movies/list.js @@ -1,101 +1,7 @@ import React from 'react' -import axios from 'axios' -import { Control, Form } from 'react-redux-form'; -import fuzzy from 'fuzzy'; -function MoviePosters(props) { - let movies = props.movies.slice(); - - // Filter the movies - if (props.filter !== "") { - const filtered = fuzzy.filter(props.filter, movies, { - extract: (el) => el.title - }); - movies = filtered.map((el) => el.original); - } - - // Limit the number of results - if (movies.length > props.perPage) { - movies = movies.slice(0, props.perPage); - } - - return ( -
- -
- {movies.map(function(movie, index) { - const selected = (movie.imdb_id === props.selectedMovieId) ? true : false; - return ( - props.onClick(movie.imdb_id)} - /> - )} - )} -
-
- ); -} - -class MovieListFilter extends React.Component { - render() { - return ( -
-
-
- - - - - -
-
- ); - } -} - -function MoviePoster(props) { - const selected = props.selected ? ' thumbnail-selected' : ''; - const imgClass = 'thumbnail' + selected; - return ( -
- - - -
- ); -} - -function MovieDetails(props) { - return ( -
-
-

{props.movie.title}

-

{props.movie.title}

-

- -  {props.movie.runtime} min -

-

- -  {props.movie.rating} ({props.movie.votes} counts) -

-

{props.movie.plot}

-
- -
- ); -} +import ListPosters from '../list/posters' +import ListDetails from '../list/details' class MovieButtons extends React.Component { constructor(props) { @@ -112,7 +18,7 @@ class MovieButtons extends React.Component { render() { const imdb_link = `http://www.imdb.com/title/${this.props.movie.imdb_id}`; return ( -
+
{this.props.fetching || @@ -159,19 +65,24 @@ export default class MovieList extends React.Component { const selectedMovie = movies[index]; return (
- {selectedMovie && - + + + }
); diff --git a/src/public/js/components/navbar.js b/src/public/js/components/navbar.js index 859ca48..fd25207 100644 --- a/src/public/js/components/navbar.js +++ b/src/public/js/components/navbar.js @@ -27,6 +27,9 @@ export default class NavBar extends React.Component { Polochon movies + + Polochon shows +