TicketingSeatPage.js 11 KB
Newer Older
1
import { useState, useEffect, useRef } from 'react'
Kim, Subin's avatar
Kim, Subin committed
2
import { Link, useHistory } from 'react-router-dom'
Jiwon Yoon's avatar
Jiwon Yoon committed
3
4
import CountButton from '../components/CountButton'
import SeatTable from '../components/SeatTable/SeatTable'
5
6
import axios from 'axios'
import { useAuth } from '../context/auth_context.js'
Kim, Subin's avatar
Kim, Subin committed
7
import { Modal } from 'bootstrap'
8
import catchErrors from '../utils/catchErrors'
Kim, Subin's avatar
Kim, Subin committed
9
import styles from '../components/SeatTable/seatTable.module.scss'
한규민's avatar
한규민 committed
10
import reservationApi from '../apis/reservation.api.js'
Jiwon Yoon's avatar
Jiwon Yoon committed
11
12

const TicketingSeatPage = ({ location }) => {
13
14
15
16
    const history = useHistory()
    const modalRef = useRef(null)
    const modal = useRef()
    const { user } = useAuth()
17
    const [error, setError] = useState()
Jiwon Yoon's avatar
Jiwon Yoon committed
18
    const [ticketInfo, setTicketInfo] = useState({ ...location.state })
19
    const [theaterInfo, setTheaterInfo] = useState({ theatertypeId: 0 })
Jiwon Yoon's avatar
Jiwon Yoon committed
20
    const [selectedSeats, setSelectedSeats] = useState([])
21
    const [reservedSeats, setReservedSeats] = useState([])
22
23
24
25
26
    const [ticketFee, setTicketFee] = useState({
        youth: 0,
        adult: 0,
        senior: 0
    })
Jiwon Yoon's avatar
Jiwon Yoon committed
27
    const [count, setCount] = useState({
28
        youth: 0,
Jiwon Yoon's avatar
Jiwon Yoon committed
29
        adult: 0,
30
        senior: 0
Jiwon Yoon's avatar
Jiwon Yoon committed
31
    })
Jiwon Yoon's avatar
Jiwon Yoon committed
32

33
34
    useEffect(() => {
        getInfo()
Jiwon Yoon's avatar
Jiwon Yoon committed
35
    }, [ticketInfo.timetableId])
Kim, Subin's avatar
Kim, Subin committed
36
    
37
38
39
    useEffect(() => {
        getTicketFee()
    }, [theaterInfo.theatertypeId])
Jiwon Yoon's avatar
Jiwon Yoon committed
40

41
42
    async function getInfo() {
        try {
Jiwon Yoon's avatar
Jiwon Yoon committed
43
            setError("")
44
            const response = await axios.post('/api/theater/getInfo', {
45
                theaterId: ticketInfo.theaterId
46
47
            })
            setTheaterInfo(response.data)
Jiwon Yoon's avatar
Jiwon Yoon committed
48
            const response2 = await reservationApi.findReservedSeats(ticketInfo.timetableId);
Jiwon Yoon's avatar
Jiwon Yoon committed
49
            const reserve = response2.map((el) =>
50
                el.row + '-' + el.col
한규민's avatar
한규민 committed
51
52
            );
            setReservedSeats(reserve);
53
        } catch (error) {
54
55
56
57
58
59
            catchErrors(error, setError)
        }
    }

    async function getTicketFee() {
        try {
Jiwon Yoon's avatar
Jiwon Yoon committed
60
            setError("")
61
62
63
64
65
            const response3 = await axios.get(`/api/info/ticketfee`, {
                params: {
                    theaterTypeId: theaterInfo.theatertypeId
                }
            })
Jiwon Yoon's avatar
Jiwon Yoon committed
66
67
68
            const week = ticketInfo.week
            const partTime = ticketInfo.partTime
            const basicFee = response3.data[0][partTime] + response3.data[0].defaultPrice + response3.data[0][week]
69
70
71
72
73
74
75
            setTicketFee({
                adult: basicFee + response3.data[0].adult,
                youth: basicFee + response3.data[0].youth,
                senior: basicFee + response3.data[0].senior
            })
        } catch (error) {
            catchErrors(error, setError)
76
77
        }
    }
Jiwon Yoon's avatar
Jiwon Yoon committed
78

79
    function loginModal() {
80
        if (user.role === "member") {
81
            history.push("/payment", {
82
                ...ticketInfo, selectedSeats: selectedSeats, ...count, totalFee: count.adult * ticketFee.adult + count.youth * ticketFee.youth + count.senior * ticketFee.senior
83
84
85
86
87
88
            });
        } else {
            modal.current = new Modal(modalRef.current)
            modal.current?.show()
        }
    }
Jiwon Yoon's avatar
Jiwon Yoon committed
89

90
91
    return (
        <>
92
            <div ref={modalRef} className="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabIndex="-1" aria-labelledby="staticBackdropLabel" aria-hidden={modal}>
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
                <div className="modal-dialog">
                    <div className="modal-content">
                        <div className="modal-header">
                            <h5 className="modal-title" id="staticBackdropLabel">로그인이 필요한 서비스입니다.</h5>
                            <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                        <div className="modal-body">
                            로그인을 하시겠습니까? 비회원예매로 진행하시겠습니까?
                        </div>
                        <div className="modal-footer">
                            <Link to={{ pathname: '/login' }}>
                                <button type="button" className="btn btn-secondary" data-bs-dismiss="modal" >
                                    로그인
                                </button>
                            </Link>
                            <Link to={{
                                pathname: `/payment`,
Kim, Subin's avatar
Kim, Subin committed
110
                                state: { ...ticketInfo, selectedSeats: selectedSeats, ...count, totalFee: count.adult * ticketFee.adult + count.youth * ticketFee.youth + count.senior * ticketFee.senior }
111
112
113
114
115
                            }}>
                                <button type="button" className="btn btn-primary" data-bs-dismiss="modal">비회원예매</button>
                            </Link>
                        </div>
                    </div>
Jiwon Yoon's avatar
Jiwon Yoon committed
116
117
                </div>
            </div>
118
            <div className="mx-5 pb-5" style={{ color: "white" }}>
119
                <div className="row justify-content-center my-5">
Jiwon Yoon's avatar
Jiwon Yoon committed
120
                    <div className="col-sm-4">
121
122
                        <h3 className="py-2 text-white text-center" style={{ border: "3px solid #000000", borderBottom: "3px solid #FEDC00" }}>좌석선택</h3>
                    </div>
Jiwon Yoon's avatar
Jiwon Yoon committed
123
                </div>
Kim, Subin's avatar
Kim, Subin committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
                <div className="d-flex flex-md-row flex-column-reverse justify-content-center my-3">
                    <div className="col-md-4 mb-4">
                        <div className="d-flex flex-column flex-sm-row flex-md-column justify-content-center text-sm-end text-center me-md-5">
                            <div>
                                <p className="d-inline-block col-3 col-sm-auto mb-0">일반</p>
                                <span>
                                    <CountButton name="adult" count={count} setCount={setCount} />
                                </span>
                            </div>
                            <div>
                                <p className="d-inline-block col-3 col-sm-auto mb-0">청소년</p>
                                <span>
                                    {ticketInfo.adult
                                        ?
                                        <CountButton name="youth" count={count} setCount={setCount} disabled />
                                        :
                                        <CountButton name="youth" count={count} setCount={setCount} />
                                    }
                                </span>
                            </div>
                            <div>
                                <p className="d-inline-block col-3 col-sm-auto mb-0">경로우대</p>
                                <span>
                                    <CountButton name="senior" count={count} setCount={setCount} />
                                </span>
149
150
151
                            </div>
                        </div>
                    </div>
Kim, Subin's avatar
Kim, Subin committed
152
                    <div className="col-md-5 mb-4 p-2 text-center" style={{ backgroundColor: '#252525' }}>
153
154
155
156
                        <div>{ticketInfo.cinema} | {ticketInfo.selectedTheater}</div>
                        <div>{ticketInfo.title}</div>
                        <div>{ticketInfo.time}</div>
                    </div>
Jiwon Yoon's avatar
Jiwon Yoon committed
157
                </div>
Kim, Subin's avatar
Kim, Subin committed
158
159
                <div className="d-flex flex-column align-items-center border p-5">
                    <div className="col-md-8 col-lg-7">
160
161
                        <SeatTable count={count} setSelectedSeats={setSelectedSeats} selectedSeats={selectedSeats} theaterInfo={theaterInfo} reservedSeats={reservedSeats} />
                    </div>
Kim, Subin's avatar
Kim, Subin committed
162
                    <div className="col-auto mt-5">
163
164
165
166
167
168
169
170
171
                        <div>
                            <button className={styles.on} style={{ height: '1rem', width: '1rem' }} disabled></button>
                            <span> 선택됨</span>
                        </div>
                        <div>
                            <button className={styles.btnBlock} style={{ height: '1rem', width: '1rem' }} disabled></button>
                            <span> 선택불가</span>
                        </div>
                    </div>
Jiwon Yoon's avatar
Jiwon Yoon committed
172
                </div>
173
                <div className="row p-3 mt-5" style={{ backgroundColor: "#252525" }}>
174
                    <div className="col-sm-2 mb-1 text-center">
175
                        {ticketInfo
176
                            ? <img style={{ width: "6rem" }} src={`https://image.tmdb.org/t/p/original${ticketInfo.poster_path}`} alt="영화포스터" />
177
178
                            : <div className="mb-2" style={{ color: "white" }}>영화선택</div>}
                    </div>
179
                    <div className="col-sm-4  mb-1" style={{ color: "white" }}>
180
181
182
183
                        {ticketInfo
                            ? <ul>
                                <li>영화: {ticketInfo.title}</li>
                                <li>극장: {ticketInfo.cinema}</li>
Jiwon Yoon's avatar
Jiwon Yoon committed
184
                                <li>일시: {ticketInfo.time} </li>
Jiwon Yoon's avatar
Jiwon Yoon committed
185
                                <li>상영관: {ticketInfo.selectedTheater}</li>
186
                                <li>좌석: {selectedSeats.map(el => String.fromCharCode(parseInt(el.split('-')[0]) + 64) + el.split('-')[1]) + ' '}</li>
187
                            </ul>
188
189
190
                            :
                            <div className="mb-2  text-center">극장선택</div>
                        }
191
                    </div>
192
193
194
195
196
197
198
199
200
201
202
203
204
205
                    <div className="col-sm-4  mb-1">
                        {selectedSeats
                            ?
                            <ul>
                                <li>성인: {count.adult}</li>
                                <li>청소년: {count.youth}</li>
                                <li>경로: {count.senior}</li>
                                <li className="mt-3"> 결제금액: {count.adult * ticketFee.adult + count.youth * ticketFee.youth + count.senior * ticketFee.senior}</li>
                            </ul>
                            : <></>}
                    </div>
                    <div className="col-sm-2 text-center  mb-1">
                        <div className="h5 mb-3">결제하기</div>
                        {selectedSeats.length > 0 && count.adult + count.youth + count.senior === selectedSeats.length
206
207
                            ?
                            <button onClick={loginModal} style={{ backgroundColor: '#252525', border: 0 }} >
208
                                <img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" style={{ width: "70px" }} alt="결제하기" />
209
210
                            </button>
                            :
211
212
                            <button onClick={() => { alert("좌석을 선택해주세요.") }} style={{ backgroundColor: '#252525', border: 0 }}>
                                <img className="border border-3 rounded-3" src="/images/icons8-arrow-white.png" style={{ width: "70px" }} alt="결제하기" />
213
                            </button>
Jiwon Yoon's avatar
Jiwon Yoon committed
214

215
216
                        }
                    </div>
Jiwon Yoon's avatar
Jiwon Yoon committed
217
218
                </div>
            </div>
219
        </>
Jiwon Yoon's avatar
Jiwon Yoon committed
220
221
222
223
    )
}

export default TicketingSeatPage