Commit 9fdda5c9 authored by Kim, Subin's avatar Kim, Subin
Browse files

theater

parent 01c7acd7
import axios from "axios";
import { baseUrl } from "../utils/baseUrl.js";
const getAll = async () => {
const { data } = await axios.get(`${baseUrl}/api/theater`)
return data
}
const getOne = async () => {
const { data } = await axios.get(`${baseUrl}/api/theater`)
return data
}
const getTheaterType = async () => {
const { data } = await axios.get(`${baseUrl}/api/theater/type`)
return data
}
const sendData = async (theater) => {
const { data } = await axios.put(`${baseUrl}/api/theater/type`, theater)
return data
}
const remove = async () => {
const { data } = await axios.delete(`${baseUrl}/api/theater`)
return data
}
const theaterApi = {
getAll,
getOne,
getTheaterType,
sendData,
remove
}
export default theaterApi
\ No newline at end of file
import { Link, Route, Switch, useRouteMatch } from "react-router-dom";
import MovieEdit from "./MovieEdit";
import TheaterEdit from "./TheaterEdit";
import TimeTableEdit from "./TimeTableEdit";
import CinemaEdit from "./CinemaEdit";
import styles from "./admin.module.scss";
......@@ -16,6 +17,9 @@ const Admin = () => {
<li className="nav-item">
<Link to={`${match.url}/theater`} className="nav-link text-dark text-center">상영관 관리</Link>
</li>
<li className="nav-item">
<Link to={`${match.url}/timetable`} className="nav-link text-dark text-center">상영시간표 관리</Link>
</li>
<li className="nav-item">
<Link to={`${match.url}/cinema`} className="nav-link text-dark text-center">영화관 관리</Link>
</li>
......@@ -24,6 +28,7 @@ const Admin = () => {
<Switch>
<Route path={`${match.path}/movie`}><MovieEdit /></Route>
<Route path={`${match.path}/theater`}><TheaterEdit /></Route>
<Route path={`${match.path}/timetable`}><TimeTableEdit /></Route>
<Route path={`${match.path}/cinema`}><CinemaEdit /></Route>
<Route path={`${match.path}`}><MovieEdit /></Route>
</Switch>
......
......@@ -53,19 +53,19 @@ const CinemaEdit = () => {
<>
<h2 className="border-bottom border-2 text-center pb-2 me-2">현재 영화관 정보</h2>
<div className="mb-3">
<label for="cinemaName" className="form-label">영화관 이름</label>
<label htmlfor="cinemaName" className="form-label">영화관 이름</label>
<input type="text" className={`form-control mb-2 ${styles.shadowNone}`} id="cinemaName" name="cinemaName" value={cinemaInfo.cinemaName} onChange={handleChange} />
<p> 상영관 : 8개관 | 좌석 : 1,282</p>
</div>
<div className="mb-3">
<label for="transportation" className="form-label">대중교통 안내</label>
<label htmlfor="transportation" className="form-label">대중교통 안내</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="transportation" name="transportation" value={cinemaInfo.transportation} onChange={handleChange}></textarea>
</div>
<div className="mb-3">
<label for="parking" className="form-label">자가용/주차안내</label>
<label htmlfor="parking" className="form-label">자가용/주차안내</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="parking" name="parking" value={cinemaInfo.parking} onChange={handleChange}></textarea>
</div>
<label for="keyword" className="form-label">지도보기</label>
<label htmlfor="keyword" className="form-label">지도보기</label>
<div className="input-group mb-3">
<span className="input-group-text" id="address"><i className="bi bi-geo-alt-fill"></i></span>
<input type="text" className={`form-control ${styles.shadowNone}`} id="address" name="address" value={cinemaInfo.address} onChange={handleChange} value={cinemaInfo.address} />
......@@ -75,7 +75,7 @@ const CinemaEdit = () => {
<TicketEditForm editFee={ticketFee} formRef={formRef} />
<TicketFeeTable setEditFee={setTicketFee} formRef={formRef} />
<div className="mb-3">
<label for="moreFeeInfo" className="form-label">관람료 추가정보</label>
<label htmlfor="moreFeeInfo" className="form-label">관람료 추가정보</label>
<textarea className={`form-control ${styles.shadowNone} ${styles.textarea}`} rows="7" id="moreFeeInfo" name="moreFeeInfo" value={cinemaInfo.moreFeeInfo} onChange={handleChange}></textarea>
</div>
<div className="d-grid gap-2 mb-5">
......
import { useState, useRef } from "react";
import TheaterTable from "./TheaterTable";
import TheaterEditForm from "./TheaterEditForm";
const TheaterEdit = () => {
return (
<div>
const [edit, setEdit] = useState({})
const formRef = useRef(null)
</div>
return (
<>
<h2 className="border-bottom border-2 text-center pb-2 me-2">현재 상영관 정보</h2>
<TheaterTable setEdit={setEdit} formRef={formRef} />
<h5 className="mb-3">상영관 정보 설정</h5>
<TheaterEditForm edit={edit} formRef={formRef} />
</>
)
}
export default TheaterEdit
\ No newline at end of file
import { useState, useEffect } from "react";
import theaterApi from "../../apis/theater.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";
const INIT_THEATER = {
theaterName: "",
theaterType: 0,
rows: 1,
columns: 1
}
const TheaterEditForm = ({ edit, formRef }) => {
const [theater, setTheater] = useState(INIT_THEATER)
const [types, setTypes] = useState([])
const [error, setError] = useState("")
useEffect(() => {
getTypeList()
}, [])
useEffect(() => {
setTheater({ ...theater, ...edit })
}, [edit])
async function getTypeList() {
try {
setError("")
const resTypes = await theaterApi.getTheaterType()
setTypes(resTypes)
} catch (error) {
catchErrors(error, setError)
}
}
function handleChange(e) {
const { name, value } = e.target
setTheater({ ...theater, [name]: value })
}
async function handleSubmit(e) {
e.preventDefault()
try {
setError("")
await theaterApi.sendData(theater)
alert("해당 상영관 정보 등록이 성공적으로 완료되었습니다.")
window.location.reload()
} catch (error) {
catchErrors(error, setError)
}
}
return (
<form ref={formRef} onSubmit={handleSubmit}>
<div className="d-flex justify-content-lg-between row row-cols-2 row-cols-lg-4 gx-0 gy-2 gy-lg-0 mb-2 mb-lg-3">
<label htmlfor="theaterName" className="col-3 col-lg-auto col-form-label">상영관 이름</label>
<div className="col-9 col-lg-4">
<input className={`form-control ${styles.shadowNone}`} id="theaterName" name="theaterName" type="text" value={theater.theaterName} onChange={handleChange} />
</div>
<label htmlfor="theaterType" className="col-3 col-lg-auto col-form-label text-lg-center">상영관 종류</label>
<div className="col-9 col-lg-5">
<select className={`form-select ${styles.shadowNone} ${styles.selectInput}`} id="theaterType" name="theaterType" onChange={handleChange} aria-label="select theaterType" defaultValue={theater.theaterType}>
{types.length !== 0 ?
types.map((type, index) => {
if (index === 0) return <>
<option value="0" disabled>상영관 종류를 선택해주십시오.</option>
<option value={type.id}>{type.theaterType}</option>
</>
else return <option value={type.id}>{type.theaterType}</option>
})
: <option value="0" disabled>서버에 등록된 상영관 종류가 없습니다.</option>}
</select>
</div>
</div>
<div className="d-flex flex-wrap row row-cols-2 gx-0 gy-2 gy-lg-0">
<label htmlfor="seatInfo" className="col-3 col-lg-auto col-form-label me-lg-4">좌석 정보</label>
<div className="d-flex col-9 col-sm-5">
<div className="col-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} id="rows" name="rows" type="number" min="1" max="26" value={theater.rows} onChange={handleChange} />
</div>
<label htmlfor="rows" className="col-form-label mx-2"></label>
<div className="col-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} id="columns" name="columns" type="number" min="1" value={theater.columns} onChange={handleChange} />
</div>
<label htmlfor="columns" className="col-form-label mx-2"></label>
</div>
<div className="col-12 col-sm-auto ms-sm-auto">
<button type="submit" className={`btn btn-dark w-100 ${styles.customBtn}`}>추가</button>
</div>
</div>
</form>
)
}
export default TheaterEditForm
\ No newline at end of file
import { useState, useEffect } from "react";
import theaterApi from "../../apis/theater.api.js";
import catchErrors from "../../utils/catchErrors.js";
import styles from "./admin.module.scss";
const TheaterTable = ({ setEdit, formRef }) => {
const [theaterList, setTheaterList] = useState([])
const [error, setError] = useState("")
useEffect(() => {
getTheaterList()
}, [])
async function getTheaterList() {
try {
setError("")
const list = await theaterApi.getAll()
setTheaterList(list)
} catch (error) {
catchErrors(error, setError)
}
}
async function editTheater() {
try {
setError("")
const res = await theaterApi.getOne()
setEdit({ ...res })
formRef?.current.scrollIntoView({ behavior: "smooth", block: "center" })
} catch (error) {
catchErrors(error, setError)
}
}
async function deleteTheater() {
try {
setError("")
await theaterApi.remove()
alert("해당 상영관 정보를 성공적으로 삭제했습니다.")
getTheaterList()
} catch (error) {
catchErrors(error, setError)
}
}
return (
<table className={`table text-center align-middle ${styles.tableForm}`}>
<thead className={`table-dark align-middle ${styles.dNone}`}>
<tr>
<th>상영관 이름</th>
<th>상영관 종류</th>
<th>좌석 정보</th>
<th></th>
</tr>
</thead>
<tbody>
{theaterList.length !== 0 ? theaterList.map(info =>
<tr>
<td>ads</td>
<td>ads</td>
<td>ads</td>
<td>
<div className="d-flex flex-column">
<button type="button" className="btn btn-primary my-1" onClick={() => editTheater()}>수정</button>
<button type="button" className="btn btn-danger my-1" onClick={() => deleteTheater()}>삭제</button>
</div>
</td>
</tr>)
: <tr>
<td colSpan="4">등록된 상영관 정보가 없습니다.</td>
</tr>}
</tbody>
</table>
)
}
export default TheaterTable
\ No newline at end of file
......@@ -44,49 +44,49 @@ const TicketEditForm = ({ editFee, formRef }) => {
return (
<form ref={formRef} onSubmit={handleSubmit}>
<div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="theaterType" className="col-md-auto col-form-label text-center text-md-start">상영관 종류</label>
<label htmlfor="theaterType" className="col-md-auto col-form-label text-center text-md-start">상영관 종류</label>
<div className="col-md-4 col-lg-3 mx-md-2">
<input className={`form-control ${styles.shadowNone}`} type="text" id="theaterType" name="theaterType" value={ticketFee.theaterType} onChange={handleChange} />
</div>
<label for="defaultPrice" className="col-md-auto col-form-label text-center text-md-start">기본 가격</label>
<label htmlfor="defaultPrice" className="col-md-auto col-form-label text-center text-md-start">기본 가격</label>
<div className="col-md-3 col-lg-2 mx-md-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="defaultPrice" name="defaultPrice" value={ticketFee.defaultPrice} onChange={handleChange} />
</div>
</div>
<div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="weekdays" className="col-md-1 col-form-label text-center text-md-start">주중</label>
<label htmlfor="weekdays" className="col-md-1 col-form-label text-center text-md-start">주중</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="weekdays" name="weekdays" value={ticketFee.weekdays} onChange={handleChange} />
</div>
<label for="weekend" className="col-md-1 col-form-label text-center">주말</label>
<label htmlfor="weekend" className="col-md-1 col-form-label text-center">주말</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="weekend" name="weekend" value={ticketFee.weekend} onChange={handleChange} />
</div>
</div>
<div className="d-flex row row-cols-2 mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="morning" className="col-md-1 col-form-label text-center text-md-start">조조</label>
<label htmlfor="morning" className="col-md-1 col-form-label text-center text-md-start">조조</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="morning" name="morning" value={ticketFee.morning} onChange={handleChange} />
</div>
<label for="day" className="col-md-1 col-form-label text-center">일반</label>
<label htmlfor="day" className="col-md-1 col-form-label text-center">일반</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="day" name="day" value={ticketFee.day} onChange={handleChange} />
</div>
<label for="night" className="col-md-1 col-form-label text-center">심야</label>
<label htmlfor="night" className="col-md-1 col-form-label text-center">심야</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="night" name="night" value={ticketFee.night} onChange={handleChange} />
</div>
</div>
<div className="d-flex row row-cols-2 flex-wrap flex-lg-nowrap mb-2 mb-md-3 gx-0 gy-2 gy-md-0">
<label for="youth" className="col-md-1 col-form-label text-center text-md-start">청소년</label>
<label htmlfor="youth" className="col-md-1 col-form-label text-center text-md-start">청소년</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="youth" name="youth" value={ticketFee.youth} onChange={handleChange} />
</div>
<label for="adult" className="col-md-1 col-form-label text-center">일반</label>
<label htmlfor="adult" className="col-md-1 col-form-label text-center">일반</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="adult" name="adult" value={ticketFee.adult} onChange={handleChange} />
</div>
<label for="senior" className="col-md-1 col-form-label text-center">경로</label>
<label htmlfor="senior" className="col-md-1 col-form-label text-center">경로</label>
<div className="col-md-3 col-lg-2">
<input className={`form-control ${styles.shadowNone}`} type="number" id="senior" name="senior" value={ticketFee.senior} onChange={handleChange} />
</div>
......
const TimeTableEdit = () => {
return (
<>
</>
)
}
export default TimeTableEdit
\ No newline at end of file
......@@ -44,6 +44,12 @@
}
}
.selectInput {
& option[disabled] {
color: #000;
}
}
.word {
word-break: keep-all;
}
......
import { Theater, TicketFee } from "../db/index.js";
const getAll = async (req, res) => {
try {
const findList = await Theater.findAll({ include: [{ model: TicketFee, attributes: ["theaterType"] }] })
console.log("Ads==", findList)
return res.json(findList)
} catch (error) {
return res.status(500).send(error.message || "상영관 정보 가져오는 중 에러 발생")
}
}
const getTypes = async (req, res) => {
try {
const findTypes = await TicketFee.findAll({ attributes: ['id', 'theaterType'] })
return res.json(findTypes)
} catch (error) {
return res.status(500).send(error.message || "상영관 정보 가져오는 중 에러 발생")
}
}
const submit = async (req, res) => {
try {
const { id } = req.body
let response = null
if (id) response = await Theater.update({ ...req.body }, { where: { id: id } })
else response = await Theater.create({ ...req.body })
return res.json(response)
} catch (error) {
return res.status(500).send(error.message || "상영관 정보 저장 중 에러 발생")
}
}
const remove = async (req, res) => {
try {
} catch (error) {
return res.status(500).send(error.message || "상영관 정보 삭제 중 에러 발생")
}
}
export default {
getAll,
getTypes,
submit,
remove
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import RoleModel from "../models/role.model.js";
import MovieModel from "../models/movie.model.js";
import CinemaModel from "../models/cinema.model.js";
import TheaterModel from "../models/theater.model.js";
import TheaterTypeModel from "../models/theatertype.model.js";
import TicketFeeModel from "../models/ticketfee.model.js";
import TimeTableModel from '../models/role.model.js';
import ReservationModel from '../models/reservation.model.js';
......@@ -30,6 +31,7 @@ const Role = RoleModel(sequelize)
const Movie = MovieModel(sequelize)
const Cinema = CinemaModel(sequelize)
const Theater = TheaterModel(sequelize)
const TheaterType = TheaterTypeModel(sequelize)
const TicketFee = TicketFeeModel(sequelize)
const TimeTable = TimeTableModel(sequelize)
const Reservation = ReservationModel(sequelize)
......@@ -37,7 +39,9 @@ const Reservation = ReservationModel(sequelize)
User.belongsTo(Role);
Role.hasOne(User);
TicketFee.hasOne(Theater, { foreignKey: "theaterType", targetKey: "theaterType", onDelete : "Cascade" });
Theater.belongsTo(TheaterType);
TicketFee.belongsTo(TheaterType, { onDelete: 'CASCADE' });
export {
sequelize,
......@@ -46,6 +50,7 @@ export {
Movie,
Cinema,
Theater,
TheaterType,
TicketFee,
TimeTable,
Reservation
......
......@@ -19,7 +19,6 @@ sequelize
);
const adminRole = await Role.findOne({ where: { name: "admin" } });
console.log("adminRole : ", adminRole);
// if (!adminRole) {
await User.create({
userId: "admin",
......@@ -30,7 +29,7 @@ sequelize
password: "admin!",
roleId: adminRole?.id,
});
// }else{}
// }
app.listen(appConfig.port, () => {
console.log(`Server is running on port ${appConfig.port}`);
......
......@@ -6,9 +6,13 @@ const TheaterModel = (sequelize) => {
const Theater = sequelize.define(
"theater",
{
theaterNum: {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
theaterName: {
type: DataTypes.STRING
},
rows: {
type: DataTypes.STRING,
......
import Sequelize from "sequelize";
const { DataTypes } = Sequelize;
const TheaterTypeModel = (sequelize) => {
const TheaterType = sequelize.define(
"theatertype",
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
theaterTypeName: {
type: DataTypes.STRING,
unique: true
}
},
{
timestamps: true,
freezeTableName: true,
tableName: "theatertypes"
}
);
return TheaterType;
};
export default TheaterTypeModel;
\ No newline at end of file
......@@ -11,9 +11,6 @@ const TicketFeeModel = (sequelize) => {
primaryKey: true,
autoIncrement: true,
},
theaterType: {
type: DataTypes.STRING
},
weekdays: {
type: DataTypes.INTEGER
},
......
import express from "express";
import userRouter from './user.route.js'
import movieRouter from './movie.route.js'
import theaterRouter from "./theater.route.js";
import cinemaRouter from "./cinema.route.js";
import kakaopayRouter from "./kakaopay.route.js";
import emailRouter from './email.route.js'
......@@ -12,5 +13,6 @@ router.use('/auth', userRouter)
router.use('/kakaopay',kakaopayRouter)
router.use('/email',emailRouter)
router.use('/info', cinemaRouter)
router.use('/theater', theaterRouter)
export default router;
\ No newline at end of file
import express from "express";
import theaterCtrl from "../controllers/theater.controller.js";
const router = express.Router();
router
.route("/")
.get(theaterCtrl.getAll)
.put(theaterCtrl.submit)
.delete(theaterCtrl.remove)
router
.route("/type")
.get(theaterCtrl.getTypes)
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