Skip to content

Commit 5a38d54

Browse files
authored
Merge pull request #13 from moonhuicheol/feature/mypage
✨ feat: 마이페이지/비밀번호 및 정보수정 페이지 구현
2 parents cb9d1ec + b297a2e commit 5a38d54

File tree

12 files changed

+309
-3
lines changed

12 files changed

+309
-3
lines changed

src/components/ui/input/Input.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@ import * as S from "./inputStyle";
44
export default function Input<I extends FieldValues>({
55
type,
66
keyname,
7-
...props
7+
disable,
8+
defaultValue,
89
}: IInputProps<I>) {
910
const { register } = useFormContext<I>();
1011

11-
return <S.input type={type} {...register(keyname)} {...props}></S.input>;
12+
return (
13+
<S.input
14+
type={type}
15+
{...register(keyname)}
16+
disabled={disable}
17+
defaultValue={defaultValue}
18+
></S.input>
19+
);
1220
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
interface IInputProps<P> {
22
type: HTMLInputTypeAttribute;
33
keyname: Path<P>;
4+
defaultValue?: string;
5+
disable?: boolean;
46
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { FormProvider, useForm } from "react-hook-form";
2+
import Input from "../../../components/ui/input/Input";
3+
import * as S from "./checkPasswordStyle";
4+
import Button from "../../../components/ui/button/Button";
5+
import { ICheckPassword } from "./schema";
6+
import { useNavigate } from "react-router-dom";
7+
8+
export default function CheckPassword() {
9+
const methods = useForm<ICheckPassword>();
10+
const navigate = useNavigate();
11+
const onClickSubmit = async (data: ICheckPassword) => {
12+
console.log(data);
13+
navigate("/user/mypage/updateMyPage");
14+
};
15+
16+
return (
17+
<FormProvider {...methods}>
18+
<S.container>
19+
<S.checkPasswordBox onSubmit={methods.handleSubmit(onClickSubmit)}>
20+
<S.p>본인 인증을 위해 비밀번호 확인이 필요합니다.</S.p>
21+
<S.p>비밀번호를 입력해 주세요.</S.p>
22+
<S.label>비밀번호</S.label>
23+
<Input<ICheckPassword> type="text" keyname="password" />
24+
<S.buttonBox>
25+
<Button type="button" size="sm" bgcolor="black" textcolor="white">
26+
이전
27+
</Button>
28+
<Button type="submit" size="sm" bgcolor="green" textcolor="black">
29+
다음
30+
</Button>
31+
</S.buttonBox>
32+
</S.checkPasswordBox>
33+
</S.container>
34+
</FormProvider>
35+
);
36+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import styled from "styled-components";
2+
3+
export const container = styled.div`
4+
display: flex;
5+
flex-direction: column;
6+
align-items: center;
7+
justify-content: center;
8+
width: 100%;
9+
height: 100%;
10+
`;
11+
12+
export const checkPasswordBox = styled.form`
13+
display: flex;
14+
flex-direction: column;
15+
justify-content: center;
16+
width: 400px;
17+
`;
18+
19+
export const p = styled.p`
20+
font-weight: 500;
21+
font-size: 20px;
22+
line-height: 26px;
23+
letter-spacing: -0.02em;
24+
color: var(--color-gray-999);
25+
`;
26+
27+
export const label = styled.label`
28+
margin-top: 30px;
29+
font-weight: 500;
30+
font-size: 18px;
31+
color: var(--color-gray-999);
32+
margin-bottom: 11px;
33+
`;
34+
35+
export const buttonBox = styled.div`
36+
width: 400px;
37+
margin-top: 150px;
38+
display: flex;
39+
gap: 20px;
40+
`;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface ICheckPassword {
2+
password: string;
3+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { FormProvider, useForm } from "react-hook-form";
2+
import Button from "../../../components/ui/button/Button";
3+
import Input from "../../../components/ui/input/Input";
4+
import * as S from "./updateMyPageStyle";
5+
import { schema, UpdateMyPageType } from "./schema";
6+
import { zodResolver } from "@hookform/resolvers/zod";
7+
8+
export default function UpdateMyPage() {
9+
const methods = useForm<UpdateMyPageType>({
10+
resolver: zodResolver(schema),
11+
mode: "onChange",
12+
});
13+
const onClickSubmit = (data: UpdateMyPageType) => {
14+
console.log(data);
15+
};
16+
17+
return (
18+
<FormProvider {...methods}>
19+
<S.container>
20+
<S.contentsBox onSubmit={methods.handleSubmit(onClickSubmit)}>
21+
<S.imgBox>
22+
<S.title>내 정보 수정</S.title>
23+
<S.img></S.img>
24+
<Button type="button" bgcolor="blue" textcolor="black" size="sm">
25+
프로필 사진 수정
26+
</Button>
27+
</S.imgBox>
28+
<S.inputBox>
29+
<S.label>이메일</S.label>
30+
<Input
31+
type="text"
32+
keyname="email"
33+
defaultValue="abc@sample.com"
34+
disable={true}
35+
/>
36+
</S.inputBox>
37+
<S.inputBox>
38+
<S.label>비밀번호</S.label>
39+
<Input<UpdateMyPageType> type="password" keyname="password" />
40+
<S.errorMessage>
41+
{methods.formState.errors.password?.message}
42+
</S.errorMessage>
43+
</S.inputBox>
44+
<S.inputBox>
45+
<S.label>비밀번호 확인</S.label>
46+
<Input<UpdateMyPageType> type="password" keyname="checkPassword" />
47+
<S.errorMessage>
48+
{methods.formState.errors.checkPassword?.message}
49+
</S.errorMessage>
50+
</S.inputBox>
51+
<S.inputBox>
52+
<S.label>닉네임</S.label>
53+
<Input<UpdateMyPageType> type="text" keyname="nickname" />
54+
<S.errorMessage>
55+
{methods.formState.errors.nickname?.message}
56+
</S.errorMessage>
57+
</S.inputBox>
58+
<S.buttonBox>
59+
<Button type="button" bgcolor="black" textcolor="white" size="sm">
60+
이전
61+
</Button>
62+
<Button type="submit" bgcolor="green" textcolor="black" size="sm">
63+
다음
64+
</Button>
65+
</S.buttonBox>
66+
</S.contentsBox>
67+
</S.container>
68+
</FormProvider>
69+
);
70+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { z } from "zod";
2+
3+
export const schema = z
4+
.object({
5+
password: z
6+
.string()
7+
.min(1, { message: "비밀번호는 최소 한 글자 이상이어야 합니다." }),
8+
checkPassword: z.string(),
9+
nickname: z
10+
.string()
11+
.min(1, { message: "닉네임은 최소 한 글자 이상이어야 합니다." }),
12+
})
13+
.refine((data) => data.password === data.checkPassword, {
14+
message: "비밀번호가 일치하지 않습니다.",
15+
path: ["checkPassword"],
16+
});
17+
18+
export type UpdateMyPageType = z.infer<typeof schema>;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import styled from "styled-components";
2+
3+
export const container = styled.div`
4+
display: flex;
5+
flex-direction: column;
6+
justify-content: center;
7+
align-items: center;
8+
width: 100%;
9+
height: 100%;
10+
`;
11+
12+
export const contentsBox = styled.form`
13+
display: flex;
14+
flex-direction: column;
15+
justify-content: center;
16+
width: 400px;
17+
gap: 30px;
18+
`;
19+
20+
export const imgBox = styled.div`
21+
display: flex;
22+
flex-direction: column;
23+
align-items: center;
24+
width: 100%;
25+
gap: 30px;
26+
`;
27+
28+
export const inputBox = styled.div`
29+
display: flex;
30+
flex-direction: column;
31+
width: 100%;
32+
gap: 10px;
33+
`;
34+
35+
export const title = styled.div`
36+
font-weight: 700;
37+
font-size: 32px;
38+
color: var(--color-gray-999);
39+
`;
40+
41+
export const img = styled.div`
42+
width: 80px;
43+
height: 80px;
44+
border-radius: 50%;
45+
background: #5076ff;
46+
backdrop-filter: blur(24px);
47+
`;
48+
49+
export const label = styled.label`
50+
font-weight: 500;
51+
font-size: 18px;
52+
color: var(--color-gray-999);
53+
`;
54+
55+
export const buttonBox = styled.div`
56+
width: 100%;
57+
display: flex;
58+
gap: 20px;
59+
margin-top: 50px;
60+
`;
61+
62+
export const errorMessage = styled.div`
63+
color: var(--color-warning);
64+
`;

src/pages/user/login/Login.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { FormProvider, useForm } from "react-hook-form";
22
import { zodResolver } from "@hookform/resolvers/zod";
33
import Button from "../../../components/ui/button/Button";
4-
import * as S from "./LoginStyle";
54
import { loginSchema, schema } from "./schema";
65
import Input from "../../../components/ui/input/Input";
6+
import * as S from "./loginStyle2";
77

88
export default function LoginPage() {
99
const methods = useForm<loginSchema>({

src/pages/user/login/LoginStyle.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const container = styled.div`
66
align-items: center;
77
width: 100%;
88
gap: 50px;
9+
height: 100%;
910
`;
1011

1112
export const loginBox = styled.div`

0 commit comments

Comments
 (0)