Commit eacc9ce9 authored by 한규민's avatar 한규민
Browse files

Merge branch 'master' into gyumin

parents 19251ba0 c6fcbcbe
...@@ -14,7 +14,8 @@ import AdminPage from "./pages/AdminPage/AdminPage"; ...@@ -14,7 +14,8 @@ import AdminPage from "./pages/AdminPage/AdminPage";
import TicketingPage from "./pages/TicketingPage"; import TicketingPage from "./pages/TicketingPage";
import TicketingSeatPage from './pages/TicketingSeatPage' import TicketingSeatPage from './pages/TicketingSeatPage'
import SearchPage from "./pages/SearchPage"; import SearchPage from "./pages/SearchPage";
import Payment from "./pages/PaymentPage"; import Payment from "./pages/PaymentPage/PaymentPage";
import PaymentCompletePage from "./pages/PaymentCompletePage";
function App() { function App() {
...@@ -39,6 +40,8 @@ function App() { ...@@ -39,6 +40,8 @@ function App() {
<Route path="/ticket/seat" component={TicketingSeatPage} /> <Route path="/ticket/seat" component={TicketingSeatPage} />
<Route path="/ticket" component={TicketingPage} /> <Route path="/ticket" component={TicketingPage} />
<Route path="/payment" component={Payment} /> <Route path="/payment" component={Payment} />
<Route path="/paymentcomplete" component={PaymentCompletePage} />
<Route path="/theater" component={TheaterPage}/>
<Route path="/search" component={SearchPage} /> <Route path="/search" component={SearchPage} />
</Switch> </Switch>
</Router> </Router>
......
...@@ -16,8 +16,8 @@ const getTicketFee = async () => { ...@@ -16,8 +16,8 @@ const getTicketFee = async () => {
return data return data
} }
const getTicketFeeOne = async (theaterType) => { const getTicketFeeOne = async (theatertypeId) => {
const { data } = await axios.get(`${baseUrl}/api/info/ticketfee/${theaterType}`) const { data } = await axios.get(`${baseUrl}/api/info/ticketfee/${theatertypeId}`)
return data return data
} }
...@@ -26,8 +26,8 @@ const editTicketFee = async (ticketFeeInfo) => { ...@@ -26,8 +26,8 @@ const editTicketFee = async (ticketFeeInfo) => {
return data return data
} }
const removeTicketFee = async (theaterType) => { const removeTicketFee = async (theatertypeId) => {
const { data } = await axios.delete(`${baseUrl}/api/info/ticketfee?theaterType=${theaterType}`) const { data } = await axios.delete(`${baseUrl}/api/info/ticketfee?theaterTypeId=${theatertypeId}`)
return data return data
} }
......
...@@ -10,38 +10,42 @@ const getAllfromTM = async () => { ...@@ -10,38 +10,42 @@ const getAllfromTM = async () => {
const { data } = await axios.get(`${baseUrl}/api/movie/all`, payload) const { data } = await axios.get(`${baseUrl}/api/movie/all`, payload)
return data return data
} }
const getMoviesfromTM = async (category) => {
console.log(category)
const response = await axios.get(`${baseUrl}/api/movie/showmovies/${category}`)
console.log(response.data)
return response.data
}
const getMovieInfofromTM = async (id) => { const getMovieInfofromTM = async (id) => {
const movieId = id const movieId = id
const response = await axios.get(`${TMDBUrl}/${movieId}?api_key=${process.env.REACT_APP_TMDB_API_KEY}&language=ko-KR`) const response = await axios.get(`${TMDBUrl}/${movieId}?api_key=${process.env.REACT_APP_TMDB_API_KEY}&language=ko-KR`)
console.log(response.data)
return response.data return response.data
} }
const getImagesfromTM = async (id) => { const getImagesfromTM = async (id) => {
const movieId = id const movieId = id
const response = await axios.get(`${TMDBUrl}/${movieId}/images?api_key=${process.env.REACT_APP_TMDB_API_KEY}`) const response = await axios.get(`${TMDBUrl}/${movieId}/images?api_key=${process.env.REACT_APP_TMDB_API_KEY}`)
return response.data return response.data
} }
const getCreditsfromTM = async (id) =>{
const getCreditsfromTM = async (id) => {
const movieId = id const movieId = id
const response = await axios.get(`${TMDBUrl}/${movieId}/credits?api_key=${process.env.REACT_APP_TMDB_API_KEY}`) const response = await axios.get(`${TMDBUrl}/${movieId}/credits?api_key=${process.env.REACT_APP_TMDB_API_KEY}`)
return response.data return response.data
} }
const getVideosfromTM = async (id) =>{ const getVideosfromTM = async (id) => {
const movieId = id const movieId = id
const response = await axios.get(`${TMDBUrl}/${movieId}/videos?api_key=${process.env.REACT_APP_TMDB_API_KEY}`) const response = await axios.get(`${TMDBUrl}/${movieId}/videos?api_key=${process.env.REACT_APP_TMDB_API_KEY}`)
return response.data.results return response.data.results
} }
const getListfromDB = async () => {
const { data } = await axios.get(`${baseUrl}/api/movie`)
return data
}
const getListByCategoryfromDB = async (category) => {
const { data } = await axios.get(`${baseUrl}/api/movie/movielist/${category}`)
return data
}
const submit = async (movieId) => { const submit = async (movieId) => {
const { data } = await axios.post(`${baseUrl}/api/movie/${movieId}`) const { data } = await axios.post(`${baseUrl}/api/movie/${movieId}`)
console.log("data==", data) return data
} }
const remove = async (movieId) => { const remove = async (movieId) => {
...@@ -61,11 +65,12 @@ const search = async ({ type, keyword }) => { ...@@ -61,11 +65,12 @@ const search = async ({ type, keyword }) => {
const movieApi = { const movieApi = {
getAllfromTM, getAllfromTM,
getMoviesfromTM, getListByCategoryfromDB,
getMovieInfofromTM, getMovieInfofromTM,
getImagesfromTM, getImagesfromTM,
getCreditsfromTM, getCreditsfromTM,
getVideosfromTM, getVideosfromTM,
getListfromDB,
submit, submit,
remove, remove,
search, search,
......
...@@ -6,8 +6,8 @@ const getAll = async () => { ...@@ -6,8 +6,8 @@ const getAll = async () => {
return data return data
} }
const getOne = async () => { const getOne = async (theaterId) => {
const { data } = await axios.get(`${baseUrl}/api/theater`) const { data } = await axios.get(`${baseUrl}/api/theater/${theaterId}`)
return data return data
} }
...@@ -17,12 +17,12 @@ const getTheaterType = async () => { ...@@ -17,12 +17,12 @@ const getTheaterType = async () => {
} }
const sendData = async (theater) => { const sendData = async (theater) => {
const { data } = await axios.put(`${baseUrl}/api/theater/type`, theater) const { data } = await axios.put(`${baseUrl}/api/theater`, theater)
return data return data
} }
const remove = async () => { const remove = async (theaterId) => {
const { data } = await axios.delete(`${baseUrl}/api/theater`) const { data } = await axios.delete(`${baseUrl}/api/theater/${theaterId}`)
return data return data
} }
......
import axios from "axios";
import { baseUrl } from "../utils/baseUrl.js";
const submit = async (sendData) => {
const { data } = await axios.post(`${baseUrl}/api/timetable`, sendData)
return data
}
const timetableApi = {
submit
}
export default timetableApi
\ No newline at end of file
...@@ -4,8 +4,9 @@ import catchErrors from "../../utils/catchErrors.js"; ...@@ -4,8 +4,9 @@ import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss"; import styles from "./admin.module.scss";
const INIT_THEATER = { const INIT_THEATER = {
id: 0,
theaterName: "", theaterName: "",
theaterType: 0, theatertypeId: 0,
rows: 1, rows: 1,
columns: 1 columns: 1
} }
...@@ -47,26 +48,28 @@ const TheaterEditForm = ({ edit, formRef }) => { ...@@ -47,26 +48,28 @@ const TheaterEditForm = ({ edit, formRef }) => {
window.location.reload() window.location.reload()
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
setTheater({ ...theater, ...INIT_THEATER })
} }
} }
return ( return (
<form ref={formRef} onSubmit={handleSubmit}> <form ref={formRef} className="mb-5" 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"> <div className="d-flex justify-content-lg-between row row-cols-2 row-cols-lg-5 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> <label htmlfor="theaterName" className="col-3 col-lg-auto col-form-label">상영관 이름</label>
<div className="col-9 col-lg-4"> <div className="col-8 col-lg-4">
<input className={`form-control ${styles.shadowNone}`} id="theaterName" name="theaterName" type="text" value={theater.theaterName} onChange={handleChange} /> <input className={`form-control ${styles.shadowNone}`} id="theaterName" name="theaterName" type="text" value={theater.theaterName} onChange={handleChange} />
</div> </div>
<label htmlfor="theaterName" className="col-auto col-form-label mx-2 mx-lg-0"></label>
<label htmlfor="theaterType" className="col-3 col-lg-auto col-form-label text-lg-center">상영관 종류</label> <label htmlfor="theaterType" className="col-3 col-lg-auto col-form-label text-lg-center">상영관 종류</label>
<div className="col-9 col-lg-5"> <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}> <select className={`form-select ${styles.shadowNone} ${styles.selectInput}`} id="theatertypeId" name="theatertypeId" value={theater.theatertypeId} onChange={handleChange} aria-label="select theaterType" defaultValue="0">
{types.length !== 0 ? {types.length !== 0 ?
types.map((type, index) => { types.map((type, index) => {
if (index === 0) return <> if (index === 0) return <>
<option value="0" disabled>상영관 종류를 선택해주십시오.</option> <option value="0" disabled>상영관 종류를 선택해주십시오.</option>
<option value={type.id}>{type.theaterType}</option> <option value={type.id}>{type.theaterTypeName}</option>
</> </>
else return <option value={type.id}>{type.theaterType}</option> else return <option value={type.id}>{type.theaterTypeName}</option>
}) })
: <option value="0" disabled>서버에 등록된 상영관 종류가 없습니다.</option>} : <option value="0" disabled>서버에 등록된 상영관 종류가 없습니다.</option>}
</select> </select>
......
...@@ -21,10 +21,10 @@ const TheaterTable = ({ setEdit, formRef }) => { ...@@ -21,10 +21,10 @@ const TheaterTable = ({ setEdit, formRef }) => {
} }
} }
async function editTheater() { async function editTheater(theaterId) {
try { try {
setError("") setError("")
const res = await theaterApi.getOne() const res = await theaterApi.getOne(theaterId)
setEdit({ ...res }) setEdit({ ...res })
formRef?.current.scrollIntoView({ behavior: "smooth", block: "center" }) formRef?.current.scrollIntoView({ behavior: "smooth", block: "center" })
} catch (error) { } catch (error) {
...@@ -32,10 +32,10 @@ const TheaterTable = ({ setEdit, formRef }) => { ...@@ -32,10 +32,10 @@ const TheaterTable = ({ setEdit, formRef }) => {
} }
} }
async function deleteTheater() { async function deleteTheater(theaterId) {
try { try {
setError("") setError("")
await theaterApi.remove() await theaterApi.remove(theaterId)
alert("해당 상영관 정보를 성공적으로 삭제했습니다.") alert("해당 상영관 정보를 성공적으로 삭제했습니다.")
getTheaterList() getTheaterList()
} catch (error) { } catch (error) {
...@@ -56,13 +56,13 @@ const TheaterTable = ({ setEdit, formRef }) => { ...@@ -56,13 +56,13 @@ const TheaterTable = ({ setEdit, formRef }) => {
<tbody> <tbody>
{theaterList.length !== 0 ? theaterList.map(info => {theaterList.length !== 0 ? theaterList.map(info =>
<tr> <tr>
<td>ads</td> <td>{info.theaterName}</td>
<td>ads</td> <td>{info.theatertype.theaterTypeName}</td>
<td>ads</td> <td>{info.rows} {info.columns}<br /> {info.rows*info.columns}</td>
<td> <td>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<button type="button" className="btn btn-primary my-1" onClick={() => editTheater()}>수정</button> <button type="button" className="btn btn-primary my-1" onClick={() => editTheater(info.id)}>수정</button>
<button type="button" className="btn btn-danger my-1" onClick={() => deleteTheater()}>삭제</button> <button type="button" className="btn btn-danger my-1" onClick={() => deleteTheater(info.id)}>삭제</button>
</div> </div>
</td> </td>
</tr>) </tr>)
......
...@@ -4,7 +4,8 @@ import catchErrors from "../../utils/catchErrors.js"; ...@@ -4,7 +4,8 @@ import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss"; import styles from "./admin.module.scss";
const INIT_TICKETFEE = { const INIT_TICKETFEE = {
theaterType: "", theatertypeId: 0,
theaterTypeName: "",
weekdays: "", weekdays: "",
weekend: "", weekend: "",
morning: "", morning: "",
...@@ -46,7 +47,7 @@ const TicketEditForm = ({ editFee, formRef }) => { ...@@ -46,7 +47,7 @@ const TicketEditForm = ({ editFee, formRef }) => {
<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 htmlfor="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="theaterTypeName" name="theaterTypeName" value={ticketFee.theaterTypeName} onChange={handleChange} />
</div> </div>
<label htmlfor="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">
......
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import cinemaApi from "../../apis/cinema.api.js"; import cinemaApi from "../../apis/cinema.api.js";
import catchErrors from "../../utils/catchErrors.js"; import catchErrors from "../../utils/catchErrors.js";
import { useAuth } from '../../context/auth_context'
import styles from "./admin.module.scss"; import styles from "./admin.module.scss";
const TicketFeeTable = ({ setEditFee, formRef }) => { const TicketFeeTable = ({ setEditFee, formRef }) => {
const [ticketFee, setTicketFee] = useState([]) const [ticketFee, setTicketFee] = useState([])
const [error, setError] = useState("") const [error, setError] = useState("")
const { user } = useAuth()
useEffect(() => { useEffect(() => {
getInfo() getInfo()
...@@ -20,10 +24,10 @@ const TicketFeeTable = ({ setEditFee, formRef }) => { ...@@ -20,10 +24,10 @@ const TicketFeeTable = ({ setEditFee, formRef }) => {
} }
} }
async function editRow(theaterType) { async function editRow(theatertypeId) {
try { try {
setError("") setError("")
const res = await cinemaApi.getTicketFeeOne(theaterType) const res = await cinemaApi.getTicketFeeOne(theatertypeId)
setEditFee({ ...res }) setEditFee({ ...res })
formRef?.current.scrollIntoView({ behavior: "smooth", block: "center" }) formRef?.current.scrollIntoView({ behavior: "smooth", block: "center" })
} catch (error) { } catch (error) {
...@@ -31,10 +35,10 @@ const TicketFeeTable = ({ setEditFee, formRef }) => { ...@@ -31,10 +35,10 @@ const TicketFeeTable = ({ setEditFee, formRef }) => {
} }
} }
async function deleteData(theaterType) { async function deleteData(theatertypeId) {
try { try {
setError("") setError("")
await cinemaApi.removeTicketFee(theaterType) await cinemaApi.removeTicketFee(theatertypeId)
alert("해당 관람료 정보를 성공적으로 삭제했습니다.") alert("해당 관람료 정보를 성공적으로 삭제했습니다.")
getInfo() getInfo()
} catch (error) { } catch (error) {
...@@ -47,7 +51,7 @@ const TicketFeeTable = ({ setEditFee, formRef }) => { ...@@ -47,7 +51,7 @@ const TicketFeeTable = ({ setEditFee, formRef }) => {
} }
return ( return (
<table className={`table caption-top text-center align-middle ${styles.tableForm}`}> <table style={{ color: user.role==="admin"?"":"white" }} className={`table caption-top text-center align-middle ${styles.tableForm}`}>
<caption className="text-dark">영화관람료 안내</caption> <caption className="text-dark">영화관람료 안내</caption>
<thead className={`table-dark align-middle ${styles.dNone}`}> <thead className={`table-dark align-middle ${styles.dNone}`}>
<tr> <tr>
...@@ -57,25 +61,31 @@ const TicketFeeTable = ({ setEditFee, formRef }) => { ...@@ -57,25 +61,31 @@ const TicketFeeTable = ({ setEditFee, formRef }) => {
<th>청소년</th> <th>청소년</th>
<th>일반</th> <th>일반</th>
<th>경로</th> <th>경로</th>
{user.role === "admin"
?
<th style={{ width: "14%" }}></th> <th style={{ width: "14%" }}></th>
: <></>}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{ticketFee.length !== 0 ? ticketFee.map(info => {ticketFee.length !== 0 ? ticketFee.map(info =>
<> <>
<tr> <tr>
<td rowSpan="6" className={`d-block d-md-table-cell ${styles.Row} ${styles.type}`}>{info.theaterType}</td> <td rowSpan="6" className={`d-block d-md-table-cell ${styles.Row} ${styles.type}`}>{info.theatertype.theaterTypeName}</td>
<td rowSpan="3" className={`d-block d-md-table-cell ${styles.Row} ${styles.moreData}`} data-label="- 청소년 / 성인 / 경로">주중(~)</td> <td rowSpan="3" className={`d-block d-md-table-cell ${styles.Row} ${styles.moreData}`} data-label="- 청소년 / 성인 / 경로">주중(~)</td>
<td className="d-inline-block d-md-table-cell">조조 (06:00 ~ )</td> <td className="d-inline-block d-md-table-cell">조조 (06:00 ~ )</td>
<td className="d-inline-block d-md-table-cell">{priceToString(info.weekdays + info.morning + info.youth + info.defaultPrice)}</td> <td className="d-inline-block d-md-table-cell">{priceToString(info.weekdays + info.morning + info.youth + info.defaultPrice)}</td>
<td className="d-inline-block d-md-table-cell">{priceToString(info.weekdays + info.morning + info.adult + info.defaultPrice)}</td> <td className="d-inline-block d-md-table-cell">{priceToString(info.weekdays + info.morning + info.adult + info.defaultPrice)}</td>
<td className="d-inline-block d-md-table-cell">{priceToString(info.weekdays + info.morning + info.senior + info.defaultPrice)}</td> <td className="d-inline-block d-md-table-cell">{priceToString(info.weekdays + info.morning + info.senior + info.defaultPrice)}</td>
{user.role === "admin"
?
<td rowSpan="6" className="d-none d-md-table-cell"> <td rowSpan="6" className="d-none d-md-table-cell">
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<button type="button" className="btn btn-primary my-1" onClick={() => editRow(info.theaterType)}>수정</button> <button type="button" className="btn btn-primary my-1" onClick={() => editRow(info.theatertypeId)}>수정</button>
<button type="button" className="btn btn-danger my-1" onClick={() => deleteData(info.theaterType)}>삭제</button> <button type="button" className="btn btn-danger my-1" onClick={() => deleteData(info.theatertypeId)}>삭제</button>
</div> </div>
</td> </td>
: <></>}
</tr> </tr>
<tr> <tr>
<td className="d-inline-block d-md-table-cell">일반 (11:00 ~ )</td> <td className="d-inline-block d-md-table-cell">일반 (11:00 ~ )</td>
...@@ -107,12 +117,15 @@ const TicketFeeTable = ({ setEditFee, formRef }) => { ...@@ -107,12 +117,15 @@ const TicketFeeTable = ({ setEditFee, formRef }) => {
<td className="d-inline-block d-md-table-cell">{priceToString(info.weekend + info.night + info.youth + info.defaultPrice)}</td> <td className="d-inline-block d-md-table-cell">{priceToString(info.weekend + info.night + info.youth + info.defaultPrice)}</td>
<td className="d-inline-block d-md-table-cell">{priceToString(info.weekend + info.night + info.adult + info.defaultPrice)}</td> <td className="d-inline-block d-md-table-cell">{priceToString(info.weekend + info.night + info.adult + info.defaultPrice)}</td>
<td className="d-inline-block d-md-table-cell">{priceToString(info.weekend + info.night + info.senior + info.defaultPrice)}</td> <td className="d-inline-block d-md-table-cell">{priceToString(info.weekend + info.night + info.senior + info.defaultPrice)}</td>
{user.role === "admin"
?
<td className={`d-block d-md-none ${styles.borderTop}`}> <td className={`d-block d-md-none ${styles.borderTop}`}>
<div className="d-flex justify-content-end"> <div className="d-flex justify-content-end">
<button type="button" className="btn btn-primary" onClick={() => editRow(info.theaterType)}>수정</button> <button type="button" className="btn btn-primary" onClick={() => editRow(info.theatertypeId)}>수정</button>
<button type="button" className="btn btn-danger ms-2" onClick={() => deleteData(info.theaterType)}>삭제</button> <button type="button" className="btn btn-danger ms-2" onClick={() => deleteData(info.theatertypeId)}>삭제</button>
</div> </div>
</td> </td>
: <></>}
</tr> </tr>
</>) </>)
: <tr> : <tr>
......
const TimeTable = () => {
return (
<div className="col-6">
</div>
)
}
export default TimeTable
\ No newline at end of file
import TimeTableEditForm from "./TimeTableEditForm";
import TimeTable from "./TimeTable";
const TimeTableEdit = () => { const TimeTableEdit = () => {
return ( return (
<> <>
<h2 className="border-bottom border-2 text-center pb-2 me-2">현재 상영시간표 정보</h2>
<div className="d-flex">
<TimeTableEditForm />
<TimeTable />
</div>
</> </>
) )
} }
......
import { useState, useEffect } from "react";
import movieApi from "../../apis/movie.api.js";
import theaterApi from "../../apis/theater.api.js";
import timetableApi from "../../apis/timetable.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";
const INIT_INFO = {
theater: 0,
start: "",
end: ""
}
const TimeTableEditForm = () => {
const [movieList, setMovieList] = useState([])
const [theaterList, setTheaterList] = useState([])
const [selectId, setSelectId] = useState(0)
const [selectMovie, setSelectMovie] = useState({})
const [info, setInfo] = useState({ end_date: "" })
const [selectInfo, setSelectInfo] = useState(INIT_INFO)
const [showTimes, setShowTimes] = useState({ list: [] })
const [error, setError] = useState("")
useEffect(() => {
getMoviesfromDB()
getTheater()
}, [])
useEffect(() => {
setSelectInfo({ ...selectInfo, ...INIT_INFO })
setShowTimes({ list: [] })
}, [selectId])
async function getMoviesfromDB() {
try {
setError("")
const res = await movieApi.getListfromDB()
setMovieList(res)
} catch (error) {
catchErrors(error, setError)
}
}
async function getTheater() {
try {
setError("")
const res = await theaterApi.getAll()
setTheaterList(res)
} catch (error) {
catchErrors(error, setError)
}
}
function getDate(string) {
const arr = string.split(':')
const date = new Date(0, 0, 0, Number(arr[0]), Number(arr[1]))
return date
}
function addRunTime(start, runTime) {
const startArr = start.split(':')
const add = Number(startArr[1]) + runTime
let hours = Number(startArr[0]) + Math.floor(add / 60)
if (Math.floor(hours / 24) > 0) hours = '0' + hours % 24
else if (hours <= 9) hours = '0' + hours
let mins = add % 60
if (mins <= 9) mins = '0' + mins
setSelectInfo({ ...selectInfo, "start": start, "end": hours + ':' + mins })
}
function addData() {
const { list } = showTimes
const isSelect = Object.values(selectInfo).every((el) => Boolean(el))
if (isSelect) {
const isTime = list.find(el => el.theaterTypeId === selectInfo.theater && (getDate(el.start) <= getDate(selectInfo.end) && getDate(el.end) >= getDate(selectInfo.start)))
if (isTime) alert('이미 추가한 상영시간대입니다. 다른 시간대를 골라주시기 바랍니다.')
else {
const theater = theaterList.find(theater => theater.theatertypeId === selectInfo.theater)
if (theater) {
const myTime = {
theaterTypeId: selectInfo.theater,
theaterName: theater.theaterName + '관 / ' + theater.theatertype.theaterTypeName,
start: selectInfo.start,
end: selectInfo.end
}
setShowTimes({ list: list.concat(myTime) })
} else alert('선택한 상영관을 찾지 못했습니다. 다시 시도하길 바랍니다.')
}
} else alert('추가할 데이터의 갯수가 부족합니다. 모든 항목을 입력해주시길 바랍니다.')
setSelectInfo({ ...selectInfo, ...INIT_INFO })
}
function delData(index) {
let { list } = showTimes
list.splice(index, 1)
setShowTimes({ list: list })
}
async function handleChange(e) {
try {
setError("")
const { name, value } = e.target
if (name === "movieId") {
setSelectId(value)
const res = await movieApi.getMovieInfofromTM(value)
setSelectMovie({ ...res })
setInfo({ ...info, end_date: "" })
} else if (name === "end_date") {
setInfo({ ...info, [name]: value })
} else if (name === "theater") {
setSelectInfo({ ...selectInfo, [name]: Number(value) })
} else if (name === "start") {
addRunTime(value, selectMovie.runtime)
} else setSelectInfo({ ...selectInfo, [name]: value })
} catch (error) {
catchErrors(error, setError)
}
}
async function handleSubmit(e) {
e.preventDefault()
const timeArr = []
try {
setError("")
showTimes.list.map(time => {
timeArr.push({ theater: time.theaterTypeId, start: time.start, end: time.end })
})
const sendData = {
movieId: selectMovie.id,
title: selectMovie.title,
release_date: selectMovie.release_date,
runtime: selectMovie.runtime,
theater: timeArr,
date: info.end_date
}
await timetableApi.submit(sendData)
alert("해당 상영시간표 정보 등록이 성공적으로 완료되었습니다.")
window.location.reload()
} catch (error) {
catchErrors(error, setError)
}
}
return (
<form className="col-6" onSubmit={handleSubmit}>
<select className={`form-select mb-3 ${styles.shadowNone} ${styles.selectInput}`} id="movieId" name="movieId" value={selectId} onChange={handleChange} aria-label="select movie" defaultValue="0">
{movieList.length !== 0 ?
movieList.map((movie, index) => {
if (index === 0) return <>
<option value="0" disabled>영화를 선택해주십시오.</option>
<option value={movie.movieId}>{movie.title}</option>
</>
else return <option value={movie.movieId}>{movie.title}</option>
})
: <option value="0" disabled>서버에 등록된 영화가 없습니다.</option>}
</select>
<div className="col-md-6 mb-3">
<label htmlFor="release_date" className="form-label">상영시작일</label>
<input type="text" className={`form-control ${styles.shadowNone}`} id="release_date" name="release_date" value={selectMovie?.release_date || ''} disabled />
</div>
<div className="col-md-6 mb-3">
<label htmlFor="end_date" className="form-label">상영종료일</label>
<input type="date" className={`form-control ${styles.shadowNone}`} id="end_date" name="end_date" value={info.end_date} min={selectMovie.release_date} onChange={handleChange} />
</div>
<p>시간대 설정</p>
<ul className="list-group list-group-flush">
{showTimes.list.length !== 0 ?
showTimes.list.map((timeInfo, index) => <li className="list-group-item d-flex justify-content-between align-items-center">
{timeInfo.theaterName}&nbsp;&nbsp;&nbsp;{timeInfo.start} ~ {timeInfo.end}
<button type="button" className="btn btn-danger" onClick={() => delData(index)}>삭제</button>
</li>) : <li className="list-group-item text-center">추가된 시간대가 없습니다. 폼을 작성해 시간대를 추가해 주세요.</li>}
</ul>
<div>
<div>
<select className={`form-select mb-3 ${styles.shadowNone} ${styles.selectInput}`} id="theater" name="theater" value={selectInfo.theater} onChange={handleChange} aria-label="select theater" defaultValue="0">
{theaterList.length !== 0 ?
theaterList.map((theater, index) => {
if (index === 0) return <>
<option value="0" disabled>상영관을 선택해주십시오.</option>
<option value={theater.theatertypeId}>{theater.theaterName} / {theater.theatertype.theaterTypeName}</option>
</>
else return <option value={theater.theatertypeId}>{theater.theaterName} / {theater.theatertype.theaterTypeName}</option>
})
: <option value="0" disabled>서버에 등록된 상영관이 없습니다.</option>}
</select>
</div>
<div>
<input type="time" id="start" name="start" value={selectInfo.start} onChange={handleChange} disabled={!selectId || !selectInfo.theater} />
<p>{(selectId && selectInfo.start !== "") ? "~ " + selectInfo.end : ""}</p>
</div>
<div>
<button type="button" className={`btn btn-dark ${styles.customBtn}`} onClick={addData}>추가</button>
</div>
</div>
<div>
<button type="submit" className={`btn btn-dark ${styles.customBtn}`}>등록</button>
</div>
</form>
)
}
export default TimeTableEditForm
\ No newline at end of file
import {useState} from 'react' const CountButton = ({name, count, setCount}) => {
const CountButton = (props) => {
const name = props.name
function handleCount(event) { function handleCount(event) {
if (event.target.name === "backbutton") { if (event.target.name === "backbutton") {
props.setCount({...props.count, [name] :props.count[name] - 1}) setCount({...count, [name] :count[name] - 1})
} else if (event.target.name === "forwardbutton") { } else if (event.target.name === "forwardbutton") {
props.setCount({...props.count, [name] :props.count[name] + 1}) setCount({...count, [name] :count[name] + 1})
} else { } else {
props.setCount({...props.count, [name] :event.target.value}) setCount({...count, [name] :event.target.value})
} }
} }
return ( return (
<div className=""> <>
<button type="button" name="backbutton" style={{ backgroundColor: "black", border: "0" }} onClick={handleCount}> <button type="button" name="backbutton" style={{ backgroundColor: "black", border: "0" }} onClick={handleCount}>
<img src="/images/icons8-back-24.png" name="backbutton" alt="<" /> <img src="/images/icons8-back-24.png" name="backbutton" alt="<" />
</button> </button>
<input type='number' onChange={handleCount} value={props.count[name]} style={{ width: '2rem' }} className="text-center" /> <input type='number' onChange={handleCount} value={count[name]} style={{ width: '2rem' }} className="text-center" />
<button type="button" name="forwardbutton" min="0" style={{ backgroundColor: "black", border: "0" }} onClick={handleCount}> <button type="button" name="forwardbutton" min="0" style={{ backgroundColor: "black", border: "0" }} onClick={handleCount}>
<img src="/images/icons8-forward-24.png" name="forwardbutton" alt=">" /> <img src="/images/icons8-forward-24.png" name="forwardbutton" alt=">" />
</button> </button>
</div> </>
) )
} }
......
import axios from 'axios'
const Kakaopay = (props) => {
async function handleClick() {
try {
const response = await axios.post('/api/kakaopay/test/single', {
cid: 'TC0ONETIME',
partner_order_id: 'orderNum',
partner_user_id: 'userName',
item_name: props.ticketInfo.title,
quantity: props.ticketInfo.teenager+props.ticketInfo.adult+props.ticketInfo.elderly,
total_amount: props.ticketInfo.teenager * 7000 + props.ticketInfo.adult * 8000 + props.ticketInfo.elderly * 6000,
vat_amount: 0,
tax_free_amount: 0,
approval_url: 'http://localhost:3000/',
fail_url: 'http://localhost:3000/',
cancel_url: 'http://localhost:3000/',
})
console.log(response.data)
if (response.data) {
window.location.href = response.data.redirect_url
}
} catch (error) {
console.log(error)
}
}
return (
<>
<button onClick={handleClick} style={{ backgroundColor: "black", border: '0' }}>
<img src="/images/payment_icon_yellow_medium.png" />
</button>
</>
)
}
export default Kakaopay
\ No newline at end of file
...@@ -104,7 +104,6 @@ const Login = () => { ...@@ -104,7 +104,6 @@ const Login = () => {
<input className={styles.input} type="number" name="gusetBirthday" id="gusetBirthday" placeholder="생년월일" onChange={handleGuestOnChange} maxLength="6" required /> <input className={styles.input} type="number" name="gusetBirthday" id="gusetBirthday" placeholder="생년월일" onChange={handleGuestOnChange} maxLength="6" required />
<input className={styles.input} type="number" name="gusetMbnum" id="gusetMbnum" placeholder="휴대폰 번호" onChange={handleGuestOnChange} maxLength="11" required /> <input className={styles.input} type="number" name="gusetMbnum" id="gusetMbnum" placeholder="휴대폰 번호" onChange={handleGuestOnChange} maxLength="11" required />
<input className={styles.input} type="password" name="guestPassword" id="password" placeholder="비밀번호" onChange={handleGuestOnChange} maxLength="11" required /> <input className={styles.input} type="password" name="guestPassword" id="password" placeholder="비밀번호" onChange={handleGuestOnChange} maxLength="11" required />
<p className={`text-white ${styles.fontSizeTwo}`}> <p className={`text-white ${styles.fontSizeTwo}`}>
비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다. 비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다.
</p> </p>
......
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