Skip to content

Commit 5a0ea2e

Browse files
authored
Merge pull request #38 from codeit-sprint-part3-6team/#33_공통컴포넌트_Input이메일-비밀번호
#33 공통컴포넌트 input이메일 비밀번호
2 parents 0fc0a9f + 947b7e8 commit 5a0ea2e

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
.authField + .authField {
2+
margin-top: 16px;
3+
}
4+
5+
.title {
6+
font-size: 16px;
7+
font-weight: 400;
8+
color: var(--black-medium);
9+
cursor: pointer;
10+
}
11+
12+
.authInput {
13+
display: flex;
14+
flex-direction: column;
15+
position: relative;
16+
margin-top: 8px;
17+
}
18+
19+
.authInput input {
20+
padding: 0 16px;
21+
border: 1px solid var(--gray-medium);
22+
border-radius: 8px;
23+
width: 100%;
24+
height: 50px;
25+
}
26+
27+
.authInput input.password {
28+
padding-right: 56px;
29+
}
30+
31+
.authInput input:focus {
32+
border: 1px solid var(--violet);
33+
outline: none;
34+
}
35+
36+
.authInput input::placeholder {
37+
color: var(--gray-dark);
38+
}
39+
40+
.authInput.error input,
41+
.authInput.error input:focus {
42+
border: 1px solid var(--red);
43+
}
44+
45+
.authInput span {
46+
margin-top: 8px;
47+
font-size: 14px;
48+
font-weight: 400;
49+
color: var(--red);
50+
}
51+
52+
.authInput button {
53+
padding: 0;
54+
border: none;
55+
background: none;
56+
width: 24px;
57+
height: 24px;
58+
cursor: pointer;
59+
position: absolute;
60+
top: 50%;
61+
right: 16px;
62+
transform: translateY(-50%);
63+
}
64+
65+
.authInput button svg {
66+
width: 100%;
67+
height: 100%;
68+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { ChangeEvent, MouseEvent, useState } from 'react';
2+
import styles from './AuthInput.module.css';
3+
import Visibility from 'public/ic/ic_visibility.svg';
4+
import InVisibility from 'public/ic/ic_invisibility.svg';
5+
6+
type AuthInputProps = {
7+
htmlFor: string;
8+
title: string;
9+
id: string;
10+
type: string | null;
11+
placeholder: string;
12+
value: string;
13+
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
14+
error?: boolean;
15+
errorMessage?: string;
16+
};
17+
18+
function AuthInput({
19+
htmlFor,
20+
title,
21+
type = 'text',
22+
id,
23+
placeholder,
24+
value,
25+
onChange,
26+
error,
27+
errorMessage,
28+
}: AuthInputProps) {
29+
const [isVisibleToggle, setIsVisibleToggle] = useState(false);
30+
31+
const isPassword = type === 'password';
32+
const inputType = isPassword ? (isVisibleToggle ? 'text' : 'password') : type;
33+
34+
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
35+
e.preventDefault();
36+
setIsVisibleToggle(!isVisibleToggle);
37+
};
38+
39+
return (
40+
<div className={styles.authField}>
41+
<label className={styles.title} htmlFor={htmlFor}>
42+
{title}
43+
</label>
44+
45+
<div className={`${styles.authInput} ${error ? styles.error : ''}`}>
46+
<input
47+
type={inputType}
48+
id={id}
49+
className={`${isPassword ? styles.password : ''}`}
50+
placeholder={placeholder}
51+
value={value}
52+
onChange={onChange}
53+
/>
54+
55+
{isPassword && (
56+
<button onClick={handleClick}>
57+
{isVisibleToggle ? <Visibility /> : <InVisibility />}
58+
</button>
59+
)}
60+
61+
{error && <span>{errorMessage}</span>}
62+
</div>
63+
</div>
64+
);
65+
}
66+
67+
export default AuthInput;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import AuthInput from '@/components/common/input/AuthInput';
2+
import { useState } from 'react';
3+
4+
export default function TestAuthInput() {
5+
const [emailValue, setEmailValue] = useState('');
6+
const [passwordValue, setPasswordValue] = useState('');
7+
8+
return (
9+
<>
10+
<div style={{ width: '540px' }}>
11+
<AuthInput
12+
htmlFor="email"
13+
title="이메일"
14+
id="email"
15+
type="text"
16+
placeholder="이메일을 입력해 주세요"
17+
value={emailValue}
18+
onChange={(e) => setEmailValue(e.target.value)}
19+
error={true}
20+
errorMessage="이메일 형식으로 작성해 주세요."
21+
/>
22+
23+
<AuthInput
24+
htmlFor="password"
25+
title="비밀번호"
26+
id="password"
27+
type="password"
28+
placeholder="비밀번호를 입력해 주세요"
29+
value={passwordValue}
30+
onChange={(e) => setPasswordValue(e.target.value)}
31+
/>
32+
</div>
33+
</>
34+
);
35+
}

src/pages/api/axios.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import axios from 'axios';
2+
3+
const instance = axios.create({
4+
baseURL: process.env.NEXT_PUBLIC_API_URL,
5+
});
6+
7+
export default instance;

0 commit comments

Comments
 (0)