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

Merge branch 'kimpen'

parents e5b75efa 19e3ba65
/node_modules
.env.development
.env.development.local
.env.local
\ No newline at end of file
.env.local
......@@ -13,6 +13,7 @@
# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
......
......@@ -6736,6 +6736,11 @@
"to-regex-range": "^5.0.1"
}
},
"filter-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
......@@ -10790,6 +10795,22 @@
"prepend-http": "^1.0.0",
"query-string": "^4.1.0",
"sort-keys": "^1.0.0"
},
"dependencies": {
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"requires": {
"object-assign": "^4.1.0",
"strict-uri-encode": "^1.0.0"
}
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
}
}
},
"npm-run-path": {
......@@ -12645,12 +12666,14 @@
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.1.tgz",
"integrity": "sha512-uIw3iRvHnk9to1blJCG3BTc+Ro56CBowJXKmNNAm3RulvPBzWLRqKSiiDk+IplJhsydwtuNMHi8UGQFcCLVfkA==",
"requires": {
"object-assign": "^4.1.0",
"strict-uri-encode": "^1.0.0"
"decode-uri-component": "^0.2.0",
"filter-obj": "^1.1.0",
"split-on-first": "^1.0.0",
"strict-uri-encode": "^2.0.0"
}
},
"querystring": {
......@@ -14441,6 +14464,11 @@
}
}
},
"split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
......@@ -14571,9 +14599,9 @@
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
},
"string-length": {
"version": "4.0.2",
......
......@@ -10,6 +10,7 @@
"bootstrap": "^5.0.2",
"bootstrap-icons": "^1.5.0",
"node-sass": "^6.0.1",
"query-string": "^7.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/images/Logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/images/Logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
......@@ -24,13 +22,14 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=process.env.REACT_APP_KAKAO_KEY&libraries=services"></script>
<title>Butter Studio</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=%REACT_APP_KAKAO_KEY%&libraries=services"></script>
<title>Butter Studio</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
......@@ -40,5 +39,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
</body>
</html>
\ No newline at end of file
......@@ -11,26 +11,28 @@ import TheaterPage from "./pages/TheaterPage";
import MyPage from "./pages/MyPage";
import AdminPage from "./pages/AdminPage/AdminPage";
import TicketingPage from "./pages/TicketingPage";
import SearchPage from "./pages/SearchPage";
function App() {
return (
<div className="" style={{ backgroundColor: "black" }}>
<SubNav />
<Header />
<MainNav />
<Router>
<Router style={{ backgroundColor: "black" }}>
<SubNav />
<Header />
<MainNav />
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/login" component={LoginPage} />
<Route path="/signup" component={SignupPage} />
<Route path="/movielist" component={MovieListPage} />
<Route path="/movie/:movieId" component={MoviePage}/>
<Route path="/ticket" component={TicketingPage}/>
<Route path="/admin" component={AdminPage}/>
<Route path="/movie/:movieId" component={MoviePage} />
<Route path="/ticket" component={TicketingPage} />
<Route path="/search" component={SearchPage} />
<Route path="/admin" component={AdminPage} />
</Switch>
</Router>
</div>
// </div>
);
}
......
import axios from "axios";
import { baseUrl, TMDBUrl } from "../utils/baseUrl";
const getUpcomingfromTM = async () => {
const { data } = await axios.get(`${TMDBUrl}/upcoming?api_key=${process.env.REACT_APP_TMDB_API_KEY}&language=ko-KR`)
return data.results
}
const submit = async (movieId) => {
const { data } = await axios.post(`${baseUrl}/api/movie/${movieId}`)
console.log("data==",data)
}
const movieApi = {
getUpcomingfromTM,
submit
}
export default movieApi
\ No newline at end of file
import { useState, useEffect } from "react";
import Search from "../Search";
import MovieTable from "../MovieTable";
import Pagination from "../Pagination";
import movieApi from "../../apis/movie.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";
const MovieEdit = () => {
const [search, setSearch] = useState({ kind: "", keyword: "" })
const [movieList, setMovieList] = useState([])
const [error, setError] = useState("")
useEffect(() => {
getMovieList()
}, [])
async function getMovieList() {
try {
setError("")
const getMovieList = await movieApi.getUpcomingfromTM()
setMovieList(getMovieList)
} catch (error) {
catchErrors(error, setError)
}
}
async function searchMovie() {
try {
setError("")
} catch (error) {
catchErrors(error, setError)
}
}
return (
<>
<div className="d-flex justify-content-end mb-3">
<Search type="admin" />
{console.log("search==",search)}
<div className="d-flex justify-content-md-end justify-content-center mb-3">
<Search type="admin" search={search} setSearch={setSearch} handleClick={searchMovie} />
</div>
<MovieTable />
<MovieTable movieList={movieList} />
<div className="d-flex flex-wrap">
<Pagination />
<div className="d-flex justify-content-end col-12 col-md-4 my-2">
......
@media screen and (max-width: 767px) {
@media screen and (max-width: 768px) {
.box {
margin-bottom: 100px;
......
import axios from "axios"
<<<<<<< HEAD
import baseUrl from '../../utils/baseUrl'
import React, { useState, useEffect } from "react"
import "./box-office.module.scss"
// import "./mystyle.css"
=======
import { baseUrl } from '../../utils/baseUrl'
import React, { useState, useEffect } from "react"
import styles from "./box-office.module.scss"
>>>>>>> kimpen
const BoxOffice = () => {
const [TMDB_TopRated_Data, setTMDB_TopRated_Data] = useState()
......
......@@ -106,6 +106,7 @@ const KakaoMap = ({ keyword, cinemaInfo, setCinemaInfo }) => {
i;
for (i = 1; i <= pagination.last; i++) {
// let el = <a>{i}</a>
let el = document.createElement('a');
// el.href = "#";
el.innerHTML = i;
......
import { useState } from "react";
import movieApi from "../../apis/movie.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./movie-table.module.scss";
const MovieTable = () => {
const MovieTable = ({ movieList }) => {
const [error, setError] = useState("")
async function handleClick(e, movieId) {
e.preventDefault();
try {
setError("");
await movieApi.submit(movieId)
alert("서버 등록이 완료되었습니다.")
} catch (error) {
catchErrors(error, setError)
}
}
return (
<table className={`table text-center ${styles.tableForm}`}>
<thead className={`table-dark ${styles.dNone}`}>
<tr>
<th>제목</th>
<th>감독</th>
<th>상영일</th>
<th>줄거리</th>
<th>포스터</th>
<th>스틸컷</th>
......@@ -14,28 +31,32 @@ const MovieTable = () => {
</tr>
</thead>
<tbody>
<tr className={styles.Row} data-bs-toggle="collapse" data-bs-target={"#movie1"}>
<td className="d-inline-block d-md-table-cell">블랙위도우</td>
<td data-label="- " className={`d-inline-block d-md-table-cell ${styles.data}`}>케이트 쇼트랜드</td>
<td className="d-none d-md-table-cell">O</td>
<td className="d-none d-md-table-cell">O</td>
<td className="d-none d-md-table-cell">X</td>
<td className="d-none d-md-table-cell">X</td>
</tr>
<tr className={styles.Row}>
<td colSpan="6" className="collapse" id={"movie1"}>
<div className={`d-inline-block d-md-none ${styles.word} mb-2`}>
줄거리 - O /
포스터 - O /
스틸컷 - X /
예고편 - X
</div>
<div className="d-flex justify-content-end">
<button type="button" className="btn btn-primary mx-2">수정</button>
<button type="button" className="btn btn-danger">삭제</button>
</div>
</td>
</tr>
{movieList?.map(movie =>
<>
<tr className={styles.Row} data-bs-toggle="collapse" data-bs-target={"#movie" + movie.id}>
<td className="d-inline-block d-md-table-cell">{movie.title}</td>
<td data-label="- " className={`d-inline-block d-md-table-cell ${styles.data}`}>케이트 쇼트랜드</td>
<td data-label="/ " className={`d-inline-block d-md-table-cell ${styles.data}`}>{movie.release_date}</td>
<td className="d-none d-md-table-cell">{movie.overview !== '' ? 'O' : 'X'}</td>
<td className="d-none d-md-table-cell">{movie.poster_path !== '' ? 'O' : 'X'}</td>
<td className="d-none d-md-table-cell">{movie.backdrop_path !== '' ? 'O' : 'X'}</td>
<td className="d-none d-md-table-cell">{movie.video !== false ? 'O' : 'X'}</td>
</tr>
<tr className={styles.Row}>
<td colSpan="7" className="collapse" id={"movie" + movie.id}>
<div className={`d-inline-block d-md-none ${styles.word} mb-2`}>
줄거리 - {movie.overview !== '' ? 'O' : 'X'} /
포스터 - {movie.poster_path !== '' ? 'O' : 'X'} /
스틸컷 - {movie.backdrop_path !== '' ? 'O' : 'X'} /
예고편 - {movie.video !== false ? 'O' : 'X'}
</div>
<div className="d-flex justify-content-end">
<button type="button" className="btn btn-primary" onClick={(e) => handleClick(e, movie.id)}>등록</button>
{/* <button type="button" className="btn btn-danger">삭제</button> */}
</div>
</td>
</tr>
</>)}
</tbody>
</table>
)
......
......@@ -6,7 +6,7 @@
word-break: keep-all;
}
@media screen and (max-width: 767px) {
@media screen and (max-width: 768px) {
.tableForm {
border-top: 2px solid;
......
import { useState } from "react";
import { useHistory } from "react-router";
import Search from "../Search";
const MainNav = () => {
const [search, setSearch] = useState({ keyword: "" })
const history = useHistory()
function searchMovie() {
history.push(`/search?title=${search.keyword}`)
}
return (
<nav class="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 class="nav-link text-white" href="/ticket">빠른예매</a>
<a class="nav-link text-white" href="#">극장</a>
<Search type="home" />
<Search type="home" search={search} setSearch={setSearch} handleClick={searchMovie} />
</nav>
)
}
......
import styles from "./search.module.scss";
const Search = ({ type }) => {
console.log("type==",type)
const Search = ({ type, search, setSearch, handleClick }) => {
function handleSearch(e) {
const { name, value } = e.target
setSearch({ ...search, [name]: value })
}
console.log("type==", type)
return (
<div className="d-flex">
<input className="form-control" type="text" id={type === "home" ? styles.searchWhite : styles.search} />
<i className={`bi bi-search align-self-center ${type === "home" ? "text-white" : "mx-2"} ${styles.icon}`} style={{ fontSize: "1.3rem" }}></i>
{type === "home" ? null :
<select className={`form-select ${styles.search}`} name="kind" aria-label="select search" onChange={handleSearch}>
<option selected value="title">제목</option>
<option value="director">감독명</option>
</select>
}
<input className={`form-control ${type === "home" ? styles.searchWhite : `${styles.search}`}`} name="keyword" type="text" onChange={handleSearch} />
<i className={`bi bi-search align-self-center ${type === "home" ? "text-white" : "mx-2"} ${styles.icon}`} onClick={handleClick} style={{ fontSize: "1.3rem" }}></i>
</div>
)
}
......
......@@ -2,7 +2,7 @@
cursor: pointer;
}
#searchWhite {
.searchWhite {
background: transparent;
border: none;
border-bottom: 2px solid #fff;
......@@ -21,8 +21,7 @@
}
}
#search {
background: transparent;
.search {
border: none;
border-bottom: 2px solid #000;
border-radius: 0;
......
import { useLocation } from 'react-router-dom';
import queryString from 'query-string';
import MovieChart from "./MovieChart/index.js";
const SearchResult = () => {
const { search } = useLocation()
const { title } = queryString.parse(search)
console.log("search==",search,"title==",title)
return (
<>
<h3 className="text-white text-center my-5">'{title}' 관한 검색 결과입니다.</h3>
<MovieChart />
</>
)
}
export default SearchResult
\ No newline at end of file
import SearchResult from "../components/SearchResult.js";
const SearchPage = () => {
return (
<SearchResult />
)
}
export default SearchPage
\ No newline at end of file
......@@ -41,17 +41,17 @@ $theme-colors: map-merge($theme-colors, $custom-colors);
font-style: normal;
}
// @media (max-width: 767px) {
// .carousel-inner .carousel-item > div {
// display: none;
// }
// .carousel-inner .carousel-item > div:first-child {
// display: block;
// }
// .table > :not(caption) > * > * {
// border-bottom-width: 0;
// }
// }
@media (max-width: 768px) {
// .carousel-inner .carousel-item > div {
// display: none;
// }
// .carousel-inner .carousel-item > div:first-child {
// display: block;
// }
.table > :not(caption) > * > * {
border-bottom-width: 0;
}
}
// /* medium and up screens */
// @media (min-width: 768px) {
......
......@@ -4,4 +4,6 @@ const baseUrl = process.env.NODE_ENV === 'production'
? `http://localhost:3001/${clientConfig.serverRoot}`
: `http://localhost:3000`
export default baseUrl
\ No newline at end of file
const TMDBUrl = "https://api.themoviedb.org/3/movie"
export { baseUrl, TMDBUrl }
\ 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