프로젝트/영화 목록 (Netflix) 앱

영화목록 (Netflix) 앱 10 - 페이지 접근제한 설정하기

syleemomo 2021. 11. 25. 20:53
728x90

 

* 사용자 정보 유무에 따른 페이지 접근제한 하기 - Home 

import React, { useState, useEffect } from 'react'
import { Link, useNavigate } from 'react-router-dom'

import { Movie, Loading, Input, Button, Menu } from 'components'
import './Home.css'

const Home = () => {

    // 사용자 정보 유무에 따른 페이지 접근 제한하기
    const navigateToRegister = useNavigate()
    const user = JSON.parse(sessionStorage.getItem('user'))
    if(!user){
        useEffect ( () => {
            alert("Sorry ! You need to register first !")
            navigateToRegister('/')
        })
        
        return <></>
    }


    const [loading, setLoading] = useState(true)
    const [movies, setMovies] = useState([])
    const [query, setQuery] = useState('')
    const [isSorted, setIsSorted] = useState(-1)
    const [limit, setLimit] = useState(6)
    const navigate = useNavigate()

    const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
    console.log(likes)
    

    useEffect( () => {
        fetch('https://yts.mx/api/v2/list_movies.json?limit=20')
        .then( res => res.json())
        .then( result => {
            const {data: {movies}} = result
            console.log(movies)
            setLoading(false)
            setMovies(movies)
        })
    }, [])

    const handleChange = (e) => {
        const { value } = e.target
        setQuery(value)
    }

    const sortByYear = (e) => {
        setIsSorted(isSorted * -1)
    }

    const updateLikes = (id) => {
        const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
       
        if(likes[id] === null || likes[id] === undefined){
            likes[id] = 0
        }
        likes[id] += 1
        sessionStorage.setItem('likes', JSON.stringify(likes))
    }

    const handleRemove = (id) => {
        const moviesFiltered = movies.filter(movie => movie.id !== id)
        setMovies(moviesFiltered)

        // likes 리스트에서도 해당 영화에 대한 좋아요 정보 제거
        const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
        delete likes[id]
        sessionStorage.setItem('likes', JSON.stringify(likes))

    }
    const displayEntireMovies = () => {
        console.log('display all movies !')
        setLimit(movies.length)
    }

    const homeUI = movies
                        .filter(movie => {
                            const title = movie.title.toLowerCase()
                            const genres = movie.genres.join(' ').toLowerCase()
                            const q = query.toLowerCase()
                        
                            return title.includes(q) || genres.includes(q)
                        })
                        .sort( (a, b) => {
                            return (b.year - a.year) * isSorted;
                        })
                        .slice(0, limit)
                        .map(movie =>
                            <div className='movie-item' key={movie.id}  >
                                <div className='movie-delete' onClick={(e) => handleRemove(movie.id)}>X</div>
                                <Link 
                                    to='/detail'
                                    state={{ movie }} 
                                    style={{ textDecoration: 'none', color: 'white'}}
                                    onClick={() => updateLikes(movie.id)}
                                >
                                    
                                    <Movie 
                                            title={movie.title} 
                                            genres={movie.genres} 
                                            cover={movie.medium_cover_image} 
                                            summary={movie.summary}
                                            year={movie.year}
                                            rating={movie.rating}
                                            likes={likes[movie.id]}
                                        />
                                </Link>
                            </div> 
                                    )

    const toRankPage = () => {
        navigate('/recommend', { state: { movies }})
    }
    return (
        <>
            {loading? <Loading/>: <div className='Home-container'>
                                    <Menu>
                                        <Button handleClick={toRankPage}>Rank</Button>
                                    </Menu>
                                    <div className='Home-entire'>
                                        <Button handleClick={displayEntireMovies}>See Entire Movies</Button>
                                    </div>
                                    
                                    <div className='Home-contents'>
                                        <Input name='search' type='text' placeholder='Search movies ...' value={query} onChange={handleChange}/>
                                        <Button handleClick={sortByYear}>정렬</Button>
                                        <div className='Home-movies'>{homeUI}</div>
                                    </div>
                                  </div>}
        </>
    )
}

export default Home

Home.js 파일을 위와 같이 수정하자!

// 사용자 정보 유무에 따른 페이지 접근 제한하기
const navigateToRegister = useNavigate()
const user = JSON.parse(sessionStorage.getItem('user'))
if(!user){
    useEffect ( () => {
        alert("Sorry ! You need to register first !")
        navigateToRegister('/')
    })

    return <></>
}

위 코드가 추가되었다. 사용자가 /home 경로로 직접 접근했을때 세션스토리지로부터 사용자 정보를 조회한다. 사용자 정보가 존재하면 홈화면에 영화목록을 보여주고, 그렇지 않으면 경고창을 띄운 다음 사용자 등록 화면으로 이동한다. 즉, 사용자에게 유저 정보를 입력하도록 안내한다. 

 

* 사용자 정보 유무에 따른 페이지 접근제한 하기 - Detail

import React, { useEffect } from 'react'
import { Movie, Button, Menu } from 'components'
import { useLocation, useNavigate } from 'react-router-dom'

import './Detail.css'

const Detail = () => {
    // 사용자 정보 유무에 따른 페이지 접근 제한하기
    const navigateToRegister = useNavigate()
    const user = JSON.parse(sessionStorage.getItem('user'))
    if(!user){
        useEffect ( () => {
            alert("Sorry ! You need to register first !")
            navigateToRegister('/')
        })
        
        return <></>
    }

    
    const location = useLocation()
    const { movie } = location.state
    const { yt_trailer_code } = movie
    console.log(movie)
    const navigate = useNavigate()

    const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
    console.log(likes)

    const watchMovieTrailer = () => {
        window.location.href = yt_trailer_code? `https://www.youtube.com/watch?v=${yt_trailer_code}`: ""
    }
    const toHomePage = () => {
        navigate('/home')
    }
    return (
        <div className='Detail-container'>
            <Menu>
                <Button handleClick={toHomePage}>Home</Button>
            </Menu>
            <div className='Detail-contents'>
                <Movie title={movie.title} 
                        genres={movie.genres} 
                        cover={movie.medium_cover_image} 
                        summary={movie.summary}
                        year={movie.year}
                        rating={movie.rating}
                        likes={likes[movie.id]}>    
                </Movie>

                <div className='Movie-info'>
                    <p className='Movie-runtime'>Runtime {movie.runtime} min.</p>
                    <p className='Movie-summary'>{movie.summary}</p>
                    <a href={movie.torrents.length !== 0 ? movie.torrents[0].url : ''} download>Download Torrent</a><br/>
                    <Button handleClick={watchMovieTrailer}>Watch Youtube trailer</Button>
                </div>
            </div>
        </div>
    )
}
export default Detail

Detail.js 파일을 위와 같이 수정하자!

import React, { useEffect } from 'react'

useEffect 함수를 추가로 임포트한다. 

// 사용자 정보 유무에 따른 페이지 접근 제한하기
const navigateToRegister = useNavigate()
const user = JSON.parse(sessionStorage.getItem('user'))
if(!user){
    useEffect ( () => {
        alert("Sorry ! You need to register first !")
        navigateToRegister('/')
    })

    return <></>
}

Home.js 와 동일한 코드를 추가하면 된다. 

 

* 사용자 정보 유무에 따른 페이지 접근 제한하기 - Recommendation

import React, { useEffect } from 'react'
import { useLocation, Link, useNavigate } from 'react-router-dom'

import { Movie, Menu, Button } from 'components'
import './Recommendation.css'

const Recommendation = () => {
    
    // 사용자 정보 유무에 따른 페이지 접근 제한하기
    const navigateToRegister = useNavigate()
    const user = JSON.parse(sessionStorage.getItem('user'))
    if(!user){
        useEffect ( () => {
            alert("Sorry ! You need to register first !")
            navigateToRegister('/')
        })
        
        return <></>
    }


    const location = useLocation()
    const { movies } = location.state
    console.log(movies)
    const navigate = useNavigate()

    const likes = JSON.parse(sessionStorage.getItem('likes')) || {}
    console.log(likes)

    const toHomePage = () => {
        navigate('/home')
    }

    const bestMovies = movies
                            .sort( (a, b) => {
                                return (b.rating - a.rating);
                            })
                            .slice(0, 3)
                            .map(movie =>
                                <Link key={movie.id}  
                                    to='/detail'
                                    state={{ movie }} 
                                    style={{ textDecoration: 'none', color: 'white'}}
                                >
                                    <Movie 
                                            title={movie.title} 
                                            genres={movie.genres} 
                                            cover={movie.medium_cover_image} 
                                            summary={movie.summary}
                                            year={movie.year}
                                            rating={movie.rating}
                                            likes={likes[movie.id]}
                                        />
                                </Link> 
                                        )
    
    // likes 객체를 배열 객체로 변환하기
    const likesArray = []
    for(let like in likes){
        likesArray.push({ id: like, favorite: likes[like]})
    }

    // favorite (좋아요 숫자) 기준으로 정렬하기
    const bestMoviesByLikes = likesArray
    .sort( (a, b) => {
        return (b.favorite - a.favorite);
    })
    .slice(0, 3)
    .map(likeInfo => {
        const movieId = parseInt(likeInfo.id) 
        const movie = movies.filter(movie => movie.id === movieId)[0]
        console.log('movie by likes',parseInt(likeInfo.id))
        console.log('movie: ', movie)

        return (
            <Link key={movie.id}  
            to='/detail'
            state={{ movie }} 
            style={{ textDecoration: 'none', color: 'white'}}
        >
            <Movie 
                    title={movie.title} 
                    genres={movie.genres} 
                    cover={movie.medium_cover_image} 
                    summary={movie.summary}
                    year={movie.year}
                    rating={movie.rating}
                    likes={likes[movie.id]}
                />
        </Link> 
        )     
     } )
                


    return (
        <div className='Recommendation-container'>
            <Menu>
                <Button handleClick={toHomePage}>Home</Button>
            </Menu>
            <div className='Recommendation-text first-text'>Best Movies by rating</div>
            <div className='Recommendation-bestmovies'>{bestMovies}</div>
            <div className='Recommendation-text second-text'>Best Movies by likes</div>
            <div className='Recommendation-bestmovies'>{bestMoviesByLikes}</div>
        </div>
    )
}
export default Recommendation

Recommendation.js 파일을 위와 같이 수정하자!

import React, { useEffect } from 'react'

useEffect 함수를 추가로 임포트한다. 

// 사용자 정보 유무에 따른 페이지 접근 제한하기
const navigateToRegister = useNavigate()
const user = JSON.parse(sessionStorage.getItem('user'))
if(!user){
    useEffect ( () => {
        alert("Sorry ! You need to register first !")
        navigateToRegister('/')
    })

    return <></>
}

Home.js 와 동일한 코드를 추가하면 된다. 

728x90