diff --git a/src/api/comment.js b/src/api/comment.js index c290452..0ff2b5c 100644 --- a/src/api/comment.js +++ b/src/api/comment.js @@ -1,4 +1,4 @@ -import instance from "../shared/axios"; +import instance from '../shared/axios'; export const commentApis = { getCommentList: async (id) => await instance.get(`api/posts/${id}/comments`), @@ -9,16 +9,16 @@ export const commentApis = { editComment: async (commentData) => await instance.put( `api/posts/${commentData.id}/comments/${commentData.commentId}`, - commentData + commentData, ), removeComment: async (commentData) => await instance.delete( - `api/posts/${commentData.id}/comments/${commentData.commentId}` + `api/posts/${commentData.id}/comments/${commentData.commentId}`, ), postReply: async (replyData) => - await instance.post(`api/comments/${replyData.replyId}/commentReply`, { + await instance.post(`api/comments/${replyData.commentId}/commentReply`, { content: replyData.content, }), diff --git a/src/components/AlertModal.js b/src/components/AlertModal.js index 49e32b6..8e64c73 100644 --- a/src/components/AlertModal.js +++ b/src/components/AlertModal.js @@ -1,8 +1,14 @@ -import styled, { css, keyframes } from "styled-components"; -import { Btn, GrayLineBtn, ModalBtn } from "../styles/style"; -import { Content } from "./ApplyBtn"; +import styled, { css, keyframes } from 'styled-components'; +import { Btn, GrayLineBtn, ModalBtn } from '../styles/style'; +import { Content } from './ApplyBtn'; -const AlertModal = ({open, message, setAlertModalOpen, actionMessage, action}) => { +const AlertModal = ({ + open, + message, + setAlertModalOpen, + actionMessage, + action, +}) => { ////console.log(props) // const { open } = props; // console.log(props) @@ -11,24 +17,17 @@ const AlertModal = ({open, message, setAlertModalOpen, actionMessage, action}) = {open && (
- {message} -
- {!actionMessage ? - setAlertModalOpen(false)}> - 확인 - : - <> - setAlertModalOpen(false)}>취소 - - {actionMessage} - - - - - - } - -
+ {message} +
+ {!actionMessage ? ( + 확인 + ) : ( + <> + 취소 + {actionMessage} + + )} +
)} @@ -37,7 +36,6 @@ const AlertModal = ({open, message, setAlertModalOpen, actionMessage, action}) = }; const Wrap = styled.div` - ${(props) => props.open && css` @@ -49,8 +47,8 @@ const Wrap = styled.div` z-index: 99; background-color: rgba(0, 0, 0, 0.3); display: flex; - align-items: center;'' - animation: ${ModalBgShow} 0.3s; + align-items: center; + ''animation: ${ModalBgShow} 0.3s; `} `; @@ -76,14 +74,14 @@ const ModalBgShow = keyframes` `; export const Section = styled.section` - height:200px; + height: 200px; margin: 0 auto; - display:flex; - justify-content:center; - align-items:center; + display: flex; + justify-content: center; + align-items: center; border-radius: 15px; - border:${props => props.theme.border}; - background-color: ${(props)=>props.theme.backgroundColor}; + border: ${(props) => props.theme.border}; + background-color: ${(props) => props.theme.backgroundColor}; animation: ${ModalShow} 0.3s; overflow: hidden; `; diff --git a/src/components/ApplyBtn.js b/src/components/ApplyBtn.js index 3d42d3c..3e21cf1 100644 --- a/src/components/ApplyBtn.js +++ b/src/components/ApplyBtn.js @@ -1,17 +1,17 @@ -import { useState } from "react"; -import { Btn, GrayLineBtn, LineBtn } from "../styles/style"; -import styled, { css, keyframes } from "styled-components"; -import { useQueryClient } from "react-query"; -import { usePostApply } from "../hook/useApplyMutation"; -import ViewApply from "../components/ViewApply"; -import AlertModal from "../components/AlertModal"; -import { usePostDeadline } from "../hook/usePostData"; +import { useState } from 'react'; +import { Btn, GrayLineBtn, LineBtn } from '../styles/style'; +import styled, { css, keyframes } from 'styled-components'; +import { useQueryClient } from 'react-query'; +import { usePostApply } from '../hook/useApplyMutation'; +import ViewApply from '../components/ViewApply'; +import AlertModal from '../components/AlertModal'; +import { usePostDeadline } from '../hook/usePostData'; const ApplyBtn = ({ myPostData }) => { const [isHover, setIsHover] = useState(false); const [viewApply, setViewApply] = useState(false); const [modalOpen, setModalOpen] = useState(false); - const [applyModal,setApplyModal] = useState(false); + const [applyModal, setApplyModal] = useState(false); const userStatus = myPostData.userStatus; const id = myPostData.postId; const applierCnt = myPostData.applierCnt; @@ -21,23 +21,22 @@ const ApplyBtn = ({ myPostData }) => { const { mutateAsync: apply } = usePostApply(); const { mutateAsync: deadlinePost } = usePostDeadline(); -//디바운싱 삭제 (서버 구매함) + //디바운싱 삭제 (서버 구매함) const applyBtn = async () => { - if (userStatus === "applicant") { - await apply(id); - setModalOpen(true); - queryClient.invalidateQueries("detailPost"); - } - if (userStatus === "MEMBER") { - await apply(id); - console.log('dhodkseho') - } - + if (userStatus === 'applicant') { + await apply(id); + setModalOpen(true); + queryClient.invalidateQueries('detailPost'); + } + if (userStatus === 'MEMBER') { + await apply(id); + console.log('dhodkseho'); + } }; const deadlineBtn = async () => { await deadlinePost(id); - queryClient.invalidateQueries("detailPost"); + queryClient.invalidateQueries('detailPost'); }; function viewApplyModal(id) { @@ -51,20 +50,19 @@ const ApplyBtn = ({ myPostData }) => { setModalOpen(false); }; - const openApplyModal = () =>{ + const openApplyModal = () => { setApplyModal(true); - applyBtn() - } + applyBtn(); + }; const closeApplyModal = () => { setApplyModal(false); -queryClient.invalidateQueries("detailPost"); - } - + queryClient.invalidateQueries('detailPost'); + }; return ( - {userStatus === "author" && ( + {userStatus === 'author' && ( <> { @@ -89,32 +87,34 @@ queryClient.invalidateQueries("detailPost");

{applierCnt}명이 지원했어요!

- )} + )} {deadline === false ? ( - userStatus === "MEMBER" ? ( + userStatus === 'MEMBER' ? ( - ) : userStatus === "applicant" ? ( + ) : userStatus === 'applicant' ? ( ) : ( - userStatus === "participant" && + userStatus === 'participant' && ) ) : ( - userStatus !== "author" && ( + userStatus !== 'author' && ( 모집 마감 ) )} - - - + + + {viewApply && ( @@ -133,10 +133,10 @@ const style = css` justify-content: center; position: absolute; - @media screen and (max-width:770px) { - font-size:0.938rem; - width:150px; - padding:14px 20px; + @media screen and (max-width: 770px) { + font-size: 0.938rem; + width: 150px; + padding: 14px 20px; } `; @@ -161,8 +161,8 @@ const Alert = styled.div` bottom: 20%; animation: ${alertAni} 0.2s linear; - @media screen and (max-width:770px){ - display:none; + @media screen and (max-width: 770px) { + display: none; } `; @@ -171,8 +171,8 @@ const Button = styled(Btn)` right: 0px; bottom: 0px; - @media screen and (max-width:770px){ - bottom :-70px; + @media screen and (max-width: 770px) { + bottom: -70px; //right:-30px; } `; @@ -181,10 +181,9 @@ const Button2 = styled(LineBtn)` right: 200px; bottom: 0px; - @media screen and (max-width:770px){ - bottom :-70px; - right:165px; - + @media screen and (max-width: 770px) { + bottom: -70px; + right: 165px; } `; @@ -209,7 +208,6 @@ export const Content = styled.div` } button { width: 100px; - } @media screen and (max-width: 500) { @@ -218,5 +216,4 @@ export const Content = styled.div` } `; - export default ApplyBtn; diff --git a/src/components/Comment.js b/src/components/Comment.js index 2528de8..2b07758 100644 --- a/src/components/Comment.js +++ b/src/components/Comment.js @@ -1,22 +1,22 @@ -import { useRef, useState } from "react"; -import { useQueryClient } from "react-query"; +import { useRef, useState } from 'react'; +import { useQueryClient } from 'react-query'; -import { useParams } from "react-router-dom"; -import { useRecoilValue } from "recoil"; -import { UserInfoAtom } from "../atom/atom"; +import { useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; +import { UserInfoAtom } from '../atom/atom'; -import styled from "styled-components"; -import person from "../styles/images/person.png"; +import styled from 'styled-components'; +import person from '../styles/images/person.png'; import { useEditComment, useRemoveComment, usePostReply, -} from "../hook/useCommentData"; -import DropDown from "./DropDown"; -import { Btn, GrayLineBtn } from "../styles/style"; -import AlertModal from "./AlertModal"; -import { Content } from "./ApplyBtn"; -import ModalOpen from "./Modal_prev"; +} from '../hook/useCommentData'; +import DropDown from './DropDown'; +import { Btn, GrayLineBtn } from '../styles/style'; +import AlertModal from './AlertModal'; +import { Content } from './ApplyBtn'; +import ModalOpen from './Modal_prev'; const Comment = ({ data }) => { //대댓글 드롭다운 열기/닫기 @@ -26,10 +26,10 @@ const Comment = ({ data }) => { const [isModalOpen, setIsModalOpen] = useState(false); const params = useParams(); const id = params.postId; - const replyId = data.commentId; + const commentId = data.commentId; - const comment_ref = useRef(""); - const replyRef = useRef(""); + const comment_ref = useRef(''); + const replyRef = useRef(''); const [isEdit, setIsEdit] = useState(false); const isLogin = useRecoilValue(UserInfoAtom); @@ -37,47 +37,47 @@ const Comment = ({ data }) => { const loginUser = isLogin?.nickname; const writeUser = data.nickname; ////console.log(writeUser, "글쓴이"); - console.log(data) + console.log(data); const queryClient = useQueryClient(); const { mutateAsync: editComment } = useEditComment(); const { mutateAsync: removeComment } = useRemoveComment(); const modifyCommentClick = async (commentId) => { - if(comment_ref.current.value === ""){ + if (comment_ref.current.value === '') { openModiModal(); return; } - const commentData = { id, commentId, content: comment_ref.current.value } + const commentData = { id, commentId, content: comment_ref.current.value }; setIsEdit(false); await editComment(commentData); - queryClient.invalidateQueries("commentList"); + queryClient.invalidateQueries('commentList'); }; - const deleteCommentClick = async (commentId) => { + const deleteCommentClick = async () => { const commentData = { commentId, id }; await removeComment(commentData); - queryClient.invalidateQueries("commentList"); + queryClient.invalidateQueries('commentList'); }; - // 대 댓글 작성 + // 대댓글 작성 const { mutateAsync: addReply } = usePostReply(); const onCheckEnter = (e) => { - if (e.key === "Enter") { + if (e.key === 'Enter') { addReplyClick(); } }; const addReplyClick = async () => { - if(isLogin && replyRef.current.value === ""){ + if (isLogin && replyRef.current.value === '') { openModiModal(); return; } - const replyData = { replyId, content: replyRef.current.value }; + const replyData = { commentId, content: replyRef.current.value }; await addReply(replyData); - replyRef.current.value = ""; - queryClient.invalidateQueries("commentList"); + replyRef.current.value = ''; + queryClient.invalidateQueries('commentList'); }; const openModal = () => { @@ -94,17 +94,16 @@ const Comment = ({ data }) => { setModiModalOpen(false); }; - const viewModal = () => { setIsModalOpen((prev) => !prev); }; - const userChk = () =>{ - const isLogin = localStorage.getItem("token"); - if(!isLogin){ + const userChk = () => { + const isLogin = localStorage.getItem('token'); + if (!isLogin) { viewModal(); } - } + }; return (
@@ -121,7 +120,7 @@ const Comment = ({ data }) => { {data.modifiedAt.substring(0, 10)} setDropdownVisibility(!dropdownVisibility)}> - {dropdownVisibility ? "닫기" : "답글 쓰기"} + {dropdownVisibility ? '닫기' : '답글 쓰기'} {loginUser === writeUser && ( @@ -174,30 +173,20 @@ const Comment = ({ data }) => {
- - -

댓글을 삭제하시겠습니까?

-
- 취소 - { - deleteCommentClick(data.commentId); - }} - > - 삭제 - -
-
-
- - - -

내용을 입력해주세요!

-
- 확인 -
-
-
+ + + + {isModalOpen && } ); @@ -220,10 +209,10 @@ const Img = styled.img` margin-right: 10px; `; -const ReplyBtn = styled(Btn)` -margin-left: auto; -margin-top: 10px; -margin-bottom: 20px; +const ReplyBtn = styled(Btn)` + margin-left: auto; + margin-top: 10px; + margin-bottom: 20px; `; const Contents = styled.div` @@ -249,14 +238,12 @@ const Date = styled.span` const CommentBtnBox = styled.div` display: flex; justify-content: flex-end; - `; export const CommentDate = styled.span` -color:${(props)=>props.theme.textColor_sub}; -font-size: 0.875rem; - -`; + color: ${(props) => props.theme.textColor_sub}; + font-size: 0.875rem; +`; export const ModiBtn = styled.button` background-color: ${(props) => props.theme.backgroundColor}; @@ -265,7 +252,7 @@ export const ModiBtn = styled.button` padding: 4px 12px; width: 69px; height: 32px; - font-size:0.75rem; + font-size: 0.75rem; font-weight: 400; margin-left: 10px; cursor: pointer; diff --git a/src/components/Comments.js b/src/components/Comments.js index e388798..63a9678 100644 --- a/src/components/Comments.js +++ b/src/components/Comments.js @@ -1,21 +1,21 @@ -import { useRef, useState } from "react"; -import { useQueryClient } from "react-query"; -import { useNavigate, useParams } from "react-router-dom"; -import { useRecoilValue } from "recoil"; -import styled, { css } from "styled-components"; -import { UserInfoAtom } from "../atom/atom"; -import { useGetCommentList, usePostComment } from "../hook/useCommentData"; -import { Btn } from "../styles/style"; -import AlertModal from "./AlertModal"; -import { Content } from "./ApplyBtn"; -import Comment from "./Comment"; -import ModalOpen from "./Modal_prev"; -import ReplyComment from "./ReplyComment"; +import { useRef, useState } from 'react'; +import { useQueryClient } from 'react-query'; +import { useNavigate, useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; +import styled, { css } from 'styled-components'; +import { UserInfoAtom } from '../atom/atom'; +import { useGetCommentList, usePostComment } from '../hook/useCommentData'; +import { Btn } from '../styles/style'; +import AlertModal from './AlertModal'; +import { Content } from './ApplyBtn'; +import Comment from './Comment'; +import ModalOpen from './Modal_prev'; +import ReplyComment from './ReplyComment'; const Comments = () => { const params = useParams(); const isLogin = useRecoilValue(UserInfoAtom); - const comment_ref = useRef(""); + const comment_ref = useRef(''); const [modalOpen, setModalOpen] = useState(false); const [btnState, setBtnState] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); @@ -28,20 +28,20 @@ const Comments = () => { const { mutateAsync: addComment } = usePostComment(); const onCheckEnter = (e) => { - if (e.key === "Enter") { + if (e.key === 'Enter') { addCommentClick(); } }; const addCommentClick = async () => { - if(isLogin && comment_ref.current.value === ""){ + if (isLogin && comment_ref.current.value === '') { openModal(); return; } const commentData = { id, content: comment_ref.current.value }; await addComment(commentData); - comment_ref.current.value = ""; - queryClient.invalidateQueries("commentList"); + comment_ref.current.value = ''; + queryClient.invalidateQueries('commentList'); }; const onChange = (e) => { @@ -53,22 +53,20 @@ const Comments = () => { } }; - - const viewModal = () => { setIsModalOpen((prev) => !prev); }; - const userChk = () =>{ - const isLogin = localStorage.getItem("token"); - if(!isLogin){ + const userChk = () => { + const isLogin = localStorage.getItem('token'); + if (!isLogin) { viewModal(); } - } + }; const openModal = () => { setModalOpen(true); - document.body.style.overflow = "hidden"; + document.body.style.overflow = 'hidden'; }; const closeModal = () => { setModalOpen(false); @@ -87,11 +85,13 @@ const Comments = () => { onChange={onChange} /> - @@ -108,27 +108,23 @@ const Comments = () => { commentId={data.commentId} /> ))} - + ))} - - -

내용을 입력해주세요!

-
- 확인 -
-
-
+ - {isModalOpen && } + {isModalOpen && }
); }; const CommentHr = styled.hr` -border: ${(props)=>props.theme.border}; - + border: ${(props) => props.theme.border}; `; const Wrap = styled.div` @@ -174,5 +170,4 @@ const Button = styled(Btn)` `} `; - export default Comments; diff --git a/src/components/Login.js b/src/components/Login.js index 7629872..ddf4fc0 100644 --- a/src/components/Login.js +++ b/src/components/Login.js @@ -1,35 +1,34 @@ -import React, { useState, useCallback } from "react"; -import styled from "styled-components"; -import kakaoBTN from "../styles/icon/login/kakaoLogin.svg"; -import Register from "./Register"; - -import { Btn } from "../styles/style"; -import { login } from "../shared/userOauth"; -import { useSetRecoilState } from "recoil"; -import { modalContentAtom } from "../atom/atom"; -import { userApis } from "../api/user"; -import Loading from "../shared/Loading"; -import AlertModal from "../components/AlertModal"; +import React, { useState, useCallback } from 'react'; +import styled from 'styled-components'; +import kakaoBTN from '../styles/icon/login/kakaoLogin.svg'; +import Register from './Register'; + +import { Btn } from '../styles/style'; +import { login } from '../shared/userOauth'; +import { useSetRecoilState } from 'recoil'; +import { modalContentAtom } from '../atom/atom'; +import { userApis } from '../api/user'; +import Loading from '../shared/Loading'; +import AlertModal from '../components/AlertModal'; const Login = () => { const setModalContent = useSetRecoilState(modalContentAtom); const [alertModalOpen, setAlertModalOpen] = useState(false); - const [errorMessage, setErrorMessage] = useState(""); + const [errorMessage, setErrorMessage] = useState(''); let debounce = null; //아이디, 비밀번호 - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); //오류메시지 상태저장 - const [emailMessage, setEmailMessage] = useState(""); - const [passwordMessage, setPasswordMessage] = useState(""); + const [emailMessage, setEmailMessage] = useState(''); + const [passwordMessage, setPasswordMessage] = useState(''); // 유효성 검사 const [isEmail, setIsEmail] = useState(false); const [isPassword, setIsPassword] = useState(false); - // 아이디 const onChangeId = useCallback((e) => { const emailRegex = @@ -38,10 +37,10 @@ const Login = () => { setEmail(emailCurrent); if (!emailRegex.test(emailCurrent)) { - setEmailMessage("이메일 형식을 다시 한번 확인해 주세요."); + setEmailMessage('이메일 형식을 다시 한번 확인해 주세요.'); setIsEmail(false); } else { - setEmailMessage("알맞게 작성되었습니다 :)"); + setEmailMessage('알맞게 작성되었습니다 :)'); setIsEmail(true); } }, []); @@ -53,10 +52,10 @@ const Login = () => { setPassword(passwordCurrent); if (!passwordRegex.test(passwordCurrent)) { - setPasswordMessage("3글자 이상, 10글자 미만으로 입력해주세요. "); + setPasswordMessage('3글자 이상, 10글자 미만으로 입력해주세요. '); setIsPassword(false); } else { - setPasswordMessage("알맞게 작성되었습니다 :)"); + setPasswordMessage('알맞게 작성되었습니다 :)'); setIsPassword(true); } }, []); @@ -68,42 +67,48 @@ const Login = () => { const KakaoURL = process.env.REACT_APP_SOCIAL_URL; + const closeModal = () => { + setAlertModalOpen(false); + }; -const login = (data) => { - if (debounce) { - clearTimeout(debounce); - } - debounce = setTimeout(async () => { - try{ - const response = await userApis.login(data) - console.log(response) - - if(response.status === 200){ - const accessToken = response.data.data.token.accessToken; - const refreshToken = response.data.data.token.refreshToken; - const id = response.data.data.userId; - if (accessToken !== null) { - localStorage.setItem("token", accessToken); - localStorage.setItem("retoken", refreshToken); - localStorage.setItem("id", id); - window.location.reload(); - } - - } - if(response.status === 400) { - console.log(alertModalOpen) - setAlertModalOpen(true); - setErrorMessage(response.data.errorMessage) + const login = (data) => { + if (debounce) { + clearTimeout(debounce); } - } catch (err){ - console.log(err) - } - }, 100); -}; + debounce = setTimeout(async () => { + try { + const response = await userApis.login(data); + console.log(response); + + if (response.status === 200) { + const accessToken = response.data.data.token.accessToken; + const refreshToken = response.data.data.token.refreshToken; + const id = response.data.data.userId; + if (accessToken !== null) { + localStorage.setItem('token', accessToken); + localStorage.setItem('retoken', refreshToken); + localStorage.setItem('id', id); + window.location.reload(); + } + } + if (response.status === 400) { + console.log(alertModalOpen); + setAlertModalOpen(true); + setErrorMessage(response.data.errorMessage); + } + } catch (err) { + console.log(err); + } + }, 100); + }; return ( - + LOGIN <span> 로그인</span> @@ -120,15 +125,15 @@ const login = (data) => { onChange={onChangeId} placeholder="이메일을 입력해주세요." /> - <p className={isEmail ? "success" : "error"}> + <p className={isEmail ? 'success' : 'error'}> {email.length > 0 && ( - <span className={`message ${isEmail ? "success" : "error"}`}> + <span className={`message ${isEmail ? 'success' : 'error'}`}> {emailMessage} </span> )} </p> </InputContent> - <InputContent > + <InputContent> 비밀번호 <LoginInput onChange={onChangePassword} @@ -139,7 +144,7 @@ const login = (data) => { /> <p> {password.length > 0 && ( - <span className={`message ${isPassword ? "success" : "error"}`}> + <span className={`message ${isPassword ? 'success' : 'error'}`}> {passwordMessage} </span> )} @@ -244,10 +249,10 @@ export const LoginBtn = styled(Btn)` font: inherit; color: ${(props) => props.theme.textColor_btn}; background-color: ${(props) => - props.disabled ? "#E1E1E1" : props.theme.keyColor}; + props.disabled ? '#E1E1E1' : props.theme.keyColor}; :hover { - background-color: ${(props) => (props.disabled ? "#E1E1E1" : "#FF891C")}; - cursor: ${(props) => (props.disabled ? "default" : "pointer")}; + background-color: ${(props) => (props.disabled ? '#E1E1E1' : '#FF891C')}; + cursor: ${(props) => (props.disabled ? 'default' : 'pointer')}; } `; diff --git a/src/components/MyPagePostList.js b/src/components/MyPagePostList.js index 655a361..263509a 100644 --- a/src/components/MyPagePostList.js +++ b/src/components/MyPagePostList.js @@ -1,100 +1,131 @@ -import { Btn, GrayLineBtn, LineBtn, ListProfilePic, ListStack, ListTitle, PostBody } from "../styles/style" -import { useRecoilValue } from "recoil"; -import { UserInfoAtom } from "../atom/atom"; -import { useMatch, useNavigate } from "react-router-dom"; -import styled from "styled-components"; -import DefaultProfile from "../styles/icon/global/profile.svg" -import { ReactComponent as CommentCnt } from "../styles/icon/post/commentCnt.svg"; -import { ReactComponent as BookmarkCnt } from "../styles/icon/post/bookmarkCnt.svg" -import UserBookmark from "./UserBookmark"; -import { usePostApply } from "../hook/useApplyMutation"; -import AlertModal from "./AlertModal"; -import { Content } from "./ApplyBtn"; -import { useState } from "react"; - -const MyPagePostList = ({ - data, - viewApplyModal, - currentTab -}) => { -//console.log(data) - const isMypage = useMatch("/mypage") - const [modalOpen, setModalOpen] = useState(false); - //console.log(currentTab) - const navigate = useNavigate() - const { mutate: postApply } = usePostApply() - - // const cancelApply = () => { - // if(confirm('지원을 취소하시겠어요?')) - // }; - - const openModal = () => { - setModalOpen(true); - }; - const closeModal = () => { +import { + Btn, + GrayLineBtn, + LineBtn, + ListProfilePic, + ListStack, + ListTitle, + PostBody, +} from '../styles/style'; +import { useRecoilValue } from 'recoil'; +import { UserInfoAtom } from '../atom/atom'; +import { useMatch, useNavigate } from 'react-router-dom'; +import styled from 'styled-components'; +import DefaultProfile from '../styles/icon/global/profile.svg'; +import { ReactComponent as CommentCnt } from '../styles/icon/post/commentCnt.svg'; +import { ReactComponent as BookmarkCnt } from '../styles/icon/post/bookmarkCnt.svg'; +import UserBookmark from './UserBookmark'; +import { usePostApply } from '../hook/useApplyMutation'; +import AlertModal from './AlertModal'; +import { Content } from './ApplyBtn'; +import { useState } from 'react'; +import { useQueryClient } from 'react-query'; + +const MyPagePostList = ({ data, viewApplyModal, currentTab }) => { + //console.log(data) + const [completeMessage, setCompleteMessage] = useState(''); + const [completeModal, setCompleteModal] = useState(false); + const queryClient = useQueryClient(); + const postId = data.postId; + const isMypage = useMatch('/mypage'); + const [modalOpen, setModalOpen] = useState(false); + //console.log(currentTab) + const navigate = useNavigate(); + const { mutateAsync: postApply } = usePostApply(); + + // const cancelApply = () => { + // if(confirm('지원을 취소하시겠어요?')) + // }; + + const applyBtn = async () => { + try { + const response = await postApply(postId); + console.log(response); + if (response.status === 200) { setModalOpen(false); - }; - - return ( - <> - <PostBody key={data.postId} > - <HeadBody> - {currentTab !== 4 ? - <> - <ListProfilePic src={data.profileImg === null ? - DefaultProfile - : data.profileImg} /> - {data.nickname} - </> - : null } - - {data.bookMarkStatus ? - <UserBookmark postId={data.postId} - bookmarkStatus={data.bookMarkStatus} - currentTab={currentTab} /> - : - <UserBookmark postId={data.postId} currentTab={currentTab} />} - </HeadBody> - - <ListTitle onClick={() => navigate(`/detail/${data.postId}`)}> - {data.title} - </ListTitle> - <ListContent> - {data.content} - <div> - {data.stacks.map((stack, index) => { - return ( - <ListStack key={index}>#{stack}</ListStack> - ) - })} - </div> - - </ListContent> - - - - <ListBottom> - 시작 예정일 {data.startAt} - <Count> - <CommentCnt /> {data.commentCnt} - <BookmarkCnt /> {data.bookmarkCnt} - </Count> - - </ListBottom> - {currentTab === 3 ? - <MyPageBtn onClick={openModal} >지원 취소하기</MyPageBtn> - : null} - - {isMypage !== null && currentTab === 2 || currentTab === 4 ? - <MyPageBtn - onClick={() => - viewApplyModal({ - postId: data.postId, - title: data.title, - deadline: data.deadline - })} >팀원 목록 보기</MyPageBtn> - : null} - {/* {currentTab === 4 ? + // setCompleteMessage(response.data.msg); + // setCompleteModal(true) + queryClient.invalidateQueries('applyproject'); + } + } catch (error) { + console.log(error); + } + }; + + const openModal = () => { + setModalOpen(true); + }; + const closeModal = () => { + setModalOpen(false); + }; + + const closeCompleteModal = () => { + setCompleteModal(false); + }; + + return ( + <> + <PostBody key={data.postId}> + <HeadBody> + {currentTab !== 4 ? ( + <> + <ListProfilePic + src={ + data.profileImg === null ? DefaultProfile : data.profileImg + } + /> + {data.nickname} + </> + ) : null} + + {data.bookMarkStatus ? ( + <UserBookmark + postId={data.postId} + bookmarkStatus={data.bookMarkStatus} + currentTab={currentTab} + /> + ) : ( + <UserBookmark postId={data.postId} currentTab={currentTab} /> + )} + </HeadBody> + + <ListTitle onClick={() => navigate(`/detail/${data.postId}`)}> + {data.title} + </ListTitle> + <ListContent> + {data.content} + <div> + {data.stacks.map((stack, index) => { + return <ListStack key={index}>#{stack}</ListStack>; + })} + </div> + </ListContent> + + <ListBottom> + 시작 예정일 {data.startAt} + <Count> + <CommentCnt /> {data.commentCnt} + <BookmarkCnt /> {data.bookmarkCnt} + </Count> + </ListBottom> + {currentTab === 3 ? ( + <MyPageBtn onClick={openModal}>지원 취소하기</MyPageBtn> + ) : null} + + {(isMypage !== null && currentTab === 2) || currentTab === 4 ? ( + <MyPageBtn + onClick={() => + viewApplyModal({ + postId: data.postId, + title: data.title, + deadline: data.deadline, + }) + } + > + 팀원 목록 보기 + </MyPageBtn> + ) : null} + {/* {currentTab === 4 ? <MyPageBtn onClick={() => viewApplyModal({ @@ -103,75 +134,70 @@ const MyPagePostList = ({ deadline: data.deadline })} >팀원 목록 보기</MyPageBtn> : null} */} - </PostBody> - - - <AlertModal open={modalOpen}> - <Content> - <h4>프로젝트 지원을 취소하시겠습니까?</h4> - <div> - <GrayLineBtn onClick={closeModal}> 닫기 </GrayLineBtn> - <Btn onClick={() => postApply(data.postId)}> 지원취소 </Btn> - </div> - </Content> - </AlertModal> - - - </> - - ) -} - + </PostBody> + + <AlertModal + open={modalOpen} + setAlertModalOpen={closeModal} + message={'프로젝트 지원을 취소하시겠습니까?'} + action={applyBtn} + actionMessage={'지원취소'} + /> + + <AlertModal + open={completeModal} + setAlertModalOpen={closeCompleteModal} + message={completeMessage} + /> + </> + ); +}; const HeadBody = styled.div` -gap:8px; -margin-bottom: 16px; -display: flex; -align-items: center; + gap: 8px; + margin-bottom: 16px; + display: flex; + align-items: center; `; const ListContent = styled.div` -line-height: 16px; -font-size: 0.875rem; -margin-top: 8px; -gap:8px; -display: flex; -flex-direction: column; + line-height: 16px; + font-size: 0.875rem; + margin-top: 8px; + gap: 8px; + display: flex; + flex-direction: column; `; const ListBottom = styled.div` -display: flex; -align-items: flex-end; -gap:5px; -font-size: 0.813rem; -margin-top: 18px; + display: flex; + align-items: flex-end; + gap: 5px; + font-size: 0.813rem; + margin-top: 18px; `; const Count = styled(ListBottom)` -margin-top: 0px; -margin-left: auto; + margin-top: 0px; + margin-left: auto; `; const MyPageBtn = styled(LineBtn)` -margin-top: 24px; -width: 100%; + margin-top: 24px; + width: 100%; `; - - - export default MyPagePostList; - - //✅ - // const cancelApply = async (postId) => { - // alert('지원을 취소하시겠습니까?') - // try { - // return await instance.post(`/api/apply/${postId}`) - // } catch (error) { - // alert(error) - // } - // } - - //✅ - // const { mutate } = useMutation(cancelApply) \ No newline at end of file +//✅ +// const cancelApply = async (postId) => { +// alert('지원을 취소하시겠습니까?') +// try { +// return await instance.post(`/api/apply/${postId}`) +// } catch (error) { +// alert(error) +// } +// } + +//✅ +// const { mutate } = useMutation(cancelApply) diff --git a/src/pages/Detail.js b/src/pages/Detail.js index c7a0a18..ac79f39 100644 --- a/src/pages/Detail.js +++ b/src/pages/Detail.js @@ -1,31 +1,34 @@ -import { useQueryClient } from "react-query"; -import { useNavigate, useParams } from "react-router-dom"; -import Comments from "../components/Comments"; -import { useDeletePost, useGetPost } from "../hook/usePostData"; -import styled from "styled-components"; -import { ReactComponent as BookmarkIcon } from "../styles/icon/post/bookmark.svg"; -import { ReactComponent as BookmarkFill } from "../styles/icon/post/bookmarkFill.svg"; -import { ReactComponent as Arrow } from "../styles/icon/detail/backArrow.svg"; -import person from "../styles/icon/global/profile.svg"; -import paw from "../styles/icon/detail/paw.svg"; -import {ReactComponent as Edit} from "../styles/icon/detail/edit.svg"; -import {ReactComponent as Remove} from "../styles/icon/detail/remove.svg"; -import { usePostBookmark } from "../hook/useUserData"; -import ApplyBtn, { Content } from "../components/ApplyBtn"; -import Loading from "../shared/Loading"; -import { useState } from "react"; -import AlertModal from "../components/AlertModal"; -import { Btn, GrayLineBtn } from "../styles/style"; - +import { useQueryClient } from 'react-query'; +import { useNavigate, useParams } from 'react-router-dom'; +import Comments from '../components/Comments'; +import { useDeletePost, useGetPost } from '../hook/usePostData'; +import styled from 'styled-components'; +import { ReactComponent as BookmarkIcon } from '../styles/icon/post/bookmark.svg'; +import { ReactComponent as BookmarkFill } from '../styles/icon/post/bookmarkFill.svg'; +import { ReactComponent as Arrow } from '../styles/icon/detail/backArrow.svg'; +import person from '../styles/icon/global/profile.svg'; +import paw from '../styles/icon/detail/paw.svg'; +import { ReactComponent as Edit } from '../styles/icon/detail/edit.svg'; +import { ReactComponent as Remove } from '../styles/icon/detail/remove.svg'; +import { usePostBookmark } from '../hook/useUserData'; +import ApplyBtn, { Content } from '../components/ApplyBtn'; +import Loading from '../shared/Loading'; +import { useState } from 'react'; +import AlertModal from '../components/AlertModal'; +import { Btn, GrayLineBtn } from '../styles/style'; const Detail = () => { const navigate = useNavigate(); const params = useParams(); const id = params.postId; - const isLogin = localStorage.getItem("token"); + const isLogin = localStorage.getItem('token'); const [modalOpen, setModalOpen] = useState(false); - - const { data: postList, isLoading: isLoadingPost , isFetching:isFetchingPost } = useGetPost(id); + + const { + data: postList, + isLoading: isLoadingPost, + isFetching: isFetchingPost, + } = useGetPost(id); const author = postList?.data.nickname; const userStatus = postList?.data.userStatus; @@ -37,26 +40,26 @@ const Detail = () => { const deletePostClick = async () => { await deletePost(id); - navigate("/"); + navigate('/'); }; const bookMark = async () => { await bookmark(id); - queryClient.invalidateQueries("detailPost"); + queryClient.invalidateQueries('detailPost'); }; const openModal = () => { setModalOpen(true); }; - + const closeModal = () => { setModalOpen(false); }; - if(isLoadingPost || isFetchingPost){ - return <Loading /> + if (isLoadingPost || isFetchingPost) { + return <Loading />; } - + return ( <> <Wrap> @@ -68,21 +71,20 @@ const Detail = () => { }} /> <div> - {isLogin && - userStatus !== "author" && - (postList?.data.bookMarkStatus ? ( - <BookmarkFill onClick={bookMark} /> - ) : ( - <BookmarkIcon onClick={bookMark} /> - )) - } + {isLogin && + userStatus !== 'author' && + (postList?.data.bookMarkStatus ? ( + <BookmarkFill onClick={bookMark} /> + ) : ( + <BookmarkIcon onClick={bookMark} /> + ))} </div> </LinkBtn> <User> <h3>{postList?.data.title}</h3> <div onClick={() => { - userStatus === "author" + userStatus === 'author' ? navigate(`/mypage`) : navigate(`/mypage/${author}`); }} @@ -93,7 +95,7 @@ const Detail = () => { </User> <Userbtn> - {(userStatus === "author" || userStatus === "master") && ( + {(userStatus === 'author' || userStatus === 'master') && ( <> <ModifyBtn onClick={() => @@ -104,7 +106,7 @@ const Detail = () => { <span>게시글 수정</span> </ModifyBtn> <DeleteBtn onClick={openModal}> - <Remove/> + <Remove /> <span>게시글 삭제</span> </DeleteBtn> </> @@ -156,15 +158,13 @@ const Detail = () => { </Article> <Comments /> - <AlertModal open={modalOpen}> - <Content> - <h4>게시글을 삭제하시겠습니까?</h4> - <div> - <GrayLineBtn onClick={closeModal}> 닫기 </GrayLineBtn> - <Btn onClick={deletePostClick}> 삭제 </Btn> - </div> - </Content> - </AlertModal> + <AlertModal + open={modalOpen} + message={'게시글을 삭제하시겠습니까?'} + setAlertModalOpen={closeModal} + action={deletePostClick} + actionMessage={'삭제'} + /> </Wrap> </> ); @@ -182,7 +182,7 @@ const Wrap = styled.div` font-size: 1rem; } hr { - border: ${(props)=>props.theme.border}; + border: ${(props) => props.theme.border}; } span { font-weight: 500; @@ -216,14 +216,13 @@ const User = styled.div` justify-content: center; line-height: 30px; - div { display: flex; flex-direction: column; align-items: center; - margin-top:15px; + margin-top: 15px; cursor: pointer; - + p { padding-top: 5px; } @@ -231,7 +230,6 @@ const User = styled.div` h3 { padding-bottom: 15px; - } img { @@ -242,12 +240,8 @@ const User = styled.div` @media screen and (max-width: 786px) { h3 { - padding:0 10px; - + padding: 0 10px; } - - - } `; const ArrowBtn = styled(Arrow)` @@ -271,24 +265,24 @@ const Userbtn = styled.div` } @media screen and (max-width: 786px) { - top:130px; + top: 130px; } `; const ModifyBtn = styled.button` background-color: ${(props) => props.theme.divBackGroundColor}; - padding:0 10px 0 5px; + padding: 0 10px 0 5px; height: 32px; border: ${(props) => props.theme.modifyBtnBorder}; border-radius: 8px; display: flex; align-items: center; cursor: pointer; - stroke: ${props => props.theme.headerTextColor}; + stroke: ${(props) => props.theme.headerTextColor}; span { color: ${(props) => props.theme.headerTextColor}; - padding-left:5px; + padding-left: 5px; } @media screen and (max-width: 770px) { @@ -304,22 +298,21 @@ const ModifyBtn = styled.button` `; export const DeleteBtn = styled(ModifyBtn)` - border: ${props => props.theme.alertBorder}; + border: ${(props) => props.theme.alertBorder}; margin-left: 10px; - stroke: ${props => props.theme.removeBtnColor}; + stroke: ${(props) => props.theme.removeBtnColor}; span { - color: ${props => props.theme.removeBtnColor}; - + color: ${(props) => props.theme.removeBtnColor}; } `; const LinkBtn = styled.div` display: flex; - svg{ + svg { cursor: pointer; } - + justify-content: space-between; //padding-bottom: 10px; @media screen and(max-width:768) { @@ -343,23 +336,18 @@ const ContentWrap = styled.div` const Title = styled.div` display: flex; - + p:first-child { width: 120px; } - - `; const Stack = styled.div` display: flex; - flex-wrap:wrap; - row-gap:10px; + flex-wrap: wrap; + row-gap: 10px; max-width: 750px; align-items: center; - - - span { background-color: ${(props) => props.theme.stackBackground}; @@ -372,8 +360,8 @@ const Stack = styled.div` color: ${(props) => props.theme.stackColor}; } @media screen and (max-width: 770px) { - row-gap:0px; - flex-wrap:nowrap; + row-gap: 0px; + flex-wrap: nowrap; max-width: 220px; overflow-x: auto; white-space: nowrap; diff --git a/src/pages/Mypage.js b/src/pages/Mypage.js index f2fd4ca..9835e33 100644 --- a/src/pages/Mypage.js +++ b/src/pages/Mypage.js @@ -1,24 +1,36 @@ -import React, { useEffect, useRef, useState } from "react"; -import Bookmark from "../components/Bookmark"; -import MyProject from "../components/MyProject"; -import JoinProject from "../components/JoinProject"; -import { useNavigate } from "react-router-dom"; -import { Btn,GrayLineBtn,LineBtn,MyStack,Option,PostBody,SelectBoxOpen,TabBody} from "../styles/style"; -import styled from "styled-components"; -import { ReactComponent as Arrow } from "../styles/icon/detail/backArrow.svg"; -import {useMyProfileReset,useMyProfileEdit } from "../hook/useProfileMutation"; -import { useRecoilValue } from "recoil"; -import { UserInfoAtom } from "../atom/atom"; -import profilepic from "../styles/icon/global/profile.svg"; -import ApplyProject from "../components/ApplyProject"; -import pen from "../styles/icon/myPage/pen.svg"; -import StackSelector from "../components/StackSeletor"; -import { withDraw } from "../shared/userOauth"; -import { SelectArrow } from "../components/WriteSelect"; -import AlertModal from "../components/AlertModal"; -import { Content } from "../components/ApplyBtn"; -import { useQueryClient } from "react-query"; -import { InputContent } from "../components/Login"; +import React, { useEffect, useRef, useState } from 'react'; +import Bookmark from '../components/Bookmark'; +import MyProject from '../components/MyProject'; +import JoinProject from '../components/JoinProject'; +import { useNavigate } from 'react-router-dom'; +import { + Btn, + GrayLineBtn, + LineBtn, + MyStack, + Option, + PostBody, + SelectBoxOpen, + TabBody, +} from '../styles/style'; +import styled from 'styled-components'; +import { ReactComponent as Arrow } from '../styles/icon/detail/backArrow.svg'; +import { + useMyProfileReset, + useMyProfileEdit, +} from '../hook/useProfileMutation'; +import { useRecoilValue } from 'recoil'; +import { UserInfoAtom } from '../atom/atom'; +import profilepic from '../styles/icon/global/profile.svg'; +import ApplyProject from '../components/ApplyProject'; +import pen from '../styles/icon/myPage/pen.svg'; +import StackSelector from '../components/StackSeletor'; +import { withDraw } from '../shared/userOauth'; +import { SelectArrow } from '../components/WriteSelect'; +import AlertModal from '../components/AlertModal'; +import { Content } from '../components/ApplyBtn'; +import { useQueryClient } from 'react-query'; +import { InputContent } from '../components/Login'; const MyPage = () => { const userInfo = useRecoilValue(UserInfoAtom); @@ -41,38 +53,35 @@ const MyPage = () => { const queryClient = useQueryClient(); const navigate = useNavigate(); - + const detailsRef = useRef(null); const details = detailsRef.current; -const [nickCheck, setNickCheck] = useState(true); -const [nickMessage, setNickMessage] = useState(""); + const [nickCheck, setNickCheck] = useState(true); + const [nickMessage, setNickMessage] = useState(''); const imageRef = useRef(); const [exitModalOpen, setExitModalOpen] = useState(false); const formData = new FormData(); - const token = localStorage.getItem("token"); - const userId = localStorage.getItem("id"); + const token = localStorage.getItem('token'); + const userId = localStorage.getItem('id'); const tabList = [ - { id: 1, name: "관심 프로젝트", content: <Bookmark currentTab={1} /> }, - { id: 2, name: "참여한 프로젝트", content: <JoinProject currentTab={2} /> }, + { id: 1, name: '관심 프로젝트', content: <Bookmark currentTab={1} /> }, + { id: 2, name: '참여한 프로젝트', content: <JoinProject currentTab={2} /> }, { id: 3, - name: "신청한 프로젝트", + name: '신청한 프로젝트', content: <ApplyProject currentTab={3} />, }, - { id: 4, name: "내가 쓴 프로젝트", content: <MyProject currentTab={4} /> }, + { id: 4, name: '내가 쓴 프로젝트', content: <MyProject currentTab={4} /> }, ]; useEffect(() => { console.log(userInfo); console.log(myData); - - - if (userInfo === undefined && !token) { setModalOpen(true); } else { @@ -87,42 +96,42 @@ const [nickMessage, setNickMessage] = useState(""); height: window.innerHeight, }); } - window.addEventListener("resize", handleResize); + window.addEventListener('resize', handleResize); handleResize(); if (windowSize.width < 600) { setIsMobile(true); } else if (windowSize.width >= 600) { setIsMobile(false); } - return () => window.removeEventListener("resize", handleResize); + return () => window.removeEventListener('resize', handleResize); }, [windowSize.width, userInfo]); const EditMyData = async () => { const image = myData.profileImg; if (image === null) { - } else if (typeof image === "string") { + } else if (typeof image === 'string') { } else if (image !== null) { - formData.append("image", image); + formData.append('image', image); } const data = { stacks: myData.stacks, nickname: myData.nickname, }; const formdata = JSON.stringify(data); - const blob = new Blob([formdata], { type: "application/json" }); + const blob = new Blob([formdata], { type: 'application/json' }); - formData.append("body", blob); + formData.append('body', blob); try { const response = await profileEdit(formData); setIsEdit(false); - queryClient.invalidateQueries("userinfo"); + queryClient.invalidateQueries('userinfo'); setNickCheck(true); } catch (error) { if (error.response.status === 400) { console.log(error.response.status); setNickCheck(false); - setNickMessage("중복된 닉네임입니다"); + setNickMessage('중복된 닉네임입니다'); console.log(nickCheck); } } @@ -132,13 +141,11 @@ const [nickMessage, setNickMessage] = useState(""); const { mutateAsync: imageReSet } = useMyProfileReset(); const imageResetBtn = () => { - imageReSet() - setImagePreview(null) - setMyData((prev)=>({...prev,profileImg:null})); - queryClient.invalidateQueries("userInfo"); - - - } + imageReSet(); + setImagePreview(null); + setMyData((prev) => ({ ...prev, profileImg: null })); + queryClient.invalidateQueries('userInfo'); + }; const encodeFileToBase64 = (img) => { //console.log(img); @@ -165,10 +172,10 @@ const [nickMessage, setNickMessage] = useState(""); setMyData((prev) => ({ ...prev, nickname: newNickname })); if (newNickname.length < 3 || newNickname.length > 8) { setNickCheck(false); - setNickMessage("3글자 이상, 8글자 아래로 정해주세요."); + setNickMessage('3글자 이상, 8글자 아래로 정해주세요.'); } else { setNickCheck(true); - setNickMessage("알맞게 작성 되었습니다."); + setNickMessage('알맞게 작성 되었습니다.'); } }; @@ -180,27 +187,29 @@ const [nickMessage, setNickMessage] = useState(""); setExitModalOpen(false); }; - const needLoginUser = () =>{ - navigate("/", { state: "needLogin" }) - } + const needLoginUser = () => { + navigate('/', { state: 'needLogin' }); + }; if (userInfo === undefined && !token) { return ( - <AlertModal open={modalOpen} - setAlertModalOpen={needLoginUser} - message={"⚠️ 로그인이 필요한 서비스입니다"} + <AlertModal + open={modalOpen} + setAlertModalOpen={needLoginUser} + message={'⚠️ 로그인이 필요한 서비스입니다'} /> ); } return ( <WholeBody> - <AlertModal - open={exitModalOpen} - setAlertModalOpen={setExitModalOpen} - message={"개발바닥에서 탈퇴하시겠습니까?"} - action={withDraw} - actionMessage={"회원탈퇴하기"}/> + <AlertModal + open={exitModalOpen} + setAlertModalOpen={exitBtnClose} + message={'개발바닥에서 탈퇴하시겠습니까?'} + action={withDraw} + actionMessage={'회원탈퇴하기'} + /> {isMobile ? ( <Leftarrow @@ -213,38 +222,35 @@ const [nickMessage, setNickMessage] = useState(""); <PostBody> {isEdit ? ( <> - <ProfileWrap> - <ProfilePicWrap> - {imagePreview === null ? ( - <Profilepic> - {" "} - <img src={profilepic} alt="profileImage" />{" "} - </Profilepic> - ) : ( - <Profilepic> - {" "} - <img src={imagePreview} alt="profileImage" />{" "} - </Profilepic> - )} - - - <File> - <label htmlFor="profile"> - <div> - <img src={pen} alt="" /> - </div> - </label> - <input - id="profile" - type="file" - ref={imageRef} - accept="image/*" - onChange={(event) => editImg(event)} - /> - </File> - + <ProfileWrap> + <ProfilePicWrap> + {imagePreview === null ? ( + <Profilepic> + {' '} + <img src={profilepic} alt="profileImage" />{' '} + </Profilepic> + ) : ( + <Profilepic> + {' '} + <img src={imagePreview} alt="profileImage" />{' '} + </Profilepic> + )} + + <File> + <label htmlFor="profile"> + <div> + <img src={pen} alt="" /> + </div> + </label> + <input + id="profile" + type="file" + ref={imageRef} + accept="image/*" + onChange={(event) => editImg(event)} + /> + </File> </ProfilePicWrap> - <Profile> <input @@ -252,7 +258,7 @@ const [nickMessage, setNickMessage] = useState(""); onChange={(event) => editNickname(event)} /> {myData?.nickname.length > 0 ? ( - <AlertMessage className={nickCheck ? "success" : "error"}> + <AlertMessage className={nickCheck ? 'success' : 'error'}> {nickMessage} </AlertMessage> ) : null} @@ -261,27 +267,26 @@ const [nickMessage, setNickMessage] = useState(""); <StackSelector data={myData} setSelectedData={setMyData} /> </InputContent> </Profile> - - - </ProfileWrap> - <BtnWrap> - - <Button onClick={imageResetBtn}>기본 이미지로 변경</Button> - <Button type="submit" onClick={EditMyData} disabled={!(nickCheck)} >편집 완료</Button> - <Button3 onClick={exitBtnOpen}>회원 탈퇴</Button3> - </BtnWrap> - </> + </ProfileWrap> + <BtnWrap> + <Button onClick={imageResetBtn}>기본 이미지로 변경</Button> + <Button type="submit" onClick={EditMyData} disabled={!nickCheck}> + 편집 완료 + </Button> + <Button3 onClick={exitBtnOpen}>회원 탈퇴</Button3> + </BtnWrap> + </> ) : ( <ProfileWrap> {userInfo?.profileImg === null ? ( <Profilepic> - {" "} - <img src={profilepic} alt="profileImage" />{" "} + {' '} + <img src={profilepic} alt="profileImage" />{' '} </Profilepic> ) : ( <Profilepic> - {" "} - <img src={myData?.profileImg} alt="profileImage" />{" "} + {' '} + <img src={myData?.profileImg} alt="profileImage" />{' '} </Profilepic> )} <Profile> @@ -290,7 +295,7 @@ const [nickMessage, setNickMessage] = useState(""); <Stacks> {userInfo?.stacks?.map((mystack, index) => { return ( - <MyStack key={index} style={{ marginTop: "10px" }}> + <MyStack key={index} style={{ marginTop: '10px' }}> #{mystack} </MyStack> ); @@ -321,14 +326,14 @@ const [nickMessage, setNickMessage] = useState(""); } }} key={tab.id} - className={currentTab === tab.id ? "focused" : null} + className={currentTab === tab.id ? 'focused' : null} > {tab.name} </MyOption> ); })} </MySelectBoxOpen> - </details>{" "} + </details>{' '} <MyPageHr /> </> ) : ( @@ -341,7 +346,7 @@ const [nickMessage, setNickMessage] = useState(""); setTab(tab.id); }} key={tab.id} - className={currentTab === tab.id ? "focused" : null} + className={currentTab === tab.id ? 'focused' : null} > {tab.name} </Tab> @@ -422,7 +427,7 @@ const BtnWrap = styled.div` flex-direction: column; text-align: right; gap: 10px; -margin-top: 10px; + margin-top: 10px; span { color: ${(props) => props.theme.errorColor}; font-size: 0.875rem; @@ -472,12 +477,11 @@ export const Profilepic = styled.div` } `; const File = styled.div` - div { position: absolute; bottom: 0px; left: 120px; - box-shadow: ${(props)=>props.theme.boxShadow}; + box-shadow: ${(props) => props.theme.boxShadow}; display: flex; align-items: center; justify-content: center; @@ -488,16 +492,16 @@ const File = styled.div` @media screen and (max-width: 650px) { bottom: -10px; - left: 45px; - width: 35px; - height: 35px; + left: 45px; + width: 35px; + height: 35px; } } label { cursor: pointer; } - input[type="file"] { + input[type='file'] { display: none; } `; @@ -542,9 +546,9 @@ const ModalBtn = styled(Btn)` bottom: 10px; `; const ProfilePicWrap = styled.div` -display: flex; + display: flex; -position: relative; + position: relative; `; export const Profile = styled.div` @@ -614,7 +618,7 @@ const Button2 = styled(Btn)` `; const Button3 = styled.div` -margin-top: 20px; + margin-top: 20px; color: ${(props) => props.theme.errorColor}; font-size: 0.875rem; cursor: pointer;