diff --git a/src/app/design-system/page.tsx b/src/app/design-system/page.tsx
index f1b53c2..0c65a68 100644
--- a/src/app/design-system/page.tsx
+++ b/src/app/design-system/page.tsx
@@ -4,7 +4,6 @@ import Button from '@/shared/components/button/Button';
import TextButton from '@/shared/components/button/TextButton';
import Input from '@/shared/components/Input-box/Input';
import { useState } from 'react';
-import { customToast } from '@/shared/components/toast/CustomToastUtils';
import ModalLayout from '@/shared/components/modal-pop/ModalLayout';
import SelectBox from '@/domains/shared/components/select-box/SelectBox';
@@ -13,10 +12,12 @@ import LikeBtn from '@/domains/community/components/like/LikeBtn';
import Share from '@/domains/shared/components/share/Share';
import Keep from '@/domains/shared/components/keep/Keep';
import ConfirmModal from '@/shared/components/modal-pop/ConfirmModal';
+import { useToast } from '@/shared/hook/useToast';
function Page() {
const [isModalOpen, setModalOpen] = useState(false);
const [isConfirmOpen, setConfirmOpen] = useState(false);
+ const { toastSuccess, toastInfo, toastError } = useToast();
return (
@@ -78,21 +79,21 @@ function Page() {
diff --git a/src/domains/login/components/LoginRedirectHandler.tsx b/src/domains/login/components/LoginRedirectHandler.tsx
index 79d03b1..65a9c47 100644
--- a/src/domains/login/components/LoginRedirectHandler.tsx
+++ b/src/domains/login/components/LoginRedirectHandler.tsx
@@ -1,67 +1,11 @@
'use client';
-import { useEffect, useState } from 'react';
-import { usePathname, useRouter } from 'next/navigation';
-import { customToast } from '@/shared/components/toast/CustomToastUtils';
-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';
+import { useLoginRedirect } from '../hook/useAuthHooks';
function LoginRedirectHandler() {
- const pathname = usePathname();
- const router = useRouter();
- const { user, updateUser } = useAuthStore();
- const [loading, setLoading] = useState(true);
- const [welcomeModalOpen, setWelcomeModalOpen] = useState(false);
-
- useEffect(() => {
- if (!user && loading) {
- updateUser()
- .then((fetchedUser) => {
- if (!fetchedUser) {
- router.replace('/login');
- }
- })
- .catch(() => {
- router.replace('/login');
- })
- .finally(() => setLoading(false));
- } else {
- setLoading(false);
- }
- }, [user, loading, updateUser, router]);
-
- useEffect(() => {
- if (!user || loading) return;
-
- const preLoginPath = getCookie('preLoginPath') || '/';
- // 로그인 상태인데 이전 페이지가 /login이면 메인으로 이동
- if (user && preLoginPath === '/login') {
- router.replace('/');
- removeCookie('preLoginPath');
- return;
- }
-
- // 첫 유저일 경우 모달 오픈
- if (pathname.startsWith('/login/user/first-user')) {
- setWelcomeModalOpen(true);
- }
- // 기존 유저일 경우
- else if (pathname.startsWith('/login/user/success')) {
- customToast.success(`${user.nickname}님 \n 로그인 성공 🎉`);
- router.replace(preLoginPath);
- removeCookie('preLoginPath');
- }
- }, [pathname, user, loading, router]);
-
- // 환영 모달 닫힐 때 이동
- const handleCloseWelcomeModal = () => {
- setWelcomeModalOpen(false);
- const preLoginPath = getCookie('preLoginPath') || '/';
- removeCookie('preLoginPath');
- router.replace(preLoginPath);
- };
+ const { loading, welcomeModalOpen, handleCloseWelcomeModal, user } = useLoginRedirect();
if (loading) {
return (
diff --git a/src/domains/login/components/LogoutConfirm.tsx b/src/domains/login/components/LogoutConfirm.tsx
index 330f25b..8329aac 100644
--- a/src/domains/login/components/LogoutConfirm.tsx
+++ b/src/domains/login/components/LogoutConfirm.tsx
@@ -1,18 +1,23 @@
import ConfirmModal from '@/shared/components/modal-pop/ConfirmModal';
+import { useLogout } from '../hook/useAuthHooks';
interface Props {
open: boolean;
onClose: () => void;
- onLogout: () => void;
}
-function LogoutConfirm({ open, onClose, onLogout }: Props) {
+function LogoutConfirm({ open, onClose }: Props) {
+ const logoutHandler = useLogout();
+
return (
{
+ await logoutHandler();
+ onClose();
+ }}
onCancel={onClose}
/>
);
diff --git a/src/domains/login/hook/useAuthHooks.ts b/src/domains/login/hook/useAuthHooks.ts
new file mode 100644
index 0000000..6fd5a96
--- /dev/null
+++ b/src/domains/login/hook/useAuthHooks.ts
@@ -0,0 +1,75 @@
+import { useAuthStore } from '@/domains/shared/store/auth';
+import { useCallback } from 'react';
+import { useEffect, useState } from 'react';
+import { usePathname, useRouter } from 'next/navigation';
+import { getCookie, removeCookie } from '@/domains/shared/auth/utils/cookie';
+import { useToast } from '@/shared/hook/useToast';
+
+export const useLogout = () => {
+ const logout = useAuthStore((state) => state.logout);
+ const { toastSuccess, toastError } = useToast();
+
+ const handleLogout = useCallback(async () => {
+ try {
+ await logout();
+ toastSuccess('로그아웃 되었습니다.');
+ } catch (err) {
+ console.error('로그아웃 실패', err);
+ toastError('로그아웃 실패 ❌ 다시 시도해주세요.');
+ }
+ }, [logout, toastSuccess, toastError]);
+
+ return handleLogout;
+};
+
+export const useLoginRedirect = () => {
+ const router = useRouter();
+ const pathname = usePathname();
+ const { user, updateUser } = useAuthStore();
+ const { toastSuccess } = useToast();
+
+ const [loading, setLoading] = useState(true);
+ const [welcomeModalOpen, setWelcomeModalOpen] = useState(false);
+
+ useEffect(() => {
+ if (!user && loading) {
+ updateUser()
+ .then((fetchedUser) => {
+ if (!fetchedUser) router.replace('/login');
+ })
+ .catch(() => router.replace('/login'))
+ .finally(() => setLoading(false));
+ } else {
+ setLoading(false);
+ }
+ }, [user, loading, updateUser, router]);
+
+ useEffect(() => {
+ if (!user || loading) return;
+
+ const preLoginPath = getCookie('preLoginPath') || '/';
+
+ if (user && preLoginPath === '/login') {
+ router.replace('/');
+ removeCookie('preLoginPath');
+ return;
+ }
+
+ if (pathname.startsWith('/login/user/first-user')) {
+ setWelcomeModalOpen(true);
+ } else if (pathname.startsWith('/login/user/success')) {
+ toastSuccess(`${user.nickname}님 \n 로그인 성공 🎉`);
+ router.replace(preLoginPath);
+ removeCookie('preLoginPath');
+ }
+ }, [pathname, user, loading, router, toastSuccess]);
+
+ const handleCloseWelcomeModal = () => {
+ setWelcomeModalOpen(false);
+ const preLoginPath = getCookie('preLoginPath') || '/';
+ removeCookie('preLoginPath');
+ router.replace(preLoginPath);
+ };
+
+ return { loading, welcomeModalOpen, handleCloseWelcomeModal, user };
+};
diff --git a/src/domains/recommend/components/BotMessage.tsx b/src/domains/recommend/components/BotMessage.tsx
index 80652ec..d9bb2b8 100644
--- a/src/domains/recommend/components/BotMessage.tsx
+++ b/src/domains/recommend/components/BotMessage.tsx
@@ -5,6 +5,7 @@ import Image from 'next/image';
import { useState } from 'react';
import BotCocktailCard from './BotCocktailCard';
import BotOptions from './BotOptions';
+import TypingIndicator from './TypingIndicator';
interface Message {
id: string;
@@ -82,6 +83,7 @@ function BotMessage() {
)}
))}
+
);
diff --git a/src/domains/recommend/components/ChatSection.tsx b/src/domains/recommend/components/ChatSection.tsx
index 8dfc12b..de25c7e 100644
--- a/src/domains/recommend/components/ChatSection.tsx
+++ b/src/domains/recommend/components/ChatSection.tsx
@@ -4,7 +4,6 @@ import { useState } from 'react';
import BotMessage from './BotMessage';
import UserMessage from './UserMessage';
import MessageInput from './MessageInput';
-import TypingIndicator from './TypingIndicator';
function ChatSection() {
const [messages, setMessages] = useState