diff --git a/src/components/Navbar.js b/src/components/Navbar.js
index 3482315..46eaa27 100644
--- a/src/components/Navbar.js
+++ b/src/components/Navbar.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react'
+import React, { useState, useEffect, useRef } from 'react'
import { NavLink } from 'react-router-dom'
import { withRouter } from 'react-router-dom'
@@ -10,6 +10,7 @@ import DropdownArrow from '../static/images/drop-down-arrow.svg'
import DropdownContent from '../components/DropdownContent'
const Navbar = ({ history }) => {
+ const searchInput = React.useRef(null)
const [userInput, setUserInput] = useState('')
const [scrollDimensions] = useScroll()
const { scrollY } = scrollDimensions
@@ -19,10 +20,14 @@ const Navbar = ({ history }) => {
}
useEffect(() => {
- userInput.length <= 0
- ? history.push('/')
- : history.push(`/search?q=${userInput}`)
- }, [userInput])
+ if (
+ document.activeElement === searchInput.current &&
+ userInput.length === 0
+ ) {
+ history.push('/browse')
+ }
+ if (userInput.length > 0) history.push(`/search?q=${userInput}`)
+ }, [userInput, searchInput])
const onLogoClick = () => {
setUserInput('')
@@ -50,6 +55,7 @@ const Navbar = ({ history }) => {
onChange(event)}
className='navigation__container--left__input'
diff --git a/src/components/UI/Modal.js b/src/components/UI/Modal.js
index f3a95e8..64d7e0f 100644
--- a/src/components/UI/Modal.js
+++ b/src/components/UI/Modal.js
@@ -6,8 +6,10 @@ const Modal = ({
show,
modalClosed,
children,
+ movie,
movie: { backdrop_path, poster_path },
}) => {
+ console.log('Modal.movie', movie)
const backgroundStyle = {
backgroundSize: 'cover',
backgroundImage: `url(https://image.tmdb.org/t/p/original/${
diff --git a/src/pages/Search.js b/src/pages/Search.js
index 1449354..9ea9699 100644
--- a/src/pages/Search.js
+++ b/src/pages/Search.js
@@ -3,10 +3,10 @@ import { useLocation } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
import { useDebounce } from '../hooks/useDebounce'
+import * as movieActions from '../store/actions'
import Modal from '../components/UI/Modal'
import MovieDetails from '../components/Movie/MovieDetails'
import Movie from '../components/Movie/Movie'
-import axios from '../axios-movies'
// A custom hook that builds on useLocation to parse
// the query string for you.
@@ -14,171 +14,80 @@ const useQuery = () => {
return new URLSearchParams(useLocation().search)
}
-const Search = ({ history }) => {
+const Search = () => {
let query = useQuery()
const debouncedSearchTerm = useDebounce(query.get('q'), 500)
const [isToggleModal, setIsToggleModal] = useState(false)
- const searchResults = useSelector((state) => state.searchMovie)
+ const { searchResults, isLoading } = useSelector((state) => state.searchMovie)
+ const { movieDetails } = useSelector((state) => state.movieDetails)
const dispatch = useDispatch()
- // constructor(props) {
- // super(props)
- // this.state = {
- // movies: [],
- // toggleModal: false,
- // /** Holds the movie information for a single movie. */
- // movieOverview: {},
- // }
- // }
useEffect(() => {
if (debouncedSearchTerm) {
- console.log('maing api call....')
+ dispatch(movieActions.fetchSearchMovie(debouncedSearchTerm))
}
}, [debouncedSearchTerm])
- console.log('location', query.get('q'))
-
- // componentDidMount = async () => {
-
- // console.log('movie roww', movieRows)
- // const { movieRows } = this.props.history.location;
- // if (movieRows) {
- // await this.setState({ movies: movieRows });
-
- // }
- // }
-
- // useEffect(() => {
- // if (!userInput) {
- // console.log('Search.useEffect()')
- // history.push('/')
- // }
- // }, [userInput])
-
- // useEffect(() => {
- // console.log('searchResults', searchResults)
- // }, [searchResults])
-
- // componentDidUpdate = async (prevProps) => {
- // console.log('hiiiiiii')
- // if (
- // prevProps.location.movieRows.length !==
- // this.props.location.movieRows.length
- // ) {
- // await this.setState({ movies: this.props.location.movieRows });
- // }
- // }
-
- const closeModal = () => {
+ const onCloseModalHandler = () => {
setIsToggleModal(false)
}
- // /* Get the appropriate details for a specific movie that was clicked */
- // selectMovieHandler = (movie) => {
- // this.setState({ toggleModal: true });
+ const onSelectMovieHandler = (movie) => {
+ dispatch(movieActions.fetchMovieDetails(movie.media_type, movie.id))
+ setIsToggleModal(true)
+ }
- // let url;
- // /** Make the appropriate API call to get the details for a single movie or tv show. */
- // if (movie.media_type === "movie") {
- // const movieId = movie.id;
- // url = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.API_KEY}`;
+ const renderSearchResults = () => {
+ return searchResults.length > 0 ? (
+ <>
+
+ {searchResults.map((movie) => {
+ let movieRows = []
+ let movieImageUrl
+ if (movie.poster_path !== null && movie.media_type !== 'person') {
+ movieImageUrl =
+ 'https://image.tmdb.org/t/p/w500' + movie.poster_path
+ const movieComponent = (
+ onSelectMovieHandler(movie)}
+ key={movie.id}
+ movieImage={movieImageUrl}
+ movie={movie}
+ />
+ )
+ movieRows.push(movieComponent)
+ }
+ return movieRows
+ })}
+
+
+
+
+ >
+ ) : (
+
+
+
+ Your search for "{debouncedSearchTerm}" did not have any matches.
+
+
Suggestions:
+
+ - Try different keywords
+ - Looking for a movie or TV show?
+ - Try using a movie, TV show title, an actor or director
+ - Try a genre, like comedy, romance, sports, or drama
+
+
+
+ )
+ }
- // } else if (movie.media_type === "tv") {
- // const tvId = movie.id
- // url = `https://api.themoviedb.org/3/tv/${tvId}?api_key=${process.env.API_KEY}`;
- // }
-
- // axios.get(url)
- // .then(res => {
- // const movieData = res.data;
- // this.setState({ movieOverview: movieData });
- // }).catch(error => {
- // console.log(error);
- // });
- // }
-
- // const { movies } = this.state
- // const { userInput } = this.props.location
- // console.log('search().render()', this.props.history.location)
-
- return
hello
- // searchResults === undefined ? (
- //
- // ) : (
- //
- // {searchResults.map((movie) => {
- // let movieRows = []
- // let movieImageUrl
- // if (movie.poster_path !== null && movie.media_type !== 'person') {
- // movieImageUrl = 'https://image.tmdb.org/t/p/w500' + movie.poster_path
-
- // /** Set the movie object to our Movie component */
- // const movieComponent = (
- // this.selectMovieHandler(movie)}
- // key={movie.id}
- // movieImage={movieImageUrl}
- // movie={movie}
- // />
- // )
-
- // /** Push our movie component to our movieRows array */
- // movieRows.push(movieComponent)
- // }
- // return movieRows
- // })}
- //
- // )
-
- // <>
- // {searchResults && searchResults.data.length > 0 ? (
- //
- // {searchResults.map((movie) => {
- // let movieRows = []
- // let movieImageUrl
- // if (movie.poster_path !== null && movie.media_type !== 'person') {
- // movieImageUrl =
- // 'https://image.tmdb.org/t/p/w500' + movie.poster_path
-
- // /** Set the movie object to our Movie component */
- // const movieComponent = (
- // this.selectMovieHandler(movie)}
- // key={movie.id}
- // movieImage={movieImageUrl}
- // movie={movie}
- // />
- // )
-
- // /** Push our movie component to our movieRows array */
- // movieRows.push(movieComponent)
- // }
- // return movieRows
- // })}
- //
- // ) : (
- //
- //
- //
Your search for "{userInput}" did not have any matches.
- //
Suggestions:
- //
- // - Try different keywords
- // - Looking for a movie or TV show?
- // - Try using a movie, TV show title, an actor or director
- // - Try a genre, like comedy, romance, sports, or drama
- //
- //
- //
- // )}
- /*
*/
- /* */
- /* */
- // >
+ return !isLoading ? renderSearchResults() :
Loading...
}
export default Search
diff --git a/src/store/actions/index.js b/src/store/actions/index.js
index 80811db..d769aa5 100644
--- a/src/store/actions/index.js
+++ b/src/store/actions/index.js
@@ -1,7 +1,6 @@
import axios from '../../axios-movies'
export const FETCH_HEADER_MOVIE = 'FETCH_HEADER_MOVIE'
-export const FETCH_SEARCH_MOVIE = 'FETCH_SEARCH_MOVIE'
export const FETCH_TRENDING = 'FETCH_TRENDING'
export const FETCH_NETFLIX_ORIGINALS = 'FETCH_NETFLIX_ORIGINALS'
export const FETCH_TOP_RATED = 'FETCH_TOP_RATED'
@@ -10,15 +9,49 @@ export const FETCH_COMEDY_MOVIES = 'FETCH_COMEDY_MOVIES'
export const FETCH_HORROR_MOVIES = 'FETCH_HORROR_MOVIES'
export const FETCH_ROMANCE_MOVIES = 'FETCH_ROMANCE_MOVIES'
export const FETCH_DOCUMENTARIES = 'FETCH_DOCUMENTARIES'
+// movie details
+export const FETCH_MOVIE_DETAILS = 'FETCH_MOVIE_DETAILS'
+export const FETCH_MOVIE_DETAILS_SUCCESS = 'FETCH_MOVIE_DETAILS_SUCCESS'
+export const FETCH_MOVIE_DETAILS_FAIL = 'FETCH_MOVIE_DETAILS_FAIL'
+// search
+export const FETCH_SEARCH_MOVIE = 'FETCH_SEARCH_MOVIE'
+export const FETCH_SEARCH_MOVIE_FAIL = 'FETCH_SEARCH_MOVIE_FAIL'
+export const FETCH_SEARCH_MOVIE_SUCCESS = 'FETCH_SEARCH_MOVIE_SUCCESS'
+
+const media_type = {
+ tv: 'tv',
+ movie: 'movie',
+}
+
+export const fetchMovieDetails = (mediaType, mediaId) => {
+ return async (dispatch) => {
+ try {
+ dispatch({ type: FETCH_MOVIE_DETAILS })
+ let urlPath
+ if (mediaType === media_type.movie)
+ urlPath = `/movie/${mediaId}?api_key=${process.env.API_KEY}`
+ if (mediaType === media_type.tv)
+ urlPath = `/tv/${mediaId}?api_key=${process.env.API_KEY}`
+
+ const request = await axios.get(urlPath)
+ dispatch({ type: FETCH_MOVIE_DETAILS_SUCCESS, payload: request })
+ } catch (error) {
+ console.log('error', error)
+ dispatch({ type: FETCH_MOVIE_DETAILS_FAIL })
+ }
+ }
+}
export const fetchSearchMovie = (searchTerm) => {
return async (dispatch) => {
try {
+ dispatch({ type: FETCH_SEARCH_MOVIE })
const request = await axios.get(
`/search/multi?api_key=${process.env.API_KEY}&language=en-US&include_adult=false&query=${searchTerm}`
)
- dispatch({ type: FETCH_SEARCH_MOVIE, payload: request })
+ dispatch({ type: FETCH_SEARCH_MOVIE_SUCCESS, payload: request })
} catch (error) {
+ dispatch({ type: FETCH_SEARCH_MOVIE_FAIL })
console.log('error', error)
}
}
diff --git a/src/store/reducers/index.js b/src/store/reducers/index.js
index bf9a80a..b7f9edb 100644
--- a/src/store/reducers/index.js
+++ b/src/store/reducers/index.js
@@ -9,6 +9,7 @@ import RomanceMoviesReducer from './reducerRomanceMovies'
import DocumentaryReducer from './reducerDocumentary'
import HeaderMovieReducer from './reducerHeaderMovie'
import SearchMovieReducer from './reducerSearchMovie'
+import MovieDetailsReducer from './reducerMovieDetails'
const rootReducer = combineReducers({
trending: TrendingReducer,
@@ -21,6 +22,7 @@ const rootReducer = combineReducers({
documentary: DocumentaryReducer,
headerMovie: HeaderMovieReducer,
searchMovie: SearchMovieReducer,
+ movieDetails: MovieDetailsReducer,
})
export default rootReducer
diff --git a/src/store/reducers/reducerMovieDetails.js b/src/store/reducers/reducerMovieDetails.js
new file mode 100644
index 0000000..d7067a8
--- /dev/null
+++ b/src/store/reducers/reducerMovieDetails.js
@@ -0,0 +1,24 @@
+import {
+ FETCH_MOVIE_DETAILS,
+ FETCH_MOVIE_DETAILS_SUCCESS,
+ FETCH_MOVIE_DETAILS_FAIL,
+} from '../actions/index'
+
+const initialState = {
+ isLoading: false,
+ movieDetails: [],
+}
+
+export default function (state = initialState, action) {
+ switch (action.type) {
+ case FETCH_MOVIE_DETAILS:
+ return { ...state, isLoading: true }
+ case FETCH_MOVIE_DETAILS_FAIL:
+ return { ...state, isLoading: false }
+ case FETCH_MOVIE_DETAILS_SUCCESS:
+ const movieDetails = action.payload.data
+ return { ...state, movieDetails, isLoading: false }
+ default:
+ return state
+ }
+}
diff --git a/src/store/reducers/reducerSearchMovie.js b/src/store/reducers/reducerSearchMovie.js
index 48a199d..54713e5 100644
--- a/src/store/reducers/reducerSearchMovie.js
+++ b/src/store/reducers/reducerSearchMovie.js
@@ -1,10 +1,23 @@
-import { FETCH_SEARCH_MOVIE } from '../actions/index'
+import {
+ FETCH_SEARCH_MOVIE,
+ FETCH_SEARCH_MOVIE_FAIL,
+ FETCH_SEARCH_MOVIE_SUCCESS,
+} from '../actions/index'
-export default function (state = {}, action) {
+const initialState = {
+ isLoading: false,
+ searchResults: [],
+}
+
+export default function (state = initialState, action) {
switch (action.type) {
case FETCH_SEARCH_MOVIE:
- const data = action.payload.data.results
- return { ...state, data }
+ return { ...state, isLoading: true }
+ case FETCH_SEARCH_MOVIE_FAIL:
+ return { ...state, isLoading: false }
+ case FETCH_SEARCH_MOVIE_SUCCESS:
+ const searchResults = action.payload.data.results
+ return { ...state, searchResults, isLoading: false }
default:
return state
}