wr: 지도팝업 작업계획

This commit is contained in:
2026-06-26 10:01:10 +09:00
parent 07db5b1fbd
commit 1ead18b53c
2 changed files with 311 additions and 8 deletions
@@ -1,3 +1,6 @@
/**
* 지도에서 feature 선택시 팝업
*/
"use client";
import { useWrStore } from "@/app/store";
import CoSttnDetailPopup from "@/components/ui/map/detailPopup/coSttnDetailPopup/coSttnDetailPopup";
@@ -20,7 +23,7 @@ export default function MapFeaturePopup() {
coSttnMapDetail
} = useWrStore((state) => state);
const { pbnMapHeadList } = pbnMap;
const [isDetail, setIsDetail] = useState<any>(undefined);
const [isDetail, setIsDetail] = useState<any>(undefined); // isFeatureCd && layerNm
const [layerNm, setLayerNm] = useState<string>();
const searchParams = useSearchParams();
@@ -57,32 +60,32 @@ export default function MapFeaturePopup() {
useEffect(() => {
console.log(' layerNm ' , layerNm)
if (isFeatureCd && layerNm) {
if (layerNm === "tb_wr_bdst_ruse_fclt") {
if (layerNm === "tb_wr_bdst_ruse_fclt") { // 하수재이용시설
setIsDetail(isFeatureCd);
} else if (layerNm === "tb_il_swage_prcs_fclt") {
} else if (layerNm === "tb_il_swage_prcs_fclt") { // 하수처리시설
pbnMapDetaile(isFeatureCd).then((res) => {
console.log('res', res)
setIsDetail([res]);
});
} else if (layerNm === "tb_wr_rnwtr_utztn_fclt") {
} else if (layerNm === "tb_wr_rnwtr_utztn_fclt") { // 빗물이용시설
rainMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "tb_wr_rswtr_fclt") {
} else if (layerNm === "tb_wr_rswtr_fclt") { // 중수도시설
rswtMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "tb_wr_htdfl_fclt") {
} else if (layerNm === "tb_wr_htdfl_fclt") { // 온배수시설
htdfMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
}else if(layerNm ==='tb_wr_ruse_fclt_dmd_co'){
}else if(layerNm ==='tb_wr_ruse_fclt_dmd_co'){ // 수요처
coSttnMapDetail(isFeatureCd).then((res) => {
console.log('tb_wr_ruse_fclt_dmd_co ', res)
setIsDetail(res);
});
} else if (layerNm === "tb_wr_tmpr_dmd_co") {
} else if (layerNm === "tb_wr_tmpr_dmd_co") { // 잠재수요처
ldrmntMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
@@ -0,0 +1,300 @@
# 지도 팝업 레이아웃 점검 작업계획
작성일: 2026-06-26
대상 앱: `D:\iipbs\frontend\apps\wr`
대상 화면:
- `http://localhost:3001/mapFeaturePopup?layerNm=tb_wr_bdst_ruse_fclt&featureCd=43150SW001F`
- `http://localhost:3001/mapFeaturePopup?layerNm=tb_wr_tmpr_dmd_co&featureCd=미래산업`
- 선택 팝업 공통 검토 범위:
- `tb_wr_bdst_ruse_fclt` 하수재이용시설
- `tb_wr_tmpr_dmd_co` 잠재수요처
- `tb_wr_ruse_fclt_dmd_co` 수요처
- `tb_wr_rnwtr_utztn_fclt` 빗물이용시설
- `tb_wr_rswtr_fclt` 중수도시설
- `tb_wr_htdfl_fclt` 온배수시설
- `tb_il_swage_prcs_fclt` 하수처리시설
- 공통 진입 파일:
- `apps/wr/app/(popUp-layout)/mapFeaturePopup/page.tsx`
- `apps/wr/components/lib/func/mapUtil.ts`
## 1. 작업 배경
- 지도 팝업에서 두 종류의 레이아웃 문제가 확인되었다.
- `하수재이용시설` 팝업은 컨텐츠 높이가 늘어나지 못해 하단 영역이 잘린다.
- `잠재수요처` 팝업은 컨텐츠 자체는 보이지만, 팝업 창 하단이 검은 배경으로 채워지지 않고 흰색 여백으로 남는다.
- 이 문제는 개별 폼 내부만이 아니라 지도 팝업 공통 래퍼, 팝업별 본문 높이 전략, 새 창 크기 전략을 함께 점검해야 재발을 막을 수 있다.
## 2. 현재 구조 분석
### 2.1 지도 팝업 공통 진입 구조
- `apps/wr/app/(popUp-layout)/mapFeaturePopup/page.tsx`
- `layerNm` 값에 따라 서로 다른 상세 컴포넌트를 렌더링한다.
- 공통 본문 래퍼는 다음 클래스를 사용한다.
- `className="box-border m-0 bg-background p-4 pb-24 text-foreground md:p-6"`
- 현재 이 공통 래퍼에는 `min-h-screen`, `min-h-dvh`, `h-full` 같은 viewport 채움 조건이 없다.
- 따라서 컨텐츠 높이가 창 높이보다 작을 때는 문서 body의 기본 배경색이 하단에 그대로 노출될 수 있다.
### 2.2 하수재이용시설 경로
- `mapFeaturePopup/page.tsx`
- `layerNm === "tb_wr_bdst_ruse_fclt"` 일 때 `RuseDetailPopup` 렌더링
- `apps/wr/components/ui/map/detailPopup/ruseDetailPopup.tsx`
- 시설별 탭을 만들고 각 탭에서 `PbnstSttnModal data={item} isMap={true}` 렌더링
- `apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx:257`
- `const Wrapper: React.ElementType = isMap ? "div" : ScrollArea;`
- `apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx:267`
- 지도 팝업 여부와 무관하게 `<Wrapper className="h-[70vh]">` 적용
- 지도 팝업에서는 `Wrapper`가 일반 `div`이므로:
- 내부 스크롤이 생기지 않고
- 높이만 `70vh`로 고정되어
- 아래쪽 `하수재이용시설 현황`, `하수재이용실적` 테이블이 박스 밖으로 밀린다.
### 2.3 잠재수요처 경로
- `mapFeaturePopup/page.tsx`
- `layerNm === "tb_wr_tmpr_dmd_co"` 일 때 `CoDetailModal isMap={true}` 렌더링
- `apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx`
- 내부 본문은 `<ScrollArea className="h-[79vh] mx-8">` 사용
- 즉 잠재수요처는 내부 폼 스크롤은 이미 있으나,
- 공통 팝업 바깥 래퍼가 viewport 전체 높이를 채우지 못하면
- 컨텐츠가 끝난 뒤 창 하단의 남는 공간이 `bg-background`가 아닌 흰색으로 보일 수 있다.
- 추가로 `pb-24` 같은 하단 padding이 공통 래퍼에 고정 적용되어 있어,
- 팝업별 실제 본문 높이와 맞지 않으면 시각적으로 불필요한 하단 여백처럼 보일 수 있다.
### 2.4 다른 선택 팝업 경로
- `tb_wr_ruse_fclt_dmd_co`
- `apps/wr/components/ui/map/detailPopup/coSttnDetailPopup/coSttnDetailPopup.tsx`
- 내부 `bodyClassNm={"w-full mx-auto bg-background rounded-lg shadow-md p-6"}` 사용
- `tb_wr_rnwtr_utztn_fclt`, `tb_wr_rswtr_fclt`, `tb_wr_htdfl_fclt`
- `apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx`
- 별도 `ScrollArea`는 주석 처리되어 있고, 최상위 공통 팝업 래퍼 의존도가 높다.
- `tb_il_swage_prcs_fclt`
- `mapFeaturePopup/page.tsx` 안에서 `UiTable` 2개를 직접 렌더링
- 역시 공통 래퍼 배경/높이 정책의 영향을 그대로 받는다.
### 2.5 흰 여백이 없는 팝업과 있는 팝업의 구조 차이
- 흰 여백이 없다고 확인된 팝업:
- `tb_wr_ruse_fclt_dmd_co`
- `tb_wr_rnwtr_utztn_fclt`
- `tb_wr_rswtr_fclt`
- 흰 여백이 나타난다고 확인된 팝업:
- `tb_wr_tmpr_dmd_co`
- `tb_wr_bdst_ruse_fclt`
- `tb_il_swage_prcs_fclt`
차이점 1. 개별 본문 컴포넌트의 배경 책임
- 흰 여백이 없는 `tb_wr_ruse_fclt_dmd_co`는
- `coSttnDetailPopup.tsx:23`에서 `bodyClassNm={"w-full mx-auto bg-background rounded-lg shadow-md p-6"}`를 직접 넘긴다.
- 즉 공통 팝업 래퍼 바깥이 아니라, 실제 본문 카드 자체가 `bg-background`를 명시적으로 가진다.
- 반대로 `tb_wr_tmpr_dmd_co`는
- `coDatailModal.tsx:52`의 최상위가 단순 `<div>`이고,
- 내부는 `ScrollArea className="h-[79vh] mx-8"` 중심 구조다.
- 본문 전체 배경을 개별 카드로 강하게 감싸기보다 공통 팝업 래퍼 배경에 더 의존한다.
- `tb_il_swage_prcs_fclt`는
- `mapFeaturePopup/page.tsx:103` 이하에서 `UiTable` 2개를 직접 렌더링하고,
- 별도 카드형 본문 래퍼 없이 공통 래퍼 위에 바로 쌓는다.
차이점 2. 본문 높이 점유 방식
- 흰 여백이 없는 `tb_wr_rnwtr_utztn_fclt`, `tb_wr_rswtr_fclt`는
- `sttnDetailModal.tsx:81` 이하에서 상세 폼 컴포넌트를 직접 렌더링한다.
- 현재 지도 팝업용 `ScrollArea`는 주석 처리되어 있어, 공통 래퍼 안에서 폼이 자연 높이로 이어진다.
- 실제 데이터량이 비교적 충분하면 본문이 창 하단 가까이까지 내려와 흰 여백이 드러나지 않을 수 있다.
- 반대로 `tb_wr_tmpr_dmd_co`는
- `coDatailModal.tsx:67`의 `h-[79vh]` 스크롤 영역이 명시되어 있고,
- 바깥 공통 래퍼에는 `pb-24`가 남아 있어 하단 잔여 공간이 시각적으로 더 잘 드러날 가능성이 있다.
- `tb_wr_bdst_ruse_fclt`는
- `pbnstSttnModal.tsx:267`에서 `h-[70vh]` 고정 높이를 사용한다.
- 이 경우 본문이 자연스럽게 창 끝까지 이어지지 못하고, 잘림 또는 하단 여백 문제가 함께 나타날 수 있다.
차이점 3. 공통 래퍼 의존도
- 흰 여백이 없는 쪽은
- 개별 컴포넌트가 자체 배경 카드나 충분한 컨텐츠 높이를 가져 공통 래퍼 결함이 눈에 덜 띈다.
- 흰 여백이 있는 쪽은
- 개별 카드 배경이 약하거나
- 본문 높이가 고정되거나 짧아
- `mapFeaturePopup/page.tsx:100`의 공통 래퍼가 viewport 끝까지 채워지지 않는 문제가 바로 노출된다.
### 2.6 팝업 창 자체 크기
- `apps/wr/components/lib/func/mapUtil.ts:146`
- 하수재이용시설: `window.innerHeight - 100`
- 잠재수요처: `window.innerHeight - 300`
- 수요처: `window.innerHeight - 430`
- 팝업 창 크기 자체 차이도 존재하지만,
- 이번 증상은 우선 새 창 크기보다 내부 공통 래퍼와 개별 팝업의 높이 전략 불일치 영향이 더 크다.
## 3. 문제 유형 정리
### 3.1 유형 A: 내부 컨텐츠 잘림
- 대상:
- `tb_wr_bdst_ruse_fclt`
- 원인:
- `isMap=true`인데도 내부 래퍼가 `h-[70vh]`로 고정
- `ScrollArea`가 아닌 일반 `div`라서 컨텐츠가 늘어나지 못함
### 3.2 유형 B: 팝업 하단 흰색 잔여 영역
- 우선 확인 대상:
- `tb_wr_tmpr_dmd_co`
- 함께 점검할 대상:
- `tb_wr_bdst_ruse_fclt`
- `tb_il_swage_prcs_fclt`
- 원인 후보:
- 공통 래퍼가 viewport 전체 높이를 채우지 않음
- 공통 래퍼의 하단 padding이 팝업별 컨텐츠 높이와 맞지 않음
- 팝업별 내부 스크롤 높이와 새 창 높이 계산이 제각각임
- 개별 팝업이 본문 배경을 자체적으로 채우지 못하고 공통 래퍼에 의존함
## 4. 수정 대상
### 4.1 공통 우선 수정 파일
- `D:\iipbs\frontend\apps\wr\app\(popUp-layout)\mapFeaturePopup\page.tsx`
### 4.2 하수재이용시설 직접 수정 파일
- `D:\iipbs\frontend\apps\wr\components\ui\modal\sttn\pbnstSttnModal\pbnstSttnModal.tsx`
- `D:\iipbs\frontend\apps\wr\components\ui\map\detailPopup\ruseDetailPopup.tsx`
- `D:\iipbs\frontend\apps\wr\components\ui\form\fcltReg\pbnstReg\mngReg\mngRegForm.tsx`
### 4.3 잠재수요처 및 타 팝업 점검 파일
- `D:\iipbs\frontend\apps\wr\components\ui\modal\sttn\sttnDetailModal\coDatailModal.tsx`
- `D:\iipbs\frontend\apps\wr\components\ui\map\detailPopup\coSttnDetailPopup\coSttnDetailPopup.tsx`
- `D:\iipbs\frontend\apps\wr\components\ui\modal\sttn\sttnDetailModal\sttnDetailModal.tsx`
- `D:\iipbs\frontend\apps\wr\components\lib\func\mapUtil.ts`
## 5. 권장 구현 방향
### 5.1 공통 팝업 래퍼 정규화
- `mapFeaturePopup/page.tsx`의 최상위 래퍼를 지도 팝업 공통 레이아웃 기준점으로 삼는다.
- 다음 방향으로 정리하는 것이 우선이다.
- `bg-background`가 항상 팝업 창 하단까지 채워지도록 `min-h-screen` 또는 `min-h-dvh` 적용
- 필요 시 `h-full`과 조합해 새 창 viewport를 안정적으로 덮도록 조정
- 공통 `pb-24`는 팝업별로 과도한 여백을 만드는지 점검하고, 필요하면 축소 또는 분기 처리
### 5.2 하수재이용시설 전용 높이 분기
- `PbnstSttnModal`에서 `isMap`일 때 `h-[70vh]`를 제거하거나 `max-h` 기반으로 완화
- 비지도 화면에서는 기존 `ScrollArea + h-[70vh]` 유지
- 지도 팝업에서는:
- 본문 전체가 자연스럽게 늘어나게 하거나
- 큰 테이블만 별도 스크롤 처리
### 5.3 잠재수요처 하단 흰 영역 대응
- `CoDetailModal` 자체의 `ScrollArea h-[79vh]`는 유지하되,
- 먼저 공통 팝업 래퍼의 배경/최소높이 문제를 해결한다.
- 그 다음에도 하얀 영역이 남으면 아래 순서로 추가 점검:
- `pb-24` 제거 또는 축소 시 시각적 개선 여부
- `ScrollArea` 높이를 `79vh` 고정 대신 `calc(100vh - 헤더/패딩)` 기반으로 변경할지 검토
- 팝업 창 자체 높이(`mapUtil.ts`)가 본문 높이 전략과 맞는지 재조정
### 5.4 선택된 타 팝업 공통 점검
- 잠재수요처 수정과 동일한 공통 래퍼 아래에서 동작하는 팝업들은 모두 한 번씩 확인한다.
- 특히 다음을 확인:
- 컨텐츠가 짧을 때 창 하단이 흰색으로 비는지
- 컨텐츠가 길 때 내부 스크롤/전체 스크롤이 자연스러운지
- 배경색이 본문 카드까지만 적용되고 바깥 여백은 흰색으로 남지 않는지
- 이번 확인 결과상 우선순위는 두 그룹으로 나눈다.
- 흰 여백 발생 그룹:
- `tb_wr_tmpr_dmd_co`
- `tb_wr_bdst_ruse_fclt`
- `tb_il_swage_prcs_fclt`
- 비교 기준 그룹:
- `tb_wr_ruse_fclt_dmd_co`
- `tb_wr_rnwtr_utztn_fclt`
- `tb_wr_rswtr_fclt`
## 6. 상세 작업 단계
### 단계 1. 공통 래퍼 수정
- `mapFeaturePopup/page.tsx`
- 최상위 래퍼에 viewport 채움 클래스 추가
- `pb-24`의 필요성 재검토
- 팝업 종류별로 공통 패딩 분기 필요 여부 확인
### 단계 2. 하수재이용시설 잘림 수정
- `pbnstSttnModal.tsx`
- `isMap`일 때 `h-[70vh]` 제거 또는 `max-h`로 전환
- 비지도 화면 동작은 유지
- 필요 시:
- `RuseDetailPopup`의 `TabsContent`
- `PbnstMngForm` 내부 `h-[200px] overflow-y-auto`
- `하수재이용실적` 테이블 영역
- 순서로 추가 보정
### 단계 3. 잠재수요처 하단 흰 영역 점검
- `coDatailModal.tsx`
- 공통 래퍼 수정 후에도 하얀 하단이 남는지 재확인
- 남는 경우 `ScrollArea h-[79vh]`를 `calc()` 기반으로 조정 검토
- 함께 비교:
- `coSttnDetailPopup.tsx`의 `bodyClassNm bg-background` 구조와 어떤 차이로 결과가 갈리는지 확인
- `mapUtil.ts`
- 잠재수요처 팝업 높이(`window.innerHeight - 300`)가 현재 본문 구조와 맞는지 재검토
### 단계 4. 선택된 타 팝업 회귀 점검
- 발생 그룹 확인:
- `tb_wr_tmpr_dmd_co`
- `tb_wr_bdst_ruse_fclt`
- `tb_il_swage_prcs_fclt`
- 비교 그룹 확인:
- `tb_wr_ruse_fclt_dmd_co`
- `tb_wr_rnwtr_utztn_fclt`
- `tb_wr_rswtr_fclt`
- 두 그룹 비교 기준:
- 개별 본문이 `bg-background` 카드를 직접 가지는지
- 본문이 자연 높이인지 고정 `vh` 높이인지
- 공통 래퍼 `pb-24`와 결합될 때 하단 빈 공간이 드러나는지
- 이후 추가 증상이 확인되면:
- 공통 래퍼로 해결 가능한지 우선 판단
- 개별 컴포넌트 고정 높이/패딩이 있으면 2차 수정 대상으로 분리
## 7. 구현 시 주의사항
- 지도 팝업 컴포넌트들은 일반 화면/등록 화면과 공용인 경우가 많다.
- 따라서 수정은 반드시 `isMap` 또는 팝업 전용 경로 기준으로 제한해야 한다.
- `PbnstSttnModal`의 일반 화면 `ScrollArea + h-[70vh]` 동작은 회귀되지 않게 유지해야 한다.
- 잠재수요처의 경우 내부 폼이 아니라 바깥 공통 래퍼 문제일 가능성이 크므로, 개별 폼 높이부터 섣불리 줄이지 않는다.
- `UiTable`, `ScrollArea`, 카드형 래퍼가 혼합되어 있어, 공통 래퍼와 개별 본문 래퍼의 책임을 분리해서 봐야 한다.
## 8. 검증 계획
### 8.1 하수재이용시설 검증
- `tb_wr_bdst_ruse_fclt` 클릭 시 팝업 본문 하단이 잘리지 않는다.
- `하수재이용시설 현황` 아래 `하수재이용실적` 영역이 같은 배경 안에서 정상적으로 이어진다.
- 데이터가 길어도 전체 스크롤 또는 의도한 내부 스크롤이 정상 동작한다.
### 8.2 잠재수요처 검증
- `tb_wr_tmpr_dmd_co` 클릭 시 마지막 입력 필드 아래로 흰색 빈 영역이 남지 않는다.
- 팝업 창 하단까지 `bg-background`가 자연스럽게 이어진다.
- 내부 스크롤은 유지되되, 배경색이 창 하단에서 끊기지 않는다.
### 8.3 선택 팝업 공통 검증
- 발생 그룹인 `tb_wr_tmpr_dmd_co`, `tb_wr_bdst_ruse_fclt`, `tb_il_swage_prcs_fclt`는 흰 여백이 제거되는지 확인한다.
- 비교 그룹인 `tb_wr_ruse_fclt_dmd_co`, `tb_wr_rnwtr_utztn_fclt`, `tb_wr_rswtr_fclt`는 기존처럼 흰 여백 없이 유지되는지 확인한다.
- 컨텐츠가 짧은 팝업에서 하단 흰색 잔여 영역이 남지 않는다.
- 컨텐츠가 긴 팝업에서 잘림 없이 스크롤이 가능하다.
## 9. 결론
- 이번 이슈는 `하수재이용시설`의 고정 높이 문제와 `잠재수요처`·`하수처리시설`의 하단 배경 노출 문제로 나뉘지만, 비교 결과 공통 출발점은 `mapFeaturePopup/page.tsx` 공통 래퍼다.
- 1차 우선순위는 `mapFeaturePopup/page.tsx` 공통 래퍼를 viewport 기준으로 정규화하는 것이다.
- 2차 우선순위는 `PbnstSttnModal`의 지도 팝업 전용 `70vh` 고정 높이 제거다.
- 이후에는 "개별 본문 배경을 직접 가지는 팝업"과 "공통 래퍼 배경에 의존하는 팝업"의 차이를 기준으로, 하단 흰색 잔여 영역과 컨텐츠 잘림을 함께 정리하는 것이 맞다.