100 lines
2.6 KiB
TypeScript
100 lines
2.6 KiB
TypeScript
// apps/dm/app/(landing)/reuse/apply/modal/WaterQualityRefModal.tsx (수질기준참고 모달)
|
||
"use client";
|
||
|
||
import { useEffect, useId } from "react";
|
||
import Image from "next/image";
|
||
|
||
type Props = {
|
||
open: boolean;
|
||
onClose: () => void;
|
||
imageSrc: string;
|
||
title?: string;
|
||
};
|
||
|
||
export default function WaterQualityRefModal({
|
||
open,
|
||
onClose,
|
||
imageSrc,
|
||
title = "수질 기준 참고",
|
||
}: Props) {
|
||
const titleId = useId();
|
||
|
||
useEffect(() => {
|
||
if (!open) return;
|
||
|
||
const onKeyDown = (e: KeyboardEvent) => {
|
||
if (e.key === "Escape") onClose();
|
||
};
|
||
window.addEventListener("keydown", onKeyDown);
|
||
|
||
// 스크롤 잠금
|
||
const prev = document.body.style.overflow;
|
||
document.body.style.overflow = "hidden";
|
||
|
||
return () => {
|
||
window.removeEventListener("keydown", onKeyDown);
|
||
document.body.style.overflow = prev;
|
||
};
|
||
}, [open, onClose]);
|
||
|
||
if (!open) return null;
|
||
|
||
return (
|
||
<div className="fixed inset-0 z-[120]">
|
||
{/* Backdrop */}
|
||
<button
|
||
type="button"
|
||
aria-label="닫기"
|
||
onClick={onClose}
|
||
className="absolute inset-0 bg-black/40"
|
||
/>
|
||
|
||
{/* Dialog */}
|
||
<div className="absolute inset-0 flex items-center justify-center p-4">
|
||
<div
|
||
role="dialog"
|
||
aria-modal="true"
|
||
aria-labelledby={titleId}
|
||
className="w-full max-w-[1100px] rounded-[18px] bg-white shadow-2xl overflow-hidden"
|
||
>
|
||
{/* Header */}
|
||
<div className="relative px-10 pt-9 pb-6">
|
||
<button
|
||
type="button"
|
||
onClick={onClose}
|
||
aria-label="닫기"
|
||
className="absolute right-7 top-7 h-10 w-10 grid place-items-center rounded-full hover:bg-gray-100"
|
||
>
|
||
<span className="text-2xl leading-none">×</span>
|
||
</button>
|
||
|
||
<h2
|
||
id={titleId}
|
||
className="text-left text-[28px] font-bold tracking-tight text-gray-900"
|
||
>
|
||
{title}
|
||
</h2>
|
||
|
||
<div className="mt-5 h-px w-full bg-gray-200" />
|
||
</div>
|
||
|
||
{/* Body (스크롤 영역) */}
|
||
<div className="px-10 pb-10">
|
||
<div className="max-h-[70vh] overflow-auto bg-white">
|
||
{/* 이미지가 길어도 여기서 스크롤 */}
|
||
<Image
|
||
src={imageSrc}
|
||
alt="수질 기준 참고"
|
||
width={851}
|
||
height={2334}
|
||
className="block mx-auto max-w-full h-auto"
|
||
priority
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|