diff --git a/components/ActivityDetails/ActivityDetails.tsx b/components/ActivityDetails/ActivityDetails.tsx
index cf4331e..fb96208 100644
--- a/components/ActivityDetails/ActivityDetails.tsx
+++ b/components/ActivityDetails/ActivityDetails.tsx
@@ -29,7 +29,7 @@ import { darkModeState } from '@/states/themeState';
import { ShareButton } from '../ShareButton/ShareButton';
import { ViewedActivitiesState } from '@/states/ViewedState';
import { ViewedActivityProps } from '../ViewedActivities/ViewedActivities.type';
-import useLoginState from '@/hooks/useLoginState';
+import useLoginState from '@/hooks/Auth/useLoginState';
import profileThumbnail from '@/public/image/profile-circle-icon-512x512-zxne30hp.png';
import SendChat from '../Chat/SendChat';
diff --git a/components/ActivityDetails/ImageContainer/ImageContainer.tsx b/components/ActivityDetails/ImageContainer/ImageContainer.tsx
index 384fbe7..c1336f9 100644
--- a/components/ActivityDetails/ImageContainer/ImageContainer.tsx
+++ b/components/ActivityDetails/ImageContainer/ImageContainer.tsx
@@ -5,6 +5,7 @@ import { ImageContainerProps } from './ImageContainer.types';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
import { PaginationButton } from '@/components/Button/Button';
+import { useImageModal } from '@/hooks/useImageModal';
export default function ImageContainer({
bannerImageUrl,
@@ -12,6 +13,7 @@ export default function ImageContainer({
}: ImageContainerProps) {
const defaultImage = '/image/globalnomad.png';
const filledSubImages = [...subImages];
+ const openImageModal = useImageModal();
// 빈 자리는 기본 이미지 채워 넣음
for (let i = subImages.length + 1; i <= 4; i++) {
@@ -38,8 +40,9 @@ export default function ImageContainer({
return (
-
openImageModal({ imageUrl: bannerImageUrl })}
>
-
+
{filledSubImages.map((image) => (
-
openImageModal({ imageUrl: image.imageUrl })}
>
-
+
))}
{shouldUseSlider && (
@@ -71,6 +75,7 @@ export default function ImageContainer({
{mobileImages.map((image) => (
openImageModal({ imageUrl: image.imageUrl })}
className="m:relative m:w-full m:h-[300px] outline-none"
>
(() =>
+ setImageModal({ ...ImageModal, isOpen: false })
+ );
+
+ const closeModal = () => {
+ setImageModal({ ...ImageModal, isOpen: false });
+ };
+
+ return ImageModal.isOpen && window ? (
+
+
+
+
+
+
+ ) : null;
+}
diff --git a/components/ImageModal/ImageModalProps.ts b/components/ImageModal/ImageModalProps.ts
new file mode 100644
index 0000000..47df71f
--- /dev/null
+++ b/components/ImageModal/ImageModalProps.ts
@@ -0,0 +1,6 @@
+import { ReactNode } from 'react';
+
+export interface ImageModalProps {
+ isOpen: boolean;
+ imageUrl: string;
+}
diff --git a/components/Layout/NavigationBar.tsx b/components/Layout/NavigationBar.tsx
index 6a9d6b7..c1d7937 100644
--- a/components/Layout/NavigationBar.tsx
+++ b/components/Layout/NavigationBar.tsx
@@ -9,7 +9,7 @@ import NavigationDropdown from '../NavigationDropdown/NavigationDropdown';
import useClickOutside from '@/hooks/useClickOutside';
import useGetNotification from '@/hooks/useGetNotification';
import NotificationDropdown from '../NavigationDropdown/NotificationDropdown';
-import useLoginState from '@/hooks/useLoginState';
+import useLoginState from '@/hooks/Auth/useLoginState';
import Spinner from '../Spinner/Spinner';
import profileThumbnail from '@/public/image/profile-circle-icon-512x512-zxne30hp.png';
import { useRecoilState } from 'recoil';
diff --git a/components/NavigationDropdown/NavigationDropdown.tsx b/components/NavigationDropdown/NavigationDropdown.tsx
index 7143767..b833ba4 100644
--- a/components/NavigationDropdown/NavigationDropdown.tsx
+++ b/components/NavigationDropdown/NavigationDropdown.tsx
@@ -1,4 +1,4 @@
-import useLogout from '@/hooks/useLogout';
+import useLogout from '@/hooks/Auth/useLogout';
import Link from 'next/link';
export default function NavigationDropdown() {
diff --git a/components/ReservationListCard/ReservationListCard.tsx b/components/ReservationListCard/ReservationListCard.tsx
index 9bf72a6..1951d5e 100644
--- a/components/ReservationListCard/ReservationListCard.tsx
+++ b/components/ReservationListCard/ReservationListCard.tsx
@@ -52,8 +52,8 @@ const ReservationListCard = ({ reservationData }: ReservationCardProps) => {
}
return (
-
-
+
+
-
+
{!isOpen ? (
{
+ const [imageModal, setImageModal] = useRecoilState(ImageModalState);
+
+ const openImageModal = (props: Omit) => {
+ setImageModal({
+ ...props,
+ isOpen: true,
+ });
+ };
+
+ const closeImageModal = () => {
+ setImageModal({
+ ...imageModal,
+ isOpen: false,
+ });
+ };
+
+ // 브라우저 뒤로가기 버튼이벤트 발생 시 모달 닫기
+ window.addEventListener('popstate', function (event) {
+ closeImageModal();
+ });
+
+ return openImageModal;
+};
diff --git a/hooks/useModal.ts b/hooks/useModal.ts
index 4bd5278..362a99e 100644
--- a/hooks/useModal.ts
+++ b/hooks/useModal.ts
@@ -19,5 +19,10 @@ export const useModal = () => {
});
};
+ // 브라우저 뒤로가기 버튼이벤트 발생 시 모달 닫기
+ window.addEventListener('popstate', function (event) {
+ closeModal();
+ });
+
return { openModal, closeModal };
};
diff --git a/hooks/useUserData.ts b/hooks/useUserData.ts
index 5235c44..122ccdd 100644
--- a/hooks/useUserData.ts
+++ b/hooks/useUserData.ts
@@ -1,9 +1,9 @@
import { apiMyInfo } from '@/pages/api/users/apiUsers';
-import { userDefaultState, userState } from '@/states/userState';
+import { userState } from '@/states/userState';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { useRecoilState } from 'recoil';
-import useLoginState from './useLoginState';
+import useLoginState from './Auth/useLoginState';
export const useUserData = () => {
const [userId, setUserId] = useState();
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 08ea3a5..bcdc70b 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -8,13 +8,14 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import Popup from '@/components/Popup/Popup';
import Layout from '@/components/Layout/Layout';
import Modal from '@/components/Modal/Modal';
-import SilentRefresh from '@/hooks/useSilentRefresh';
+import SilentRefresh from '@/hooks/Auth/useSilentRefresh';
import Spinner from '@/components/Spinner/Spinner';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import SidenNavigationMobile from '@/components/SideNavigation/SideNavigationMobile';
import Theme from '@/components/Theme/Theme';
import TopButton from '@/components/Button/TopButton';
+import ImageModal from '@/components/ImageModal/ImageModal';
declare global {
interface Window {
@@ -68,6 +69,7 @@ export default function App({ Component, pageProps }: AppProps) {
) : (
+
{childContent}
diff --git a/pages/calendar.tsx b/pages/calendar.tsx
index 6a3bada..d911330 100644
--- a/pages/calendar.tsx
+++ b/pages/calendar.tsx
@@ -16,7 +16,7 @@ import { darkModeState } from '@/states/themeState';
import { InitialPageMeta } from '@/components/MetaData/MetaData';
import { GetServerSideProps } from 'next';
import { SSRMetaProps } from '@/components/MetaData/MetaData.type';
-import useAuthRedirect from '@/hooks/useAuthRedirect';
+import useAuthRedirect from '@/hooks/Auth/useAuthRedirect';
export const getServerSideProps: GetServerSideProps = async () => {
const OGTitle = '예약현황 | GLOBALNOMAD';
diff --git a/pages/login.tsx b/pages/login.tsx
index 3e301ec..e45587c 100644
--- a/pages/login.tsx
+++ b/pages/login.tsx
@@ -5,9 +5,9 @@ import { loginFormValues } from '@/components/AuthInputBox/AuthInputBox.types';
import { loginValidation } from '@/components/AuthInputBox/validation';
import Link from 'next/link';
import { PrimaryButton } from '@/components/Button/Button';
-import useLogin from '@/hooks/useLogin';
+import useLogin from '@/hooks/Auth/useLogin';
import { useEffect, useMemo, useState } from 'react';
-import useLoginState from '@/hooks/useLoginState';
+import useLoginState from '@/hooks/Auth/useLoginState';
import { useRouter } from 'next/router';
import { GetServerSideProps } from 'next';
import useEnterSubmit from '@/hooks/useEnterSubmit';
diff --git a/pages/myactivity/edit.tsx b/pages/myactivity/edit.tsx
index bb229f2..ea90f65 100644
--- a/pages/myactivity/edit.tsx
+++ b/pages/myactivity/edit.tsx
@@ -6,7 +6,7 @@ import { getActivityInfo } from '../api/activities/apiactivities';
import { GetServerSideProps } from 'next';
import { InitialPageMeta } from '@/components/MetaData/MetaData';
import { SSRMetaProps } from '@/components/MetaData/MetaData.type';
-import useAuthRedirect from '@/hooks/useAuthRedirect';
+import useAuthRedirect from '@/hooks/Auth/useAuthRedirect';
export const getServerSideProps: GetServerSideProps = async () => {
const OGTitle = '내 체험 수정 | GLOBALNOMAD';
diff --git a/pages/myactivity/index.tsx b/pages/myactivity/index.tsx
index b79df71..3da2807 100644
--- a/pages/myactivity/index.tsx
+++ b/pages/myactivity/index.tsx
@@ -15,7 +15,7 @@ import { darkModeState } from '@/states/themeState';
import { InitialPageMeta } from '@/components/MetaData/MetaData';
import { GetServerSideProps } from 'next';
import { SSRMetaProps } from '@/components/MetaData/MetaData.type';
-import useAuthRedirect from '@/hooks/useAuthRedirect';
+import useAuthRedirect from '@/hooks/Auth/useAuthRedirect';
export const getServerSideProps: GetServerSideProps = async () => {
const OGTitle = '내 체험 관리 | GLOBALNOMAD';
diff --git a/pages/myactivity/register.tsx b/pages/myactivity/register.tsx
index 5806dd3..011b7fb 100644
--- a/pages/myactivity/register.tsx
+++ b/pages/myactivity/register.tsx
@@ -1,7 +1,7 @@
import { InitialPageMeta } from '@/components/MetaData/MetaData';
import { SSRMetaProps } from '@/components/MetaData/MetaData.type';
import RegisterForm from '@/components/MyActivity/Register/RegisterForm';
-import useAuthRedirect from '@/hooks/useAuthRedirect';
+import useAuthRedirect from '@/hooks/Auth/useAuthRedirect';
import { GetServerSideProps } from 'next';
export const getServerSideProps: GetServerSideProps = async () => {
diff --git a/pages/mypage.tsx b/pages/mypage.tsx
index 7b6f3c3..39fa2ef 100644
--- a/pages/mypage.tsx
+++ b/pages/mypage.tsx
@@ -3,8 +3,8 @@ import { SSRMetaProps } from '@/components/MetaData/MetaData.type';
import MyPageInput from '@/components/MyPageInput/MyPageInput';
import SidenNavigation from '@/components/SideNavigation/SideNavigation';
import SidenNavigationMobile from '@/components/SideNavigation/SideNavigationMobile';
-import useAuthRedirect from '@/hooks/useAuthRedirect';
-import useLoginState from '@/hooks/useLoginState';
+import useAuthRedirect from '@/hooks/Auth/useAuthRedirect';
+import useLoginState from '@/hooks/Auth/useLoginState';
import { useSideNavigation } from '@/hooks/useSideNavigation';
import { GetServerSideProps } from 'next';
import { useRouter } from 'next/router';
diff --git a/pages/reservation.tsx b/pages/reservation.tsx
index 744cb0a..cd1aaa9 100644
--- a/pages/reservation.tsx
+++ b/pages/reservation.tsx
@@ -18,7 +18,7 @@ import { darkModeState } from '@/states/themeState';
import { InitialPageMeta } from '@/components/MetaData/MetaData';
import { GetServerSideProps } from 'next';
import { SSRMetaProps } from '@/components/MetaData/MetaData.type';
-import useAuthRedirect from '@/hooks/useAuthRedirect';
+import useAuthRedirect from '@/hooks/Auth/useAuthRedirect';
export const getServerSideProps: GetServerSideProps = async () => {
const OGTitle = '예약내역 | GLOBALNOMAD';
@@ -87,7 +87,7 @@ export default function MyReservationPage({ OGTitle, OGUrl }: SSRMetaProps) {
)}
{reservationListByFilter.length > 0 ? (
-
+
{reservationListByFilter.map(
(reservationData: MyReservationProps) => {
return (
diff --git a/pages/signup.tsx b/pages/signup.tsx
index 32f3643..9ae9253 100644
--- a/pages/signup.tsx
+++ b/pages/signup.tsx
@@ -1,14 +1,14 @@
import AuthInputBox from '@/components/AuthInputBox/AuthInputBox';
import Image from 'next/image';
import Link from 'next/link';
-import useSignup from '@/hooks/useSignup';
+import useSignup from '@/hooks/Auth/useSignup';
import { useForm } from 'react-hook-form';
import { signUpFormValues } from '@/components/AuthInputBox/AuthInputBox.types';
import { signupValidation } from '@/components/AuthInputBox/validation';
import { PrimaryButton } from '@/components/Button/Button';
import { SignupBody } from './api/users/apiUser.types';
import { useEffect, useMemo, useState } from 'react';
-import useLoginState from '@/hooks/useLoginState';
+import useLoginState from '@/hooks/Auth/useLoginState';
import { useRouter } from 'next/router';
import { GetServerSideProps } from 'next';
import useEnterSubmit from '@/hooks/useEnterSubmit';
diff --git a/states/ImageModalState.tsx b/states/ImageModalState.tsx
new file mode 100644
index 0000000..660d4b4
--- /dev/null
+++ b/states/ImageModalState.tsx
@@ -0,0 +1,10 @@
+import { ImageModalProps } from '@/components/ImageModal/ImageModalProps';
+import { atom } from 'recoil';
+
+export const ImageModalState = atom({
+ key: 'ImageModalState',
+ default: {
+ isOpen: false,
+ imageUrl: '',
+ },
+});