converted components to .ts

This commit is contained in:
andres alcocer
2022-11-26 16:25:35 -05:00
parent 907500f0f5
commit 7b82882998
33 changed files with 291 additions and 326 deletions

View File

@@ -2,3 +2,8 @@ declare module '*.svg' {
const content: any const content: any
export default content export default content
} }
declare module '*.png' {
const value: any
export = value
}

View File

@@ -1,4 +1,4 @@
import React, { Component } from 'react' import React from 'react'
import { Swiper, SwiperSlide } from 'swiper/react' import { Swiper, SwiperSlide } from 'swiper/react'
import SwiperCore, { Navigation, Pagination, Scrollbar, A11y } from 'swiper' import SwiperCore, { Navigation, Pagination, Scrollbar, A11y } from 'swiper'

View File

@@ -6,7 +6,12 @@ import MuteIcon from '../static/images/mute.svg'
import UnmuteIcon from '../static/images/unmute.svg' import UnmuteIcon from '../static/images/unmute.svg'
import ReactPlayer from 'react-player' import ReactPlayer from 'react-player'
const Header = ({ movie: { name, overview } }) => { interface IHeader {
name: string
overview: string
}
const Header = ({ name, overview }: IHeader) => {
const [isMuted, setIsMuted] = useState(true) const [isMuted, setIsMuted] = useState(true)
return ( return (
@@ -33,7 +38,6 @@ const Header = ({ movie: { name, overview } }) => {
<AddLogo className='header__container-btnMyList-add' /> <AddLogo className='header__container-btnMyList-add' />
My List My List
</button> </button>
{isMuted ? ( {isMuted ? (
<MuteIcon <MuteIcon
onClick={() => setIsMuted(false)} onClick={() => setIsMuted(false)}

View File

@@ -3,6 +3,11 @@ import * as actionMoviesSlice from '../store/slices/actionMovieSlice'
import * as movieDetailsSlice from '../store/slices/movieDetailsSlice' import * as movieDetailsSlice from '../store/slices/movieDetailsSlice'
import * as netflixOriginalsSlice from '../store/slices/netflixOriginalsSlice' import * as netflixOriginalsSlice from '../store/slices/netflixOriginalsSlice'
import * as trendingSlice from '../store/slices/trendingSlice' import * as trendingSlice from '../store/slices/trendingSlice'
import * as topRatedSlice from '../store/slices/topRatedSlice'
import * as comedySlice from '../store/slices/comedyMoviesSlice'
import * as documentarySlice from '../store/slices/documentarySlice'
import * as horrorMoviesSlice from '../store/slices/horrorMoviesSlice'
import * as romanceMoviesSlice from '../store/slices/romanceMoviesSlice'
import { useAppSelector, useAppDispatch } from '../store' import { useAppSelector, useAppDispatch } from '../store'
import Header from './Header' import Header from './Header'
@@ -12,17 +17,16 @@ const MainContent = ({ selectMovieHandler }: { selectMovieHandler: any }) => {
const { movieDetails } = useAppSelector((state) => state.movieDetails) const { movieDetails } = useAppSelector((state) => state.movieDetails)
const netflixOriginals = useAppSelector((state) => state.netflixOriginals) const netflixOriginals = useAppSelector((state) => state.netflixOriginals)
const trending = useAppSelector((state) => state.trending) const trending = useAppSelector((state) => state.trending)
// const topRated = useSelector((state) => state.topRated) const topRated = useAppSelector((state) => state.topRated)
const actionMoviesState = useAppSelector((state) => state.action) const actionMoviesState = useAppSelector((state) => state.action)
// const comedyMovies = useSelector((state) => state.comedy) const comedyMovies = useAppSelector((state) => state.comedy)
// const horrorMovies = useSelector((state) => state.horror) const horrorMovies = useAppSelector((state) => state.horror)
// const romanceMovies = useSelector((state) => state.romance) const romanceMovies = useAppSelector((state) => state.romance)
// const documentaries = useSelector((state) => state.documentary) const documentaries = useAppSelector((state) => state.documentary)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
useEffect(() => { useEffect(() => {
// dispatch(movieDetailsSlice.getMovieDetailsAsync('tv', '63351'))
dispatch( dispatch(
movieDetailsSlice.getMovieDetailsAsync({ movieDetailsSlice.getMovieDetailsAsync({
mediaType: 'tv', mediaType: 'tv',
@@ -31,17 +35,17 @@ const MainContent = ({ selectMovieHandler }: { selectMovieHandler: any }) => {
) )
dispatch(netflixOriginalsSlice.getNetflixOriginalsAsync()) dispatch(netflixOriginalsSlice.getNetflixOriginalsAsync())
dispatch(trendingSlice.getTrendingAsync()) dispatch(trendingSlice.getTrendingAsync())
// dispatch(movieActions.fetchTopRated()) dispatch(topRatedSlice.getTopRatedAsync())
dispatch(actionMoviesSlice.getActionMoviesAsync()) dispatch(actionMoviesSlice.getActionMoviesAsync())
// dispatch(movieActions.fetchComedyMovies()) dispatch(comedySlice.getComedyMoviesAsync())
// dispatch(movieActions.fetchHorrorMovies()) dispatch(horrorMoviesSlice.getHorrorMoviesAsync())
// dispatch(movieActions.fetchRomanceMovies()) dispatch(romanceMoviesSlice.getRomanceMoviesAsync())
// dispatch(movieActions.fetchDocumentaries()) dispatch(documentarySlice.getDocumentariesAsync())
}, [dispatch]) }, [dispatch])
return ( return (
<div className='container'> <div className='container'>
<Header movie={movieDetails} /> <Header name={movieDetails.name} overview={movieDetails.overview} />
<div className='movieShowcase'> <div className='movieShowcase'>
<DisplayMovieRow <DisplayMovieRow
isNetflixMovies={true} isNetflixMovies={true}
@@ -54,17 +58,17 @@ const MainContent = ({ selectMovieHandler }: { selectMovieHandler: any }) => {
selectMovieHandler={selectMovieHandler} selectMovieHandler={selectMovieHandler}
movies={trending.data} movies={trending.data}
/> />
{/* <DisplayMovieRow <DisplayMovieRow
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={actionMoviesState.data} movies={actionMoviesState.data}
/> />
{/* <DisplayMovieRow <DisplayMovieRow
title='Comedy' title='Comedy'
selectMovieHandler={selectMovieHandler} selectMovieHandler={selectMovieHandler}
movies={comedyMovies.data} movies={comedyMovies.data}
@@ -83,7 +87,7 @@ const MainContent = ({ selectMovieHandler }: { selectMovieHandler: any }) => {
title='Documentaries' title='Documentaries'
selectMovieHandler={selectMovieHandler} selectMovieHandler={selectMovieHandler}
movies={documentaries.data} movies={documentaries.data}
/> */} />
</div> </div>
</div> </div>
) )

35
src/components/Modal.tsx Normal file
View File

@@ -0,0 +1,35 @@
import React from 'react'
interface IBackdrop {
toggleBackdrop?: () => void
show: boolean
}
interface IModal extends IBackdrop {
backgroundImage: string
children: JSX.Element
}
const Backdrop = ({ toggleBackdrop, show }: IBackdrop) =>
show ? <div onClick={toggleBackdrop} className='backdrop'></div> : null
const Modal = ({ show, toggleBackdrop, children, backgroundImage }: IModal) => {
const backgroundStyle = {
backgroundSize: 'cover',
backgroundImage: `url(https://image.tmdb.org/t/p/original/${backgroundImage})`,
}
return (
<div>
<Backdrop show={show} toggleBackdrop={toggleBackdrop} />
<div
style={backgroundStyle}
className={show ? 'modal show' : 'modal hide'}
>
{children}
</div>
</div>
)
}
export default Modal

View File

@@ -2,9 +2,10 @@ import React from 'react'
import AddIcon from '../static/images/add.svg' import AddIcon from '../static/images/add.svg'
import PlayIcon from '../static/images/play-button.svg' import PlayIcon from '../static/images/play-button.svg'
import { IMovieDetails } from '../store/slices/movieDetailsSlice'
const MovieDetails = ({ const MovieDetails = (props: IMovieDetails) => {
movie: { const {
title, title,
name, name,
vote_average, vote_average,
@@ -15,8 +16,7 @@ const MovieDetails = ({
number_of_episodes, number_of_episodes,
number_of_seasons, number_of_seasons,
overview, overview,
}, } = props
}) => {
return ( return (
<div className='modal__container'> <div className='modal__container'>
<h1 className='modal__title'>{title || name}</h1> <h1 className='modal__title'>{title || name}</h1>

View File

@@ -7,7 +7,7 @@ import SearchLogo from '../static/images/search-icon.svg'
import NetflixLogo from '../static/images/Netflix_Logo_RGB.png' import NetflixLogo from '../static/images/Netflix_Logo_RGB.png'
import BellLogo from '../static/images/bell-logo.svg' import BellLogo from '../static/images/bell-logo.svg'
import DropdownArrow from '../static/images/drop-down-arrow.svg' import DropdownArrow from '../static/images/drop-down-arrow.svg'
import DropdownContent from '../components/DropdownContent' import DropdownContent from './DropdownContent'
const Navbar = () => { const Navbar = () => {
const navigate = useNavigate() const navigate = useNavigate()
@@ -16,7 +16,7 @@ const Navbar = () => {
const [scrollDimensions] = useScroll() const [scrollDimensions] = useScroll()
const { scrollY } = scrollDimensions const { scrollY } = scrollDimensions
const onChange = async (event) => { const onChange = async (event: any) => {
setUserInput(event.target.value) setUserInput(event.target.value)
} }

View File

@@ -1,6 +0,0 @@
import React from 'react'
const backdrop = ({ toggleBackdrop, show }) =>
show ? <div onClick={toggleBackdrop} className='backdrop'></div> : null
export default backdrop

View File

@@ -1,24 +0,0 @@
import React from 'react'
import Backdrop from './Backdrop'
const Modal = ({ show, modalClosed, children, backgroundImage }) => {
const backgroundStyle = {
backgroundSize: 'cover',
backgroundImage: `url(https://image.tmdb.org/t/p/original/${backgroundImage})`,
}
return (
<div>
<Backdrop show={show} toggleBackdrop={modalClosed} />
<div
style={backgroundStyle}
className={show ? 'modal show' : 'modal hide'}
>
{children}
</div>
</div>
)
}
export default Modal

View File

@@ -1,6 +1,5 @@
import { useDebounce } from './useDebounce' import { useDebounce } from './useDebounce'
import { useScroll } from './useScroll' import { useScroll } from './useScroll'
import { useViewport } from './useViewport' import { useViewport } from './useViewport'
import { useWithRouter } from './useWithRouter'
export { useDebounce, useScroll, useViewport, useWithRouter } export { useDebounce, useScroll, useViewport }

View File

@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
export const useDebounce = (value, delay) => { export const useDebounce = (value: string, delay: number) => {
// State and setters for debounced value // State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value) const [debouncedValue, setDebouncedValue] = useState(value)

View File

@@ -1,13 +1,16 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import MainContent from '../components/MainContent' import MainContent from '../components/MainContent'
import Modal from '../components/UI/Modal' import Modal from '../components/Modal'
import ModalMovieDetails from '../components/ModalMovieDetails' import ModalMovieDetails from '../components/ModalMovieDetails'
import { IMovieDetails } from '../store/slices/movieDetailsSlice' import { IMovieDetails } from '../store/slices/movieDetailsSlice'
const Home = () => { const Home = () => {
const [toggleModal, setToggleModal] = useState(false) const [toggleModal, setToggleModal] = useState(false)
const [movieDetails, setMovieDetails] = useState<IMovieDetails>() const [movieDetails, setMovieDetails] = useState<IMovieDetails>({
poster_path: '',
backdrop_path: '',
})
const selectMovieHandler = async (movie: IMovieDetails) => { const selectMovieHandler = async (movie: IMovieDetails) => {
setToggleModal(true) setToggleModal(true)
@@ -25,10 +28,10 @@ const Home = () => {
</div> </div>
<Modal <Modal
show={toggleModal} show={toggleModal}
modalClosed={closeModal} toggleBackdrop={closeModal}
backgroundImage={movieDetails.backdrop_path || movieDetails.poster_path} backgroundImage={movieDetails.backdrop_path || movieDetails.poster_path}
> >
<ModalMovieDetails movie={movieDetails} /> <ModalMovieDetails {...movieDetails} />
</Modal> </Modal>
</> </>
) )

View File

@@ -3,9 +3,10 @@ import { useLocation } from 'react-router-dom'
import { useAppSelector, useAppDispatch } from '../store' 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/Modal'
import { useDebounce } from '../hooks/useDebounce' import { useDebounce } from '../hooks/useDebounce'
import * as movieActions from '../store/actions' import * as searchSlice from '../store/slices/searchSlice'
import * as movieDetailsSlice from '../store/slices/movieDetailsSlice'
interface IMovie { interface IMovie {
id: string id: string
@@ -31,7 +32,7 @@ const Search = () => {
useEffect(() => { useEffect(() => {
if (debouncedSearchTerm) { if (debouncedSearchTerm) {
dispatch(movieActions.fetchSearchMovie(debouncedSearchTerm)) dispatch(searchSlice.searchItemsAsync(debouncedSearchTerm))
} }
}, [debouncedSearchTerm]) }, [debouncedSearchTerm])
@@ -40,7 +41,12 @@ const Search = () => {
} }
const onSelectMovieHandler = (movie: IMovie) => { const onSelectMovieHandler = (movie: IMovie) => {
dispatch(movieActions.fetchMovieDetails(movie.media_type, movie.id)) dispatch(
movieDetailsSlice.getMovieDetailsAsync({
mediaType: movie.media_type,
mediaId: movie.id,
})
)
setIsToggleModal(true) setIsToggleModal(true)
} }
@@ -67,12 +73,12 @@ const Search = () => {
</div> </div>
<Modal <Modal
show={isToggleModal} show={isToggleModal}
modalClosed={onCloseModalHandler} toggleBackdrop={onCloseModalHandler}
backgroundImage={ backgroundImage={
movieDetails.backdrop_path || movieDetails.poster_path movieDetails.backdrop_path || movieDetails.poster_path
} }
> >
<ModalMovieDetails movie={movieDetails} /> <ModalMovieDetails {...movieDetails} />
</Modal> </Modal>
</> </>
) : ( ) : (

View File

@@ -1,149 +0,0 @@
import axios from '../../axios-movies'
export const FETCH_TRENDING = 'FETCH_TRENDING'
export const FETCH_NETFLIX_ORIGINALS = 'FETCH_NETFLIX_ORIGINALS'
export const FETCH_TOP_RATED = 'FETCH_TOP_RATED'
export const FETCH_ACTION_MOVIES = 'FETCH_ACTION_MOVIES'
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: string, mediaId: string) => {
return async (dispatch: any) => {
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: string) => {
return async (dispatch: any) => {
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_SUCCESS, payload: request })
} catch (error) {
dispatch({ type: FETCH_SEARCH_MOVIE_FAIL })
console.log('error', error)
}
}
}
export const fetchNetflixOriginals = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/discover/tv?api_key=${process.env.API_KEY}&with_networks=213`
)
dispatch({ type: FETCH_NETFLIX_ORIGINALS, payload: request })
} catch (error) {
console.log('error', error)
}
}
}
export const fetchTrending = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/trending/all/week?api_key=${process.env.API_KEY}&language=en-US`
)
dispatch({ type: FETCH_TRENDING, payload: request })
} catch (error) {}
}
}
export const fetchTopRated = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/movie/top_rated?api_key=${process.env.API_KEY}&language=en-US`
)
dispatch({ type: FETCH_TOP_RATED, payload: request })
} catch (error) {}
}
}
export const fetchActionMovies = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=28`
)
dispatch({ type: FETCH_ACTION_MOVIES, payload: request })
} catch (error) {}
}
}
export const fetchComedyMovies = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=35`
)
dispatch({ type: FETCH_COMEDY_MOVIES, payload: request })
} catch (error) {}
}
}
export const fetchHorrorMovies = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=27`
)
dispatch({ type: FETCH_HORROR_MOVIES, payload: request })
} catch (error) {}
}
}
export const fetchRomanceMovies = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=10749`
)
dispatch({ type: FETCH_ROMANCE_MOVIES, payload: request })
} catch (error) {}
}
}
export const fetchDocumentaries = () => {
return async (dispatch: any) => {
try {
const request = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=99`
)
dispatch({ type: FETCH_DOCUMENTARIES, payload: request })
} catch (error) {}
}
}

View File

@@ -3,12 +3,12 @@ import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import TrendingReducer from './slices/trendingSlice' import TrendingReducer from './slices/trendingSlice'
import NetflixOriginalsReducer from './slices/netflixOriginalsSlice' import NetflixOriginalsReducer from './slices/netflixOriginalsSlice'
import TopRatedReducer from './slices/reducerTopRated' import TopRatedReducer from './slices/topRatedSlice'
import ActionMoviesReducer from './slices/actionMovieSlice' import ActionMoviesReducer from './slices/actionMovieSlice'
import ComedyMoviesReducer from './slices/reducerComedyMovies' import ComedyMoviesReducer from './slices/comedyMoviesSlice'
import HorrorMoviesReducer from './slices/reducerHorrorMovies' import HorrorMoviesReducer from './slices/horrorMoviesSlice'
import RomanceMoviesReducer from './slices/reducerRomanceMovies' import RomanceMoviesReducer from './slices/romanceMoviesSlice'
import DocumentaryReducer from './slices/reducerDocumentary' import DocumentaryReducer from './slices/documentarySlice'
import SearchMovieReducer from './slices/searchSlice' import SearchMovieReducer from './slices/searchSlice'
import MovieDetailsReducer from './slices/movieDetailsSlice' import MovieDetailsReducer from './slices/movieDetailsSlice'
@@ -16,13 +16,13 @@ export const store = configureStore({
reducer: { reducer: {
trending: TrendingReducer, trending: TrendingReducer,
netflixOriginals: NetflixOriginalsReducer, netflixOriginals: NetflixOriginalsReducer,
// topRated: TopRatedReducer, topRated: TopRatedReducer,
action: ActionMoviesReducer, action: ActionMoviesReducer,
// comedy: ComedyMoviesReducer, comedy: ComedyMoviesReducer,
// horror: HorrorMoviesReducer, horror: HorrorMoviesReducer,
// romance: RomanceMoviesReducer, romance: RomanceMoviesReducer,
searchMovie: SearchMovieReducer, searchMovie: SearchMovieReducer,
// documentary: DocumentaryReducer, documentary: DocumentaryReducer,
movieDetails: MovieDetailsReducer, movieDetails: MovieDetailsReducer,
}, },
}) })

View File

@@ -0,0 +1,33 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from '../../axios-movies'
import { RootState } from '../index'
import { IMovieDetails } from './movieDetailsSlice'
const initialState: { data: IMovieDetails[] } = {
data: [],
}
export const getComedyMoviesAsync = createAsyncThunk<
any,
void,
{ state: RootState }
>('comedy/getComedyMovies', async () => {
const response = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=28`
)
return response.data.results
})
const comedyMovieSlice = createSlice({
name: 'comedyMovie',
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getComedyMoviesAsync.fulfilled, (state, { payload }) => {
state.data = payload
})
},
})
export default comedyMovieSlice.reducer

View File

@@ -0,0 +1,33 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from '../../axios-movies'
import { RootState } from '../index'
import { IMovieDetails } from './movieDetailsSlice'
const initialState: { data: IMovieDetails[] } = {
data: [],
}
export const getDocumentariesAsync = createAsyncThunk<
any,
void,
{ state: RootState }
>('documentary/getDocumentaries', async () => {
const response = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=99`
)
return response.data.results
})
const documentarySlice = createSlice({
name: 'actionMovie',
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getDocumentariesAsync.fulfilled, (state, { payload }) => {
state.data = payload
})
},
})
export default documentarySlice.reducer

View File

@@ -0,0 +1,33 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from '../../axios-movies'
import { RootState } from '../index'
import { IMovieDetails } from './movieDetailsSlice'
const initialState: { data: IMovieDetails[] } = {
data: [],
}
export const getHorrorMoviesAsync = createAsyncThunk<
any,
void,
{ state: RootState }
>('horror/getHorrorMovies', async () => {
const response = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=27`
)
return response.data.results
})
const horrorMoviesSlice = createSlice({
name: 'horrorMovies',
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getHorrorMoviesAsync.fulfilled, (state, { payload }) => {
state.data = payload
})
},
})
export default horrorMoviesSlice.reducer

View File

@@ -6,16 +6,16 @@ import { RootState } from '../index'
export interface IMovieDetails { export interface IMovieDetails {
backdrop_path?: string backdrop_path?: string
poster_path?: string poster_path?: string
title: any title?: any
name: any name?: any
vote_average: any vote_average?: any
release_date: any release_date?: any
first_air_date: any first_air_date?: any
runtime: any runtime?: any
episode_run_time: any episode_run_time?: any
number_of_episodes: any number_of_episodes?: any
number_of_seasons: any number_of_seasons?: any
overview: any overview?: any
} }
interface IInitialState { interface IInitialState {
@@ -29,7 +29,7 @@ const media_type = {
} }
const initialState: IInitialState = { const initialState: IInitialState = {
isLoading: false, isLoading: true,
movieDetails: { movieDetails: {
backdrop_path: '', backdrop_path: '',
poster_path: '', poster_path: '',
@@ -57,7 +57,7 @@ export const getMovieDetailsAsync = createAsyncThunk<
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}`
const response = await axios.get(urlPath) const response = await axios.get(urlPath)
return response.data.results return response.data
}) })
const movieDetailsSlice = createSlice({ const movieDetailsSlice = createSlice({
@@ -67,8 +67,13 @@ const movieDetailsSlice = createSlice({
extraReducers: (builder) => { extraReducers: (builder) => {
builder.addCase(getMovieDetailsAsync.fulfilled, (state, { payload }) => { builder.addCase(getMovieDetailsAsync.fulfilled, (state, { payload }) => {
state.isLoading = false state.isLoading = false
console.log('state ', state)
console.log('payload', payload)
state.movieDetails = payload state.movieDetails = payload
}) })
builder.addCase(getMovieDetailsAsync.pending, (state) => {
state.isLoading = true
})
}, },
}) })

View File

@@ -1,11 +0,0 @@
import { FETCH_COMEDY_MOVIES } from '../actions/index'
export default function (state = {}, action: any) {
switch (action.type) {
case FETCH_COMEDY_MOVIES:
const data = action.payload.data.results
return { ...state, data }
default:
return state
}
}

View File

@@ -1,11 +0,0 @@
import { FETCH_DOCUMENTARIES } from '../actions/index'
export default function (state = {}, action: any) {
switch (action.type) {
case FETCH_DOCUMENTARIES:
const data = action.payload.data.results
return { ...state, data }
default:
return state
}
}

View File

@@ -1,11 +0,0 @@
import { FETCH_HORROR_MOVIES } from '../actions/index'
export default function (state = {}, action: any) {
switch (action.type) {
case FETCH_HORROR_MOVIES:
const data = action.payload.data.results
return { ...state, data }
default:
return state
}
}

View File

@@ -1,11 +0,0 @@
import { FETCH_ROMANCE_MOVIES } from '../actions/index'
export default function (state = {}, action: any) {
switch (action.type) {
case FETCH_ROMANCE_MOVIES:
const data = action.payload.data.results
return { ...state, data }
default:
return state
}
}

View File

@@ -1,11 +0,0 @@
import { FETCH_TOP_RATED } from '../actions/index'
export default function (state = {}, action: any) {
switch (action.type) {
case FETCH_TOP_RATED:
const data = action.payload.data.results
return { ...state, data }
default:
return state
}
}

View File

@@ -0,0 +1,33 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from '../../axios-movies'
import { RootState } from '../index'
import { IMovieDetails } from './movieDetailsSlice'
const initialState: { data: IMovieDetails[] } = {
data: [],
}
export const getRomanceMoviesAsync = createAsyncThunk<
any,
void,
{ state: RootState }
>('romance/getRomanceMovies', async () => {
const response = await axios.get(
`/discover/movie?api_key=${process.env.API_KEY}&with_genres=28`
)
return response.data.results
})
const romanceMovieSlice = createSlice({
name: 'romanceMovie',
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getRomanceMoviesAsync.fulfilled, (state, { payload }) => {
state.data = payload
})
},
})
export default romanceMovieSlice.reducer

View File

@@ -2,35 +2,6 @@ import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from '../../axios-movies' import axios from '../../axios-movies'
import { RootState } from '../index' 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 = { const initialState = {
searchResults: [{}], searchResults: [{}],
@@ -39,7 +10,7 @@ const initialState = {
export const searchItemsAsync = createAsyncThunk< export const searchItemsAsync = createAsyncThunk<
any, any,
void, string,
{ state: RootState } { state: RootState }
>('search/getSearchItems', async (searchTerm) => { >('search/getSearchItems', async (searchTerm) => {
const response = await axios.get( const response = await axios.get(

View File

@@ -0,0 +1,33 @@
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from '../../axios-movies'
import { RootState } from '../index'
import { IMovieDetails } from './movieDetailsSlice'
const initialState: { data: IMovieDetails[] } = {
data: [],
}
export const getTopRatedAsync = createAsyncThunk<
any,
void,
{ state: RootState }
>('topRated/getTopRated', async () => {
const response = await axios.get(
`/movie/top_rated?api_key=${process.env.API_KEY}&language=en-US`
)
return response.data.results
})
const trendingSlice = createSlice({
name: 'topRated',
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getTopRatedAsync.fulfilled, (state, { payload }) => {
state.data = payload
})
},
})
export default trendingSlice.reducer

View File

@@ -8,7 +8,9 @@
"sourceMap": true, "sourceMap": true,
"allowJs": true, "allowJs": true,
"moduleResolution": "node", "moduleResolution": "node",
"typeRoots": ["types/", "node_modules/@types"], "typeRoots": ["custom.d.ts", "node_modules/@types"],
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true
} },
"files": ["custom.d.ts"],
"include": ["src/", "custom.d.ts"]
} }