converted redux store to ts
This commit is contained in:
68
package-lock.json
generated
68
package-lock.json
generated
@@ -9,10 +9,12 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^1.9.0",
|
||||||
"@types/jest": "^29.2.3",
|
"@types/jest": "^29.2.3",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"@types/react": "^18.0.25",
|
"@types/react": "^18.0.25",
|
||||||
"@types/react-dom": "^18.0.9",
|
"@types/react-dom": "^18.0.9",
|
||||||
|
"@types/react-redux": "^7.1.24",
|
||||||
"axios": "^1.2.0",
|
"axios": "^1.2.0",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"firebase": "^9.14.0",
|
"firebase": "^9.14.0",
|
||||||
@@ -3929,6 +3931,29 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@reduxjs/toolkit": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-ak11IrjYcUXRqlhNPwnz6AcvA2ynJTu8PzDbbqQw4a3xR4KZtgiqbNblQD+10CRbfK4+5C79SOyxnT9dhBqFnA==",
|
||||||
|
"dependencies": {
|
||||||
|
"immer": "^9.0.16",
|
||||||
|
"redux": "^4.2.0",
|
||||||
|
"redux-thunk": "^2.4.2",
|
||||||
|
"reselect": "^4.1.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.9.0 || ^17.0.0 || ^18",
|
||||||
|
"react-redux": "^7.2.1 || ^8.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@remix-run/router": {
|
"node_modules/@remix-run/router": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz",
|
||||||
@@ -4944,6 +4969,17 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-redux": {
|
||||||
|
"version": "7.1.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
|
||||||
|
"integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.0",
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
|
"redux": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
@@ -21112,6 +21148,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/reselect": {
|
||||||
|
"version": "4.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
|
||||||
|
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
|
||||||
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.0",
|
"version": "1.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
|
||||||
@@ -27617,6 +27658,17 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||||
},
|
},
|
||||||
|
"@reduxjs/toolkit": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-ak11IrjYcUXRqlhNPwnz6AcvA2ynJTu8PzDbbqQw4a3xR4KZtgiqbNblQD+10CRbfK4+5C79SOyxnT9dhBqFnA==",
|
||||||
|
"requires": {
|
||||||
|
"immer": "^9.0.16",
|
||||||
|
"redux": "^4.2.0",
|
||||||
|
"redux-thunk": "^2.4.2",
|
||||||
|
"reselect": "^4.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@remix-run/router": {
|
"@remix-run/router": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz",
|
||||||
@@ -28410,6 +28462,17 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-redux": {
|
||||||
|
"version": "7.1.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
|
||||||
|
"integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.0",
|
||||||
|
"@types/react": "*",
|
||||||
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
|
"redux": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/resolve": {
|
"@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
|
||||||
@@ -40182,6 +40245,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||||
},
|
},
|
||||||
|
"reselect": {
|
||||||
|
"version": "4.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
|
||||||
|
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
|
||||||
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.22.0",
|
"version": "1.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
|
||||||
|
|||||||
@@ -13,10 +13,12 @@
|
|||||||
"author": "Andres Alcocer",
|
"author": "Andres Alcocer",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^1.9.0",
|
||||||
"@types/jest": "^29.2.3",
|
"@types/jest": "^29.2.3",
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.9",
|
||||||
"@types/react": "^18.0.25",
|
"@types/react": "^18.0.25",
|
||||||
"@types/react-dom": "^18.0.9",
|
"@types/react-dom": "^18.0.9",
|
||||||
|
"@types/react-redux": "^7.1.24",
|
||||||
"axios": "^1.2.0",
|
"axios": "^1.2.0",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"firebase": "^9.14.0",
|
"firebase": "^9.14.0",
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import * as actionMovies from '../store/slices/actionMovieSlice'
|
||||||
import * as movieActions from '../store/actions'
|
import { useAppSelector, useAppDispatch } from '../store'
|
||||||
|
|
||||||
import Header from './Header'
|
import Header from './Header'
|
||||||
import DisplayMovieRow from './DisplayMovieRow'
|
import DisplayMovieRow from './DisplayMovieRow'
|
||||||
|
|
||||||
const MainContent = ({ selectMovieHandler }) => {
|
const MainContent = ({ selectMovieHandler }) => {
|
||||||
const { movieDetails } = useSelector((state) => state.movieDetails)
|
// const { movieDetails } = useSelector((state) => state.movieDetails)
|
||||||
const netflixOriginals = useSelector((state) => state.netflixOriginals)
|
// const netflixOriginals = useSelector((state) => state.netflixOriginals)
|
||||||
const trending = useSelector((state) => state.trending)
|
// const trending = useSelector((state) => state.trending)
|
||||||
const topRated = useSelector((state) => state.topRated)
|
// const topRated = useSelector((state) => state.topRated)
|
||||||
const actionMovies = useSelector((state) => state.action)
|
const actionMoviesState = useAppSelector((state) => state.action)
|
||||||
const comedyMovies = useSelector((state) => state.comedy)
|
// const comedyMovies = useSelector((state) => state.comedy)
|
||||||
const horrorMovies = useSelector((state) => state.horror)
|
// const horrorMovies = useSelector((state) => state.horror)
|
||||||
const romanceMovies = useSelector((state) => state.romance)
|
// const romanceMovies = useSelector((state) => state.romance)
|
||||||
const documentaries = useSelector((state) => state.documentary)
|
// const documentaries = useSelector((state) => state.documentary)
|
||||||
|
|
||||||
const dispatch = useDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(movieActions.fetchMovieDetails('tv', '63351'))
|
// dispatch(movieActions.fetchMovieDetails('tv', '63351'))
|
||||||
dispatch(movieActions.fetchNetflixOriginals())
|
// dispatch(movieActions.fetchNetflixOriginals())
|
||||||
dispatch(movieActions.fetchTrending())
|
// dispatch(movieActions.fetchTrending())
|
||||||
dispatch(movieActions.fetchTopRated())
|
// dispatch(movieActions.fetchTopRated())
|
||||||
dispatch(movieActions.fetchActionMovies())
|
dispatch(actionMovies.getActionMoviesAsync())
|
||||||
dispatch(movieActions.fetchComedyMovies())
|
// dispatch(movieActions.fetchComedyMovies())
|
||||||
dispatch(movieActions.fetchHorrorMovies())
|
// dispatch(movieActions.fetchHorrorMovies())
|
||||||
dispatch(movieActions.fetchRomanceMovies())
|
// dispatch(movieActions.fetchRomanceMovies())
|
||||||
dispatch(movieActions.fetchDocumentaries())
|
// dispatch(movieActions.fetchDocumentaries())
|
||||||
}, [dispatch])
|
}, [dispatch])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<Header movie={movieDetails} />
|
{/* <Header movie={movieDetails} /> */}
|
||||||
<div className='movieShowcase'>
|
<div className='movieShowcase'>
|
||||||
<DisplayMovieRow
|
{/* <DisplayMovieRow
|
||||||
isNetflixMovies={true}
|
isNetflixMovies={true}
|
||||||
title='Netflix Originals'
|
title='Netflix Originals'
|
||||||
selectMovieHandler={selectMovieHandler}
|
selectMovieHandler={selectMovieHandler}
|
||||||
@@ -49,13 +49,13 @@ const MainContent = ({ selectMovieHandler }) => {
|
|||||||
title='Top Rated'
|
title='Top Rated'
|
||||||
selectMovieHandler={selectMovieHandler}
|
selectMovieHandler={selectMovieHandler}
|
||||||
movies={topRated.data}
|
movies={topRated.data}
|
||||||
/>
|
/> */}
|
||||||
<DisplayMovieRow
|
<DisplayMovieRow
|
||||||
title='Action Movies'
|
title='Action Movies'
|
||||||
selectMovieHandler={selectMovieHandler}
|
selectMovieHandler={selectMovieHandler}
|
||||||
movies={actionMovies.data}
|
movies={actionMoviesState.data}
|
||||||
/>
|
/>
|
||||||
<DisplayMovieRow
|
{/* <DisplayMovieRow
|
||||||
title='Comedy'
|
title='Comedy'
|
||||||
selectMovieHandler={selectMovieHandler}
|
selectMovieHandler={selectMovieHandler}
|
||||||
movies={comedyMovies.data}
|
movies={comedyMovies.data}
|
||||||
@@ -74,7 +74,7 @@ const MainContent = ({ selectMovieHandler }) => {
|
|||||||
title='Documentaries'
|
title='Documentaries'
|
||||||
selectMovieHandler={selectMovieHandler}
|
selectMovieHandler={selectMovieHandler}
|
||||||
movies={documentaries.data}
|
movies={documentaries.data}
|
||||||
/>
|
/> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import * as ReactDOM from 'react-dom/client'
|
import * as ReactDOM from 'react-dom/client'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import { createStore, applyMiddleware } from 'redux'
|
|
||||||
import ReduxThunk from 'redux-thunk'
|
|
||||||
import '@babel/polyfill'
|
import '@babel/polyfill'
|
||||||
|
|
||||||
import reducers from './store/reducers'
|
import { store } from './store'
|
||||||
import AppRouter from './AppRouter'
|
import AppRouter from './AppRouter'
|
||||||
|
|
||||||
// Import Swiper styles
|
// Import Swiper styles
|
||||||
@@ -15,8 +13,6 @@ import 'swiper/css/pagination'
|
|||||||
// Import main sass file to apply global styles
|
// Import main sass file to apply global styles
|
||||||
import './static/sass/style.scss'
|
import './static/sass/style.scss'
|
||||||
|
|
||||||
const store = createStore(reducers, applyMiddleware(ReduxThunk))
|
|
||||||
|
|
||||||
const app = (
|
const app = (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<AppRouter />
|
<AppRouter />
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
|
import { useAppSelector, useAppDispatch } from '../store'
|
||||||
import ModalMovieDetails from '../components/ModalMovieDetails'
|
import ModalMovieDetails from '../components/ModalMovieDetails'
|
||||||
import Modal from '../components/UI/Modal'
|
import Modal from '../components/UI/Modal'
|
||||||
import { useDebounce } from '../hooks/useDebounce'
|
import { useDebounce } from '../hooks/useDebounce'
|
||||||
import * as movieActions from '../store/actions'
|
import * as movieActions from '../store/actions'
|
||||||
|
|
||||||
|
interface IMovie {
|
||||||
|
id: string
|
||||||
|
media_type?: string
|
||||||
|
backdrop_path?: string
|
||||||
|
}
|
||||||
|
|
||||||
// A custom hook that builds on useLocation to parse
|
// A custom hook that builds on useLocation to parse
|
||||||
// the query string for you.
|
// the query string for you.
|
||||||
const useQuery = () => {
|
const useQuery = () => {
|
||||||
@@ -16,9 +23,11 @@ const Search = () => {
|
|||||||
let query = useQuery()
|
let query = useQuery()
|
||||||
const debouncedSearchTerm = useDebounce(query.get('q'), 500)
|
const debouncedSearchTerm = useDebounce(query.get('q'), 500)
|
||||||
const [isToggleModal, setIsToggleModal] = useState(false)
|
const [isToggleModal, setIsToggleModal] = useState(false)
|
||||||
const { searchResults, isLoading } = useSelector((state) => state.searchMovie)
|
const { searchResults, isLoading } = useAppSelector(
|
||||||
const { movieDetails } = useSelector((state) => state.movieDetails)
|
(state) => state.searchMovie
|
||||||
const dispatch = useDispatch()
|
)
|
||||||
|
const { movieDetails } = useAppSelector((state) => state.movieDetails)
|
||||||
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (debouncedSearchTerm) {
|
if (debouncedSearchTerm) {
|
||||||
@@ -30,7 +39,7 @@ const Search = () => {
|
|||||||
setIsToggleModal(false)
|
setIsToggleModal(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSelectMovieHandler = (movie) => {
|
const onSelectMovieHandler = (movie: IMovie) => {
|
||||||
dispatch(movieActions.fetchMovieDetails(movie.media_type, movie.id))
|
dispatch(movieActions.fetchMovieDetails(movie.media_type, movie.id))
|
||||||
setIsToggleModal(true)
|
setIsToggleModal(true)
|
||||||
}
|
}
|
||||||
@@ -39,7 +48,7 @@ const Search = () => {
|
|||||||
return searchResults.length > 0 ? (
|
return searchResults.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
<div className='search-container'>
|
<div className='search-container'>
|
||||||
{searchResults.map((movie) => {
|
{searchResults.map((movie: IMovie) => {
|
||||||
if (movie.backdrop_path !== null && movie.media_type !== 'person') {
|
if (movie.backdrop_path !== null && movie.media_type !== 'person') {
|
||||||
const movieImageUrl =
|
const movieImageUrl =
|
||||||
'https://image.tmdb.org/t/p/w500' + movie.backdrop_path
|
'https://image.tmdb.org/t/p/w500' + movie.backdrop_path
|
||||||
@@ -31,7 +31,6 @@ export const fetchMovieDetails = (mediaType: string, mediaId: string) => {
|
|||||||
urlPath = `/movie/${mediaId}?api_key=${process.env.API_KEY}`
|
urlPath = `/movie/${mediaId}?api_key=${process.env.API_KEY}`
|
||||||
if (mediaType === media_type.tv)
|
if (mediaType === media_type.tv)
|
||||||
urlPath = `/tv/${mediaId}?api_key=${process.env.API_KEY}`
|
urlPath = `/tv/${mediaId}?api_key=${process.env.API_KEY}`
|
||||||
console.log('media type', mediaType, urlPath)
|
|
||||||
const request = await axios.get(urlPath)
|
const request = await axios.get(urlPath)
|
||||||
dispatch({ type: FETCH_MOVIE_DETAILS_SUCCESS, payload: request })
|
dispatch({ type: FETCH_MOVIE_DETAILS_SUCCESS, payload: request })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
33
src/store/index.ts
Normal file
33
src/store/index.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { configureStore } from '@reduxjs/toolkit'
|
||||||
|
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
|
||||||
|
|
||||||
|
import TrendingReducer from './slices/reducerTrending'
|
||||||
|
import NetflixOriginalsReducer from './slices/reducerNetflixOriginals'
|
||||||
|
import TopRatedReducer from './slices/reducerTopRated'
|
||||||
|
import ActionMoviesReducer from './slices/actionMovieSlice'
|
||||||
|
import ComedyMoviesReducer from './slices/reducerComedyMovies'
|
||||||
|
import HorrorMoviesReducer from './slices/reducerHorrorMovies'
|
||||||
|
import RomanceMoviesReducer from './slices/reducerRomanceMovies'
|
||||||
|
import DocumentaryReducer from './slices/reducerDocumentary'
|
||||||
|
import SearchMovieReducer from './slices/searchSlice'
|
||||||
|
import MovieDetailsReducer from './slices/movieDetailsSlice'
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
// trending: TrendingReducer,
|
||||||
|
// netflixOriginals: NetflixOriginalsReducer,
|
||||||
|
// topRated: TopRatedReducer,
|
||||||
|
action: ActionMoviesReducer,
|
||||||
|
// comedy: ComedyMoviesReducer,
|
||||||
|
// horror: HorrorMoviesReducer,
|
||||||
|
// romance: RomanceMoviesReducer,
|
||||||
|
searchMovie: SearchMovieReducer,
|
||||||
|
// documentary: DocumentaryReducer,
|
||||||
|
movieDetails: MovieDetailsReducer,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export type RootState = ReturnType<typeof store.getState>
|
||||||
|
export type AppDispatch = typeof store.dispatch
|
||||||
|
export const useAppDispatch = () => useDispatch<AppDispatch>()
|
||||||
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import { combineReducers } from 'redux'
|
|
||||||
import TrendingReducer from './reducerTrending'
|
|
||||||
import NetflixOriginalsReducer from './reducerNetflixOriginals'
|
|
||||||
import TopRatedReducer from './reducerTopRated'
|
|
||||||
import ActionMoviesReducer from './reducerActionMovies'
|
|
||||||
import ComedyMoviesReducer from './reducerComedyMovies'
|
|
||||||
import HorrorMoviesReducer from './reducerHorrorMovies'
|
|
||||||
import RomanceMoviesReducer from './reducerRomanceMovies'
|
|
||||||
import DocumentaryReducer from './reducerDocumentary'
|
|
||||||
import SearchMovieReducer from './reducerSearchMovie'
|
|
||||||
import MovieDetailsReducer from './reducerMovieDetails'
|
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
|
||||||
trending: TrendingReducer,
|
|
||||||
netflixOriginals: NetflixOriginalsReducer,
|
|
||||||
topRated: TopRatedReducer,
|
|
||||||
action: ActionMoviesReducer,
|
|
||||||
comedy: ComedyMoviesReducer,
|
|
||||||
horror: HorrorMoviesReducer,
|
|
||||||
romance: RomanceMoviesReducer,
|
|
||||||
documentary: DocumentaryReducer,
|
|
||||||
searchMovie: SearchMovieReducer,
|
|
||||||
movieDetails: MovieDetailsReducer,
|
|
||||||
})
|
|
||||||
|
|
||||||
export default rootReducer
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { FETCH_ACTION_MOVIES } from '../actions/index'
|
|
||||||
|
|
||||||
export default function (state = {}, action: any) {
|
|
||||||
switch (action.type) {
|
|
||||||
case FETCH_ACTION_MOVIES:
|
|
||||||
const data = action.payload.data.results
|
|
||||||
return { ...state, data }
|
|
||||||
default:
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import {
|
|
||||||
FETCH_MOVIE_DETAILS,
|
|
||||||
FETCH_MOVIE_DETAILS_SUCCESS,
|
|
||||||
FETCH_MOVIE_DETAILS_FAIL,
|
|
||||||
} from '../actions/index'
|
|
||||||
|
|
||||||
interface IInitialState {
|
|
||||||
isLoading: boolean
|
|
||||||
movieDetails: []
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialState: IInitialState = {
|
|
||||||
isLoading: false,
|
|
||||||
movieDetails: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function (state = initialState, action: any) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import {
|
|
||||||
FETCH_SEARCH_MOVIE,
|
|
||||||
FETCH_SEARCH_MOVIE_FAIL,
|
|
||||||
FETCH_SEARCH_MOVIE_SUCCESS,
|
|
||||||
} from '../actions/index'
|
|
||||||
|
|
||||||
interface IInitialState {
|
|
||||||
isLoading: boolean
|
|
||||||
searchResults: []
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialState: IInitialState = {
|
|
||||||
isLoading: false,
|
|
||||||
searchResults: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function (state = initialState, action: any) {
|
|
||||||
switch (action.type) {
|
|
||||||
case FETCH_SEARCH_MOVIE:
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
43
src/store/slices/actionMovieSlice.ts
Normal file
43
src/store/slices/actionMovieSlice.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
import axios from '../../axios-movies'
|
||||||
|
// import { FETCH_ACTION_MOVIES } from '../actions/index'
|
||||||
|
import { RootState } from '../index'
|
||||||
|
|
||||||
|
// export default function (state = {}, action: any) {
|
||||||
|
// switch (action.type) {
|
||||||
|
// case FETCH_ACTION_MOVIES:
|
||||||
|
// const data = action.payload.data.results
|
||||||
|
// return { ...state, data }
|
||||||
|
// default:
|
||||||
|
// return state
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
data: [{}],
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getActionMoviesAsync = createAsyncThunk<
|
||||||
|
any,
|
||||||
|
void,
|
||||||
|
{ state: RootState }
|
||||||
|
>('action/getActionMovies', async () => {
|
||||||
|
const response = await axios.get(
|
||||||
|
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=28`
|
||||||
|
)
|
||||||
|
return response.data.results
|
||||||
|
})
|
||||||
|
|
||||||
|
const actionMovieSlice = createSlice({
|
||||||
|
name: 'actionMovie',
|
||||||
|
initialState,
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: (builder) => {
|
||||||
|
builder.addCase(getActionMoviesAsync.fulfilled, (state, { payload }) => {
|
||||||
|
state.data = payload
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default actionMovieSlice.reducer
|
||||||
100
src/store/slices/movieDetailsSlice.ts
Normal file
100
src/store/slices/movieDetailsSlice.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
import axios from '../../axios-movies'
|
||||||
|
import { RootState } from '../index'
|
||||||
|
import {
|
||||||
|
FETCH_MOVIE_DETAILS,
|
||||||
|
FETCH_MOVIE_DETAILS_SUCCESS,
|
||||||
|
FETCH_MOVIE_DETAILS_FAIL,
|
||||||
|
} from '../actions/index'
|
||||||
|
import { string } from 'prop-types'
|
||||||
|
|
||||||
|
interface IMovieDetails {
|
||||||
|
backdrop_path?: string
|
||||||
|
poster_path?: string
|
||||||
|
title: any
|
||||||
|
name: any
|
||||||
|
vote_average: any
|
||||||
|
release_date: any
|
||||||
|
first_air_date: any
|
||||||
|
runtime: any
|
||||||
|
episode_run_time: any
|
||||||
|
number_of_episodes: any
|
||||||
|
number_of_seasons: any
|
||||||
|
overview: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInitialState {
|
||||||
|
isLoading: boolean
|
||||||
|
movieDetails: IMovieDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
const media_type = {
|
||||||
|
tv: 'tv',
|
||||||
|
movie: 'movie',
|
||||||
|
}
|
||||||
|
|
||||||
|
// const initialState: IInitialState = {
|
||||||
|
// isLoading: false,
|
||||||
|
// movieDetails: [],
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default function (state = initialState, action: any) {
|
||||||
|
// 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
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const initialState: IInitialState = {
|
||||||
|
isLoading: false,
|
||||||
|
movieDetails: {
|
||||||
|
backdrop_path: '',
|
||||||
|
poster_path: '',
|
||||||
|
title: '',
|
||||||
|
name: '',
|
||||||
|
vote_average: '',
|
||||||
|
release_date: '',
|
||||||
|
first_air_date: '',
|
||||||
|
runtime: '',
|
||||||
|
episode_run_time: '',
|
||||||
|
number_of_episodes: '',
|
||||||
|
number_of_seasons: '',
|
||||||
|
overview: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getMovieDetailsAsync = createAsyncThunk<
|
||||||
|
any,
|
||||||
|
string,
|
||||||
|
{ state: RootState }
|
||||||
|
>('movieDetails/getMovieDetailsAsync', async (mediaType, mediaId) => {
|
||||||
|
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 response = await axios.get(urlPath)
|
||||||
|
return response.data.results
|
||||||
|
})
|
||||||
|
|
||||||
|
const movieDetailsSlice = createSlice({
|
||||||
|
name: 'movieDetails',
|
||||||
|
initialState,
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: (builder) => {
|
||||||
|
builder.addCase(getMovieDetailsAsync.fulfilled, (state, { payload }) => {
|
||||||
|
state.isLoading = false
|
||||||
|
state.movieDetails = payload
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default movieDetailsSlice.reducer
|
||||||
66
src/store/slices/searchSlice.ts
Normal file
66
src/store/slices/searchSlice.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
import axios from '../../axios-movies'
|
||||||
|
import { RootState } from '../index'
|
||||||
|
import {
|
||||||
|
FETCH_SEARCH_MOVIE,
|
||||||
|
FETCH_SEARCH_MOVIE_FAIL,
|
||||||
|
FETCH_SEARCH_MOVIE_SUCCESS,
|
||||||
|
} from '../actions/index'
|
||||||
|
|
||||||
|
// interface IInitialState {
|
||||||
|
// isLoading: boolean
|
||||||
|
// searchResults: []
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const initialState: IInitialState = {
|
||||||
|
// isLoading: false,
|
||||||
|
// searchResults: [],
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default function (state = initialState, action: any) {
|
||||||
|
// switch (action.type) {
|
||||||
|
// case FETCH_SEARCH_MOVIE:
|
||||||
|
// 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
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
searchResults: [{}],
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const searchItemsAsync = createAsyncThunk<
|
||||||
|
any,
|
||||||
|
void,
|
||||||
|
{ state: RootState }
|
||||||
|
>('search/getSearchItems', async (searchTerm) => {
|
||||||
|
const response = await axios.get(
|
||||||
|
`/search/multi?api_key=${process.env.API_KEY}&language=en-US&include_adult=false&query=${searchTerm}`
|
||||||
|
)
|
||||||
|
return response.data.results
|
||||||
|
})
|
||||||
|
|
||||||
|
const searchSlice = createSlice({
|
||||||
|
name: 'search',
|
||||||
|
initialState,
|
||||||
|
reducers: {},
|
||||||
|
extraReducers: (builder) => {
|
||||||
|
builder.addCase(searchItemsAsync.fulfilled, (state, { payload }) => {
|
||||||
|
state.isLoading = false
|
||||||
|
state.searchResults = payload
|
||||||
|
})
|
||||||
|
builder.addCase(searchItemsAsync.pending, (state) => {
|
||||||
|
state.isLoading = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default searchSlice.reducer
|
||||||
Reference in New Issue
Block a user