From 371048ff6c202f0f61a923f77d494a7a9ebb79f8 Mon Sep 17 00:00:00 2001 From: Youngseo Kang Date: Tue, 31 Aug 2021 17:41:55 +0900 Subject: [PATCH 01/10] =?UTF-8?q?:sparkles:=20[Client]=20Mypage.js=20:=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=84=A0=ED=83=9D=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/Mypage.js | 59 +++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/client/src/pages/Mypage.js b/client/src/pages/Mypage.js index 244e189..a18fbf0 100644 --- a/client/src/pages/Mypage.js +++ b/client/src/pages/Mypage.js @@ -1,7 +1,8 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import styled from "styled-components"; import axios from "axios"; import { Redirect } from "react-router"; +import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons"; const MypageWrap = styled.div` width: 100%; @@ -79,6 +80,9 @@ function Mypage({ isLogin, accToken }) { const [userContent, setUserContent] = useState({ data: [], }); + const [isOn, setIsOn] = useState(false); + const [checkedItems, setCheckedItems] = useState([]); + const getUserContent = async () => { let userContent = await axios.get(`${url}/myContents`, { header: { authorization: `Bearer ${accToken}` }, @@ -86,6 +90,35 @@ function Mypage({ isLogin, accToken }) { setUserContent({ data: userContent.data.data }); }; + // const contentCount = userContent.data.length; + // const contentThumbsupCount = userContent; + // console.log(contentThumbsupCount); + + const contentCount = userContent.data.length; // 전체 글 수 + const contentThumbsupCount = userContent.data.reduce((acc, cur) => { + if (acc < cur.thumbsup) return cur.thumbsup; + else return acc; + }, 0); // 최고 추천수 + + const handleCheck = (id) => { + setCheckedItems([...checkedItems, id]); + }; // checkbox 하나씩 선택하기 + const handleClick = (checked) => { + if (checked) { + // 전체 선택 + setCheckedItems([...userContent.data.map((ele) => ele.id)]); + setIsOn(true); + } else { + // 전체 해제 + setCheckedItems([]); + setIsOn(false); + } + }; + console.log(checkedItems); + const deleteContent = () => { + // + }; // 만든 글 삭제하기 + useEffect(() => { getUserContent(); }, []); @@ -98,7 +131,10 @@ function Mypage({ isLogin, accToken }) { {" "} {/* 내가 쓴 글 목록 */} -

작성하신 글은 0개 이며, 최대 추천수는 0개 입니다

+

+ 작성하신 글은 {contentCount}개 이며, 최대 추천수는{" "} + {contentThumbsupCount}개 입니다 +

+ handleCheck(ele.id)} + />

{ele.wordName}

{ele.wordMean}

@@ -119,7 +163,14 @@ function Mypage({ isLogin, accToken }) { })} - + From ee68e69fb528cd1479214d2c32d15208641babf5 Mon Sep 17 00:00:00 2001 From: minjman2659 Date: Tue, 31 Aug 2021 17:43:09 +0900 Subject: [PATCH 02/10] =?UTF-8?q?[Client]=20MypageEdit.js=20:=20=EC=97=94?= =?UTF-8?q?=ED=84=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/MypageEdit.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/src/pages/MypageEdit.js b/client/src/pages/MypageEdit.js index 8de5ce5..66171c0 100644 --- a/client/src/pages/MypageEdit.js +++ b/client/src/pages/MypageEdit.js @@ -166,6 +166,13 @@ function MypageEdit({ newPassword: "", newPasswordRe: "", }); + + const handleKeyPressEdit = (e) => { + if (e.type === "keypress" && e.code === "Enter") { + handleEdit(); + } + }; + const handleEditInputValue = (key) => (e) => { setEditUser({ ...editUser, [key]: e.target.value }); }; @@ -237,6 +244,7 @@ function MypageEdit({ id="username" placeholder="사용자 이름" onChange={handleEditInputValue("username")} + onKeyPress={handleKeyPressEdit} value={editUser.username} > From 236b3c40d537edf0f56ab1709b61c4dd86b68cf8 Mon Sep 17 00:00:00 2001 From: Youngseo Kang Date: Tue, 31 Aug 2021 19:00:46 +0900 Subject: [PATCH 03/10] =?UTF-8?q?:sparkles:=20[Client]=20axiosMypage.js=20?= =?UTF-8?q?:=20=EB=88=84=EB=A5=B4=EB=A9=B4=20=ED=95=B4=EB=8B=B9=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=B6=94=EA=B0=80=EC=A0=95=EB=B3=B4=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=A0=84=EC=B2=B4=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.js | 17 +++++-- client/src/comp/MoreClickModal.js | 13 ++--- client/src/pages/Mypage.js | 81 +++++++++++++++++++++---------- 3 files changed, 73 insertions(+), 38 deletions(-) diff --git a/client/src/App.js b/client/src/App.js index c8dbf25..59beca5 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -24,7 +24,10 @@ function App() { const [onModal, setOnModal] = useState(false); // 로그인, 회원가입 모달 열 여부 const [searchValue, setSearchValue] = useState(""); // search input에 검색하려는 값 const [result, setResult] = useState([]); // search 결과값 - + const [currResult, setCurrResult] = useState({ + data: "", + }); // 눌러서 볼 search값 + console.log(currResult); const [writeModal, setWriteModal] = useState(false); const [closeLogoutModal, setCloseLogoutModal] = useState(false); const [onSignoutModal, setOnSignoutModal] = useState(false); @@ -84,7 +87,10 @@ function App() { {/* 단어 뜻 모달 */} {moreClickModal ? ( - + ) : null}
-

{/*단어*/}자만추

+

{currResult.data.wordName}

-

- {/*단어 뜻*/}자연스러운 만남 추구 자연스러운 만남 추구 - 자연스러운 만남 추구 자연스러운 만남 추구 자연스러운 만남 추구 - 자연스러운 만남 추구 자연스러운 만남 추구 자연스러운 만남 추구 - 자연스러운 만남 추구 자연스러운 만남 추구 -

+

{currResult.data.wordMean}

diff --git a/client/src/pages/Mypage.js b/client/src/pages/Mypage.js index a18fbf0..1cf10c7 100644 --- a/client/src/pages/Mypage.js +++ b/client/src/pages/Mypage.js @@ -35,6 +35,7 @@ const ContentList = styled.ul` /* justify-content: space-between; */ padding: 1vw 0; border-bottom: 3px solid #000; + cursor: pointer; > input { /* flex: 1 1 auto; */ } @@ -75,7 +76,7 @@ const ContentCheck = styled.div` } `; -function Mypage({ isLogin, accToken }) { +function Mypage({ isLogin, accToken, setMoreClickModal, setCurrResult }) { const url = process.env.REACT_APP_API_URL || `http://localhost:4000`; const [userContent, setUserContent] = useState({ data: [], @@ -83,6 +84,11 @@ function Mypage({ isLogin, accToken }) { const [isOn, setIsOn] = useState(false); const [checkedItems, setCheckedItems] = useState([]); + const readResult = (ele) => { + setCurrResult({ data: ele }); + setMoreClickModal(true); + }; + const getUserContent = async () => { let userContent = await axios.get(`${url}/myContents`, { header: { authorization: `Bearer ${accToken}` }, @@ -90,22 +96,24 @@ function Mypage({ isLogin, accToken }) { setUserContent({ data: userContent.data.data }); }; - // const contentCount = userContent.data.length; - // const contentThumbsupCount = userContent; - // console.log(contentThumbsupCount); - - const contentCount = userContent.data.length; // 전체 글 수 - const contentThumbsupCount = userContent.data.reduce((acc, cur) => { - if (acc < cur.thumbsup) return cur.thumbsup; - else return acc; - }, 0); // 최고 추천수 - - const handleCheck = (id) => { - setCheckedItems([...checkedItems, id]); + const handleSingleCheck = (checked, id) => { + console.log(checked, id); + if (checked === true) { + setCheckedItems([...checkedItems, id]); + } else { + setCheckedItems([checkedItems.filter((ele) => ele.id !== id)]); + } + console.log(checkedItems.length, userContent.data.map.length); + if (checkedItems.length === userContent.data.map.length) { + setIsOn(true); + } else { + setIsOn(false); + } }; // checkbox 하나씩 선택하기 - const handleClick = (checked) => { + + const handleAllClick = (checked) => { if (checked) { - // 전체 선택 + // 전체 선택, true일때 setCheckedItems([...userContent.data.map((ele) => ele.id)]); setIsOn(true); } else { @@ -114,11 +122,26 @@ function Mypage({ isLogin, accToken }) { setIsOn(false); } }; - console.log(checkedItems); - const deleteContent = () => { - // + + const deleteContent = async () => { + await axios.post( + `${url}/contents/delete`, + { + contentId: checkedItems, + }, + { + headers: { authorization: `Bearer ${accToken}` }, + } + ); + alert("글이 삭제되었습니다."); }; // 만든 글 삭제하기 + const contentCount = userContent.data.length; // 전체 글 수 + const contentThumbsupCount = userContent.data.reduce((acc, cur) => { + if (acc < cur.thumbsup) return cur.thumbsup; + else return acc; + }, 0); // 최고 추천수 + useEffect(() => { getUserContent(); }, []); @@ -143,15 +166,17 @@ function Mypage({ isLogin, accToken }) { {userContent.data.map((ele, idx) => { return ( -
  • +
  • readResult(ele)} + > + handleSingleCheck(e.target.checked, ele.id) } - onChange={() => handleCheck(ele.id)} />

    {ele.wordName}

    @@ -166,12 +191,16 @@ function Mypage({ isLogin, accToken }) { - + From e8b13cbb369ede94c47d58ad4fdc3a05aff68e2b Mon Sep 17 00:00:00 2001 From: minjman2659 Date: Tue, 31 Aug 2021 21:04:46 +0900 Subject: [PATCH 04/10] =?UTF-8?q?[Client]=20SignoutModal.js=20:=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=20=ED=83=88=ED=87=B4=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/.env.example | 1 + client/src/App.js | 7 ++++++- client/src/comp/Modal.js | 2 +- client/src/comp/SignoutModal.js | 34 +++++++++++++++++++++++++++++++-- client/src/pages/MypageEdit.js | 2 +- 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 client/.env.example diff --git a/client/.env.example b/client/.env.example new file mode 100644 index 0000000..168771e --- /dev/null +++ b/client/.env.example @@ -0,0 +1 @@ +REACT_APP_API_URL \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index 59beca5..8772d51 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -82,7 +82,12 @@ function App() { {/* 회원탈퇴 모달 */} {onSignoutModal ? ( - + ) : null} {/* 단어 뜻 모달 */} diff --git a/client/src/comp/Modal.js b/client/src/comp/Modal.js index 214814c..d852875 100644 --- a/client/src/comp/Modal.js +++ b/client/src/comp/Modal.js @@ -382,7 +382,7 @@ function Modal({ setOnModal, setisLogin, setUserInfo, setAccToken, accToken }) { console.log(signupResult.data.message); // {message:"~~"} history.push("/"); setOnModal(false); - alert("회원가입이 완료되었습니다."); + alert("회원가입이 완료되었습니다. 로그인 해주세요."); } } catch (error) { console.log(error); diff --git a/client/src/comp/SignoutModal.js b/client/src/comp/SignoutModal.js index acbfbf6..1ff0f3d 100644 --- a/client/src/comp/SignoutModal.js +++ b/client/src/comp/SignoutModal.js @@ -1,6 +1,9 @@ import React, { useState } from "react"; +import { useHistory } from "react-router"; import styled from "styled-components"; import logo from "../signout-logo.png"; +import axios from "axios"; +axios.defaults.withCredentials = true; const ModalBack = styled.div` width: 100vw; @@ -118,7 +121,34 @@ const CancelButton = styled.button` const KakaoWrap = styled.div``; -function SignoutModal({ setOnSignoutModal }) { +function SignoutModal({ + setOnSignoutModal, + setAccToken, + setisLogin, + accToken, +}) { + const url = process.env.REACT_APP_API_URL || `http://localhost:4000`; + const history = useHistory(); + + const handleSignOut = async () => { + try { + await axios({ + url: `${url}/user/signout`, + method: "delete", + headers: { authorization: `Bearer ${accToken}` }, + }); + alert("슬빠... (슬프지만 빠이라는 뜻) ㅠ"); + setOnSignoutModal(false); + setAccToken(null); + setisLogin(false); + localStorage.clear(); + history.push("/"); + } catch (error) { + console.log(error); + alert("다시 시도해주세요. (가지 말라는 뜻이 아닐까요?)"); + } + }; + return ( <> @@ -136,7 +166,7 @@ function SignoutModal({ setOnSignoutModal }) { setOnSignoutModal(false)}>

    떠나지 않기

    - +

    떠나기...

    diff --git a/client/src/pages/MypageEdit.js b/client/src/pages/MypageEdit.js index 66171c0..2d5dc7b 100644 --- a/client/src/pages/MypageEdit.js +++ b/client/src/pages/MypageEdit.js @@ -221,7 +221,7 @@ function MypageEdit({ } }; - const handleCancel = async () => { + const handleCancel = () => { setEditUser({ username: "", oldPassword: "", From 438dfa9dc10be1e2385c984e8748c074fd815502 Mon Sep 17 00:00:00 2001 From: minjman2659 Date: Tue, 31 Aug 2021 21:50:32 +0900 Subject: [PATCH 05/10] =?UTF-8?q?[Client/Server]=20userPicEdit=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/MypageEdit.js | 34 ++++++++++++++++-- server/controllers/user/userPicEdit.js | 48 ++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/client/src/pages/MypageEdit.js b/client/src/pages/MypageEdit.js index 2d5dc7b..8076211 100644 --- a/client/src/pages/MypageEdit.js +++ b/client/src/pages/MypageEdit.js @@ -205,7 +205,7 @@ function MypageEdit({ if (editRes.data.accessToken) { setAccToken(editRes.data.accessToken); } - alert("정보가 업데이트 되었습니다. 다시 로그인해 주세요."); + alert("정보가 업데이트 되었습니다. 다시 로그인해주세요."); await axios.post(`${url}/user/logout`, null, { headers: { authorization: `Bearer ${accToken}` }, }); @@ -217,7 +217,7 @@ function MypageEdit({ } } catch (error) { console.log(error); - alert("다시 입력해 주세요."); + alert("다시 입력해주세요."); } }; @@ -230,6 +230,32 @@ function MypageEdit({ }); }; + const handleUserPic = async () => { + try { + const userPicEdit = await axios({ + url: `${url}/user/userPicEdit`, + method: "patch", + headers: { authorization: `Bearer ${accToken}` }, + data: { userPic: userInfo.userPic }, + }); + if (userPicEdit.data.accessToken) { + setAccToken(userPicEdit.data.accessToken); + } + alert("사진이 변경되었습니다. 다시 로그인해주세요."); + await axios.post(`${url}/user/logout`, null, { + headers: { authorization: `Bearer ${accToken}` }, + }); + setCloseLogoutModal(false); + setAccToken(null); + setisLogin(false); + localStorage.clear(); + history.push("/"); + } catch (error) { + console.log(error); + alert("다시 시도해주세요."); + } + }; + return ( <> {isLogin ? ( @@ -283,7 +309,9 @@ function MypageEdit({ 이용자 사진 - + diff --git a/server/controllers/user/userPicEdit.js b/server/controllers/user/userPicEdit.js index f4a3d1e..ad877ca 100644 --- a/server/controllers/user/userPicEdit.js +++ b/server/controllers/user/userPicEdit.js @@ -1,6 +1,48 @@ +const { user } = require("../../models"); +const { + isAuthorized, + generateAccessToken, +} = require("../tokenFunction/accessToken"); +const { refreshAuthorized } = require("../tokenFunction/refreshToken"); +const { defaultImgs } = require("../user/imgResource"); +const { verify } = require("jsonwebtoken"); + +const getRandomImg = (defaultImgs) => { + const randomImgIdx = Math.floor(Math.random() * 4); + return defaultImgs[randomImgIdx]; +}; module.exports = { - patch: (req, res) => { - res.send("This is user/userPicEdit"); + patch: async (req, res) => { + const { userPic } = req.body; + // console.log(userPic); + if (!isAuthorized(req)) { + if (refreshAuthorized(req)) { + const token = req.cookies.refreshToken; + const tokenCheck = verify(token, process.env.REFRESH_SECRET); + delete tokenCheck.exp; + const accessToken = generateAccessToken(tokenCheck); + const userInfo = await user.findOne({ + where: { id: tokenCheck.id }, + }); + const newUserPics = defaultImgs.filter((el) => el !== userPic); + userInfo.userPic = getRandomImg(newUserPics); + await userInfo.save(); + res.status(201).json({ accessToken, message: "ok" }); + } else { + res.status(401).json({ message: "Send new Login Request" }); + } + } else { + const token = req.headers.authorization; + const realToken = token.split(" ")[1]; + const tokenCheck = verify(realToken, process.env.ACCESS_SECRET); + const userInfo = await user.findOne({ + where: { id: tokenCheck.id }, + }); + const newUserPics = defaultImgs.filter((el) => el !== userPic); + userInfo.userPic = getRandomImg(newUserPics); + await userInfo.save(); + res.status(200).json({ message: "ok" }); } -} \ No newline at end of file + }, +}; From 1fa88cd6465e0e61397a7e5722e898ea42081a36 Mon Sep 17 00:00:00 2001 From: Youngseo Kang Date: Tue, 31 Aug 2021 22:56:17 +0900 Subject: [PATCH 06/10] =?UTF-8?q?:sparkles:=20[Client]=20axios:=20?= =?UTF-8?q?=EC=B6=94=EC=B2=9C=20=EC=88=98=20=EC=A6=9D=EA=B0=80=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.js | 16 +++++- client/src/comp/MoreClickModal.js | 27 +++++++++- client/src/comp/SearchResult.js | 12 +++-- client/src/comp/WriteModal.js | 1 + client/src/pages/Mypage.js | 86 +++++++++++++++++++++---------- client/src/pages/Search.js | 4 +- client/src/pages/SearchMore.js | 16 ++++-- 7 files changed, 125 insertions(+), 37 deletions(-) diff --git a/client/src/App.js b/client/src/App.js index 59beca5..7cbf06d 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -27,7 +27,7 @@ function App() { const [currResult, setCurrResult] = useState({ data: "", }); // 눌러서 볼 search값 - console.log(currResult); + const [writeModal, setWriteModal] = useState(false); const [closeLogoutModal, setCloseLogoutModal] = useState(false); const [onSignoutModal, setOnSignoutModal] = useState(false); @@ -45,6 +45,11 @@ function App() { } }, [accToken]); + const [needUpdate, setNeedUpdate] = useState(false); // 리렌더링 필요한지 + useEffect(() => { + setResult([...result]); + }, [needUpdate]); + return (
    @@ -67,6 +72,8 @@ function App() { setAccToken={setAccToken} userInfo={userInfo} isLogin={isLogin} + needUpdate={needUpdate} + setNeedUpdate={setNeedUpdate} /> ) : null} @@ -90,6 +97,8 @@ function App() { ) : null} @@ -114,7 +123,6 @@ function App() { @@ -132,6 +142,8 @@ function App() { result={result} setMoreClickModal={setMoreClickModal} setWriteModal={setWriteModal} + setCurrResult={setCurrResult} + setResult={setResult} /> diff --git a/client/src/comp/MoreClickModal.js b/client/src/comp/MoreClickModal.js index 9b9894f..65c1a49 100644 --- a/client/src/comp/MoreClickModal.js +++ b/client/src/comp/MoreClickModal.js @@ -1,5 +1,6 @@ import styled from "styled-components"; import thumbs_up_icon from "../thumbs_up_icon.png"; +import axios from "axios"; const ModalBack = styled.div` width: 100vw; @@ -90,7 +91,29 @@ const Word = styled.div` } `; -function MoreClickModal({ setMoreClickModal, currResult }) { +function MoreClickModal({ + setMoreClickModal, + currResult, + setAccToken, + accToken, +}) { + const url = process.env.REACT_APP_API_URL || `http://localhost:4000`; + const thumbsUpIncrease = async (eleId) => { + let thumbsupClicked = await axios.patch( + `${url}/contents/thumbsup`, + { + contentId: String(eleId), + }, + { + headers: { authorization: `Bearer ${accToken}` }, + } + ); + if (thumbsupClicked.data.accessToken) { + setAccToken(thumbsupClicked.data.accessToken); + } + alert("좋아요 버튼을 눌렀습니다."); + setMoreClickModal(false); + }; return ( <> @@ -103,7 +126,7 @@ function MoreClickModal({ setMoreClickModal, currResult }) {

    {currResult.data.wordMean}

    - diff --git a/client/src/comp/WriteModal.js b/client/src/comp/WriteModal.js index e4ef5b3..fa347bf 100644 --- a/client/src/comp/WriteModal.js +++ b/client/src/comp/WriteModal.js @@ -109,7 +109,8 @@ function WriteModal({ accToken, setAccToken, userInfo, - setisLogin, + setNeedUpdate, + needUpdate, }) { const url = process.env.REACT_APP_API_URL || `http://localhost:4000`; const history = useHistory(); @@ -143,8 +144,8 @@ function WriteModal({ setAccToken(writeRes.data.accessToken); } alert("새로운 줄임말이 등록되었습니다."); + setNeedUpdate(!needUpdate); setWriteModal(false); - history.push("/mypage"); } } catch (error) { alert("다시 로그인해주세요."); diff --git a/client/src/pages/Search.js b/client/src/pages/Search.js index 4bc859e..2ef5f5a 100644 --- a/client/src/pages/Search.js +++ b/client/src/pages/Search.js @@ -2,7 +2,6 @@ import { useState } from "react"; import styled from "styled-components"; import SearchInput from "../comp/SearchInput"; import SearchResult from "../comp/SearchResult"; -import SearchMore from "./SearchMore"; const SearchSection = styled.section` min-height: 55vh; @@ -27,6 +26,7 @@ function Search({ result, setResult, setCurrResult, + searchWord, }) { return ( @@ -35,6 +35,7 @@ function Search({ setSearchValue={setSearchValue} setSearched={setSearched} setResult={setResult} + searchWord={searchWord} /> {searched ? ( Date: Wed, 1 Sep 2021 01:17:28 +0900 Subject: [PATCH 08/10] =?UTF-8?q?:sparkles:=20[Client]=20axiosMypage=20:?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EC=84=A0=ED=83=9D=20=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=EB=B0=95=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/Mypage.js | 59 ++++----- client/src/pages/SearchMore.js | 221 ++++++++++++++++++--------------- 2 files changed, 146 insertions(+), 134 deletions(-) diff --git a/client/src/pages/Mypage.js b/client/src/pages/Mypage.js index 5e23e0f..8a11cd8 100644 --- a/client/src/pages/Mypage.js +++ b/client/src/pages/Mypage.js @@ -83,8 +83,9 @@ function Mypage({ isLogin, accToken, setMoreClickModal, setCurrResult }) { }); const [gotDeleted, setGotDeleted] = useState(false); // 데이터 삭제하는거 확인하는 state const [orderBy, setOrderBy] = useState("byDates"); // 정리할 기준 지정 - const [isOn, setIsOn] = useState(false); - const [checkedItems, setCheckedItems] = useState([]); + const [checkedItems, setCheckedItems] = useState( + userContent.data.map((el) => el.id) + ); useEffect(() => { getUserContent(); @@ -122,37 +123,19 @@ function Mypage({ isLogin, accToken, setMoreClickModal, setCurrResult }) { }); }; // 유저가 쓴 글 가져오기 - const handleSingleCheck = async (checked, id) => { - if (checked === true) { - console.log("checked: " + checked); - await setCheckedItems([...checkedItems, id]); - console.log("isOn: " + isOn); - if (checkedItems.length === userContent.data.map.length - 1) { - setIsOn(true); - } else { - setIsOn(false); - } + const handleCheckChange = (checked, id) => { + if (checked) { + setCheckedItems([...checkedItems, id]); } else { - console.log("checked: " + checked); - await setCheckedItems([checkedItems.filter((ele) => ele.id !== id)]); - console.log("isOn: " + isOn); - if (checkedItems.length === userContent.data.map.length - 1) { - setIsOn(true); - } else { - setIsOn(false); - } + setCheckedItems(checkedItems.filter((el) => el !== id)); } - }; // checkbox 하나씩 선택하기 + }; - const handleAllClick = (checked) => { + const handleAllCheck = (checked) => { if (checked) { - // 전체 선택, true일때 - setCheckedItems([...userContent.data.map((ele) => ele.id)]); - setIsOn(true); + setCheckedItems(userContent.data.map((el) => el.id)); } else { - // 전체 해제 setCheckedItems([]); - setIsOn(false); } }; @@ -206,7 +189,7 @@ function Mypage({ isLogin, accToken, setMoreClickModal, setCurrResult }) { type="checkbox" checked={checkedItems.includes(ele.id) ? true : false} onChange={(e) => - handleSingleCheck(e.target.checked, ele.id) + handleCheckChange(e.target.checked, ele.id) } />
    - +
    diff --git a/client/src/pages/SearchMore.js b/client/src/pages/SearchMore.js index ba05e38..c8bfcd0 100644 --- a/client/src/pages/SearchMore.js +++ b/client/src/pages/SearchMore.js @@ -5,6 +5,104 @@ import thumbs_up_icon from "../thumbs_up_icon.png"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faChevronDown, faChevronUp } from "@fortawesome/free-solid-svg-icons"; +const EmptyResult = styled.div` + text-align: center; + > img { + width: 20vh; + height: 20vh; + } +`; +const Result = styled.div` + display: flex; + flex-direction: column; +`; +const ResultName = styled.h2` + text-align: center; + font-size: 1.5em; + margin-bottom: 2vw; +`; +const Morebutton = styled.button` + display: block; + width: 10vw; + min-width: 80px; + height: 5vh; + background-color: #000; + border: 2px solid #000; + border-radius: 5vh; + margin: 0 auto 2vw; + font-size: max(12px, 0.8vw); + color: #fff; + transition: all 0.3s; + cursor: pointer; + :hover { + background-color: #fff; + color: #000; + } +`; +const ResultList = styled.ul` + margin-top: 20px; + width: 100%; + margin: 0 auto; + li { + display: flex; + width: 75%; + height: 8vh; + margin: 2vh auto 0; + border: 2px solid #000; + border-radius: 40px; + text-align: center; + line-height: 8vh; + background-color: #d2f8e0; + cursor: pointer; + transition: all 0.3s; + p { + flex: 1 1 auto; + font-size: max(14px, 1vw); + } + p:nth-child(2) { + flex: 3 1 auto; + } + .imgWrap { + position: relative; + right: 0.5vw; + } + .imgWrap img { + position: relative; + top: 0.2vw; + width: max(1.1vw, 18px); + height: max(1.1vw, 18px); + } + } + li:nth-child(1) { + margin-top: 0px; + } + li:hover { + background-color: white; + color: black; + } +`; +const MoveDir = styled.div` + width: 5vh; + height: 10vh; + border: 1px solid #000; + border-radius: 30px; + overflow: hidden; + position: fixed; + right: 2vh; + bottom: 5vh; + display: flex; + flex-direction: column; + background-color: #000; + > .fit { + flex: 1 1 auto; + margin: 0 auto; + width: 50%; + background-color: #000; + color: #fff; + cursor: pointer; + } +`; + function SearchMore({ result, setMoreClickModal, @@ -17,104 +115,33 @@ function SearchMore({ setCurrResult({ data: info }); setMoreClickModal(true); }; + // const [scrollY, setScrollY] = useState(0); + // const [showBtn, setShowBtn] = useState(false); + // const handleFollow = () => { + // setScrollY(window.pageYOffset); // window scroll값 저장 + // if (scrollY > 30) { + // setShowBtn(true); + // } else { + // setShowBtn(false); + // } + // }; + // const handleTop = () => { + // window.scrollTo({ + // top: 0, + // behavior: "smooth", + // }); + // setScrollY(0); + // setShowBtn(false); + // }; + // const handleDown = () => { + // window.scrollTo({ + // bottom: 0, + // behavior: "smooth", + // }); + // setScrollY(0); + // setShowBtn(false); + // }; - const EmptyResult = styled.div` - text-align: center; - > img { - width: 20vh; - height: 20vh; - } - `; - const Result = styled.div` - display: flex; - flex-direction: column; - `; - const ResultName = styled.h2` - text-align: center; - font-size: 1.5em; - margin-bottom: 2vw; - `; - const Morebutton = styled.button` - display: block; - width: 10vw; - min-width: 80px; - height: 5vh; - background-color: #000; - border: 2px solid #000; - border-radius: 5vh; - margin: 0 auto 2vw; - font-size: max(12px, 0.8vw); - color: #fff; - transition: all 0.3s; - cursor: pointer; - :hover { - background-color: #fff; - color: #000; - } - `; - const ResultList = styled.ul` - margin-top: 20px; - width: 100%; - margin: 0 auto; - li { - display: flex; - width: 75%; - height: 8vh; - margin: 2vh auto 0; - border: 2px solid #000; - border-radius: 40px; - text-align: center; - line-height: 8vh; - background-color: #d2f8e0; - cursor: pointer; - transition: all 0.3s; - p { - flex: 1 1 auto; - font-size: max(14px, 1vw); - } - p:nth-child(2) { - flex: 3 1 auto; - } - .imgWrap { - position: relative; - right: 0.5vw; - } - .imgWrap img { - position: relative; - top: 0.2vw; - width: max(1.1vw, 18px); - height: max(1.1vw, 18px); - } - } - li:nth-child(1) { - margin-top: 0px; - } - li:hover { - background-color: white; - color: black; - } - `; - const MoveDir = styled.div` - width: 5vh; - height: 10vh; - border: 1px solid #000; - border-radius: 30px; - overflow: hidden; - position: fixed; - right: 2vh; - bottom: 5vh; - display: flex; - flex-direction: column; - background-color: #000; - > .fit { - flex: 1 1 auto; - margin: 0 auto; - width: 50%; - background-color: #000; - color: #fff; - cursor: pointer; - } - `; return ( <> {moreResult.length === 0 ? ( From a4989a76127ca86793d1cee04b502e09f81aa9da Mon Sep 17 00:00:00 2001 From: Youngseo Kang Date: Wed, 1 Sep 2021 02:40:11 +0900 Subject: [PATCH 09/10] =?UTF-8?q?:sparkles:=20[Client]=20axiosEditContent?= =?UTF-8?q?=20:=20=EB=8B=A8=EC=96=B4=20=EB=9C=BB=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20axios=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20u?= =?UTF-8?q?seEffect=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.js | 39 +++++- client/src/comp/EditContentModal.js | 176 ++++++++++++++++++++++++++++ client/src/pages/Mypage.js | 39 +++--- 3 files changed, 232 insertions(+), 22 deletions(-) create mode 100644 client/src/comp/EditContentModal.js diff --git a/client/src/App.js b/client/src/App.js index 59fa783..fd1c2a2 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -13,6 +13,7 @@ import MypageEdit from "./pages/MypageEdit"; import SignoutModal from "./comp/SignoutModal"; import MoreClickModal from "./comp/MoreClickModal"; import axios from "axios"; +import EditContentModal from "./comp/EditContentModal"; function App() { // console.log(dummyData); @@ -29,12 +30,19 @@ function App() { const [currResult, setCurrResult] = useState({ data: "", }); // 눌러서 볼 search값 + const [editResult, setEditResult] = useState({ + data: "", + }); // 변경 필요한 값 + const [userContent, setUserContent] = useState({ + data: [], + }); // 개인이 작성한 글 결과값 const [needUpdate, setNeedUpdate] = useState(false); // 리렌더링 필요한지 const [writeModal, setWriteModal] = useState(false); const [closeLogoutModal, setCloseLogoutModal] = useState(false); const [onSignoutModal, setOnSignoutModal] = useState(false); const [moreClickModal, setMoreClickModal] = useState(false); + const [editContentModal, setEditContentModal] = useState(false); useEffect(() => { setSearched(false); @@ -48,8 +56,9 @@ function App() { } }, [accToken]); - useEffect(() => { - searchWord(searchValue); + useEffect(async () => { + await searchWord(searchValue); + await searchUserWord(); }, [needUpdate]); const searchWord = async (searchValue) => { @@ -60,6 +69,17 @@ function App() { setSearched(true); }; + const searchUserWord = async () => { + let userContent = await axios.get(`${url}/myContents`, { + header: { authorization: `Bearer ${accToken}` }, + }); + setUserContent({ + data: userContent.data.data.sort( + (a, b) => new Date(b.createdAt) - new Date(a.createdAt) + ), + }); + }; // 유저가 쓴 글 가져오기 + return (
    @@ -119,6 +139,17 @@ function App() { /> ) : null} + {/*단어 뜻 수정 모달 */} + {editContentModal ? ( + + ) : null}
  • ); From 8ac8bd16816b1c17756fa63092c0b69deaa47f53 Mon Sep 17 00:00:00 2001 From: Lee Naeun Date: Wed, 1 Sep 2021 10:50:20 +0900 Subject: [PATCH 10/10] =?UTF-8?q?[Client]=20Mypage.js=20:=20css=20?= =?UTF-8?q?=EB=B0=8F=20=EC=B5=9C=EC=8B=A0=20=EC=84=B1=EB=8A=A5=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.js | 3 +- client/src/comp/SearchResult.js | 28 ++++++--- client/src/comp/logoutModal.js | 2 + client/src/dummy/dummyData.js | 107 -------------------------------- client/src/pages/Mypage.js | 49 ++++++++++----- client/src/pages/Search.js | 4 +- 6 files changed, 60 insertions(+), 133 deletions(-) delete mode 100644 client/src/dummy/dummyData.js diff --git a/client/src/App.js b/client/src/App.js index fd1c2a2..e323632 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,5 +1,4 @@ import "./app.css"; -import dummyData from "./dummy/dummyData"; import Search from "./pages/Search"; import SearchMore from "./pages/SearchMore"; import { useEffect, useState } from "react"; @@ -113,6 +112,7 @@ function App() { setCloseLogoutModal={setCloseLogoutModal} setisLogin={setisLogin} accToken={accToken} + setSearched={setSearched} setAccToken={setAccToken} /> ) : null} @@ -205,6 +205,7 @@ function App() { setCurrResult={setCurrResult} setEditContentModal={setEditContentModal} setEditResult={setEditResult} + setUserContent={setUserContent} /> diff --git a/client/src/comp/SearchResult.js b/client/src/comp/SearchResult.js index c6a859d..94ad836 100644 --- a/client/src/comp/SearchResult.js +++ b/client/src/comp/SearchResult.js @@ -1,5 +1,6 @@ import React, { useEffect } from "react"; import styled from "styled-components"; +import thumbs_up_icon from "../thumbs_up_icon.png"; import { Link, Redirect } from "react-router-dom"; import empty from "../empty.png"; @@ -43,23 +44,29 @@ function SearchResult({ cursor: pointer; transition: all 0.3s; p { - padding: 0 5px; + flex: 1 1 auto; font-size: max(14px, 1vw); - flex: 1 0 auto; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; } p:nth-child(2) { flex: 3 1 auto; } + .imgWrap { + position: relative; + right: 0.5vw; + } + .imgWrap img { + position: relative; + top: 0.2vw; + width: max(1.1vw, 18px); + height: max(1.1vw, 18px); + } } li:nth-child(1) { margin-top: 0px; } li:hover { - background-color: #000; - color: #fff; + background-color: white; + color: black; } `; const EmptyResult = styled.div` @@ -131,7 +138,12 @@ function SearchResult({
  • showMore(ele)}>

    {ele.wordName}

    {ele.wordMean}

    -

    {ele.thumbsup}

    +

    + + thumbsup + + {ele.thumbsup} +

  • ); })} diff --git a/client/src/comp/logoutModal.js b/client/src/comp/logoutModal.js index d52c6a3..200de44 100644 --- a/client/src/comp/logoutModal.js +++ b/client/src/comp/logoutModal.js @@ -96,6 +96,7 @@ function LogoutModal({ setCloseLogoutModal, setisLogin, accToken, + setSearched, setAccToken, }) { const url = process.env.REACT_APP_API_URL || `http://localhost:4000`; @@ -107,6 +108,7 @@ function LogoutModal({ setCloseLogoutModal(false); setAccToken(null); setisLogin(false); + setSearched(false); localStorage.clear(); history.push("/"); }; diff --git a/client/src/dummy/dummyData.js b/client/src/dummy/dummyData.js deleted file mode 100644 index 97ca478..0000000 --- a/client/src/dummy/dummyData.js +++ /dev/null @@ -1,107 +0,0 @@ -const word = [ - { - id: 1, - wordName: "자만추", - wordMean: "자연스러운 만남 추구", - thumbsup: 10, - created_at: Date.now(), - userId: 4, - }, - { - id: 2, - wordName: "자만추", - wordMean: "자릿값 만원 추가", - thumbsup: 15, - created_at: Date.now(), - userId: 3, - }, - { - id: 3, - wordName: "자만추", - wordMean: "자장면에 만두 추가", - thumbsup: 5, - created_at: Date.now(), - userId: 2, - }, - { - id: 4, - wordName: "자만추", - wordMean: "자주 만나기 추하다", - thumbsup: 20, - created_at: Date.now(), - userId: 3, - }, - { - id: 4, - wordName: "자만추", - wordMean: "자주 만나기 추하다", - thumbsup: 20, - created_at: Date.now(), - userId: 3, - }, - { - id: 4, - wordName: "자만추", - wordMean: "자주 만나기 추하다", - thumbsup: 20, - created_at: Date.now(), - userId: 3, - }, - { - id: 4, - wordName: "자만추", - wordMean: "자주 만나기 추하다", - thumbsup: 20, - created_at: Date.now(), - userId: 3, - }, - { - id: 4, - wordName: "자만추", - wordMean: "자주 만나기 추하다", - thumbsup: 20, - created_at: Date.now(), - userId: 3, - }, -]; - -const userInfo = [ - { - id: 1, - username: "김민재", - email: "blackbean@gmail.com", - password: "Minjae!123", - phone: "01010101010", - userPic: null, - created_at: Date.now(), - }, - { - id: 2, - username: "강영서", - email: "younglady@gmail.com", - password: "Young!123", - phone: "01012121212", - userPic: null, - created_at: Date.now(), - }, - { - id: 3, - username: "배윤수", - email: "pearYoon@gmail.com", - password: "Pear!123", - phone: "01022222222", - userPic: null, - created_at: Date.now(), - }, - { - id: 4, - username: "이나은", - email: "nanni@gmail.com", - password: "Nanni!123", - phone: "01088888888", - userPic: null, - created_at: Date.now(), - }, -]; - -export default { userInfo, word }; diff --git a/client/src/pages/Mypage.js b/client/src/pages/Mypage.js index 3eba74a..b0f3490 100644 --- a/client/src/pages/Mypage.js +++ b/client/src/pages/Mypage.js @@ -24,6 +24,28 @@ const UserContent = styled.div` padding: 1vw 0; border-bottom: 3px solid #000; margin-bottom: 2vw; + > p { + line-height: 20px; + font-size: max(0.9vw, 13px); + padding: 10px 0; + > span { + font-weight: 700; + } + } + > select { + width: max(5vw, 60px); + height: max(2vw, 20px); + background-color: white; + border-radius: 20px; + outline: none; + cursor: pointer; + text-align-last: center; + text-align: center; + border: 2px solid black; + -ms-text-align-last: center; + -moz-text-align-last: center; + font-size: max(0.8vw, 10px); + } `; const ContentList = styled.ul` @@ -94,6 +116,7 @@ function Mypage({ userContent.data.map((el) => el.id) ); + console.log(userContent); useEffect(() => { searchUserWord(); }, [gotDeleted]); // 삭제시 다시 데이터 받아옴 @@ -167,10 +190,20 @@ function Mypage({ {" "} {/* 내가 쓴 글 목록 */} +
    + handleAllCheck(e.target.checked)} + /> + 전체 선택 +

    - 작성하신 글은 {contentCount}개 이며, 최대 추천수는{" "} - {contentThumbsupCount}개 입니다 + 작성하신 글은 {contentCount}개 이며, 최대 추천수는{" "} + {contentThumbsupCount}개 입니다

    handleAllCheck(e.target.checked)} - /> - 전체 선택 - diff --git a/client/src/pages/Search.js b/client/src/pages/Search.js index 2ef5f5a..282ccfe 100644 --- a/client/src/pages/Search.js +++ b/client/src/pages/Search.js @@ -50,9 +50,7 @@ function Search({ setAccToken={setAccToken} setCurrResult={setCurrResult} /> - ) : ( -
    하이~ 에이치아이~
    - )} + ) : null} ); }