Skip to content

Commit

Permalink
Merge pull request #206 from kakao-tech-campus-2nd-step3/Week11
Browse files Browse the repository at this point in the history
�Fix: 로그인 로직 수정
  • Loading branch information
ppochaco authored Nov 12, 2024
2 parents eabb1ce + bacd90b commit 7eeb962
Showing 5 changed files with 233 additions and 47 deletions.
29 changes: 27 additions & 2 deletions src/api/services/user/login.api.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useQuery } from '@tanstack/react-query'

import { fetchInstance } from '@/api/instance'
import { authorizationInstance, fetchInstance } from '@/api/instance'

type KakaoLoginParam = {
code: string
}

type KakaoLoginResponse = {
userId: number
role: 'USER' | 'TEMP'
}

const kakaoLogin = async ({ code }: KakaoLoginParam) => {
@@ -16,7 +17,7 @@ const kakaoLogin = async ({ code }: KakaoLoginParam) => {
)
const accessToken = response.headers.authorization

return { accessToken, userId: response.data.userId }
return { accessToken, userId: response.data.userId, role: response.data.role }
}

export const useKakaoLogin = ({ code }: KakaoLoginParam) => {
@@ -25,3 +26,27 @@ export const useKakaoLogin = ({ code }: KakaoLoginParam) => {
queryFn: () => kakaoLogin({ code }),
})
}

export type RegisterUserRequestBody = {
name: string
gender: string
year: number
month: number
day: number
}

type RegisterUeserResponse = {
userId: number
jwt: string
role: 'USER'
}

export const registerUser = async (data: RegisterUserRequestBody) => {
const response = await authorizationInstance.post<RegisterUeserResponse>(
'/api/user/information',
data
)
const accessToken = response.headers.authorization

return { accessToken, userId: response.data.userId }
}
7 changes: 7 additions & 0 deletions src/pages/Layout/MainLayout/GlobalErrorFallback/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEffect } from 'react'
import { FallbackProps } from 'react-error-boundary'
import { useNavigate } from 'react-router-dom'

@@ -18,6 +19,12 @@ export const GlobalErrorFallback = ({

const navigate = useNavigate()

useEffect(() => {
if (status === 428) {
navigate('/register')
}
}, [status, navigate])

return (
<PageLayout
LeftSection={<GroupSectionSkeleton />}
6 changes: 6 additions & 0 deletions src/pages/LoginRedirectPage/LoginRedirectSection/index.tsx
Original file line number Diff line number Diff line change
@@ -19,6 +19,12 @@ export const LoginRedirectSection = ({ code }: LoginRedirectSectionProps) => {

useEffect(() => {
if (data) {
if (data.role === 'TEMP') {
setAuthToken(data.accessToken)
setMyUserId(data.userId)
navigate('/register')
return
}
setAuthToken(data.accessToken)
setMyUserId(data.userId)
navigate('/')
220 changes: 175 additions & 45 deletions src/pages/RegisterPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,203 @@
import { useForm } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'

import {
Box,
Button,
Flex,
Heading,
Input,
Radio,
RadioGroup,
Stack,
Text,
} from '@chakra-ui/react'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation } from '@tanstack/react-query'

import {
RegisterUserRequestBody,
registerUser,
} from '@/api/services/user/login.api'
import {
Form,
FormControl,
FormField,
FormItem,
FormMessage,
} from '@/components/Form'
import { RegisterUserFields, RegisterUserSchema } from '@/schema/user'
import { useAuthTokenStore } from '@/stores/auth-token'
import { useMyUserIdStore } from '@/stores/my-user-id'

export default function RegisterPage() {
const navigate = useNavigate()

const form = useForm<RegisterUserFields>({
resolver: zodResolver(RegisterUserSchema),
mode: 'onBlur',
defaultValues: {
name: '',
gender: undefined,
year: '',
month: '',
day: '',
},
})

const setAuthToken = useAuthTokenStore((state) => state.setAuthToken)
const setMyUserId = useMyUserIdStore((state) => state.setMyUserId)

const { mutate } = useMutation({
mutationFn: (data: RegisterUserRequestBody) => registerUser(data),
onSuccess: (data) => {
setAuthToken(data.accessToken)
setMyUserId(data.userId)
navigate('/')
},
})

const onValid = () => {
mutate({
name: form.getValues('name'),
gender: form.getValues('gender'),
year: Number(form.getValues('year')),
month: Number(form.getValues('month')),
day: Number(form.getValues('day')),
})
}

return (
<Flex
flexDirection="column"
justifyContent="center"
alignItems="center"
width="full"
gap={6}
p={4}
padding={4}
>
<Heading color="brown.600" size="xl" fontWeight="800">
회원가입
</Heading>
<Text color="gray.600" fontSize="md" textAlign="center">
가입을 통해 더 다양한 서비스를 만나보세요!
</Text>

<Box width="100%" maxWidth="400px">
<Text fontWeight="bold" mb={2}>
이름
</Text>
<Input placeholder="이름 입력" />
</Box>

<Box width="100%" maxWidth="400px">
<Text fontWeight="bold" mb={2}>
성별
</Text>
<RadioGroup>
<Stack direction="row" spacing={5}>
<Radio value="남" colorScheme="brown">
</Radio>
<Radio value="여" colorScheme="brown">
</Radio>
</Stack>
</RadioGroup>
</Box>

<Box width="100%" maxWidth="400px">
<Text fontWeight="bold" mb={2}>
나이
</Text>
<Input type="number" placeholder="나이 입력" />
</Box>

<Button
bg="brown.500"
color="secondary_background"
_hover={{ bg: 'brown.600' }}
size="lg"
width="100%"
maxWidth="400px"
mt={6}
>
가입하기
</Button>
<Form {...form}>
<form onSubmit={form.handleSubmit(onValid)}>
<Flex flexDirection="column" gap={4} maxWidth="400px">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormControl>
<Text fontWeight="bold" mb={2}>
이름
</Text>
<Input
value={field.value}
onChange={field.onChange}
placeholder="쿠키즈"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="gender"
render={({ field }) => (
<FormItem>
<FormControl>
<Text fontWeight="bold" mb={2}>
성별
</Text>
<RadioGroup value={field.value} onChange={field.onChange}>
<Flex gap={5}>
<Radio value="male" colorScheme="brown">
</Radio>
<Radio value="female" colorScheme="brown">
</Radio>
</Flex>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Flex flexDirection="column">
<Text fontWeight="bold" mb={2}>
생년월일
</Text>
<Flex gap={2}>
<FormField
control={form.control}
name="year"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
value={field.value}
onChange={field.onChange}
type="number"
placeholder="YYYY"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="month"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
value={field.value}
onChange={field.onChange}
type="number"
placeholder="MM"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="day"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
value={field.value}
onChange={field.onChange}
type="number"
placeholder="DD"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</Flex>
</Flex>
<Button
bg="brown.500"
color="secondary_background"
_hover={{ bg: 'brown.600' }}
size="lg"
width="full"
mt={6}
type="submit"
>
가입하기
</Button>
</Flex>
</form>
</Form>
</Flex>
)
}
18 changes: 18 additions & 0 deletions src/schema/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { z } from 'zod'

export const RegisterUserSchema = z.object({
name: z
.string()
.min(1, { message: '이름을 입력해주세요' })
.regex(/^[가-힣]+$/, { message: '공백없이 한글만 입력해주세요' }),
gender: z.enum(['male', 'female'], {
errorMap: () => ({ message: '성별을 선택해주세요' }),
}),
year: z
.string()
.regex(/^[0-9]{4}$/, { message: '연도는 4자리 숫자로 입력해 주세요' }),
month: z.string().regex(/^[0-9]{1,2}$/, { message: '숫자만 입력해주세요' }),
day: z.string().regex(/^[0-9]{1,2}$/, { message: '숫자만 입력해주세요' }),
})

export type RegisterUserFields = z.infer<typeof RegisterUserSchema>

0 comments on commit 7eeb962

Please sign in to comment.