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",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "^1.9.0",
|
||||
"@types/jest": "^29.2.3",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"@types/react-redux": "^7.1.24",
|
||||
"axios": "^1.2.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"firebase": "^9.14.0",
|
||||
@@ -3929,6 +3931,29 @@
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"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": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz",
|
||||
@@ -4944,6 +4969,17 @@
|
||||
"@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": {
|
||||
"version": "1.17.1",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.22.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz",
|
||||
@@ -28410,6 +28462,17 @@
|
||||
"@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": {
|
||||
"version": "1.17.1",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.22.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
"author": "Andres Alcocer",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "^1.9.0",
|
||||
"@types/jest": "^29.2.3",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"@types/react-redux": "^7.1.24",
|
||||
"axios": "^1.2.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"firebase": "^9.14.0",
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import * as movieActions from '../store/actions'
|
||||
import * as actionMovies from '../store/slices/actionMovieSlice'
|
||||
import { useAppSelector, useAppDispatch } from '../store'
|
||||
|
||||
import Header from './Header'
|
||||
import DisplayMovieRow from './DisplayMovieRow'
|
||||
|
||||
const MainContent = ({ selectMovieHandler }) => {
|
||||
const { movieDetails } = useSelector((state) => state.movieDetails)
|
||||
const netflixOriginals = useSelector((state) => state.netflixOriginals)
|
||||
const trending = useSelector((state) => state.trending)
|
||||
const topRated = useSelector((state) => state.topRated)
|
||||
const actionMovies = useSelector((state) => state.action)
|
||||
const comedyMovies = useSelector((state) => state.comedy)
|
||||
const horrorMovies = useSelector((state) => state.horror)
|
||||
const romanceMovies = useSelector((state) => state.romance)
|
||||
const documentaries = useSelector((state) => state.documentary)
|
||||
// const { movieDetails } = useSelector((state) => state.movieDetails)
|
||||
// const netflixOriginals = useSelector((state) => state.netflixOriginals)
|
||||
// const trending = useSelector((state) => state.trending)
|
||||
// const topRated = useSelector((state) => state.topRated)
|
||||
const actionMoviesState = useAppSelector((state) => state.action)
|
||||
// const comedyMovies = useSelector((state) => state.comedy)
|
||||
// const horrorMovies = useSelector((state) => state.horror)
|
||||
// const romanceMovies = useSelector((state) => state.romance)
|
||||
// const documentaries = useSelector((state) => state.documentary)
|
||||
|
||||
const dispatch = useDispatch()
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(movieActions.fetchMovieDetails('tv', '63351'))
|
||||
dispatch(movieActions.fetchNetflixOriginals())
|
||||
dispatch(movieActions.fetchTrending())
|
||||
dispatch(movieActions.fetchTopRated())
|
||||
dispatch(movieActions.fetchActionMovies())
|
||||
dispatch(movieActions.fetchComedyMovies())
|
||||
dispatch(movieActions.fetchHorrorMovies())
|
||||
dispatch(movieActions.fetchRomanceMovies())
|
||||
dispatch(movieActions.fetchDocumentaries())
|
||||
// dispatch(movieActions.fetchMovieDetails('tv', '63351'))
|
||||
// dispatch(movieActions.fetchNetflixOriginals())
|
||||
// dispatch(movieActions.fetchTrending())
|
||||
// dispatch(movieActions.fetchTopRated())
|
||||
dispatch(actionMovies.getActionMoviesAsync())
|
||||
// dispatch(movieActions.fetchComedyMovies())
|
||||
// dispatch(movieActions.fetchHorrorMovies())
|
||||
// dispatch(movieActions.fetchRomanceMovies())
|
||||
// dispatch(movieActions.fetchDocumentaries())
|
||||
}, [dispatch])
|
||||
|
||||
return (
|
||||
<div className='container'>
|
||||
<Header movie={movieDetails} />
|
||||
{/* <Header movie={movieDetails} /> */}
|
||||
<div className='movieShowcase'>
|
||||
<DisplayMovieRow
|
||||
{/* <DisplayMovieRow
|
||||
isNetflixMovies={true}
|
||||
title='Netflix Originals'
|
||||
selectMovieHandler={selectMovieHandler}
|
||||
@@ -49,13 +49,13 @@ const MainContent = ({ selectMovieHandler }) => {
|
||||
title='Top Rated'
|
||||
selectMovieHandler={selectMovieHandler}
|
||||
movies={topRated.data}
|
||||
/>
|
||||
/> */}
|
||||
<DisplayMovieRow
|
||||
title='Action Movies'
|
||||
selectMovieHandler={selectMovieHandler}
|
||||
movies={actionMovies.data}
|
||||
movies={actionMoviesState.data}
|
||||
/>
|
||||
<DisplayMovieRow
|
||||
{/* <DisplayMovieRow
|
||||
title='Comedy'
|
||||
selectMovieHandler={selectMovieHandler}
|
||||
movies={comedyMovies.data}
|
||||
@@ -74,7 +74,7 @@ const MainContent = ({ selectMovieHandler }) => {
|
||||
title='Documentaries'
|
||||
selectMovieHandler={selectMovieHandler}
|
||||
movies={documentaries.data}
|
||||
/>
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import React from 'react'
|
||||
import * as ReactDOM from 'react-dom/client'
|
||||
import { Provider } from 'react-redux'
|
||||
import { createStore, applyMiddleware } from 'redux'
|
||||
import ReduxThunk from 'redux-thunk'
|
||||
import '@babel/polyfill'
|
||||
|
||||
import reducers from './store/reducers'
|
||||
import { store } from './store'
|
||||
import AppRouter from './AppRouter'
|
||||
|
||||
// Import Swiper styles
|
||||
@@ -15,8 +13,6 @@ import 'swiper/css/pagination'
|
||||
// Import main sass file to apply global styles
|
||||
import './static/sass/style.scss'
|
||||
|
||||
const store = createStore(reducers, applyMiddleware(ReduxThunk))
|
||||
|
||||
const app = (
|
||||
<Provider store={store}>
|
||||
<AppRouter />
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
import { useAppSelector, useAppDispatch } from '../store'
|
||||
import ModalMovieDetails from '../components/ModalMovieDetails'
|
||||
import Modal from '../components/UI/Modal'
|
||||
import { useDebounce } from '../hooks/useDebounce'
|
||||
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
|
||||
// the query string for you.
|
||||
const useQuery = () => {
|
||||
@@ -16,9 +23,11 @@ const Search = () => {
|
||||
let query = useQuery()
|
||||
const debouncedSearchTerm = useDebounce(query.get('q'), 500)
|
||||
const [isToggleModal, setIsToggleModal] = useState(false)
|
||||
const { searchResults, isLoading } = useSelector((state) => state.searchMovie)
|
||||
const { movieDetails } = useSelector((state) => state.movieDetails)
|
||||
const dispatch = useDispatch()
|
||||
const { searchResults, isLoading } = useAppSelector(
|
||||
(state) => state.searchMovie
|
||||
)
|
||||
const { movieDetails } = useAppSelector((state) => state.movieDetails)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedSearchTerm) {
|
||||
@@ -30,7 +39,7 @@ const Search = () => {
|
||||
setIsToggleModal(false)
|
||||
}
|
||||
|
||||
const onSelectMovieHandler = (movie) => {
|
||||
const onSelectMovieHandler = (movie: IMovie) => {
|
||||
dispatch(movieActions.fetchMovieDetails(movie.media_type, movie.id))
|
||||
setIsToggleModal(true)
|
||||
}
|
||||
@@ -39,7 +48,7 @@ const Search = () => {
|
||||
return searchResults.length > 0 ? (
|
||||
<>
|
||||
<div className='search-container'>
|
||||
{searchResults.map((movie) => {
|
||||
{searchResults.map((movie: IMovie) => {
|
||||
if (movie.backdrop_path !== null && movie.media_type !== 'person') {
|
||||
const movieImageUrl =
|
||||
'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}`
|
||||
if (mediaType === media_type.tv)
|
||||
urlPath = `/tv/${mediaId}?api_key=${process.env.API_KEY}`
|
||||
console.log('media type', mediaType, urlPath)
|
||||
const request = await axios.get(urlPath)
|
||||
dispatch({ type: FETCH_MOVIE_DETAILS_SUCCESS, payload: request })
|
||||
} 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