HyeonJun Jeon

[Add] Repeated schedules

...@@ -2,6 +2,7 @@ const express = require("express"); ...@@ -2,6 +2,7 @@ const express = require("express");
2 const dbRouter = express.Router(); 2 const dbRouter = express.Router();
3 3
4 const schedules_dateRouter = require("./schedules_date"); 4 const schedules_dateRouter = require("./schedules_date");
5 +const schedules_repeatRouter = require("./Schedules_repeat");
5 const schedules_timeRouter = require("./Schedules_time"); 6 const schedules_timeRouter = require("./Schedules_time");
6 const subjectsRouter = require("./Subjects"); 7 const subjectsRouter = require("./Subjects");
7 const userSubjectRouter = require("./user-subject"); 8 const userSubjectRouter = require("./user-subject");
...@@ -13,6 +14,7 @@ async function route() { ...@@ -13,6 +14,7 @@ async function route() {
13 dbRouter.use("/subjects", subjectsRouter); 14 dbRouter.use("/subjects", subjectsRouter);
14 dbRouter.use("/schedules_date", schedules_dateRouter); 15 dbRouter.use("/schedules_date", schedules_dateRouter);
15 dbRouter.use("/schedules_time", schedules_timeRouter); 16 dbRouter.use("/schedules_time", schedules_timeRouter);
17 + dbRouter.use("/schedules_repeat", schedules_repeatRouter);
16 } 18 }
17 19
18 route(); 20 route();
......
1 +const express = require("express");
2 +const mysql2 = require("mysql2/promise");
3 +const { connectOption } = require("../libs/MySQL");
4 +const schedules_repeatRouter = express.Router();
5 +
6 +async function route() {
7 + const connection = await mysql2.createConnection(connectOption);
8 +
9 + // (userID, day) => schedules
10 + schedules_repeatRouter.get("/", async (req, res) => {
11 + // console.log("/db/schedules_repeat");
12 + try {
13 + const queryString = `
14 + SELECT sc.label, sc.type, sc.description, sc.uid, sc.url, sc.detail, sbj.name, us.nickname, us.color, sc.startTime, sc.endTime
15 + FROM schedules_repeat sc
16 + INNER JOIN \`user-subject\` us
17 + ON sc.userID = us.userID
18 + AND sc.subjectID = us.subjectID
19 + AND us.status = 1
20 + INNER JOIN subjects sbj
21 + ON sc.subjectID = sbj.ID
22 + WHERE sc.day = "${req.query.day}"
23 + AND sc.userID = ${req.query.userID}
24 + AND sc.status = 1
25 + ORDER BY sc.startTime`;
26 + const [results] = await connection.query(queryString);
27 + res.send(results);
28 + } catch (e) {
29 + console.log(e);
30 + res.end();
31 + }
32 + });
33 +
34 + // (userID, label, subjectID, type, desciption, url, status, day, startTime, endTime)
35 + schedules_repeatRouter.post("/", async (req, res) => {
36 + console.log("/db/schedules_repeat");
37 + try {
38 + const queryString = `
39 + INSERT INTO schedules_repeat (userID, label, subjectID, type, status, day, startTime, endTime)
40 + VALUE (${req.body.userID}, ${req.body.label}, ${req.body.subjectID}, ${req.body.type},
41 + ${req.body.status}, ${req.body.day}, ${req.body.startTime}, ${req.body.endTime});
42 + UPDATE schedules_repeat
43 + SET uid = -id;`;
44 + await connection.query(queryString);
45 + res.end();
46 + } catch (e) {
47 + console.log(e);
48 + res.end();
49 + }
50 + });
51 +}
52 +route();
53 +
54 +module.exports = schedules_repeatRouter;
...@@ -15,21 +15,24 @@ const GridItem = ({ targetDate }) => { ...@@ -15,21 +15,24 @@ const GridItem = ({ targetDate }) => {
15 15
16 useEffect(() => { 16 useEffect(() => {
17 async function loadScheduleItems() { 17 async function loadScheduleItems() {
18 - const userID = await localforage.getItem("userID"); 18 + const params = {
19 - const params = { userID, date: toYMDStr(targetDate, "-") }; 19 + userID: await localforage.getItem("userID"),
20 + date: toYMDStr(targetDate, "-"),
21 + day: targetDate.getDay(),
22 + };
20 const { data: scdate } = await axios.get( 23 const { data: scdate } = await axios.get(
21 "http://localhost:3001/db/schedules_date", 24 "http://localhost:3001/db/schedules_date",
22 - { 25 + { params }
23 - params,
24 - }
25 ); 26 );
26 const { data: sctime } = await axios.get( 27 const { data: sctime } = await axios.get(
27 "http://localhost:3001/db/schedules_time", 28 "http://localhost:3001/db/schedules_time",
28 - { 29 + { params }
29 - params, 30 + );
30 - } 31 + const { data: scrpeat } = await axios.get(
32 + "http://localhost:3001/db/schedules_repeat",
33 + { params }
31 ); 34 );
32 - setSchedules(scdate.concat(sctime)); 35 + setSchedules(scrpeat.concat(scdate, sctime));
33 } 36 }
34 loadScheduleItems(); 37 loadScheduleItems();
35 }, [targetDate]); 38 }, [targetDate]);
......
1 import zoomSymbol from "../assets/zoom.png"; 1 import zoomSymbol from "../assets/zoom.png";
2 import ecampusSymbol from "../assets/e-Campus.png"; 2 import ecampusSymbol from "../assets/e-Campus.png";
3 +import { useRef } from "react";
3 4
4 const ScheduleItem = ({ schedule }) => { 5 const ScheduleItem = ({ schedule }) => {
5 const { 6 const {
6 name: subjectName, 7 name: subjectName,
7 nickname: subjectNickname, 8 nickname: subjectNickname,
8 - uid: scheID, 9 + uid: scheUID,
9 color: subjectColor, 10 color: subjectColor,
10 url, 11 url,
11 type, 12 type,
12 label, 13 label,
13 - description, 14 + description = null,
14 - detail, 15 + detail = null,
15 startTime = null, //HHMMSS문자열 16 startTime = null, //HHMMSS문자열
16 endTime = null, 17 endTime = null,
17 } = schedule; 18 } = schedule;
19 + let sTime = startTime ? startTime.substring(0, 5) : ""; //HHMM
20 + let eTime = endTime ? endTime.substring(0, 5) : "";
18 21
19 const selectSymbol = () => { 22 const selectSymbol = () => {
20 let symbol; 23 let symbol;
...@@ -30,33 +33,28 @@ const ScheduleItem = ({ schedule }) => { ...@@ -30,33 +33,28 @@ const ScheduleItem = ({ schedule }) => {
30 return symbol; 33 return symbol;
31 }; 34 };
32 35
36 + const popupRef = useRef();
37 +
33 const click = (e) => { 38 const click = (e) => {
34 - let target; 39 + if (e.target.classList.contains("ss"))
35 - if (e.target.className === "ScheduleItem") target = e.target; 40 + popupRef.current.style.display = "grid";
36 - else if (e.target.classList.contains("ss")) target = e.target.offsetParent;
37 else { 41 else {
38 - if (e.target.className === "spc") 42 + if (e.target.className === "spc") popupRef.current.style.display = "none";
39 - e.target.offsetParent.style.display = "none";
40 - return;
41 } 43 }
42 -
43 - target.lastChild.style.display = "grid";
44 }; 44 };
45 45
46 return ( 46 return (
47 <div 47 <div
48 - className="ScheduleItem" 48 + className="ScheduleItem ss"
49 style={{ borderColor: "#" + subjectColor }} 49 style={{ borderColor: "#" + subjectColor }}
50 onClick={click} 50 onClick={click}
51 > 51 >
52 <img className="s_symbol ss" src={selectSymbol()} alt="404" /> 52 <img className="s_symbol ss" src={selectSymbol()} alt="404" />
53 - {startTime && ( 53 + {startTime && <span className="s_start ss">{sTime}</span>}
54 - <span className="s_start ss">{startTime.substring(0, 5)}</span> 54 + {endTime && <span className="s_end ss">{eTime}</span>}
55 - )}
56 - {endTime && <span className="s_end ss">{endTime.substring(0, 5)}</span>}
57 <span className="s_slabel ss">{label}</span> 55 <span className="s_slabel ss">{label}</span>
58 56
59 - <div className="s_popup"> 57 + <div className="s_popup" ref={popupRef}>
60 <div className="spl"> 58 <div className="spl">
61 <span>{subjectName}</span> 59 <span>{subjectName}</span>
62 {url ? ( 60 {url ? (
...@@ -66,6 +64,7 @@ const ScheduleItem = ({ schedule }) => { ...@@ -66,6 +64,7 @@ const ScheduleItem = ({ schedule }) => {
66 ) : ( 64 ) : (
67 <span>{label}</span> 65 <span>{label}</span>
68 )} 66 )}
67 + {(startTime || endTime) && <span>{sTime + " ~ " + eTime}</span>}
69 {description && <span>{description}</span>} 68 {description && <span>{description}</span>}
70 {detail && <div dangerouslySetInnerHTML={{ __html: detail }}></div>} 69 {detail && <div dangerouslySetInnerHTML={{ __html: detail }}></div>}
71 </div> 70 </div>
......
1 -import { useState } from "react"; 1 +import { useRef, useState } from "react";
2 2
3 const SideSubject = ({ subject, dispatch }) => { 3 const SideSubject = ({ subject, dispatch }) => {
4 const defaultColor = "#EFEFEF"; 4 const defaultColor = "#EFEFEF";
...@@ -20,8 +20,10 @@ const SideSubject = ({ subject, dispatch }) => { ...@@ -20,8 +20,10 @@ const SideSubject = ({ subject, dispatch }) => {
20 else e.target.style["background-color"] = subject.color; 20 else e.target.style["background-color"] = subject.color;
21 }; 21 };
22 22
23 + const popupRef = useRef();
24 +
23 const labelClick = (e) => { 25 const labelClick = (e) => {
24 - e.target.nextSibling.style.display = "flex"; 26 + popupRef.current.style.display = "flex";
25 }; 27 };
26 28
27 const popupClose = (e) => { 29 const popupClose = (e) => {
...@@ -29,7 +31,7 @@ const SideSubject = ({ subject, dispatch }) => { ...@@ -29,7 +31,7 @@ const SideSubject = ({ subject, dispatch }) => {
29 nickname: subject.nickname || subject.name, 31 nickname: subject.nickname || subject.name,
30 color: subject.color, 32 color: subject.color,
31 }); 33 });
32 - e.target.offsetParent.style.display = "none"; 34 + popupRef.current.style.display = "none";
33 }; 35 };
34 36
35 const popupApply = (e) => { 37 const popupApply = (e) => {
...@@ -63,7 +65,7 @@ const SideSubject = ({ subject, dispatch }) => { ...@@ -63,7 +65,7 @@ const SideSubject = ({ subject, dispatch }) => {
63 <span className="ssl" onClick={labelClick}> 65 <span className="ssl" onClick={labelClick}>
64 {subject.nickname || subject.name} 66 {subject.nickname || subject.name}
65 </span> 67 </span>
66 - <div className="ss_popup"> 68 + <div className="ss_popup" ref={popupRef}>
67 <div className="sspd"> 69 <div className="sspd">
68 <div className="sspd_1"> 70 <div className="sspd_1">
69 <span>이름</span> 71 <span>이름</span>
......