HyeonJun Jeon

[Add] Nickname, color popup

......@@ -40,6 +40,24 @@ async function route() {
res.end();
}
});
// (userID, subjectID, nickname, color)
userSubjectRouter.put("/modify", async (req, res) => {
console.log("/db/user-subject/modify");
try {
const queryString = `
UPDATE \`user-subject\`
SET color = '${req.body.color}',
nickname = '${req.body.nickname}'
WHERE userID = ${req.body.userID}
AND subjectID = ${req.body.subjectID}`;
await connection.query(queryString);
res.end();
} catch (e) {
console.log(e);
res.end();
}
});
}
route();
......
import { useState } from "react";
const SideSubject = ({ subject, dispatch }) => {
const defaultColor = "#EFEFEF";
const [state, setState] = useState({
nickname: subject.nickname || subject.name,
color: subject.color,
});
const handleChangeState = (e) => {
setState({
...state,
[e.target.name]: e.target.value,
});
};
const check = (e) => {
dispatch({ type: "CHECKED", subjectID: subject.subjectID });
......@@ -7,6 +20,37 @@ const SideSubject = ({ subject, dispatch }) => {
else e.target.style["background-color"] = subject.color;
};
const labelClick = (e) => {
e.target.nextSibling.style.display = "flex";
};
const popupClose = (e) => {
setState({
nickname: subject.nickname || subject.name,
color: subject.color,
});
e.target.offsetParent.style.display = "none";
};
const popupApply = (e) => {
if (state.nickname.length < 1) alert("이름을 입력해 주세요");
else if (state.color.length !== 6) alert("색상은 6자리 16진수 값 입니다");
else {
let check = true;
for (const c of state.color) if (isNaN(parseInt(c, 16))) check = false;
if (!check) alert("색상은 16진수 값 입니다");
else {
dispatch({
type: "MODIFY",
subjectID: subject.subjectID,
nickname: state.nickname,
color: state.color,
});
e.target.offsetParent.style.display = "none";
}
}
};
return (
<div className="SideSubject">
<div
......@@ -16,8 +60,33 @@ const SideSubject = ({ subject, dispatch }) => {
backgroundColor: subject.status ? "#" + subject.color : defaultColor,
}}
></div>
<span>{subject.name}</span>
<span className="ssl" onClick={labelClick}>
{subject.nickname || subject.name}
</span>
<div className="ss_popup">
<div className="sspd">
<div className="sspd_1">
<span>이름</span>
<input
name="nickname"
value={state.nickname}
onChange={handleChangeState}
/>
</div>
<div className="sspd_2">
<span>색상</span>
<input
name="color"
value={state.color}
onChange={handleChangeState}
/>
</div>
</div>
<div className="ssp_btns">
<button onClick={popupApply}>적용 </button>
<button onClick={popupClose}>취소</button>
</div>
</div>
</div>
);
};
......
......@@ -10,9 +10,10 @@ import axios from "axios";
export const CalendarStateContext = React.createContext();
const render = (subsObj, args) => {
let sub;
switch (args.type) {
case "CHECKED":
const sub = subsObj[args.subjectID];
sub = subsObj[args.subjectID];
sub.status = !sub.status;
axios.put("http://localhost:3001/db/user-subject/check", {
userID: sub.userID,
......@@ -20,6 +21,17 @@ const render = (subsObj, args) => {
status: +sub.status,
});
return { ...subsObj, [args.subjectID]: sub };
case "MODIFY":
sub = subsObj[args.subjectID];
sub.nickname = args.nickname;
sub.color = args.color;
axios.put("http://localhost:3001/db/user-subject/modify", {
userID: sub.userID,
subjectID: args.subjectID,
nickname: sub.nickname,
color: sub.color,
});
return { ...subsObj, [args.subjectID]: sub };
case "INIT":
return args.subsObj;
default:
......
......@@ -6,9 +6,9 @@ aside {
}
.SideSubject {
height: 25px;
padding: 5px 0px 5px 0px;
display: flex;
position: relative;
}
.ssc {
......@@ -21,5 +21,53 @@ aside {
}
.SideSubject > span {
cursor: pointer;
line-height: 25px;
}
.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(241, 241, 241);
display: none;
border: solid thin black;
padding: 5px;
}
.sspd {
display: flex;
flex-direction: column;
}
.sspd > div {
display: flex;
margin-bottom: 3px;
}
.sspd > div > span {
text-align: center;
line-height: 30px;
margin-right: 5px;
width: 35px;
}
.sspd > div > input {
flex-grow: 1;
height: 24px;
}
.ssp_btns {
margin-top: 2px;
}
.ssp_btns > button {
padding: 5px 9px 5px 9px;
margin-left: 2px;
}
......