Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion next.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { NextConfig } from 'next';

const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL;
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URI;

const nextConfig: NextConfig = {
reactStrictMode: true,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@svgr/cli": "^8.1.0",
"@tanstack/react-query": "^5.75.5",
"clsx": "^2.1.1",
"js-base64": "^3.7.7",
"next": "15.2.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
Expand Down
16 changes: 14 additions & 2 deletions src/app/(auth)/@content/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import { Spacing } from '@/components/ui/Spacing';
import Logo from '@/assets/logo.svg';
import IconKaKao from '@/assets/icons/icon-kakao.svg';
Expand All @@ -14,11 +16,21 @@ export default function LoginPage() {
<Spacing size={120} />
<section className="flex flex-col gap-3">
{/* TODO : api 연결할 때 onClick 연결 필요 */}
<button className="flex h-[45px] w-[300px] items-center justify-center rounded-md bg-[#fee500] p-[14px]">
<button
onClick={() => {
window.location.href = `${process.env.NEXT_PUBLIC_API_BASE_URI}/oauth2/authorization/kakao`;
}}
className="flex h-[45px] w-[300px] items-center justify-center rounded-md bg-[#fee500] p-[14px]"
>
<IconKaKao />
<KakaoText />
</button>
<button className="border-layout-grey4 flex h-[45px] w-[300px] items-center justify-center rounded-md border p-[14px]">
<button
onClick={() => {
window.location.href = `${process.env.NEXT_PUBLIC_API_BASE_URI}/oauth2/authorization/google`;
}}
className="border-layout-grey4 flex h-[45px] w-[300px] items-center justify-center rounded-md border p-[14px]"
>
<IconGoogle />
<GoogleText />
</button>
Expand Down
29 changes: 26 additions & 3 deletions src/app/(auth)/@content/sign-up/step3/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Spacing } from '@/components/ui/Spacing';
import { Button } from '@/components/ui/Button';
import { StepBar } from '@/components/ui/StepBar';
import { useSignupStore } from '@/stores/signUpStore';
import { useSignUp } from '@/hooks/users/useSignUp';
import IconArrowDown from '@/assets/icons/icon-arrow-down.svg';
import IconArrowBack from '@/assets/icons/icon-arrow-back.svg';

Expand Down Expand Up @@ -35,7 +36,8 @@ const category = [

export default function Step1() {
const router = useRouter();
const { preferences, setPreferences, clearPreferences } = useSignupStore();
const { username, role, preferences, setPreferences, clearPreferences } = useSignupStore();
const { mutate: signUp } = useSignUp();

const [currentIndex, setCurrentIndex] = useState(0);

Expand All @@ -52,6 +54,14 @@ export default function Step1() {
router.push('/sign-up-complete');
};

const handleSignUp = () => {
signUp({
name: username,
job: role,
tags: preferences,
});
};

return (
<section>
<div className="title-lg flex whitespace-pre-line">
Expand Down Expand Up @@ -111,11 +121,24 @@ export default function Step1() {
</div>
<Spacing size={40} />
<div className="flex w-full justify-between">
<Button size="small" state="line" onClick={handleSkipBtn}>
<Button
size="small"
state="line"
onClick={() => {
handleSkipBtn();
handleSignUp();
}}
>
건너뛰기
</Button>
{preferences.length >= 3 ? (
<Button size="small" onClick={handleNextBtn}>
<Button
size="small"
onClick={() => {
handleNextBtn();
handleSignUp();
}}
>
다음으로
</Button>
) : (
Expand Down
1 change: 0 additions & 1 deletion src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export default function AuthLayout({ content, image }: Props) {
return (
<div className="flex min-h-screen">
<div className="flex w-1/2 items-center justify-center">{content}</div>

<div className="relative w-1/2">{image}</div>
</div>
);
Expand Down
36 changes: 36 additions & 0 deletions src/app/callback/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client';

import { useEffect, Suspense } from 'react';
import { useSearchParams, useRouter } from 'next/navigation';
import { handleLoginSuccess } from '@/utils/loginHandler';

function CallbackContent() {
const searchParams = useSearchParams();
const router = useRouter();

useEffect(() => {
const type = searchParams.get('type');
const accessToken = searchParams.get('token');

switch (type) {
case 'NEW_USER':
router.replace('/sign-up/step1');
break;
case 'SUCCESS':
default:
handleLoginSuccess(accessToken);
router.replace('/advice');
break;
}
}, [searchParams, router]);

return <p>Redirecting...</p>;
}

export default function Callback() {
return (
<Suspense fallback={<p>Loading...</p>}>
<CallbackContent />
</Suspense>
);
}
13 changes: 7 additions & 6 deletions src/components/ui/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { cn } from '@/lib/utils';
Expand All @@ -8,17 +9,19 @@ import Logo from '@/assets/logo.svg';

export default function Header() {
const pathname = usePathname();
const [isLogin, setIsLogin] = useState(false);

const menus = [
{ label: '조언받기', href: '/advice' },
{ label: '찾아보기', href: '/explore' },
{ label: '보관함', href: '/archive' },
];

{
/* TODO : 쿠키에서 로그인 여부 받아서 수정할 수 있도록 하기 */
}
const isLogin = true;
useEffect(() => {
const token = localStorage.getItem('token');
const user = localStorage.getItem('user');
setIsLogin(!!(token && user));
}, []);

return (
<header className="bg-layout-grey1 mx-auto mb-[100px] flex min-w-screen items-center justify-between px-24 py-3">
Expand All @@ -29,7 +32,6 @@ export default function Header() {
<nav className="flex gap-20">
{menus.map((menu) => {
const isActive = pathname.startsWith(menu.href);

return (
<Link
key={menu.href}
Expand All @@ -51,7 +53,6 @@ export default function Header() {
<Button
variant="grey"
size="small"
// TODO : 로그아웃 연결
onClick={() => {
alert('로그아웃!');
}}
Expand Down
7 changes: 7 additions & 0 deletions src/hooks/users/useSignUp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SignupRequest, userSignUp } from '@/services/users/postSignUp';
import { useMutation } from '@tanstack/react-query';

export const useSignUp = () =>
useMutation<void, Error, SignupRequest>({
mutationFn: (data) => userSignUp(data),
});
14 changes: 14 additions & 0 deletions src/services/users/postSignUp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { customFetch } from '@/utils/customFetch';

export interface SignupRequest {
name: string;
job: string;
tags: string[];
}

export const userSignUp = async (payload: SignupRequest): Promise<void> => {
return customFetch('/users/sign-up', {
method: 'POST',
body: JSON.stringify(payload),
});
};
15 changes: 15 additions & 0 deletions src/utils/loginHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { decode } from 'js-base64';

export const handleLoginSuccess = (accessToken: string | null) => {
if (accessToken) {
const payload = accessToken.split('.')[1] || '';
const decodedPayload = decode(payload);
const payloadObject = JSON.parse(decodedPayload);
const { name: tokenName } = payloadObject;

const userInfo = { name: tokenName };

localStorage.setItem('token', accessToken);
localStorage.setItem('user', JSON.stringify(userInfo));
}
};
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3876,6 +3876,7 @@ __metadata:
eslint-plugin-react: "npm:^7.37.5"
eslint-plugin-react-hooks: "npm:^5.2.0"
husky: "npm:^9.1.7"
js-base64: "npm:^3.7.7"
lint-staged: "npm:^15.5.0"
next: "npm:15.2.4"
postcss: "npm:^8.5.3"
Expand Down Expand Up @@ -4564,6 +4565,13 @@ __metadata:
languageName: node
linkType: hard

"js-base64@npm:^3.7.7":
version: 3.7.7
resolution: "js-base64@npm:3.7.7"
checksum: 10c0/3c905a7e78b601e4751b5e710edd0d6d045ce2d23eb84c9df03515371e1b291edc72808dc91e081cb9855aef6758292a2407006f4608ec3705373dd8baf2f80f
languageName: node
linkType: hard

"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
Expand Down