HyeonJun Jeon

[Add] Schedule add popup

......@@ -21,8 +21,7 @@ async function route() {
DELETE FROM \`${req.body.table}\` sc
WHERE sc.userID = ${req.body.userID}
AND sc.uid = ${req.body.uid}`;
const [result] = await connection.query(queryString);
console.log(req.body);
await connection.query(queryString);
res.end();
} catch (e) {
console.log(e);
......
......@@ -30,6 +30,41 @@ async function route() {
res.end();
}
});
// (userID, label, subjectID, type, description, url, date)
schedules_dateRouter.post("/", async (req, res) => {
console.log("post /db/schedules_date");
try {
let queryString = `
INSERT INTO \`schedules_date\`
(userID, label, subjectID, type, description, url, date, status)
VALUES (${req.body.userID}, "${req.body.label}", ${req.body.subjectID}, "${req.body.type}",
"${req.body.description}", "${req.body.url}", "${req.body.date}", 1);`;
await connection.query(queryString);
queryString = `UPDATE \`schedules_date\`
SET uid = -ID
WHERE ID = LAST_INSERT_ID();`;
await connection.query(queryString);
queryString = `
SELECT sc.label, sc.type, sc.description, sc.url, sc.detail,
sbj.name, us.nickname, us.color, sc.uid, "schedules_date" \`table\`
FROM schedules_date sc
INNER JOIN \`user-subject\` us
ON sc.userID = us.userID
AND sc.subjectID = us.subjectID
AND us.status = 1
INNER JOIN subjects sbj
ON sc.subjectID = sbj.ID
WHERE sc.ID = LAST_INSERT_ID()`;
[results] = await connection.query(queryString);
res.send(results[0]);
} catch (e) {
console.log(e);
res.end();
}
});
}
route();
......
......@@ -38,12 +38,29 @@ async function route() {
try {
const queryString = `
INSERT INTO schedules_repeat (userID, label, subjectID, type, status, day, startTime, endTime)
VALUE (${req.body.userID}, ${req.body.label}, ${req.body.subjectID}, ${req.body.type},
${req.body.status}, ${req.body.day}, ${req.body.startTime}, ${req.body.endTime});
VALUE (${req.body.userID}, "${req.body.label}", ${req.body.subjectID}, "${req.body.type}",
1, ${req.body.day}, "${req.body.startTime}", "${req.body.endTime}");`;
queryString = `
UPDATE schedules_repeat
SET uid = -id;`;
SET uid = -ID
WHERE ID = LAST_INSERT_ID()`;
await connection.query(queryString);
res.end();
queryString = `
SELECT sc.label, sc.type, sc.description, sc.uid, sc.url, sc.detail, sbj.name,
us.nickname, us.color, sc.startTime, sc.endTime, "schedules_repeat" \`table\`
FROM schedules_repeat sc
INNER JOIN \`user-subject\` us
ON sc.userID = us.userID
AND sc.subjectID = us.subjectID
AND us.status = 1
INNER JOIN subjects sbj
ON sc.subjectID = sbj.ID
WHERE sc.ID = LAST_INSERT_ID()
ORDER BY sc.startTime`;
[results] = await connection.query(queryString);
res.send(results[0]);
} catch (e) {
console.log(e);
res.end();
......
......@@ -31,6 +31,44 @@ async function route() {
res.end();
}
});
// (userID, label, subjectID, type, description, url, date, startTime, endTime)
schedules_timeRouter.post("/", async (req, res) => {
console.log("post /db/schedules_time");
try {
const startTime = req.body.startTime ? `"${req.body.startTime}"` : "null";
const endTime = req.body.endTime ? `"${req.body.endTime}"` : "null";
let queryString = `
INSERT INTO \`schedules_time\`
(userID, label, subjectID, type, description, url, date, status, startTime, endTime)
VALUES (${req.body.userID}, "${req.body.label}", ${req.body.subjectID}, "${req.body.type}", "${req.body.description}",
"${req.body.url}", "${req.body.date}", 1, ${startTime}, ${endTime});`;
await connection.query(queryString);
queryString = `
UPDATE schedules_time
SET uid = -ID
WHERE ID = LAST_INSERT_ID()`;
await connection.query(queryString);
queryString = `SELECT sc.label, sc.type, sc.description, sc.url, sc.detail, sbj.name, us.nickname,
us.color, sc.uid, sc.startTime, sc.endTime, "schedules_time" \`table\`
FROM schedules_time sc
INNER JOIN \`user-subject\` us
ON sc.userID = us.userID
AND sc.subjectID = us.subjectID
AND us.status = 1
INNER JOIN subjects sbj
ON sc.subjectID = sbj.ID
WHERE sc.ID = LAST_INSERT_ID()
ORDER BY sc.endTime`;
[results] = await connection.query(queryString);
res.send(results[0]);
} catch (e) {
console.log(e);
res.end();
}
});
}
route();
......
import { useContext, useEffect, useState } from "react";
import { useContext, useEffect, useRef, useState } from "react";
import localforage from "localforage";
import { toYMD, toYMDStr } from "../utils/Dates";
......@@ -8,10 +8,19 @@ import ScheduleItem from "./ScheduleItem";
import axios from "axios";
const GridItem = ({ targetDate }) => {
const { state } = useContext(CalendarStateContext);
const { month: calMonth } = toYMD(state.date);
const { state: calState, subsObj } = useContext(CalendarStateContext);
const { month: calMonth } = toYMD(calState.date);
const { month, date } = toYMD(targetDate);
const [schedules, setSchedules] = useState();
const [state, setState] = useState({
label: "",
startTime: "",
endTime: "",
description: "",
url: "",
type: "assignment",
subjectID: 0,
});
useEffect(() => {
async function loadScheduleItems() {
......@@ -32,11 +41,20 @@ const GridItem = ({ targetDate }) => {
"http://localhost:3001/db/schedules_repeat",
{ params }
);
const subs = await localforage.getItem("subjects");
setState({ ...state, subjectID: subs[0].subjectID });
setSchedules(scrpeat.concat(scdate, sctime));
}
loadScheduleItems();
}, [targetDate]);
const handleChangeState = (e) => {
setState({
...state,
[e.target.name]: e.target.value,
});
};
const finishSchedule = async (table, uid) => {
for (const i in schedules)
if (schedules[i].uid === uid) {
......@@ -52,15 +70,96 @@ const GridItem = ({ targetDate }) => {
}
};
const popupRef = useRef();
const click = async (e) => {
if (e.target.classList.contains("gi")) {
popupRef.current.style.display = "flex";
} else if (e.target.className === "gipc") {
popupRef.current.style.display = "none";
} else if (e.target.className === "gipa") {
// (userID, label, subjectID, type, description, url, date)
const table =
state.startTime || state.endTime ? "schedules_time" : "schedules_date";
const { data: sche } = await axios.post(
"http://localhost:3001/db/" + table,
{
userID: await localforage.getItem("userID"),
...state,
date: toYMDStr(targetDate, "-"),
}
);
setSchedules(schedules.concat(sche));
popupRef.current.style.display = "none";
}
};
return (
<div className="GridItem" relative={month - calMonth || null}>
<span className="date">
<div
className="GridItem gi"
relative={month - calMonth || null}
onClick={click}
>
<span className="date gi">
{calMonth !== month ? month + "/" + date : date}
</span>
{schedules &&
schedules.map((sche, index) => (
<ScheduleItem key={index} schedule={sche} finish={finishSchedule} />
))}
<div className="gi_popup" popup="true" ref={popupRef}>
<span>일정 추가</span>
<div className="gipd">
<input
name="label"
placeholder="이름"
value={state.label}
onChange={handleChangeState}
/>
<select
name="subjectID"
value={state.subjectID}
onChange={handleChangeState}
>
{Object.values(subsObj).map((sub, index) => (
<option key={index} value={sub.subjectID}>
{sub.name}
</option>
))}
</select>
<select name="type" value={state.type} onChange={handleChangeState}>
<option value={"assignment"}>E-Campus</option>
<option value={"zoom"}>Zoom</option>
</select>
<input
name="startTime"
placeholder="시작 (HH:MM)"
value={state.startTime}
onChange={handleChangeState}
/>
<input
name="endTime"
placeholder="종료 (HH:MM)"
value={state.endTime}
onChange={handleChangeState}
/>
<textarea
name="description"
placeholder="설명"
value={state.description}
onChange={handleChangeState}
/>
<textarea
name="url"
placeholder="링크"
value={state.url}
onChange={handleChangeState}
/>
</div>
<div className="gip_btn">
<button className="gipc">취소</button>
<button className="gipa">추가</button>
</div>
</div>
</div>
);
};
......
......@@ -62,7 +62,7 @@ const ScheduleItem = ({ schedule, finish }) => {
{endTime && <span className="s_end ss">{eTime}</span>}
<span className="s_slabel ss">{label}</span>
<div className="s_popup" ref={popupRef}>
<div className="s_popup" popup="true" ref={popupRef}>
<div className="spl">
<span>{subjectName}</span>
{url ? (
......
......@@ -65,7 +65,7 @@ const SideSubject = ({ subject, dispatch }) => {
<span className="ssl" onClick={labelClick}>
{subject.nickname || subject.name}
</span>
<div className="ss_popup" ref={popupRef}>
<div className="ss_popup" popup="true" ref={popupRef}>
<div className="sspd">
<div className="sspd_1">
<span>이름</span>
......
......@@ -59,6 +59,7 @@ const Calendar = () => {
"http://localhost:3001/db/user-subject",
{ params: { userID } }
);
await localforage.setItem("subjects", subjects);
let tsubsObj = {};
for (const sub of subjects) {
tsubsObj[sub.subjectID] = sub;
......
......@@ -47,6 +47,54 @@ button:disabled {
display: flex;
}
.GridItem {
position: relative;
}
.gi_popup {
flex-direction: column;
padding: 5px;
top: 30px;
}
.gi_popup > span {
font-size: large;
}
.gip_btn {
display: flex;
flex-direction: row-reverse;
}
.gip_btn > button {
padding: 5px 9px 5px 9px;
margin-left: 2px;
}
.gipd {
margin: 5px 0 5px 0;
display: grid;
grid-template-columns: repeat(2, minmax(100px, auto));
grid-template-rows: repeat(6, minmax(30px, auto));
row-gap: 5px;
column-gap: 5px;
}
.gipd > * {
grid-column: 1 / span 2;
}
.gipd > :nth-child(4) {
grid-column: 1;
}
.gipd > :nth-child(5) {
grid-column: 2;
}
.gipd > :nth-child(6),
.gipd > :nth-child(7) {
resize: none;
height: 60px;
}
.ScheduleItem {
display: flex;
margin: 1px 0 1px 0;
......@@ -80,18 +128,21 @@ button:disabled {
padding: 0;
}
.s_popup {
[popup] {
position: absolute;
z-index: 1000;
top: calc(100% + 5px);
left: 20px;
background: rgb(250, 250, 250);
box-shadow: 0px 0px 5px gray;
border: solid thin grey;
border-radius: 5px;
display: none;
padding: 10px;
cursor: auto;
}
.s_popup {
top: calc(100% + 5px);
left: 20px;
padding: 10px;
width: 300px;
}
......
......@@ -28,18 +28,11 @@ aside {
.ss_popup {
flex-direction: column;
align-items: flex-end;
position: absolute;
z-index: 1000;
top: 30px;
left: 30px;
/* height: 150px;
width: 250px; */
/* transform: translate(-50%, -50%); */
background: rgb(250, 250, 250);
box-shadow: 0px 0px 5px gray;
border: solid thin grey;
border-radius: 5px;
display: none;
padding: 5px;
}
......