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
26e786c6
Commit
26e786c6
authored
Aug 02, 2021
by
Jiwon Yoon
Browse files
Merge branch 'jiwon'
parents
dd1c9aee
54b1ec39
Changes
29
Hide whitespace changes
Inline
Side-by-side
client/public/images/photothumb.db
View file @
26e786c6
No preview for this file type
client/src/App.js
View file @
26e786c6
...
...
@@ -14,7 +14,7 @@ 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
"
;
import
Payment
from
"
./pages/PaymentPage
/PaymentPage
"
;
function
App
()
{
...
...
@@ -38,6 +38,7 @@ function App() {
<
Route
path
=
"
/ticket/seat
"
component
=
{
TicketingSeatPage
}
/
>
<
Route
path
=
"
/ticket
"
component
=
{
TicketingPage
}
/
>
<
Route
path
=
"
/payment
"
component
=
{
Payment
}
/
>
<
Route
path
=
"
/theater
"
component
=
{
TheaterPage
}
/
>
<
Route
path
=
"
/search
"
component
=
{
SearchPage
}
/
>
<
/Switch
>
<
/Router
>
...
...
client/src/components/CountButton.js
View file @
26e786c6
import
{
useState
}
from
'
react
'
const
CountButton
=
(
props
)
=>
{
const
name
=
props
.
name
const
CountButton
=
(
{
count
,
setCount
}
)
=>
{
const
name
=
name
function
handleCount
(
event
)
{
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
"
)
{
props
.
setCount
({...
props
.
count
,
[
name
]
:
props
.
count
[
name
]
+
1
})
setCount
({...
count
,
[
name
]
:
count
[
name
]
+
1
})
}
else
{
props
.
setCount
({...
props
.
count
,
[
name
]
:
event
.
target
.
value
})
setCount
({...
count
,
[
name
]
:
event
.
target
.
value
})
}
}
...
...
@@ -16,7 +16,7 @@ const CountButton = (props) => {
<
button
type
=
"
button
"
name
=
"
backbutton
"
style
=
{{
backgroundColor
:
"
black
"
,
border
:
"
0
"
}}
onClick
=
{
handleCount
}
>
<
img
src
=
"
/images/icons8-back-24.png
"
name
=
"
backbutton
"
alt
=
"
<
"
/>
<
/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
}
>
<
img
src
=
"
/images/icons8-forward-24.png
"
name
=
"
forwardbutton
"
alt
=
"
>
"
/>
<
/button
>
...
...
client/src/components/Kakaopay.js
View file @
26e786c6
import
axios
from
'
axios
'
const
Kakaopay
=
(
props
)
=>
{
const
Kakaopay
=
(
{
ticketInfo
}
)
=>
{
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
,
item_name
:
ticketInfo
.
title
,
quantity
:
ticketInfo
.
teenager
+
ticketInfo
.
adult
+
ticketInfo
.
elderly
,
total_amount
:
ticketInfo
.
teenager
*
7000
+
ticketInfo
.
adult
*
8000
+
ticketInfo
.
elderly
*
6000
,
vat_amount
:
0
,
tax_free_amount
:
0
,
approval_url
:
'
http://localhost:3000/
'
,
...
...
client/src/components/Login/Login.js
View file @
26e786c6
...
...
@@ -103,7 +103,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
=
"
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
/>
<
p
className
=
{
`text-white
${
styles
.
fontSizeTwo
}
`
}
>
※
비회원
정보
오
입력
시
예매
내역
확인
/
취소
및
티켓
발권이
어려울
수
있으니
다시
한번
확인해
주시기
바랍니다
.
<
/p
>
...
...
client/src/components/SeatTable/SeatTable.js
View file @
26e786c6
import
{
useState
}
from
'
react
'
//
import { useState } from 'react'
import
styles
from
'
./seatTable.module.scss
'
const
SeatTable
=
(
props
)
=>
{
const
SeatTable
=
(
{
theaterInfo
,
count
,
setSelectedSeats
,
selectedSeats
,
reservedSeats
}
)
=>
{
const
table
=
[]
if
(
props
.
theaterInfo
)
{
for
(
let
rowIndex
=
0
;
rowIndex
<
props
.
theaterInfo
.
rows
;
rowIndex
++
)
{
if
(
theaterInfo
)
{
for
(
let
rowIndex
=
0
;
rowIndex
<
theaterInfo
.
rows
;
rowIndex
++
)
{
table
.
push
(
<
span
className
=
"
me-3
"
style
=
{{
color
:
"
gray
"
}}
>
{
String
.
fromCharCode
(
rowIndex
+
65
)}
<
/span>
)
for
(
let
colIndex
=
0
;
colIndex
<
props
.
theaterInfo
.
columns
;
colIndex
++
)
{
for
(
let
colIndex
=
0
;
colIndex
<
theaterInfo
.
columns
;
colIndex
++
)
{
table
.
push
(
<
span
>
{
props
.
reservedSeats
.
find
(
el
=>
el
===
String
(
rowIndex
+
1
)
+
'
-
'
+
String
(
colIndex
+
1
))
{
reservedSeats
.
find
(
el
=>
el
===
String
(
rowIndex
+
1
)
+
'
-
'
+
String
(
colIndex
+
1
))
?
<
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
>
<
button
className
=
{
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
>
)
...
...
@@ -24,25 +24,25 @@ const SeatTable = (props) => {
function
handleClick
(
event
)
{
const
num
=
Object
.
values
(
props
.
count
).
reduce
((
a
,
b
)
=>
(
a
+
b
))
if
(
props
.
selectedSeats
.
find
(
el
=>
el
===
event
.
target
.
name
+
'
-
'
+
event
.
target
.
id
))
{
const
num
=
Object
.
values
(
count
).
reduce
((
a
,
b
)
=>
(
a
+
b
))
if
(
selectedSeats
.
find
(
el
=>
el
===
event
.
target
.
name
+
'
-
'
+
event
.
target
.
id
))
{
//제거
const
deleted
=
props
.
selectedSeats
.
filter
((
element
)
=>
element
!==
event
.
target
.
name
+
'
-
'
+
event
.
target
.
id
);
props
.
setSelectedSeats
(
deleted
)
const
deleted
=
selectedSeats
.
filter
((
element
)
=>
element
!==
event
.
target
.
name
+
'
-
'
+
event
.
target
.
id
);
setSelectedSeats
(
deleted
)
}
else
{
if
(
props
.
selectedSeats
.
length
>
num
-
1
)
{
if
(
selectedSeats
.
length
>
num
-
1
)
{
alert
(
"
선택한 좌석이 예매인원보다 많습니다.
"
)
}
else
{
//추가
props
.
setSelectedSeats
([...
props
.
selectedSeats
,
event
.
target
.
name
+
'
-
'
+
event
.
target
.
id
])
setSelectedSeats
([...
selectedSeats
,
event
.
target
.
name
+
'
-
'
+
event
.
target
.
id
])
}
}
}
return
(
<
div
className
=
"
text-center
"
>
{
/* {console.log(
props.
theaterInfo)} */
}
{
console
.
log
(
props
.
selectedSeats
)}
{
/* {console.log(theaterInfo)} */
}
{
console
.
log
(
selectedSeats
)}
<
div
className
=
"
mb-2
"
style
=
{{
backgroundColor
:
"
gray
"
}}
>
Screen
<
/div
>
{
table
}
<
/div
>
...
...
client/src/components/TheaterInfo.js
0 → 100644
View file @
26e786c6
import
axios
from
"
axios
"
import
{
useState
,
useEffect
}
from
'
react
'
import
catchErrors
from
"
../utils/catchErrors
"
const
TheaterInfo
=
()
=>
{
const
[
theaterInfo
,
setTheaterInfo
]
=
useState
()
const
[
error
,
setError
]
=
useState
()
useEffect
(()
=>
{
getTheaterInfo
()
},
[])
async
function
getTheaterInfo
()
{
try
{
const
response
=
await
axios
.
get
(
'
/api/info/cinema
'
)
console
.
log
(
response
.
data
)
setTheaterInfo
(
response
.
data
)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
return
(
<>
{
/* <h3>{theaterInfo.cinemaName}</h3> */
}
<
div
>
총
상영관
수
:
<
/div
>
{
/* <div>{theaterInfo.address}</div> */
}
<
/
>
)
}
export
default
TheaterInfo
\ No newline at end of file
client/src/components/TicketingMovie/TicketingMovie.js
View file @
26e786c6
...
...
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
import
axios
from
'
axios
'
import
styles
from
"
./ticketingMovie.module.scss
"
const
TicketingMovie
=
(
props
)
=>
{
const
TicketingMovie
=
(
{
ticketInfo
,
setTicketInfo
}
)
=>
{
const
[
movieList
,
setMovieList
]
=
useState
([])
useEffect
(()
=>
{
getMovieList
()
...
...
@@ -19,16 +19,16 @@ const TicketingMovie = (props) => {
function
handleClick
(
event
)
{
console
.
log
(
event
.
target
.
name
)
props
.
setTicketInfo
({...
props
.
ticketInfo
,
movieId
:
event
.
target
.
name
})
setTicketInfo
({...
ticketInfo
,
movieId
:
event
.
target
.
name
})
}
return
(
<
div
>
{
console
.
log
(
props
.
ticketInfo
.
movieId
)}
{
console
.
log
(
ticketInfo
.
movieId
)}
<
div
className
=
"
d-grid gap-2
"
>
{
movieList
.
length
>
0
?
movieList
.
map
(
movie
=>
(
<
button
name
=
{
movie
.
id
}
className
=
{
`
${
props
.
ticketInfo
.
movieId
==
movie
.
id
?
styles
.
on
:
styles
.
btn
}
`
}
onClick
=
{
handleClick
}
>
<
button
name
=
{
movie
.
id
}
className
=
{
`
${
ticketInfo
.
movieId
==
movie
.
id
?
styles
.
on
:
styles
.
btn
}
`
}
onClick
=
{
handleClick
}
>
{
movie
.
title
}
<
/button
>
))
...
...
client/src/components/TicketingTheater/TicketingTheater.js
View file @
26e786c6
import
styles
from
"
./ticketingTheater.module.scss
"
const
TicketingTheater
=
(
props
)
=>
{
const
TicketingTheater
=
(
{
ticketInfo
,
cinemaInfo
,
setTicketInfo
}
)
=>
{
function
handleClick
(
event
)
{
// event.preventDefault()
console
.
log
(
event
.
target
.
name
)
props
.
setTicketInfo
({
...
props
.
ticketInfo
,
cinema
:
event
.
target
.
name
})
setTicketInfo
({
...
ticketInfo
,
cinema
:
event
.
target
.
name
})
}
return
(
<
div
>
<
div
className
=
"
d-grid gap-2
"
>
<
button
name
=
{
props
.
cinemaInfo
.
cinemaName
}
className
=
{
`
${
props
.
ticketInfo
.
cinema
===
props
.
cinemaInfo
.
cinemaName
?
styles
.
on
:
styles
.
btn
}
`
}
onClick
=
{
handleClick
}
>
{
props
.
cinemaInfo
.
cinemaName
}
<
/button
>
<
button
name
=
{
cinemaInfo
.
cinemaName
}
className
=
{
`
${
ticketInfo
.
cinema
===
cinemaInfo
.
cinemaName
?
styles
.
on
:
styles
.
btn
}
`
}
onClick
=
{
handleClick
}
>
{
cinemaInfo
.
cinemaName
}
<
/button
>
<
/div
>
<
/div
>
)
...
...
client/src/components/TicketingTimeTable/TicketingTimeTable.js
View file @
26e786c6
const
TicketingTimeTable
=
(
props
)
=>
{
const
TicketingTimeTable
=
(
{
ticketInfo
}
)
=>
{
return
(
<
div
>
<
div
className
=
"
text-center
"
style
=
{{
color
:
"
white
"
}}
>
{
console
.
log
(
props
.
ticketInfo
.
movieId
,
props
.
ticketInfo
.
theater
)}
{
props
.
ticketInfo
.
movieId
&&
props
.
ticketInfo
.
theater
?
<
div
>
{
props
.
ticketInfo
.
movieId
}
{
props
.
ticketInfo
.
theater
}
<
/div
>
{
console
.
log
(
ticketInfo
.
movieId
,
ticketInfo
.
cinema
)}
{
ticketInfo
.
movieId
&&
ticketInfo
.
cinema
?
<
div
>
{
ticketInfo
.
movieId
}
{
ticketInfo
.
cinema
}
<
/div
>
:
<
div
>
영화와
극장을
모두
선택해주세요
.
<
/div>
}
<
/div
>
<
/div
>
...
...
client/src/components/Video.js
View file @
26e786c6
import
{
useEffect
,
useState
}
from
'
react
'
import
movieApi
from
'
../apis/movie.api.js
'
const
Video
=
(
props
)
=>
{
const
Video
=
(
{
movieId
}
)
=>
{
const
[
videoUrls
,
setVideoUrls
]
=
useState
([])
useEffect
(()
=>
{
getVideos
()
...
...
@@ -8,7 +8,7 @@ const Video = (props) => {
async
function
getVideos
()
{
try
{
const
data
=
await
movieApi
.
getVideosfromTM
(
props
.
movieId
)
const
data
=
await
movieApi
.
getVideosfromTM
(
movieId
)
setVideoUrls
(
data
)
}
catch
(
error
)
{
console
.
log
(
error
)
...
...
client/src/pages/PaymentPage.js
deleted
100644 → 0
View file @
dd1c9aee
import
axios
from
'
axios
'
import
{
useEffect
,
useState
}
from
'
react
'
import
Kakaopay
from
'
../components/Kakaopay
'
import
{
useAuth
}
from
'
../context/auth_context
'
import
catchErrors
from
'
../utils/catchErrors
'
const
Payment
=
({
location
})
=>
{
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
)
{
try
{
const
response
=
await
axios
.
post
(
'
/api/email/send
'
,
{
...
ticketInfo
,
...
userInfo
})
console
.
log
(
response
.
data
)
}
catch
(
error
)
{
console
.
log
(
error
)
}
}
return
(
<
div
className
=
"
container
"
style
=
{{
color
:
"
white
"
}}
>
{
console
.
log
(
ticketInfo
)}
{
console
.
log
(
userInfo
)}
<
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
"
>
<
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
>
<
img
src
=
"
/images/naverpay_button.png
"
/>
<
Kakaopay
ticketInfo
=
{
ticketInfo
}
setTicketInfo
=
{
setTicketInfo
}
/
>
<
div
className
=
"
my-5
"
>
<
button
className
=
"
btn btn-warning
"
type
=
"
button
"
onClick
=
{
SendMail
}
>
결제완료
<
/button
>
<
/div
>
<
/div
>
<
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
=
"
영화포스터
"
/>
<
h5
className
=
"
my-3
"
>
{
ticketInfo
.
title
}
<
/h5
>
<
div
>
{
ticketInfo
.
cinema
}
<
/div
>
<
div
>
{
ticketInfo
.
time
}
<
/div
>
<
div
className
=
"
mb-3
"
>
{
ticketInfo
.
selectedTheater
}
관
{
ticketInfo
.
selectedSeats
}
<
/div
>
<
div
className
=
"
rounded-3 p-3
"
style
=
{{
backgroundColor
:
'
#404040
'
}}
>
<
div
>
청소년
:
{
ticketInfo
.
teenager
}
명
<
/div
>
<
div
>
성인
:
{
ticketInfo
.
adult
}
명
<
/div
>
<
div
>
경로우대
:
{
ticketInfo
.
elderly
}
명
<
/div
>
<
div
>
총
결제금액
:
{
ticketInfo
.
teenager
*
7000
+
ticketInfo
.
adult
*
8000
+
ticketInfo
.
elderly
*
6000
}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
)
}
export
default
Payment
\ No newline at end of file
client/src/pages/PaymentPage/PaymentPage.js
0 → 100644
View file @
26e786c6
import
axios
from
'
axios
'
import
{
useEffect
,
useState
}
from
'
react
'
import
Kakaopay
from
'
../../components/Kakaopay
'
import
{
useAuth
}
from
'
../../context/auth_context
'
import
catchErrors
from
'
../../utils/catchErrors
'
import
styles
from
'
./PaymentPage.module.scss
'
const
Payment
=
({
location
})
=>
{
const
[
ticketInfo
,
setTicketInfo
]
=
useState
({
...
location
.
state
})
const
[
error
,
setError
]
=
useState
(
""
)
const
[
userInfo
,
setUserInfo
]
=
useState
()
const
[
guestInfo
,
setGuestInfo
]
=
useState
({})
const
[
guestID
,
setGuestID
]
=
useState
()
const
{
user
}
=
useAuth
()
useEffect
(()
=>
{
console
.
log
(
user
.
id
)
if
(
user
.
id
>
0
)
{
getUserInfo
()
}
},
[])
async
function
getUserInfo
()
{
try
{
const
response
=
await
axios
.
post
(
`/api/auth/getuserinfo`
,
{
id
:
user
.
id
})
setUserInfo
(
response
.
data
)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
function
handleChangeGuest
(
e
)
{
setGuestInfo
({
...
guestInfo
,
[
e
.
target
.
name
]:
String
(
e
.
target
.
value
)
})
}
async
function
handleClickGuest
()
{
try
{
const
response
=
await
axios
.
post
(
'
/api/auth/guest/save
'
,
{
...
guestInfo
})
setGuestID
(
response
.
data
.
id
)
// console.log(response.data)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
async
function
reservationComplete
()
{
try
{
if
(
userInfo
)
{
const
response
=
await
axios
.
post
(
`/api/reservation/save`
,
{
userType
:
"
member
"
,
user
:
userInfo
.
id
,
...
ticketInfo
,
payment
:
"
카카오페이
"
,
timetable
:
1
})
console
.
log
(
"
회원예매완료===
"
,
response
.
data
)
}
else
{
if
(
guestID
)
{
const
response
=
await
axios
.
post
(
`/api/reservation/save`
,
{
userType
:
"
guest
"
,
user
:
guestID
,
...
ticketInfo
,
payment
:
"
카카오페이
"
,
timetable
:
1
})
console
.
log
(
"
비회원예매완료===
"
,
response
.
data
)
}
else
{
alert
(
"
비회원 정보를 모두 입력 후 저장버튼을 눌러주세요.
"
)
}
}
const
responseEmail
=
await
axios
.
post
(
'
/api/email/send
'
,
{
...
ticketInfo
,
...
userInfo
,
...
guestInfo
,
})
console
.
log
(
"
이메일전송완료===
"
,
responseEmail
.
data
)
}
catch
(
error
)
{
catchErrors
(
error
,
setError
)
}
}
return
(
<
div
className
=
"
container
"
style
=
{{
color
:
"
white
"
}}
>
{
console
.
log
(
ticketInfo
)}
{
console
.
log
(
userInfo
)}
{
console
.
log
(
guestInfo
)}
<
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
>
<
/div
>
<
/div
>
<
div
className
=
"
row justify-content-center
"
>
<
div
className
=
"
col-sm-8 text-center
"
>
{
user
?.
id
>
0
?
<
div
>
<
h5
className
=
"
mb-3
"
>
회원정보
<
/h5
>
<
/div
>
:
<
div
>
<
h5
className
=
"
mb-4 p-2
"
style
=
{{
backgroundColor
:
"
white
"
,
color
:
"
black
"
}}
>
비회원예매
정보입력
<
/h5
>
<
div
className
=
"
my-1
"
>
<
label
className
=
{
styles
.
labelStyle
}
>
이름
<
/label
>
<
input
type
=
"
text
"
name
=
"
name
"
placeholder
=
"
이름
"
onChange
=
{
handleChangeGuest
}
required
/>
<
/div
>
<
div
className
=
"
my-1
"
>
<
label
className
=
{
styles
.
labelStyle
}
>
이메일
<
/label
>
<
input
type
=
"
email
"
name
=
"
email
"
placeholder
=
"
이메일
"
onChange
=
{
handleChangeGuest
}
required
/>
<
/div
>
<
div
className
=
"
my-1
"
>
<
label
className
=
{
styles
.
labelStyle
}
>
생년월일
<
/label
>
<
input
type
=
"
number
"
name
=
"
birth
"
placeholder
=
"
생년월일
"
onChange
=
{
handleChangeGuest
}
maxLength
=
"
6
"
required
/>
<
/div
>
<
div
className
=
"
my-1
"
>
<
label
className
=
{
styles
.
labelStyle
}
>
휴대폰
번호
<
/label
>
<
input
type
=
"
number
"
name
=
"
phoneNumber
"
placeholder
=
"
휴대폰 번호
"
onChange
=
{
handleChangeGuest
}
maxLength
=
"
11
"
required
/>
<
/div
>
<
div
className
=
"
my-1
"
>
<
label
className
=
{
styles
.
labelStyle
}
>
비밀번호
<
/label
>
<
input
type
=
"
password
"
name
=
"
guestPassword
"
placeholder
=
"
비밀번호
"
onChange
=
{
handleChangeGuest
}
required
style
=
{{
width
:
"
178px
"
}}
/
>
<
/div
>
<
div
className
=
"
m-2
"
>
<
p
className
=
{
`text-muted
${
styles
.
warningText
}
`
}
>
※
비회원
정보
오기입
시
예매
내역
확인
/
취소
및
티켓
발권이
어려울
수
있으니
다시
한번
확인해
주시기
바랍니다
.
<
/p
>
<
/div
>
<
button
className
=
"
btn btn-warning mb-3
"
type
=
"
button
"
style
=
{{
width
:
"
100%
"
}}
onClick
=
{
handleClickGuest
}
>
비회원
정보
저장
<
/button
>
<
/div
>
}
<
h5
className
=
"
my-4 p-2
"
style
=
{{
backgroundColor
:
"
white
"
,
color
:
"
black
"
}}
>
결제방법
<
/h5
>
<
img
src
=
"
/images/naverpay_button.png
"
/>
<
Kakaopay
ticketInfo
=
{
ticketInfo
}
setTicketInfo
=
{
setTicketInfo
}
/
>
<
div
className
=
"
my-5
"
>
<
button
className
=
"
btn btn-warning
"
type
=
"
button
"
style
=
{{
width
:
"
100%
"
}}
onClick
=
{
reservationComplete
}
>
결제완료
<
/button
>
<
/div
>
<
/div
>
<
div
className
=
"
col-sm-4
"
>
<
div
className
=
"
text-center rounded-3 p-3
"
style
=
{{
backgroundColor
:
"
#252525
"
}}
>
<
img
style
=
{{
maxHeight
:
"
10rem
"
}}
src
=
{
`https://image.tmdb.org/t/p/original
${
ticketInfo
.
poster_path
}
`
}
alt
=
"
영화포스터
"
/>
<
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
])
+
65
)
+
el
.
split
(
'
-
'
)[
1
])
+
'
'
}
<
/div
>
<
div
className
=
"
rounded-3 p-3
"
style
=
{{
backgroundColor
:
'
#404040
'
}}
>
<
div
>
청소년
:
{
ticketInfo
.
teenager
}
명
<
/div
>
<
div
>
성인
:
{
ticketInfo
.
adult
}
명
<
/div
>
<
div
>
경로우대
:
{
ticketInfo
.
elderly
}
명
<
/div
>
<
div
>
총
결제금액
:
{
ticketInfo
.
teenager
*
7000
+
ticketInfo
.
adult
*
8000
+
ticketInfo
.
elderly
*
6000
}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
)
}
export
default
Payment
\ No newline at end of file
client/src/pages/PaymentPage/PaymentPage.module.scss
0 → 100644
View file @
26e786c6
.labelStyle
{
display
:
inline-block
;
width
:
80px
;
text-align
:
right
;
margin-right
:
1rem
;
}
.warningText
{
font-size
:
small
;
}
\ No newline at end of file
client/src/pages/PaymentPage/index.js
0 → 100644
View file @
26e786c6
export
{
default
}
from
"
./PaymentPage
"
\ No newline at end of file
client/src/pages/TheaterPage.js
View file @
26e786c6
import
{
useState
}
from
'
react
'
import
{
useState
}
from
'
react
'
import
TheaterInfo
from
'
../components/TheaterInfo
'
const
TheaterPage
=
()
=>
{
const
[
state
,
setState
]
=
useState
(
0
)
...
...
@@ -19,7 +20,7 @@ const TheaterPage = () => {
<
/div
>
<
div
className
=
"
tab-content text-center
"
id
=
"
myTabContent
"
style
=
{{
color
:
"
white
"
}}
>
<
div
className
=
"
tab-pane fade show active
"
id
=
"
overview
"
role
=
"
tabpanel
"
aria
-
labelledby
=
"
overview-tab
"
>
<
div
>
극장정보
<
/div
>
<
TheaterInfo
/
>
<
/div
>
<
div
className
=
"
tab-pane fade
"
id
=
"
stillcut
"
role
=
"
tabpanel
"
aria
-
labelledby
=
"
stillcut-tab
"
>
<
div
>
상영시간표
<
/div
>
...
...
client/src/pages/TicketingPage.js
View file @
26e786c6
...
...
@@ -10,7 +10,7 @@ const TicketingPage = ({ location }) => {
const
[
ticketInfo
,
setTicketInfo
]
=
useState
({
...
location
.
state
,
cinema
:
""
,
selectedTheater
:
1
,
selectedTheater
:
"
1
"
,
time
:
"
2021/07/21 10:00
"
})
const
[
cinemaInfo
,
setCinemaInfo
]
=
useState
({})
...
...
@@ -52,7 +52,7 @@ const TicketingPage = ({ location }) => {
<
TicketingMovie
ticketInfo
=
{
ticketInfo
}
setTicketInfo
=
{
setTicketInfo
}
/
>
<
/div
>
<
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 text-white text-center
"
style
=
{{
border
:
"
3px solid #000000
"
,
borderBottom
:
"
3px solid #FEDC00
"
}}
>
극장
<
/h3
>
<
TicketingTheater
cinemaInfo
=
{
cinemaInfo
}
ticketInfo
=
{
ticketInfo
}
setTicketInfo
=
{
setTicketInfo
}
/
>
<
/div
>
<
div
className
=
"
col-sm-5 mb-4
"
>
...
...
client/src/pages/TicketingSeatPage.js
View file @
26e786c6
...
...
@@ -29,10 +29,11 @@ const TicketingSeatPage = ({ location }) => {
async
function
getInfo
()
{
try
{
const
response
=
await
axios
.
post
(
'
/api/theater/getInfo
'
,
{
theaterN
um
:
ticketInfo
.
selectedTheater
theaterN
ame
:
ticketInfo
.
selectedTheater
})
console
.
log
(
response
.
data
)
setTheaterInfo
(
response
.
data
)
const
response2
=
await
axios
.
post
(
'
/api/reservation/findreservation
'
,
{
timetable
:
1
})
...
...
@@ -90,7 +91,7 @@ const TicketingSeatPage = ({ location }) => {
{
console
.
log
(
ticketInfo
)}
{
console
.
log
(
reservedSeats
)}
<
div
className
=
"
row justify-content-center my-5
"
>
<
div
className
=
"
col-sm-4
mb-3
"
>
<
div
className
=
"
col-sm-4
"
>
<
h3
className
=
"
py-2 text-white text-center
"
style
=
{{
border
:
"
3px solid #000000
"
,
borderBottom
:
"
3px solid #FEDC00
"
}}
>
좌석선택
<
/h3
>
<
/div
>
<
/div
>
...
...
@@ -144,8 +145,8 @@ const TicketingSeatPage = ({ location }) => {
<
li
>
영화
:
{
ticketInfo
.
title
}
<
/li
>
<
li
>
극장
:
{
ticketInfo
.
cinema
}
<
/li
>
<
li
>
일시
:
2021
/
07
/
21
10
:
00
<
/li
>
<
li
>
상영관
:
3
관
<
/li
>
<
li
>
좌석
:
{
selectedSeats
}
<
/li
>
<
li
>
상영관
:
{
ticketInfo
.
selectedTheater
}
관
<
/li
>
<
li
>
좌석
:
{
selectedSeats
.
map
(
el
=>
String
.
fromCharCode
(
parseInt
(
el
.
split
(
'
-
'
)[
0
])
+
64
)
+
el
.
split
(
'
-
'
)[
1
])
+
'
'
}
<
/li
>
<
/ul
>
:
<
div
><
/div>
}
<
/div
>
...
...
server/controllers/email.controller.js
View file @
26e786c6
import
nodemailer
from
"
nodemailer
"
const
SendMail
=
async
(
req
,
res
)
=>
{
const
{
email
,
title
,
cinema
,
selectedTheater
,
time
,
nick
name
}
=
req
.
body
const
{
email
,
title
,
cinema
,
selectedTheater
,
time
,
name
}
=
req
.
body
const
selectedSeats
=
req
.
body
.
selectedSeats
const
sendMail
=
async
(
email
,
title
,
cinema
,
selectedTheater
,
time
,
nick
name
,
selectedSeats
)
=>
{
const
sendMail
=
async
(
email
,
title
,
cinema
,
selectedTheater
,
time
,
name
,
selectedSeats
)
=>
{
// 메일을 전달해줄 객체
const
transporter
=
nodemailer
.
createTransport
({
host
:
'
smtp.gmail.com
'
,
...
...
@@ -26,7 +26,7 @@ const SendMail = async (req,res) => {
from
:
`
${
cinema
}
<angelayoon99@gmail.com>`
,
to
:
`
${
email
}
`
,
subject
:
`
${
cinema
}
예매확인내역:
${
title
}
`
,
text
:
`
${
nick
name
}
님의 예매:
${
title
}
/
${
cinema
}
/
${
selectedTheater
}
관 / 일시:
${
time
}
/
${
selectedSeats
}
/`
,
text
:
`
${
name
}
님의 예매:
${
title
}
/
${
cinema
}
/
${
selectedTheater
}
관 / 일시:
${
time
}
/
${
selectedSeats
}
/`
,
};
// 메일 전송
...
...
@@ -39,7 +39,7 @@ const SendMail = async (req,res) => {
}
}
sendMail
(
email
,
title
,
cinema
,
selectedTheater
,
time
,
nick
name
,
selectedSeats
);
sendMail
(
email
,
title
,
cinema
,
selectedTheater
,
time
,
name
,
selectedSeats
);
}
...
...
server/controllers/reservation.controller.js
View file @
26e786c6
import
axios
from
'
axios
'
import
{
Reservation
,
Theater
}
from
'
../db/index.js
'
import
{
Movie
,
Reservation
,
Theater
}
from
'
../db/index.js
'
import
sequelize
from
'
sequelize
'
const
{
Op
}
=
sequelize
const
findReservation
=
async
(
req
,
res
)
=>
{
const
{
timetable
}
=
req
.
body
const
findReservation
=
async
(
req
,
res
)
=>
{
const
{
timetable
}
=
req
.
body
try
{
const
reservedSeats
=
await
Reservation
.
findAll
({
where
:
{
timetable
:
timetable
timetable
:
timetable
}
})
console
.
log
(
reservedSeats
)
res
.
json
(
reservedSeats
)
}
catch
(
error
)
{
return
res
.
status
(
500
).
send
(
error
.
message
||
"
이미 예매되어있는 좌석을 찾는 중 오류발생
"
)
res
.
status
(
500
).
send
(
error
.
message
||
"
이미 예매되어있는 좌석을 찾는 중 오류발생
"
)
}
}
export
default
{
findReservation
}
\ No newline at end of file
const
saveReservation
=
async
(
req
,
res
)
=>
{
const
{
movieId
,
selectedTheater
,
timetable
,
payment
,
user
,
userType
}
=
req
.
body
const
rows
=
req
.
body
.
selectedSeats
.
map
(
el
=>
el
.
split
(
'
-
'
)[
0
])
const
cols
=
req
.
body
.
selectedSeats
.
map
(
el
=>
el
.
split
(
'
-
'
)[
1
])
try
{
for
(
let
index
=
0
;
index
<
rows
.
length
;
index
++
)
{
const
reservation
=
await
Reservation
.
create
({
user
:
user
,
userType
:
userType
,
movieId
:
movieId
,
theater
:
selectedTheater
,
row
:
rows
[
index
],
col
:
cols
[
index
],
timetable
:
timetable
,
payment
:
payment
})
res
.
json
(
reservation
)
}
const
movie
=
await
Movie
.
findOne
({
where
:
{
movieId
:
movieId
}
})
movie
.
ticket_sales
++
await
movie
.
save
();
}
catch
(
error
)
{
console
.
log
(
error
)
res
.
status
(
500
).
send
(
error
.
message
||
"
예매DB에 저장 실패
"
)
}
}
export
default
{
findReservation
,
saveReservation
}
\ No newline at end of file
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