From 04b22d99f3a5e1c54860bec3a5c2695c8309055d Mon Sep 17 00:00:00 2001 From: HyunJungJo98 Date: Wed, 16 Mar 2022 21:16:50 +0900 Subject: [PATCH] =?UTF-8?q?[#47]=EA=B4=80=EB=A6=AC=EC=9E=90=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=94=94=EC=9E=90=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Comment/Comment.js | 1 - .../src/components/DMPage/DMDetail.js | 18 ++- .../src/components/Modals/Modal.js | 8 +- .../src/components/MyPage/MyPageAdmin.js | 43 ++++-- .../src/components/Report/Report.js | 99 ++++++++++++-- .../src/components/TopBar/LogIn.js | 9 +- .../src/components/TopBar/NavigationBar.js | 11 +- .../TransactionPage/TransactionPage.js | 30 ++-- .../src/css/Comments.module.css | 3 - .../src/css/DMPage/DMList.module.css | 1 - .../EventPage/EventMovieThumbnail.module.css | 13 +- .../src/css/Modal/modal.module.css | 4 +- .../src/css/MyPage/MyPageAdmin.module.css | 71 ++++++++++ .../src/css/Report/Report.module.css | 129 ++++++++++++++++++ .../src/css/TopBar/LogIn.module.css | 2 +- frontend/sweet-red-beans/src/img/ticket3.png | Bin 0 -> 9338 bytes 16 files changed, 372 insertions(+), 70 deletions(-) delete mode 100644 frontend/sweet-red-beans/src/css/Comments.module.css create mode 100644 frontend/sweet-red-beans/src/css/MyPage/MyPageAdmin.module.css create mode 100644 frontend/sweet-red-beans/src/css/Report/Report.module.css create mode 100644 frontend/sweet-red-beans/src/img/ticket3.png diff --git a/frontend/sweet-red-beans/src/components/Comment/Comment.js b/frontend/sweet-red-beans/src/components/Comment/Comment.js index 62b9132..38e129d 100644 --- a/frontend/sweet-red-beans/src/components/Comment/Comment.js +++ b/frontend/sweet-red-beans/src/components/Comment/Comment.js @@ -1,5 +1,4 @@ import React, { useEffect, useState } from "react"; -import styles from "../../css/Comments.module.css" import axios from "axios"; import { useNavigate } from "react-router"; import { useSelector } from "react-redux"; diff --git a/frontend/sweet-red-beans/src/components/DMPage/DMDetail.js b/frontend/sweet-red-beans/src/components/DMPage/DMDetail.js index 5468cf8..52d2631 100644 --- a/frontend/sweet-red-beans/src/components/DMPage/DMDetail.js +++ b/frontend/sweet-red-beans/src/components/DMPage/DMDetail.js @@ -101,22 +101,20 @@ const DMDetail = ({selectedRoom}) => { setContents(prev=>[...prev, message]); }; - const onChange = useCallback( (e) => { setMessage(e.target.value); }, [] ) - - const disconnect = () => { - if(stompClient != null) { - stompClient.disconnect(); - } - } + useEffect(() => { + console.log("아ㅏ아아ㅏ아아아아"); + }, []) //이제까지 메시지 내역 조회 useEffect(() => { + setContents([]); + setMessage(""); if(selectedRoom !== undefined){ axios.get("http://localhost:8080/direct-message/detail", { withCredentials: true, @@ -139,6 +137,12 @@ const DMDetail = ({selectedRoom}) => { }) }); setComplete(selectedRoom.is_complete) + + return () => { + if(stompClient != null) { + stompClient.disconnect(); + } + } }, [selectedRoom]) //신뢰도 +1 주는 버튼 diff --git a/frontend/sweet-red-beans/src/components/Modals/Modal.js b/frontend/sweet-red-beans/src/components/Modals/Modal.js index e1b2996..6f6d408 100644 --- a/frontend/sweet-red-beans/src/components/Modals/Modal.js +++ b/frontend/sweet-red-beans/src/components/Modals/Modal.js @@ -20,11 +20,11 @@ const Modal = (props) => { {header}
{props.children}
- + + */} ) : null} diff --git a/frontend/sweet-red-beans/src/components/MyPage/MyPageAdmin.js b/frontend/sweet-red-beans/src/components/MyPage/MyPageAdmin.js index eec3bd1..af3268a 100644 --- a/frontend/sweet-red-beans/src/components/MyPage/MyPageAdmin.js +++ b/frontend/sweet-red-beans/src/components/MyPage/MyPageAdmin.js @@ -2,12 +2,13 @@ import React, { useEffect, useState } from "react"; import Report from "../Report/Report"; import axios from "axios"; import Pagination from "./MyPageDetail/Pagination"; +import style from "../../css/MyPage/MyPageAdmin.module.css"; const MyPageAdmin = () => { const [reports, setReports] = useState([]); const [reportIsHere, setReportIsHere] = useState(false); - const [limit, setLimit] = useState(10); + const [limit, setLimit] = useState(15); const [page, setPage] = useState(1); const offset = (page - 1) * limit; @@ -27,21 +28,33 @@ const MyPageAdmin = () => { return ( <> - {reportIsHere ? reports.slice(offset, offset + limit).map((item, index) => ( -
- -
- )) : null} +
+
+
+
승인여부
+
신고자
+
신고 받은 사람
+
신고한 시간
+
+
+ {reportIsHere ? reports.slice(offset, offset + limit).map((item, index) => ( +
+ +
+ )) : null} +
+
+
+ {reports !== undefined ? + + : null + } +
+
- ) } diff --git a/frontend/sweet-red-beans/src/components/Report/Report.js b/frontend/sweet-red-beans/src/components/Report/Report.js index 12eb30c..1006471 100644 --- a/frontend/sweet-red-beans/src/components/Report/Report.js +++ b/frontend/sweet-red-beans/src/components/Report/Report.js @@ -1,46 +1,123 @@ import axios from "axios"; import React, { useEffect, useState } from "react"; +import { useNavigate } from "react-router"; +import style from "../../css/Report/Report.module.css"; +import Modal from "../Modals/Modal"; const Report = ({report}) => { + const navigation = useNavigate(); + const [modalOpen, setModalOpen] = useState(false); const [content, setContent] = useState(""); const [date, setDate] = useState(""); const [nickname, setNickname] = useState(""); - const [disable, setDisable] = useState(false); const [reportedNickname, setReportedNickname] = useState(""); + const [isComplete, setIsComplete] = useState(false); + + const openModal = () => { + setModalOpen(true); + }; + const closeModal = () => { + setModalOpen(false); + }; useEffect(() => { setContent(report.report_content); setDate(report.written_date) setNickname(report.nickname); setReportedNickname(report.reported_nickname) - }, []) + setIsComplete(report.is_complete); + console.log(report); + }, [report]) + + const useConfirm = (message = null, onConfirm, onCancel) => { + if (!onConfirm || typeof onConfirm !== "function") { + return; + } + if (onCancel && typeof onCancel !== "function") { + return; + } + + const confirmAction = () => { + if (window.confirm(message)) { + onConfirm(); + } else { + onCancel(); + } + }; + + return confirmAction; + }; - const reportAcceptClick = () => { + const confirm = () => { axios.patch('http://localhost:8080/manager/report', { - user_id:report.user_id + user_id:report.reported_nickname }, {withCredentials: true} ) .then((response) => { if(response.data){ - setDisable(true); console.log(response.data) } }) .catch((error) => { console.log(error); }) + closeModal(); + navigation(0); + } + + const cancelConfirm = () => console.log("승인 취소") + + const reportAcceptClick = useConfirm( + "승인하시겠습니까?", + confirm, + cancelConfirm + ); + + const parseDate = (written_date) => { + const d = new Date(written_date); + const year = d.getFullYear(); + let month = d.getMonth(); + let date = d.getDate(); + let hours = d.getHours(); + let min = d.getMinutes(); + if(month<10){ + month = '0'+month; + } + if(date<10){ + date = '0'+date; + } + if(hours<10){ + hours = '0'+hours; + } + if(min<10){ + min = '0'+min; + } + return ( +
{year}-{month}-{date} {hours} : {min}
+ ) } return ( <> -
{content}
-
{date}
-
{nickname}
-
신고당한 사람 : {reportedNickname}
-
- + +
+
+
신고자 : {nickname}
+
{parseDate(date)}
+
+
신고 받은 사람 : {reportedNickname}
+
{content}
+ +
+
+
+
{isComplete ? "승인" : "미승인"}
+
{nickname}
+
{reportedNickname}
+
{parseDate(date)}
+ ) } diff --git a/frontend/sweet-red-beans/src/components/TopBar/LogIn.js b/frontend/sweet-red-beans/src/components/TopBar/LogIn.js index a3e361d..d114c6b 100644 --- a/frontend/sweet-red-beans/src/components/TopBar/LogIn.js +++ b/frontend/sweet-red-beans/src/components/TopBar/LogIn.js @@ -74,9 +74,15 @@ const LogIn = () =>{ const date = new Date(); date.setMinutes(date.getMinutes() + 30); cookies.set("login", true, {expires: date}); + cookies.set("user", { + authority:response.data.authority, + porfileImage:response.data.image_url, + nickname:response.data.nickname, + }, {expires:date}); setModalOpen(false); - navigation(0); + + } else { alert("로그인에 실패했습니다."); @@ -95,6 +101,7 @@ const LogIn = () =>{ .then(response => { if(response.data.result){ cookies.remove("login") + cookies.remove("user") navigation(0) } else { alert("로그아웃에 실패했습니다."); diff --git a/frontend/sweet-red-beans/src/components/TopBar/NavigationBar.js b/frontend/sweet-red-beans/src/components/TopBar/NavigationBar.js index 0f02f5b..f8c9111 100644 --- a/frontend/sweet-red-beans/src/components/TopBar/NavigationBar.js +++ b/frontend/sweet-red-beans/src/components/TopBar/NavigationBar.js @@ -4,8 +4,10 @@ import { Link } from "react-router-dom"; import styles from "../../css/TopBar/NavigationBar.module.css"; import BottomCategory from "./BottomCategory"; import { useNavigate } from "react-router"; +import { Cookies } from "react-cookie"; const NavigationBar = () => { + const cookies = new Cookies(); const navigation = useNavigate(); const [hide, setHide] = useState(true); const [userId, setUserId] = useState(false); @@ -44,7 +46,14 @@ const NavigationBar = () => { } const mypageClick = () => { - navigation('/mypage'); + const authority = cookies.get("user").authority + if(authority === "일반") { + navigation('/mypage'); + } + else if (authority === "관리자") { + navigation('/adminpage'); + } + } diff --git a/frontend/sweet-red-beans/src/components/TransactionPage/TransactionPage.js b/frontend/sweet-red-beans/src/components/TransactionPage/TransactionPage.js index 55dab3a..b41ffa7 100644 --- a/frontend/sweet-red-beans/src/components/TransactionPage/TransactionPage.js +++ b/frontend/sweet-red-beans/src/components/TransactionPage/TransactionPage.js @@ -8,9 +8,12 @@ import { getCookie } from "../../Cookie"; import { useNavigate } from "react-router"; import { useSelector } from "react-redux"; import userImage from "../../img/user.png"; +import { Cookies } from "react-cookie"; const TransactionPage = () => { - const navigation = useNavigate() + const cookies = new Cookies(); + const navigation = useNavigate(); + const [modalOpen, setModalOpen] = useState(false); const [transactions, setTransactions] = useState([]); const [transactionIsHere, setTransactionIsHere] = useState(false); @@ -32,7 +35,6 @@ const TransactionPage = () => { //내 프로필 const [nickname, setNickname] = useState(""); const [profileImage, setProfileImage] = useState(""); - const [reliability, setReliability] = useState(0); const [fetching, setFetching] = useState(false); @@ -231,21 +233,15 @@ const TransactionPage = () => { .catch(error => console.log(error)); //내 프로필 조회 - axios.get('http://localhost:8080/mypage',{ - withCredentials: true , - }) - .then(response => { - setNickname(response.data.user.nickname); - setProfileImage(response.data.user.profile_url); - setReliability(response.data.user.reliability); - }) - .catch(error => { - if(error.response.status === 401){ - setNickname("익명"); - setProfileImage(userImage); - setReliability(0); - } - }); + if(cookies.get("user")){ + setNickname(cookies.get("user").nickname); + setProfileImage(cookies.get("user").porfileImage); + } + else { + setNickname("익명"); + setProfileImage(userImage); + } + }, []) useEffect(()=>{ diff --git a/frontend/sweet-red-beans/src/css/Comments.module.css b/frontend/sweet-red-beans/src/css/Comments.module.css deleted file mode 100644 index 00ff9fd..0000000 --- a/frontend/sweet-red-beans/src/css/Comments.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.display{ - visibility: hidden; -} \ No newline at end of file diff --git a/frontend/sweet-red-beans/src/css/DMPage/DMList.module.css b/frontend/sweet-red-beans/src/css/DMPage/DMList.module.css index 561b7fa..85a75e9 100644 --- a/frontend/sweet-red-beans/src/css/DMPage/DMList.module.css +++ b/frontend/sweet-red-beans/src/css/DMPage/DMList.module.css @@ -23,5 +23,4 @@ border-radius: 20px; background-clip: padding-box; border: 4px solid transparent; - } \ No newline at end of file diff --git a/frontend/sweet-red-beans/src/css/EventPage/EventMovieThumbnail.module.css b/frontend/sweet-red-beans/src/css/EventPage/EventMovieThumbnail.module.css index 7dd51e9..75352ce 100644 --- a/frontend/sweet-red-beans/src/css/EventPage/EventMovieThumbnail.module.css +++ b/frontend/sweet-red-beans/src/css/EventPage/EventMovieThumbnail.module.css @@ -42,23 +42,24 @@ } .likeOnButton { - background: url("../../img/ticket.png"); + background: url("../../img/ticket3.png"); } .likeOffButton { - background: url("../../img/ticket.png"); + background: url("../../img/ticket3.png"); } .likeOnButton, .likeOffButton { cursor: pointer; position: absolute; - width: 50px; - height: 50px; + width: 40px; + height: 40px; border-radius: 50px; - border: #c4c4c4 solid 1px; - background-size: 60%; + background-size: 80%; background-repeat: no-repeat; background-position: 50% 50%; + border: none; + /* border: #c4c4c4 solid 1px;*/ background-color: rgba(255, 255, 255, 0.8); top: 10px; right: 10px; diff --git a/frontend/sweet-red-beans/src/css/Modal/modal.module.css b/frontend/sweet-red-beans/src/css/Modal/modal.module.css index 7bae988..634af5f 100644 --- a/frontend/sweet-red-beans/src/css/Modal/modal.module.css +++ b/frontend/sweet-red-beans/src/css/Modal/modal.module.css @@ -7,11 +7,11 @@ left: 0; z-index: 99; background-color: rgba(0, 0, 0, 0.6); - } +} .openModal > section { width: 90%; - max-width: 450px; + max-width: 500px; margin: 0 auto; border-radius: 0.3rem; background-color: white; diff --git a/frontend/sweet-red-beans/src/css/MyPage/MyPageAdmin.module.css b/frontend/sweet-red-beans/src/css/MyPage/MyPageAdmin.module.css new file mode 100644 index 0000000..76f90ba --- /dev/null +++ b/frontend/sweet-red-beans/src/css/MyPage/MyPageAdmin.module.css @@ -0,0 +1,71 @@ +.layout{ + max-width: 800px; + margin: 0 auto; + margin-top: 50px; + background-color: white; + border: #c4c4c4 1px solid; + border-radius: 20px; + padding: 50px 100px 30px 100px; +} + +.reportBox { + width: 100%; + border-top: #F23333 3px solid; +} + +.topBar { + position: relative; + height: 45px; + border-bottom: #c4c4c4 1px solid; +} + +.topBar div { + position: absolute; + display: inline-block; + top:50%; + transform: translate(0%, -50%); + font-size: 14px; +} + +.topBar div:nth-child(1) { + left:15px; + width: 60px; +} + +.topBar div:nth-child(2) { + left:200px; + width: 100px; +} + +.topBar div:nth-child(3) { + left: 400px; + width: 100px; +} + +.topBar div:nth-child(4) { + right:0px; + width: 200px; +} +.writeButtonArea { + margin-top: 30px; + text-align: right; +} + +.writeButtonArea button{ + cursor: pointer; + border: none; + width: 100px; + height: 50px; + background-color: #F23333; + color: white; + border-radius: 10px; + font-size: 1rem; + font-family: 'ROKAFSansBold'; +} + +@font-face { + font-family: 'ROKAFSansBold'; + src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts2201-3@1.0/ROKAFSansBold.woff') format('woff'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/frontend/sweet-red-beans/src/css/Report/Report.module.css b/frontend/sweet-red-beans/src/css/Report/Report.module.css new file mode 100644 index 0000000..79e0838 --- /dev/null +++ b/frontend/sweet-red-beans/src/css/Report/Report.module.css @@ -0,0 +1,129 @@ +.main { + position: relative; + height: 45px; + border-bottom: #c4c4c4 1px solid; +} + +.main > div{ + position: absolute; + display: inline-block; + top:50%; + transform: translate(0%, -50%); + color: black; + font-size: 14px; + overflow:hidden; + text-overflow: ellipsis; + white-space:nowrap; +} + +.main > div:nth-child(1) { + cursor: pointer; + width: 60px;; + text-align: center; + left:15px; +} + +.main > div:nth-child(1):hover { + text-decoration: underline; +} + +.main > .incomplete { + color: #F32222; +} + +.main > div:nth-child(2) { + left:200px; + width: 100px; + color: #c4c4c4; + cursor:default; +} + +.main > div:nth-child(3) { + left: 400px; + width: 100px; + color: #c4c4c4; + cursor:default; +} + +.main > div:nth-child(4) { + right:0px; + width: 200px; + color: #c4c4c4; + cursor:default; +} + +.modal { + font-size: 14px; + margin: 0 auto; + width: 400px; +} + +.modal > .topArea { + position: relative; + height: 45px; + text-align: center; + border-top: #F32222 3px solid; + border-bottom: #c4c4c4 1px solid; +} + +.modal > .topArea > div { + position: absolute; + top:50%; + transform: translate(0, -50%); +} + +.modal > .topArea > div:nth-child(1) { + left: 10px; +} + +.modal > .topArea > div:nth-child(2) { + font-size: 12px; + color: #c4c4c4; + right: 10px; +} + +/* 신고 받은 사람 */ +.modal > div:nth-child(2) { + height: 45px; + border-bottom: #c4c4c4 1px solid; + vertical-align: middle; + display: flex; + align-items: center; + box-sizing: border-box; + padding-left: 10px; + background-color: #f0f0f0; +} + +/* 내용 */ +.modal > div:nth-child(3) { + height: 300px; + border-bottom: #c4c4c4 1px solid; + text-align: left; + box-sizing: border-box; + padding: 10px; + overflow:auto; +} + +.modal > div:nth-child(3)::-webkit-scrollbar{ + width: 15px; +} + +.modal > div:nth-child(3)::-webkit-scrollbar-thumb{ + width: 15px; + background-color: #C4C4C4; + border-radius: 20px; + background-clip: padding-box; + border: 4px solid transparent; +} + +.modal > button { + font-size: 16px; + cursor: pointer; + margin-top: 45px; + height: 50px; + width: 110px; + background-color: #F32222; + color: white; + border: none; + border-radius: 10px; +} \ No newline at end of file diff --git a/frontend/sweet-red-beans/src/css/TopBar/LogIn.module.css b/frontend/sweet-red-beans/src/css/TopBar/LogIn.module.css index d86114c..c579fb4 100644 --- a/frontend/sweet-red-beans/src/css/TopBar/LogIn.module.css +++ b/frontend/sweet-red-beans/src/css/TopBar/LogIn.module.css @@ -28,7 +28,7 @@ color: #F23333; margin-bottom: 15px; text-align: left; - margin-left: 65px; + margin-left: 85px; margin-top: -5px; } diff --git a/frontend/sweet-red-beans/src/img/ticket3.png b/frontend/sweet-red-beans/src/img/ticket3.png new file mode 100644 index 0000000000000000000000000000000000000000..722540001dd3546fe5f8e53a1314ef4974088835 GIT binary patch literal 9338 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