Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
students
butter-studio
Commits
3916c374
Commit
3916c374
authored
Aug 11, 2021
by
Kim, Subin
Browse files
Merge branch 'master' into kimpen
parents
eb9bcd78
52c103b2
Changes
23
Show whitespace changes
Inline
Side-by-side
client/public/images/moon.svg
0 → 100644
View file @
3916c374
<svg
width=
"97"
height=
"97"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
overflow=
"hidden"
><defs><clipPath
id=
"clip0"
><rect
x=
"201"
y=
"119"
width=
"97"
height=
"97"
/></clipPath></defs><g
clip-path=
"url(#clip0)"
transform=
"translate(-201 -119)"
><path
d=
"M248.49 131.63C244.751 129.811 240.911 128.599 237.072 128.094 248.186 139.107 251.521 156.385 244.145 171.239 236.87 186.092 220.905 193.771 205.547 191.649 208.275 194.377 211.609 196.802 215.247 198.621 233.738 207.816 256.169 200.237 265.263 181.747 274.356 163.256 266.98 140.926 248.49 131.63Z"
fill=
"#4472C4"
/><path
d=
"M288.805 174.068C288.603 173.765 288.603 173.36 288.805 173.057L290.725 170.228C290.927 169.824 290.927 169.42 290.725 169.117 290.523 168.814 290.018 168.611 289.715 168.712L286.582 169.521C286.178 169.622 285.774 169.42 285.572 169.117L283.652 166.288C283.349 165.883 282.945 165.782 282.541 165.883 282.136 165.984 281.833 166.389 281.833 166.793L281.631 170.228C281.631 170.632 281.328 170.935 280.924 171.137L277.792 171.845C277.388 171.946 277.084 172.249 277.084 172.754 277.084 173.158 277.286 173.562 277.691 173.664L279.004 174.371 280.722 175.28C280.823 175.381 281.025 175.482 281.126 175.684 281.227 175.886 281.227 175.988 281.227 176.19L281.227 179.625C281.227 180.029 281.429 180.433 281.833 180.534 282.237 180.635 282.642 180.534 282.945 180.231L285.168 177.503C285.471 177.2 285.875 177.099 286.279 177.2L289.614 178.413C290.018 178.514 290.422 178.413 290.725 178.109 291.028 177.806 291.028 177.301 290.826 176.998L288.805 174.068Z"
fill=
"#4472C4"
/><path
d=
"M279.206 148.908 281.934 143.957C282.237 143.351 282.844 143.048 283.551 143.149L289.108 144.058C289.816 144.159 290.422 143.856 290.725 143.25 291.028 142.644 290.927 141.835 290.523 141.431L286.683 137.289C286.279 136.884 286.178 136.177 286.38 135.571L288.502 130.418C288.704 129.811 288.603 129.104 288.199 128.7 287.795 128.296 286.986 128.094 286.481 128.397L281.732 130.721C281.126 131.024 280.419 130.822 280.015 130.418L276.175 126.578C275.67 126.073 274.861 125.972 274.255 126.174 273.649 126.477 273.346 127.184 273.346 127.791L274.053 133.146C274.154 133.853 273.851 134.459 273.245 134.762L268.496 137.086C267.89 137.39 267.586 137.996 267.688 138.703 267.789 139.309 268.294 139.916 268.9 140.017L271.224 140.724 274.255 141.633C274.558 141.734 274.76 141.936 275.064 142.139 275.266 142.341 275.367 142.644 275.468 142.947L276.377 148.504C276.478 149.211 276.983 149.717 277.691 149.818 278.398 149.919 278.903 149.515 279.206 148.908Z"
fill=
"#4472C4"
/></g></svg>
\ No newline at end of file
client/public/images/sun.svg
0 → 100644
View file @
3916c374
<svg
width=
"114"
height=
"115"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
overflow=
"hidden"
><defs><clipPath
id=
"clip0"
><rect
x=
"108"
y=
"110"
width=
"114"
height=
"115"
/></clipPath></defs><g
clip-path=
"url(#clip0)"
transform=
"translate(-108 -110)"
><path
d=
"M33.4246 56.9691C33.4286 56.0641 33.4845 55.1602 33.592 54.2616L19.4263 54.2616 19.4263 59.6054 33.5813 59.6054C33.4799 58.7302 33.4275 57.8501 33.4246 56.9691Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M42.3569 38.5379 32.3131 28.5 28.5344 32.2774 38.5736 42.3166C39.6887 40.9189 40.9578 39.6513 42.3569 38.5379Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M56.9739 33.4198C57.8669 33.4235 58.7589 33.4779 59.6458 33.5825L59.6458 19.3871 54.302 19.3871 54.302 33.5825C55.1888 33.4778 56.0809 33.4235 56.9739 33.4198Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M75.373 42.3118 85.4121 32.2727 81.6335 28.5 71.5896 38.5427C72.9887 39.6524 74.2579 40.9169 75.373 42.3118Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M38.5439 71.5861 28.5344 81.5931 32.3131 85.3717 42.3166 75.3694C40.9207 74.2544 39.655 72.9852 38.5439 71.5861Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M56.9739 80.5184C56.0809 80.5148 55.1888 80.4605 54.302 80.3558L54.302 94.4799 59.6458 94.4799 59.6458 80.3558C58.7589 80.4604 57.8669 80.5146 56.9739 80.5184Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M80.3546 54.2616C80.5758 56.0358 80.5794 57.8303 80.3652 59.6054L94.525 59.6054 94.525 54.2616Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M71.63 75.3694 81.6335 85.3717 85.4121 81.5931 75.4062 71.5861C74.2939 72.9853 73.0272 74.2545 71.63 75.3694Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/><path
d=
"M75.7732 56.9691C75.7732 67.3524 67.3559 75.7696 56.9727 75.7696 46.5894 75.7696 38.1722 67.3524 38.1722 56.9691 38.1722 46.5859 46.5894 38.1686 56.9727 38.1686 56.973 38.1686 56.9735 38.1686 56.9739 38.1686 67.3564 38.1686 75.7732 46.5854 75.7732 56.9679 75.7732 56.9683 75.7732 56.9688 75.7732 56.9691Z"
fill=
"#FFC000"
transform=
"matrix(1 0 0 1.00877 108 110)"
/></g></svg>
\ No newline at end of file
client/src/App.js
View file @
3916c374
...
...
@@ -15,8 +15,9 @@ import AdminPage from "./pages/AdminPage/AdminPage";
import
TicketingPage
from
"
./pages/TicketingPage
"
;
import
TicketingSeatPage
from
'
./pages/TicketingSeatPage
'
import
SearchPage
from
"
./pages/SearchPage
"
;
import
Payment
from
"
./pages/PaymentPage/PaymentPage
"
;
import
Payment
Page
from
"
./pages/PaymentPage/PaymentPage
"
;
import
PaymentCompletePage
from
"
./pages/PaymentCompletePage
"
;
import
PaymentFailPage
from
"
./pages/PaymentFailPage
"
;
function
App
()
{
...
...
@@ -39,9 +40,10 @@ function App() {
<
Route
path
=
"
/guest
"
component
=
{
GuestPage
}
/
>
<
Route
path
=
"
/ticket/seat
"
component
=
{
TicketingSeatPage
}
/
>
<
Route
path
=
"
/ticket
"
component
=
{
TicketingPage
}
/
>
<
Route
path
=
"
/payment
"
component
=
{
Payment
}
/
>
<
Route
path
=
"
/payment
"
component
=
{
Payment
Page
}
/
>
<
Route
path
=
"
/paymentcomplete
"
component
=
{
PaymentCompletePage
}
/
>
<
Route
path
=
"
/theater
"
component
=
{
TheaterPage
}
/
>
<
Route
path
=
"
/paymentfail
"
component
=
{
PaymentFailPage
}
/
>
<
Route
path
=
"
/theater
"
component
=
{
TheaterPage
}
/
>
<
Route
path
=
"
/search
"
component
=
{
SearchPage
}
/
>
<
/Switch
>
<
/div
>
...
...
client/src/apis/kakaopay.api.js
0 → 100644
View file @
3916c374
import
axios
from
"
axios
"
;
import
{
baseUrl
}
from
"
../utils/baseUrl.js
"
;
const
approveReq
=
async
(
info
)
=>
{
const
url
=
`
${
baseUrl
}
/api/kakaopay/test/single`
;
const
{
data
}
=
await
axios
.
post
(
url
,
info
);
return
data
}
const
approveSuccess
=
async
(
info
)
=>
{
const
url
=
`
${
baseUrl
}
/api/kakaopay/success`
;
const
{
data
}
=
await
axios
.
post
(
url
,
info
);
return
data
}
const
paymentCancel
=
async
(
info
)
=>
{
const
url
=
`
${
baseUrl
}
/api/kakaopay/cancel`
;
const
{
data
}
=
await
axios
.
post
(
url
,
info
);
return
data
}
const
kakaopayApi
=
{
approveReq
,
approveSuccess
,
paymentCancel
}
export
default
kakaopayApi
\ No newline at end of file
client/src/apis/reservation.api.js
View file @
3916c374
...
...
@@ -4,7 +4,7 @@ import { baseUrl } from "../utils/baseUrl.js";
const
findReservedSeats
=
async
(
timeTable
)
=>
{
console
.
log
(
timeTable
)
const
url
=
`
${
baseUrl
}
/api/reservation/findreservation`
;
const
{
data
}
=
await
axios
.
post
(
url
,
{
timeTable
:
timeTable
});
const
{
data
}
=
await
axios
.
post
(
url
,
{
timeTable
:
timeTable
});
return
data
}
...
...
@@ -25,12 +25,26 @@ const save = async (save) => {
const
url
=
`
${
baseUrl
}
/api/reservation/save`
;
const
{
data
}
=
await
axios
.
post
(
url
,
save
);
return
data
}
const
saveTid
=
async
(
tid
)
=>
{
const
url
=
`
${
baseUrl
}
/api/reservation/savetid`
;
const
{
data
}
=
await
axios
.
post
(
url
,
tid
);
return
data
}
const
deleteReservation
=
async
()
=>
{
const
url
=
`
${
baseUrl
}
/api/reservation/delete`
;
const
{
data
}
=
await
axios
.
get
(
url
);
return
data
}
const
reservationApi
=
{
findReservation
,
findReservedSeats
,
findOneReservation
,
save
save
,
saveTid
,
deleteReservation
}
export
default
reservationApi
\ No newline at end of file
client/src/components/Admin/TimeTable.js
View file @
3916c374
...
...
@@ -51,7 +51,10 @@ const TimeTable = ({ ticketInfo = { movieId: 0 }, setTicketInfo }) => {
...
ticketInfo
,
timetableId
:
time
.
id
,
time
:
time
.
date
.
split
(
'
T
'
)[
0
]
+
"
"
+
hours
+
"
:
"
+
mins
,
selectedTheater
:
time
.
theater
.
theaterName
selectedTheater
:
time
.
theater
.
theaterName
,
theaterId
:
time
.
theaterId
,
partTime
:
time
.
partTime
,
week
:
time
.
week
})
}
...
...
@@ -65,7 +68,7 @@ const TimeTable = ({ ticketInfo = { movieId: 0 }, setTicketInfo }) => {
if
(
ticketInfo
.
movieId
!==
0
)
return
<
div
className
=
"
d-inline-flex m-2
"
>
<
div
className
=
{
`card text-dark
${
styles
.
cursor
}
`
}
onClick
=
{()
=>
handleClick
(
time
)}
>
<
div
className
=
"
card-body py-1
"
>
{
moment
(
time
.
start_time
).
format
(
'
HH:mm
'
)}
~
{
moment
(
time
.
end_time
).
format
(
'
HH:mm
'
)}
<
/div
>
<
div
className
=
"
card-body py-1
"
>
<
img
src
=
{
`
${
time
.
partTime
===
"
morning
"
?
'
/images/sun.svg
'
:
time
.
partTime
===
"
night
"
?
'
/images/moon.svg
'
:
'
...
'
}
`
}
style
=
{{
width
:
'
20px
'
}}
alt
=
""
/>
{
moment
(
time
.
start_time
).
format
(
'
HH:mm
'
)}
~
{
moment
(
time
.
end_time
).
format
(
'
HH:mm
'
)}
<
/div
>
<
div
className
=
"
card-footer text-center py-1
"
>
{
time
.
theater
.
rows
*
time
.
theater
.
columns
-
time
.
reservations
}
/ {time.theater.rows * time.theater.columns}</
div
>
<
/div
>
<
/div
>
...
...
@@ -80,7 +83,9 @@ const TimeTable = ({ ticketInfo = { movieId: 0 }, setTicketInfo }) => {
<
/div
>
})}
<
/div>
)
:
<
p
className
=
"
text-center mt-5 mb-0
"
>
서버에
저장되어
있는
상영시간표가
존재하지
않습니다
.
<
br
/>
아래의
양식을
작성해
새로운
상영시간표를
등록해주세요
.
<
/p>
}
:
<
p
className
=
"
text-center mt-5 mb-0
"
>
서버에
저장되어
있는
상영시간표가
존재하지
않습니다
.
{
/* <br />아래의 양식을 작성해 새로운 상영시간표를 등록해주세요. */
}
<
/p>
}
<
/
>
)
}
...
...
client/src/components/BoxOffice/BoxOffice.js
View file @
3916c374
import
{
useState
,
useEffect
}
from
"
react
"
import
{
Link
}
from
"
react
-router-dom
"
const
BoxOffice
=
({
TMDB_TopRated_Data
})
=>
{
const
BoxOffice
=
({
TMDB_TopRated_Data
})
=>
{
return
(
<
div
className
=
"
container text-center my-3
"
>
{
/* <div id="carouselExampleControls" className="carousel slide" data-bs-ride="carousel">
<
h2
className
=
"
fw-bold text-white text-center my-5
"
>
BoxOffice
<
/h2
>
{
console
.
log
(
TMDB_TopRated_Data
)}
<
div
id
=
"
carouselExampleControls
"
className
=
"
carousel slide
"
data
-
bs
-
ride
=
"
carousel
"
>
<
div
className
=
"
carousel-inner
"
>
{TMDB_TopRated_Data.length
>
0
{
TMDB_TopRated_Data
.
length
>
0
?
TMDB_TopRated_Data.map((movie, index) => {
<div className={`carousel-item ${index === 0 ? "active" : ""}`}>
{console.log(movie.poster_path)}
<img src={`https://image.tmdb.org/t/p/original${movie.poster_path}`} className="d-block w-100" alt="Movie Poster"/>
TMDB_TopRated_Data
.
map
((
movie
,
index
)
=>
<
div
className
=
{
`carousel-item
${
index
===
0
?
"
active
"
:
""
}
`
}
>
<
Link
to
=
{{
pathname
:
`/movie/
${
movie
.
id
}
`
,
state
:
{
...
movie
}
}}
>
<
img
src
=
{
`https://image.tmdb.org/t/p/original
${
movie
.
poster_path
}
`
}
style
=
{{
width
:
"
200px
"
}}
className
=
""
alt
=
"
Movie Poster
"
/>
<
/Link
>
<
div
className
=
"
mt-1 text-white
"
>
{
index
+
1
}
위
<
/div
>
<
/div
>
}
)
)
:
<
div
className
=
"
carousel-item
"
>
{
console
.
log
(
"
스틸컷 불러오기 오류
"
)}
...
...
@@ -29,7 +40,7 @@ const BoxOffice = ({TMDB_TopRated_Data}) => {
<
span
className
=
"
carousel-control-next-icon
"
aria
-
hidden
=
"
true
"
><
/span
>
<
span
className
=
"
visually-hidden
"
>
Next
<
/span
>
<
/button
>
</div>
*/
}
<
/div
>
<
/div
>
)
...
...
client/src/components/Collection.js
View file @
3916c374
...
...
@@ -23,25 +23,24 @@ const Collection = ({ TMDB_TopRated_Data }) => {
return
(
<>
<
h2
className
=
"
fw-bold text-white text-center my-5
"
>
Movie
Collection
<
/h2
>
<
div
className
=
"
d-flex
justify-content-sm-center
"
style
=
{{
marginBottom
:
"
8rem
"
}}
>
<
div
className
=
"
col-m
d
-8
"
>
<
div
className
=
"
row
justify-content-sm-center
"
style
=
{{
marginBottom
:
"
8rem
"
}}
>
<
div
className
=
"
col-
s
m-8
"
>
{
videoUrls
.
length
>
0
?
<
div
className
=
""
>
<
div
className
=
"
ratio ratio-16x9
"
>
<
iframe
src
=
{
`https://www.youtube.com/embed/
${
videoUrls
[
0
].
key
}
`
}
title
=
"
YouTube video
"
allowFullScreen
><
/iframe
>
<
/div
>
<
/div
>
:
<
div
className
=
"
text-center
"
>
예고편
정보가
존재하지
않습니다
.
<
/div>
}
<
/div
>
<
div
className
=
"
col-sm-3
"
>
{
TMDB_TopRated_Data
.
length
>
0
?
<
img
src
=
{
`https://image.tmdb.org/t/p/original
${
TMDB_TopRated_Data
[
0
].
poster_path
}
`
}
className
=
"
col-md-3
bg-black
"
/>
<
img
src
=
{
`https://image.tmdb.org/t/p/original
${
TMDB_TopRated_Data
[
0
].
poster_path
}
`
}
className
=
"
img-fluid
bg-black
"
/>
:
<
div
className
=
"
col-md-3
"
><
/div
>
<
div
><
/div
>
}
<
/div
>
<
/div
>
<
/
>
)
}
...
...
client/src/components/KakaopaymentCancelBtn.js
0 → 100644
View file @
3916c374
import
kakaopayApi
from
"
../apis/kakaopay.api
"
import
catchErrors
from
"
../utils/catchErrors
"
const
KakaopaymentCancelBtn
=
()
=>
{
const
[
error
,
setError
]
=
useState
()
async
function
paymentCancel
()
{
try
{
setError
(
""
)
//실행하기 전에 먼저 reservation에서 해당하는 예매건에 대한 tid가져오기
const
response
=
await
kakaopayApi
.
paymentCancel
({
cid
:
'
TC0ONETIME
'
,
tid
:
''
,
cancel_amount
:
''
,
cancel_tax_free_amount
:
0
,
})
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
return
(
<
button
className
=
"
btn btn-warning
"
onClick
=
{
paymentCancel
}
>
결제취소
<
/button
>
)
}
\ No newline at end of file
client/src/components/TheaterInfo.js
View file @
3916c374
...
...
@@ -53,12 +53,14 @@ const TheaterInfo = () => {
try
{
const
response
=
await
cinemaApi
.
getCinemaInfo
()
const
response2
=
await
theaterApi
.
getAll
()
setCinemaInfo
({
...
response
.
data
,
theaterNum
:
response2
.
data
.
length
})
if
(
response
&&
response2
)
{
setCinemaInfo
({
...
response
,
theaterNum
:
response2
.
length
})
setCurrentInfo
({
name
:
"
대중교통 안내
"
,
title
:
"
transportation
"
,
information
:
response
.
data
.
transportation
information
:
response
.
transportation
})
}
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
...
...
@@ -75,7 +77,7 @@ const TheaterInfo = () => {
return
(
<>
{
cinemaInfo
?
<
div
>
<
div
>
<
h2
className
=
"
m-5
"
>
{
cinemaInfo
.
cinemaName
}
<
/h2
>
<
div
className
=
"
my-3 text-center
"
>
<
img
src
=
"
/images/movieTheater.jpg
"
style
=
{{
width
:
"
80%
"
}}
/
>
...
...
@@ -111,7 +113,7 @@ const TheaterInfo = () => {
<
div
id
=
"
map
"
><
/div
>
<
/div
>
:
<
div
>
<
div
className
=
"
pb-5
"
>
극장정보를
불러올
수
없습니다
.
<
/div>
}
<
/
>
...
...
client/src/components/TicketingTheater/TicketingTheater.js
View file @
3916c374
...
...
@@ -8,7 +8,12 @@ const TicketingTheater = ({ ticketInfo, cinemaInfo, setTicketInfo }) => {
return
(
<
div
className
=
"
d-grid gap-2
"
>
{
cinemaInfo
?
<
button
name
=
{
cinemaInfo
.
cinemaName
}
className
=
{
`
${
ticketInfo
.
cinema
===
cinemaInfo
.
cinemaName
?
styles
.
on
:
styles
.
btn
}
`
}
onClick
=
{
handleClick
}
>
{
cinemaInfo
.
cinemaName
}
<
/button
>
:
<><
/
>
}
<
/div
>
)
}
...
...
client/src/pages/MoviePage.js
View file @
3916c374
...
...
@@ -66,7 +66,7 @@ const MoviePage = ({ location }) => {
<
/div
>
<
div
className
=
"
col-sm-6
"
style
=
{{
color
:
"
white
"
}}
>
<
h1
className
=
"
pb-3
"
>
{
movieInfo
.
title
}
<
/h1
>
<
p
>
예매율
:{
Math
.
round
((
movieInfo
.
ticket_sales
/
(
movieInfo
.
totalReservationRate
.
totalReservationRate
||
1
))
*
100
)}
%
누적관객수
:
{
movieInfo
.
ticket_sales
}
명
<
/p
>
<
p
>
예매율
:
{
Math
.
round
((
movieInfo
.
ticket_sales
/
(
movieInfo
.
totalReservationRate
.
totalReservationRate
||
1
))
*
100
)}
%<
/p
>
{
movieInfo
.
director
||
movieInfo
.
cast
?
<>
...
...
@@ -80,7 +80,7 @@ const MoviePage = ({ location }) => {
if
(
idx
!==
0
)
return
acc
+
'
,
'
+
cur
.
name
else
return
acc
+
cur
.
name
},
""
)}
<
/p
>
<
p
>
개봉일
:{
movieInfo
.
release_date
}
<
/p
>
<
p
>
개봉일
:
{
movieInfo
.
release_date
}
<
/p
>
<
div
className
=
"
text-end
"
>
<
Link
to
=
{{
pathname
:
`/ticket`
,
...
...
@@ -101,9 +101,9 @@ const MoviePage = ({ location }) => {
<
li
className
=
"
nav-item
"
role
=
"
presentation
"
>
<
button
className
=
"
nav-link mx-auto
"
style
=
{{
color
:
"
white
"
,
borderColor
:
"
black
"
,
backgroundColor
:
"
black
"
,
borderBottom
:
state
===
1
?
"
3px solid
"
:
"
none
"
,
borderBottomColor
:
state
===
1
?
"
#FEDC00
"
:
"
black
"
}}
id
=
"
stillcut-tab
"
data
-
bs
-
toggle
=
"
tab
"
data
-
bs
-
target
=
"
#stillcut
"
type
=
"
button
"
role
=
"
tab
"
aria
-
controls
=
"
stillcut
"
aria
-
selected
=
"
false
"
onClick
=
{()
=>
setState
(
1
)}
>
예고편
<
/button
>
<
/li
>
<
li
className
=
"
nav-item
"
role
=
"
presentation
"
>
{
/*
<li className="nav-item" role="presentation">
<button className="nav-link mx-auto" style={{ color: "white", borderColor: "black", backgroundColor: "black", borderBottom: state === 2 ? "3px solid" : "none", borderBottomColor: state === 2 ? "#FEDC00" : "black" }} id="review-tab" data-bs-toggle="tab" data-bs-target="#review" type="button" role="tab" aria-controls="review" aria-selected="false" onClick={() => setState(2)}>관람평</button>
<
/li
>
</li>
*/
}
<
/ul
>
<
/div
>
<
div
className
=
"
tab-content text-center
"
id
=
"
myTabContent
"
style
=
{{
color
:
"
white
"
}}
>
...
...
@@ -113,9 +113,9 @@ const MoviePage = ({ location }) => {
<
div
className
=
"
tab-pane fade
"
id
=
"
stillcut
"
role
=
"
tabpanel
"
aria
-
labelledby
=
"
stillcut-tab
"
>
<
Video
movieId
=
{
movieInfo
.
id
}
/
>
<
/div
>
<
div
className
=
"
tab-pane fade
"
id
=
"
review
"
role
=
"
tabpanel
"
aria
-
labelledby
=
"
review-tab
"
>
{
/*
<div className="tab-pane fade" id="review" role="tabpanel" aria-labelledby="review-tab">
<div className="mt-5 pb-5 px-5">관람평</div>
<
/div
>
</div>
*/
}
<
/div
>
<
/div
>
...
...
client/src/pages/PaymentCompletePage.js
View file @
3916c374
import
axios
from
'
axios
'
import
{
useEffect
,
useState
}
from
'
react
'
import
axios
from
'
axios
'
import
moment
from
'
moment
'
;
import
{
useAuth
}
from
'
../context/auth_context
'
import
catchErrors
from
'
../utils/catchErrors
'
import
reservationApi
from
'
../apis/reservation.api
'
import
kakaopayApi
from
'
../apis/kakaopay.api
'
;
const
PaymentCompletePage
=
()
=>
{
const
{
user
}
=
useAuth
()
...
...
@@ -24,20 +26,21 @@ const PaymentCompletePage = () => {
async
function
saveGuestReservation
()
{
try
{
setError
(
""
)
const
response
=
await
axios
.
get
(
`/api/auth/guestinfo/
${
user
.
id
}
`
);
const
response2
=
await
reservationApi
.
findOneReservation
()
cons
ole
.
log
(
"
예매내역=====
"
,
response2
)
//
if (response.data||response2) {
//
const responseEmail = await axios.post('/api/email/send', {
//
reservationData: response2,
//
userData: { ...response.data },
//
cinema: "Butter Studio 조치원",
//
title:
"더 수어사이드 스쿼드"
,
//
theater:
"1"
,
//
time:
"2021/07/21 10:00"
//
})
//
console.log(responseEmail.data
)
//
}
cons
t
response3
=
await
reservationApi
.
saveTid
({
tid
:
localStorage
.
getItem
(
'
tid
'
)}
)
if
(
response
.
data
||
response2
)
{
const
responseEmail
=
await
axios
.
post
(
'
/api/email/send
'
,
{
reservationData
:
response2
.
map
(
el
=>
{
return
{
"
row
"
:
el
.
row
,
"
col
"
:
el
.
col
}
})
,
userData
:
{
...
response
.
data
},
cinema
:
"
Butter Studio 조치원
"
,
title
:
response2
[
0
].
title
,
theater
:
response2
[
0
].
theater
.
theaterName
,
time
:
response2
[
0
].
timetable
.
date
.
split
(
'
T
'
)[
0
]
+
'
'
+
moment
(
response2
[
0
].
timetable
.
start_time
).
format
(
'
HH:mm
'
)
})
localStorage
.
removeItem
(
'
tid
'
)
}
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
...
...
@@ -45,18 +48,23 @@ const PaymentCompletePage = () => {
async
function
saveUserReservation
()
{
try
{
setError
(
""
)
const
response
=
await
axios
.
post
(
`/api/auth/getuserinfo`
,
{
id
:
user
.
id
})
// if (response.data) {
// const responseEmail = await axios.post('/api/email/send', {
// ...response2.data,
// ...response.data,
// })
// console.log(responseEmail.data)
// }
const
response2
=
await
reservationApi
.
findOneReservation
()
const
response3
=
await
reservationApi
.
saveTid
({
tid
:
localStorage
.
getItem
(
'
tid
'
)})
if
(
response
.
data
||
response2
)
{
const
responseEmail
=
await
axios
.
post
(
'
/api/email/send
'
,
{
reservationData
:
response2
.
map
(
el
=>
{
return
{
"
row
"
:
el
.
row
,
"
col
"
:
el
.
col
}
}),
userData
:
{
...
response
.
data
},
cinema
:
"
Butter Studio 조치원
"
,
title
:
response2
[
0
].
title
,
theater
:
response2
[
0
].
theater
.
theaterName
,
time
:
response2
[
0
].
timetable
.
date
.
split
(
'
T
'
)[
0
]
+
'
'
+
moment
(
response2
[
0
].
timetable
.
start_time
).
format
(
'
HH:mm
'
)
})
localStorage
.
removeItem
(
'
tid
'
)
}
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
...
...
@@ -64,9 +72,10 @@ const PaymentCompletePage = () => {
async
function
approveKakaopay
(
tid
)
{
try
{
setError
(
""
)
const
urlParams
=
new
URLSearchParams
(
window
.
location
.
search
);
const
pg_token
=
urlParams
.
get
(
'
pg_token
'
);
const
response
=
await
axios
.
post
(
`/api/kakaopay/s
uccess
`
,
{
const
response
=
await
kakaopayApi
.
approveS
uccess
(
{
'
tid
'
:
tid
,
cid
:
'
TC0ONETIME
'
,
partner_order_id
:
'
butter_studio
'
,
...
...
@@ -80,10 +89,18 @@ const PaymentCompletePage = () => {
}
return
(
<
div
className
=
"
text-center
"
>
<
h3
>
예매가
정상적으로
완료되었습니다
.
<
/h3
>
<
button
>
홈으로
<
/button
>
{
user
.
role
===
"
member
"
?
<
button
>
마이페이지
<
/button> : <></
>
}
<
div
className
=
"
container text-center py-5
"
>
<
h3
className
=
"
my-3 text-white
"
>
예매가
정상적으로
완료되었습니다
.
<
/h3
>
{
user
.
role
===
"
member
"
?
<
a
href
=
"
/mypage
"
>
<
button
className
=
"
btn btn-warning mx-1
"
>
마이페이지
<
/button
>
<
/a
>
:
<
a
href
=
"
/
"
>
<
button
className
=
"
btn btn-warning mx-1
"
>
홈으로
<
/button
>
<
/a
>
}
<
/div
>
)
}
...
...
client/src/pages/PaymentFailPage.js
0 → 100644
View file @
3916c374
import
{
useEffect
,
useState
}
from
'
react
'
import
{
useAuth
}
from
'
../context/auth_context
'
import
catchErrors
from
'
../utils/catchErrors
'
import
reservationApi
from
'
../apis/reservation.api
'
const
PaymentCompletePage
=
()
=>
{
const
[
error
,
setError
]
=
useState
()
useEffect
(()
=>
{
deleteReservation
()
},
[])
async
function
deleteReservation
()
{
try
{
const
response
=
await
reservationApi
.
deleteReservation
()
localStorage
.
removeItem
(
'
tid
'
)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
return
(
<
div
className
=
"
container text-center py-5
"
>
<
h3
className
=
"
my-3 text-white
"
>
결제에
실패하셨습니다
.
<
/h3
>
<
a
href
=
"
/ticket
"
>
<
button
className
=
"
btn btn-warning mx-1
"
>
다시
예매하기
<
/button
>
<
/a
>
<
a
href
=
"
/
"
>
<
button
className
=
"
btn btn-warning mx-1
"
>
홈으로
<
/button
>
<
/a
>
<
/div
>
)
}
export
default
PaymentCompletePage
\ No newline at end of file
client/src/pages/PaymentPage/PaymentPage.js
View file @
3916c374
import
axios
from
'
axios
'
import
{
useEffect
,
useState
}
from
'
react
'
import
authApi
from
'
../../apis/auth.api
'
import
kakaopayApi
from
'
../../apis/kakaopay.api
'
import
reservationApi
from
'
../../apis/reservation.api
'
import
{
useAuth
}
from
'
../../context/auth_context
'
import
catchErrors
from
'
../../utils/catchErrors
'
...
...
@@ -73,23 +74,24 @@ const Payment = ({ location }) => {
userType
:
"
member
"
,
user
:
userInfo
.
id
,
...
ticketInfo
,
timetable
:
1
})
const
responsekakao
=
await
axios
.
post
(
'
/api/kakaopay/test/single
'
,
{
const
responsekakao
=
await
kakaopayApi
.
approveReq
(
{
cid
:
'
TC0ONETIME
'
,
partner_order_id
:
'
butter_studio
'
,
partner_user_id
:
'
000000
'
+
(
userInfo
.
id
||
guestInfo
.
id
)
,
partner_user_id
:
'
000000
'
+
guestID
,
item_name
:
ticketInfo
.
title
,
item_code
:
ticketInfo
.
movieId
,
quantity
:
ticketInfo
.
adult
+
ticketInfo
.
youth
+
ticketInfo
.
senior
,
total_amount
:
ticketInfo
.
totalFee
,
vat_amount
:
0
,
tax_free_amount
:
0
,
approval_url
:
'
http://localhost:3000/paymentcomplete
'
,
fail_url
:
'
http://localhost:3000/
ticket
'
,
cancel_url
:
'
http://localhost:3000/
ticket
'
,
fail_url
:
'
http://localhost:3000/
paymentfail
'
,
cancel_url
:
'
http://localhost:3000/
paymentfail
'
,
})
if
(
response
&&
responsekakao
)
{
window
.
location
.
href
=
responsekakao
.
data
.
redirect_url
localStorage
.
setItem
(
'
tid
'
,
responsekakao
.
tid
)
window
.
location
.
href
=
responsekakao
.
redirect_url
}
}
else
{
if
(
guestID
)
{
...
...
@@ -97,12 +99,11 @@ const Payment = ({ location }) => {
userType
:
"
guest
"
,
user
:
guestID
,
...
ticketInfo
,
timetableId
:
1
})
const
responsekakao
=
await
axios
.
post
(
'
/api/kakaopay/test/single
'
,
{
const
responsekakao
=
await
kakaopayApi
.
approveReq
(
{
cid
:
'
TC0ONETIME
'
,
partner_order_id
:
'
butter_studio
'
,
partner_user_id
:
'
000000
'
+
guestID
,
partner_user_id
:
'
000000
'
+
guestID
,
item_name
:
ticketInfo
.
title
,
item_code
:
ticketInfo
.
movieId
,
quantity
:
ticketInfo
.
adult
+
ticketInfo
.
youth
+
ticketInfo
.
senior
,
...
...
@@ -110,12 +111,12 @@ const Payment = ({ location }) => {
vat_amount
:
0
,
tax_free_amount
:
0
,
approval_url
:
'
http://localhost:3000/paymentcomplete
'
,
fail_url
:
'
http://localhost:3000/
ticket
'
,
cancel_url
:
'
http://localhost:3000/
ticket
'
,
fail_url
:
'
http://localhost:3000/
paymentfail
'
,
cancel_url
:
'
http://localhost:3000/
paymentfail
'
,
})
if
(
response
||
responsekakao
)
{
localStorage
.
setItem
(
'
tid
'
,
responsekakao
.
data
.
tid
)
window
.
location
.
href
=
responsekakao
.
data
.
redirect_url
if
(
response
&&
responsekakao
)
{
localStorage
.
setItem
(
'
tid
'
,
responsekakao
.
tid
)
window
.
location
.
href
=
responsekakao
.
redirect_url
}
}
else
{
alert
(
"
비회원 정보를 모두 입력 후 비회원 정보 저장 버튼을 눌러주세요.
"
)
...
...
@@ -129,7 +130,6 @@ const Payment = ({ location }) => {
return
(
<
div
className
=
"
container
"
style
=
{{
color
:
"
white
"
}}
>
{
console
.
log
(
ticketInfo
)}
<
div
className
=
"
row justify-content-center my-5
"
>
<
div
className
=
"
col-sm-4
"
>
<
h3
className
=
"
py-2 text-white text-center
"
style
=
{{
border
:
"
3px solid #000000
"
,
borderBottom
:
"
3px solid #FEDC00
"
}}
>
결제하기
<
/h3
>
...
...
@@ -211,7 +211,7 @@ const Payment = ({ location }) => {
<
h5
className
=
"
my-3
"
>
{
ticketInfo
.
title
}
<
/h5
>
<
div
>
{
ticketInfo
.
cinema
}
<
/div
>
<
div
>
{
ticketInfo
.
time
}
<
/div
>
<
div
className
=
"
mb-3
"
>
{
ticketInfo
.
selectedTheater
}
관
{
ticketInfo
.
selectedSeats
.
map
(
el
=>
String
.
fromCharCode
(
parseInt
(
el
.
split
(
'
-
'
)[
0
])
+
6
5
)
+
el
.
split
(
'
-
'
)[
1
])
+
'
'
}
<
/div
>
<
div
className
=
"
mb-3
"
>
{
ticketInfo
.
selectedTheater
}
관
{
ticketInfo
.
selectedSeats
.
map
(
el
=>
String
.
fromCharCode
(
parseInt
(
el
.
split
(
'
-
'
)[
0
])
+
6
4
)
+
el
.
split
(
'
-
'
)[
1
])
+
'
'
}
<
/div
>
<
div
className
=
"
rounded-3 p-3
"
style
=
{{
backgroundColor
:
'
#404040
'
}}
>
<
div
>
성인
:
{
ticketInfo
.
adult
}
명
<
/div
>
<
div
>
청소년
:
{
ticketInfo
.
youth
}
명
<
/div
>
...
...
client/src/pages/TheaterPage.js
View file @
3916c374
...
...
@@ -44,7 +44,7 @@ const TheaterPage = () => {
<
TheaterInfo
/>
<
/div
>
<
div
className
=
"
tab-pane fade
"
id
=
"
stillcut
"
role
=
"
tabpanel
"
aria
-
labelledby
=
"
stillcut-tab
"
>
<
div
>
상영시간표
<
/div
>
<
div
className
=
"
pb-5
"
>
상영시간표
<
/div
>
<
/div
>
<
div
className
=
"
tab-pane fade
"
id
=
"
review
"
role
=
"
tabpanel
"
aria
-
labelledby
=
"
review-tab
"
>
<
div
className
=
"
d-flex justify-content-center
"
>
...
...
client/src/pages/TicketingPage.js
View file @
3916c374
...
...
@@ -10,6 +10,7 @@ import catchErrors from "../utils/catchErrors.js"
const
TicketingPage
=
({
location
})
=>
{
const
[
ticketInfo
,
setTicketInfo
]
=
useState
({
movieId
:
0
,
...
location
.
state
,
cinema
:
""
,
selectedTheater
:
""
,
...
...
@@ -24,7 +25,9 @@ const TicketingPage = ({ location }) => {
},
[])
useEffect
(()
=>
{
if
(
ticketInfo
.
movieId
>
0
)
{
getMovieInfo
()
}
},
[
ticketInfo
])
async
function
getMovieInfo
()
{
...
...
@@ -50,11 +53,11 @@ const TicketingPage = ({ location }) => {
console
.
log
(
response
.
data
)
setCinemaInfo
(
response
.
data
)
}
catch
(
error
)
{
c
onsole
.
log
(
e
rror
)
c
atchErrors
(
error
,
setE
rror
)
}
}
return
(
<
div
className
=
"
container
"
style
=
{{
backgroundColor
:
"
black
"
}}
>
<
div
className
=
"
container
pb-5
"
style
=
{{
backgroundColor
:
"
black
"
}}
>
<
div
className
=
"
row justify-content-center my-5
"
>
<
div
className
=
"
col-sm-4 mb-4
"
>
<
h3
className
=
"
py-2 text-white text-center
"
style
=
{{
border
:
"
3px solid #000000
"
,
borderBottom
:
"
3px solid #FEDC00
"
}}
>
영화
<
/h3
>
...
...
@@ -70,12 +73,12 @@ const TicketingPage = ({ location }) => {
<
/div
>
<
/div
>
<
div
className
=
"
row p-3
"
style
=
{{
backgroundColor
:
"
#252525
"
}}
>
<
div
className
=
"
col-sm-3
border-end
text-center
"
>
<
div
className
=
"
col-sm-3 text-center
"
>
{
movieInfo
?
<
img
style
=
{{
maxHeight
:
"
10rem
"
}}
src
=
{
`https://image.tmdb.org/t/p/original
${
movieInfo
.
poster_path
}
`
}
alt
=
"
영화포스터
"
/>
:
<
div
className
=
"
mb-2
"
style
=
{{
color
:
"
white
"
}}
>
영화선택
<
/div>
}
<
/div
>
<
div
className
=
"
col-sm-6
border-end
"
style
=
{{
color
:
"
white
"
}}
>
<
div
className
=
"
col-sm-6
"
style
=
{{
color
:
"
white
"
}}
>
<
div
className
=
"
mb-2 text-center
"
>
극장선택
<
/div
>
{
movieInfo
&&
ticketInfo
.
cinema
?
<
ul
>
...
...
@@ -87,16 +90,16 @@ const TicketingPage = ({ location }) => {
:
<
div
><
/div>
}
<
/div
>
<
div
className
=
"
col-sm-3 text-center
"
>
<
div
className
=
"
mb-
2
"
style
=
{{
color
:
"
white
"
}}
>
좌석선택
<
/div
>
{
movieInfo
&&
ticketInfo
.
cinema
<
div
className
=
"
mb-
3
"
style
=
{{
color
:
"
white
"
}}
>
좌석선택
<
/div
>
{
movieInfo
&&
ticketInfo
.
cinema
&&
ticketInfo
.
timetableId
?
<
Link
to
=
{{
pathname
:
`/ticket/seat`
,
state
:
{
...
ticketInfo
,
...
movieInfo
}
}}
>
<
img
className
=
"
border border-3 rounded-3
"
src
=
"
/images/icons8-arrow-white.png
"
alt
=
"
예매하기
"
/>
<
img
className
=
"
border border-3 rounded-3
"
src
=
"
/images/icons8-arrow-white.png
"
alt
=
"
예매하기
"
style
=
{{
width
:
'
80px
'
}}
/
>
<
/Link
>
:
<
img
className
=
"
border border-3 rounded-3
"
src
=
"
/images/icons8-arrow-white.png
"
alt
=
"
예매하기
"
/>
:
<
img
className
=
"
border border-3 rounded-3
"
src
=
"
/images/icons8-arrow-white.png
"
alt
=
"
예매하기
"
style
=
{{
width
:
'
80px
'
}}
/
>
}
<
/div
>
<
/div
>
...
...
client/src/pages/TicketingSeatPage.js
View file @
3916c374
...
...
@@ -32,7 +32,7 @@ const TicketingSeatPage = ({ location }) => {
useEffect
(()
=>
{
getInfo
()
},
[])
},
[
ticketInfo
.
timetableId
])
useEffect
(()
=>
{
getTicketFee
()
...
...
@@ -42,10 +42,10 @@ const TicketingSeatPage = ({ location }) => {
try
{
setError
(
""
)
const
response
=
await
axios
.
post
(
'
/api/theater/getInfo
'
,
{
theaterId
:
ticketInfo
.
selectedT
heater
theaterId
:
ticketInfo
.
t
heater
Id
})
setTheaterInfo
(
response
.
data
)
const
response2
=
await
reservationApi
.
findReservedSeats
(
1
);
const
response2
=
await
reservationApi
.
findReservedSeats
(
ticketInfo
.
timetableId
);
const
reserve
=
response2
.
map
((
el
)
=>
el
.
row
+
'
-
'
+
el
.
col
);
...
...
@@ -63,7 +63,9 @@ const TicketingSeatPage = ({ location }) => {
theaterTypeId
:
theaterInfo
.
theatertypeId
}
})
const
basicFee
=
response3
.
data
[
0
].
day
+
response3
.
data
[
0
].
defaultPrice
+
response3
.
data
[
0
].
weekdays
const
week
=
ticketInfo
.
week
const
partTime
=
ticketInfo
.
partTime
const
basicFee
=
response3
.
data
[
0
][
partTime
]
+
response3
.
data
[
0
].
defaultPrice
+
response3
.
data
[
0
][
week
]
setTicketFee
({
adult
:
basicFee
+
response3
.
data
[
0
].
adult
,
youth
:
basicFee
+
response3
.
data
[
0
].
youth
,
...
...
@@ -179,7 +181,7 @@ const TicketingSeatPage = ({ location }) => {
?
<
ul
>
<
li
>
영화
:
{
ticketInfo
.
title
}
<
/li
>
<
li
>
극장
:
{
ticketInfo
.
cinema
}
<
/li
>
<
li
>
일시
:
2021
/
07
/
21
10
:
00
<
/li
>
<
li
>
일시
:
{
ticketInfo
.
time
}
<
/li
>
<
li
>
상영관
:
{
ticketInfo
.
selectedTheater
}
관
<
/li
>
<
li
>
좌석
:
{
selectedSeats
.
map
(
el
=>
String
.
fromCharCode
(
parseInt
(
el
.
split
(
'
-
'
)[
0
])
+
64
)
+
el
.
split
(
'
-
'
)[
1
])
+
'
'
}
<
/li
>
<
/ul
>
...
...
server/controllers/kakaopay.controller.js
View file @
3916c374
import
axios
from
'
axios
'
import
config
from
"
../config/app.config.js
"
;
const
success
=
async
(
req
,
res
)
=>
{
const
success
=
async
(
req
,
res
)
=>
{
try
{
// const { cid, tid, partner_order_id, partner_user_id, pg_token } = req.body
const
item
=
req
.
body
...
...
@@ -20,12 +20,10 @@ const success = async(req, res) => {
})
const
resp
=
response
.
data
console
.
log
(
'
resp
'
,
resp
)
res
.
json
({...
resp
})
res
.
json
({
...
resp
})
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
const
fail
=
(
req
,
res
)
=>
{
...
...
@@ -34,10 +32,27 @@ const fail = (req, res) => {
})
}
const
cancel
=
(
req
,
res
)
=>
{
return
res
.
json
({
message
:
'
Canceled
'
const
cancel
=
async
(
req
,
res
)
=>
{
try
{
const
item
=
req
.
body
const
data
=
[]
for
(
let
property
in
item
)
{
let
encodedKey
=
encodeURIComponent
(
property
);
let
encodedValue
=
encodeURIComponent
(
item
[
property
]);
data
.
push
(
encodedKey
+
"
=
"
+
encodedValue
);
}
const
bodyData
=
data
.
join
(
'
&
'
)
const
response
=
await
axios
.
post
(
'
https://kapi.kakao.com/v1/payment/cancel
'
,
bodyData
,
{
headers
:
{
'
Authorization
'
:
`KakaoAK
${
config
.
kakaoAdminKey
}
`
,
'
Content-Type
'
:
'
application/x-www-form-urlencoded;charset=UTF-8
'
,
},
})
const
resp
=
response
.
data
res
.
json
(
resp
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
const
singleTest
=
async
(
req
,
res
)
=>
{
...
...
server/controllers/movie.controller.js
View file @
3916c374
...
...
@@ -137,7 +137,7 @@ const getMovieList = async (req, res) => {
}
}
elements
.
sort
(
function
(
a
,
b
)
{
return
a
.
release_date
-
b
.
release_date
return
b
.
release_date
-
a
.
release_date
})
res
.
json
(
elements
)
}
else
{
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment