-
Notifications
You must be signed in to change notification settings - Fork 1
Fix/75 빌드 오류 수정 및 알림창 변경 #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
677ae9c
e3bac1e
82ae621
bf6841c
4bbcb01
53be277
2198cd8
501429b
8eedd53
cea81c8
573a47a
0f1d9db
48b9269
35a3271
e313b55
32b23c8
a93fead
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| 'use client'; | ||
|
|
||
| interface KakaoLoadingProps { | ||
| message: string; | ||
| } | ||
|
|
||
| export default function KakaoLoading({ message }: KakaoLoadingProps) { | ||
| return ( | ||
| <div className='flex min-h-screen items-center justify-center bg-white'> | ||
| <div className='flex flex-col items-center'> | ||
| <div className='mb-6 h-30 w-30 animate-spin rounded-full border-4 border-yellow-100 border-t-transparent' /> | ||
| <p className='mt-4 text-lg font-semibold text-black'>{message}</p> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| 'use client'; | ||
|
|
||
| export const dynamic = 'force-dynamic'; | ||
|
|
||
| import Popup from '@/components/Popup'; | ||
| import useUserStore from '@/stores/authStore'; | ||
| import { PopupState } from '@/types/popupTypes'; | ||
| import axios from 'axios'; | ||
| import { useRouter, useSearchParams } from 'next/navigation'; | ||
| import { useEffect, useState } from 'react'; | ||
| import KakaoLoading from '../components/KakaoLoading'; | ||
|
|
||
| /** | ||
| * 카카오 로그인 콜백 처리 페이지 컴포넌트입니다. | ||
| * | ||
| * 카카오 인증 서버에서 리디렉션된 `code` 쿼리 파라미터를 받아 | ||
| * 백엔드(`/api/auth/kakao/sign-in`)에 로그인 요청을 보냅니다. | ||
| * 응답에 포함된 사용자 정보를 Zustand 스토어에 저장하고, | ||
| * 로그인 성공 시 메인 페이지(`/`)로 이동합니다. | ||
| * | ||
| * 오류 발생 시 상태 코드에 따라 다른 알림 메시지를 출력하고 | ||
| * 적절한 페이지(`/signup` 또는 `/login`)로 이동합니다. | ||
| * | ||
| * 주요 흐름: | ||
| * 1. `code` 파라미터 확인 | ||
| * 2. POST 요청으로 로그인 시도 | ||
| * 3. 사용자 존재 시 상태 저장 및 리다이렉트 | ||
| * 4. 오류 상황에 따라 알림 및 경로 분기 | ||
| * | ||
| */ | ||
| export default function KakaoSigninCallbackPage() { | ||
| const router = useRouter(); | ||
| const searchParams = useSearchParams(); | ||
| const setUser = useUserStore((state) => state.setUser); | ||
|
|
||
| const [popup, setPopup] = useState<PopupState>({ | ||
| message: '', | ||
| redirect: '', | ||
| isOpen: false, | ||
| }); | ||
|
|
||
| useEffect(() => { | ||
| const code = searchParams.get('code'); | ||
| if (!code) return; | ||
|
|
||
| /** | ||
| * 카카오 로그인 처리를 위한 비동기 함수입니다. | ||
| * - 백엔드에 인증 코드 전송 | ||
| * - 사용자 정보 저장 | ||
| * - 오류 처리 및 알림 | ||
| */ | ||
| const handleKakaoLogin = async () => { | ||
| try { | ||
| const res = await axios.post('/api/auth/kakao/sign-in', { code }); | ||
| const data = res.data; | ||
|
|
||
| if (data.user) { | ||
| setUser(data.user); | ||
| router.push('/'); | ||
| } | ||
| } catch (err: unknown) { | ||
| if (axios.isAxiosError(err)) { | ||
| const status = err.response?.status; | ||
|
|
||
| switch (status) { | ||
| case 404: | ||
| setPopup({ | ||
| message: '가입된 회원이 아닙니다. 회원가입을 진행해주세요.', | ||
| redirect: '/signup', | ||
| isOpen: true, | ||
| }); | ||
| break; | ||
| case 500: | ||
| setPopup({ | ||
| message: '서버 오류입니다. 잠시 후 다시 시도해주세요.', | ||
| redirect: '/login', | ||
| isOpen: true, | ||
| }); | ||
| default: | ||
| setPopup({ | ||
| message: '카카오 로그인 실패', | ||
| redirect: '/login', | ||
| isOpen: true, | ||
| }); | ||
| break; | ||
| } | ||
| } else { | ||
| setPopup({ | ||
| message: '사용자 정보가 없습니다. 다시 시도해주세요.', | ||
| redirect: '/login', | ||
| isOpen: true, | ||
| }); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| handleKakaoLogin(); | ||
| }, [searchParams, router]); | ||
|
|
||
| return ( | ||
| <> | ||
| <KakaoLoading message='카카오 로그인 처리 중...' /> | ||
|
|
||
| <Popup | ||
| isOpen={popup.isOpen} | ||
| type='alert' | ||
| onClose={() => { | ||
| setPopup((prev) => ({ ...prev, isOpen: false })); | ||
| router.push(popup.redirect); | ||
| }} | ||
| > | ||
| {popup.message} | ||
| </Popup> | ||
| </> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,86 +1,11 @@ | ||
| // 'use client'; | ||
|
|
||
| // export const dynamic = 'force-dynamic'; | ||
|
|
||
| // import useUserStore from '@/stores/authStore'; | ||
| // import axios from 'axios'; | ||
| // import { useRouter, useSearchParams } from 'next/navigation'; | ||
| // import { useEffect } from 'react'; | ||
|
|
||
| // /** | ||
| // * 카카오 로그인 콜백 처리 페이지 컴포넌트입니다. | ||
| // * | ||
| // * 카카오 인증 서버에서 리디렉션된 `code` 쿼리 파라미터를 받아 | ||
| // * 백엔드(`/api/auth/kakao/sign-in`)에 로그인 요청을 보냅니다. | ||
| // * 응답에 포함된 사용자 정보를 Zustand 스토어에 저장하고, | ||
| // * 로그인 성공 시 메인 페이지(`/`)로 이동합니다. | ||
| // * | ||
| // * 오류 발생 시 상태 코드에 따라 다른 알림 메시지를 출력하고 | ||
| // * 적절한 페이지(`/signup` 또는 `/login`)로 이동합니다. | ||
| // * | ||
| // * 주요 흐름: | ||
| // * 1. `code` 파라미터 확인 | ||
| // * 2. POST 요청으로 로그인 시도 | ||
| // * 3. 사용자 존재 시 상태 저장 및 리다이렉트 | ||
| // * 4. 오류 상황에 따라 알림 및 경로 분기 | ||
| // * | ||
| // * @component | ||
| // * @returns {JSX.Element} "카카오 로그인 처리 중입니다..."라는 텍스트를 포함한 JSX | ||
| // */ | ||
| export default function KakaoSigninCallbackPage() { | ||
| return <div>카카오 로그인 처리 예정</div>; | ||
| import { Suspense } from 'react'; | ||
| import KakaoSigninCallbackPage from './kakaoSigninCallbackPage'; | ||
| import Loading from '@/components/Loading'; | ||
|
|
||
| export default function KakaoSigninPage() { | ||
| return ( | ||
| <Suspense fallback={<Loading />}> | ||
| <KakaoSigninCallbackPage /> | ||
| </Suspense> | ||
| ); | ||
| } | ||
| // const router = useRouter(); | ||
| // const searchParams = useSearchParams(); | ||
| // const setUser = useUserStore((state) => state.setUser); | ||
|
|
||
| // useEffect(() => { | ||
| // const code = searchParams.get('code'); | ||
| // if (!code) return; | ||
|
|
||
| // /** | ||
| // * 카카오 로그인 처리를 위한 비동기 함수입니다. | ||
| // * - 백엔드에 인증 코드 전송 | ||
| // * - 사용자 정보 저장 | ||
| // * - 오류 처리 및 알림 | ||
| // */ | ||
| // const handleKakaoLogin = async () => { | ||
| // try { | ||
| // const res = await axios.post('/api/auth/kakao/sign-in', { code }); | ||
| // const data = res.data; | ||
|
|
||
| // if (data.user) { | ||
| // setUser(data.user); | ||
| // router.push('/'); | ||
| // } | ||
| // } catch (err: unknown) { | ||
| // if (axios.isAxiosError(err)) { | ||
| // const status = err.response?.status; | ||
| // const message = err.response?.data?.error; | ||
|
|
||
| // switch (status) { | ||
| // case 404: | ||
| // alert('가입된 회원이 아닙니다. 회원가입을 진행해주세요.'); | ||
| // router.push('/signup'); | ||
| // break; | ||
| // case 500: | ||
| // alert('서버 오류입니다. 잠시 후 다시 시도해주세요.'); | ||
| // router.push('/login'); | ||
| // break; | ||
| // default: | ||
| // alert(message || '카카오 로그인 실패'); | ||
| // router.push('/login'); | ||
| // break; | ||
| // } | ||
| // } else { | ||
| // alert('사용자 정보가 없습니다. 다시 시도해주세요.'); | ||
| // router.push('/login'); | ||
| // } | ||
| // } | ||
| // }; | ||
|
|
||
| // handleKakaoLogin(); | ||
| // }, [searchParams, router]); | ||
|
|
||
| // return <div>카카오 로그인 처리 중입니다...</div>; | ||
| // } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| 'use client'; | ||
|
|
||
| export const dynamic = 'force-dynamic'; | ||
|
|
||
| import Popup from '@/components/Popup'; | ||
| import useUserStore from '@/stores/authStore'; | ||
| import { PopupState } from '@/types/popupTypes'; | ||
| import axios from 'axios'; | ||
| import { useRouter, useSearchParams } from 'next/navigation'; | ||
| import { useEffect, useState } from 'react'; | ||
| import KakaoLoading from '../components/KakaoLoading'; | ||
|
|
||
| const adjectives = [ | ||
| '상냥한', | ||
| '용감한', | ||
| '조용한', | ||
| '귀여운', | ||
| '멋진', | ||
| '차분한', | ||
| '빠른', | ||
| '신비한', | ||
| ]; | ||
| const animals = [ | ||
| '고양이', | ||
| '호랑이', | ||
| '강아지', | ||
| '여우', | ||
| '곰', | ||
| '사자', | ||
| '토끼', | ||
| '다람쥐', | ||
| ]; | ||
|
Comment on lines
+13
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 상수를 별도 파일로 분리하는 것을 고려해보세요. 형용사와 동물 배열이 컴포넌트 내부에 하드코딩되어 있습니다. 코드 재사용성과 유지보수성을 위해 별도의 상수 파일로 분리하는 것을 권장합니다. 예시로 export const ADJECTIVES = [
'상냥한',
'용감한',
'조용한',
// ... 나머지 형용사들
];
export const ANIMALS = [
'고양이',
'호랑이',
'강아지',
// ... 나머지 동물들
];🤖 Prompt for AI Agents |
||
|
|
||
| /** | ||
| * 카카오 회원가입 콜백 처리 페이지 컴포넌트입니다. | ||
| * | ||
| * 카카오 인증 서버에서 전달된 `code` 쿼리 파라미터를 바탕으로 | ||
| * 백엔드(`/api/auth/kakao/sign-up`)에 회원가입 요청을 보내고, | ||
| * 성공적으로 가입된 사용자 정보를 Zustand 스토어에 저장한 후 | ||
| * 로그인 페이지(`/login`)로 이동합니다. | ||
| * | ||
| * 요청 시 랜덤한 형용사 + 동물 조합으로 닉네임을 생성하여 함께 전송합니다. | ||
| * | ||
| * 주요 흐름: | ||
| * 1. `code` 쿼리 파라미터 존재 여부 확인 | ||
| * 2. 랜덤 닉네임 생성 | ||
| * 3. 서버에 회원가입 요청 전송 | ||
| * 4. 성공 시 사용자 정보 저장 및 리다이렉션 | ||
| * 5. 실패 시 알림 후 회원가입 페이지로 이동 | ||
| */ | ||
| export default function KakaoSignupCallbackPage() { | ||
| const router = useRouter(); | ||
| const searchParams = useSearchParams(); | ||
| const setUser = useUserStore((state) => state.setUser); | ||
|
|
||
| const [popup, setPopup] = useState<PopupState>({ | ||
| message: '', | ||
| redirect: '', | ||
| isOpen: false, | ||
| }); | ||
|
|
||
| useEffect(() => { | ||
| const code = searchParams.get('code'); | ||
|
|
||
| if (!code) return; | ||
|
|
||
| const nickname = `${adjectives[Math.floor(Math.random() * adjectives.length)]}${animals[Math.floor(Math.random() * animals.length)]}`; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 닉네임 중복 가능성을 고려해보세요. 현재 예시 개선안: const nickname = `${adjectives[Math.floor(Math.random() * adjectives.length)]}${animals[Math.floor(Math.random() * animals.length)]}${Date.now().toString().slice(-4)}`;🤖 Prompt for AI Agents |
||
|
|
||
| /** | ||
| * 카카오 회원가입 처리를 위한 비동기 함수입니다. | ||
| * - 인증 코드와 랜덤 닉네임을 포함하여 서버에 POST 요청 | ||
| * - 응답으로 받은 사용자 정보를 상태에 저장 | ||
| * - 성공 시 로그인 페이지로, 실패 시 회원가입 페이지로 이동 | ||
| */ | ||
| const handleKakaoSignup = async () => { | ||
| try { | ||
| const res = await axios.post('/api/auth/kakao/sign-up', { | ||
| code, | ||
| nickname, | ||
| }); | ||
| const data = res.data; | ||
|
|
||
| if (data.user) { | ||
| setUser(data.user); | ||
| router.push('/login'); | ||
| } | ||
| } catch (err: unknown) { | ||
| if (axios.isAxiosError(err)) { | ||
| const status = err.response?.status; | ||
|
|
||
| switch (status) { | ||
| case 400: | ||
| setPopup({ | ||
| message: '이미 가입된 회원입니다.', | ||
| redirect: '/login', | ||
| isOpen: true, | ||
| }); | ||
| break; | ||
| case 500: | ||
| setPopup({ | ||
| message: '서버 오류입니다. 잠시 후 다시 시도해주세요.', | ||
| redirect: '/signup', | ||
| isOpen: true, | ||
| }); | ||
| break; | ||
| default: | ||
| setPopup({ | ||
| message: '회원가입에 실패했습니다. 다시 시도해주세요.', | ||
| redirect: '/signup', | ||
| isOpen: true, | ||
| }); | ||
| break; | ||
| } | ||
| } else { | ||
| setPopup({ | ||
| message: '예기치 못한 오류가 발생했습니다. 다시 시도해주세요.', | ||
| redirect: '/signup', | ||
| isOpen: true, | ||
| }); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| handleKakaoSignup(); | ||
| }, [searchParams, router]); | ||
|
|
||
| return ( | ||
| <> | ||
| <KakaoLoading message='카카오 회원가입 처리 중...' /> | ||
|
|
||
| <Popup | ||
| isOpen={popup.isOpen} | ||
| type='alert' | ||
| onClose={() => { | ||
| setPopup((prev) => ({ ...prev, isOpen: false })); | ||
| router.push(popup.redirect); | ||
| }} | ||
| > | ||
| {popup.message} | ||
| </Popup> | ||
| </> | ||
| ); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.