login.tsx (2949B)
1 import { useTokenFlushTrigger } from '@/components/contexts/TokenContext' 2 import { SubmitButton } from '@/components/elements/Button' 3 import Title from '@/components/elements/Title' 4 import Field from '@/components/form/Field' 5 import Fields from '@/components/form/Fields' 6 import Form from '@/components/form/Form' 7 import Container from '@/components/layout/Container' 8 import Hero from '@/components/layout/Hero' 9 import Section from '@/components/layout/Section' 10 import { useRouter } from 'next/router' 11 import { useCallback, useState } from 'react' 12 13 export default function LoginPage () { 14 return ( 15 <> 16 <Hero> 17 <Title kind="headline">Login</Title> 18 </Hero> 19 20 <Container> 21 <Section> 22 <LoginForm/> 23 </Section> 24 </Container> 25 </> 26 ) 27 } 28 29 function LoginForm () { 30 const router = useRouter() 31 const [email, setEmail] = useState('') 32 const [password, setPassword] = useState('') 33 const flushToken = useTokenFlushTrigger() 34 const [errorMessage, setErrorMessage] = useState<string | null>(null) 35 const [isLoading, setLoading] = useState(false) 36 37 const handleSubmit = useCallback(() => { 38 const handleError = (status: number) => { 39 switch (status) { 40 case 401: 41 setErrorMessage('이메일 혹은 비밀번호가 잘못되었습니다.') 42 break 43 44 default: 45 setErrorMessage('알 수 없는 오류가 발생했습니다.') 46 break 47 } 48 } 49 50 setLoading(true) 51 setErrorMessage(null) 52 53 !(async () => { 54 const res = await fetch('/api/auth/token', { 55 method: 'POST', 56 credentials: 'same-origin', 57 headers: { 58 'Content-Type': 'application/json' 59 }, 60 body: JSON.stringify({ email, password }), 61 }) 62 63 if (!res.ok) { 64 handleError(res.status) 65 setLoading(false) 66 return 67 } 68 69 flushToken() 70 71 if (typeof router.query.redirect_to === 'string') { 72 await router.push(router.query.redirect_to as string) 73 } else { 74 await router.push('/') 75 } 76 })().catch ((err) => { 77 console.error(err) 78 setErrorMessage('알 수 없는 오류가 발생했습니다.') 79 }) 80 }, [email, password]) 81 82 return ( 83 <Form onSubmit={handleSubmit}> 84 <Fields> 85 <Field 86 type="text" 87 color={errorMessage != null ? 'error' : undefined} 88 disabled={isLoading} 89 placeholder="Email" 90 value={email} 91 message={errorMessage ?? undefined} 92 onValueChange={setEmail} 93 /> 94 <Field 95 type="password" 96 color={errorMessage != null ? 'error' : undefined} 97 disabled={isLoading} 98 placeholder="Password" 99 value={password} 100 onValueChange={setPassword} 101 /> 102 103 <SubmitButton 104 color="primary" 105 disabled={isLoading} 106 value={'Login'} 107 /> 108 </Fields> 109 </Form> 110 ) 111 }