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
4 changes: 0 additions & 4 deletions src/api/index.ts

This file was deleted.

18 changes: 18 additions & 0 deletions src/app/api/login/set-pre-login-path/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NextRequest, NextResponse } from 'next/server';

export async function POST(req: NextRequest) {
const { path } = await req.json(); // 클라이언트가 보내는 페이지 경로
const res = NextResponse.json({ ok: true });

res.cookies.set({
name: 'preLoginPath',
value: path,
path: '/',
maxAge: 60 * 30, // 30분
httpOnly: false, // JS에서 읽을 수 있게
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
});

return res;
}
33 changes: 0 additions & 33 deletions src/shared/@store/modal.ts

This file was deleted.

39 changes: 32 additions & 7 deletions src/shared/components/auth/LoginRedirectHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
import { useEffect, useState } from 'react';
import { usePathname, useRouter } from 'next/navigation';
import { useAuthStore } from '@/shared/@store/auth';
import { useModalStore } from '@/shared/@store/modal';
import { customToast } from '@/shared/components/toast/CustomToastUtils';
import Spinner from '../spinner/Spinner';
import WelcomeModal from './WelcomeModal';
import { getCookie, removeCookie } from './utils/cookie';

function LoginRedirectHandler() {
const pathname = usePathname();
const router = useRouter();
const { user, updateUser } = useAuthStore();
const { openWelcomeModal } = useModalStore();
const [loading, setLoading] = useState(true);
const [welcomeModalOpen, setWelcomeModalOpen] = useState(false);

useEffect(() => {
if (!user && loading) {
Expand All @@ -32,15 +33,28 @@ function LoginRedirectHandler() {
useEffect(() => {
if (!user || loading) return;

const preLoginPath = sessionStorage.getItem('preLoginPath') || '/';
const preLoginPath = getCookie('preLoginPath') || '/';
console.log(preLoginPath);

// 첫 유저일 경우 모달 오픈
if (pathname.startsWith('/login/first-user')) {
openWelcomeModal(user.nickname);
} else if (pathname.startsWith('/login/success')) {
setWelcomeModalOpen(true);
}
// 기존 유저일 경우
else if (pathname.startsWith('/login/success')) {
customToast.success(`${user.nickname}님 \n 로그인 성공 🎉`);
router.replace(preLoginPath);
removeCookie('preLoginPath');
}
}, [pathname, user, router, openWelcomeModal, loading]);
}, [pathname, user, loading, router]);

// 환영 모달 닫힐 때 이동
const handleCloseWelcomeModal = () => {
setWelcomeModalOpen(false);
const preLoginPath = getCookie('preLoginPath') || '/';
removeCookie('preLoginPath');
router.replace(preLoginPath);
};

if (loading) {
return (
Expand All @@ -50,6 +64,17 @@ function LoginRedirectHandler() {
);
}

return null;
return (
<>
{/* 첫 유저 모달 */}
{user && (
<WelcomeModal
userNickname={user.nickname}
open={welcomeModalOpen}
onClose={handleCloseWelcomeModal}
/>
)}
</>
);
}
export default LoginRedirectHandler;
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ import Button from '@/shared/components/button/Button';
import ModalLayout from '@/shared/components/modalPop/ModalLayout';
import Ssury from '@/shared/assets/ssury/ssury_jump.webp';
import { useRouter } from 'next/navigation';
import { useModalStore } from '@/shared/@store/modal';
import { useAuthStore } from '@/shared/@store/auth';

function Welcome() {
const router = useRouter();
const { user } = useAuthStore();
const { welcomeModal, closeWelcomeModal } = useModalStore();
interface Props {
userNickname: string;
open: boolean;
onClose: () => void;
}

if (!welcomeModal.open || !user) return null;
function Welcome({ userNickname, open, onClose }: Props) {
const router = useRouter();

return (
<ModalLayout
open={welcomeModal.open}
onClose={closeWelcomeModal}
title={`환영합니다, ${user.nickname}님!`}
open={open}
onClose={onClose}
title={`환영합니다, ${userNickname}님!`}
description="바텐더 쑤리가 안내해드릴게요"
buttons={
<>
<Button
type="button"
color="purple"
onClick={() => {
closeWelcomeModal();
onClose();
router.push('/recipe');
}}
>
Expand All @@ -37,7 +37,7 @@ function Welcome() {
<Button
type="button"
onClick={() => {
closeWelcomeModal();
onClose();
router.push('/recommend');
}}
>
Expand Down
10 changes: 10 additions & 0 deletions src/shared/components/auth/utils/cookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function getCookie(name: string) {
if (typeof document === 'undefined') return null;
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return match ? decodeURIComponent(match[2]) : null;
}

export function removeCookie(name: string) {
if (typeof document === 'undefined') return;
document.cookie = `${name}=; path=/; max-age=0`;
}
8 changes: 8 additions & 0 deletions src/shared/components/auth/utils/setPreLoginPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export async function setPreLoginPath(path: string) {
await fetch('/api/login/set-pre-login-path', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path }), // 인자로 받은 path 사용
credentials: 'include',
});
}
5 changes: 3 additions & 2 deletions src/shared/components/header/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { usePathname } from 'next/navigation';
import { useEffect, useRef } from 'react';
import gsap from 'gsap';
import { useAuthStore } from '@/shared/@store/auth';
import { setPreLoginPath } from '../auth/utils/setPreLoginPath';

interface Props {
isClicked: boolean;
Expand Down Expand Up @@ -116,9 +117,9 @@ function DropdownMenu({ isClicked, setIsClicked }: Props) {
) : (
<Link
href="/login"
onNavigate={() => {
onNavigate={async () => {
setIsClicked(false);
sessionStorage.setItem('preLoginPath', window.location.pathname);
await setPreLoginPath(window.location.pathname);
}}
className="flex items-center gap-2 text-black font-light text-xl hover:text-black/70"
>
Expand Down
5 changes: 3 additions & 2 deletions src/shared/components/header/HeaderBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SignIn from '@/shared/assets/icons/sign_in_24.svg';
import { useRouter } from 'next/navigation';
import tw from '@/shared/utills/tw';
import { useAuthStore } from '@/shared/@store/auth';
import { setPreLoginPath } from '../auth/utils/setPreLoginPath';

type RouterType = ReturnType<typeof useRouter>;

Expand Down Expand Up @@ -39,8 +40,8 @@ function HeaderBtn({ pathname }: { pathname: string }) {
icon: SignIn,
label: '로그인',
className: `${pathname === '/login' ? 'text-tertiary' : ''}`,
onClick: () => {
sessionStorage.setItem('preLoginPath', window.location.pathname);
onClick: async () => {
await setPreLoginPath(window.location.pathname);
router.push('/login');
},
},
Expand Down
1 change: 0 additions & 1 deletion src/shared/lib/index.ts

This file was deleted.