-
MovieApp 만들기) 5.Favorite 페이지 만들기NODE.JS 2021. 4. 27. 23:05
좋아하는 영화 목록을 나타내는 Favorite page를 만들기 위해서는
1. favorite page template을 만들고
2. mongoDB에서 favorite 된 목록을 가져오고
3. 가져온 기능을 화면에 나타내주고,
4. remove 기능을 추가하는 순서로 진행한다.
client->views->FavoritePage->FavoritePage.js파일을 만들어준다.
App.js 파일에 가서 화면을 볼 수 있게 페이지를 추가해준다. 여기서 favorite의 루트는 로그인 한 사람만 볼 수 있도록 true 로 해준다.
import React, { Suspense } from 'react'; import { Route, Switch } from "react-router-dom"; import Auth from "../hoc/auth"; // pages for this product import LandingPage from "./views/LandingPage/LandingPage.js"; import LoginPage from "./views/LoginPage/LoginPage.js"; import RegisterPage from "./views/RegisterPage/RegisterPage.js"; import NavBar from "./views/NavBar/NavBar"; import Footer from "./views/Footer/Footer"; import MovieDetail from "./views/MovieDetail/MovieDetail"; import FavoritePage from "./views/FavoritePage/FavoritePage"; //null Anyone Can go inside //true only logged in user can go inside //false logged in user can't go inside function App() { return ( <Suspense fallback={(<div>Loading...</div>)}> <NavBar /> <div style={{ paddingTop: '69px', minHeight: 'calc(100vh - 80px)' }}> <Switch> <Route exact path="/" component={Auth(LandingPage, null)} /> <Route exact path="/login" component={Auth(LoginPage, false)} /> <Route exact path="/register" component={Auth(RegisterPage, false)} /> <Route exact path="/movie/:movieId" component={Auth(MovieDetail, null)} /> <Route exact path="/favorite" component={Auth(FavoritePage, true)} /> </Switch> </div> <Footer /> </Suspense> ); } export default App;
그다음 navbar에 favorite 메뉴를 추가해준다.
navbar->sections->leftmenu.js를 수정한다.
import React from 'react'; import { Menu } from 'antd'; const SubMenu = Menu.SubMenu; const MenuItemGroup = Menu.ItemGroup; function LeftMenu(props) { return ( <Menu mode={props.mode}> <Menu.Item key="mail"> <a href="/">Home</a> </Menu.Item> <Menu.Item key="favorite"> <a href="/favorite">Favorite</a> </Menu.Item> </Menu> ) } export default LeftMenu
favoritePage.js 파일은 다음과 같이 수정해서 전체적인 구조를 만들어 준다.
import React from 'react' function FavoritePage() { return ( <div style={{width:'85%', margin:'3rem auto'}}> <h2>Favorite Movies</h2> <hr /> <table> <thead> <tr> <th>Movie Title</th> <th>Movie RunTime</th> <td>Remove from favorites</td> </tr> </thead> <tbody> </tbody> </table> </div> ) } export default FavoritePage
그다음 favoritePage 폴더에 favorite.css 파일을 추가해서 디자인해준다.
table{ font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; } td,th { border: 1px solid #dddddd; text-align: left; padding: 8px; } tr:nth-child(even) { background-color: #dddddd; }
css파일을 favoritePage.js에 import 해준다.
import './favorite.css';
다음엔 mongoDB에서 영화정보를 가져오자.
favoritePage.js파일에 다음과 같은 코드를 추가한다.
function FavoritePage() { useEffect(() => { Axios.post('api/favorite/getFavoritedMovie',{userFrom:localStorage.getItem('userId')})//내가 누구인지를 백엔드에 같이 보내줘서 정보 가져오도록 한다. .then(response =>{ if(response.data.success){ }else{ alert('영화 정보를 가져오는데 실패했습니다. ') } }) }, [])
다음으로 route폴더의 favorite.js 파일로 가서 정보를 가져와서 프론트에 보내는 코드를 추가한다.
//좋아하는 영화정보 가져오기 router.post('/getFavoritedMovie', (req, res) =>{ Favorite.find({'userFrom':req.body.userFrom}) .exec((err, favorites)=>{ if(err)return res.status(400).send(err) return res.status(200).json({success:true, favorites})//좋아하는 영화들의 형식이 배열 형태로 있을 것이다. }) })
다음으로 가져온 데이터를 화면에 출력해보자.
useState구문을 추가한다.
import Axios from 'axios'; import React,{useEffect, useState} from 'react' import './favorite.css'; function FavoritePage() { const [Favorites, setFavorites] = useState([]) useEffect(() => { Axios.post('api/favorite/getFavoritedMovie',{userFrom:localStorage.getItem('userId')})//내가 누구인지를 백엔드에 같이 보내줘서 정보 가져오도록 한다. .then(response =>{ if(response.data.success){ setFavorites(response.data.favorites) }else{ alert('영화 정보를 가져오는데 실패했습니다. ') } }) }, []) return ( <div style={{width:'85%', margin:'3rem auto'}}> <h2>Favorite Movies</h2> <hr /> <table> <thead> <tr> <th>Movie Title</th> <th>Movie RunTime</th> <td>Remove from favorites</td> </tr> </thead> <tbody> {favorites.map((favorite,index)=>( <tr key = {index}> <td>{favorite.movieTitle}</td> <td>{favorite.movieRunTime}</td> <td><button>Remove</button></td> </tr> ))} </tbody> </table> </div> ) } export default FavoritePage
그 다음은 ant 디자인을 적용해서 영화 이름에 마우스를 가져다 대면 사진이 뜨도록 해보자.
Popover를 사용한다.
import Axios from 'axios'; import React,{useEffect, useState} from 'react' import './favorite.css'; import {Popover} from 'antd'; import {IMAGE_BASE_URL} from '../../Config' //..생략 const renderCards = Favorites.map((favorite,index)=>{ //이미지가 있을 때는 마우스 가져다 대면 사진이 뜨도록 해보자. const content = ( <div> {favorite.moviePost ? <img src = {`${IMAGE_BASE_URL}w500${favorite.movie.Post}`}/> : "no image"} </div> ) return <tr key = {index}> <Popover content={content} title={`${favorite.movieTitle}`}> <td>{favorite.movieTitle}</td> <td>{favorite.movieRunTime}</td> <td><button>Remove</button></td> </Popover> </tr> }) return ( <div style={{width:'85%', margin:'3rem auto'}}> <h2>Favorite Movies</h2> <hr /> <table> <thead> <tr> <th>Movie Title</th> <th>Movie RunTime</th> <td>Remove from favorites</td> </tr> </thead> <tbody> {renderCards} </tbody> </table> </div> ) } export default FavoritePage
그다음은 remove버튼을 활성화 해보자.
이번에는 이전의 버튼과 달리 파라미터가 있는 함수를 실행할 것이다. (onClick={()=>함수명(파라미터)}의 형식)
import Axios from 'axios'; import React,{useEffect, useState} from 'react' import './favorite.css'; import {Popover} from 'antd'; import {IMAGE_BASE_URL} from '../../Config' import { response } from 'express'; function FavoritePage() { const [Favorites, setFavorites] = useState([]) useEffect(() => { Axios.post('api/favorite/getFavoritedMovie',{userFrom:localStorage.getItem('userId')})//내가 누구인지를 백엔드에 같이 보내줘서 정보 가져오도록 한다. .then(response =>{ if(response.data.success){ setFavorites(response.data.favorites) }else{ alert('영화 정보를 가져오는데 실패했습니다. ') } }) }, []) const onClickDelete = (movieId, userFrom) =>{ const variables = { movieId, userFrom } Axios.post('/api/favorite/removeFroemFavorite', variables) .then(response=>{ if(response.data.success){ } else{ alert('리스트에서 지우는데 실패했습니다.') } }) } const renderCards = Favorites.map((favorite,index)=>{ //이미지가 있을 때는 마우스 가져다 대면 사진이 뜨도록 해보자. const content = ( <div> {favorite.moviePost ? <img src = {`${IMAGE_BASE_URL}w500${favorite.movie.Post}`}/> : "no image"} </div> ) return <tr key = {index}> <Popover content={content} title={`${favorite.movieTitle}`}> <td>{favorite.movieTitle}</td> <td>{favorite.movieRunTime}</td> <td><button onClick={()=>onClickDelete(favorite.movieId, favorite.userFrom)}>Remove</button></td> </Popover> </tr> }) return ( <div style={{width:'85%', margin:'3rem auto'}}> <h2>Favorite Movies</h2> <hr /> <table> <thead> <tr> <th>Movie Title</th> <th>Movie RunTime</th> <td>Remove from favorites</td> </tr> </thead> <tbody> {renderCards} </tbody> </table> </div> ) } export default FavoritePage
서버 쪽으로 넘어가서 실행해보자. route의 favorite.js에 다음과 같은 내용을 추가해준다.
router.post('/removeFromFavorite', (req, res) =>{ Favorite.findOneAndDelete({movieId: req.body.movieId, userFrom: req.body.userFrom}) .exec((err, result)=>{ if(err)return res.status(400).send(err) return res.status(200).json({success:true}) }) })
다시 프론트에서 결과를 보여주기 위해서는 1. 리프레시 해서 새로운 목록을 받아오는 방법과 2, 하나를 뺀 결과값을 출력하는 것이 있는데
우리는 리프레시 해서 새롭게 보여주는 방식을 사용한다.
영화 목록을 요청하는 것은 중복되므로 fetchFavoritedMovie라는 함수로 따로 빼서 재활용 한다.
결과적으로 favoritePage.js는 다음과 같다.
import Axios from 'axios'; import React,{useEffect, useState} from 'react' import './favorite.css'; import {Popover} from 'antd'; import {IMAGE_BASE_URL} from '../../Config' import { response } from 'express'; function FavoritePage() { const [Favorites, setFavorites] = useState([]) useEffect(() => { fetchFavoritedMovie() }, []) const fetchFavoritedMovie = ()=>{ Axios.post('api/favorite/getFavoritedMovie',{userFrom:localStorage.getItem('userId')})//내가 누구인지를 백엔드에 같이 보내줘서 정보 가져오도록 한다. .then(response =>{ if(response.data.success){ setFavorites(response.data.favorites) }else{ alert('영화 정보를 가져오는데 실패했습니다. ') } }) } const onClickDelete = (movieId, userFrom) =>{ const variables = { movieId, userFrom } Axios.post('/api/favorite/removeFroemFavorite', variables) .then(response=>{ if(response.data.success){ fetchFavoritedMovie() } else{ alert('리스트에서 지우는데 실패했습니다.') } }) } const renderCards = Favorites.map((favorite,index)=>{ //이미지가 있을 때는 마우스 가져다 대면 사진이 뜨도록 해보자. const content = ( <div> {favorite.moviePost ? <img src = {`${IMAGE_BASE_URL}w500${favorite.movie.Post}`}/> : "no image"} </div> ) return <tr key = {index}> <Popover content={content} title={`${favorite.movieTitle}`}> <td>{favorite.movieTitle}</td> <td>{favorite.movieRunTime}</td> <td><button onClick={()=>onClickDelete(favorite.movieId, favorite.userFrom)}>Remove</button></td> </Popover> </tr> }) return ( <div style={{width:'85%', margin:'3rem auto'}}> <h2>Favorite Movies</h2> <hr /> <table> <thead> <tr> <th>Movie Title</th> <th>Movie RunTime</th> <td>Remove from favorites</td> </tr> </thead> <tbody> {renderCards} </tbody> </table> </div> ) } export default FavoritePage
사진으로 보면,
리무브 버튼을 누르면, 다음과 같이 목록이 사라지는 것을 볼 수 있다. 이로하여 무비 앱 만들기는 완료!
'NODE.JS' 카테고리의 다른 글
MERN 기본파일 만들기 - 1) node, express 실행하고 mongodb연결하기, BodyParser & Postman 이용해서 register생성 (0) 2021.05.10 Youtube 만들기) 1.BoilerPlate설치하고 MongoDB 연결하기 (0) 2021.04.28 MovieApp 만들기) 4.Favorite Button 만들기 (0) 2021.04.27 MovieApp 만들기) 3.Movie Detail 만들기 (0) 2021.04.27 MovieApp 만들기) 2.Landing Page 만들기 (0) 2021.04.26