61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
import { Button, Input } from '@/components'
|
||
import { useLogin } from '@/features/auth/hooks/useLogin'
|
||
|
||
const inputClassName = 'h-12 rounded-md px-4 text-base'
|
||
|
||
export function LoginForm() {
|
||
const {
|
||
id,
|
||
password,
|
||
errorMessage,
|
||
isLoading,
|
||
onIdChange,
|
||
onPasswordChange,
|
||
onLogin,
|
||
} = useLogin()
|
||
|
||
return (
|
||
<form
|
||
onSubmit={(e) => {
|
||
e.preventDefault()
|
||
onLogin()
|
||
}}
|
||
className="flex w-full flex-col justify-center gap-6"
|
||
>
|
||
<div className="flex flex-col gap-3">
|
||
<Input
|
||
type="text"
|
||
aria-label="아이디"
|
||
placeholder="아이디를 입력해주세요."
|
||
value={id}
|
||
onChange={(e) => onIdChange(e.target.value)}
|
||
autoComplete="username"
|
||
className={inputClassName}
|
||
/>
|
||
<Input
|
||
type="password"
|
||
aria-label="비밀번호"
|
||
placeholder="비밀번호를 입력해주세요."
|
||
value={password}
|
||
onChange={(e) => onPasswordChange(e.target.value)}
|
||
autoComplete="current-password"
|
||
className={inputClassName}
|
||
/>
|
||
<p
|
||
className="text-sm tracking-[-0.28px] text-destructive"
|
||
role="alert"
|
||
aria-live="polite"
|
||
>
|
||
{errorMessage || ' '}
|
||
</p>
|
||
</div>
|
||
|
||
<Button type="submit" size="lg" className="w-full" disabled={isLoading}>
|
||
{isLoading ? '로그인 중…' : '로그인'}
|
||
</Button>
|
||
</form>
|
||
)
|
||
}
|
||
|
||
export default LoginForm
|