dh_demo

DreamHanks demo project
git clone git://git.lair.cx/dh_demo
Log | Files | Refs | README

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 }