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
1 change: 0 additions & 1 deletion src/app/community/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import CommunityFilter from '@/domains/community/main/CommunityFilter';
import CommunityTab from '@/domains/community/main/CommunityTab';
import PostCard from '@/domains/community/main/PostCard';
Expand Down
4 changes: 2 additions & 2 deletions src/app/design-system/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import Input from '@/shared/components/InputBox/Input';
import { useState } from 'react';
import { customToast } from '@/shared/components/toast/CustomToastUtils';
import ModalLayout from '@/shared/components/modalPop/ModalLayout';
import ConfirmPop from '@/shared/components/modalPop/ConfirmPop';
import SelectBox from '@/domains/shared/select-box/SelectBox';

import Spinner from '@/shared/components/spinner/Spinner';
import LikeBtn from '@/domains/community/components/like/LikeBtn';
import Share from '@/domains/shared/share/Share';
import Keep from '@/domains/shared/keep/Keep';
import ConfirmModal from '@/shared/components/modalPop/ConfirmModal';

function Page() {
const [isModalOpen, setModalOpen] = useState(false);
Expand Down Expand Up @@ -129,7 +129,7 @@ function Page() {
<div>모달팝업 내용</div>
</ModalLayout>

<ConfirmPop
<ConfirmModal
open={isConfirmOpen}
onClose={() => setConfirmOpen(false)}
title="Confirm제목"
Expand Down
7 changes: 0 additions & 7 deletions src/app/login/first-user/page.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/app/login/success/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import LoginRedirectHandler from '@/domains/shared/auth/LoginRedirectHandler';
import LoginRedirectHandler from '@/domains/login/components/LoginRedirectHandler';

function Page() {
return <LoginRedirectHandler />;
Expand Down
7 changes: 7 additions & 0 deletions src/app/login/user/first-user/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import LoginRedirectHandler from '@/domains/login/components/LoginRedirectHandler';

function Page() {
return <LoginRedirectHandler />;
}

export default Page;
6 changes: 6 additions & 0 deletions src/app/login/user/success/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import LoginRedirectHandler from '@/domains/login/components/LoginRedirectHandler';

function Page() {
return <LoginRedirectHandler />;
}
export default Page;
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

import { useEffect, useState } from 'react';
import { usePathname, useRouter } from 'next/navigation';

import { customToast } from '@/shared/components/toast/CustomToastUtils';

import WelcomeModal from './WelcomeModal';
import { getCookie, removeCookie } from './utils/cookie';
import { useAuthStore } from '../store/auth';
import { getCookie, removeCookie } from '@/domains/shared/auth/utils/cookie';
import { useAuthStore } from '@/domains/shared/store/auth';
import Spinner from '@/shared/components/spinner/Spinner';
import WelcomeModal from '@/domains/login/components/WelcomeModal';

function LoginRedirectHandler() {
const pathname = usePathname();
Expand All @@ -29,21 +27,28 @@ function LoginRedirectHandler() {
router.replace('/login');
})
.finally(() => setLoading(false));
} else {
setLoading(false);
}
}, [user, loading, updateUser, router]);

useEffect(() => {
if (!user || loading) return;

const preLoginPath = getCookie('preLoginPath') || '/';
console.log(preLoginPath);
// 로그인 상태인데 이전 페이지가 /login이면 메인으로 이동
if (user && preLoginPath === '/login') {
router.replace('/');
removeCookie('preLoginPath');
return;
}

// 첫 유저일 경우 모달 오픈
if (pathname.startsWith('/login/first-user')) {
if (pathname.startsWith('/login/user/first-user')) {
setWelcomeModalOpen(true);
}
// 기존 유저일 경우
else if (pathname.startsWith('/login/success')) {
else if (pathname.startsWith('/login/user/success')) {
customToast.success(`${user.nickname}님 \n 로그인 성공 🎉`);
router.replace(preLoginPath);
removeCookie('preLoginPath');
Expand Down
20 changes: 20 additions & 0 deletions src/domains/login/components/LogoutConfirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ConfirmModal from '@/shared/components/modalPop/ConfirmModal';

interface Props {
open: boolean;
onClose: () => void;
onLogout: () => void;
}

function LogoutConfirm({ open, onClose, onLogout }: Props) {
return (
<ConfirmModal
open={open}
onClose={onClose}
description="정말 로그아웃 하시겠어요?"
onConfirm={onLogout}
onCancel={onClose}
/>
);
}
export default LogoutConfirm;
4 changes: 0 additions & 4 deletions src/domains/shared/auth/LoginConfirm.tsx

This file was deleted.

108 changes: 54 additions & 54 deletions src/domains/shared/store/auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { customToast } from '@/shared/components/toast/CustomToastUtils';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';

interface User {
id: string;
Expand All @@ -21,63 +22,62 @@ interface AuthState {
updateUser: () => Promise<User | null>;
}

export const useAuthStore = create<AuthState>((set) => ({
user: null,
accessToken: null,
isLoggedIn: false,
export const useAuthStore = create<AuthState>()(
persist(
(set) => ({
user: null,
accessToken: null,
isLoggedIn: false,

loginWithProvider: (provider) => {
window.location.href = `http://localhost:8080/oauth2/authorization/${provider}`;
},
loginWithProvider: (provider) => {
window.location.href = `http://localhost:8080/oauth2/authorization/${provider}`;
},

setUser: (user, token) => {
const updatedUser = { ...user, abv_degree: 5.0 };
set({ user: updatedUser, accessToken: token, isLoggedIn: true });
setUser: (user, token) => {
const updatedUser = { ...user, abv_degree: 5.0 };
set({ user: updatedUser, accessToken: token, isLoggedIn: true });
customToast.success(`${updatedUser.nickname}님, 로그인 성공 🎉`);
},

customToast.success(`${updatedUser.nickname}님, 로그인 성공 🎉`);
},
logout: async () => {
try {
await fetch('http://localhost:8080/user/auth/logout', {
method: 'POST',
credentials: 'include',
});
customToast.success('로그아웃 되었습니다.');
set({ user: null, accessToken: null, isLoggedIn: false });
} catch (err) {
customToast.error('로그아웃 실패❌ \n 다시 시도해주세요.');
console.error('로그아웃 실패', err);
}
},

logout: async () => {
try {
await fetch('http://localhost:8080/user/auth/logout', {
method: 'POST',
credentials: 'include',
});
updateUser: async () => {
try {
const res = await fetch('http://localhost:8080/user/auth/refresh', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
});

customToast.success('로그아웃 되었습니다.');
set({ user: null, accessToken: null, isLoggedIn: false });
} catch (err) {
customToast.error('로그아웃 실패❌ \n 다시 시도해주세요.');
console.error('로그아웃 실패', err);
}
},
if (!res.ok) throw new Error('토큰 갱신 실패');
const data = await res.json();
const userInfo = data?.data?.user;
const accessToken = data?.data?.accessToken;

updateUser: async () => {
try {
const res = await fetch('http://localhost:8080/user/auth/refresh', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
});

if (!res.ok) throw new Error('토큰 갱신 실패');
const data = await res.json();

console.log('updateUser response:', data);
const userInfo = data?.data?.user;
const accessToken = data?.data?.accessToken;

if (userInfo && accessToken) {
set({ user: userInfo, accessToken, isLoggedIn: true });
console.log('토큰 및 유저 정보 갱신 완료:', userInfo);
return userInfo;
}

return null;
} catch (err) {
console.error('updateUser 실패', err);
set({ accessToken: null, user: null, isLoggedIn: false });
return null;
}
},
}));
if (userInfo && accessToken) {
set({ user: userInfo, accessToken, isLoggedIn: true });
return userInfo;
}
return null;
} catch (err) {
console.error('updateUser 실패', err);
set({ accessToken: null, user: null, isLoggedIn: false });
return null;
}
},
}),
{ name: 'auth-storage' } // localStorage key
)
);
Loading