diff --git a/package-lock.json b/package-lock.json
index 1458f57..e7a0691 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13685,4 +13685,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/MovieInfo/actions.js b/src/MovieInfo/actions.js
new file mode 100644
index 0000000..0d7b7c1
--- /dev/null
+++ b/src/MovieInfo/actions.js
@@ -0,0 +1,25 @@
+import {
+ FETCH_MOVIE_LIST,
+ FETCH_MOVIE_LIST_SUCCESS,
+ FETCH_MOVIE_LIST_FAILURE,
+} from './constants';
+
+export function fetchMovieList() {
+ return {
+ type: FETCH_MOVIE_LIST,
+ };
+}
+
+export function fetchMovieListSuccess(movieList) {
+ return {
+ type: FETCH_MOVIE_LIST_SUCCESS,
+ payload: movieList,
+ };
+}
+
+export function fetchMovieListFailure(error) {
+ return {
+ type: FETCH_MOVIE_LIST_FAILURE,
+ payload: { error },
+ };
+}
diff --git a/src/MovieInfo/component.jsx b/src/MovieInfo/component.jsx
new file mode 100644
index 0000000..e298bee
--- /dev/null
+++ b/src/MovieInfo/component.jsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+function MovieInfo({ movie }) {
+ const { poster_path: path, overview } = movie;
+ return (
+
+
+
+

+
+
+
+
+ );
+}
+
+MovieInfo.propTypes = {
+ movie: PropTypes.object,
+};
+
+export default MovieInfo;
diff --git a/src/MovieInfo/constants.js b/src/MovieInfo/constants.js
new file mode 100644
index 0000000..50b8be8
--- /dev/null
+++ b/src/MovieInfo/constants.js
@@ -0,0 +1,9 @@
+export const FETCH_MOVIE_LIST = '@movieInfo/FETCH_MOVIE_LIST';
+
+export const FETCH_MOVIE_LIST_SUCCESS = '@movieInfo/FETCH_MOVIE_LIST_SUCCESS';
+
+export const FETCH_MOVIE_LIST_FAILURE = '@movieInfo/FETCH_MOVIE_LIST_FAILURE';
+
+export const POPULAR_MOVIES = 'Popular Movies';
+
+export const ERROR_TEXT = 'Oops! Something went wrong. Please refresh';
diff --git a/src/MovieInfo/container.jsx b/src/MovieInfo/container.jsx
new file mode 100644
index 0000000..d437052
--- /dev/null
+++ b/src/MovieInfo/container.jsx
@@ -0,0 +1,64 @@
+import React, { useEffect } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import {
+ fetchMovieListSuccess,
+ fetchMovieListFailure,
+} from './actions';
+import MovieInfo from './component';
+import { ERROR_TEXT } from './constants';
+import { getDataFromAPI } from '../HandleAPICalls/actions';
+
+const URL =
+ 'https://api.themoviedb.org/3/movie/popular?api_key=1e2bbb1e97b4751a4945af538fa72a41';
+
+function Movie({
+ getDataFromAPI: getData,
+ fetchMovieListSuccess: fetchMovieSucces,
+ fetchMovieListFailure: fetchMovieFailure,
+ movies: { data, error },
+}) {
+ useEffect(() => {
+ getData(URL, 'GET', undefined, fetchMovieSucces, fetchMovieFailure);
+ }, [getData, fetchMovieFailure, fetchMovieFailure]);
+ return (
+
+ {!data.length &&
}
+ {error &&
{ERROR_TEXT}
}
+
+ {data.map(movie => (
+
+
+
+ ))}
+
+
+ );
+}
+
+function mapStateToProps(state) {
+ return { movies: state.movieList };
+}
+function mapDispatchToProps(dispatch) {
+ return bindActionCreators(
+ {
+ getDataFromAPI,
+ fetchMovieListFailure,
+ fetchMovieListSuccess,
+ },
+ dispatch,
+ );
+}
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps,
+)(Movie);
+
+Movie.propTypes = {
+ movies: PropTypes.object,
+ getDataFromAPI: PropTypes.func,
+ fetchMovieListSuccess: PropTypes.func,
+ fetchMovieListFailure: PropTypes.func
+};
diff --git a/src/MovieInfo/reducer.js b/src/MovieInfo/reducer.js
new file mode 100644
index 0000000..88e85e7
--- /dev/null
+++ b/src/MovieInfo/reducer.js
@@ -0,0 +1,32 @@
+import {
+ FETCH_MOVIE_LIST,
+ FETCH_MOVIE_LIST_SUCCESS,
+ FETCH_MOVIE_LIST_FAILURE,
+} from './constants';
+
+const movieListInitialState = {
+ data: [],
+ isFetching: false,
+ error: null,
+};
+
+export default function movieListReducer(
+ state = movieListInitialState,
+ action,
+) {
+ switch (action.type) {
+ case FETCH_MOVIE_LIST:
+ return { ...state, isFetching: true };
+ case FETCH_MOVIE_LIST_SUCCESS:
+ return {
+ ...state,
+ isFetching: false,
+ data: [...action.payload.results],
+ error: null,
+ };
+ case FETCH_MOVIE_LIST_FAILURE:
+ return { ...state, error: action.payload };
+ default:
+ return state;
+ }
+}
diff --git a/src/app/App.jsx b/src/app/App.jsx
index 2a02b19..0e2572c 100644
--- a/src/app/App.jsx
+++ b/src/app/App.jsx
@@ -1,18 +1,13 @@
import React from 'react';
-import RandomQuote from '../RandomQuote/container';
-import TodoApp from './TodoApp/container';
+import Movie from '../MovieInfo/container';
+import { POPULAR_MOVIES } from '../MovieInfo/constants';
export default function App() {
return (
-
Hello React with Hot Reload !
+
{POPULAR_MOVIES}
+
-
-
-
Todos App - React hooks🔥
-
-
-
);
}
diff --git a/src/index.css b/src/index.css
index cf1defb..e5f4511 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,6 +1,7 @@
-@import url('https://fonts.googleapis.com/css?family=Dancing+Script');
+@import url("https://fonts.googleapis.com/css?family=Dancing+Script");
body {
height: 100%;
+ width: 100%;
}
h1 {
@@ -9,5 +10,117 @@ h1 {
font-size: 5em;
text-align: center;
padding-top: 15vh;
- font-family: 'Dancing Script', cursive;
+ font-family: "Dancing Script", cursive;
+}
+
+h2 {
+ color: #4568de;
+ margin: 0 auto;
+ font-size: 6rem;
+ text-align: center;
+ font-family: "Dancing Script", cursive;
+}
+
+/* show spinner - inspired from w3schools */
+
+.movie-card {
+ background-color: transparent;
+ width: 15.625rem;
+ height: 18.75rem;
+ perspective: 1000px;
+}
+
+.movie-card-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ transition: transform 0.6s;
+ transform-style: preserve-3d;
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
+}
+
+.movie-card:hover .movie-card-inner {
+ transform: rotateY(180deg);
+}
+
+.movie-card-front,
+.movie-card-back {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ backface-visibility: hidden;
+}
+
+.movie-card-front {
+ background-color: #bbb;
+ color: black;
+}
+
+.movie-card-back {
+ background-color: #beebe7;
+ color: #000;
+ transform: rotateY(180deg);
+ overflow: hidden;
+}
+
+.movie-container {
+ width: 100%;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.items {
+ margin: 1rem;
+}
+
+.image {
+ width: 15.625rem;
+ height: 18.75rem;
+}
+
+.movie-description {
+ text-align: justify;
+ padding: 0.625rem;
+ line-height: 1.5;
+ font-weight: bold;
+ font-family: "Dancing Script";
+}
+
+.align-center {
+ text-align: center;
+}
+
+.error-text {
+ color: red;
+ font-weight: bold;
+ font-family: "Dancing Script";
+}
+
+/* show spinner - inspired from pure css loader */
+
+.lds-dual-ring {
+ display: inline-block;
+ width: 5rem;
+ height: 5rem;
+}
+.lds-dual-ring:after {
+ content: " ";
+ display: block;
+ width: 6rem;
+ height: 6rem;
+ margin: 0.1rem;
+ border-radius: 50%;
+ border: 5px solid green;
+ border-color: green transparent green transparent;
+ animation: lds-dual-ring 1.2s linear infinite;
+}
+@keyframes lds-dual-ring {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
}
diff --git a/src/reducers/index.js b/src/reducers/index.js
index 91cda8d..cf7a354 100644
--- a/src/reducers/index.js
+++ b/src/reducers/index.js
@@ -1,6 +1,8 @@
import { combineReducers } from 'redux';
+import movieListReducer from '../MovieInfo/reducer';
import randomQuoteReducer from '../RandomQuote/reducer';
export default combineReducers({
quote: randomQuoteReducer,
+ movieList: movieListReducer,
});