Commit 64d60802 authored by 한규민's avatar 한규민
Browse files

Merge branch 'master' into gyumin

parents dca77d17 44b5a715
...@@ -19,28 +19,32 @@ import Payment from "./pages/PaymentPage"; ...@@ -19,28 +19,32 @@ import Payment from "./pages/PaymentPage";
function App() { function App() {
return ( return (
<div className="" style={{ backgroundColor: "black" }}> <AuthProvider>
<AuthProvider> <Router>
<Router> <Switch>
<SubNav /> <Route path="/admin" component={AdminPage} />
<Header /> <div style={{ backgroundColor: "black" }}>
<MainNav /> <Router>
<Switch> <SubNav />
<Route exact path="/" component={HomePage} /> <Header />
<Route path="/login" component={LoginPage} /> <MainNav />
<Route path="/signup" component={SignupPage} /> <Switch>
<Route path="/movielist" component={MovieListPage} /> <Route exact path="/" component={HomePage} />
<Route path="/movie/:movieId" component={MoviePage} /> <Route path="/login" component={LoginPage} />
<Route path="/mypage" component={MyPage} /> <Route path="/signup" component={SignupPage} />
<Route path="/ticket/seat" component={TicketingSeatPage} /> <Route path="/movielist" component={MovieListPage} />
<Route path="/ticket" component={TicketingPage} /> <Route path="/movie/:movieId" component={MoviePage} />
<Route path="/payment" component={Payment} /> <Route path="/mypage" component={MyPage} />
<Route path="/search" component={SearchPage} /> <Route path="/ticket/seat" component={TicketingSeatPage} />
<Route path="/admin" component={AdminPage} /> <Route path="/ticket" component={TicketingPage} />
</Switch> <Route path="/payment" component={Payment} />
</Router> <Route path="/search" component={SearchPage} />
</AuthProvider> </Switch>
</div> </Router>
</div>
</Switch>
</Router>
</AuthProvider>
); );
} }
......
import axios from "axios";
import { baseUrl } from "../utils/baseUrl.js";
const getAll = async () => {
const { data } = await axios.get(`${baseUrl}/api/theater`)
return data
}
const getOne = async () => {
const { data } = await axios.get(`${baseUrl}/api/theater`)
return data
}
const getTheaterType = async () => {
const { data } = await axios.get(`${baseUrl}/api/theater/type`)
return data
}
const sendData = async (theater) => {
const { data } = await axios.put(`${baseUrl}/api/theater/type`, theater)
return data
}
const remove = async () => {
const { data } = await axios.delete(`${baseUrl}/api/theater`)
return data
}
const theaterApi = {
getAll,
getOne,
getTheaterType,
sendData,
remove
}
export default theaterApi
\ No newline at end of file
import { Link, Route, Switch, useRouteMatch } from "react-router-dom"; import { Link, Route, Switch, useRouteMatch } from "react-router-dom";
import MovieEdit from "./MovieEdit"; import MovieEdit from "./MovieEdit";
import TheaterEdit from "./TheaterEdit"; import TheaterEdit from "./TheaterEdit";
import TimeTableEdit from "./TimeTableEdit";
import CinemaEdit from "./CinemaEdit"; import CinemaEdit from "./CinemaEdit";
import styles from "./admin.module.scss"; import styles from "./admin.module.scss";
...@@ -16,6 +17,9 @@ const Admin = () => { ...@@ -16,6 +17,9 @@ const Admin = () => {
<li className="nav-item"> <li className="nav-item">
<Link to={`${match.url}/theater`} className="nav-link text-dark text-center">상영관 관리</Link> <Link to={`${match.url}/theater`} className="nav-link text-dark text-center">상영관 관리</Link>
</li> </li>
<li className="nav-item">
<Link to={`${match.url}/timetable`} className="nav-link text-dark text-center">상영시간표 관리</Link>
</li>
<li className="nav-item"> <li className="nav-item">
<Link to={`${match.url}/cinema`} className="nav-link text-dark text-center">영화관 관리</Link> <Link to={`${match.url}/cinema`} className="nav-link text-dark text-center">영화관 관리</Link>
</li> </li>
...@@ -24,6 +28,7 @@ const Admin = () => { ...@@ -24,6 +28,7 @@ const Admin = () => {
<Switch> <Switch>
<Route path={`${match.path}/movie`}><MovieEdit /></Route> <Route path={`${match.path}/movie`}><MovieEdit /></Route>
<Route path={`${match.path}/theater`}><TheaterEdit /></Route> <Route path={`${match.path}/theater`}><TheaterEdit /></Route>
<Route path={`${match.path}/timetable`}><TimeTableEdit /></Route>
<Route path={`${match.path}/cinema`}><CinemaEdit /></Route> <Route path={`${match.path}/cinema`}><CinemaEdit /></Route>
<Route path={`${match.path}`}><MovieEdit /></Route> <Route path={`${match.path}`}><MovieEdit /></Route>
</Switch> </Switch>
......
...@@ -53,19 +53,19 @@ const CinemaEdit = () => { ...@@ -53,19 +53,19 @@ const CinemaEdit = () => {
<> <>
<h2 className="border-bottom border-2 text-center pb-2 me-2">현재 영화관 정보</h2> <h2 className="border-bottom border-2 text-center pb-2 me-2">현재 영화관 정보</h2>
<div className="mb-3"> <div className="mb-3">
<label for="cinemaName" className="form-label">영화관 이름</label> <label htmlfor="cinemaName" className="form-label">영화관 이름</label>
<input type="text" className={`form-control mb-2 ${styles.shadowNone}`} id="cinemaName" name="cinemaName" value={cinemaInfo.cinemaName} onChange={handleChange} /> <input type="text" className={`form-control mb-2 ${styles.shadowNone}`} id="cinemaName" name="cinemaName" value={cinemaInfo.cinemaName} onChange={handleChange} />
<p> 상영관 : 8개관 | 좌석 : 1,282</p> <p> 상영관 : 8개관 | 좌석 : 1,282</p>
</div> </div>
<div className="mb-3"> <div className="mb-3">
<label for="transportation" className="form-label">대중교통 안내</label> <label htmlfor="transportation" className="form-label">대중교통 안내</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="transportation" name="transportation" value={cinemaInfo.transportation} onChange={handleChange}></textarea> <textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="transportation" name="transportation" value={cinemaInfo.transportation} onChange={handleChange}></textarea>
</div> </div>
<div className="mb-3"> <div className="mb-3">
<label for="parking" className="form-label">자가용/주차안내</label> <label htmlfor="parking" className="form-label">자가용/주차안내</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="parking" name="parking" value={cinemaInfo.parking} onChange={handleChange}></textarea> <textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="parking" name="parking" value={cinemaInfo.parking} onChange={handleChange}></textarea>
</div> </div>
<label for="keyword" className="form-label">지도보기</label> <label htmlfor="keyword" className="form-label">지도보기</label>
<div className="input-group mb-3"> <div className="input-group mb-3">
<span className="input-group-text" id="address"><i className="bi bi-geo-alt-fill"></i></span> <span className="input-group-text" id="address"><i className="bi bi-geo-alt-fill"></i></span>
<input type="text" className={`form-control ${styles.shadowNone}`} id="address" name="address" value={cinemaInfo.address} onChange={handleChange} value={cinemaInfo.address} /> <input type="text" className={`form-control ${styles.shadowNone}`} id="address" name="address" value={cinemaInfo.address} onChange={handleChange} value={cinemaInfo.address} />
...@@ -75,7 +75,7 @@ const CinemaEdit = () => { ...@@ -75,7 +75,7 @@ const CinemaEdit = () => {
<TicketEditForm editFee={ticketFee} formRef={formRef} /> <TicketEditForm editFee={ticketFee} formRef={formRef} />
<TicketFeeTable setEditFee={setTicketFee} formRef={formRef} /> <TicketFeeTable setEditFee={setTicketFee} formRef={formRef} />
<div className="mb-3"> <div className="mb-3">
<label for="moreFeeInfo" className="form-label">관람료 추가정보</label> <label htmlfor="moreFeeInfo" className="form-label">관람료 추가정보</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="moreFeeInfo" name="moreFeeInfo" value={cinemaInfo.moreFeeInfo} onChange={handleChange}></textarea> <textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="moreFeeInfo" name="moreFeeInfo" value={cinemaInfo.moreFeeInfo} onChange={handleChange}></textarea>
</div> </div>
<div className="d-grid gap-2 mb-5"> <div className="d-grid gap-2 mb-5">
......
import { useState, useRef } from "react";
import TheaterTable from "./TheaterTable";
import TheaterEditForm from "./TheaterEditForm";
const TheaterEdit = () => { const TheaterEdit = () => {
return ( const [edit, setEdit] = useState({})
<div> const formRef = useRef(null)
</div> return (
<>
<h2 className="border-bottom border-2 text-center pb-2 me-2">현재 상영관 정보</h2>
<TheaterTable setEdit={setEdit} formRef={formRef} />
<h5 className="mb-3">상영관 정보 설정</h5>
<TheaterEditForm edit={edit} formRef={formRef} />
</>
) )
} }
export default TheaterEdit export default TheaterEdit
\ No newline at end of file
import { useState, useEffect } from "react";
import theaterApi from "../../apis/theater.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";
const INIT_THEATER = {
theaterName: "",
theaterType: 0,
rows: 1,
columns: 1
}
const TheaterEditForm = ({ edit, formRef }) => {
const [theater, setTheater] = useState(INIT_THEATER)
const [types, setTypes] = useState([])
const [error, setError] = useState("")
useEffect(() => {
getTypeList()
}, [])
useEffect(() => {
setTheater({ ...theater, ...edit })
}, [edit])
async function getTypeList() {
try {
setError("")
const resTypes = await theaterApi.getTheaterType()
setTypes(resTypes)
} catch (error) {
catchErrors(error, setError)
}
}
function handleChange(e) {
const { name, value } = e.target
setTheater({ ...theater, [name]: value })
}
async function handleSubmit(e) {
e.preventDefault()
try {
setError("")
await theaterApi.sendData(theater)
alert("해당 상영관 정보 등록이 성공적으로 완료되었습니다.")
window.location.reload()
} catch (error) {
catchErrors(error, setError)
}
}
return (
<form ref={formRef} onSubmit={handleSubmit}>
<div className="d-flex justify-content-lg-between row row-cols-2 row-cols-lg-4 gx-0 gy-2 gy-lg-0 mb-2 mb-lg-3">
<label htmlfor="theaterName" className="col-3 col-lg-auto col-form-label">상영관 이름</label>
<div className="col-9 col-lg-4">
<input className={`form-control ${styles.shadowNone}`} id="theaterName" name="theaterName" type="text" value={theater.theaterName} onChange={handleChange} />
</div>
<label htmlfor="theaterType" className="col-3 col-lg-auto col-form-label text-lg-center">상영관 종류</label>
<div className="col-9 col-lg-5">
<select className={`form-select ${styles.shadowNone} ${styles.selectInput}`} id="theaterType" name="theaterType" onChange={handleChange} aria-label="select theaterType" defaultValue={theater.theaterType}>
{types.length !== 0 ?
types.map((type, index) => {
if (index === 0) return <>
<option value="0" disabled>상영관 종류를 선택해주십시오.</option>
<option value={type.id}>{type.theaterType}</option>
</>
else return <option value={type.id}>{type.theaterType}</option>
})
: <option value="0" disabled>서버에 등록된 상영관 종류가 없습니다.</option>}
</select>
</div>
</div>
<div className="d-flex flex-wrap row row-cols-2 gx-0 gy-2 gy-lg-0">
<label htmlfor="seatInfo" className="col-3 col-lg-auto col-form-label me-lg-4">좌석 정보</label>
<div className="d-flex col-9 col-sm-5">
<div className="col-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} id="rows" name="rows" type="number" min="1" max="26" value={theater.rows} onChange={handleChange} />
</div>
<label htmlfor="rows" className="col-form-label mx-2"></label>
<div className="col-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} id="columns" name="columns" type="number" min="1" value={theater.columns} onChange={handleChange} />
</div>
<label htmlfor="columns" className="col-form-label mx-2"></label>
</div>
<div className="col-12 col-sm-auto ms-sm-auto">
<button type="submit" className={`btn btn-dark w-100 ${styles.customBtn}`}>추가</button>
</div>
</div>
</form>
)
}
export default TheaterEditForm
\ No newline at end of file
import { useState, useEffect } from "react";
import theaterApi from "../../apis/theater.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";
const TheaterTable = ({ setEdit, formRef }) => {
const [theaterList, setTheaterList] = useState([])
const [error, setError] = useState("")
useEffect(() => {
getTheaterList()
}, [])
async function getTheaterList() {
try {
setError("")
const list = await theaterApi.getAll()
setTheaterList(list)
} catch (error) {
catchErrors(error, setError)
}
}
async function editTheater() {
try {
setError("")
const res = await theaterApi.getOne()
setEdit({ ...res })
formRef?.current.scrollIntoView({ behavior: "smooth", block: "center" })
} catch (error) {
catchErrors(error, setError)
}
}
async function deleteTheater() {
try {
setError("")
await theaterApi.remove()
alert("해당 상영관 정보를 성공적으로 삭제했습니다.")
getTheaterList()
} catch (error) {
catchErrors(error, setError)
}
}
return (
<table className={`table text-center align-middle ${styles.tableForm}`}>
<thead className={`table-dark align-middle ${styles.dNone}`}>
<tr>
<th>상영관 이름</th>
<th>상영관 종류</th>
<th>좌석 정보</th>
<th></th>
</tr>
</thead>
<tbody>
{theaterList.length !== 0 ? theaterList.map(info =>
<tr>
<td>ads</td>
<td>ads</td>
<td>ads</td>
<td>
<div className="d-flex flex-column">
<button type="button" className="btn btn-primary my-1" onClick={() => editTheater()}>수정</button>
<button type="button" className="btn btn-danger my-1" onClick={() => deleteTheater()}>삭제</button>
</div>
</td>
</tr>)
: <tr>
<td colSpan="4">등록된 상영관 정보가 없습니다.</td>
</tr>}
</tbody>
</table>
)
}
export default TheaterTable
\ No newline at end of file
...@@ -44,49 +44,49 @@ const TicketEditForm = ({ editFee, formRef }) => { ...@@ -44,49 +44,49 @@ const TicketEditForm = ({ editFee, formRef }) => {
return ( return (
<form ref={formRef} onSubmit={handleSubmit}> <form ref={formRef} onSubmit={handleSubmit}>
<div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0"> <div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="theaterType" className="col-md-auto col-form-label text-center text-md-start">상영관 종류</label> <label htmlfor="theaterType" className="col-md-auto col-form-label text-center text-md-start">상영관 종류</label>
<div className="col-md-4 col-lg-3 mx-md-2"> <div className="col-md-4 col-lg-3 mx-md-2">
<input className={`form-control ${styles.shadowNone}`} type="text" id="theaterType" name="theaterType" value={ticketFee.theaterType} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="text" id="theaterType" name="theaterType" value={ticketFee.theaterType} onChange={handleChange} />
</div> </div>
<label for="defaultPrice" className="col-md-auto col-form-label text-center text-md-start">기본 가격</label> <label htmlfor="defaultPrice" className="col-md-auto col-form-label text-center text-md-start">기본 가격</label>
<div className="col-md-3 col-lg-2 mx-md-2"> <div className="col-md-3 col-lg-2 mx-md-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="defaultPrice" name="defaultPrice" value={ticketFee.defaultPrice} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="defaultPrice" name="defaultPrice" value={ticketFee.defaultPrice} onChange={handleChange} />
</div> </div>
</div> </div>
<div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0"> <div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="weekdays" className="col-md-1 col-form-label text-center text-md-start">주중</label> <label htmlfor="weekdays" className="col-md-1 col-form-label text-center text-md-start">주중</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="weekdays" name="weekdays" value={ticketFee.weekdays} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="weekdays" name="weekdays" value={ticketFee.weekdays} onChange={handleChange} />
</div> </div>
<label for="weekend" className="col-md-1 col-form-label text-center">주말</label> <label htmlfor="weekend" className="col-md-1 col-form-label text-center">주말</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="weekend" name="weekend" value={ticketFee.weekend} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="weekend" name="weekend" value={ticketFee.weekend} onChange={handleChange} />
</div> </div>
</div> </div>
<div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0"> <div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="morning" className="col-md-1 col-form-label text-center text-md-start">조조</label> <label htmlfor="morning" className="col-md-1 col-form-label text-center text-md-start">조조</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="morning" name="morning" value={ticketFee.morning} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="morning" name="morning" value={ticketFee.morning} onChange={handleChange} />
</div> </div>
<label for="day" className="col-md-1 col-form-label text-center">일반</label> <label htmlfor="day" className="col-md-1 col-form-label text-center">일반</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="day" name="day" value={ticketFee.day} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="day" name="day" value={ticketFee.day} onChange={handleChange} />
</div> </div>
<label for="night" className="col-md-1 col-form-label text-center">심야</label> <label htmlfor="night" className="col-md-1 col-form-label text-center">심야</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="night" name="night" value={ticketFee.night} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="night" name="night" value={ticketFee.night} onChange={handleChange} />
</div> </div>
</div> </div>
<div className="d-flex row row-cols-2 flex-wrap flex-lg-nowrap mb-2 mb-md-3 gx-0 gy-2 gy-md-0"> <div className="d-flex row row-cols-2 flex-wrap flex-lg-nowrap mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="youth" className="col-md-1 col-form-label text-center text-md-start">청소년</label> <label htmlfor="youth" className="col-md-1 col-form-label text-center text-md-start">청소년</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="youth" name="youth" value={ticketFee.youth} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="youth" name="youth" value={ticketFee.youth} onChange={handleChange} />
</div> </div>
<label for="adult" className="col-md-1 col-form-label text-center">일반</label> <label htmlfor="adult" className="col-md-1 col-form-label text-center">일반</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="adult" name="adult" value={ticketFee.adult} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="adult" name="adult" value={ticketFee.adult} onChange={handleChange} />
</div> </div>
<label for="senior" className="col-md-1 col-form-label text-center">경로</label> <label htmlfor="senior" className="col-md-1 col-form-label text-center">경로</label>
<div className="col-md-3 col-lg-2"> <div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="senior" name="senior" value={ticketFee.senior} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} type="number" id="senior" name="senior" value={ticketFee.senior} onChange={handleChange} />
</div> </div>
......
...@@ -12,8 +12,12 @@ const TicketFeeTable = ({ setEditFee, formRef }) => { ...@@ -12,8 +12,12 @@ const TicketFeeTable = ({ setEditFee, formRef }) => {
}, []) }, [])
async function getInfo() { async function getInfo() {
const res = await cinemaApi.getTicketFee() try {
setTicketFee(res) const res = await cinemaApi.getTicketFee()
setTicketFee(res)
} catch (error) {
catchErrors(error, setError)
}
} }
async function editRow(theaterType) { async function editRow(theaterType) {
......
const TimeTableEdit = () => {
return (
<>
</>
)
}
export default TimeTableEdit
\ No newline at end of file
...@@ -44,6 +44,12 @@ ...@@ -44,6 +44,12 @@
} }
} }
.selectInput {
& option[disabled] {
color: #000;
}
}
.word { .word {
word-break: keep-all; word-break: keep-all;
} }
......
...@@ -3,37 +3,45 @@ import styles from './seatTable.module.scss' ...@@ -3,37 +3,45 @@ import styles from './seatTable.module.scss'
const SeatTable = (props) => { const SeatTable = (props) => {
const table = [] const table = []
for (let rowIndex = 0; rowIndex < props.allSeat.row; rowIndex++) { if (props.theaterInfo) {
table.push(<span className="me-3" style={{color:"gray"}}>{String.fromCharCode(rowIndex + 65)}</span>) for (let rowIndex = 0; rowIndex < props.theaterInfo.rows; rowIndex++) {
// console.log(String.fromCharCode(rowIndex+65)) table.push(<span className="me-3" style={{ color: "gray" }}>{String.fromCharCode(rowIndex + 65)}</span>)
for (let colIndex = 0; colIndex < props.allSeat.col; colIndex++) { for (let colIndex = 0; colIndex < props.theaterInfo.columns; colIndex++) {
table.push( table.push(
<span> <span>
<button className={props.selectedSeats.find(el => el === String.fromCharCode(rowIndex + 65) + String(colIndex + 1)) ? styles.on : styles.btn} name={`${String.fromCharCode(rowIndex + 65)}${colIndex + 1}`} type="button" onClick={handleClick}> {colIndex + 1} </button> {props.reservedSeats.find(el => el === String(rowIndex + 1) + '-' + String(colIndex + 1))
</span> ?
) <button className={styles.btnBlock} name={rowIndex + 1} id={colIndex + 1} type="button" disabled>{colIndex + 1}</button>
:
<button className={props.selectedSeats.find(el => el === String(rowIndex + 1) + '-' + String(colIndex + 1)) ? styles.on : styles.btn} name={rowIndex + 1} id={colIndex + 1} type="button" onClick={handleClick}> {colIndex + 1} </button>
}
</span>
)
}
table.push(<br />)
} }
table.push(<br />)
} }
function handleClick(event) { function handleClick(event) {
const num = Object.values(props.count).reduce((a, b) => (a + b)) const num = Object.values(props.count).reduce((a, b) => (a + b))
if (props.selectedSeats.find(el => el === event.target.name)) { if (props.selectedSeats.find(el => el === event.target.name + '-' + event.target.id)) {
//제거 //제거
const deleted = props.selectedSeats.filter((element) => element !== event.target.name); const deleted = props.selectedSeats.filter((element) => element !== event.target.name + '-' + event.target.id);
props.setSelectedSeats(deleted) props.setSelectedSeats(deleted)
} else { } else {
if (props.selectedSeats.length > num - 1) { if (props.selectedSeats.length > num - 1) {
alert("선택한 좌석이 예매인원보다 많습니다.") alert("선택한 좌석이 예매인원보다 많습니다.")
} else { } else {
//추가 //추가
props.setSelectedSeats([...props.selectedSeats, event.target.name]) props.setSelectedSeats([...props.selectedSeats, event.target.name + '-' + event.target.id])
} }
} }
} }
return ( return (
<div className="text-center"> <div className="text-center">
{/* {console.log(props.theaterInfo)} */}
{console.log(props.selectedSeats)} {console.log(props.selectedSeats)}
<div className="mb-2" style={{ backgroundColor: "gray" }}>Screen</div> <div className="mb-2" style={{ backgroundColor: "gray" }}>Screen</div>
{table} {table}
......
...@@ -12,4 +12,10 @@ ...@@ -12,4 +12,10 @@
border:0; border:0;
background: red ; background: red ;
color:white color:white
}
.btnBlock {
background: gray;
border: 0;
color:white;
} }
\ No newline at end of file
...@@ -4,17 +4,13 @@ const TicketingTheater = (props) => { ...@@ -4,17 +4,13 @@ const TicketingTheater = (props) => {
function handleClick(event) { function handleClick(event) {
// event.preventDefault() // event.preventDefault()
console.log(event.target.name) console.log(event.target.name)
props.setTicketInfo({ ...props.ticketInfo, theater:event.target.name}) props.setTicketInfo({ ...props.ticketInfo, cinema: event.target.name })
} }
return ( return (
<div > <div >
<div className="d-grid gap-2"> <div className="d-grid gap-2">
{props.theaterInfo.theater.length > 0 <button name={props.cinemaInfo.cinemaName} className={`${props.ticketInfo.cinema === props.cinemaInfo.cinemaName ? styles.on : styles.btn}`} onClick={handleClick}>{props.cinemaInfo.cinemaName}</button>
? props.theaterInfo.theater.map(name => (
<button name={name} className={`${props.ticketInfo.theater === name ? styles.on : styles.btn}`} onClick={handleClick}>{name}</button>
))
: <div>영화관 정보가 존재하지 않습니다.</div>}
</div> </div>
</div> </div>
) )
......
import axios from 'axios' import axios from 'axios'
import { useState } from 'react' import { useEffect, useState } from 'react'
import Kakaopay from '../components/Kakaopay' import Kakaopay from '../components/Kakaopay'
import { useAuth } from '../context/auth_context'
import catchErrors from '../utils/catchErrors'
const Payment = ({ location }) => { const Payment = ({ location }) => {
const [ticketInfo, setTicketInfo] = useState({ ...location.state }) const [ticketInfo, setTicketInfo] = useState({ ...location.state })
const [error, setError] = useState("")
const [userInfo, setUserInfo] = useState()
const { user } = useAuth()
useEffect(() => {
getUserInfo()
}, [])
async function getUserInfo() {
try {
const response = await axios.post(`/api/auth/getuserinfo`, {
id: user.id
})
setUserInfo(response.data)
} catch (error) {
catchErrors(error, setError)
}
}
async function SendMail(e) { async function SendMail(e) {
try { try {
const response = await axios.post('/api/email/send',{ const response = await axios.post('/api/email/send', {
email:e.target.name ...ticketInfo,
...userInfo
}) })
console.log(response.data) console.log(response.data)
} catch (error) { } catch (error) {
...@@ -19,6 +42,7 @@ const Payment = ({ location }) => { ...@@ -19,6 +42,7 @@ const Payment = ({ location }) => {
return ( return (
<div className="container" style={{ color: "white" }}> <div className="container" style={{ color: "white" }}>
{console.log(ticketInfo)} {console.log(ticketInfo)}
{console.log(userInfo)}
<div className="row justify-content-center my-5"> <div className="row justify-content-center my-5">
<div className="col-sm-4 mb-3 "> <div className="col-sm-4 mb-3 ">
<h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>결제하기</h3> <h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>결제하기</h3>
...@@ -26,27 +50,40 @@ const Payment = ({ location }) => { ...@@ -26,27 +50,40 @@ const Payment = ({ location }) => {
</div> </div>
<div className="row justify-content-center"> <div className="row justify-content-center">
<div className="col-sm-8 text-center"> <div className="col-sm-8 text-center">
{user?.id > 0
?
<div>
<h5 className="mb-3">회원정보</h5>
</div>
:
<div>
<h5 className="mb-3">비회원예매 정보입력</h5>
</div>
}
<h5 className="mb-3">결제방법</h5> <h5 className="mb-3">결제방법</h5>
<img src="/images/naverpay_button.png" /> <img src="/images/naverpay_button.png" />
<Kakaopay ticketInfo={ticketInfo} setTicketInfo={setTicketInfo} /> <Kakaopay ticketInfo={ticketInfo} setTicketInfo={setTicketInfo} />
<div className="my-5">
<button className="btn btn-warning" type="button" onClick={SendMail}>결제완료</button>
</div>
</div> </div>
<div className="col-sm-4 p-3 text-center rounded-3" style={{ backgroundColor: "#252525" }}> <div className="col-sm-4 p-3 text-center rounded-3" style={{ backgroundColor: "#252525" }}>
<img style={{ maxHeight: "10rem" }} src={`https://image.tmdb.org/t/p/original${ticketInfo.poster_path}`} alt="영화포스터" /> <img style={{ maxHeight: "10rem" }} src={`https://image.tmdb.org/t/p/original${ticketInfo.poster_path}`} alt="영화포스터" />
<h5 className="my-3">{ticketInfo.title}</h5> <h5 className="my-3">{ticketInfo.title}</h5>
<div>{ticketInfo.theater}</div> <div>{ticketInfo.cinema}</div>
<div>{ticketInfo.time}</div> <div>{ticketInfo.time}</div>
<div className="mb-3">{ticketInfo.selectedCinemaNum} {ticketInfo.selectedSeats}</div> <div className="mb-3">{ticketInfo.selectedTheater} {ticketInfo.selectedSeats}</div>
<div className="rounded-3 p-3" style={{backgroundColor:'#404040'}}> <div className="rounded-3 p-3" style={{ backgroundColor: '#404040' }}>
<div>청소년: {ticketInfo.teenager}</div> <div>청소년: {ticketInfo.teenager}</div>
<div>성인: {ticketInfo.adult}</div> <div>성인: {ticketInfo.adult}</div>
<div>경로우대: {ticketInfo.elderly}</div> <div>경로우대: {ticketInfo.elderly}</div>
<div> 결제금액: {ticketInfo.teenager*7000 +ticketInfo.adult*8000+ticketInfo.elderly*6000}</div> <div> 결제금액: {ticketInfo.teenager * 7000 + ticketInfo.adult * 8000 + ticketInfo.elderly * 6000}</div>
</div> </div>
</div> </div>
</div> </div>
<div>
<button type="button" name="jiwon5393@naver.com" onClick={SendMail}>메일발송</button>
</div>
</div> </div>
) )
} }
......
import axios from 'axios'
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import movieApi from '../apis/movie.api.js' import movieApi from '../apis/movie.api.js'
...@@ -8,16 +9,17 @@ import TicketingTimeTable from "../components/TicketingTimeTable/TicketingTimeTa ...@@ -8,16 +9,17 @@ import TicketingTimeTable from "../components/TicketingTimeTable/TicketingTimeTa
const TicketingPage = ({ location }) => { const TicketingPage = ({ location }) => {
const [ticketInfo, setTicketInfo] = useState({ const [ticketInfo, setTicketInfo] = useState({
...location.state, ...location.state,
theater:"", cinema:"",
selectedCinemaNum: 3, selectedTheater: 1,
time: "2021/07/21 10:00" time: "2021/07/21 10:00"
}) })
const [theaterInfo, setTheaterInfo] = useState({ const [cinemaInfo, setCinemaInfo] = useState({})
theater: ["Butter Studio 조치원"],
cinemaNum: [1, 2, 3, 4]
})
const [movieInfo, setMovieInfo] = useState() const [movieInfo, setMovieInfo] = useState()
useEffect(() => {
getCinemaInfo()
}, [])
useEffect(() => { useEffect(() => {
getMovieInfo() getMovieInfo()
}, [ticketInfo]) }, [ticketInfo])
...@@ -30,7 +32,15 @@ const TicketingPage = ({ location }) => { ...@@ -30,7 +32,15 @@ const TicketingPage = ({ location }) => {
console.log(error) console.log(error)
} }
} }
async function getCinemaInfo() {
try {
const response = await axios.get('/api/info/cinema')
console.log(response.data)
setCinemaInfo(response.data)
} catch (error) {
console.log(error)
}
}
return ( return (
<div className="container" style={{ backgroundColor: "black" }}> <div className="container" style={{ backgroundColor: "black" }}>
<div> <div>
...@@ -43,11 +53,11 @@ const TicketingPage = ({ location }) => { ...@@ -43,11 +53,11 @@ const TicketingPage = ({ location }) => {
</div> </div>
<div className="col-sm-3 mb-4 "> <div className="col-sm-3 mb-4 ">
<h3 className="py-2 mb-3 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>극장</h3> <h3 className="py-2 mb-3 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>극장</h3>
<TicketingTheater theaterInfo={theaterInfo} ticketInfo={ticketInfo} setTicketInfo={setTicketInfo} /> <TicketingTheater cinemaInfo={cinemaInfo} ticketInfo={ticketInfo} setTicketInfo={setTicketInfo} />
</div> </div>
<div className="col-sm-5 mb-4 "> <div className="col-sm-5 mb-4 ">
<h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>시간표</h3> <h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>시간표</h3>
<TicketingTimeTable ticketInfo={ticketInfo} theaterInfo={theaterInfo} /> <TicketingTimeTable ticketInfo={ticketInfo} cinemaInfo={cinemaInfo} />
</div> </div>
</div> </div>
<div className="row p-3" style={{ backgroundColor: "#252525"}}> <div className="row p-3" style={{ backgroundColor: "#252525"}}>
...@@ -58,18 +68,18 @@ const TicketingPage = ({ location }) => { ...@@ -58,18 +68,18 @@ const TicketingPage = ({ location }) => {
</div> </div>
<div className="col-sm-6 border-end" style={{ color: "white" }}> <div className="col-sm-6 border-end" style={{ color: "white" }}>
<div className="mb-2 text-center">극장선택</div> <div className="mb-2 text-center">극장선택</div>
{movieInfo && ticketInfo.theater {movieInfo && ticketInfo.cinema
? <ul> ? <ul>
<li>영화: {movieInfo.title}</li> <li>영화: {movieInfo.title}</li>
<li>극장: {ticketInfo.theater}</li> <li>극장: {ticketInfo.cinema}</li>
<li>일시: {ticketInfo.time}</li> <li>일시: {ticketInfo.time}</li>
<li>상영관: {ticketInfo.selectedCinemaNum}</li> <li>상영관: {ticketInfo.selectedTheater}</li>
</ul> </ul>
: <div></div>} : <div></div>}
</div> </div>
<div className="col-sm-3 text-center"> <div className="col-sm-3 text-center">
<div className="mb-2" style={{ color: "white" }}>좌석선택</div> <div className="mb-2" style={{ color: "white" }}>좌석선택</div>
{movieInfo && ticketInfo.theater {movieInfo && ticketInfo.cinema
? ?
<Link to={{ <Link to={{
pathname: `/ticket/seat`, pathname: `/ticket/seat`,
......
import { Link } from 'react-router-dom' import { Link, useHistory } from 'react-router-dom'
import { useState } from 'react' import { useState, useEffect, useRef } from 'react'
import { Modal } from 'bootstrap'
import CountButton from '../components/CountButton' import CountButton from '../components/CountButton'
import SeatTable from '../components/SeatTable/SeatTable' import SeatTable from '../components/SeatTable/SeatTable'
import styles from '../components/SeatTable/seatTable.module.scss'
import axios from 'axios'
import { useAuth } from '../context/auth_context.js'
const TicketingSeatPage = ({ location }) => { const TicketingSeatPage = ({ location }) => {
const history = useHistory()
const modalRef = useRef(null)
const modal = useRef()
const { user } = useAuth()
const [ticketInfo, setTicketInfo] = useState({ ...location.state }) const [ticketInfo, setTicketInfo] = useState({ ...location.state })
const [theaterInfo, setTheaterInfo] = useState()
const [selectedSeats, setSelectedSeats] = useState([]) const [selectedSeats, setSelectedSeats] = useState([])
const [reservedSeats, setReservedSeats] = useState([])
const [count, setCount] = useState({ const [count, setCount] = useState({
adult: 0, adult: 0,
teenager: 0, teenager: 0,
elderly: 0 elderly: 0
}) })
const allSeat = { row: 6, col: 10 }
return (
<div className="container" style={{ color: "white" }}>
{console.log(ticketInfo)}
<div className="row justify-content-center my-5">
<div className="col-sm-4 mb-3 ">
<h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>좌석선택</h3>
</div>
</div>
<div className="row justify-content-center my-3">
<div className="col-sm-6 mb-4 text-center">
<div className="row">
<div className="col-sm-6 text-end"> useEffect(() => {
<div className="my-1">일반</div> getInfo()
<div className="my-1">청소년</div> }, [])
<div className="my-1">경로우대</div>
</div>
<div className="col-sm-6 text-start">
<CountButton name="adult" count={count} setCount={setCount} />
<CountButton name="teenager" count={count} setCount={setCount} />
<CountButton name="elderly" count={count} setCount={setCount} />
</div>
</div>
{/* <span className="">일반</span>
<CountButton name="adult" count={count} setCount={setCount} />
<span className="">청소년</span> async function getInfo() {
<CountButton name="teenager" count={count} setCount={setCount} /> try {
const response = await axios.post('/api/theater/getInfo', {
theaterNum: ticketInfo.selectedTheater
})
console.log(response.data)
setTheaterInfo(response.data)
const response2 = await axios.post('/api/reservation/findreservation', {
timetable: 1
})
console.log(response2.data)
const reserve = response2.data.map((el) =>
el.row + '-' + el.col
)
setReservedSeats(reserve)
} catch (error) {
console.log(error)
}
}
<span className="">경로우대</span> function loginModal() {
<CountButton name="elderly" count={count} setCount={setCount} /> */} if (user) {
history.push("/payment", {
...ticketInfo, selectedSeats: selectedSeats, ...count
});
} else {
modal.current = new Modal(modalRef.current)
modal.current?.show()
}
}
</div> return (
<div className="col-sm-6 mb-4 p-2 text-center" style={{ backgroundColor: '#252525' }}> <>
<div>{ticketInfo.theater} | {ticketInfo.selectedCinemaNum}</div> <div ref={modalRef} className="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden={modal}>
<div>{ticketInfo.title}</div> <div className="modal-dialog">
<div>{ticketInfo.time}</div> <div className="modal-content">
{ }
<div className="modal-header">
<h5 className="modal-title" id="staticBackdropLabel">로그인이 필요한 서비스입니다.</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
로그인을 하시겠습니까? 비회원예매로 진행하시겠습니까?
</div>
<div className="modal-footer">
<Link to={{ pathname: '/login' }}>
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal" >
로그인
</button>
</Link>
<Link to={{
pathname: `/payment`,
state: { ...ticketInfo, selectedSeats: selectedSeats, ...count }
}}>
<button type="button" className="btn btn-primary" data-bs-dismiss="modal">비회원예매</button>
</Link>
</div>
</div>
</div> </div>
</div> </div>
<div className="row justify-content-center border p-5 "> <div className="container" style={{ color: "white" }}>
<div className="col-sm-8"> {console.log(ticketInfo)}
<SeatTable count={count} setSelectedSeats={setSelectedSeats} selectedSeats={selectedSeats} allSeat={allSeat} /> {console.log(reservedSeats)}
</div> <div className="row justify-content-center my-5">
<div className="col-sm-4 mt-5"> <div className="col-sm-4 mb-3 ">
<p>선택</p> <h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>좌석선택</h3>
<p>선택불가</p> </div>
</div> </div>
</div> <div className="row justify-content-center my-3">
<div className="row p-3 mt-5" style={{ backgroundColor: "#252525" }}> <div className="col-sm-6 mb-4 text-center">
<div className="col-sm-3 border-end text-center"> <div className="row">
{ticketInfo
? <img style={{ maxHeight: "10rem" }} src={`https://image.tmdb.org/t/p/original${ticketInfo.poster_path}`} alt="영화포스터" /> <div className="col-sm-6 text-end">
: <div className="mb-2" style={{ color: "white" }}>영화선택</div>} <div className="my-1">일반</div>
<div className="my-1">청소년</div>
<div className="my-1">경로우대</div>
</div>
<div className="col-sm-6 text-start">
<CountButton name="adult" count={count} setCount={setCount} />
<CountButton name="teenager" count={count} setCount={setCount} />
<CountButton name="elderly" count={count} setCount={setCount} />
</div>
</div>
</div>
<div className="col-sm-6 mb-4 p-2 text-center" style={{ backgroundColor: '#252525' }}>
<div>{ticketInfo.cinema} | {ticketInfo.selectedTheater}</div>
<div>{ticketInfo.title}</div>
<div>{ticketInfo.time}</div>
</div>
</div> </div>
<div className="col-sm-6 border-end" style={{ color: "white" }}> <div className="row justify-content-center border p-5 ">
<div className="mb-2 text-center">극장선택</div> <div className="col-sm-8">
{ticketInfo <SeatTable count={count} setSelectedSeats={setSelectedSeats} selectedSeats={selectedSeats} theaterInfo={theaterInfo} reservedSeats={reservedSeats} />
? <ul> </div>
<li>영화: {ticketInfo.title}</li> <div className="col-sm-4 mt-5">
<li>극장: {ticketInfo.theater}</li> <div>
<li>일시: 2021/07/21 10:00 </li> <button className={styles.on} style={{ height: '1rem', width: '1rem' }} disabled></button>
<li>상영관: 3</li> <span> 선택됨</span>
<li>좌석: {selectedSeats}</li> </div>
</ul> <div>
: <div></div>} <button className={styles.btnBlock} style={{ height: '1rem', width: '1rem' }} disabled></button>
<span> 선택불가</span>
</div>
</div>
</div> </div>
<div className="col-sm-3 text-center"> <div className="row p-3 mt-5" style={{ backgroundColor: "#252525" }}>
<div className="mb-2" style={{ color: "white" }}>결제하기</div> <div className="col-sm-3 border-end text-center">
{ticketInfo {ticketInfo
? ? <img style={{ maxHeight: "10rem" }} src={`https://image.tmdb.org/t/p/original${ticketInfo.poster_path}`} alt="영화포스터" />
<Link to={{ : <div className="mb-2" style={{ color: "white" }}>영화선택</div>}
pathname: `/payment`, </div>
state: { ...ticketInfo, selectedSeats: selectedSeats, ...count } <div className="col-sm-6 border-end" style={{ color: "white" }}>
}}> <div className="mb-2 text-center">극장선택</div>
<img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" alt="예매하기" /> {ticketInfo
</Link> ? <ul>
: <li>영화: {ticketInfo.title}</li>
<img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" alt="예매하기" /> <li>극장: {ticketInfo.cinema}</li>
<li>일시: 2021/07/21 10:00 </li>
<li>상영관: 3</li>
<li>좌석: {selectedSeats}</li>
</ul>
: <div></div>}
</div>
<div className="col-sm-3 text-center">
<div className="mb-2" style={{ color: "white" }}>결제하기</div>
{ticketInfo
?
<button onClick={loginModal} style={{ backgroundColor: '#252525', border: 0 }} >
<img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" alt="결제하기" />
</button>
:
<button disabled>
<img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" alt="결제하기" />
</button>
} }
</div>
</div> </div>
</div> </div>
</div> </>
) )
} }
......
...@@ -39,29 +39,6 @@ ...@@ -39,29 +39,6 @@
"negotiator": "0.6.2" "negotiator": "0.6.2"
} }
}, },
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"requires": {
"debug": "4"
},
"dependencies": {
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"ansi-align": { "ansi-align": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
...@@ -124,11 +101,6 @@ ...@@ -124,11 +101,6 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
}, },
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"axios": { "axios": {
"version": "0.21.1", "version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
...@@ -267,15 +239,6 @@ ...@@ -267,15 +239,6 @@
} }
} }
}, },
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"camelcase": { "camelcase": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
...@@ -464,11 +427,6 @@ ...@@ -464,11 +427,6 @@
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true "dev": true
}, },
"dayjs": {
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
"integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
},
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
...@@ -678,21 +636,6 @@ ...@@ -678,21 +636,6 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"get-stream": { "get-stream": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
...@@ -745,25 +688,12 @@ ...@@ -745,25 +688,12 @@
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
"dev": true "dev": true
}, },
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true "dev": true
}, },
"has-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
},
"has-yarn": { "has-yarn": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
...@@ -788,30 +718,6 @@ ...@@ -788,30 +718,6 @@
"toidentifier": "1.0.0" "toidentifier": "1.0.0"
} }
}, },
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"requires": {
"agent-base": "6",
"debug": "4"
},
"dependencies": {
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
...@@ -1252,11 +1158,6 @@ ...@@ -1252,11 +1158,6 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
}, },
"object-inspect": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
},
"on-finished": { "on-finished": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
...@@ -1383,11 +1284,6 @@ ...@@ -1383,11 +1284,6 @@
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true "dev": true
}, },
"pop-iterate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pop-iterate/-/pop-iterate-1.0.1.tgz",
"integrity": "sha1-zqz9q0q/NT16DyqqLB/Hs/lBO6M="
},
"postgres-array": { "postgres-array": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
...@@ -1456,26 +1352,11 @@ ...@@ -1456,26 +1352,11 @@
"escape-goat": "^2.0.0" "escape-goat": "^2.0.0"
} }
}, },
"q": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",
"integrity": "sha1-dbjbAlWhpa+C9Yw/Oqoe/sfQ0TQ=",
"requires": {
"asap": "^2.0.0",
"pop-iterate": "^1.0.1",
"weak-map": "^1.0.5"
}
},
"qs": { "qs": {
"version": "6.7.0", "version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
}, },
"querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"range-parser": { "range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
...@@ -1542,11 +1423,6 @@ ...@@ -1542,11 +1423,6 @@
"rc": "^1.2.8" "rc": "^1.2.8"
} }
}, },
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"responselike": { "responselike": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
...@@ -1564,11 +1440,6 @@ ...@@ -1564,11 +1440,6 @@
"any-promise": "^1.3.0" "any-promise": "^1.3.0"
} }
}, },
"rootpath": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/rootpath/-/rootpath-0.1.2.tgz",
"integrity": "sha1-Wzeah9ypBum5HWkKWZQ5vvJn6ms="
},
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
...@@ -1579,11 +1450,6 @@ ...@@ -1579,11 +1450,6 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
}, },
"scmp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="
},
"semver": { "semver": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
...@@ -1697,16 +1563,6 @@ ...@@ -1697,16 +1563,6 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
}, },
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"requires": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"signal-exit": { "signal-exit": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
...@@ -1865,34 +1721,6 @@ ...@@ -1865,34 +1721,6 @@
"nopt": "~1.0.10" "nopt": "~1.0.10"
} }
}, },
"twilio": {
"version": "3.66.0",
"resolved": "https://registry.npmjs.org/twilio/-/twilio-3.66.0.tgz",
"integrity": "sha512-2jek7akXcRMusoR20EWA1+e5TQp9Ahosvo81wTUoeS7H24A1xbVQJV4LfSWQN4DLUY1oZ4d6tH2oCe/+ELcpNA==",
"requires": {
"axios": "^0.21.1",
"dayjs": "^1.8.29",
"https-proxy-agent": "^5.0.0",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"q": "2.0.x",
"qs": "^6.9.4",
"rootpath": "^0.1.2",
"scmp": "^2.1.0",
"url-parse": "^1.5.0",
"xmlbuilder": "^13.0.2"
},
"dependencies": {
"qs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"requires": {
"side-channel": "^1.0.4"
}
}
}
},
"type-fest": { "type-fest": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
...@@ -1971,15 +1799,6 @@ ...@@ -1971,15 +1799,6 @@
"xdg-basedir": "^4.0.0" "xdg-basedir": "^4.0.0"
} }
}, },
"url-parse": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"url-parse-lax": { "url-parse-lax": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
...@@ -2014,11 +1833,6 @@ ...@@ -2014,11 +1833,6 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
}, },
"weak-map": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz",
"integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes="
},
"widest-line": { "widest-line": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
...@@ -2060,11 +1874,6 @@ ...@@ -2060,11 +1874,6 @@
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
"dev": true "dev": true
}, },
"xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
......
...@@ -27,8 +27,7 @@ ...@@ -27,8 +27,7 @@
"nodemailer": "^6.6.3", "nodemailer": "^6.6.3",
"pg": "^8.6.0", "pg": "^8.6.0",
"pg-hstore": "^2.3.4", "pg-hstore": "^2.3.4",
"sequelize": "^6.6.4", "sequelize": "^6.6.4"
"twilio": "^3.66.0"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^2.0.12" "nodemon": "^2.0.12"
......
...@@ -6,6 +6,7 @@ const getAll = async (req, res) => { ...@@ -6,6 +6,7 @@ const getAll = async (req, res) => {
where: { id: 1 }, where: { id: 1 },
attributes: ['cinemaName', 'transportation', 'parking', 'address', 'moreFeeInfo'] attributes: ['cinemaName', 'transportation', 'parking', 'address', 'moreFeeInfo']
}) })
console.log("INfo====",info)
return res.json(info) return res.json(info)
} catch (error) { } catch (error) {
return res.status(500).send(error.message || "영화관 정보 가져오는 중 에러 발생") return res.status(500).send(error.message || "영화관 정보 가져오는 중 에러 발생")
......
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