Skip to content

Commit

Permalink
Merge pull request #144 from epigram5-9/merge/FE-54
Browse files Browse the repository at this point in the history
FE-54๐Ÿ”€๋ธŒ๋žœ์น˜ ์ตœ์‹ 
  • Loading branch information
jisurk authored Aug 1, 2024
2 parents c7c540b + 156686f commit c1ab854
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 29 deletions.
11 changes: 11 additions & 0 deletions src/apis/postGoogleOauth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import httpClient from '.';

const postGoogleOauth = async (code: string) => {
const response = await httpClient.post('/auth/signIn/GOOGLE', {
redirectUri: process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI,
token: code,
});
return response.data;
};

export default postGoogleOauth;
12 changes: 12 additions & 0 deletions src/apis/postNaverOauth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import httpClient from '.';

const postNaverOauth = async (code: string, state: string) => {
const response = await httpClient.post('/auth/signIn/NAVER', {
state,
redirectUri: process.env.NEXT_PUBLIC_NAVER_REDIRECT_URI,
token: code,
});
return response.data;
};

export default postNaverOauth;
12 changes: 9 additions & 3 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import SHARE_ICON from '../../../public/icon/share-icon.svg';
// NOTE isButton ์ผ ๊ฒฝ์šฐ textInButton์˜ ๊ฐ’์„ ๋ฌด์กฐ๊ฑด ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
// NOTE SHARE_ICON ์ถ”๊ฐ€ ์‹œ ํ† ์ŠคํŠธ ๊ธฐ๋Šฅ๋„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์•„๋ž˜ <Toaster /> ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

// TODO ์ƒˆ๋กœ ๋ฐ”๋€ ํ”ผ๊ทธ๋งˆ ์‹œ์•ˆ์œผ๋กœ ๋ฐ”๊ฟ€์ง€ ์ถ”ํ›„ ๊ฒฐ์ •

export interface HeaderProps {
icon: 'back' | 'search' | '';
routerPage: string;
isLogo: boolean;
insteadOfLogo: string;
isProfileIcon: boolean;
Expand All @@ -31,10 +32,15 @@ export interface HeaderProps {
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
}

function Header({ isLogo, icon, insteadOfLogo, isButton, isProfileIcon, isShareIcon, textInButton, routerPage, disabled, onClick }: HeaderProps) {
function Header({ isLogo, icon, insteadOfLogo, isButton, isProfileIcon, isShareIcon, textInButton, disabled, onClick }: HeaderProps) {
const router = useRouter();
const { toast } = useToast();

// ๋’ค๋กœ๊ฐ€๊ธฐ
const handleBack = () => {
router.back();
};

// ํŽ˜์ด์ง€ ์ด๋™ ํ•จ์ˆ˜
const handleNavigateTo = (path: string) => {
router.push(path);
Expand Down Expand Up @@ -65,7 +71,7 @@ function Header({ isLogo, icon, insteadOfLogo, isButton, isProfileIcon, isShareI
<div className='container flex justify-between items-center'>
<div className='flex items-center space-x-4'>
{icon === 'back' && (
<button className='w-5 h-5 lg:w-9 lg:h-9' type='button' onClick={() => handleNavigateTo(routerPage)} aria-label='๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ'>
<button className='w-5 h-5 lg:w-9 lg:h-9' type='button' onClick={handleBack} aria-label='๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ'>
<Image src={ARROW_LEFT_ICON} alt='๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ ์ด๋ฏธ์ง€' />
</button>
)}
Expand Down
13 changes: 1 addition & 12 deletions src/components/epigram/EditEpigram.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,7 @@ function EditEpigram({ epigram }: EditEpigramProps) {

return (
<>
<Header
icon='back'
routerPage={`/epigrams/${epigram.id}`}
isLogo
insteadOfLogo='์—ํ”ผ๊ทธ๋žจ ์ˆ˜์ •'
isProfileIcon
isShareIcon={false}
isButton={false}
textInButton=''
disabled={false}
onClick={() => {}}
/>
<Header icon='back' isLogo insteadOfLogo='์—ํ”ผ๊ทธ๋žจ ์ˆ˜์ •' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<div className='border-t-2 w-full flex flex-col justify-center items-center'>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className='flex flex-col justify-center item-center gap-6 lg:gap-8 w-[312px] md:w-[384px] lg:w-[640px] py-6'>
Expand Down
41 changes: 41 additions & 0 deletions src/hooks/useGoogleLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import postGoogleOauth from '@/apis/postGoogleOauth';
import { toast } from '@/components/ui/use-toast';
import { useMutation } from '@tanstack/react-query';
import { isAxiosError } from 'axios';
import { useRouter } from 'next/router';

const useGoogleLogin = () => {
const router = useRouter();

return useMutation({
mutationFn: async (code: string) => {
const result = await postGoogleOauth(code);
localStorage.setItem('accessToken', result.accessToken);
localStorage.setItem('refreshToken', result.refreshToken);
return result;
},
onSuccess: () => {
router.push('/epigrams');
},
onError: (error) => {
if (isAxiosError(error)) {
const status = error.response?.status;

if (!status) return;

if (status === 400) {
toast({ description: '์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์„ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.', className: 'bg-state-error text-white font-semibold' });
router.push('/auth/SignIn');
return;
}

if (status >= 500) {
toast({ description: '์„œ๋ฒ„์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”.', className: 'bg-state-error text-white font-semibold' });
}
}
toast({ description: '์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.', className: 'bg-state-error text-white font-semibold' });
},
});
};

export default useGoogleLogin;
2 changes: 1 addition & 1 deletion src/hooks/useKakaoLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const useKakaoLogin = () => {
return result;
},
onSuccess: () => {
router.push('/');
router.push('/epigrams');
},
onError: (error) => {
if (isAxiosError(error)) {
Expand Down
42 changes: 42 additions & 0 deletions src/hooks/useNaverLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import postNaverOauth from '@/apis/postNaverOauth';
import { toast } from '@/components/ui/use-toast';
import { useMutation } from '@tanstack/react-query';
import { isAxiosError } from 'axios';
import { useRouter } from 'next/router';

const useNaverLogin = () => {
const router = useRouter();

return useMutation({
mutationFn: async ({ code, state }: { code: string; state: string }) => {
const result = await postNaverOauth(code, state);
localStorage.setItem('accessToken', result.accessToken);
localStorage.setItem('refreshToken', result.refreshToken);
return result;
},
onSuccess: () => {
router.push('/epigrams');
},
onError: (error) => {
if (isAxiosError(error)) {
const status = error.response?.status;

if (!status) return;

if (status === 400) {
toast({ description: '์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์„ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.', className: 'bg-state-error text-white font-semibold' });
router.push('/auth/SignIn');
return;
}

if (status >= 500) {
toast({ description: '์„œ๋ฒ„์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”.', className: 'bg-state-error text-white font-semibold' });
}
}

toast({ description: '์•Œ ์ˆ˜ ์—†๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.', className: 'bg-state-error text-white font-semibold' });
},
});
};

export default useNaverLogin;
33 changes: 30 additions & 3 deletions src/hooks/useSignInMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { postSignin } from '@/apis/auth';
import { toast } from '@/components/ui/use-toast';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import { isAxiosError } from 'axios';

const useSigninMutation = () => {
const router = useRouter();
Expand All @@ -11,10 +12,36 @@ const useSigninMutation = () => {
onSuccess: (data) => {
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
router.push('/');
router.push('/epigrams');
},
onError: () => {
toast({ description: '์ด๋ฉ”์ผ ํ˜น์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.', className: 'border-state-error text-state-error font-semibold' });
onError: (error) => {
if (!isAxiosError(error)) {
return;
}

const { status } = error.response || {};

if (status === 500) {
toast({
description: '์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.',
className: 'border-state-error text-state-error font-semibold',
});
return;
}

// NOTE: status๊ฐ’์€ ํ•ญ์ƒ ์žˆ์œผ๋ฉฐ undefined์™€ ์ˆซ์ž๋ฅผ ๋น„๊ต์—ฐ์‚ฐ ํ•  ์ˆ˜ ์—†์–ด Number๋กœ ์„ค์ •
if (Number(status) >= 500) {
toast({
description: '์„œ๋ฒ„์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.',
className: 'border-state-error text-state-error font-semibold',
});
return;
}

toast({
description: '์ด๋ฉ”์ผ ํ˜น์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.',
className: 'border-state-error text-state-error font-semibold',
});
},
});
};
Expand Down
2 changes: 1 addition & 1 deletion src/pageLayout/Epigram/AddEpigram.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function AddEpigram() {

return (
<>
<Header icon='search' routerPage='/search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<div className='border-t-2 w-full flex flex-col justify-center items-center'>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className='flex flex-col justify-center item-center gap-6 lg:gap-8 w-[312px] md:w-[384px] lg:w-[640px] py-6'>
Expand Down
2 changes: 1 addition & 1 deletion src/pageLayout/Epigrams/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import FAB from '@/components/main/FAB';
function MainLayout() {
return (
<>
<Header icon='search' routerPage='/.' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<main className='w-full min-h-screen bg-background-100 flex flex-col items-center'>
<div className='w-[360px] flex flex-col items-center gap-6 mt-10 mb-40'>
<section className='mt-10'>
Expand Down
2 changes: 1 addition & 1 deletion src/pageLayout/MypageLayout/MyPageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function MyPageLayout() {

return (
<div className='bg-background-100 w-full relative h-dvh'>
<Header icon='back' routerPage='/mypage' isLogo={false} insteadOfLogo='' isProfileIcon={false} isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<Header icon='back' isLogo={false} insteadOfLogo='' isProfileIcon={false} isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<div className='bg-background-100 w-full h-[200px]'></div>
<div className='w-full flex flex-col items-center bg-blue-100 rounded-3xl relative shadow-3xl'>
<Profile image={data.image} nickname={data.nickname} />
Expand Down
2 changes: 1 addition & 1 deletion src/pageLayout/SearchLayout/SearchLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function SearchLayout() {

return (
<>
<Header icon='search' routerPage='/search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />;
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />;
<div className='container mx-auto max-w-screen-sm bg-blue-100'>
<SearchBar onSearch={handleSearch} currentSearch={currentSearch} />
<RecentSearches searches={searches} onSearch={handleSearch} onClear={handleClearAll} />
Expand Down
15 changes: 10 additions & 5 deletions src/pages/auth/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,24 @@ export default function SignIn() {
</Form>
<div className=' flex justify-end items-center gap-2 w-full lg:max-w-[640px] md:max-w-[384px] md:px-0 px-6 md:mb-[60px] mb-[50px]'>
<h2 className=' text-blue-400 lg:text-xl md:text-base sm:text-sm'>ํšŒ์›์ด ์•„๋‹ˆ์‹ ๊ฐ€์š”?</h2>
<Link href='/'>
<Link href='/auth/SignUp'>
<Button type='button' variant='link' className='lg:text-xl md:text-base sm:text-sm p-0 underline'>
๊ฐ€์ž…ํ•˜๊ธฐ
</Button>
</Link>
</div>
<div className='flex gap-4'>
<Link href={`https://nid.naver.com/oauth2.0/authorize?client_id=${process.env.NEXT_PUBLIC_NAVER_CLIENT_ID}&redirect_uri=http://localhost:3000&response_type=code`}>
<Link
href={`https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${process.env.NEXT_PUBLIC_NAVER_CLIENT_ID}&state=${'test'}&redirect_uri=${process.env.NEXT_PUBLIC_NAVER_REDIRECT_URI}`}
>
<Image src='/logo-naver.svg' alt='logo-naver' width={60} height={60} className='md:size-[60px] size-10' />
</Link>
<Link href={`https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&redirect_uri=http://localhost:3000&response_type=code&scope=email%20profile`}>
<Image src='/logo-google.svg' alt='logo-google' width={60} height={60} className='md:size-[60px] size-10' />
</Link>
{/* // FIXME: ๊ตฌ๊ธ€ ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์‹œ 500์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ถ€๋ถ„์œผ๋กœ ์ฃผ์„ ์ฒ˜๋ฆฌํ•˜์˜€์Œ */}
{/* <Link
href={`https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}&response_type=code&scope=email%20profile`}
> */}
<Image src='/logo-google.svg' alt='logo-google' width={60} height={60} className='md:size-[60px] size-10' />
{/* </Link> */}
<Link href={`https://kauth.kakao.com/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_KAKAO_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_REDIRECT_URI}&response_type=code`}>
<Image src='/logo-kakao.svg' alt='logo-kakao' width={60} height={60} className='md:size-[60px] size-10' />
</Link>
Expand Down
21 changes: 21 additions & 0 deletions src/pages/auth/redirect/google-callback/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect } from 'react';
import { useSearchParams } from 'next/navigation';
import useGoogleLogin from '@/hooks/useGoogleLogin';

export default function Google() {
const searchParams = useSearchParams();
const code = searchParams.get('code');
const { mutate: login } = useGoogleLogin();

useEffect(() => {
if (code) {
login(code);
} else {
/* eslint-disable no-console */
console.log(code); // code๊ฐ€ ์—†์„ ๋•Œ ์ฝ˜์†”์— ์ถœ๋ ฅ
}
}, [code, login]);
}

// code๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์˜ ์˜ˆ์‹œ http://localhost:3000/auth/redirect/kakao
// ํ† ์ŠคํŠธ๋กœ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ณ , ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
19 changes: 19 additions & 0 deletions src/pages/auth/redirect/naver/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import useNaverLogin from '@/hooks/useNaverLogin';
import { useSearchParams } from 'next/navigation';
import { useEffect } from 'react';

export default function Naver() {
const searchParams = useSearchParams();
const code = searchParams.get('code');
const state = searchParams.get('state');
const { mutate: login } = useNaverLogin();

useEffect(() => {
if (code && state) {
login({ code, state });
} else {
/* eslint-disable no-console */
console.log(code, state); // code๊ฐ€ ์—†์„ ๋•Œ ์ฝ˜์†”์— ์ถœ๋ ฅ
}
}, [code, state, login]);
}
2 changes: 1 addition & 1 deletion src/pages/epigrams/[id]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function DetailPage() {

return (
<div className='flex flex-col '>
<Header icon='search' routerPage='/search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<Header icon='search' isLogo insteadOfLogo='' isProfileIcon isShareIcon={false} isButton={false} textInButton='' disabled={false} onClick={() => {}} />
<EpigramFigure epigram={epigram} currentUserId={userData?.id} />
<EpigramComment epigramId={epigram.id} currentUserId={userData?.id} userImage={userData?.image} />
</div>
Expand Down

0 comments on commit c1ab854

Please sign in to comment.