modal 창 하나로 수정 버튼에 따라 그에 맞는 내용이 modal 창에 뜨게끔 구현을 해보았다.
MyPage.jsx - 수정 버튼
import EditModal from '../../components/MyPage/EditModal/EditModal';
import { Fragment, useEffect } from 'react';
import {
MyPageContainer,
MyInfoContainer,
MyPageTagTitle,
MyInfoInput,
MyInfoEditButton,
NickNameContainer,
GithubContainer,
MyPageTabsContainer,
InputCheckContainer,
} from './style.js';
const MyPage = () => {
const [github, setGithub] = useState('https://github.com/');
const [userName, setUserName] = useState('눈누난나');
// True: 닉네임 수정, False: Github 수정
const [contentInfo, setContentInfo] = useState('');
// 모달창 노출 여부 state
const [modalOpen, setModalOpen] = useState(false);
// 닉네임 수정 모달 창 열림
const openUserNameModal = () => {
setModalOpen(true);
setContentInfo(true);
};
// 깃허브 수정 모달 창 열림
const openGithubModal = () => {
setModalOpen(true);
setContentInfo(false);
};
// 닉네임 입력
const InputUserName = (e) => {
setUserName(e.target.value);
};
// 깃허브 링크 입력
const InputGithub = (e) => {
setGithub(e.target.value);
};
return (
<Fragment>
<MyPageContainer>
{/* 닉네임, 깃허브 링크 수정 */}
<MyInfoContainer>
<NickNameContainer>
<MyPageTagTitle>닉네임</MyPageTagTitle>
<InputCheckContainer>
<MyInfoInput>{userName}</MyInfoInput>
<MyInfoEditButton onClick={openUserNameModal}>
수정
</MyInfoEditButton>
{modalOpen && (
<EditModal
setModalOpen={setModalOpen}
setContentInfo={contentInfo}
setUserName={userName}
/>
)}
</InputCheckContainer>
</NickNameContainer>
<GithubContainer>
<MyPageTagTitle>GitHub</MyPageTagTitle>
<InputCheckContainer>
<MyInfoInput>{github}</MyInfoInput>
<MyInfoEditButton onClick={openGithubModal}>
수정
</MyInfoEditButton>
{modalOpen && (
<EditModal
setModalOpen={setModalOpen}
setContentInfo={contentInfo}
setUserName={userName}
setGithub={github}
/>
)}
</InputCheckContainer>
</GithubContainer>
</MyInfoContainer>
</MyPageContainer>
</Fragment>
);
};
export default MyPage;
style.js
import styled from 'styled-components';
import { Tabs, TabList, Tab, TabPanel } from 'react-tabs';
export const MyPageContainer = styled.div`
display: flex;
margin: 0 auto;
max-width: 90%;
@media screen and (max-width: 800px) {
flex-direction: column;
margin: 0 auto;
}
`;
export const MyInfoContainer = styled.div`
padding-top: 65px;
flex: 30%;
margin: 0 auto;
@media screen and (max-width: 800px) {
display: flex;
flex-direction: column;
justify-content: center;
}
`;
export const NickNameContainer = styled.div`
margin-bottom: 40px;
@media screen and (max-width: 800px) {
width: 430px;
}
`;
export const InputCheckContainer = styled.div`
display: flex;
justify-content: space-between;
`;
export const GithubContainer = styled.div``;
export const MyPageTagTitle = styled.div`
font-weight: 600;
`;
export const MyInfoInput = styled.p`
border: none;
border-bottom: 0.6px solid #c6c6c6;
min-width: 200px;
width: 70%;
margin: 20px 10px 20px 0;
outline: none;
flex: 80%;
`;
export const MyInfoEditButton = styled.button`
border: 1px solid #205295;
border-radius: 7px;
color: #205295;
background-color: #fff;
font-weight: 600;
padding: 5px 10px;
margin-right: 20px;
height: 35px;
width: 50px;
cursor: pointer;
flex: 20%;
&:hover {
background: #205295;
color: #fff;
}
@media screen and (max-width: 800px) {
margin-right: 0px;
}
`;
닉네임 수정 버튼을 누를 시 아래와 같은 모달 창이 뜬다.
깃허브 수정 버튼을 누를 시 아래와 같은 모달 창이 뜬다.
Modal.jsx - 모달 창
import React, { useState } from 'react';
import {
ModalBackground,
ModalContainer,
ModalTopItems,
ModalClose,
MyInfoInput,
ButtonContainer,
CancelButton,
SaveButton,
} from './style.js';
const EditModal = ({
setModalOpen,
setContentInfo,
setUserName,
setGithub,
}) => {
const [currentInput, setCurrentInput] = useState();
// X버튼 onClick 이벤트 핸들러
const closeModal = () => {
setModalOpen(false);
};
// 닉네임 입력
const getInput = (e) => {
setCurrentInput(e.target.value);
};
// 수정 취소
const cancelEdit = () => {
setModalOpen(false);
};
// 수정 저장
const saveEdit = () => {
setModalOpen(false);
};
return (
<ModalBackground>
<ModalContainer>
<ModalTopItems>
{setContentInfo ? <h3>닉네임 변경</h3> : <h3>Github Link 변경</h3>}
<ModalClose onClick={() => closeModal()}>X</ModalClose>
</ModalTopItems>
<MyInfoInput
onChange={getInput}
value={currentInput}
maxLength={10}
placeholder={setContentInfo ? setUserName : setGithub}
/>
<ButtonContainer>
<CancelButton onClick={() => cancelEdit()}>취소</CancelButton>
<SaveButton onClick={() => saveEdit()}>저장</SaveButton>
</ButtonContainer>
</ModalContainer>
</ModalBackground>
);
};
export default EditModal;
style.js
import styled from 'styled-components';
export const ModalBackground = styled.div`
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(67, 79, 101, 0.8);
`;
export const ModalContainer = styled.div`
/* 모달창 크기 */
width: 420px;
height: 220px;
/* 최상단 위치 */
z-index: 999;
/* 모달 배치 */
/* translate는 본인의 크기 기준으로 작동한다. */
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
/* 모달창 디자인 */
background-color: #fff;
border-radius: 7px;
padding: 15px 35px 10px 35px;
box-sizing: border-box;
`;
export const ModalTopItems = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
`;
export const ModalClose = styled.button`
height: 20px;
border: none;
background-color: transparent;
font-weight: 600;
cursor: pointer;
color: #d7d7d7;
font-size: 16px;
:hover {
color: #000;
}
`;
export const MyInfoInput = styled.input`
border: none;
border-bottom: 0.6px solid #c6c6c6;
min-width: 200px;
width: 100%;
margin: 20px 10px 20px 0;
outline: none;
flex: 80%;
`;
export const ButtonContainer = styled.div`
padding-top: 20px;
display: flex;
gap: 10px;
justify-content: right;
`;
export const CancelButton = styled.button`
background-color: rgba(233, 236, 242, 0.8);
border: none;
box-sizing: border-box;
padding: 8px 15px;
border-radius: 7px;
font-weight: 600;
cursor: pointer;
:hover {
background-color: rgba(188, 188, 188, 0.4);
}
`;
export const SaveButton = styled(CancelButton)`
background-color: rgba(36, 55, 99, 0.8);
color: #fff;
:hover {
background-color: rgba(36, 55, 99);
}
`;
'개발 일지 > TIL' 카테고리의 다른 글
[ TypeScript ] (0) | 2023.01.27 |
---|---|
[ React ] 웹 링크 유효성 검사, React Query Firebase (0) | 2023.01.27 |
[ TypeScript ] TypeScript 설치 및 파일 생성 (0) | 2023.01.21 |
[ React Query ] 게시물에 따른 comments 업데이트 (0) | 2023.01.21 |
[ React Query ] useQuery, isError, isLoading (0) | 2023.01.19 |
댓글