물재이용 지도 전반적인 수정 트리에서 클릭시 까지 완료(검색바 해야함)

This commit is contained in:
leedj312
2025-08-05 20:28:32 +09:00
parent 2c6327bc3a
commit 24a55142fb
72 changed files with 3009 additions and 88 deletions
@@ -0,0 +1,150 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import { pbnMapTableSize } from "@/app/store/map/pbnstMap";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { tableData } from "@/components/lib/func/commom";
import {
ContentsDiv,
SearchBaseForm,
SearchInput,
Title,
UiTable,
type ReturnType,
} from "@common/business_components/ui";
import { Label } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: "list" | "detail" | "nothing";
onFeatureSelect: (feature: any) => void;
onClose: () => void;
isRuseReg: { data: any | undefined };
}
const HasuFacility = ({
seletectedLayerNm,
viewMode,
onClose,
onFeatureSelect,
isRuseReg,
}: Props) => {
const { code, pbnMap, pbnMapInit } = useWrStore((state) => state);
const { pbnMapHeadList, pbnMapRes, pbnMapCount } = pbnMap;
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
const [isReset, setIsReset] = useState(false);
const [pbnRuseNm, setPbnRuseNm] = useState<string>("");
const ref = useRef<ReturnType>({} as ReturnType);
useEffect(() => {
if (code.sggCd.length && pbnMapRes.length > 0) {
setHasuTable(tableData(pbnMapRes, { code }));
}
}, [code, pbnMapRes]);
useEffect(() => {
if (seletectedLayerNm !== "하수처리시설" || viewMode != "list") return;
if (!pbnMap.isInit) {
console.log('ref.current ', ref.current)
pbnMapInit(1, pbnMapTableSize, ref.current);
}
}, [pbnMap.isInit, pbnMapInit]);
const hasuCellClick = (index: number | undefined) => {
if (index !== undefined && pbnMapRes !== undefined) {
onFeatureSelect(pbnMapRes[index]);
onClose();
}
};
return viewMode == "list" ? (
<ContentsDiv>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<Title title="하수처리시설 현황" />
<SearchBaseForm
selectSidoData={code.cityCd}
selectSigunData={code.sggCd}
selectRegionData={code.rvbsnCd}
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
buttonOrder={["query", "init", "excel"]}
rightClassName="ml-auto mr-6 flex items-center space-x-1"
leftClassName="flex gap-5 w-9/12 m-4"
leftSelectClassName="w-1/4"
rightChildren={<></>}
leftChildren={
<div className="col-span-3 flex items-center">
<Label className="w-full mt-2 ml-4 text-xl text-gray-600">
{"하수처리시설명"}
</Label>
<SearchInput
className={"text-2xl w-full"}
label=""
textValue={pbnRuseNm || ""}
setText={(e) => {
setPbnRuseNm(e || "");
}}
/>
</div>
}
queryClick={() => {
setIsReset(true);
}}
initClick={function (): void {
setPbnRuseNm("");
}}
btnClass={btnClass}
ref={ref}
isAdmin={false}
excelClick={function (returnType: ReturnType): void {
console.log("pbnstSttnSearch ", returnType);
}}
/>
</div>
<div className="col-span-6">
{/* 높이 조정 */}
<UiTable
tableData={hasuTable || []}
headlist={pbnMapHeadList}
pageSize={pbnMapTableSize}
total={pbnMapCount || 0}
headName={""}
cellClick={hasuCellClick}
onPageChange={(page) => {
pbnMapInit(page, pbnMapTableSize, ref.current);
setIsReset(false);
}}
resetPageNo={isReset}
/>
</div>
</div>
</ContentsDiv>
) : (
<div style={{ overflowX: "hidden" }}>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isRuseReg?.data || []}
headlist={pbnMapHeadList.slice(0, 4)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => {}}
onPageChange={() => {}}
/>
<UiTable
tableData={isRuseReg?.data || []}
headlist={pbnMapHeadList.slice(4)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => {}}
onPageChange={() => {}}
/>
</div>
);
};
export default HasuFacility;
+13
View File
@@ -0,0 +1,13 @@
"use client";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<>
<div>{children}</div>
</>
);
}
@@ -0,0 +1,84 @@
"use client";
import { CoSttnMap } from "@/components/ui/map/LayerPopUp/CoSttnMap/CoSttnMap";
import { HasuFacility } from "@/components/ui/map/LayerPopUp/HasuFacilty/HasuFacility";
import { HtdflFacility } from "@/components/ui/map/LayerPopUp/HedfFacilty/HtdfFacilty";
import { LdrmntCoMap } from "@/components/ui/map/LayerPopUp/LdrmntCoMap/LdrmntCoMap";
import { RainFacility } from "@/components/ui/map/LayerPopUp/RainFacility/RainFacility";
import { RswtFacility } from "@/components/ui/map/LayerPopUp/RswtFacilty/RswtFacilty";
import { RuseFacility } from "@/components/ui/map/LayerPopUp/RuseFacilty/RuseFacility";
import { useSearchParams } from "next/navigation";
export default function MapDetailPopUp() {
const searchParams = useSearchParams();
const bc = new BroadcastChannel("mapDetailPopUp");
const renderConditionalContent = () => {
const layerId = searchParams.get("layerNm");
switch (layerId) {
case "하수재이용시설":
return (
<RuseFacility
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
case "하수처리시설":
return (
<HasuFacility
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
case "빗물이용시설":
return (
<RainFacility
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
case "중수도시설":
return (
<RswtFacility
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
case "온배수시설":
return (
<HtdflFacility
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
case "수요처":
return (
<CoSttnMap
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
case "잠재수요처":
return (
<LdrmntCoMap
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
);
default:
return null; // 안전하게 아무 것도 렌더링하지 않음
}
};
return (
<>
<div>{renderConditionalContent()}</div>
</>
);
}
@@ -0,0 +1,187 @@
// "use client"
// import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
// import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
// import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
// import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
// import { useGisContext } from "@common/business_components/ui/map/Gis";
// import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
// import React, { useCallback, useEffect, useRef, useState } from 'react';
// import ResueFacility from '../layerPopup/reuseFacility';
// import HasuFacility from '../layerPopup/hasuFacility';
// import RainFacility from '../layerPopup/rainFacility';
// import RswtFacility from '../layerPopup/rswtFacility';
// import HtdflFacility from '../layerPopup/htdflFacility';
// import ReuseMngFacility from '../layerPopup/reuseMngFacility';
// import { detainSttn, fetchHasuDetail, fetchpbnstDetail } from "../util";
// interface NewWindowPopupProps {
// featureData: any;
// seletectedLayerNm?: string
// onFeatureSelect: (data: any) => void;
// onClose: () => void;
// }
// const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
// featureData,
// seletectedLayerNm,
// onFeatureSelect,
// onClose
// }) => {
// const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
// const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]);
// const [activeTab, setActiveTab] = useState<string>('0');
// const [viewMode, setViewMode] = useState<'list' | 'detail' | 'nothing'>('list');
// const [fcltPk, setFcltPk] = useState<string>('');
// // onClose 함수를 useCallback으로 메모이제이션
// const memoizedOnClose = useCallback(() => {
// onClose();
// }, [onClose]);
// // 빗물재이용시설 변수
// const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false });
// const [rainList, setRainList] = useState<customRainBdst[]>([]);
// // 중수도시설 변수
// const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false });
// const [rswtrList, setRswtrList] = useState<customRswtBdst[]>([]);
// // 온배수시설 변수
// const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false });
// const [htdflList, setHtdflList] = useState<customHtdflBdst[]>([]);
// // 하수처리시설 변수
// const [hasuList, setHasuList] = useState<pubHasuType[]>([]);
// const [isRuseReg, setIsRuseReg] = useState<{
// data: any | undefined;
// }>({ data: undefined });
// // 수요처관리 변수
// const [isDmdModal, setIsDmdModal] = useState<{
// isMoal: boolean;
// data: any | undefined;
// }>({ isMoal: false, data: undefined });
// const [mngList, setMngList] = useState<DemandCompType[]>([]);
// ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
// const getSelectedLayers = () => {
// console.trace('호출확인', 1)
// let result = null;
// const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
// let featureLayer: { get: (key: string) => any } = { get: () => null };
// layers.forEach((layer: any) => {
// const source = layer.getSource();
// if (source && source.hasFeature && featureData
// && typeof featureData.getId === 'function' && source.hasFeature(featureData)) {
// featureLayer = layer; // 피처가 속한 레이어 찾기)
// }
// });
// result = featureLayer.get('lyrNm');
// return result;
// };
// // 상세 목록 데이터 상태 처리
// useEffect(() => {
// if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] });
// }, [hasuList])
// useEffect(() => {
// if (rainList.length > 0) setRainDetailModal({ isOpen: true, data: rainList[0] });
// }, [rainList])
// useEffect(() => {
// if (rswtrList.length > 0) setRswtrDetailModal({ isOpen: true, data: rswtrList[0] });
// }, [rswtrList])
// useEffect(() => {
// if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] });
// }, [htdflList])
// useEffect(() => {
// if (mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] });
// }, [mngList])
// const lastCalledIdRef = useRef<string | null>(null);
// const [layerId, setLayerId] = useState<string | null>();
// useEffect(() => {
// const layers = getSelectedLayers();
// setLayerId(layers);
// }, []); // 최초 렌더링 시 호출
// // 피쳐 데이터가 변경될 때마다 호출
// useEffect(() => {
// if (!featureData || typeof featureData.getProperties !== "function" || featureData.getProperties() == '') return;
// const selectedProps = featureData.getProperties();
// const currentId = featureData.getId?.() || selectedProps?.id || selectedProps?.fid;
// // 유효하지 않은 ID는 아예 무시
// if (!currentId || typeof currentId !== 'string') return;
// // 이전과 동일하면 무시
// if (!currentId || currentId === lastCalledIdRef.current) return;
// lastCalledIdRef.current = currentId // 새로운 피처일 때만 API 호출
// const layerId = getSelectedLayers?.();
// if (!layerId || typeof layerId !== 'string') return;
// const featureCd =
// layerId === '하수재이용시설' ? selectedProps?.swtrmt_fclt_cd :
// ['빗물이용시설', '중수도시설', '온배수시설', '수요처'].includes(layerId) ? selectedProps?.bdst_nm :
// layerId === '하수처리시설' ? selectedProps?.swtrmt_fclt_nm :
// null;
// if (!featureCd || featureCd === fcltPk) return;
// if (layerId === '하수재이용시설') {
// fetchpbnstDetail(featureCd, setTabData);
// } else if (layerId === '하수처리시설') {
// fetchHasuDetail(featureCd, selectedProps?.swtrmt_fclt_cd).then((data) => { setHasuList(data) })
// } else {
// detainSttn(featureCd, layerId).then((res) => {
// if (layerId === '빗물이용시설') setRainList(res);
// else if (layerId === '중수도시설') setRswtrList(res);
// else if (layerId === '온배수시설') { setHtdflList(res); setHtdflDetailModal({ isOpen: true, data: res[0] }); }
// else if (layerId === '수요처') setMngList(res);
// });
// }
// setFcltPk(featureCd);
// setActiveTab(featureCd);
// setViewMode("detail");
// }, [featureData]);
// ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
// // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수
// const renderConditionalContent = () => {
// const actTabData = tabData.find((tab) => tab.id === activeTab);
// if (layerId === null || layerId === undefined) {
// setLayerId(seletectedLayerNm || '');
// }
// switch (layerId) {
// case '하수재이용시설':
// return (<ResueFacility viewMode={viewMode} seletectedLayerNm={layerId} tabData={tabData} actTabData={actTabData} setFcltPk={setFcltPk} onFeatureSelect={onFeatureSelect} onClose={onClose} />)
// case '하수처리시설':
// return (<HasuFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} isRuseReg={isRuseReg} />)
// case '빗물이용시설':
// return (<RainFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} rainDetailModal={rainDetailModal} />)
// case '중수도시설':
// return (<RswtFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} rswtrDetailModal={rswtrDetailModal} />)
// case '온배수시설':
// return (<HtdflFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} htdflDetailModal={htdflDetailModal} />)
// case '수요처':
// return(<ReuseMngFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} isDmdModal={isDmdModal} />)
// default:
// break;
// }
// return null; // 조건에 맞는 콘텐츠가 없을 경우
// };
// return (
// // viewMode == 'nothing' ? <></> :
// // <NewWindowPortal
// // onClose={memoizedOnClose}
// // title="시설 상세 정보"
// // scrollbars='yes'
// // viewMode={viewMode}
// // resizable='no'>
// // {/* 체크된 레이어에 따른 조건부 렌더링 */}
// // {renderConditionalContent()}
// // </NewWindowPortal>
// <div>
// {renderConditionalContent()}
// </div>
// );
// };
// export default NewWindowPopup;
@@ -0,0 +1,148 @@
import React, { useState, useEffect, useRef, useCallback, createContext, useContext } from 'react';
import { createPortal } from 'react-dom';
// 현재 문서의 스타일(CSS)을 새 창으로 복사하는 함수
const copyStyles = (sourceDoc: Document, targetDoc: Document) => {
Array.from(sourceDoc.styleSheets).forEach(styleSheet => {
try {
if (styleSheet.cssRules) { // <style> 태그로 주입된 CSS
const newStyleEl = sourceDoc.createElement('style');
Array.from(styleSheet.cssRules).forEach(cssRule => {
newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
});
targetDoc.head.appendChild(newStyleEl);
} else if (styleSheet.href) { // <link> 태그로 연결된 CSS 파일
const newLinkEl = sourceDoc.createElement('link');
newLinkEl.rel = 'stylesheet';
newLinkEl.href = styleSheet.href;
targetDoc.head.appendChild(newLinkEl);
}
} catch (e) {
console.warn('스타일시트를 복사할 수 없습니다:', e);
}
});
};
interface NewWindowPortalProps {
children: React.ReactNode;
onClose: () => void;
title?: string;
width?: number;
height?: number;
resizable?: string;
scrollbars?: string;
viewMode?: 'list' | 'detail' | 'nothing';
}
// Context to provide the new window's document
const NewWindowContext = createContext<Document | null>(null);
// Custom hook to consume the new window's document
export const useNewWindowDocument = () => {
const context = useContext(NewWindowContext);
if (context === null) {
throw new Error('useNewWindowDocument must be used within a NewWindowContext.Provider');
}
return context;
};
const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", resizable = "yes", scrollbars = "yes", viewMode }) => {
const [container, setContainer] = useState<HTMLElement | null>(null);
const [targetDocument, setTargetDocument] = useState<Document | null>(null);
const newWindowRef = useRef<Window | null>(null);
const onCloseRef = useRef(onClose);
// onClose 함수를 ref로 저장하여 의존성 문제 해결
useEffect(() => {
onCloseRef.current = onClose;
}, [onClose]);
const handleUnload = useCallback(() => {
onCloseRef.current();
}, []);
useEffect(() => {
if (newWindowRef.current) {
if (viewMode == 'detail') {
newWindowRef.current.resizeTo(1100, 700);
} else {
newWindowRef.current.resizeTo(screen.availWidth, screen.availHeight);
}
}
}, [viewMode]);
useEffect(() => {
// 이미 창이 열려있으면 새로 열지 않음
if (newWindowRef.current && !newWindowRef.current.closed) return;
// 브라우저 화면 정보
const screenLeft = window.screenLeft ?? window.screenX;
const screenTop = window.screenTop ?? window.screenY;
const screenWidth = window.innerWidth ?? document.documentElement.clientWidth;
const screenHeight = window.innerHeight ?? document.documentElement.clientHeight;
// 중앙 위치 계산
const left = screenLeft + (screenWidth - window.screen.width) / 2;
const top = screenTop + (screenHeight - window.screen.height) / 2;
// 1. 새 창을 열고 참조를 저장합니다.
const popupOptions = `width=${window.screen.width},height=${window.screen.height},left=${left}, top=${top}, resizable=${resizable},scrollbars=${scrollbars}`;
newWindowRef.current = window.open('', title, popupOptions);
if (newWindowRef.current) {
newWindowRef.current.document.title = title;
// 2. React 컴포넌트를 마운트할 컨테이너 div를 생성하여 새 창의 body에 추가합니다.
const div = newWindowRef.current.document.createElement('div');
newWindowRef.current.document.body.appendChild(div);
setContainer(div);
setTargetDocument(newWindowRef.current.document);
// 3. 메인 창의 스타일을 새 창으로 복사합니다. (매우 중요)
copyStyles(document, newWindowRef.current.document);
// 4. 사용자가 창을 닫을 때 부모에게 알리기 위한 이벤트 리스너를 설정합니다.
newWindowRef.current.addEventListener('unload', handleUnload);
// 5. 컴포넌트가 사라질 때 창을 닫는 클린업 함수를 반환합니다.
return () => {
if (newWindowRef.current) {
newWindowRef.current.removeEventListener('unload', handleUnload);
if (!newWindowRef.current.closed) {
newWindowRef.current.close();
}
}
};
} else {
alert('팝업이 차단되었습니다. 팝업 차단을 해제하고 다시 시도해주세요.');
onCloseRef.current();
}
}, [handleUnload, onClose, title]);
// `createPortal`을 사용해 children을 새 창의 container div에 렌더링합니다.
// children을 NewWindowContext.Provider로 감싸서 새 창의 document를 하위 컴포넌트에서 접근 가능하도록 함
return container && targetDocument ? (
createPortal(
<NewWindowContext.Provider value={targetDocument}>
{children}
</NewWindowContext.Provider>,
container
)
) : null;
};
export default NewWindowPortal;
/*
Usage example inside popup children:
import { useNewWindowDocument } from './newWindowPortal';
const PopupChildComponent = () => {
const newWindowDocument = useNewWindowDocument();
return (
<SomeSelectComponent
menuPortalTarget={newWindowDocument.body} // For react-select or MUI Select to render dropdowns correctly in new window
{...otherProps}
/>
);
};
*/
+18
View File
@@ -0,0 +1,18 @@
"use client";
import Base from "../base";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<Base>
{children}
</Base>
);
}
@@ -0,0 +1,83 @@
import { useWrStore } from '@/app/store';
import type { customHtdflBdst } from '@/app/store/ruseFcltMng/fcltReg/htdflReg';
import { tableData } from '@/components/lib/func/commom';
import SttnDetailModal from '@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal';
import { Title, UiTable } from '@common/business_components/ui';
import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeColSpan';
import React, { useEffect, useState } from 'react'
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
htdflDetailModal: { isOpen: boolean; data: customHtdflBdst | undefined };
}
const HtdflFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, htdflDetailModal }: Props) => {
const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
const [htdflPage, setHtdflPage] = useState(1)
// 온배수시설 cellClick 이벤트 (상세정보)
const htdflCellClick = (index: number | undefined) => {
if (index !== undefined && htdflTable !== undefined) {
onFeatureSelect(htdflTable[index]);
onClose();
}
};
useEffect(() => {
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
if (!htdflSttn.isInit) {
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
useEffect(() => {
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
const data = tableData(htdflSttnRes, { code });
const chData = data
.map((item: any) => ({
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].htdflObj,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
}))
.filter((item: any) => item.htdflObj !== undefined);
setHtdflTable(chData);
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
useEffect(() => {
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
return (
viewMode == 'detail' ? (
<SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} />
) : (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="온배수시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={htdflTable || []}
headlist={htdflSttn.htdflSttHeadList}
pageSize={20}
total={htdflSttnResCount || 0}
cellClick={(index: number | undefined) => {
htdflCellClick(index ?? undefined);
}}
onPageChange={setHtdflPage}
>
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
</UiTable>
</div>
)
)
}
export default HtdflFacility
@@ -0,0 +1,105 @@
import { useWrStore } from "@/app/store";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { tableData } from "@/components/lib/func/commom";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
rainDetailModal: { isOpen: boolean; data: customRainBdst | undefined };
}
const RainFacility = ({seletectedLayerNm,viewMode,onFeatureSelect,onClose,rainDetailModal}:Props) => {
// 빗물재이용시설 변수
const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
(state) => state
);
const { rainSttnRes, rainSttnResCount } = rainSttn;
const [rainTable, setRainTable] = useState<customRainBdst[]>();
const [rainPage, setRainPage] = useState(1)
// 빗물재이용시설 cellClick 이벤트 (상세정보)
const rainCellClick = (index: number | undefined, headId: string) => {
if (
index !== undefined &&
rainTable !== undefined &&
headId !== 'chBuildingYn') {
onFeatureSelect(rainTable[index]);
onClose();
}
}
useEffect(() => {
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
console.log('빗물이용시설 초기값 호출', viewMode)
if (!rainSttn.isInit) {
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rainSttn.isInit, rainSttnInit]);
useEffect(() => {
const data = tableData(rainSttnRes, { code });
const chData = data
.map((item: any) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].rainyObj,
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst: item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
};
})
.filter((item: any) => item.rainyObj !== undefined);
setRainTable(chData);
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
useEffect(() => {
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
return (viewMode == 'detail' ?
(<SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} />)
: (
<>
<div className="flex justify-between items-center">
<Title title="빗물이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rainTable || []}
headlist={rainSttn.rainSttHeadList}
pageSize={20}
total={rainSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rainCellClick(index ?? undefined, headId);
}}
onPageChange={setRainPage}
>
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
</UiTable>
</>
))
}
export default RainFacility;
@@ -0,0 +1,146 @@
import { useWrStore } from "@/app/store";
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
import { Title, UITab, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useState, useEffect, useCallback } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
setFcltPk: (pk: string) => void;
onFeatureSelect: (feature: any) => void;
onClose: () => void;
actTabData: { id: string; name: string; data: any } | undefined;
tabData: { id: string; name: string; data: any }[];
}
const ResueFacility = ({ viewMode, seletectedLayerNm, tabData, actTabData, setFcltPk, onFeatureSelect, onClose}: Props) => {
const [activeTab, setActiveTab] = useState<string>(''); // 현재 활성화된 탭
// 하수재이용시설 변수
const {
pbnstSttn,
pbnstSttnSearch,
pbnSttnInit,
getFlcts
} = useWrStore((state) => state);
const { fclts, pbnstSttnResCount } = pbnstSttn
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>()
// 재이용시설 cellClick 이벤트 (상세정보)
const pbnstCellClick = (index: number | undefined) => {
if (
index !== undefined &&
pbnstSttn.pbnstSttnRes &&
pbnstSttn.pbnstSttnRes[index]
) {
setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltId);
onFeatureSelect(pbnstSttn.pbnstSttnRes[index]);
onClose()
}
};
// 재이용 현황 초기값
useEffect(() => {
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
if (!pbnstSttn.isInit) {
getFlcts()
}
}, [seletectedLayerNm, pbnstSttn.isInit]);
useEffect(() => {
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
pbnSttnInit("1", "20", {
partValue: "A",
sidoValue: '0',
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: ""
}, String(new Date().getFullYear()), pbnstSttn.fclts);
}, [fclts, pbnSttnInit, pbnstSttn.fclts, seletectedLayerNm])
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
// 재이용시설 조회
// 재이용시설 페이징처리 관련 함수
const onPageChangeHandler = useCallback((page: number) => {
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
pbnstSttnSearch(
false,
String(page),
String(20),
{
partValue: "A",
sidoValue: "0",
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: "",
},
"",
String(new Date().getFullYear()), fclts
);
}, [fclts, pbnstSttnSearch]);
// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제.
// const excelClick = useCallback(() => {
// // if (codeData) pbnstSttnSearch(1, "10000", codeData);
// excelDownload(
// [[]],
// "하수재이용시설 현황",
// "sample_pbnstSttn.xlsx",
// "A1:U2"
// );
// }, [pbnstSttnSearch]);
return (
viewMode == 'detail' ?
// 재이용시설 상세
<>
<div className="flex justify-between items-center mb-4">
<Title title="하수재이용시설 상세정보" />
</div>
<div className="flex justify-between items-center mb-8">
<UITab
defaultValue={activeTab}
tabList={tabData.map((tab) => ({
value: tab.id,
label: tab.name,
onClick: () => setActiveTab(tab.id),
}))}
/>
</div>
<PbnstSttnModal
data={actTabData?.data[0] || ({} as customPbnst)}
titleVisible={false}
/>
</> :
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="하수재이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={bdstTable || []}
headlist={pbnstSttn.pbnstSttHeadList}
pageSize={20}
total={pbnstSttnResCount || 0}
cellClick={(index: number | undefined) => {
pbnstCellClick(index);
}}
onPageChange={onPageChangeHandler}
>
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
</UiTable>
</div>
)
}
export default ResueFacility;
@@ -0,0 +1,103 @@
import { useWrStore } from '@/app/store';
import { tableData, formatPhoneNumber } from '@/components/lib/func/commom';
import { Title, UiTable } from '@common/business_components/ui';
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
import moment from 'moment';
import React, { useEffect, useState } from 'react'
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
isDmdModal: { data: any | undefined };
}
const ReuseMngFacility = ({seletectedLayerNm, viewMode, onFeatureSelect, onClose, isDmdModal}:Props) => {
const { code,
coSttn,
coSttnInit,
coSttnSearch,
} = useWrStore((state) => state);
const [mngTable, setMngTable] = useState<DemandCompType[]>();
const [mngPage, setMngPage] = useState(1);
const { coSttnRes, coSttnResCount, coSttHeadList } = coSttn;
useEffect(() => {
if (seletectedLayerNm !== '수요처' || viewMode != 'list') return;
if (!coSttn.isInit) {
coSttnInit("1", "20", "0");
}
}, [coSttn.isInit, coSttnInit]);
const coMngCellClick = (index: number | undefined) => {
if (index !== undefined && mngTable !== undefined) {
onFeatureSelect(mngTable[index]);
onClose();
}
};
useEffect(() => {
if (seletectedLayerNm !== '수요처' || viewMode!='list') return;
if (coSttnRes) {
if (coSttnRes?.length > 0 && code.cityCd.length > 0) {
const data = tableData(coSttnRes, { code });
const chData = data.map((item: any) => ({
...item,
telno: formatPhoneNumber(item.telno || undefined),
regDt: moment(item.regDt).format("YYYY-MM-DD"),
dmdInfoId: `${item.dmdInfoId.slice(0, 3)}-${item.dmdInfoId.slice(3, 5)}-${item.dmdInfoId.slice(5, 10)}-${item.dmdInfoId.slice(10)}`
}));
// .filter((item: any) => item !== undefined);
setMngTable(chData);
}
}
}, [coSttnRes, code]);
useEffect(() => {
if (seletectedLayerNm !== '수요처' || viewMode!='list') return;
coSttnSearch(String(mngPage), "20", String(0));
}, [coSttnSearch, mngPage]);
return (
viewMode == 'detail'
? (
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="수요처 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(0, 3)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(3)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</div>
) : (<div>
<div className="flex justify-between items-center">
<Title title="수요처 현황" />
</div>
<UiTable
headName={[]}
tableData={mngTable || []}
headlist={coSttHeadList}
pageSize={20}
total={coSttnResCount + 10 || 0}
cellClick={(index: number | undefined) => {
coMngCellClick(index);
// setUpdateData(coSttnRes[index as number]);
}}
onPageChange={(page) => {
setMngPage(page);
}}
></UiTable></div>)
)
}
export default ReuseMngFacility
@@ -0,0 +1,107 @@
import { useWrStore } from "@/app/store";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { tableData } from "@/components/lib/func/commom";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
interface Props {
seletectedLayerNm: string;
viewMode: 'list' | 'detail' | 'nothing';
onFeatureSelect: (feature: any) => void;
onClose: () => void;
rswtrDetailModal: { isOpen: boolean; data: customRswtBdst | undefined };
}
const RswtFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, rswtrDetailModal }: Props) => {
const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
(state) => state
);
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>()
const [rswtrPage, setRswtrPage] = useState(1);
// 중수도시설 cellClick 이벤트 (상세정보)
const rswtCellClick = (index: number | undefined, headId: string) => {
if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
// setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] });
// setViewMode('detail')
onFeatureSelect(rswtrTable[index]);
onClose();
}
}
useEffect(() => {
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
if (!rswtSttn.isInit) {
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
useEffect(() => {
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
const data = tableData(rswtSttnRes, { code });
const chData = data
.map((item: customRswtBdst) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0]?.rswtrObj,
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
}
})
.filter(
(item: customRswtBdst) =>
item.reuseBuilding[0]?.rswtrObj !== undefined
);
setRswtrTable(chData);
}, [code, rswtSttnRes]);
// FIXME: 윤선화 차장님 요구사항으로 엑셀 다운로드 삭제.
// const rswtSttnExcelDownload = useCallback(() => {
// if (rswtSttn.excelList.length > 0) {
// if (rswtSttn.excelList.length === 0) return;
// excelDownload(
// rswtSttn.excelList,
// "중수도시설 현황",
// "sample_rswtSttn.xlsx",
// "A1:W3",
// );
// }
// }, [rswtSttn.excelList])
useEffect(() => {
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
return (
viewMode == 'detail' ?
// 중수도시설 상세
(
<SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} />
) : (
<div style={{ overflowY: 'auto' }}>
<div className="flex justify-between items-center">
<Title title="중수도시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rswtrTable || []}
headlist={rswtSttn.rswtSttHeadList}
pageSize={20}
total={rswtSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rswtCellClick(index, headId);
}}
onPageChange={setRswtrPage}
>
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
</UiTable>
</div>
))
}
export default RswtFacility;
@@ -1,5 +1,5 @@
"use client"
import NewWindowPortal from '@/app/map/components/newWindowPortal';
import NewWindowPortal from '@/app/(with-layout)/map/components/newWindowPortal';
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
@@ -8,7 +8,7 @@ import { useGisContext } from "@common/business_components/ui/map/Gis";
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import ResueFacility from './layerPopup/reuseFacility';
import { detainSttn, fetchHasuDetail, fetchpbnstDetail } from '../util';
import { detainSttn, fetchHasuDetail, fetchpbnstDetail } from '../../../(popUp-layout)/util';
import HasuFacility from './layerPopup/hasuFacility';
import RainFacility from './layerPopup/rainFacility';
import RswtFacility from './layerPopup/rswtFacility';
@@ -22,7 +22,7 @@ interface NewWindowPopupProps {
onClose: () => void;
}
const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
const NewWindowPopup22: React.FC<NewWindowPopupProps> = ({
featureData,
seletectedLayerNm,
onFeatureSelect,
@@ -180,4 +180,4 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
);
};
export default NewWindowPopup;
export default NewWindowPopup22;
@@ -34,7 +34,7 @@ interface NewWindowPortalProps {
viewMode?: 'list' | 'detail' | 'nothing';
}
const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", resizable = "yes", scrollbars = "yes", viewMode }) => {
const NewWindowPortal22: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", resizable = "yes", scrollbars = "yes", viewMode }) => {
const [container, setContainer] = useState<HTMLElement | null>(null);
const newWindowRef = useRef<Window | null>(null);
const onCloseRef = useRef(onClose);
@@ -109,4 +109,4 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti
return container ? createPortal(children, container) : null;
};
export default NewWindowPortal;
export default NewWindowPortal22;
@@ -3,10 +3,13 @@
import Gis from "@common/business_components/ui/map/Gis";
import { useEffect, useRef, useState, useCallback } from "react";
import { mapService } from "../service";
import NewWindowPopup from "../components/newWindowPopup";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import { useWrStore } from "@/app/store";
const Map = () => {
const { comMap } = useWrStore((state) => state);
const {isFeatured} = comMap
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
const gisMaps = useRef<any | null>(null);
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
@@ -14,6 +17,7 @@ const Map = () => {
const [featureData, setFeatureData] = useState<any>(null); // 선택된 피쳐 데이터
const [checkedLayers, setCheckedLayers] = useState<string[]>([]);
const [checkedLayersData, setCheckedLayersData] = useState<any[]>([]);
const popupRef = useRef<Window | null>(null);
const fetchData = async () => {
try {
@@ -25,16 +29,35 @@ const Map = () => {
};
// 팝업 닫기 핸들러를 useCallback으로 메모이제이션
const handlePopupClose = useCallback(() => {
setIsOpen(false);
setFeatureData(null);
}, []);
// const handlePopupClose = useCallback(() => {
// setIsOpen(false);
// setFeatureData(null);
// }, []);
// 컴포넌트 마운트 시 1회 실행
useEffect(() => {
fetchData();
}, []);
useEffect(() => {
const bc = new BroadcastChannel("mapDetailPopUp");
bc.onmessage = (event) => {
if (event.data.type === "SELECT_FEATURE") {
console.log('event.data.feature ', event.data.feature)
onFeatureSelect(event.data.feature);
closePopup()
}
};
}, []);
useEffect(() =>{
console.log('isFeatured ', isFeatured)
if(isFeatured){
console.log('isFeatured ', isFeatured)
onFeatureSelect(isFeatured)
}
},[isFeatured])
// 체크된 레이어 정보를 받는 핸들러
const handleCheckedLayersChange = (
checkedIds: string[],
@@ -44,6 +67,8 @@ const Map = () => {
setCheckedLayersData(checkedNodesData);
};
// SearchModal, GisContent 등에서 호출
const onFeatureSelect = (data: any) => {
const map = gisMaps.current;
@@ -129,18 +154,39 @@ const Map = () => {
// />
// );
// };
const renderDetailView = useCallback(
(props: any) => (
<NewWindowPopup
key={featureData?.fid || featureData?.id || featureData?.ftrIdn}
onClose={handlePopupClose}
checkedLayers={checkedLayers}
checkedLayersData={checkedLayersData}
{...props}
/>
),
(props: any) => {
console.log('props ', props.seletectedLayerNm)
const url = `/mapDetilePopUp?layerNm=${encodeURIComponent(props.seletectedLayerNm)}`;
const width = window.screen.availWidth;
const height = window.screen.availHeight;
const left = 0;
const top = 0;
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`;
popupRef.current = window.open(url, "지도 레이어 팝업", popupOptions);
// return(
// <NewWindowPopup
// key={featureData?.fid || featureData?.id || featureData?.ftrIdn}
// onClose={handlePopupClose}
// checkedLayers={checkedLayers}
// checkedLayersData={checkedLayersData}
// {...props}
// />
// )
}
,
[checkedLayers, checkedLayersData] // 필요 시 의존성 넣기
);
const closePopup = () => {
if (popupRef.current && !popupRef.current.closed) {
popupRef.current.close();
popupRef.current = null;
setIsOpen(false);
setFeatureData(null);
}
};
return (
<div className="bg-container">
<Gis
@@ -10,7 +10,7 @@ import {
UiTable,
} from "@common/business_components";
import { Button } from "@common/components";
import { useWrStore } from "../../../store";
import { useWrStore } from "../../../../store";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components";
import { useCallback, useEffect, useState } from "react";
import ListDiv from "@common/business_components/ui/list_div";
+4 -7
View File
@@ -1,10 +1,9 @@
"use client";
import "./globals.css";
import { StoreProvider} from "./store";
import koBase from "../public/locales/ko/message.json";
import i18next from "i18next";
import { I18nextProvider } from "react-i18next";
import Base from "./base";
import koBase from "../public/locales/ko/message.json";
import { StoreProvider } from "./store";
export default function RootLayout({
children,
@@ -25,11 +24,9 @@ export default function RootLayout({
<html lang="en">
<body>
<I18nextProvider i18n={i18next}>
<StoreProvider>
<Base>
<StoreProvider>
{children}
</Base>
</StoreProvider>
</StoreProvider>
</I18nextProvider>
</body>
</html>
+120
View File
@@ -0,0 +1,120 @@
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import type { CommonTableProps } from "../../common/type/header";
import { coSttHeadListExport, coSttNodeListExport } from "../../matDmd/coSttn/headList";
import { fetchType, getFetchWithCount } from "@/components/lib/api";
const coSttnMapRes: DemandCompType[] = [];
export const costtnMapSize =20
export type coSttnMapState = {
coSttnMap: {
coSttnMapRes: DemandCompType[];
coSttMapHeadList: CommonTableProps[];
coSttMapNodeList: CommonTableProps[];
excelList: [];
isInit: boolean;
coSttnMapResCount: number;
};
};
type coSttnMapActions = {
coSttnMapInit: (pageNo: number, pageCnt: number, con: string) => void;
coSttnMapSearch: (pageNo: number, pageCnt: number, con: string) => void;
coSttnMapTxtSearch: (pageNo: number, pageCnt: number, con: string, txt: string) => void;
};
export type coSttnMapType = coSttnMapState & coSttnMapActions;
export const coSttnMapStateExport: coSttnMapState = {
coSttnMap: {
coSttMapHeadList: coSttHeadListExport,
coSttMapNodeList: coSttNodeListExport,
coSttnMapRes: coSttnMapRes,
excelList: [],
isInit: false,
coSttnMapResCount: 0,
},
};
export const coSttnMapActionsExport: (set: any) => coSttnMapActions = (
set: any
) => {
return {
coSttnMapInit: async (pageNo: number, pageCnt: number, con: string) => {
try {
const coSttnMapRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/request/${pageNo}/${pageCnt}/${con}`
);
set((state: coSttnMapState) => {
return {
...state,
coSttnMap: {
...state.coSttnMap,
coSttnMapRes: coSttnMapRes.data,
isInit: false,
coSttnMapResCount: coSttnMapRes.count,
},
};
});
} catch (e) {
console.log(e)
}
},
coSttnMapSearch: async (pageNo: number, pageCnt: number, con: string) => {
try {
const coSttnMapRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/request/${pageNo}/${pageCnt}/${con}`
);
if (Number(pageCnt) >= 10000) {
set((state: coSttnMapState) => {
return {
...state,
coSttnMap: {
...state.coSttnMap,
excelList: coSttnMapRes.data,
//isInit: false,
},
};
});
} else
set((state: coSttnMapState) => {
return {
...state,
coSttnMap: {
...state.coSttnMap,
coSttnMapRes: coSttnMapRes.data,
isInit: false,
coSttnMapResCount: coSttnMapRes.count,
},
};
});
} catch (erTxt) {
console.log("error", erTxt);
}
},
coSttnMapTxtSearch: async (pageNo: number, pageCnt: number, con: string, txt: string) => {
try {
const coSttnMapRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/request/${pageNo}/${pageCnt}/${con}/${txt}`)
set((state: coSttnMapState) => {
return {
...state,
coSttnMap: {
...state.coSttnMap,
coSttnMapRes: coSttnMapRes.data,
coSttnMapResCount: coSttnMapRes.count,
isInit: false,
}
}
})
} catch (erTxt) {
console.log("error", erTxt);
}
},
}
}
+58
View File
@@ -0,0 +1,58 @@
export type comMapState = {
comMap: {
isFeatured:any
isModal:boolean
};
};
type comMapActions = {
selectFeature:(feature:any)=>void,
chModalOpen:(open:boolean) => void,
};
export type comMapType = comMapState & comMapActions;
export const comMapStateExport: comMapState = {
comMap: {
isFeatured:{},
isModal:false
},
};
export const commonMapActionsExport: (set: any) => comMapActions = (
set: any
) => {
return {
selectFeature:(feature:any) => {
try {
set((state: comMapState) => {
return {
...state,
comMap: {
...state.comMap,
isFeatured:feature
},
};
});
} catch (e) {
console.log(e)
}
},chModalOpen:(open:boolean) =>{
try {
set((state: comMapState) => {
return {
...state,
comMap: {
...state.comMap,
isModal:open
},
};
});
} catch (e) {
console.log(e)
}
}
}
}
+63
View File
@@ -0,0 +1,63 @@
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { CommonTableProps } from "../../common/type/header";
import type { customHtdflBdst } from "../../ruseFcltMng/fcltReg/htdflReg";
import { htdflSttHeadListExport, htdflSttNodeListExport } from "../../ruseFcltMng/fcltSttn/htdflSttn/headList";
export const htdfMapSize = 15;
export type htdfMapState = {
htdfMap: {
htdfMapRes: customHtdflBdst[];
htdfMapCount: number;
isInit: boolean;
htdfSttHeadList: CommonTableProps[];
htdfSttNodeList: CommonTableProps[];
};
};
type htdfMapActions = {
htdfMapInit: (page: number, total: number, cityOrSgg: string) => void;
};
export type htdfMapType = htdfMapState & htdfMapActions;
export const htdfMapStateExport: htdfMapState = {
htdfMap: {
isInit: false,
htdfMapRes: [],
htdfMapCount: 1,
htdfSttHeadList: htdflSttHeadListExport,
htdfSttNodeList: htdflSttNodeListExport,
},
};
export const htdfMapActionsExport: (set: any) => htdfMapActions = (
set: any
) => {
return {
htdfMapInit: async (page: number, total: number, cityOrSgg: string) => {
try {
const htdfMapRes = await getFetchWithCount(
fetchType.WR,
`/drain/facilityList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(cityOrSgg ? `/${cityOrSgg}` : "/0")
);
set((state: htdfMapState) => {
return {
...state,
htdfMap: {
...state.htdfMap,
htdfMapRes: htdfMapRes.data,
htdfMapCount: htdfMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e);
}
},
};
};
+102
View File
@@ -0,0 +1,102 @@
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { CommonTableProps } from "../../common/type/header";
import type { customLdrmnt } from "../../matDmd/ldrmntCoSttn";
import {
ldrmntHeadListExport,
ldrmntNodeListExport,
} from "../../matDmd/ldrmntCoSttn/headList";
export const ldrmntMapSize = 20;
export type ldrmntMapState = {
ldrmntMap: {
ldrmntMapHeadList: CommonTableProps[];
ldrmntMapNodeList: CommonTableProps[];
isInit: boolean;
ldrmntMapRes: customLdrmnt[];
ldrmntMapResCount: number;
};
};
type ldrmntMapActions = {
ldrmntMapInit: (page: number, total: number, con: string) => void;
ldrmntMapSearch: (
page: number,
total: number,
con: string,
coNm: string
) => void;
};
export type ldrmntMapType = ldrmntMapState & ldrmntMapActions;
export const ldrmntMapStateExport: ldrmntMapState = {
ldrmntMap: {
ldrmntMapHeadList: ldrmntHeadListExport,
ldrmntMapNodeList: ldrmntNodeListExport,
isInit: false,
ldrmntMapRes: [],
ldrmntMapResCount: 1,
},
};
export const ldrmntMapActionsExport: (set: any) => ldrmntMapActions = (
set: any
) => {
return {
ldrmntMapInit: async (page: number, total: number, con: string) => {
try {
const ldrmntMapRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/request/temp/${page}/${total}/${con}`
);
set((state: ldrmntMapState) => {
return {
...state,
ldrmntMap: {
...state.ldrmntMap,
ldrmntMapRes: ldrmntMapRes.data,
ldrmntMapResCount: ldrmntMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e);
}
},
ldrmntMapSearch: async (
page: number,
total: number,
con: string,
coNm: string
) => {
let searchUrl = "";
if (con !== "") {
if (coNm !== "") {
searchUrl = `/reuseFc/request/temp/${page}/${total}/${con}/${coNm}`;
} else {
searchUrl = `/reuseFc/request/temp/${page}/${total}/${con}`;
}
}
try {
const ldrmntMapRes = await getFetchWithCount(fetchType.WR, searchUrl);
set((state: ldrmntMapState) => {
return {
...state,
ldrmntMap: {
...state.ldrmntMap,
ldrmntMapRes: ldrmntMapRes.data,
ldrmntMapResCount: ldrmntMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e);
}
},
};
};
+108
View File
@@ -0,0 +1,108 @@
import { fetchType, postFectch } from "@/components/lib/api";
import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
import { checkWrRegList } from "../../ruseFcltMng/fcltReg/pbnstReg";
import type { ReturnType } from "@common/business_components/ui";
import { pubFacHeadListExport } from "../../ruseFcltMng/fcltReg/pbnstReg/headList";
import type { TableUpperProps } from "../../common/type/header";
export const pbnMapTableSize =20;
const hasuListFetch = async (page: number, pageTotal:number, reurnValue: ReturnType, searchNm?:string) => {
let url = `/prcsFclt/ruseInfo/${page}/${pageTotal}/`;
const checkWrRegListRes = await checkWrRegList();
if (reurnValue.partValue === "A") {
url += `${reurnValue.partValue}/${
// reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue
reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue
}/0/1/SW`
} else if (reurnValue.partValue === "R") {
url += `${reurnValue.partValue}/${reurnValue.regionValue
? reurnValue.regionValue
: reurnValue.unitWaterShedValue
? reurnValue.unitWaterShedValue
: reurnValue.middleRegionValue
}/0/1/SW`
} else if (reurnValue.partValue === 'G') {
url += `${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW`
} else {
url += `A/0/0/1/SW`
}
if (searchNm && searchNm?.length > 0) {
url += "/" + searchNm
}
const data = checkWrRegListRes.filter((item:string) => item !== "")
const rainRes = await postFectch(
url,
data,
fetchType.COMMON
);
const hasuList = rainRes.data.map((item: any) => {
return {
...item,
fctCpc: Number(item.fctCpc) || 0,
ruse: item.ruse === false ? "N" : "Y",
};
});
return {data: hasuList, count:rainRes.count};
};
export type pbnMapState = {
pbnMap: {
isInit:boolean,
pbnMapRes:pubHasuType[]
pbnMapCount:number;
pbnMapHeadList:TableUpperProps[];
};
};
type pbnMapActions = {
pbnMapInit: (page: number, pageTotal:number, reurnValue: ReturnType) => void;
};
export type pbnMapType = pbnMapState & pbnMapActions;
export const pbnMapStateExport: pbnMapState = {
pbnMap: {
isInit: false,
pbnMapRes:[],
pbnMapCount:1,
pbnMapHeadList:pubFacHeadListExport
},
};
export const pbnMapActionsExport: (set: any) => pbnMapActions = (
set: any
) => {
return {
pbnMapInit: async (page: number, pageTotal:number, reurnValue: ReturnType) => {
try {
const pubMapRes = await hasuListFetch(page,pageTotal,reurnValue)
set((state: pbnMapState) => {
return {
...state,
pbnMap: {
...state.pbnMap,
pbnMapRes: pubMapRes.data,
pbnMapCount: pubMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e)
}
},
}
}
+67
View File
@@ -0,0 +1,67 @@
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { CommonTableProps } from "../../common/type/header";
import {
rainSttHeadListExport,
rainSttNodeListExport,
} from "../../ruseFcltMng/fcltSttn/rainSttn/headList";
import type { customRainBdst } from "../../ruseFcltMng/fcltReg/rainReg";
export const rainMapSize = 15
export type rainMapState = {
rainMap: {
rainMapRes: customRainBdst[];
rainMapCount: number;
isInit: boolean;
rainSttHeadList: CommonTableProps[];
rainSttNodeList: CommonTableProps[];
};
};
type rainMapActions = {
rainMapInit: (page: number, total: number, cityOrSgg:string) => void;
};
export type rainMapType = rainMapState & rainMapActions;
export const rainMapStateExport: rainMapState = {
rainMap: {
isInit: false,
rainMapRes: [],
rainMapCount: 1,
rainSttHeadList: rainSttHeadListExport,
rainSttNodeList: rainSttNodeListExport,
},
};
export const rainMapActionsExport: (set: any) => rainMapActions = (
set: any
) => {
return {
rainMapInit: async (page: number, total: number, cityOrSgg:string) => {
try {
const rainMapRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(cityOrSgg ? `/${cityOrSgg}` : "/0")
);
set((state: rainMapState) => {
return {
...state,
rainMap: {
...state.rainMap,
rainMapRes: rainMapRes.data,
rainMapCount: rainMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e);
}
},
};
};
+64
View File
@@ -0,0 +1,64 @@
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { CommonTableProps } from "../../common/type/header";
import type { customRswtBdst } from "../../ruseFcltMng/fcltReg/rswtReg";
import { rswtSttHeadListExport, rswtSttNodeListExport } from "../../ruseFcltMng/fcltSttn/rswtSttn/headList";
export const rswtMapSize = 15
export type rswtMapState = {
rswtMap: {
rswtMapRes: customRswtBdst[];
rswtMapCount: number;
isInit: boolean;
rswtSttHeadList: CommonTableProps[];
rswtSttNodeList: CommonTableProps[];
};
};
type rswtMapActions = {
rswtMapInit: (page: number, total: number, cityOrSgg:string) => void;
};
export type rswtMapType = rswtMapState & rswtMapActions;
export const rswtMapStateExport: rswtMapState = {
rswtMap: {
isInit: false,
rswtMapRes: [],
rswtMapCount: 1,
rswtSttHeadList: rswtSttHeadListExport,
rswtSttNodeList: rswtSttNodeListExport,
},
};
export const rswtMapActionsExport: (set: any) => rswtMapActions = (
set: any
) => {
return {
rswtMapInit: async (page: number, total: number, cityOrSgg:string) => {
try {
const rswtMapRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(cityOrSgg ? `/${cityOrSgg}` : "/0")
);
set((state: rswtMapState) => {
return {
...state,
rswtMap: {
...state.rswtMap,
rswtMapRes: rswtMapRes.data,
rswtMapCount: rswtMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e);
}
},
};
};
+94
View File
@@ -0,0 +1,94 @@
import { fetchType, getFetch } from "@/components/lib/api";
import type { CommonTableProps } from "../../common/type/header";
import type { WaterReuseFacility } from "../../ruseFcltMng/fcltSttn/pbnstSttn/type";
import {
pbnstSttNodeListExport,
pbnSttHeadListExport,
} from "../../ruseFcltMng/fcltSttn/pbnstSttn/headList";
import type { ReturnType } from "@common/business_components/ui";
import { hasuListFetch } from "../../ruseFcltMng/fcltSttn/pbnstSttn";
export const ruseMapSize = 15;
export type ruseMapState = {
ruseMap: {
ruseMapRes: WaterReuseFacility[];
ruseMapCount: number;
isInit: boolean;
fclts: string[];
ruseMapHeadList: CommonTableProps[];
ruseMapNodeList: CommonTableProps[];
};
};
type ruseMapActions = {
getMapFlcts: () => void;
ruseMapInit: (
page: number,
total: number,
reurnValue: ReturnType,
year: string,
fclts: string[]
) => void;
};
export type ruseMapType = ruseMapState & ruseMapActions;
export const ruseMapStateExport: ruseMapState = {
ruseMap: {
isInit: false,
ruseMapRes: [],
fclts: [],
ruseMapCount: 1,
ruseMapHeadList: pbnSttHeadListExport,
ruseMapNodeList: pbnstSttNodeListExport,
},
};
export const ruseMapActionsExport: (set: any) => ruseMapActions = (
set: any
) => {
return {
getMapFlcts: async () => {
const fclts = await getFetch(fetchType.WR, "/reuseFc/pubFc");
return set((state: ruseMapState) => ({
ruseMap: {
...state.ruseMap,
fclts: fclts,
},
}));
},
ruseMapInit: async (
page: number,
total: number,
reurnValue: ReturnType,
year: string,
fclts: string[]
) => {
try {
const ruseMapRes = await hasuListFetch(
String(page),
String(total),
reurnValue,
undefined,
year,
fclts
);
set((state: ruseMapState) => {
return {
...state,
ruseMap: {
...state.ruseMap,
ruseMapRes: ruseMapRes.data,
ruseMapCount: ruseMapRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e);
}
},
};
};
@@ -97,7 +97,7 @@ export const pubFacStateExport: pubFacState = {
},
};
const checkWrRegList = async () => {
export const checkWrRegList = async () => {
const wrRegList = await getFetch("wr", `/reuseFc/pubFc`);
return wrRegList;
};
@@ -87,7 +87,7 @@ export const pbnstSttnStateExport: pbnstSttnState = {
},
};
const hasuListFetch = async (
export const hasuListFetch = async (
page: string,
total: string,
reurnValue: ReturnType,
+199 -52
View File
@@ -11,19 +11,54 @@ import {
type comCodeState,
type comCodeType,
} from "./common/code";
import { comFcltSearchAction, comFcltStateExport, type comFcltState, type comFcltType } from "./common/searchCode";
import {
comFcltSearchAction,
comFcltStateExport,
type comFcltState,
type comFcltType,
} from "./common/searchCode";
import {
matDmdActionsExport,
matDmdStateExport,
type matDmdState,
type matDmdType,
} from "./matDmd";
import { coRvwActionsExport, coRvwStateExport, type coRvwState, type coRvwType } from "./matDmd/coMatRvw";
import { coSttnActionsExport, coSttnStateExport, type coSttnState, type coSttnType } from "./matDmd/coSttn"; // 옮겨야함
import { drgtActionsExport, drgtStateExport, type drgtState, type drgtType } from "./matDmd/drgtSttn";
import { ldrmntActionsExport, ldrmntStateExport, type ldrmntState, type ldrmntType } from "./matDmd/ldrmntCoSttn";
import { ruseCaseActionsExport, ruseCaseStateExport, type ruseCaseState, type ruseCaseType } from "./matDmd/ruseCaseMng";
import { ruseHstryActionsExport, ruseHstryStateExport, type ruseHstryState, type ruseHstryType } from "./matDmd/ruseRvwHstry";
import {
coRvwActionsExport,
coRvwStateExport,
type coRvwState,
type coRvwType,
} from "./matDmd/coMatRvw";
import {
coSttnActionsExport,
coSttnStateExport,
type coSttnState,
type coSttnType,
} from "./matDmd/coSttn"; // 옮겨야함
import {
drgtActionsExport,
drgtStateExport,
type drgtState,
type drgtType,
} from "./matDmd/drgtSttn";
import {
ldrmntActionsExport,
ldrmntStateExport,
type ldrmntState,
type ldrmntType,
} from "./matDmd/ldrmntCoSttn";
import {
ruseCaseActionsExport,
ruseCaseStateExport,
type ruseCaseState,
type ruseCaseType,
} from "./matDmd/ruseCaseMng";
import {
ruseHstryActionsExport,
ruseHstryStateExport,
type ruseHstryState,
type ruseHstryType,
} from "./matDmd/ruseRvwHstry";
import {
rainChkgdnActionsExport,
rainChkgdnStateExport,
@@ -36,15 +71,30 @@ import {
type rswtChkgdnState,
type rswtChkgdnType,
} from "./prfmncReg/chkgdnReg/rswrtChkgdn";
import { pbnstPrfmncActionsExport, pbnstPrfmncStateExport, type pbnstPrfmncState, type pbnstPrfmncType } from "./prfmncReg/pbnstPrfmncReg";
import {
pbnstPrfmncActionsExport,
pbnstPrfmncStateExport,
type pbnstPrfmncState,
type pbnstPrfmncType,
} from "./prfmncReg/pbnstPrfmncReg";
import {
rainChkSttnActionsExport,
rainChkSttnStateExport,
type rainChkSttnState,
type rainChkSttnType,
} from "./prfmncSttn/chkgdnSttn/rainChkgdnSttn";
import { rswtChkStateExport, rswtChkSttnActionsExport, type rswtChkSttnState, type rswtChkSttnType } from "./prfmncSttn/chkgdnSttn/rswtChkgdnSttn";
import { pbnstPrfmncSttnActionsExport, pbnstPrfmncSttnExport, type pbnstPrfmncSttnState, type pbnstPrfmncSttnType } from "./prfmncSttn/pbnstPrfmncSttn";
import {
rswtChkStateExport,
rswtChkSttnActionsExport,
type rswtChkSttnState,
type rswtChkSttnType,
} from "./prfmncSttn/chkgdnSttn/rswtChkgdnSttn";
import {
pbnstPrfmncSttnActionsExport,
pbnstPrfmncSttnExport,
type pbnstPrfmncSttnState,
type pbnstPrfmncSttnType,
} from "./prfmncSttn/pbnstPrfmncSttn";
import {
bdstActionsExport,
bdstStateExport,
@@ -81,7 +131,12 @@ import {
type htdflSttnState,
type htdflSttnType,
} from "./ruseFcltMng/fcltSttn/htdflSttn";
import { pbnstSttnActionsExport, pbnstSttnStateExport, type pbnstSttnState, type pbnstSttnType } from "./ruseFcltMng/fcltSttn/pbnstSttn";
import {
pbnstSttnActionsExport,
pbnstSttnStateExport,
type pbnstSttnState,
type pbnstSttnType,
} from "./ruseFcltMng/fcltSttn/pbnstSttn";
import {
rainSttnActionsExport,
rainSttnStateExport,
@@ -94,11 +149,74 @@ import {
type rswtSttnState,
type rswtSttnType,
} from "./ruseFcltMng/fcltSttn/rswtSttn";
import { rainStatActionsExport, rainStatExport, type rainStatState, type rainStatType } from "./stats/rainStat";
import { rswtStatActionsExport, rswtStatExport, type rswtStatState, type rswtStatType } from "./stats/rswtStat";
import {
rainStatActionsExport,
rainStatExport,
type rainStatState,
type rainStatType,
} from "./stats/rainStat";
import {
rswtStatActionsExport,
rswtStatExport,
type rswtStatState,
type rswtStatType,
} from "./stats/rswtStat";
//import { isLogin } from "./common/login";
import { LoginApi } from "@/src/entities/auth";
import { authActionsExport, authStateExport, type authState, type authType } from "./common/auth";
import {
authActionsExport,
authStateExport,
type authState,
type authType,
} from "./common/auth";
import {
pbnMapActionsExport,
pbnMapStateExport,
type pbnMapState,
type pbnMapType,
} from "./map/pbnstMap";
import {
comMapStateExport,
commonMapActionsExport,
type comMapState,
type comMapType,
} from "./map/common";
import {
rainMapActionsExport,
rainMapStateExport,
type rainMapState,
type rainMapType,
} from "./map/rainMap";
import {
rswtMapActionsExport,
rswtMapStateExport,
type rswtMapState,
type rswtMapType,
} from "./map/rswtMap";
import {
htdfMapActionsExport,
htdfMapStateExport,
type htdfMapState,
type htdfMapType,
} from "./map/htdflMap";
import {
ruseMapActionsExport,
ruseMapStateExport,
type ruseMapState,
type ruseMapType,
} from "./map/ruseMap";
import {
coSttnMapActionsExport,
coSttnMapStateExport,
type coSttnMapState,
type coSttnMapType,
} from "./map/coSttnMap";
import {
ldrmntMapActionsExport,
ldrmntMapStateExport,
type ldrmntMapState,
type ldrmntMapType,
} from "./map/ldrmntCoMap";
export type WrStore = comCodeType &
pubFacType &
@@ -112,23 +230,29 @@ export type WrStore = comCodeType &
rainSttnType &
rswtSttnType &
htdflSttnType &
rainChkSttnType&
rswtChkSttnType&
pbnstSttnType&
coSttnType& // 옮겨야함
ldrmntType& // 옮겨야함
pbnstPrfmncType&
coRvwType&
ruseHstryType&
pbnstPrfmncSttnType&
drgtType&
ruseCaseType&
rainStatType&
rswtStatType&
rainChkSttnType &
rswtChkSttnType &
pbnstSttnType &
coSttnType & // 옮겨야함
ldrmntType & // 옮겨야함
pbnstPrfmncType &
coRvwType &
ruseHstryType &
pbnstPrfmncSttnType &
drgtType &
ruseCaseType &
rainStatType &
rswtStatType &
comFcltType &
authType
;
pbnMapType &
comMapType &
rainMapType &
rswtMapType &
htdfMapType &
ruseMapType &
coSttnMapType &
ldrmntMapType &
authType;
export const StoreZus = (
initState: comCodeState &
@@ -143,22 +267,29 @@ export const StoreZus = (
rainSttnState &
rswtSttnState &
htdflSttnState &
rainChkSttnState&
comFcltState&
rainChkSttnState &
comFcltState &
rswtChkSttnState &
pbnstSttnState&
coSttnState& // 옮겨야함
ldrmntState& // 옮겨야함
pbnstPrfmncState&
coRvwState&
ruseHstryState&
pbnstPrfmncSttnState&
drgtState&
ruseCaseState&
rainStatState&
rswtStatState&
authState
= {
pbnstSttnState &
coSttnState & // 옮겨야함
ldrmntState & // 옮겨야함
pbnstPrfmncState &
coRvwState &
ruseHstryState &
pbnstPrfmncSttnState &
drgtState &
ruseCaseState &
rainStatState &
rswtStatState &
pbnMapState &
comMapState &
rainMapState &
rswtMapState &
htdfMapState &
ruseMapState &
coSttnMapState &
ldrmntMapState &
authState = {
...comCodeStateExport,
...pubFacStateExport,
...rainFacStateExport,
@@ -174,8 +305,8 @@ export const StoreZus = (
...rainChkSttnStateExport,
...rswtChkStateExport,
...pbnstSttnStateExport,
...coSttnStateExport, // 옮겨야함
...ldrmntStateExport, // 옮겨야함
...coSttnStateExport,
...ldrmntStateExport,
...pbnstPrfmncStateExport,
...coRvwStateExport,
...ruseHstryStateExport,
@@ -185,7 +316,15 @@ export const StoreZus = (
...rainStatExport,
...rswtStatExport,
...comFcltStateExport,
...authStateExport
...pbnMapStateExport,
...comMapStateExport,
...authStateExport,
...rainMapStateExport,
...rswtMapStateExport,
...htdfMapStateExport,
...ruseMapStateExport,
...coSttnMapStateExport,
...ldrmntMapStateExport,
}
) => {
return createStore<WrStore>()((set) => {
@@ -195,7 +334,7 @@ export const StoreZus = (
getMiddleRegionCd(set);
getUnitWaterShedCd(set);
getEnvPartCd(set);
LoginApi.login({userId: "CLEANWATER", password: "gktneh12!@"})
LoginApi.login({ userId: "CLEANWATER", password: "gktneh12!@" });
return {
...initState,
...comFcltSearchAction(set),
@@ -214,8 +353,8 @@ export const StoreZus = (
...rainChkSttnActionsExport(set),
...rswtChkSttnActionsExport(set),
...pbnstSttnActionsExport(set),
...coSttnActionsExport(set), // 옮겨야함
...ldrmntActionsExport(set), // 옮겨야함
...coSttnActionsExport(set), // 옮겨야함
...ldrmntActionsExport(set), // 옮겨야함
...pbnstPrfmncActionsExport(set),
...coRvwActionsExport(set),
...ruseHstryActionsExport(set),
@@ -224,7 +363,15 @@ export const StoreZus = (
...ruseCaseActionsExport(set),
...rainStatActionsExport(set),
...rswtStatActionsExport(set),
...authActionsExport(set)
...authActionsExport(set),
...commonMapActionsExport(set),
...pbnMapActionsExport(set),
...rainMapActionsExport(set),
...rswtMapActionsExport(set),
...htdfMapActionsExport(set),
...ruseMapActionsExport(set),
...coSttnMapActionsExport(set),
...ldrmntMapActionsExport(set),
};
});
};
@@ -0,0 +1,195 @@
import { useWrStore } from "@/app/store";
import { costtnMapSize } from "@/app/store/map/coSttnMap";
import {
formatPhoneNumber,
getCity,
tableData,
} from "@/components/lib/func/commom";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
SearchDiv,
SearchFormLeft,
SearchFormRight,
SearchInput,
SelectBox,
Title,
UiTable,
type SelectDataType,
} from "@common/business_components/ui";
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import { Button } from "@common/components/ui";
import moment from "moment";
import { useCallback, useEffect, useState } from "react";
export function CoSttnMap({
rtnFeature,
}: {
rtnFeature: (feature: any) => void;
}) {
const {
code,
coSttnMap,
coSttnMapInit,
coSttnMapSearch,
coSttnMapTxtSearch,
} = useWrStore((state) => state);
const [coSttnMapTable, setCoSttnMapTable] = useState<DemandCompType[]>();
const [isReset, setIsReset] = useState(false);
const { coSttMapHeadList, coSttnMapRes, coSttnMapResCount } = coSttnMap;
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>();
const [objSearch, setObjSearch] = useState<objSearchType>({
sgg: "",
city: "",
});
const [seartchTxt, setSearchTxt] = useState<string>();
const getSelCity = useCallback(
(val: string | number) => {
const cityValue = String(val);
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
setObjSearch({ city: cityValue, sgg: "0" });
},
[code.sggCd]
);
const getSgg = useCallback((val: string | number) => {
setObjSearch((prev) => ({ ...prev, sgg: String(val) }));
}, []);
useEffect(() => {
// code.cityCd 데이터가 로드되었고, 아직 시/도 선택이 안된 초기 상태일 때 실행
if (code.cityCd && code.cityCd.length > 0 && !objSearch.city) {
const firstCityVal = code.cityCd[0]?.val;
if (firstCityVal) {
// 첫 번째 시/도 값으로 상태를 초기화합니다.
getSelCity(firstCityVal);
}
}
}, [code.cityCd, objSearch.city, getSelCity]);
useEffect(() => {
if (!coSttnMap.isInit) {
coSttnMapInit(1, costtnMapSize, "0");
}
}, [coSttnMap.isInit, coSttnMapInit]);
const coSttnMapCellClick = (index: number | undefined) => {
if (index !== undefined && coSttnMapTable !== undefined) {
rtnFeature(coSttnMapTable[index]);
}
};
useEffect(() => {
if (coSttnMapRes) {
if (coSttnMapRes?.length > 0 && code.cityCd.length > 0) {
const data = tableData(coSttnMapRes, { code });
const chData = data.map((item: any) => ({
...item,
telno: formatPhoneNumber(item.telno || undefined),
regDt: moment(item.regDt).format("YYYY-MM-DD"),
dmdInfoId: `${item.dmdInfoId.slice(0, 3)}-${item.dmdInfoId.slice(3, 5)}-${item.dmdInfoId.slice(5, 10)}-${item.dmdInfoId.slice(10)}`,
}));
// .filter((item: any) => item !== undefined);
setCoSttnMapTable(chData);
}
}
}, [coSttnMapRes, code]);
return (
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
<div className="col-span-4">
<Title title={"수요처 관리"} />
<SearchDiv>
<SearchFormLeft>
<div className="col-span-10 flex flex-row">
<SelectBox
className="col-span-3 w-1/6 h-full text-2xl"
label="시도"
selectClass={""}
selectArray={code.cityCd || []}
onSelectValue={(val) => {
getSelCity(val);
}}
value={objSearch.city}
/>
<SelectBox
className="col-span-3 w-1/6 h-full text-2xl ml-4"
label="시군구"
selectClass={""}
selectArray={selectSgg || []}
onSelectValue={getSgg}
value={objSearch.sgg}
/>
<SearchInput
className={"!text-3xl ml-4"}
label="회사명"
textValue={seartchTxt ?? ""}
setText={(e) => {
setSearchTxt(e);
}}
/>
</div>
</SearchFormLeft>
<SearchFormRight className="w-3/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<div className="flex flex-row space-x-2">
<Button
className="mt-2"
size={"sm"}
onClick={() => {
const con =
objSearch.sgg && objSearch.sgg !== "0"
? objSearch.sgg
: objSearch.city;
if (con) {
if (seartchTxt && seartchTxt?.length > 0) {
coSttnMapTxtSearch(
1,
costtnMapSize,
String(con),
seartchTxt ?? ""
);
} else {
coSttnMapSearch(1, costtnMapSize, String(con));
}
setIsReset(true)
}
}}
>
조회
</Button>
</div>
</SearchFormRight>
</SearchDiv>
</div>
</div>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<UiTable
headName={[]}
tableData={coSttnMapTable || []}
headlist={coSttMapHeadList}
pageSize={20}
total={coSttnMapResCount|| 0}
cellClick={(index: number | undefined) => {
coSttnMapCellClick(index);
// setUpdateData(coSttnRes[index as number]);
}}
onPageChange={(page) => {
const con =
objSearch.sgg && objSearch.sgg !== "0"
? objSearch.sgg
: objSearch.city;
coSttnMapSearch(page, costtnMapSize, String(con));
setIsReset(false);
}}
resetPageNo={isReset}
></UiTable>
</div>
</div>
</ContentsDiv>
</>
);
}
@@ -0,0 +1,109 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import { pbnMapTableSize } from "@/app/store/map/pbnstMap";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { tableData } from "@/components/lib/func/commom";
import {
ContentsDiv,
SearchBaseForm,
SearchInput,
Title,
UiTable,
type ReturnType,
} from "@common/business_components/ui";
import { Label } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
export function HasuFacility({rtnFeature}:{rtnFeature:(feature:any)=>void } ) {
const { code, pbnMap, pbnMapInit } = useWrStore((state) => state);
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
const [isReset, setIsReset] = useState(false);
const [pbnRuseNm, setPbnRuseNm] = useState<string>("");
const ref = useRef<ReturnType>({} as ReturnType);
const { pbnMapHeadList, pbnMapRes, pbnMapCount } = pbnMap;
useEffect(() => {
if (!pbnMap.isInit) {
pbnMapInit(1, pbnMapTableSize, ref.current);
}
}, [pbnMap.isInit, pbnMapInit]);
useEffect(() => {
if (code.sggCd.length && pbnMapRes.length > 0) {
setHasuTable(tableData(pbnMapRes, { code }));
}
}, [code, pbnMapRes]);
const hasuCellClick = (index: number | undefined) => {
if (index !== undefined && pbnMapRes !== undefined) {
rtnFeature(pbnMapRes[index])
}
};
return (
<>
<ContentsDiv>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<Title title="하수처리시설 현황" />
<SearchBaseForm
selectSidoData={code.cityCd}
selectSigunData={code.sggCd}
selectRegionData={code.rvbsnCd}
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
buttonOrder={["query", "init", "excel"]}
rightClassName="ml-auto mr-6 flex items-center space-x-1"
leftClassName="flex gap-5 w-9/12 m-4"
leftSelectClassName="w-1/4"
rightChildren={<></>}
leftChildren={
<div className="col-span-3 flex items-center">
<Label className="w-full mt-2 ml-4 text-xl text-gray-600">
{"하수처리시설명"}
</Label>
<SearchInput
className={"text-2xl w-full"}
label=""
textValue={pbnRuseNm || ""}
setText={(e) => {
setPbnRuseNm(e || "");
}}
/>
</div>
}
queryClick={() => {
setIsReset(true);
}}
initClick={function (): void {
setPbnRuseNm("");
}}
btnClass={btnClass}
ref={ref}
isAdmin={false}
excelClick={function (returnType: ReturnType): void {
console.log("pbnstSttnSearch ", returnType);
}}
/>
</div>
<div className="col-span-6">
{/* 높이 조정 */}
<UiTable
tableData={hasuTable || []}
headlist={pbnMapHeadList}
pageSize={pbnMapTableSize}
total={pbnMapCount || 0}
headName={""}
cellClick={hasuCellClick}
onPageChange={(page) => {
pbnMapInit(page, pbnMapTableSize, ref.current);
setIsReset(false);
}}
resetPageNo={isReset}
/>
</div>
</div>
</ContentsDiv>
</>
);
}
@@ -0,0 +1,77 @@
import { useWrStore } from "@/app/store";
import { rainMapSize } from "@/app/store/map/rainMap";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import { tableData } from "@/components/lib/func/commom";
import { Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
export function HtdflFacility({
rtnFeature,
}: {
rtnFeature: (feature: any) => void;
}) {
const { code, htdfMap, htdfMapInit } = useWrStore((state) => state);
const { htdfMapCount, htdfMapRes, htdfSttHeadList, htdfSttNodeList } =
htdfMap;
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
const [isReset, setIsReset] = useState(false);
const htdflCellClick = (index: number | undefined) => {
if (index !== undefined && htdflTable !== undefined) {
rtnFeature(htdflTable[index]);
}
};
useEffect(() => {
if (!htdfMap.isInit) {
htdfMapInit(1, rainMapSize, "0");
}
}, [htdfMap.isInit, htdfMapInit]);
useEffect(() => {
const data = tableData(htdfMapRes, { code });
const chData = data
.map((item: any) => ({
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].htdflObj,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
}))
.filter((item: any) => item.htdflObj !== undefined);
setHtdflTable(chData);
}, [code, htdfMapRes]);
return (
<>
<div style={{ overflowY: "auto" }}>
<div className="flex justify-between items-center">
<Title title="온배수시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={htdflTable || []}
headlist={htdfSttHeadList}
pageSize={rainMapSize}
total={htdfMapCount}
cellClick={(index: number | undefined) => {
htdflCellClick(index ?? undefined);
}}
onPageChange={(page) => {
htdfMapInit(page, rainMapSize, "0");
setIsReset(false);
}}
resetPageNo={isReset}
>
<HeadMakeColSpan upHeadList={htdfSttNodeList} />
</UiTable>
</div>
</>
);
}
@@ -0,0 +1,189 @@
import { useWrStore } from "@/app/store";
import { ldrmntMapSize } from "@/app/store/map/ldrmntCoMap";
import type { customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn";
import { getCity, tableData } from "@/components/lib/func/commom";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
SearchDiv,
SearchFormLeft,
SearchFormRight,
SearchInput,
SelectBox,
Title,
UiTable,
type SelectDataType,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button } from "@common/components/ui";
import { useEffect, useState } from "react";
export function LdrmntCoMap({
rtnFeature,
}: {
rtnFeature: (feature: any) => void;
}) {
const { code, ldrmntMap, ldrmntMapInit, ldrmntMapSearch } = useWrStore(
(state) => state
);
const { ldrmntMapRes, ldrmntMapResCount, ldrmntMapHeadList } = ldrmntMap;
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>();
const [objSearch, setObjSearch] = useState<objSearchType>({
sgg: "",
city: "",
});
const [bdstTable, setBdstTable] = useState<customLdrmnt[]>();
const [searchTxt, setSearchTxt] = useState<string>();
const [resetPage, isResetPage] = useState(false);
const computeCityNm = () => {
let cityTxt = "";
let sggTxt = "";
if (objSearch.city) {
cityTxt = code.cityCd.find((c) => c.val === objSearch.city)?.text || "";
}
if (objSearch.sgg) {
sggTxt = code.sggCd.find((s) => s.val === objSearch.sgg)?.text || "";
}
if (cityTxt === "" || cityTxt === "전체") cityTxt = "0";
return sggTxt && sggTxt !== "0" ? `${cityTxt} ${sggTxt}` : cityTxt;
};
const cellClick = (index: number | undefined) => {
if (index !== undefined) {
rtnFeature(ldrmntMapRes[index]);
}
};
const getSelCity = (val: string | number) => {
const cityValue = String(val);
if (cityValue === "0") {
setSelectSgg([]);
setObjSearch({ city: cityValue, sgg: "" });
} else {
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
const firstSggVal =
data.find((item) => item.val === "0")?.val || (data[0]?.val ?? "");
setObjSearch({ city: cityValue, sgg: firstSggVal });
}
};
const getSgg = (val: string | number) => {
setObjSearch({ ...objSearch, sgg: String(val) });
};
useEffect(() => {
if (!ldrmntMap.isInit) {
ldrmntMapInit(1, ldrmntMapSize, "0");
}
}, [ldrmntMap.isInit, ldrmntMapInit]);
useEffect(() => {
const transData = Array.isArray(ldrmntMapRes)
? ldrmntMapRes
: [ldrmntMapRes];
const data = tableData(transData, { code });
const tbData = Array.isArray(data)
? data.map((item: customLdrmnt) => ({
...item,
ctpvCd: item.fctryAddr?.split(" ")[0] || "",
sggCd: item.fctryAddr?.split(" ")[1] || "",
}))
: [];
setBdstTable(tbData);
}, [ldrmntMapRes, code]);
return (
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
<div className="col-span-4">
<Title title={"잠재수요처 관리"} />
<SearchDiv>
<SearchFormLeft>
<div className="col-span-10 flex flex-row">
<SelectBox
className="col-span-2 w-1/6 h-full text-2xl"
label="시도"
selectClass={""}
selectArray={code.cityCd}
onSelectValue={getSelCity}
/>
<SelectBox
className="col-span-2 w-1/6 h-full text-2xl ml-4"
label="시군구"
selectClass={""}
selectArray={selectSgg || []}
value={objSearch.sgg} // value props 추가
onSelectValue={getSgg}
/>
<SearchInput
className={"text-2xl ml-4"}
label="회사명"
textValue={searchTxt || ""}
setText={(e) => {
setSearchTxt(e);
}}
/>
</div>
</SearchFormLeft>
<SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<div className="flex flex-row space-x-2 items-center">
<Button
size={"sm"}
onClick={() => {
ldrmntMapSearch(
1,
ldrmntMapSize,
computeCityNm(),
searchTxt || ""
);
isResetPage(true);
}}
>
조회
</Button>
</div>
</SearchFormRight>
</SearchDiv>
</div>
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<div className="overflow-x-auto">
<ListDiv className="min-w-max">
<UiTable
headName={undefined}
tableData={bdstTable || []}
headlist={ldrmntMapHeadList}
pageSize={20}
total={ldrmntMapResCount || 0}
cellClick={(index: number | undefined) => {
cellClick(index ?? undefined);
}}
onPageChange={(page) => {
ldrmntMapSearch(
page,
ldrmntMapSize,
computeCityNm(),
searchTxt || ""
);
isResetPage(false);
}}
resetPageNo={resetPage}
/>
</ListDiv>
</div>
</div>
</div>
</ContentsDiv>
</>
);
}
@@ -0,0 +1,102 @@
import { useWrStore } from "@/app/store";
import { rainMapSize } from "@/app/store/map/rainMap";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { tableData } from "@/components/lib/func/commom";
import { ContentsDiv, Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
export function RainFacility({
rtnFeature,
}: {
rtnFeature: (feature: any) => void;
}) {
const { code, rainMap, rainMapInit } = useWrStore((state) => state);
const { rainMapRes, rainMapCount, rainSttHeadList, rainSttNodeList } =
rainMap;
const [rainTable, setRainTable] = useState<customRainBdst[]>();
const [isReset, setIsReset] = useState(false);
useEffect(() => {
if (!rainMap.isInit) {
rainMapInit(1, rainMapSize, "0");
}
}, [rainMapInit, rainMap.isInit]);
const rainCellClick = (index: number | undefined, headId: string) => {
if (
index !== undefined &&
rainTable !== undefined &&
headId !== "chBuildingYn"
) {
rtnFeature(rainTable[index]);
}
};
useEffect(() => {
const data = tableData(rainMapRes, { code });
const chData = data
.map((item: any) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].rainyObj,
dtfcltCpct:
item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst:
item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt:
item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
pntfColArea:
item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct:
item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea:
Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
};
})
.filter((item: any) => item.rainyObj !== undefined);
setRainTable(chData);
}, [code, rainMapRes]);
return (
<>
<ContentsDiv>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<Title title="빗물이용시설 현황" />
<UiTable
headName={[]}
tableData={rainTable || []}
headlist={rainSttHeadList}
pageSize={20}
total={rainMapCount}
cellClick={(index: number | undefined, headId: string) => {
rainCellClick(index ?? undefined, headId);
}}
onPageChange={(page) => {
rainMapInit(page, rainMapSize, "0");
setIsReset(false);
}}
resetPageNo={isReset}
>
<HeadMakeColSpan upHeadList={rainSttNodeList} />
</UiTable>
</div>
</div>
</ContentsDiv>
</>
);
}
@@ -0,0 +1,99 @@
import { useWrStore } from "@/app/store";
import { rainMapSize } from "@/app/store/map/rainMap";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { tableData } from "@/components/lib/func/commom";
import { Title, UiTable } from "@common/business_components/ui";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { useEffect, useState } from "react";
export function RswtFacility({
rtnFeature,
}: {
rtnFeature: (feature: any) => void;
}) {
const { code, rswtMap, rswtMapInit } = useWrStore((state) => state);
const { rswtMapRes, rswtMapCount, rswtSttHeadList, rswtSttNodeList } =
rswtMap;
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>();
const [isReset, setIsReset] = useState(false);
const rswtCellClick = (index: number | undefined, headId: string) => {
if (
headId !== "chBuildingYn" &&
index !== undefined &&
rswtrTable !== undefined
) {
rtnFeature(rswtrTable[index]);
}
};
useEffect(() => {
if (!rswtMap.isInit) {
rswtMapInit(1, rainMapSize, "0");
}
}, [rswtMapInit, rswtMap.isInit]);
useEffect(() => {
const data = tableData(rswtMapRes, { code });
const chData = data
.map((item: customRswtBdst) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0]?.rswtrObj,
chBuildingYn:
item?.chgBuilding[0]?.bdstChgNm !== null &&
item?.chgBuilding.length > 0
? "Y"
: "N",
instlCst:
item.reuseBuilding[0]?.instlCst === -1
? "확인불가"
: item.reuseBuilding[0]?.instlCst,
instlCstSprtAmt:
item.reuseBuilding[0]?.instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0]?.instlCstSprtAmt,
archArea:
item?.archArea.split(".")[0] !== "-1"
? item?.archArea.split(".")[0]
: "확인불가",
};
})
.filter(
(item: customRswtBdst) => item.reuseBuilding[0]?.rswtrObj !== undefined
);
setRswtrTable(chData);
}, [code, rswtMapRes]);
return (
<>
<div style={{ overflowY: "auto" }}>
<div className="flex justify-between items-center">
<Title title="중수도시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rswtrTable || []}
headlist={rswtSttHeadList}
pageSize={20}
total={rswtMapCount}
cellClick={(index: number | undefined, headId: string) => {
rswtCellClick(index, headId);
}}
onPageChange={(page) => {
rswtMapInit(page, rainMapSize, "0");
setIsReset(false);
}}
resetPageNo={isReset}
>
<HeadMakeColSpan upHeadList={rswtSttNodeList} />
</UiTable>
</div>
</>
);
}
@@ -0,0 +1,140 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import { ruseMapSize } from "@/app/store/map/ruseMap";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { yearOptions } from "@/components/lib/func/commom";
import {
ContentsDiv,
SearchBaseForm,
SearchInput,
SelectBox,
Title,
UiTable,
type ReturnType,
} from "@common/business_components/ui";
import { Label } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
export function RuseFacility({
rtnFeature,
}: {
rtnFeature: (feature: any) => void;
}) {
const { code, ruseMap, ruseMapInit, getMapFlcts } = useWrStore(
(state) => state
);
const { ruseMapCount, fclts, ruseMapRes,ruseMapHeadList } = ruseMap;
const [ruseTable, setRuseTable] = useState<WaterReuseFacility[]>();
const [isReset, setIsReset] = useState(false);
const ref = useRef<ReturnType>({} as ReturnType);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
const [pbnRuseNm, setPbnRuseNm] = useState<string>("");
const ruseCellClick = (index: number | undefined) => {
if (
index !== undefined &&
ruseTable !== undefined
) {
rtnFeature(ruseTable[index]);
}
};
useEffect(() => {
if (!ruseMap.isInit) {
getMapFlcts();
}
}, [ruseMap.isInit]);
useEffect(() => {
ruseMapInit(1,ruseMapSize, ref.current, searchYear, fclts);
}, [fclts]);
useEffect(() => {
if (ruseMapRes && ruseMapRes.length > 0) {
setRuseTable(ruseMapRes);
} else {
setRuseTable([]);
}
}, [ruseMapRes]);
return (
<>
<ContentsDiv>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<Title title="하수재이용 시설 현황" />
<SearchBaseForm
selectSidoData={code.cityCd}
selectSigunData={code.sggCd}
selectRegionData={code.rvbsnCd}
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
buttonOrder={["query", "init", "excel"]}
rightClassName="ml-auto mr-6 flex items-center space-x-1"
leftClassName="flex gap-5 w-9/12 m-4"
leftSelectClassName="w-1/4"
rightChildren={<></>}
leftChildren={
<div className="col-span-3 flex items-center">
<SelectBox
className="w-48 h-full text-2xl"
label="연도"
selectClass={"w-full "}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
<Label className="w-full mt-2 ml-4 text-xl text-gray-600">
{"하수처리시설명"}
</Label>
<SearchInput
className={"text-2xl w-full"}
label=""
textValue={pbnRuseNm || ""}
setText={(e) => {
setPbnRuseNm(e || "");
}}
/>
</div>
}
queryClick={() => {
setIsReset(true);
}}
initClick={function (): void {
setPbnRuseNm("");
}}
btnClass={btnClass}
ref={ref}
isAdmin={false}
excelClick={function (returnType: ReturnType): void {
console.log("pbnstSttnSearch ", returnType);
}}
/>
</div>
<div className="col-span-6">
{/* 높이 조정 */}
<UiTable
tableData={ruseTable || []}
headlist={ruseMapHeadList}
pageSize={ruseMapSize}
total={ruseMapCount || 0}
headName={""}
cellClick={ruseCellClick}
onPageChange={(page) => {
ruseMapInit(page,ruseMapSize , ref.current, searchYear, fclts);
setIsReset(false);
}}
resetPageNo={isReset}
/>
</div>
</div>
</ContentsDiv>
</>
);
}
@@ -1,4 +1,4 @@
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { useWrStore } from "@/app/store";
import type { TableUpperProps } from "@/app/store/common/type/header";
import {
@@ -1,5 +1,5 @@
"use client";
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import type { TableUpperProps } from "@/app/store/common/type/header";
import type {
} from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
@@ -1,5 +1,5 @@
"use client";
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { useWrStore } from "@/app/store";
import type { TableUpperProps } from "@/app/store/common/type/header";
import { rainPageSize, type rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
@@ -1,5 +1,5 @@
"use client";
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { useWrStore } from "@/app/store";
import type { TableUpperProps } from "@/app/store/common/type/header";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
@@ -1,4 +1,4 @@
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import type { TableUpperProps } from "@/app/store/common/type/header";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
@@ -1,4 +1,4 @@
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import { headMakeprfmnc } from "@/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
import type { TableUpperProps } from "@/app/store/common/type/header";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";