converted components to .ts
This commit is contained in:
5
types/custom.d.ts → custom.d.ts
vendored
5
types/custom.d.ts → custom.d.ts
vendored
@@ -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
|
||||||
|
}
|
||||||
@@ -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'
|
||||||
|
|
||||||
|
|||||||
@@ -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)}
|
||||||
@@ -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
35
src/components/Modal.tsx
Normal 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
|
||||||
@@ -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>
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
|
|
||||||
const backdrop = ({ toggleBackdrop, show }) =>
|
|
||||||
show ? <div onClick={toggleBackdrop} className='backdrop'></div> : null
|
|
||||||
|
|
||||||
export default backdrop
|
|
||||||
@@ -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
|
|
||||||
@@ -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 }
|
||||||
@@ -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)
|
||||||
|
|
||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
33
src/store/slices/comedyMoviesSlice.ts
Normal file
33
src/store/slices/comedyMoviesSlice.ts
Normal 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
|
||||||
33
src/store/slices/documentarySlice.ts
Normal file
33
src/store/slices/documentarySlice.ts
Normal 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
|
||||||
33
src/store/slices/horrorMoviesSlice.ts
Normal file
33
src/store/slices/horrorMoviesSlice.ts
Normal 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
|
||||||
@@ -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
|
||||||
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
33
src/store/slices/romanceMoviesSlice.ts
Normal file
33
src/store/slices/romanceMoviesSlice.ts
Normal 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
|
||||||
@@ -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(
|
||||||
|
|||||||
33
src/store/slices/topRatedSlice.ts
Normal file
33
src/store/slices/topRatedSlice.ts
Normal 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
|
||||||
@@ -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"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user