diff --git a/src/features/Redirection/Redirection.tsx b/src/features/Redirection/Redirection.tsx index b428e39..f2f6be8 100644 --- a/src/features/Redirection/Redirection.tsx +++ b/src/features/Redirection/Redirection.tsx @@ -1,29 +1,44 @@ 'use client'; import React, { useEffect } from 'react'; -import { useRouter } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; const Redirection = () => { const router = useRouter(); + const searchParams = useSearchParams(); - // 쿠키 기반 로그인 상태 확인 useEffect(() => { + const accessToken = searchParams.get('accessToken'); + + if (accessToken) { + // accessToken 로컬스토리지에 저장 + localStorage.setItem('accessToken', accessToken); + console.log('accessToken 저장 완료:', accessToken); + } else { + console.warn('accessToken 없음, 홈으로 이동'); + router.replace('/'); + return; + } + const checkLoginStatus = async () => { try { const res = await fetch( `${process.env.NEXT_PUBLIC_BACKEND_URL}auth/status`, { credentials: 'include', + headers: { + Authorization: `Bearer ${accessToken}`, + }, }, ); const data = await res.json(); console.log('로그인 상태 응답:', data); - if (data.isLoggedIn) { + if (data.code === 200) { router.replace('/match-usercode'); } else { - console.log('로그인 실패 → 홈으로 이동'); + console.log('로그인 실패 → 홈으로'); router.replace('/'); } } catch (err) { @@ -33,7 +48,7 @@ const Redirection = () => { }; checkLoginStatus(); - }, [router]); + }, [router, searchParams]); return (
diff --git a/src/features/components/LoginButton.tsx b/src/features/components/LoginButton.tsx index 53e3a2b..8b1f64e 100644 --- a/src/features/components/LoginButton.tsx +++ b/src/features/components/LoginButton.tsx @@ -3,8 +3,8 @@ import React from 'react'; const LoginButton = () => { - const KAKAO_AUTH_URL = `${process.env.NEXT_PUBLIC_KAKAO_AUTH_URL}`; - + const redirectUrl = encodeURIComponent('http://localhost:3000/Redirection'); + const KAKAO_AUTH_URL = `${process.env.NEXT_PUBLIC_KAKAO_AUTH_URL}?redirectUrl=${redirectUrl}`; const loginHandler = () => { window.location.href = KAKAO_AUTH_URL; }; diff --git a/src/features/match-usercode/MatchUserCode.tsx b/src/features/match-usercode/MatchUserCode.tsx index 583fdf1..de9ebf7 100644 --- a/src/features/match-usercode/MatchUserCode.tsx +++ b/src/features/match-usercode/MatchUserCode.tsx @@ -1,13 +1,15 @@ 'use client'; + import { Button } from '@/components/atoms/button/Button'; import TextInput from '@/components/atoms/textInput/TextInput'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; +import Cookies from 'js-cookie'; import { TopBar } from '@/components/molecules/topBar/TopBar'; export default function MatchUserCode() { const [inputValue, setInputValue] = useState(''); - const [userCode, setUserCode] = useState('무서운츄러스145'); + const [userCode, setUserCode] = useState(''); const router = useRouter(); const handleInput = (value: string) => { @@ -15,25 +17,48 @@ export default function MatchUserCode() { }; const handleConnect = () => { - if (inputValue === '무서운츄러스145') router.push('/sign-nickname'); + if (inputValue === userCode) router.push('/sign-nickname'); + }; + + const getAccessToken = () => { + if (process.env.NODE_ENV === 'development') { + // 개발 환경에서는 localStorage + return localStorage.getItem('accessToken'); + } else { + // 배포 환경에서는 쿠키에서 읽기 + return Cookies.get('accessToken'); + } }; - // 쿠키 기반 로그인 상태 확인 + // 쿠키 기반 로그인 상태 확인 및 유저 코드 요청 useEffect(() => { + const accessToken = getAccessToken(); + + if (!accessToken) { + console.warn('Access token이 없습니다. 홈으로 이동합니다.'); + router.replace('/'); + return; + } + const checkLoginStatus = async () => { try { const res = await fetch( `${process.env.NEXT_PUBLIC_BACKEND_URL}auth/status`, { credentials: 'include', + headers: { + Authorization: `Bearer ${accessToken}`, + }, }, ); const data = await res.json(); + const isValid = data.code; + console.log('로그인 상태 응답:', data); - if (data.isLoggedIn) { - router.replace('/match-usercode'); + if (isValid === 200) { + fetchMatchCode(accessToken); } else { console.log('로그인 실패 → 홈으로 이동'); router.replace('/'); @@ -44,6 +69,32 @@ export default function MatchUserCode() { } }; + const fetchMatchCode = async (token: string) => { + try { + const res = await fetch( + `${process.env.NEXT_PUBLIC_BACKEND_URL}api/couple/match-code`, + { + credentials: 'include', + headers: { + Authorization: `Bearer ${token}`, + }, + }, + ); + + const data = await res.json(); + const isValid = data.code; + console.log('매치 코드 응답:', data); + + if (isValid === 200 && data.data?.matchCode) { + setUserCode(data.data.matchCode); + } else { + console.warn('매치 코드 응답 실패'); + } + } catch (err) { + console.error('매치 코드 불러오기 실패:', err); + } + }; + checkLoginStatus(); }, [router]); @@ -71,7 +122,7 @@ export default function MatchUserCode() {

내 코드

- {userCode} + {userCode || '코드 불러오는 중...'}

diff --git a/src/features/sign-nickname/SignNickName.tsx b/src/features/sign-nickname/SignNickName.tsx index a5688fa..feeea62 100644 --- a/src/features/sign-nickname/SignNickName.tsx +++ b/src/features/sign-nickname/SignNickName.tsx @@ -4,18 +4,64 @@ import { Button } from '@/components/atoms/button/Button'; import TextInput from '@/components/atoms/textInput/TextInput'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; +import Cookies from 'js-cookie'; import { TopBar } from '@/components/molecules/topBar/TopBar'; export default function SignNickName() { const [inputValue, setInputValue] = useState(''); + const [gender, setGender] = useState(''); const router = useRouter(); const handleInput = (value: string) => { setInputValue(value); }; - const handleConnect = () => { - if (inputValue.length > 0) router.push(`/home/${inputValue}`); + const getAccessToken = () => { + return process.env.NODE_ENV === 'development' + ? localStorage.getItem('accessToken') + : Cookies.get('accessToken'); + }; + + const handleConnect = async () => { + if (inputValue.length === 0 || gender === '') return; + + const accessToken = getAccessToken(); + if (!accessToken) { + console.warn('Access token이 없습니다. 다시 로그인해주세요.'); + router.push('/'); + return; + } + + const mappedGender = gender === 'male' ? 'GROOM' : 'BRIDE'; + + // try { + const res = await fetch( + `${process.env.NEXT_PUBLIC_BACKEND_URL}api/couple`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${accessToken}`, + }, + credentials: 'include', + body: JSON.stringify({ + gender: mappedGender, + nickName: inputValue, + }), + }, + ); + + const result = await res.json(); + console.log('result:', result); + + // if (result.code !== 200) { + // throw new Error(`요청 실패: ${result.message}`); + // } + + router.push(`/home/${inputValue}`); + // } catch (error) { + // console.error('요청 중 오류 발생:', error); + // } }; return ( @@ -28,6 +74,7 @@ export default function SignNickName() { router.push('/match-usercode'); }} /> +

연결 완료!

@@ -47,15 +94,49 @@ export default function SignNickName() { maxLength={2} />
+ +
+
+ {[ + { value: 'male', label: '남자' }, + { value: 'female', label: '여자' }, + ].map(({ value, label }) => { + const isSelected = gender === value; + + return ( + + ); + })} +
+