Commit b606631f authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

0719 예매페이지

parent 5f60aebc
PG_DATABASE=butterDB
PG_USER=butter
PG_PASSWORD=butter
TMDB_APP_KEY=1477348488076cafd4dcf973a314957d
REACT_APP_KAKAO_KEY=a04f2d1d1722f5fbadd556e742465d9f
...@@ -28,6 +28,7 @@ function App() { ...@@ -28,6 +28,7 @@ function App() {
<Route path="/movielist" component={MovieListPage} /> <Route path="/movielist" component={MovieListPage} />
<Route path="/movie/:movieId" component={MoviePage} /> <Route path="/movie/:movieId" component={MoviePage} />
<Route path="/ticket" component={TicketingPage} /> <Route path="/ticket" component={TicketingPage} />
<Route path="/theater" component={TheaterPage}/>
<Route path="/search" component={SearchPage} /> <Route path="/search" component={SearchPage} />
<Route path="/admin" component={AdminPage} /> <Route path="/admin" component={AdminPage} />
</Switch> </Switch>
......
...@@ -5,13 +5,18 @@ const getUpcomingfromTM = async () => { ...@@ -5,13 +5,18 @@ const getUpcomingfromTM = async () => {
const { data } = await axios.get(`${TMDBUrl}/upcoming?api_key=${process.env.REACT_APP_TMDB_API_KEY}&language=ko-KR`) const { data } = await axios.get(`${TMDBUrl}/upcoming?api_key=${process.env.REACT_APP_TMDB_API_KEY}&language=ko-KR`)
return data.results return data.results
} }
const getfromTM = async (cate) => { const getMoviesfromTM = async (cate) => {
const category = cate const category = cate
const response = await axios.get(`${baseUrl}/api/movie/showmovie/${category}`) const response = await axios.get(`${baseUrl}/api/movie/showmovies/${category}`)
console.log(response.data)
return response.data
}
const getMovieInfofromTM = async (id) => {
const movieId = id
const response = await axios.get(`${TMDBUrl}/${movieId}?api_key=${process.env.REACT_APP_TMDB_API_KEY}&language=ko-KR`)
console.log(response.data) console.log(response.data)
return response.data return response.data
} }
const submit = async (movieId) => { const submit = async (movieId) => {
const { data } = await axios.post(`${baseUrl}/api/movie/${movieId}`) const { data } = await axios.post(`${baseUrl}/api/movie/${movieId}`)
console.log("data==",data) console.log("data==",data)
...@@ -19,7 +24,8 @@ const submit = async (movieId) => { ...@@ -19,7 +24,8 @@ const submit = async (movieId) => {
const movieApi = { const movieApi = {
getUpcomingfromTM, getUpcomingfromTM,
getfromTM, getMoviesfromTM,
getMovieInfofromTM,
submit submit
} }
......
...@@ -4,17 +4,17 @@ import { Link } from 'react-router-dom'; ...@@ -4,17 +4,17 @@ import { Link } from 'react-router-dom';
import styles from "./movieChart.module.scss" import styles from "./movieChart.module.scss"
const MovieChart = () => { const MovieChart = () => {
const [TMDB_TopRated_Data, setTMDB_TopRated_Data] = useState() const [TMDB_TopRated_Data, setTMDB_TopRated_Data] = useState([])
const category="popular"
useEffect(() => { useEffect(() => {
getTMDB_TopRated() getTMDB_TopRated()
}, []) }, [])
async function getTMDB_TopRated() { async function getTMDB_TopRated() {
const category="popular"
try { try {
const data = await movieApi.getfromTM(category) const data = await movieApi.getMoviesfromTM(category)
console.log(data) console.log(data)
setTMDB_TopRated_Data(data) setTMDB_TopRated_Data([...data])
} catch (error) { } catch (error) {
} }
...@@ -25,7 +25,7 @@ const MovieChart = () => { ...@@ -25,7 +25,7 @@ const MovieChart = () => {
{TMDB_TopRated_Data {TMDB_TopRated_Data
? ?
TMDB_TopRated_Data.map(movie => ( TMDB_TopRated_Data.map(movie => (
<div className="card h-100" style={{ backgroundColor: "black" }}> <div className="card h-100 " style={{ backgroundColor: "black" }}>
<Link to={{ <Link to={{
pathname: `/movie/${movie.id}`, pathname: `/movie/${movie.id}`,
state: {...movie} state: {...movie}
...@@ -34,14 +34,14 @@ const MovieChart = () => { ...@@ -34,14 +34,14 @@ const MovieChart = () => {
<div className={`${styles.description}`}>{movie.overview}</div> <div className={`${styles.description}`}>{movie.overview}</div>
</Link> </Link>
<div className="card-body text-light"> <div className="card-body text-light">
<marquee onmouseover="this.stop()" className={`h2 card-title text-center ${styles.title}`}>{movie.title}</marquee> <div onmouseover="this.stop()" className={`h2 card-title text-center ${styles.title} ${styles.txt}`}>{movie.title}</div>
<p className="card-text text-center">예매율: {movie.ticket_sales}0% | {movie.runtime}</p> <p className={`card-text text-center ${styles.txt}`}>예매율: {movie.ticket_sales}0% | {movie.runtime}</p>
<p className="card-text text-center"><small className="text-muted">{movie.release_date} 개봉</small></p> <p className="card-text text-center"><small className="text-muted">{movie.release_date} 개봉</small></p>
</div> </div>
<Link to={{ <Link to={{
pathname:`/ticket`, pathname:`/ticket`,
state: {movieId:movie.id} state: {movieId:movie.id,}
}}> }} className="text-center">
<button className="btn btn-warning">예매하기</button> <button className="btn btn-warning">예매하기</button>
</Link> </Link>
</div> </div>
......
.layer{ .layer{
position: relative; position: relative;
} }
// .poster{ .poster{
// opacity: 1; max-height: 20rem;
// &:hover{ object-fit: contain;
// opacity: 0.3; }
// }
// }
.description{ .description{
position: absolute; position: absolute;
top: 0%; top: 0%;
...@@ -28,6 +26,6 @@ ...@@ -28,6 +26,6 @@
opacity: 1; opacity: 1;
} }
} }
.title{ .txt{
font-size: 99%;
} }
\ No newline at end of file
import React,{useState, useEffect} from 'react' import { useState, useEffect } from 'react'
import axios from 'axios' import movieApi from '../../apis/movie.api.js'
import baseUrl from '../../utils/baseUrl'
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styles from "./movieComming.module.scss" import styles from "./movieComming.module.scss"
const MovieComming = () => { const MovieComming = () => {
const [TMDB_UpComming_Data, setTMDB_UpComming_Data] = useState() const [TMDB_TopRated_Data, setTMDB_TopRated_Data] = useState()
const category="upcoming"
useEffect(() => { useEffect(() => {
getTMDB_UpComming() getTMDB_TopRated()
}, []) }, [])
async function getTMDB_UpComming() { async function getTMDB_TopRated() {
try { try {
const response = await axios.get(`/api/movie/showmovie/upcomming`) const data = await movieApi.getfromTM(category)
console.log(response.data) console.log(data)
setTMDB_UpComming_Data([...response.data]) setTMDB_TopRated_Data(data)
} catch (error) { } catch (error) {
} }
} }
return ( return (
<div class="row row-cols-1 row-cols-md-4 g-4"> <div class="row row-cols-1 row-cols-md-4 g-4">
{TMDB_UpComming_Data {console.log(TMDB_TopRated_Data)}
{TMDB_TopRated_Data
? ?
TMDB_UpComming_Data.map(movie => ( TMDB_TopRated_Data.map(movie => (
<div className="card h-100" style={{ backgroundColor: "black" }}> <div className="card h-100" style={{ backgroundColor: "black" }}>
<Link to={{ <Link to={{
pathname: `/movie/${movie.id}`, pathname: `/movie/${movie.id}`,
state: { state: {...movie}
...movie
}
}} className={`${styles.layer}`} > }} className={`${styles.layer}`} >
<img src={`https://image.tmdb.org/t/p/original${movie.poster_path}`} className={`card-img-top rounded ${styles.poster}`} alt="Movie Poster" /> <img src={`https://image.tmdb.org/t/p/original${movie.poster_path}`} className={`card-img-top rounded ${styles.poster}`} alt="Movie Poster" />
<div className={`${styles.description}`}>{movie.overview}</div> <div className={`${styles.description}`}>{movie.overview}</div>
</Link> </Link>
<div className="card-body text-light"> <div className="card-body text-light">
<marquee onmouseover="this.stop()" className={`h2 card-title text-center ${styles.title}`}>{movie.title}</marquee> <marquee onmouseover="this.stop()" className={`h2 card-title text-center ${styles.title}`}>{movie.title}</marquee>
<p className="card-text text-center">{movie.runtime}</p> <p className="card-text text-center">예매율: {movie.ticket_sales}0% | {movie.runtime}</p>
<p className="card-text text-center"><small className="text-muted">{movie.release_date} 개봉</small></p> <p className="card-text text-center"><small className="text-muted">{movie.release_date} 개봉</small></p>
</div> </div>
<button className="btn btn-warning">예매하기</button> <Link to={{
pathname:`/ticket`,
state: {movieId:movie.id}
}}>
<button className="btn btn-warning">예매하기</button>
</Link>
</div> </div>
)) ))
: <div>영화정보를 로딩할 없습니다.</div> : <div>영화정보를 로딩할 없습니다.</div>
......
...@@ -11,10 +11,10 @@ const MainNav = () => { ...@@ -11,10 +11,10 @@ const MainNav = () => {
} }
return ( return (
<nav class="nav justify-content-evenly border border-start-0 border-end-0 border-white border-2 py-1"> <nav className="nav justify-content-evenly border border-start-0 border-end-0 border-white border-2 py-1">
<a class="nav-link text-white" href="/movielist">영화</a> <a className="nav-link text-white" href="/movielist">영화</a>
<a class="nav-link text-white" href="/ticket">빠른예매</a> <a className="nav-link text-white" href="/ticket">빠른예매</a>
<a class="nav-link text-white" href="#">극장</a> <a className="nav-link text-white" href="/theater">극장</a>
<Search type="home" search={search} setSearch={setSearch} handleClick={searchMovie} /> <Search type="home" search={search} setSearch={setSearch} handleClick={searchMovie} />
</nav> </nav>
) )
......
const SubNav = () => { const SubNav = () => {
return ( return (
<nav class="nav justify-content-end py-1"> <nav className="nav justify-content-end py-1">
<a class="nav-link text-white" href="/login">로그인</a> <a className="nav-link text-white" href="/login">로그인</a>
<a class="nav-link text-white" href="/signup">회원가입</a> <a className="nav-link text-white" href="/signup">회원가입</a>
</nav> </nav>
) )
} }
......
...@@ -4,7 +4,6 @@ import styles from "./ticketingMovie.module.scss" ...@@ -4,7 +4,6 @@ import styles from "./ticketingMovie.module.scss"
const TicketingMovie = (props) => { const TicketingMovie = (props) => {
const [movieList, setMovieList] = useState([]) const [movieList, setMovieList] = useState([])
const [state, setState] = useState(0)
useEffect(() => { useEffect(() => {
getMovieList() getMovieList()
...@@ -13,27 +12,29 @@ const TicketingMovie = (props) => { ...@@ -13,27 +12,29 @@ const TicketingMovie = (props) => {
async function getMovieList() { async function getMovieList() {
try { try {
const response = await axios.get(`/api/movie/movielist`) const response = await axios.get(`/api/movie/movielist`)
console.log(response.data)
setMovieList(response.data) setMovieList(response.data)
} catch (error) { } catch (error) {
} }
} }
function handleClick(event) {
console.log(event.target.name)
props.setTicketInfo({ movieId: event.target.name })
}
return ( return (
<div className={``} > <div >
<ul className="d-grid gap-2"> {console.log(props.ticketInfo.movieId)}
<div className="d-grid gap-2">
{movieList.length > 0 {movieList.length > 0
? movieList.map(movie => ( ? movieList.map(movie => (
<li> <button name={movie.id} className={`${props.ticketInfo.movieId == movie.id ? styles.on : styles.btn}`} onClick={handleClick}>
<button className={`${styles.btn}`} onClick={() => { props.setMovieInfo({ movieId: movie.id }) }}> {movie.title}
{movie.title} </button>
</button>
</li>
)) ))
: <div>영화정보를 불러올 없습니다.</div>} : <div>영화정보를 불러올 없습니다.</div>}
</ul> </div>
</div> </div>
) )
} }
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
background:black; background:black;
color:white; color:white;
border:0; border:0;
&:focus{
background: white;
color: black;
}
} }
.on {
background: white;
color: black;
border:0;
}
\ No newline at end of file
import styles from "./ticketingTheater.module.scss" import styles from "./ticketingTheater.module.scss"
const TicketingTheater = (props) => { const TicketingTheater = (props) => {
function handleClick(event) {
// event.preventDefault()
console.log(event.target.name)
props.setTicketInfo({ ...props.ticketInfo, theater:event.target.name})
}
return ( return (
<div className={``} > <div >
<div className="d-grid gap-2"> <div className="d-grid gap-2">
{props.theaterInfo.cinemaNum.length > 0 {props.theaterInfo.theater.length > 0
? props.theaterInfo.cinemaNum.map(num => ( ? props.theaterInfo.theater.map(name => (
<button className={`${styles.btn}`} onClick={()=>props.setTheaterInfo({...props.theaterInfo,selectedCinemaNum:num})}>{num}</button> <button name={name} className={`${props.ticketInfo.theater === name ? styles.on : styles.btn}`} onClick={handleClick}>{name}</button>
)) ))
: <div>영화정보를 불러올 습니다.</div>} : <div>영화 정보가 존재하지 습니다.</div>}
</div> </div>
</div> </div>
) )
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
background:black; background:black;
color:white; color:white;
border:0; border:0;
&:focus{ }
background: white; .on {
color: black; background: white;
} color: black;
border:0;
} }
\ No newline at end of file
const TicketingTimeTable = () => {
return (
<>
</>
)
}
export default TicketingTimeTable
\ No newline at end of file
const TicketingTimeTable = (props) => {
return (
<div>
<div className="text-center" style={{color:"white"}}>
{console.log(props.ticketInfo.movieId, props.ticketInfo.theater)}
{props.ticketInfo.movieId && props.ticketInfo.theater
? <div>{props.ticketInfo.movieId} {props.ticketInfo.theater}</div>
: <div>영화와 극장을 모두 선택해주세요.</div>}
</div>
</div>
)
}
export default TicketingTimeTable
\ No newline at end of file
import {useState} from 'react'
const TheaterPage = () => { const TheaterPage = () => {
const [state, setState] = useState(0)
return ( return (
<div> <div>
<div className="">
<ul className="nav nav-tabs justify-content-center my-4 border-0" id="myTab" role="tablist">
<li className="nav-item" role="presentation">
<button className="nav-link active mx-auto" style={{ color: "white", borderColor: "black", backgroundColor: "black", borderBottom: state === 0 ? "3px solid" : "none", borderBottomColor: state === 0 ? "#FEDC00" : "black" }} id="overview-tab" data-bs-toggle="tab" data-bs-target="#overview" type="button" role="tab" aria-controls="overview" aria-selected="true" onClick={() => setState(0)}>극장정보</button>
</li>
<li className="nav-item" role="presentation">
<button className="nav-link mx-auto" style={{ color: "white", borderColor: "black", backgroundColor: "black", borderBottom: state === 1 ? "3px solid" : "none", borderBottomColor: state === 1 ? "#FEDC00" : "black" }} id="stillcut-tab" data-bs-toggle="tab" data-bs-target="#stillcut" type="button" role="tab" aria-controls="stillcut" aria-selected="false" onClick={() => setState(1)}>상영시간표</button>
</li>
<li className="nav-item" role="presentation">
<button className="nav-link mx-auto" style={{ color: "white", borderColor: "black", backgroundColor: "black", borderBottom: state === 2 ? "3px solid" : "none", borderBottomColor: state === 2 ? "#FEDC00" : "black" }} id="review-tab" data-bs-toggle="tab" data-bs-target="#review" type="button" role="tab" aria-controls="review" aria-selected="false" onClick={() => setState(2)}>관람료</button>
</li>
</ul>
</div>
<div className="tab-content text-center" id="myTabContent" style={{ color: "white" }}>
<div className="tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab">
<div>극장정보</div>
</div>
<div className="tab-pane fade" id="stillcut" role="tabpanel" aria-labelledby="stillcut-tab">
<div>상영시간표</div>
</div>
<div className="tab-pane fade" id="review" role="tabpanel" aria-labelledby="review-tab">
<div>관람료</div>
</div>
</div>
</div> </div>
) )
} }
......
import { useState } from 'react' import { useState, useEffect } from 'react'
import TicketingMovie from "../components/TicketingMovie/TicketingMovie" import { Link } from 'react-router-dom'
import TicketingTheater from "../components/TicketingTheater/TicketingTheater" import movieApi from '../apis/movie.api.js'
import TicketingTimeTable from "../components/TicketingTimeTable" import TicketingMovie from "../components/TicketingMovie/TicketingMovie.js"
import TicketingTheater from "../components/TicketingTheater/TicketingTheater.js"
import TicketingTimeTable from "../components/TicketingTimeTable/TicketingTimeTable.js"
const TicketingPage = (location) => { const TicketingPage = ({ location }) => {
// const [movieInfo, setMovieInfo] = useState(location) const [ticketInfo, setTicketInfo] = useState({
const [movieInfo, setMovieInfo] = useState({ movieId: "497698" }) ...location.state,
theater:"",
selectedCinemaNum: 0,
time: {}
})
const [theaterInfo, setTheaterInfo] = useState({ const [theaterInfo, setTheaterInfo] = useState({
theater: "Butter 조치원", theater: ["Butter Studio 조치원"],
cinemaNum: [1, 2, 3, 4], cinemaNum: [1, 2, 3, 4]
selectedCinemaNum:0
}) })
const [movieInfo, setMovieInfo] = useState()
useEffect(() => {
getMovieInfo()
}, [ticketInfo])
async function getMovieInfo() {
try {
const data = await movieApi.getMovieInfofromTM(ticketInfo.movieId)
console.log(data)
setMovieInfo(data)
} catch (error) {
console.log(error)
}
}
return ( return (
<div className="container" style={{ backgroundColor: "black" }}> <div className="container" style={{ backgroundColor: "black" }}>
<div>
{console.log(location.state)}
</div>
<div className="row justify-content-center my-5"> <div className="row justify-content-center my-5">
<div className="col-sm-4"> <div className="col-sm-4 mb-4 ">
<h2 className="py-2 text-white text-center" style={{ border: "3px solid #FEDC00", borderBottom: "3px solid #FEDC00" }}>영화</h2> <h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>영화</h3>
<TicketingMovie movieInfo={movieInfo} setMovieInfo={setMovieInfo} /> <TicketingMovie ticketInfo={ticketInfo} setTicketInfo={setTicketInfo} />
</div> </div>
<div className="col-sm-4"> <div className="col-sm-3 mb-4 ">
<h2 className="py-2 text-white text-center" style={{ border: "3px solid #FEDC00", borderBottom: "3px solid #FEDC00" }}>극장</h2> <h3 className="py-2 mb-3 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>극장</h3>
<TicketingTheater theaterInfo={theaterInfo} setTheaterInfo={setTheaterInfo} /> <TicketingTheater theaterInfo={theaterInfo} ticketInfo={ticketInfo} setTicketInfo={setTicketInfo} />
</div> </div>
<div className="col-sm-4"> <div className="col-sm-5 mb-4 ">
<h2 className="py-2 text-white text-center" style={{ border: "3px solid #FEDC00", borderBottom: "3px solid #FEDC00" }}>시간표</h2> <h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>시간표</h3>
<TicketingTimeTable movieInfo={movieInfo} theaterInfo={theaterInfo} /> <TicketingTimeTable ticketInfo={ticketInfo} theaterInfo={theaterInfo} />
</div> </div>
</div> </div>
<div className="row p-3" style={{ backgroundColor: "#252525"}}>
<div className="col-sm-3 border-end text-center">
{movieInfo
? <img style={{ maxHeight: "10rem" }} src={`https://image.tmdb.org/t/p/original${movieInfo.poster_path}`} alt="영화포스터" />
: <div className="mb-2" style={{ color: "white" }}>영화선택</div>}
</div>
<div className="col-sm-6 border-end" style={{ color: "white" }}>
<div className="mb-2 text-center">극장선택</div>
{movieInfo && ticketInfo.theater
? <ul>
<li>영화: {movieInfo.title}</li>
<li>극장: {ticketInfo.theater}</li>
<li>일시: </li>
<li>상영관: </li>
</ul>
: <div></div>}
</div>
<div className="col-sm-3 text-center">
<div className="mb-2" style={{ color: "white" }}>좌석선택</div>
{movieInfo && ticketInfo.theater
?
<Link to={{
pathname: `/seat`,
state: {}
}}>
<img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" alt="예매하기" />
</Link>
:
<img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" alt="예매하기" />
}
</div>
</div>
</div> </div>
) )
} }
......
...@@ -7,7 +7,7 @@ router ...@@ -7,7 +7,7 @@ router
.route("/") .route("/")
// .post(movieCtrl.comparePopularMovie) // .post(movieCtrl.comparePopularMovie)
router.route('/showmovie/:category') router.route('/showmovies/:category')
.get(movieCtrl.getMovieById) .get(movieCtrl.getMovieById)
router.route('/movielist') router.route('/movielist')
...@@ -18,5 +18,4 @@ router ...@@ -18,5 +18,4 @@ router
.post(movieCtrl.create) .post(movieCtrl.create)
router.param('category', movieCtrl.getMovieByCategory) router.param('category', movieCtrl.getMovieByCategory)
export default router; export default router;
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment