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

Merge branch 'kimpen'

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