Building the ProfileEditPage UI
Today I built the UI for ProfileEditPage, the page where users edit their account information.
Nothing was especially hard, but I wasn't sure how to implement password recovery, and I decided to open a popup when the find-password button is pressed.
In the change-password popup, I think pressing the find-password button should send a reset password by email.
Until now I had typed values in directly instead of using data. For an image, for example, I wrote the image URL straight into src. Now that the markup stage is wrapping up, I need to get ready to actually fetch data through API calls, so I created a Mock folder, wrote user information into a users.ts file, and changed the code to read it from there.
I also installed and tried spellChecker, which my mentor recommended for collaboration.



- Starting tomorrow I'll check the details of every page, and from Wednesday I'll start on the responsive layout!
import React, {useState} from 'react'
import MyPageBanner from '../Common/MyPageBanner'
import styled from 'styled-components'
import ChangePassword from '../Popups/ChangePassword'
import {users} from '../Mock/users'
export default function ProfileEditPage() {
const {email, password, nickName, myPage} = users[0]
const [changePassword, setChangePassword] = useState<boolean>(false)
const [profilePreview, setProfilePreview] = useState<string>(myPage.profile)
const [profileBackgroundPreview, setProfileBackgroundPreview] = useState<string>(myPage.background)
const handlePasswordChange = (e: React.MouseEvent) => {
e.preventDefault()
setChangePassword(true)
}
const handleProfileImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0]
if (file) {
const reader = new FileReader()
reader.onload = () => {
setProfilePreview(reader.result as string)
}
reader.readAsDataURL(file)
}
}
const handleProfileBackgroundImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0]
if (file) {
const reader = new FileReader()
reader.onload = () => {
setProfileBackgroundPreview(reader.result as string)
}
reader.readAsDataURL(file)
}
}
const handleEditForm = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
console.log(e)
}
return (
<>
<MyPageBanner />
<EditForm onSubmit={handleEditForm} onKeyUp={e => e.key === 'Enter' && e.preventDefault()}>
<PageTitle>회원정보 수정</PageTitle>
<Content>
<Title># 이메일</Title>
<Input value={email} type='email' readOnly />
</Content>
<Content>
<Title># 비밀번호</Title>
<Input type='password' required />
<PassWordChange
onClick={e => {
handlePasswordChange(e)
}}
>
*비밀번호 변경
</PassWordChange>
</Content>
<Content>
<Title># 닉네임</Title>
<Input value={nickName} type='text' readOnly />
</Content>
<Content>
<Title># 나를 소개하는 한 줄</Title>
<Input type='text' maxLength={40} placeholder={myPage.ment} />
</Content>
<Content>
<Title># 프로필 이미지</Title>
<ProfileImgBox>
<ProfileImg src={profilePreview} alt='ProfileImg' />
<ImgLabel htmlFor='profileImg'>이미지 선택</ImgLabel>
<InputImg id='profileImg' type='file' accept='.jpg, .jpeg, .png' onChange={handleProfileImageChange} />
</ProfileImgBox>
</Content>
<Content>
<Title># 배경 이미지</Title>
<ProfileImgBox>
<ProfileBackgroundImg src={profileBackgroundPreview} alt='ProfileBackgroundImg' />
<ImgLabel htmlFor='profileBackgroundImg'>배경이미지 선택</ImgLabel>
<InputImg
id='profileBackgroundImg'
type='file'
accept='.jpg, .jpeg, .png'
onChange={handleProfileBackgroundImageChange}
/>
</ProfileImgBox>
</Content>
<SubmitInput type='submit' value={'작성 완료'} />
</EditForm>
<ChangePassword show={changePassword} setChangePassword={setChangePassword} />
</>
)
}
const PageTitle = styled.h1`
font-size: 2rem;
margin-top: 4rem;
text-align: center;
`
const EditForm = styled.form`
width: 92%;
display: flex;
flex-direction: column;
margin: 4rem auto;
background: rgb(247, 247, 247);
border-radius: 1rem;
padding: 0px 2rem 2rem;
box-sizing: border-box;
`
const Content = styled.div`
display: flex;
align-items: center;
margin-top: 3rem;
`
const Title = styled.h2`
font-size: 1.5rem;
margin-right: 2rem;
width: 15rem;
text-align: center;
`
const Input = styled.input`
font-size: 1.3rem;
width: 27rem;
border: none;
padding: 0.8rem 0.8rem 0.8rem 1.3rem;
border-radius: 1.5rem;
&:focus {
outline: none;
}
`
const PassWordChange = styled.button`
margin-left: 1rem;
font-size: 1rem;
border: none;
cursor: pointer;
background: inherit;
cursor: pointer;
&:hover {
color: #1877f2;
}
`
const ProfileImgBox = styled.div`
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
border-radius: 1rem;
`
const ProfileImg = styled.img`
width: 12rem;
height: 12rem;
border-radius: 50%;
padding: 0.5rem;
`
const ProfileBackgroundImg = styled.img`
width: 100%;
height: 25rem;
border-radius: 1rem;
padding: 0.3rem;
`
const InputImg = styled.input`
display: none;
`
const ImgLabel = styled.label`
cursor: pointer;
font-size: 1.2rem;
height: 2rem;
display: flex;
width: 100%;
justify-content: center;
align-items: center;
border-dasharray: 100px;
&:hover {
color: #1877f2;
background: #fff;
border-color: #1877fe;
}
`
const SubmitInput = styled.input`
margin-top: 5rem;
margin-left: auto;
padding: 0.7rem 1.5rem;
font-size: 1.2rem;
cursor: pointer;
color: #fff;
background: #1877f2;
border: none;
border-radius: 0.5rem;
`- #ProfileEditPage UI