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

kakaomap

parent cb6ad5d9
import { useState, useEffect } from "react"
import movieApi from '../../apis/movie.api.js'
import "./box-office.module.css"
const BoxOffice = () => {
const [TMDB_TopRated_Data, setTMDB_TopRated_Data] = useState()
const [TMDB_TopRated_Data, setTMDB_TopRated_Data] = useState([])
useEffect(() => {
// getTMDB_TopRated()
let items = document.querySelectorAll('.carousel .carousel-item')
// console.log("item", items)
items.forEach((el) => {
const minPerSlide = 4
let next = el.nextElementSibling
for (let i = 1; i < minPerSlide; i++) {
if (!next) {
// wrap carousel by using first child
next = items[0]
}
let cloneChild = next.cloneNode(true)
el.appendChild(cloneChild.children[0])
next = next.nextElementSibling
}
})
getTMDB_TopRated()
}, [])
async function getTMDB_TopRated() {
const category = "popular"
try {
const data = await movieApi.getMoviesfromTM(category)
const data = await movieApi.getListByCategoryfromDB(category)
console.log(data)
setTMDB_TopRated_Data(data)
setTMDB_TopRated_Data([...data])
} catch (error) {
console.log(error)
}
......@@ -36,109 +20,33 @@ const BoxOffice = () => {
return (
<div className="container text-center my-3">
<div className="container text-center my-3">
<h2 className="font-weight-light">Bootstrap Multi Slide Carousel</h2>
<div className="row mx-auto my-auto justify-content-center">
<div id="recipeCarousel" className="carousel slide" data-bs-ride="carousel">
<div className="carousel-inner" role="listbox">
<div className="carousel-item active">
<div className="col-md-3">
<div className="card">
<div className="card-img">
<img src="//via.placeholder.com/500x400/31f?text=1" className="img-fluid" />
</div>
<div className="card-img-overlay">Slide 1</div>
</div>
</div>
</div>
<div className="carousel-item">
<div className="col-md-3">
<div className="card">
<div className="card-img">
<img src="//via.placeholder.com/500x400/e66?text=2" className="img-fluid" />
</div>
<div className="card-img-overlay">Slide 2</div>
</div>
</div>
</div>
<div className="carousel-item">
<div className="col-md-3">
<div className="card">
<div className="card-img">
<img src="//via.placeholder.com/500x400/7d2?text=3" className="img-fluid" />
</div>
<div className="card-img-overlay">Slide 3</div>
</div>
</div>
</div>
<div className="carousel-item">
<div className="col-md-3">
<div className="card">
<div className="card-img">
<img src="//via.placeholder.com/500x400?text=4" className="img-fluid" />
</div>
<div className="card-img-overlay">Slide 4</div>
</div>
</div>
</div>
<div className="carousel-item">
<div className="col-md-3">
<div className="card">
<div className="card-img">
<img src="//via.placeholder.com/500x400/aba?text=5" className="img-fluid" />
</div>
<div className="card-img-overlay">Slide 5</div>
</div>
</div>
</div>
<div className="carousel-item">
<div className="col-md-3">
<div className="card">
<div className="card-img">
<img src="//via.placeholder.com/500x400/fc0?text=6" className="img-fluid" />
</div>
<div className="card-img-overlay">Slide 6</div>
</div>
</div>
{/* <div id="carouselExampleControls" className="carousel slide" data-bs-ride="carousel">
<div className="carousel-inner">
{TMDB_TopRated_Data.length>0
?
TMDB_TopRated_Data.map((movie, index) => {
<div className={`carousel-item ${index === 0 ? "active" : ""}`}>
{console.log(movie.poster_path)}
<img src={`https://image.tmdb.org/t/p/original${movie.poster_path}`} className="d-block w-100" alt="Movie Poster"/>
</div>
})
:
<div className="carousel-item">
{console.log("스틸컷 불러오기 오류")}
<img src="/images/none.jpg" className="d-block w-100" alt="등록된 스틸컷이 없습니다." />
</div>
<a className="carousel-control-prev bg-transparent w-aut" href="#recipeCarousel" role="button" data-bs-slide="prev">
<span className="carousel-control-prev-icon" aria-hidden="true"></span>
</a>
<a className="carousel-control-next bg-transparent w-aut" href="#recipeCarousel" role="button" data-bs-slide="next">
<span className="carousel-control-next-icon" aria-hidden="true"></span>
</a>
</div>
</div>
<h5 className="mt-2 fw-light">advances one slide at a time</h5>
</div>
<div className="row my-auto justify-content-center">
<div id="recipeCarousel" className="carousel slide" data-bs-ride="carousel" data-bs-interval="999999999">
<div className={`carousel-inner`} role="listbox">
{TMDB_TopRated_Data ?
TMDB_TopRated_Data.map((moviePoster, index) => (
<div className={`carousel-item ${index === 0 ? "active" : ""}`}>
<div className="col-sm-3">
<div className="card">
<div className="card-img">
<img src={`https://image.tmdb.org/t/p/original${moviePoster.poster_path}`} className="img-fluid" />
</div>
</div>
</div>
</div>
))
: (<div>영화를 불러올 없습니다:(</div>)}
</div>
<a className="carousel-control-prev bg-transparent w-aut" href="#recipeCarousel" role="button"
data-bs-slide="prev">
<span className="carousel-control-prev-icon" aria-hidden="true"></span>
</a>
<a className="carousel-control-next bg-transparent w-aut" href="#recipeCarousel" role="button"
data-bs-slide="next">
<span className="carousel-control-next-icon" aria-hidden="true"></span>
</a>
}
</div>
</div>
<button className="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span className="carousel-control-prev-icon" aria-hidden="true"></span>
<span className="visually-hidden">Previous</span>
</button>
<button className="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span className="carousel-control-next-icon" aria-hidden="true"></span>
<span className="visually-hidden">Next</span>
</button>
</div> */}
</div>
)
}
......
@media (max-width: 767px) {
.carousel-inner .carousel-item > div {
display: none;
}
.carousel-inner .carousel-item > div:first-child {
display: block;
}
}
.carousel-inner .carousel-item.active,
.carousel-inner .carousel-item-next,
.carousel-inner .carousel-item-prev {
display: flex;
}
/* medium and up screens */
@media (min-width: 768px) {
.carousel-inner .carousel-item-end.active,
.carousel-inner .carousel-item-next {
transform: translateX(25%);
}
.carousel-inner .carousel-item-start.active,
.carousel-inner .carousel-item-prev {
transform: translateX(-25%);
}
}
.carousel-inner .carousel-item-end,
.carousel-inner .carousel-item-start {
transform: translateX(0);
}
@media (max-width: 767px) {
.carousel-inner .carousel-item > div {
display: none;
}
.carousel-inner .carousel-item > div:first-child {
display: block;
}
}
.carousel-inner .carousel-item.active,
.carousel-inner .carousel-item-next,
.carousel-inner .carousel-item-prev {
display: flex;
}
/* medium and up screens */
@media (min-width: 768px) {
.carousel-inner .carousel-item-end.active,
.carousel-inner .carousel-item-next {
transform: translateX(25%);
}
.carousel-inner .carousel-item-start.active,
.carousel-inner .carousel-item-prev {
transform: translateX(-25%);
}
}
.carousel-inner .carousel-item-end,
.carousel-inner .carousel-item-start {
transform: translateX(0);
}
......@@ -26,7 +26,7 @@ const SearchResult = () => {
}
return (
<>
<div className="container">
{result.length !== 0 ? (
<>
<h3 className="text-white text-center my-5">'{title}' 관한 검색 결과입니다.</h3>
......@@ -36,7 +36,7 @@ const SearchResult = () => {
</>
) : <h3 className="text-white text-center my-5 vh-100" style={{ wordBreak: "keep-all" }}>'{title}' 관한 검색 결과가 존재하지 않습니다.</h3>
}
</>
</div>
)
}
......
import { useState, useEffect } from 'react'
import { useRef, useState, useEffect } from 'react'
import axios from "axios"
import catchErrors from "../utils/catchErrors"
// import InfoModal from "./InfoModal"
// const { kakao } = window;
const { kakao } = window;
const options = {
center: new kakao.maps.LatLng(37.365264512305174, 127.10676860117488),
level: 3
};
const TheaterInfo = () => {
// if (kakao) {
// console.log("kakao")
// const mapContainer = document.getElementById('map'), // 지도를 표시할 div
// mapOption = {
// center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
// level: 3 // 지도의 확대 레벨
// };
// // 지도를 생성합니다
// const map = new kakao.maps.Map(mapContainer, mapOption);
// // 주소-좌표 변환 객체를 생성합니다
// const geocoder = new kakao.maps.services.Geocoder();
// // 주소로 좌표를 검색합니다
// geocoder.addressSearch('제주특별자치도 제주시 첨단로 242', function (result, status) {
// // 정상적으로 검색이 완료됐으면
// if (status === kakao.maps.services.Status.OK) {
// const coords = new kakao.maps.LatLng(result[0].y, result[0].x);
// // 결과값으로 받은 위치를 마커로 표시합니다
// const marker = new kakao.maps.Marker({
// map: map,
// position: coords
// });
// // 인포윈도우로 장소에 대한 설명을 표시합니다
// const infowindow = new kakao.maps.InfoWindow({
// content: '<div style="width:150px;text-align:center;padding:6px 0;">우리회사</div>'
// });
// infowindow.open(map, marker);
// // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
// map.setCenter(coords);
// }
// });
// }
const [theaterInfo, setTheaterInfo] = useState()
const container = useRef(null)
const [cinemaInfo, setCinemaInfo] = useState()
const [currentInfo, setCurrentInfo] = useState({
name: "init",
title: "init",
......@@ -49,23 +22,48 @@ const TheaterInfo = () => {
}, [])
useEffect(() => {
if (currentInfo.title === "parking") {
setTabContent(<div>{currentInfo.information}</div>)
} else if (currentInfo.title === "address") {
setTabContent(<div id="map">{currentInfo.information}</div>)
} else {
setTabContent(<div>{currentInfo.information}</div>)
if (currentInfo.title === "address") {
// 지도를 담을 영역의 DOM 레퍼런스
const container = document.getElementById("map");
// center옵션은 지도를 생성하는데 반드시 필요하며 파라미터는 위경도좌표이다. (위도,경도 순서)
// level옵션은 지도의 확대, 축소 정도이다.
const options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 3,
};
// 지도 생성 및 객체 리턴
const map = new kakao.maps.Map(container, options);
const geocoder = new kakao.maps.services.Geocoder();
// 주소로 좌표를 검색합니다
geocoder.addressSearch(`${cinemaInfo.address}`, function (result, status) {
// 정상적으로 검색이 완료됐으면
if (status === kakao.maps.services.Status.OK) {
const coords = new kakao.maps.LatLng(result[0].y, result[0].x);
// 결과값으로 받은 위치를 마커로 표시합니다
const marker = new kakao.maps.Marker({
map: map,
position: coords
});
// 인포윈도우로 장소에 대한 설명을 표시합니다
const infowindow = new kakao.maps.InfoWindow({
content: '<div style="color:black; width:150px;text-align:center;padding:6px 0;">Butter Studio</div>'
});
infowindow.open(map, marker);
// 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
map.setCenter(coords);
}
});
}
}, [currentInfo])
}, [currentInfo]);
async function getTheaterInfo() {
try {
const response = await axios.get('/api/info/cinema')
const response2 = await axios.get('/api/theater')
setTheaterInfo({...response.data, theaterNum:response2.data.length})
setCinemaInfo({ ...response.data, theaterNum: response2.data.length })
setCurrentInfo({
name:"대중교통 안내",
title:"transportation",
name: "대중교통 안내",
title: "transportation",
information: response.data.transportation
})
} catch (error) {
......@@ -84,37 +82,39 @@ const TheaterInfo = () => {
return (
<>
{theaterInfo ?
{cinemaInfo ?
<div>
{/* {console.log(currentInfo)} */}
{console.log(theaterInfo)}
<h2 className="m-5">{theaterInfo.cinemaName}</h2>
{console.log(cinemaInfo)}
<h2 className="m-5">{cinemaInfo.cinemaName}</h2>
<div className="my-3 text-center">
<img src="/images/movieTheater.jpg" style={{ width: "80%" }} />
</div>
<div className="m-3"> 상영관 : {theaterInfo.theaterNum}</div>
<div className="m-3">{theaterInfo.address}</div>
<div className="m-3"> 상영관 : {cinemaInfo.theaterNum}</div>
<div className="m-3">{cinemaInfo.address}</div>
<div className="row justify-content-sm-center py-5">
<div className="col-sm-4 text-end">
<div className="m-2">
<img src="/images/icon-bus.png" style={{ width: "35px" }} />
<button className="px-3" name="대중교통 안내" id="transportation" value={theaterInfo.transportation} type="button" onClick={handleClick} style={{ background: "black", borderLeftColor: "black", borderTopColor: "black", borderBottomColor: "black", color: "white", borderRightColor: currentInfo.title === "transportation" ? "white" : "black" }}>대중교통 안내
<button className="px-3" name="대중교통 안내" id="transportation" value={cinemaInfo.transportation} type="button" onClick={handleClick} style={{ background: "black", borderLeftColor: "black", borderTopColor: "black", borderBottomColor: "black", color: "white", borderRightColor: currentInfo.title === "transportation" ? "white" : "black" }}>대중교통 안내
</button>
</div>
<div className="m-2">
<img src="/images/icon-car.png" style={{ width: "35px" }} />
<button className="px-3" name="자가용/주차 안내" id="parking" value={theaterInfo.parking} type="button" onClick={handleClick} style={{ background: "black", borderLeftColor: "black", borderTopColor: "black", borderBottomColor: "black", color: "white", borderRightColor: currentInfo.title === "parking" ? "white" : "black" }}>자가용/주차 안내
<button className="px-3" name="자가용/주차 안내" id="parking" value={cinemaInfo.parking} type="button" onClick={handleClick} style={{ background: "black", borderLeftColor: "black", borderTopColor: "black", borderBottomColor: "black", color: "white", borderRightColor: currentInfo.title === "parking" ? "white" : "black" }}>자가용/주차 안내
</button>
</div>
<div className="m-2">
<img src="/images/icon-map.png" style={{ width: "35px" }} />
<button className="px-3" name="지도보기" id="address" value={theaterInfo.address} type="button" onClick={handleClick} style={{ background: "black", borderLeftColor: "black", borderTopColor: "black", borderBottomColor: "black", color: "white", borderRightColor: currentInfo.title === "address" ? "white" : "black" }}>지도보기
<button className="px-3" name="지도보기" id="address" value={cinemaInfo.address} type="button" onClick={handleClick} style={{ background: "black", borderLeftColor: "black", borderTopColor: "black", borderBottomColor: "black", color: "white", borderRightColor: currentInfo.title === "address" ? "white" : "black" }}>지도보기
</button>
</div>
</div>
<div className="col-sm-6">
<div className="m-2">
{tabContent}
<div id="parking" style={{ display: currentInfo.title === "parking" ? 'block' : 'none' }}>{currentInfo.information}</div>
<div id="map" ref={container} style={{ width: "400px", height: "300px", display: currentInfo.title === "address" ? 'block' : 'none' }}></div>
<div id="transportaion" style={{ display: currentInfo.title === "transportation" ? 'block' : 'none' }} >{currentInfo.information}</div>
</div>
</div>
</div>
......
......@@ -78,7 +78,7 @@ const MoviePage = ({ location }) => {
</div>
<div className="col-sm-6 " style={{ color: "white" }}>
<h1 className="pb-3">{movieInfo.title}</h1>
<p>예매율: 0% 누적관객수: {movieInfo.attendance}</p>
<p>예매율:{Math.round((movieInfo.ticket_sales/movieInfo.totalReservationRate.totalReservationRate)*100)}% 누적관객수: {movieInfo.attendance}</p>
<p>감독: {movieInfo.director}</p>
<p>출연: {movieInfo.cast}</p>
<p>장르: {movieInfo.genres.reduce((acc, cur, idx) => {
......
......@@ -158,7 +158,14 @@ const findonlyTitle = async (req, res) => {
const elements = await Promise.all(
movieIds.map(async (movieId) => {
const movie = await axios.get(`https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.TMDB_APP_KEY}&language=ko-KR`)
return movie.data
const cols = await Movie.findOne({
where: { "movieId": movieId },
attributes: ["ticket_sales", "vote_average"]
})
const totalReservationRate = await Movie.findAll({
attributes: [[sequelize.fn('SUM', sequelize.col('ticket_sales')), 'totalReservationRate']]
});
return { ...movie.data, ticket_sales: cols.ticket_sales, vote_average: cols.vote_average, totalReservationRate: totalReservationRate[0]}
})
)
return res.json({ count: movieIds.length, results: elements })
......
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