Commit e81c36c5 authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

Merge branch 'master' into jiwon

parents 2133a2a0 312689ae
import axios from "axios"; import axios from "axios";
import { baseUrl } from "../utils/baseUrl.js"; import { baseUrl } from "../utils/baseUrl.js";
const getAll = async (selectDate) => {
const { data } = await axios.get(`${baseUrl}/api/timetable?when=${selectDate}`)
return data
}
const submit = async (sendData) => { const submit = async (sendData) => {
const { data } = await axios.post(`${baseUrl}/api/timetable`, sendData) const { data } = await axios.post(`${baseUrl}/api/timetable`, sendData)
return data return data
} }
const remove = async () => {
const { data } = await axios.delete(`${baseUrl}/api/timetable/`)
return data
}
const timetableApi = { const timetableApi = {
submit getAll,
submit,
remove
} }
export default timetableApi export default timetableApi
\ No newline at end of file
import { useState, useEffect } from "react";
import moment from 'moment';
import Calender from "../Calender/Calender.js";
import timetableApi from "../../apis/timetable.api.js";
import catchErrors from "../../utils/catchErrors.js";
const TimeTable = () => { const TimeTable = () => {
const [selectDate, setSelectDate] = useState(moment().format('YYYY-MM-DD'))
const [timeList, setTimeList] = useState([])
const [error, setError] = useState("")
useEffect(() => {
getTimeTable(selectDate)
}, [selectDate])
async function getTimeTable() {
try {
setError("")
const res = await timetableApi.getAll(selectDate)
setTimeList(res)
} catch (error) {
catchErrors(error, setError)
}
}
async function deleteTime() {
try {
setError("")
await timetableApi.remove()
alert('해당 상영시간표 정보를 성공적으로 삭제하였습니다.')
getTimeTable(selectDate)
} catch (error) {
catchErrors(error, setError)
}
}
return ( return (
<div className="col-6"> <div className="col-12 col-lg-6">
{console.log("list==", timeList)}
<Calender selectDate={selectDate} setSelectDate={setSelectDate} />
{timeList.length !== 0 ?
timeList.map(el => <>
<h5>{el.theaterName} </h5>
{/* {arr = el.timetable.map(time => <div className="card">
<div className="card-body">{moment(time.start_time, 'hh:mm')} ~ {moment(time.end_time, 'hh:mm')}</div>
</div>
)
} */}
{/* {el.timetable.map(time => {
if (el.id === time.id) return <div className="card">
<div className="card-body">{moment(time.start_time, 'hh:mm')} ~ {moment(time.end_time, 'hh:mm')}</div>
</div>
})} */}
</>)
: <></>}
</div> </div>
) )
} }
......
...@@ -2,12 +2,13 @@ import TimeTableEditForm from "./TimeTableEditForm"; ...@@ -2,12 +2,13 @@ import TimeTableEditForm from "./TimeTableEditForm";
import TimeTable from "./TimeTable"; import TimeTable from "./TimeTable";
const TimeTableEdit = () => { const TimeTableEdit = () => {
return ( return (
<> <>
<h2 className="border-bottom border-2 text-center pb-2 me-2">현재 상영시간표 정보</h2> <h2 className="border-bottom border-2 text-center pb-2 me-2">현재 상영시간표 정보</h2>
<div className="d-flex"> <div className="d-flex flex-column flex-lg-row-reverse">
<TimeTableEditForm />
<TimeTable /> <TimeTable />
<TimeTableEditForm />
</div> </div>
</> </>
) )
......
...@@ -75,7 +75,7 @@ const TimeTableEditForm = () => { ...@@ -75,7 +75,7 @@ const TimeTableEditForm = () => {
const { list } = showTimes const { list } = showTimes
const isSelect = Object.values(selectInfo).every((el) => Boolean(el)) const isSelect = Object.values(selectInfo).every((el) => Boolean(el))
if (isSelect) { if (isSelect) {
const isTime = list.find(el => el.theaterTypeId === selectInfo.theater && (getDate(el.start) <= getDate(selectInfo.end) && getDate(el.end) >= getDate(selectInfo.start))) 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)))
if (isTime) alert('이미 추가한 상영시간대입니다. 다른 시간대를 골라주시기 바랍니다.') if (isTime) alert('이미 추가한 상영시간대입니다. 다른 시간대를 골라주시기 바랍니다.')
else { else {
const theater = theaterList.find(theater => theater.theatertypeId === selectInfo.theater) const theater = theaterList.find(theater => theater.theatertypeId === selectInfo.theater)
...@@ -141,11 +141,12 @@ const TimeTableEditForm = () => { ...@@ -141,11 +141,12 @@ const TimeTableEditForm = () => {
window.location.reload() window.location.reload()
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
setShowTimes({ list: [] })
} }
} }
return ( return (
<form className="col-6" onSubmit={handleSubmit}> <form className="col-12 col-lg-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"> <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.length !== 0 ?
movieList.map((movie, index) => { movieList.map((movie, index) => {
...@@ -157,24 +158,26 @@ const TimeTableEditForm = () => { ...@@ -157,24 +158,26 @@ const TimeTableEditForm = () => {
}) })
: <option value="0" disabled>서버에 등록된 영화가 없습니다.</option>} : <option value="0" disabled>서버에 등록된 영화가 없습니다.</option>}
</select> </select>
<div className="col-md-6 mb-3"> <div className="d-flex justify-content-between">
<div className="col-md-5 mb-3">
<label htmlFor="release_date" className="form-label">상영시작일</label> <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 /> <input type="text" className={`form-control ${styles.shadowNone}`} id="release_date" name="release_date" value={selectMovie?.release_date || ''} disabled />
</div> </div>
<div className="col-md-6 mb-3"> <div className="col-md-5 mb-3">
<label htmlFor="end_date" className="form-label">상영종료일</label> <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} /> <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> </div>
</div>
<p>시간대 설정</p> <p>시간대 설정</p>
<ul className="list-group list-group-flush"> <ul className="list-group list-group-flush">
{showTimes.list.length !== 0 ? {showTimes.list.length !== 0 ?
showTimes.list.map((timeInfo, index) => <li className="list-group-item d-flex justify-content-between align-items-center"> 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} {timeInfo.theaterName}&nbsp;&nbsp;&nbsp;{timeInfo.start} ~ {timeInfo.end}
<button type="button" className="btn btn-danger" onClick={() => delData(index)}>삭제</button> <button type="button" className="btn btn-danger" onClick={() => delData(index)}>삭제</button>
</li>) : <li className="list-group-item text-center">추가된 시간대가 없습니다. 을 작성해 시간대를 추가해 주세요.</li>} </li>) : <li className="list-group-item text-center">추가된 시간대가 없습니다. 아래 양식을 작성해 시간대를 추가해 주세요.</li>}
</ul> </ul>
<div> <div className="d-sm-flex flex-lg-column">
<div> <div className="col-sm-5 col-lg-12">
<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"> <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.length !== 0 ?
theaterList.map((theater, index) => { theaterList.map((theater, index) => {
...@@ -187,16 +190,18 @@ const TimeTableEditForm = () => { ...@@ -187,16 +190,18 @@ const TimeTableEditForm = () => {
: <option value="0" disabled>서버에 등록된 상영관이 없습니다.</option>} : <option value="0" disabled>서버에 등록된 상영관이 없습니다.</option>}
</select> </select>
</div> </div>
<div> <div className="d-flex justify-content-between col-sm-7 col-lg-auto mb-3">
<input type="time" id="start" name="start" value={selectInfo.start} onChange={handleChange} disabled={!selectId || !selectInfo.theater} /> <div className="d-flex col-auto">
<p>{(selectId && selectInfo.start !== "") ? "~ " + selectInfo.end : ""}</p> <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> </div>
<div> <button type="button" className={`btn btn-dark col-auto ${styles.customBtn}`} onClick={addData}>추가</button>
<button type="button" className={`btn btn-dark ${styles.customBtn}`} onClick={addData}>추가</button>
</div> </div>
</div> </div>
<div> <div className="d-grid gap-2">
<button type="submit" className={`btn btn-dark ${styles.customBtn}`}>등록</button> <button type="submit" className={`btn btn-dark ${styles.customBtn}`} disabled={showTimes.list.length === 0 ? true : false}>등록</button>
</div> </div>
</form> </form>
) )
......
import { useState, useEffect } from "react";
import moment from "moment";
import styles from "./calender.module.scss";
const Calender = ({ selectDate, setSelectDate }) => {
const [dateList, setDateList] = useState([])
const [week, setWeek] = useState(["", "", "", "", "", "", ""])
useEffect(() => {
getDate(selectDate)
}, [])
function getDate(oneDay) {
let dateArr = []
let lastWeek = moment(oneDay).subtract(7, 'days')
const nextWeek = moment(oneDay).add(7, 'days')
while (lastWeek.isBefore(nextWeek)) {
dateArr.push({ date: lastWeek.format('YYYY-MM-DD'), day: lastWeek.format('d') })
lastWeek.add(1, 'days')
}
console.log("arr=", dateArr)
console.log("same==", moment(oneDay).isSame('2021-08-07'))
const resultArr = dateArr.map(el => <div onClick={() => setSelectDate(el.date)}>
{moment(el.date).isSame(oneDay) || el.date.split('-')[2] === "01" ? <strong>{moment(el.date).format('YYYY.MM')}</strong> : ""}
<div>
<strong>{moment(el.date).format('DD')}</strong>
<em>{moment(el.date).isSame(oneDay) ? "오늘" : week[el.day]}</em>
</div>
</div>)
setDateList(resultArr)
}
return (
<>
{console.log("date==", selectDate)}
<div>
<i className="bi bi-chevron-left"></i>
{dateList.map(el => el)}
<i className="bi bi-chevron-right"></i>
</div>
</>
)
}
export default Calender
\ No newline at end of file
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
"express": "^4.17.1", "express": "^4.17.1",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"moment": "^2.29.1",
"multer": "^1.4.2", "multer": "^1.4.2",
"nodemailer": "^6.6.3", "nodemailer": "^6.6.3",
"pg": "^8.6.0", "pg": "^8.6.0",
......
import { TimeTable } from "../db/index.js"; import { TimeTable, Theater } from "../db/index.js";
import moment from 'moment';
import sequelize from 'sequelize' import sequelize from 'sequelize'
const { Op } = sequelize const { Op } = sequelize
const getAll = async (req, res) => {
try {
const { when } = req.query
const selectDate = new Date(when)
const theaterArr = []
// const timeTableArr = []
const findAll = await TimeTable.findAll({ where: { date: selectDate }, attributes: { exclude: ['createdAt', 'updatedAt'] }, order: [["theater", "ASC"], ["start_time", "ASC"]] })
findAll.forEach(element => {
if (!theaterArr.includes(element.theater)) theaterArr.push(element.theater)
})
const findTheater = await Theater.findAll({ where: { id: theaterArr }, attributes: { exclude: ['createdAt', 'updatedAt'] }, order: [['theaterName']] })
findTheater.forEach(el => {
const arr = findAll.filter(timetable => {
if (el.id === timetable.theater) return timetable.dataValues
})
el.dataValues.timetable = arr
// timeTableArr.push({ id: el.id, info: arr })
})
return res.json(findTheater)
// return res.json({findTheater, timeTableArr})
} catch (error) {
return res.status(500).send(error.message || "상영시간표 정보 가져오는 중 에러 발생")
}
}
const submit = async (req, res) => { const submit = async (req, res) => {
try { try {
console.log("req.body==", req.body) const { movieId, title, theater, runtime, release_date, date } = req.body
const { theater, runtime } = req.body const result = await Promise.all(
const result = theater.filter(async (theater) => { theater.map(async (theater) => {
const startDate = getDate(theater.start) const startTime = getTime(theater.start)
const endDate = getDate(theater.start, runtime) const endTime = getTime(theater.start, runtime)
// const isTimeTable = await TimeTable.findAll({ const isTimeTable = await TimeTable.findAll({
// where: { where: {
// [Op.and]: [ [Op.and]: [
// { theater: theater.theater }, { theater: theater.theater },
// { {
// [Op.and]: [ [Op.or]: [
// { start_date: { [Op.lte]: endDate } }, { [Op.and]: [{ start_time: { [Op.gt]: startTime } }, { end_time: { [Op.lte]: endTime } }] },
// { end_date: { [Op.gte]: startDate } } { start_time: { [Op.between]: [startTime, endTime] } }
// ] ]
// } }
// ] ]
// } }
// }) })
// [Op.or]: [{ [Op.and]: [{ start_date: { [Op.gt]: startDate } }, { start_date: { [Op.gt]: endDate } }] }, if (isTimeTable.length !== 0) return "unvalid"
// { [Op.and]: [{ end_date: { [Op.lt]: startDate } }, { end_date: { [Op.lt]: endDate } }] }] else return "valid"
console.log("isTimeTable==", isTimeTable) })
return isTimeTable )
result.map(el => {
if (el !== "valid") throw new Error("유효하지 않은 데이터입니다. 다시 등록해주시길 바랍니다.")
}) })
console.log("result==", result) let curDate = new Date(release_date)
const endDate = new Date(date)
do {
let day = curDate.getDay()
await Promise.all(
theater.map(async (theater) => {
let partTime = ""
if ('06:00' <= theater.start < '10:00') partTime = "morning"
else if ('00:00' <= theater.start < '06:00') partTime = "night"
else partTime = "day"
await TimeTable.create({ theater: theater.theater, movieId, title, release_date, date: curDate, start_time: getTime(theater.start), end_time: getTime(theater.start, runtime), partTime: partTime, week: (day === 0 || day === 6) ? "weekend" : "weekdays" })
})
)
curDate.setDate(curDate.getDate() + 1)
} while (curDate <= endDate)
res.send("success!")
} catch (error) { } catch (error) {
return res.status(500).send(error.message || "상영시간표 저장 중 에러 발생") return res.status(500).send(error.message || "상영시간표 저장 중 에러 발생")
} }
} }
const getDate = (string, runtime = 0) => { const getTime = (string, runtime = 0) => {
const arr = string.split(':') const arr = string.split(':')
const date = new Date(0, 0, 0, Number(arr[0]), Number(arr[1]) + runtime) const date = new Date(0, 0, 0, Number(arr[0]), Number(arr[1]) + runtime)
// console.log("custom==", date.toString())
return date return date
} }
const remove = async (req, res) => {
try {
const { timeId } = req.params
const delNum = await TimeTable.destroy({ where: {} })
if (delNum) res.json(delNum)
else throw new Error("해당 정보를 서버에서 삭제하는데 실패했습니다.")
} catch (error) {
return res.status(500).send(error.message || "상영시간표 삭제 중 에러 발생")
}
}
export default { export default {
submit getAll,
submit,
remove
} }
\ No newline at end of file
...@@ -6,7 +6,7 @@ import CinemaModel from "../models/cinema.model.js"; ...@@ -6,7 +6,7 @@ import CinemaModel from "../models/cinema.model.js";
import TheaterModel from "../models/theater.model.js"; import TheaterModel from "../models/theater.model.js";
import TheaterTypeModel from "../models/theatertype.model.js"; import TheaterTypeModel from "../models/theatertype.model.js";
import TicketFeeModel from "../models/ticketfee.model.js"; import TicketFeeModel from "../models/ticketfee.model.js";
import TimeTableModel from '../models/role.model.js'; import TimeTableModel from '../models/timetable.model.js';
import ReservationModel from '../models/reservation.model.js'; import ReservationModel from '../models/reservation.model.js';
import GuestModel from '../models/guest.model.js' import GuestModel from '../models/guest.model.js'
import ConfirmNumModel from '../models/confirmnum.model.js' import ConfirmNumModel from '../models/confirmnum.model.js'
......
...@@ -20,23 +20,26 @@ const TimeTableModel = (sequelize) => { ...@@ -20,23 +20,26 @@ const TimeTableModel = (sequelize) => {
title: { title: {
type: DataTypes.STRING, type: DataTypes.STRING,
}, },
runtime: {
type: DataTypes.INTEGER,
},
release_date: { release_date: {
type: DataTypes.STRING type: DataTypes.STRING
}, },
start_date: { date: {
type: DataTypes.DATE,
},
start_time: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: new Date(0) defaultValue: new Date(0)
}, },
end_date: { end_time: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: new Date(0) defaultValue: new Date(0)
}, },
time: { partTime: {
type: DataTypes.TIME, type: DataTypes.STRING,
}, },
week: {
type: DataTypes.STRING
}
}, },
{ {
// timestamps: true, // timestamps: true,
......
...@@ -5,6 +5,11 @@ const router = express.Router(); ...@@ -5,6 +5,11 @@ const router = express.Router();
router router
.route("/") .route("/")
.get(timetableCtrl.getAll)
.post(timetableCtrl.submit) .post(timetableCtrl.submit)
router
.route("/:timeId")
.delete(timetableCtrl.remove)
export default router; export default router;
\ No newline at end of file
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