TimeTableEditForm.js 9.93 KB
Newer Older
Kim, Subin's avatar
Kim, Subin committed
1
2
3
import { useState, useEffect } from "react";
import movieApi from "../../apis/movie.api.js";
import theaterApi from "../../apis/theater.api.js";
4
import timetableApi from "../../apis/timetable.api.js";
Kim, Subin's avatar
Kim, Subin committed
5
6
7
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";

8
9
10
11
const INIT_INFO = {
    theater: 0,
    start: "",
    end: ""
Kim, Subin's avatar
Kim, Subin committed
12
13
14
15
}

const TimeTableEditForm = () => {
    const [movieList, setMovieList] = useState([])
Kim, Subin's avatar
Kim, Subin committed
16
    const [theaterList, setTheaterList] = useState([])
Kim, Subin's avatar
Kim, Subin committed
17
18
    const [selectId, setSelectId] = useState(0)
    const [selectMovie, setSelectMovie] = useState({})
19
20
    const [info, setInfo] = useState({ end_date: "" })
    const [selectInfo, setSelectInfo] = useState(INIT_INFO)
Kim, Subin's avatar
Kim, Subin committed
21
    const [showTimes, setShowTimes] = useState({ list: [] })
Kim, Subin's avatar
Kim, Subin committed
22
23
24
25
26
27
28
    const [error, setError] = useState("")

    useEffect(() => {
        getMoviesfromDB()
        getTheater()
    }, [])

29
30
31
32
33
    useEffect(() => {
        setSelectInfo({ ...selectInfo, ...INIT_INFO })
        setShowTimes({ list: [] })
    }, [selectId])

Kim, Subin's avatar
Kim, Subin committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    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()
Kim, Subin's avatar
Kim, Subin committed
48
            setTheaterList(res)
Kim, Subin's avatar
Kim, Subin committed
49
50
51
52
53
        } catch (error) {
            catchErrors(error, setError)
        }
    }

54
55
56
57
58
59
    function getDate(string) {
        const arr = string.split(':')
        const date = new Date(0, 0, 0, Number(arr[0]), Number(arr[1]))
        return date
    }

Kim, Subin's avatar
Kim, Subin committed
60
61
62
63
64
    function addRunTime(start, runTime) {
        const startArr = start.split(':')
        const add = Number(startArr[1]) + runTime

        let hours = Number(startArr[0]) + Math.floor(add / 60)
65
        if (Math.floor(hours / 24) > 0) hours = '0' + hours % 24
Kim, Subin's avatar
Kim, Subin committed
66
67
68
69
        else if (hours <= 9) hours = '0' + hours

        let mins = add % 60
        if (mins <= 9) mins = '0' + mins
70

Kim, Subin's avatar
Kim, Subin committed
71
        setSelectInfo({ ...selectInfo, "start": start, "end": hours + ':' + mins })
Kim, Subin's avatar
Kim, Subin committed
72
73
    }

Kim, Subin's avatar
Kim, Subin committed
74
75
76
77
    function addData() {
        const { list } = showTimes
        const isSelect = Object.values(selectInfo).every((el) => Boolean(el))
        if (isSelect) {
78
            const isTime = list.find(el => (el.theaterTypeId === selectInfo.theater) && ((getDate(el.start) <= getDate(selectInfo.start) && getDate(selectInfo.start) <= getDate(el.end)) || (getDate(el.start) > getDate(selectInfo.start) && getDate(el.start) <= getDate(selectInfo.end))))
79
80
81
82
83
84
85
86
87
88
89
90
91
            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('선택한 상영관을 찾지 못했습니다. 다시 시도하길 바랍니다.')
            }
Kim, Subin's avatar
Kim, Subin committed
92
        } else alert('추가할 데이터의 갯수가 부족합니다. 모든 항목을 입력해주시길 바랍니다.')
93
        setSelectInfo({ ...selectInfo, ...INIT_INFO })
Kim, Subin's avatar
Kim, Subin committed
94
95
96
97
    }

    function delData(index) {
        let { list } = showTimes
98
        list.splice(index, 1)
Kim, Subin's avatar
Kim, Subin committed
99
100
101
102
103
104
105
106
107
108
109
        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 })
110
                setInfo({ ...info, end_date: "" })
Kim, Subin's avatar
Kim, Subin committed
111
            } else if (name === "end_date") {
112
                setInfo({ ...info, [name]: value })
Kim, Subin's avatar
Kim, Subin committed
113
114
115
116
117
118
119
120
            } 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)
        }
Kim, Subin's avatar
Kim, Subin committed
121
122
123
124
    }

    async function handleSubmit(e) {
        e.preventDefault()
125
        const timeArr = []
Kim, Subin's avatar
Kim, Subin committed
126
127
        try {
            setError("")
128
129
130
131
132
133
134
135
136
137
138
139
            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)
Kim, Subin's avatar
Kim, Subin committed
140
141
142
143
            alert("해당 상영시간표 정보 등록이 성공적으로 완료되었습니다.")
            window.location.reload()
        } catch (error) {
            catchErrors(error, setError)
Kim, Subin's avatar
Kim, Subin committed
144
            setShowTimes({ list: [] })
Kim, Subin's avatar
Kim, Subin committed
145
146
147
148
        }
    }

    return (
Kim, Subin's avatar
Kim, Subin committed
149
        <form className="col-12 col-lg-6 me-lg-1 mb-5 mb-lg-0" onSubmit={handleSubmit}>
150
            <h5 className={`border-top border-dark border-2 pt-3 mb-3 ${styles.borderLg}`}>상영시간표 등록</h5>
Kim, Subin's avatar
Kim, Subin committed
151
            <select className={`form-select mb-3 ${styles.shadowNone} ${styles.selectInput}`} id="movieId" name="movieId" value={selectId} onChange={handleChange} aria-label="select movie" defaultValue="0">
Kim, Subin's avatar
Kim, Subin committed
152
153
154
155
156
157
158
159
160
161
                {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>
Kim, Subin's avatar
Kim, Subin committed
162
163
164
165
166
167
168
169
170
            <div className="d-flex justify-content-between">
                <div className="col-md-5 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-5 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>
Kim, Subin's avatar
Kim, Subin committed
171
172
            </div>
            <p>시간대 설정</p>
Kim, Subin's avatar
Kim, Subin committed
173
174
175
176
177
            <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>
Kim, Subin's avatar
Kim, Subin committed
178
                    </li>) : <li className="list-group-item text-center">추가된 시간대가 없습니다. 아래 양식을 작성해 시간대를 추가해 주세요.</li>}
Kim, Subin's avatar
Kim, Subin committed
179
            </ul>
Kim, Subin's avatar
Kim, Subin committed
180
181
            <div className="d-sm-flex flex-lg-column">
                <div className="col-sm-5 col-lg-12">
Kim, Subin's avatar
Kim, Subin committed
182
183
184
                    <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) => {
Kim, Subin's avatar
Kim, Subin committed
185
186
187
188
189
190
191
192
193
                                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>
Kim, Subin's avatar
Kim, Subin committed
194
195
196
197
198
199
200
201
                <div className="d-flex justify-content-between col-sm-7 col-lg-auto mb-3">
                    <div className="d-flex col-auto">
                        <div className="col-auto ms-sm-2 ms-lg-0">
                            <input type="time" className={`form-control ${styles.shadowNone}`} id="start" name="start" value={selectInfo.start} onChange={handleChange} disabled={!selectId || !selectInfo.theater} />
                        </div>
                        <p className="align-self-center ms-2 mb-0">{(selectId && selectInfo.start !== "") ? "~ " + selectInfo.end : ""}</p>
                    </div>
                    <button type="button" className={`btn btn-dark col-auto ${styles.customBtn}`} onClick={addData}>추가</button>
Kim, Subin's avatar
Kim, Subin committed
202
203
                </div>
            </div>
Kim, Subin's avatar
Kim, Subin committed
204
205
            <div className="d-grid gap-2">
                <button type="submit" className={`btn btn-dark ${styles.customBtn}`} disabled={showTimes.list.length === 0 ? true : false}>등록</button>
Kim, Subin's avatar
Kim, Subin committed
206
207
208
209
210
211
            </div>
        </form>
    )
}

export default TimeTableEditForm