Commit e4119e0e authored by Kim, Subin's avatar Kim, Subin
Browse files

KUSchedule 등록,수정,삭제 기능 완성

parent 4c649483
...@@ -30,7 +30,7 @@ function App() { ...@@ -30,7 +30,7 @@ function App() {
<Route path="/studyplan" component={StudyPlanListPage} /> <Route path="/studyplan" component={StudyPlanListPage} />
<Route path="/subject/edit/:subjectId" component={SubjectEditPage} /> <Route path="/subject/edit/:subjectId" component={SubjectEditPage} />
<Route path="/subject/edit" component={SubjectEditPage} /> <Route path="/subject/edit" component={SubjectEditPage} />
<Route path="/admin/edit" component={ScheduleEditPage} /> <Route path="/admin/edit/:scheduleId" component={ScheduleEditPage} />
<Route path="/admin" component={AdminPage} /> <Route path="/admin" component={AdminPage} />
{/* <PrivateRoute path="/admin" component={AdminPage} role="admin" /> */} {/* <PrivateRoute path="/admin" component={AdminPage} role="admin" /> */}
......
import axios from "axios"; import axios from "axios";
import baseUrl from "../utils/baseUrl.js"; import baseUrl from "../utils/baseUrl.js";
const submit = async (sendData) => { const getOne = async (id, userId = "ku") => {
const { data } = await axios.post(`${baseUrl}/`, sendData); const { data } = await axios.get(`${baseUrl}/api/schedule/${userId}?scheduleId=${id}`);
return data
}
const getbyMonth = async (date, userId = "ku") => {
const { data } = await axios.get(`${baseUrl}/api/schedule/${userId}?date=${date}`);
return data
}
const getbyDate = async (date, userId = "ku") => {
const { data } = await axios.get(`${baseUrl}/api/schedule/${userId}?date=${date}`);
return data
}
const submit = async (schedule, userId = "ku") => {
const { data } = await axios.post(`${baseUrl}/api/schedule/${userId}`, schedule);
return data
}
const edit = async (id, schedule, userId = "ku") => {
const { data } = await axios.put(`${baseUrl}/api/schedule/${userId}?scheduleId=${id}`, schedule);
return data
}
const remove = async (id, userId = "ku") => {
const { data } = await axios.delete(`${baseUrl}/api/schedule/${userId}?scheduleId=${id}`);
return data return data
} }
const scheduleApi = { const scheduleApi = {
submit getOne,
getbyMonth,
getbyDate,
submit,
edit,
remove
} }
export default scheduleApi export default scheduleApi
\ No newline at end of file
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import styles from "./Schedule/schedule.module.scss"; import styles from "./Schedule/schedule.module.scss";
const AdminScheduleItem = ({}) => { const AdminScheduleItem = ({ schedule, handleClick }) => {
return ( return (
<div className="d-flex mb-5"> <div className="d-flex mb-5">
<i className="bi bi-check-lg fs-4 col"></i> <i className="bi bi-check-lg fs-4 col me-2"></i>
<div className="col-10"> <div className="col-11">
<div className="d-flex justify-content-between"> <div className="d-flex">
<h3>sadsad</h3> <h3 className="col-10 rows-cols-2">{schedule.title}</h3>
<div className="fs-5"> <div className="d-flex col-2 fs-5">
<Link to="/admin/edit"><i className="bi bi-pencil-square text-dark me-2" data-bs-dismiss="modal"></i></Link> <Link to={`/admin/edit/${schedule.id}`}><i className="bi bi-pencil-square text-dark me-2" data-bs-dismiss="modal"></i></Link>
<i className="bi bi-trash"></i> <i className="bi bi-trash" onClick={() => handleClick(schedule.id)}></i>
</div> </div>
</div> </div>
<p className="text-start text-secondary mb-2">2020~353543135</p> <p className="text-start text-secondary mb-2">
<div className={`text-start ${styles.textBox}`}>sadsds adsdsadsdsad sdsadsdsadsdsadsdsadsdsadsdsadsdsadsd</div> {(schedule.start === schedule.end) ? schedule.start : schedule.start + "~" + schedule.end}
</p>
<div className={`text-start ${styles.textBox}`}>{schedule.memo}</div>
</div> </div>
</div> </div>
) )
......
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import styles from "./buttons.module.scss"; import styles from "./buttons.module.scss";
const BtnGroup = ({ disabled, handleSubmit }) => { const BtnGroup = ({ text, disabled, handleSubmit }) => {
const history = useHistory(); const history = useHistory();
return ( return (
<div className="d-flex justify-content-around my-4"> <div className="d-flex justify-content-around my-4">
<button className="btn btn-white col-5 shadow-none border-dark" type="button" onClick={() => history.goBack()}>취소</button> <button className="btn btn-white col-5 shadow-none border-dark" type="button" onClick={() => history.goBack()}>취소</button>
<button className={`btn btn-crimson col-5 ${styles.disabledBtn}`} type="button" onClick={handleSubmit} disabled={disabled}>등록</button> <button className={`btn btn-crimson col-5 ${styles.disabledBtn}`} type="button" onClick={handleSubmit} disabled={disabled}>{text ? "수정" : "등록"}</button>
</div> </div>
) )
} }
......
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { Redirect, useLocation } from "react-router-dom"; import { Redirect, useParams } from "react-router-dom";
import BtnGroup from "../Buttons/BtnGroup.js"; import BtnGroup from "../Buttons/BtnGroup.js";
import scheduleApi from "../../apis/schedule.api.js"; import scheduleApi from "../../apis/schedule.api";
import catchErrors from "../../utils/catchErrors.js"; import catchErrors from "../../utils/catchErrors.js";
import styles from "./form.module.scss"; import styles from "./form.module.scss";
const ScheduleForm = () => { const ScheduleForm = () => {
const location = useLocation()
const [schedule, setSchedule] = useState({ const [schedule, setSchedule] = useState({
title: "", title: "",
startDate: "", startDate: "",
...@@ -20,6 +19,11 @@ const ScheduleForm = () => { ...@@ -20,6 +19,11 @@ const ScheduleForm = () => {
const [disabled, setDisabled] = useState(true) const [disabled, setDisabled] = useState(true)
const [success, setSuccess] = useState(false) const [success, setSuccess] = useState(false)
const [error, setError] = useState("") const [error, setError] = useState("")
const { scheduleId } = useParams()
useEffect(() => {
if (scheduleId) getOne(scheduleId)
}, [])
useEffect(() => { useEffect(() => {
let isMounted = true; let isMounted = true;
...@@ -40,6 +44,16 @@ const ScheduleForm = () => { ...@@ -40,6 +44,16 @@ const ScheduleForm = () => {
}; };
}, [schedule]) }, [schedule])
async function getOne(id) {
try {
setError("")
const resSchedule = await scheduleApi.getOne(id)
setSchedule({ ...schedule, ...resSchedule })
} catch (error) {
catchErrors(error, setError)
}
}
function handleChange(e) { function handleChange(e) {
const { name, value } = e.target const { name, value } = e.target
if (name === "allDay") { if (name === "allDay") {
...@@ -55,8 +69,14 @@ const ScheduleForm = () => { ...@@ -55,8 +69,14 @@ const ScheduleForm = () => {
e.preventDefault() e.preventDefault()
try { try {
setError("") setError("")
if (schedule.allDay === "on") setSchedule({ ...schedule, startTime: '00:00', endTime: '23:59' }) if (scheduleId) {
await scheduleApi.submit() await scheduleApi.edit(scheduleId, schedule)
alert('해당 일정이 성공적으로 수정되었습니다.')
}
else {
await scheduleApi.submit(schedule)
alert('해당 일정이 성공적으로 등록되었습니다.')
}
setSuccess(true) setSuccess(true)
} catch (error) { } catch (error) {
catchErrors(error, setError) catchErrors(error, setError)
...@@ -64,20 +84,18 @@ const ScheduleForm = () => { ...@@ -64,20 +84,18 @@ const ScheduleForm = () => {
} }
if (success) { if (success) {
alert('해당 일정이 성공적으로 등록되었습니다.')
return <Redirect to="/home" /> return <Redirect to="/home" />
} }
return ( return (
<form className="pt-5" onSubmit={handleSubmit}> <form className="pt-5">
{console.log("data==",)}
<div> <div>
<input className={`form-control form-control-lg shadow-none rounded-0 px-1 mb-5 ${styles.textInput}`} type="text" name="title" placeholder="제목" aria-label="title" onChange={handleChange} autoFocus /> <input className={`form-control form-control-lg shadow-none rounded-0 px-1 mb-5 ${styles.textInput}`} type="text" name="title" value={schedule.title} placeholder="제목" aria-label="title" onChange={handleChange} autoFocus />
</div> </div>
<div className="d-flex mb-4"> <div className="d-flex mb-4">
<label className="col col-form-label align-self-center py-0">시작</label> <label className="col col-form-label align-self-center py-0">시작</label>
<div className={schedule.allDay === "on" ? "col-7" : "col-5"}> <div className={schedule.allDay === "on" ? "col-7" : "col-5"}>
<input className={`form-control shadow-none ${styles.dateInput}`} type="date" name="startDate" aria-label="startDate" onChange={handleChange} /> <input className={`form-control shadow-none ${styles.dateInput}`} type="date" name="startDate" value={schedule.startDate} aria-label="startDate" onChange={handleChange} />
</div> </div>
<div className={"col-5 " + (schedule.allDay === "on" ? "d-none" : "d-block")}> <div className={"col-5 " + (schedule.allDay === "on" ? "d-none" : "d-block")}>
<input className={`form-control shadow-none ${styles.dateInput}`} type="time" name="startTime" aria-label="startTime" onChange={handleChange} /> <input className={`form-control shadow-none ${styles.dateInput}`} type="time" name="startTime" aria-label="startTime" onChange={handleChange} />
...@@ -105,10 +123,10 @@ const ScheduleForm = () => { ...@@ -105,10 +123,10 @@ const ScheduleForm = () => {
<div className="d-flex justify-content-between mb-5"> <div className="d-flex justify-content-between mb-5">
<i className="col bi bi-journal-text fs-3"></i> <i className="col bi bi-journal-text fs-3"></i>
<div className="col-10"> <div className="col-10">
<textarea className={`form-control shadow-none ${styles.textArea}`} name="memo" rows="5" onChange={handleChange}></textarea> <textarea className={`form-control shadow-none ${styles.textArea}`} name="memo" value={schedule.memo} rows="5" onChange={handleChange}></textarea>
</div> </div>
</div> </div>
<BtnGroup disabled={disabled} /> <BtnGroup text={scheduleId} disabled={disabled} handleSubmit={handleSubmit} />
</form> </form>
) )
} }
......
import { useState, useEffect } from "react";
import Item from "../AdminScheduleItem.js"; import Item from "../AdminScheduleItem.js";
import scheduleApi from "../../apis/schedule.api";
import catchErrors from "../../utils/catchErrors.js";
import moment from 'moment'; import moment from 'moment';
import styles from "./modal.module.scss"; import styles from "./modal.module.scss";
const ScheduleModal = ({ dateShow, setDateShow }) => { const ScheduleModal = ({ dateShow, setDateShow }) => {
const [scheduleList, setScheduleList] = useState([])
const [error, setError] = useState("")
useEffect(() => {
if (dateShow.show) getSchedule()
}, [dateShow])
async function getSchedule() {
try {
setError("")
const resList = await scheduleApi.getbyDate(dateShow.date)
setScheduleList(resList)
} catch (error) {
catchErrors(error, setError)
}
}
async function delSchedule(id) {
try {
setError("")
await scheduleApi.remove(id)
alert("해당 일정을 삭제했습니다.")
getSchedule()
} catch (error) {
catchErrors(error, setError)
}
}
return ( return (
<> <>
{dateShow.show ? <div className="modal-backdrop fade show"></div> : null} {dateShow.show ? <div className="modal-backdrop fade show"></div> : null}
...@@ -14,8 +45,9 @@ const ScheduleModal = ({ dateShow, setDateShow }) => { ...@@ -14,8 +45,9 @@ const ScheduleModal = ({ dateShow, setDateShow }) => {
<button type="button" className={`btn-close btn-close-white ms-0 ${styles.closeBtn}`} data-bs-dismiss="modal" aria-label="Close" onClick={() => setDateShow({ ...dateShow, show: false })}></button> <button type="button" className={`btn-close btn-close-white ms-0 ${styles.closeBtn}`} data-bs-dismiss="modal" aria-label="Close" onClick={() => setDateShow({ ...dateShow, show: false })}></button>
</div> </div>
<div className={`modal-body text-dark ${styles.body}`}> <div className={`modal-body text-dark ${styles.body}`}>
<Item /> {scheduleList.length !== 0 ?
<p className="text-center mb-0">선택한 날짜에 일정이 없습니다.</p> scheduleList.map((schedule, idx) => <Item key={idx} schedule={schedule} handleClick={delSchedule} />)
: <p className="text-center mb-0">선택한 날짜에 일정이 없습니다.</p>}
</div> </div>
</div> </div>
</div> </div>
......
import { KU } from "../db/index.js"; import { KU } from "../db/index.js";
import sequelize from 'sequelize';
const create = async (req, res) => { const { Op } = sequelize
const findbyId = async (req, res, next) => {
try {
const id = req.scheduleId
if (id) {
const findSchedule = await KU.findOne({ where: { id: id } })
if (!findSchedule) throw new Error("해당 일정을 찾지 못했습니다.")
else {
const { title, start, end, memo } = findSchedule
const startDate = dateToString(start, "full")
const endDate = dateToString(end, "full")
req.schedule = { title, startDate: startDate, endDate: endDate, memo }
}
next()
} else next()
} catch (error) {
return res.status(500).send(error.message || "일정 가져오는 중 에러 발생")
}
}
const findbyDate = async (req, res, next) => {
try { try {
if (req.date) {
const date = new Date(req.date)
const findList = await KU.findAll({
where: {
[Op.and]: [
{
start: {
[Op.lte]: date
}
}, {
end: {
[Op.gte]: date
}
}
]
},
order: [['updatedAt', 'DESC']]
})
findList.forEach(schedule => {
schedule.dataValues.start = dateToString(schedule.start, "twoYear")
schedule.dataValues.end = dateToString(schedule.end, "twoYear")
})
req.scheduleList = findList
next()
} else next()
} catch (error) {
return res.status(500).send(error.message || "일정 가져오는 중 에러 발생")
}
}
const create = async (req, res) => {
try {
const { title, startDate, endDate, memo } = req.body
const start = new Date(startDate)
const end = new Date(endDate)
const newSchedule = await KU.create({ title: title, start: start, end: end, memo: memo })
return res.json(newSchedule)
} catch (error) { } catch (error) {
return res.status(500).send(error.message || "일정 등록 중 에러 발생") return res.status(500).send(error.message || "일정 등록 중 에러 발생")
} }
...@@ -10,7 +68,11 @@ const create = async (req, res) => { ...@@ -10,7 +68,11 @@ const create = async (req, res) => {
const edit = async (req, res) => { const edit = async (req, res) => {
try { try {
const { scheduleId } = req.query
const { title, startDate, endDate, memo } = req.body
const updated = await KU.update({ title: title, start: startDate, end: endDate, memo: memo }, { where: { id: scheduleId } })
if (!updated) throw new Error("해당 일정의 일부 정보를 수정하는데 실패하였습니다.")
else return res.send(200)
} catch (error) { } catch (error) {
return res.status(500).send(error.message || "일정 수정 중 에러 발생") return res.status(500).send(error.message || "일정 수정 중 에러 발생")
} }
...@@ -18,14 +80,51 @@ const edit = async (req, res) => { ...@@ -18,14 +80,51 @@ const edit = async (req, res) => {
const remove = async (req, res) => { const remove = async (req, res) => {
try { try {
const { scheduleId } = req.query
const deleted = await KU.destroy({ where: { id: scheduleId } })
if (!deleted) throw new Error("해당 일정을 삭제하는데 실패하였습니다.")
else return res.send(200)
} catch (error) { } catch (error) {
return res.status(500).send(error.message || "일정 삭제 중 에러 발생") return res.status(500).send(error.message || "일정 삭제 중 에러 발생")
} }
} }
const querySeparation = async (req, res, next) => {
try {
const { scheduleId, date } = req.query
req.scheduleId = scheduleId
req.date = date
next()
} catch (error) {
return res.status(500).send(error.message || "일정 가져오는 중 에러 발생")
}
}
const send = async (req, res) => {
try {
const result = req.schedule || req.scheduleList
return res.json(result)
} catch (error) {
return res.status(500).send(error.message || "일정 가져오는 중 에러 발생")
}
}
function dateToString(dateObj, method) {
const year = dateObj.getFullYear()
const year_disit = String(year).substring(2, 4)
const month = dateObj.getMonth() + 1
const date = dateObj.getDate()
if (method === "full") return [year, (month > 9 ? "" : "0") + month, (date > 9 ? "" : "0") + date].join("-")
else if (method === "twoYear") return [year_disit, (month > 9 ? "" : "0") + month, (date > 9 ? "" : "0") + date].join("-")
}
export default { export default {
findbyId,
findbyDate,
create, create,
edit, edit,
remove remove,
querySeparation,
send
} }
\ No newline at end of file
...@@ -23,7 +23,8 @@ const KUModel = (sequelize) => { ...@@ -23,7 +23,8 @@ const KUModel = (sequelize) => {
type: DataTypes.DATE type: DataTypes.DATE
}, },
memo: { memo: {
type: DataTypes.TEXT type: DataTypes.TEXT,
defaultValue: ""
} }
}, },
{ {
......
...@@ -23,10 +23,12 @@ const ScheduleModel = (sequelize) => { ...@@ -23,10 +23,12 @@ const ScheduleModel = (sequelize) => {
type: DataTypes.DATE type: DataTypes.DATE
}, },
location: { location: {
type:DataTypes.STRING type:DataTypes.STRING,
defaultValue: ""
}, },
memo: { memo: {
type: DataTypes.TEXT type: DataTypes.TEXT,
defaultValue: ""
} }
}, },
{ {
......
...@@ -6,6 +6,7 @@ const router = express.Router(); ...@@ -6,6 +6,7 @@ const router = express.Router();
router router
.route("/ku") .route("/ku")
.get(kuCtrl.querySeparation, kuCtrl.findbyId, kuCtrl.findbyDate, kuCtrl.send)
.post(kuCtrl.create) .post(kuCtrl.create)
.put(kuCtrl.edit) .put(kuCtrl.edit)
.delete(kuCtrl.remove) .delete(kuCtrl.remove)
......
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