Skip to content

Commit 6640d7d

Browse files
committed
refactor: 각 모달의 배경색 ModalLayout 에서 처리, 모달 밖을 클릭시 자동으로 닫히게 수정, 배경 스크롤 방지
1 parent 000162b commit 6640d7d

File tree

9 files changed

+444
-469
lines changed

9 files changed

+444
-469
lines changed

src/app/components/modal/ModalLayout.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ChangePasswordModal from "./modals/form/ChangePasswordModal";
99
import EditMyProfileModal from "./modals/form/EditMyProfileModal";
1010
import EditOwnerProfileModal from "./modals/form/EditOwnerProfileModal";
1111
import { ModalType } from "@/types/modal";
12+
import { useEffect } from "react";
1213

1314
// 모달 컴포넌트 매핑
1415
const ModalComponents = {
@@ -25,6 +26,20 @@ const ModalComponents = {
2526
const ModalLayout = () => {
2627
const { isOpen, modalType, modalProps, closeModal } = useModalStore();
2728

29+
// 모달이 열릴 때 body 스크롤 방지
30+
useEffect(() => {
31+
if (isOpen) {
32+
document.body.style.overflow = "hidden";
33+
} else {
34+
document.body.style.overflow = "unset";
35+
}
36+
37+
// 컴포넌트가 언마운트될 때 스크롤 상태 복구
38+
return () => {
39+
document.body.style.overflow = "unset";
40+
};
41+
}, [isOpen]);
42+
2843
if (!isOpen || !modalType || !modalProps) return null;
2944

3045
if (!Object.keys(ModalComponents).includes(modalType)) {
@@ -36,12 +51,14 @@ const ModalLayout = () => {
3651

3752
return createPortal(
3853
<div
39-
className="fixed inset-0 z-50 flex items-center justify-center bg-gray-100/50 p-4"
54+
className="bg-black/50 fixed inset-0 z-50 flex items-center justify-center p-4"
4055
onClick={(e) => {
4156
if (e.target === e.currentTarget) closeModal();
4257
}}
58+
role="dialog"
59+
aria-modal="true"
4360
>
44-
<div className="w-full max-w-md rounded-2xl">
61+
<div className="w-full max-w-md" onClick={(e) => e.stopPropagation()}>
4562
<ModalComponent isOpen={isOpen} onClose={closeModal} {...(modalProps as any)} />
4663
</div>
4764
</div>,

src/app/components/modal/modals/alert/ApplicationDetailModal.tsx

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -51,71 +51,69 @@ const ApplicationDetailModal = ({
5151
];
5252

5353
return (
54-
<div className="bg-black/50 fixed inset-0 z-50 flex items-center justify-center p-4">
55-
<div
56-
className={cn(
57-
"relative h-[544px] w-[375px] overflow-hidden rounded-3xl bg-white p-6 md:h-[668px] md:w-[440px]",
58-
className
59-
)}
60-
>
61-
<div className="flex h-full flex-col">
62-
<div className="mb-6 md:mb-8">
63-
<div className="text-lg font-semibold md:text-2xl">내 지원 내역</div>
64-
</div>
65-
66-
<div className="flex-1">
67-
<div className="space-y-4 md:space-y-5">
68-
{applicationDate && (
69-
<div className="flex items-center justify-between text-sm md:text-base">
70-
<span className="text-muted-foreground">지원일시</span>
71-
<span>{formatDateTime(applicationDate)}</span>
72-
</div>
73-
)}
54+
<div
55+
className={cn(
56+
"relative h-[544px] w-[375px] overflow-hidden rounded-3xl bg-white p-6 md:h-[668px] md:w-[440px]",
57+
className
58+
)}
59+
>
60+
<div className="flex h-full flex-col">
61+
<div className="mb-6 md:mb-8">
62+
<div className="text-lg font-semibold md:text-2xl">내 지원 내역</div>
63+
</div>
7464

75-
{applicationStatus && (
76-
<div className="flex items-center justify-between text-sm md:text-base">
77-
<span className="text-muted-foreground">진행 상태</span>
78-
<span className="rounded bg-primary-orange-50 px-2 py-1 font-semibold text-primary-orange-300">
79-
{applicationStatus}
80-
</span>
81-
</div>
82-
)}
83-
</div>
65+
<div className="flex-1">
66+
<div className="space-y-4 md:space-y-5">
67+
{applicationDate && (
68+
<div className="flex items-center justify-between text-sm md:text-base">
69+
<span className="text-muted-foreground">지원일시</span>
70+
<span>{formatDateTime(applicationDate)}</span>
71+
</div>
72+
)}
8473

85-
<div className="mt-6 space-y-4 md:mt-8 md:space-y-6">
86-
{defaultFields.map((field) => (
87-
<div key={field.name} className="space-y-2">
88-
<label htmlFor={field.name} className="text-muted-foreground block text-sm md:text-base">
89-
{field.label}
90-
</label>
91-
<ReadOnlyInput
92-
name={field.name}
93-
type={field.type}
94-
value={field.value}
95-
size="w-full h-[48px] md:h-[54px]"
96-
/>
97-
</div>
98-
))}
99-
</div>
74+
{applicationStatus && (
75+
<div className="flex items-center justify-between text-sm md:text-base">
76+
<span className="text-muted-foreground">진행 상태</span>
77+
<span className="rounded bg-primary-orange-50 px-2 py-1 font-semibold text-primary-orange-300">
78+
{applicationStatus}
79+
</span>
80+
</div>
81+
)}
10082
</div>
10183

102-
<div className="mt-6 md:mt-8">
103-
<Link href={`/forms/${formId}`} className="block">
104-
<Button type="button" className="h-[48px] w-full text-base font-medium md:h-[54px] md:text-lg">
105-
지원 내역 상세보기
106-
</Button>
107-
</Link>
84+
<div className="mt-6 space-y-4 md:mt-8 md:space-y-6">
85+
{defaultFields.map((field) => (
86+
<div key={field.name} className="space-y-2">
87+
<label htmlFor={field.name} className="text-muted-foreground block text-sm md:text-base">
88+
{field.label}
89+
</label>
90+
<ReadOnlyInput
91+
name={field.name}
92+
type={field.type}
93+
value={field.value}
94+
size="w-full h-[48px] md:h-[54px]"
95+
/>
96+
</div>
97+
))}
10898
</div>
99+
</div>
109100

110-
<button
111-
onClick={onClose}
112-
aria-label="모달 닫기"
113-
className="absolute right-4 top-4 flex h-8 w-8 items-center justify-center rounded-full bg-white text-gray-400 hover:text-gray-600"
114-
>
115-
<Image src="/icons/x/x-sm.svg" alt="" width={16} height={16} className="block sm:hidden" />
116-
<Image src="/icons/x/x-md.svg" alt="" width={20} height={20} className="hidden sm:block" />
117-
</button>
101+
<div className="mt-6 md:mt-8">
102+
<Link href={`/forms/${formId}`} className="block">
103+
<Button type="button" className="h-[48px] w-full text-base font-medium md:h-[54px] md:text-lg">
104+
지원 내역 상세보기
105+
</Button>
106+
</Link>
118107
</div>
108+
109+
<button
110+
onClick={onClose}
111+
aria-label="모달 닫기"
112+
className="absolute right-4 top-4 flex h-8 w-8 items-center justify-center rounded-full bg-white text-gray-400 hover:text-gray-600"
113+
>
114+
<Image src="/icons/x/x-sm.svg" alt="" width={16} height={16} className="block sm:hidden" />
115+
<Image src="/icons/x/x-md.svg" alt="" width={20} height={20} className="hidden sm:block" />
116+
</button>
119117
</div>
120118
</div>
121119
);

src/app/components/modal/modals/alert/FormContinueModal.tsx

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,50 +13,46 @@ const FormContinueModal = ({ isOpen, onClose, className }: FormContinueModalProp
1313
if (!isOpen) return null;
1414

1515
return (
16-
<div className="bg-black/50 fixed inset-0 z-50 flex items-center justify-center p-4">
17-
<div
18-
className={cn("h-[284px] w-[375px] rounded-3xl bg-white p-6 shadow-lg md:h-[384px] md:w-[520px]", className)}
19-
>
20-
<div className="relative h-full">
21-
<button
22-
onClick={onClose}
23-
className="absolute right-0 top-0 flex items-center justify-center text-gray-400 hover:text-gray-600"
24-
>
25-
<Image src="/icons/x/x-sm.svg" alt="close" width={16} height={16} className="block sm:hidden" />
26-
<Image src="/icons/x/x-md.svg" alt="close" width={20} height={20} className="hidden sm:block" />
27-
</button>
28-
<div className="flex h-full flex-col items-center py-4 text-center md:py-6">
29-
<div className="flex items-center justify-center">
30-
<div className="relative h-20 w-20 md:h-[120px] md:w-[120px]">
31-
<Image
32-
src="/images/modal/closed-orange-sm.svg"
33-
alt="warning"
34-
width={80}
35-
height={80}
36-
className="block sm:hidden"
37-
/>
38-
<Image
39-
src="/images/modal/closed-orange-md.svg"
40-
alt="warning"
41-
width={120}
42-
height={120}
43-
className="hidden sm:block"
44-
/>
45-
</div>
16+
<div className={cn("h-[284px] w-[375px] rounded-3xl bg-white p-6 shadow-lg md:h-[384px] md:w-[520px]", className)}>
17+
<div className="relative h-full">
18+
<button
19+
onClick={onClose}
20+
className="absolute right-0 top-0 flex items-center justify-center text-gray-400 hover:text-gray-600"
21+
>
22+
<Image src="/icons/x/x-sm.svg" alt="close" width={16} height={16} className="block sm:hidden" />
23+
<Image src="/icons/x/x-md.svg" alt="close" width={20} height={20} className="hidden sm:block" />
24+
</button>
25+
<div className="flex h-full flex-col items-center py-4 text-center md:py-6">
26+
<div className="flex items-center justify-center">
27+
<div className="relative h-20 w-20 md:h-[120px] md:w-[120px]">
28+
<Image
29+
src="/images/modal/closed-orange-sm.svg"
30+
alt="warning"
31+
width={80}
32+
height={80}
33+
className="block sm:hidden"
34+
/>
35+
<Image
36+
src="/images/modal/closed-orange-md.svg"
37+
alt="warning"
38+
width={120}
39+
height={120}
40+
className="hidden sm:block"
41+
/>
4642
</div>
47-
<h2 className="mb-2 text-lg font-bold md:text-xl">작성 중인 알바폼이 있어요!</h2>
48-
<p className="mb-6 text-sm text-gray-600 md:text-base">이어서 작성하시겠어요?</p>
43+
</div>
44+
<h2 className="mb-2 text-lg font-bold md:text-xl">작성 중인 알바폼이 있어요!</h2>
45+
<p className="mb-6 text-sm text-gray-600 md:text-base">이어서 작성하시겠어요?</p>
4946

50-
<div className="mt-auto">
51-
<Link href="/" className="block">
52-
<Button
53-
type="button"
54-
className="h-[58px] w-[327px] text-base font-medium md:h-[72px] md:w-[360px] md:text-lg"
55-
>
56-
이어쓰기
57-
</Button>
58-
</Link>
59-
</div>
47+
<div className="mt-auto">
48+
<Link href="/" className="block">
49+
<Button
50+
type="button"
51+
className="h-[58px] w-[327px] text-base font-medium md:h-[72px] md:w-[360px] md:text-lg"
52+
>
53+
이어쓰기
54+
</Button>
55+
</Link>
6056
</div>
6157
</div>
6258
</div>

src/app/components/modal/modals/alert/RecruitmentClosedModal.tsx

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,50 +14,46 @@ const RecruitmentClosedModal = ({ formId, isOpen, onClose, className }: Recruitm
1414
if (!isOpen) return null;
1515

1616
return (
17-
<div className="bg-black/50 fixed inset-0 z-50 flex items-center justify-center p-4">
18-
<div
19-
className={cn("h-[284px] w-[375px] rounded-3xl bg-white p-6 shadow-lg md:h-[384px] md:w-[520px]", className)}
20-
>
21-
<div className="relative h-full">
22-
<button
23-
onClick={onClose}
24-
className="absolute right-0 top-0 flex items-center justify-center text-gray-400 hover:text-gray-600"
25-
>
26-
<Image src="/icons/x/x-sm.svg" alt="close" width={16} height={16} className="block sm:hidden" />
27-
<Image src="/icons/x/x-md.svg" alt="close" width={20} height={20} className="hidden sm:block" />
28-
</button>
29-
<div className="flex h-full flex-col items-center py-4 text-center md:py-6">
30-
<div className="flex items-center justify-center">
31-
<div className="relative h-20 w-20 md:h-[120px] md:w-[120px]">
32-
<Image
33-
src="/images/modal/closed-orange-sm.svg"
34-
alt="warning"
35-
width={80}
36-
height={80}
37-
className="block sm:hidden"
38-
/>
39-
<Image
40-
src="/images/modal/closed-orange-md.svg"
41-
alt="warning"
42-
width={120}
43-
height={120}
44-
className="hidden sm:block"
45-
/>
46-
</div>
17+
<div className={cn("h-[284px] w-[375px] rounded-3xl bg-white p-6 shadow-lg md:h-[384px] md:w-[520px]", className)}>
18+
<div className="relative h-full">
19+
<button
20+
onClick={onClose}
21+
className="absolute right-0 top-0 flex items-center justify-center text-gray-400 hover:text-gray-600"
22+
>
23+
<Image src="/icons/x/x-sm.svg" alt="close" width={16} height={16} className="block sm:hidden" />
24+
<Image src="/icons/x/x-md.svg" alt="close" width={20} height={20} className="hidden sm:block" />
25+
</button>
26+
<div className="flex h-full flex-col items-center py-4 text-center md:py-6">
27+
<div className="flex items-center justify-center">
28+
<div className="relative h-20 w-20 md:h-[120px] md:w-[120px]">
29+
<Image
30+
src="/images/modal/closed-orange-sm.svg"
31+
alt="warning"
32+
width={80}
33+
height={80}
34+
className="block sm:hidden"
35+
/>
36+
<Image
37+
src="/images/modal/closed-orange-md.svg"
38+
alt="warning"
39+
width={120}
40+
height={120}
41+
className="hidden sm:block"
42+
/>
4743
</div>
48-
<h2 className="mb-2 text-lg font-bold md:text-xl">모집 마감</h2>
49-
<p className="mb-6 text-sm text-gray-600 md:text-base">모집이 종료된 알바폼입니다.</p>
44+
</div>
45+
<h2 className="mb-2 text-lg font-bold md:text-xl">모집 마감</h2>
46+
<p className="mb-6 text-sm text-gray-600 md:text-base">모집이 종료된 알바폼입니다.</p>
5047

51-
<div className="mt-auto">
52-
<Link href={`/forms/${formId}`} className="block">
53-
<Button
54-
type="button"
55-
className="h-[58px] w-[327px] text-base font-medium md:h-[72px] md:w-[360px] md:text-lg"
56-
>
57-
홈으로 가기
58-
</Button>
59-
</Link>
60-
</div>
48+
<div className="mt-auto">
49+
<Link href={`/forms/${formId}`} className="block">
50+
<Button
51+
type="button"
52+
className="h-[58px] w-[327px] text-base font-medium md:h-[72px] md:w-[360px] md:text-lg"
53+
>
54+
홈으로 가기
55+
</Button>
56+
</Link>
6157
</div>
6258
</div>
6359
</div>

0 commit comments

Comments
 (0)