diff --git a/apps/wr/app/(popUp-layout)/layerPopup/hasuFacility.tsx b/apps/wr/app/(popUp-layout)/layerPopup/hasuFacility.tsx new file mode 100644 index 000000000..5868b2ccc --- /dev/null +++ b/apps/wr/app/(popUp-layout)/layerPopup/hasuFacility.tsx @@ -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(); + const [isReset, setIsReset] = useState(false); + const [pbnRuseNm, setPbnRuseNm] = useState(""); + + const ref = useRef({} 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" ? ( + +
+
+ + <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; diff --git a/apps/wr/app/map/components/layerPopup/htdflFacility.tsx b/apps/wr/app/(popUp-layout)/layerPopup/htdflFacility.tsx similarity index 100% rename from apps/wr/app/map/components/layerPopup/htdflFacility.tsx rename to apps/wr/app/(popUp-layout)/layerPopup/htdflFacility.tsx diff --git a/apps/wr/app/map/components/layerPopup/rainFacility.tsx b/apps/wr/app/(popUp-layout)/layerPopup/rainFacility.tsx similarity index 100% rename from apps/wr/app/map/components/layerPopup/rainFacility.tsx rename to apps/wr/app/(popUp-layout)/layerPopup/rainFacility.tsx diff --git a/apps/wr/app/map/components/layerPopup/reuseFacility.tsx b/apps/wr/app/(popUp-layout)/layerPopup/reuseFacility.tsx similarity index 100% rename from apps/wr/app/map/components/layerPopup/reuseFacility.tsx rename to apps/wr/app/(popUp-layout)/layerPopup/reuseFacility.tsx diff --git a/apps/wr/app/map/components/layerPopup/reuseMngFacility.tsx b/apps/wr/app/(popUp-layout)/layerPopup/reuseMngFacility.tsx similarity index 100% rename from apps/wr/app/map/components/layerPopup/reuseMngFacility.tsx rename to apps/wr/app/(popUp-layout)/layerPopup/reuseMngFacility.tsx diff --git a/apps/wr/app/map/components/layerPopup/rswtFacility.tsx b/apps/wr/app/(popUp-layout)/layerPopup/rswtFacility.tsx similarity index 100% rename from apps/wr/app/map/components/layerPopup/rswtFacility.tsx rename to apps/wr/app/(popUp-layout)/layerPopup/rswtFacility.tsx diff --git a/apps/wr/app/(popUp-layout)/layout.tsx b/apps/wr/app/(popUp-layout)/layout.tsx new file mode 100644 index 000000000..d3804ac93 --- /dev/null +++ b/apps/wr/app/(popUp-layout)/layout.tsx @@ -0,0 +1,13 @@ +"use client"; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + <> + <div>{children}</div> + </> + ); +} diff --git a/apps/wr/app/(popUp-layout)/mapDetilePopUp/page.tsx b/apps/wr/app/(popUp-layout)/mapDetilePopUp/page.tsx new file mode 100644 index 000000000..68be4a266 --- /dev/null +++ b/apps/wr/app/(popUp-layout)/mapDetilePopUp/page.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/app/(popUp-layout)/mapDetilePopUp/qweqwe.tsx b/apps/wr/app/(popUp-layout)/mapDetilePopUp/qweqwe.tsx new file mode 100644 index 000000000..365c5ef5c --- /dev/null +++ b/apps/wr/app/(popUp-layout)/mapDetilePopUp/qweqwe.tsx @@ -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; \ No newline at end of file diff --git a/apps/wr/app/(popUp-layout)/newWindowPortal.tsx b/apps/wr/app/(popUp-layout)/newWindowPortal.tsx new file mode 100644 index 000000000..6fdabead6 --- /dev/null +++ b/apps/wr/app/(popUp-layout)/newWindowPortal.tsx @@ -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} + /> + ); +}; +*/ \ No newline at end of file diff --git a/apps/wr/app/map/util.ts b/apps/wr/app/(popUp-layout)/util.ts similarity index 100% rename from apps/wr/app/map/util.ts rename to apps/wr/app/(popUp-layout)/util.ts diff --git a/apps/wr/app/(with-layout)/layout.tsx b/apps/wr/app/(with-layout)/layout.tsx new file mode 100644 index 000000000..9c813f8ec --- /dev/null +++ b/apps/wr/app/(with-layout)/layout.tsx @@ -0,0 +1,18 @@ +"use client"; +import Base from "../base"; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + + + return ( + + <Base> + {children} + </Base> + + ); +} diff --git a/apps/wr/app/map/components/layerPopup/hasuFacility.tsx b/apps/wr/app/(with-layout)/map/components/layerPopup/hasuFacility.tsx similarity index 100% rename from apps/wr/app/map/components/layerPopup/hasuFacility.tsx rename to apps/wr/app/(with-layout)/map/components/layerPopup/hasuFacility.tsx diff --git a/apps/wr/app/(with-layout)/map/components/layerPopup/htdflFacility.tsx b/apps/wr/app/(with-layout)/map/components/layerPopup/htdflFacility.tsx new file mode 100644 index 000000000..fe4bef25a --- /dev/null +++ b/apps/wr/app/(with-layout)/map/components/layerPopup/htdflFacility.tsx @@ -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 \ No newline at end of file diff --git a/apps/wr/app/(with-layout)/map/components/layerPopup/rainFacility.tsx b/apps/wr/app/(with-layout)/map/components/layerPopup/rainFacility.tsx new file mode 100644 index 000000000..54b51e8a6 --- /dev/null +++ b/apps/wr/app/(with-layout)/map/components/layerPopup/rainFacility.tsx @@ -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; \ No newline at end of file diff --git a/apps/wr/app/(with-layout)/map/components/layerPopup/reuseFacility.tsx b/apps/wr/app/(with-layout)/map/components/layerPopup/reuseFacility.tsx new file mode 100644 index 000000000..152d37999 --- /dev/null +++ b/apps/wr/app/(with-layout)/map/components/layerPopup/reuseFacility.tsx @@ -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; \ No newline at end of file diff --git a/apps/wr/app/(with-layout)/map/components/layerPopup/reuseMngFacility.tsx b/apps/wr/app/(with-layout)/map/components/layerPopup/reuseMngFacility.tsx new file mode 100644 index 000000000..9030493ff --- /dev/null +++ b/apps/wr/app/(with-layout)/map/components/layerPopup/reuseMngFacility.tsx @@ -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 \ No newline at end of file diff --git a/apps/wr/app/(with-layout)/map/components/layerPopup/rswtFacility.tsx b/apps/wr/app/(with-layout)/map/components/layerPopup/rswtFacility.tsx new file mode 100644 index 000000000..dc2537c95 --- /dev/null +++ b/apps/wr/app/(with-layout)/map/components/layerPopup/rswtFacility.tsx @@ -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; \ No newline at end of file diff --git a/apps/wr/app/map/components/newWindowPopup.tsx b/apps/wr/app/(with-layout)/map/components/newWindowPopup.tsx similarity index 97% rename from apps/wr/app/map/components/newWindowPopup.tsx rename to apps/wr/app/(with-layout)/map/components/newWindowPopup.tsx index 21d31b984..11ca0f58f 100644 --- a/apps/wr/app/map/components/newWindowPopup.tsx +++ b/apps/wr/app/(with-layout)/map/components/newWindowPopup.tsx @@ -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; \ No newline at end of file +export default NewWindowPopup22; \ No newline at end of file diff --git a/apps/wr/app/map/components/newWindowPortal.tsx b/apps/wr/app/(with-layout)/map/components/newWindowPortal.tsx similarity index 95% rename from apps/wr/app/map/components/newWindowPortal.tsx rename to apps/wr/app/(with-layout)/map/components/newWindowPortal.tsx index 119e3a52b..6a9009c6b 100644 --- a/apps/wr/app/map/components/newWindowPortal.tsx +++ b/apps/wr/app/(with-layout)/map/components/newWindowPortal.tsx @@ -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; \ No newline at end of file +export default NewWindowPortal22; \ No newline at end of file diff --git a/apps/wr/app/map/mainMap/page.tsx b/apps/wr/app/(with-layout)/map/mainMap/page.tsx similarity index 74% rename from apps/wr/app/map/mainMap/page.tsx rename to apps/wr/app/(with-layout)/map/mainMap/page.tsx index e6f75feb0..dedcca225 100644 --- a/apps/wr/app/map/mainMap/page.tsx +++ b/apps/wr/app/(with-layout)/map/mainMap/page.tsx @@ -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 diff --git a/apps/wr/app/map/popup/page.tsx b/apps/wr/app/(with-layout)/map/popup/page.tsx similarity index 100% rename from apps/wr/app/map/popup/page.tsx rename to apps/wr/app/(with-layout)/map/popup/page.tsx diff --git a/apps/wr/app/map/service/index.ts b/apps/wr/app/(with-layout)/map/service/index.ts similarity index 100% rename from apps/wr/app/map/service/index.ts rename to apps/wr/app/(with-layout)/map/service/index.ts diff --git a/apps/wr/app/map/service/map.ts b/apps/wr/app/(with-layout)/map/service/map.ts similarity index 100% rename from apps/wr/app/map/service/map.ts rename to apps/wr/app/(with-layout)/map/service/map.ts diff --git a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx similarity index 100% rename from apps/wr/app/matMng/coMat/coMatRvw/page.tsx rename to apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx diff --git a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx similarity index 100% rename from apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx rename to apps/wr/app/(with-layout)/matMng/coMat/ruseCaseMng/page.tsx diff --git a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/ruseRvwHstry/page.tsx similarity index 100% rename from apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx rename to apps/wr/app/(with-layout)/matMng/coMat/ruseRvwHstry/page.tsx diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/(with-layout)/matMng/coMng/coSttn/page.tsx similarity index 100% rename from apps/wr/app/matMng/coMng/coSttn/page.tsx rename to apps/wr/app/(with-layout)/matMng/coMng/coSttn/page.tsx diff --git a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx b/apps/wr/app/(with-layout)/matMng/coMng/drgtSttn/page.tsx similarity index 100% rename from apps/wr/app/matMng/coMng/drgtSttn/page.tsx rename to apps/wr/app/(with-layout)/matMng/coMng/drgtSttn/page.tsx diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/(with-layout)/matMng/coMng/ldrmntCoSttn/page.tsx similarity index 100% rename from apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx rename to apps/wr/app/(with-layout)/matMng/coMng/ldrmntCoSttn/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/htdflReg/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/htdflReg/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx similarity index 99% rename from apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx index d08d6f06e..688fb836c 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -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"; diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/TableHead.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/TableHead.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltReg/rainReg/TableHead.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/TableHead.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rswtReg/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rswtReg/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/htdflSttn/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx similarity index 100% rename from apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx rename to apps/wr/app/(with-layout)/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx diff --git a/apps/wr/app/stats/rainStat/page.tsx b/apps/wr/app/(with-layout)/stats/rainStat/page.tsx similarity index 100% rename from apps/wr/app/stats/rainStat/page.tsx rename to apps/wr/app/(with-layout)/stats/rainStat/page.tsx diff --git a/apps/wr/app/stats/rswtStat/page.tsx b/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx similarity index 100% rename from apps/wr/app/stats/rswtStat/page.tsx rename to apps/wr/app/(with-layout)/stats/rswtStat/page.tsx diff --git a/apps/wr/app/layout.tsx b/apps/wr/app/layout.tsx index add988817..fe4c3aff0 100644 --- a/apps/wr/app/layout.tsx +++ b/apps/wr/app/layout.tsx @@ -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> diff --git a/apps/wr/app/store/map/coSttnMap/index.tsx b/apps/wr/app/store/map/coSttnMap/index.tsx new file mode 100644 index 000000000..d6bedd9c5 --- /dev/null +++ b/apps/wr/app/store/map/coSttnMap/index.tsx @@ -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); + } + }, + } +} \ No newline at end of file diff --git a/apps/wr/app/store/map/common/index.tsx b/apps/wr/app/store/map/common/index.tsx new file mode 100644 index 000000000..2de402fa5 --- /dev/null +++ b/apps/wr/app/store/map/common/index.tsx @@ -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) + } + } + } + } \ No newline at end of file diff --git a/apps/wr/app/store/map/htdflMap/index.tsx b/apps/wr/app/store/map/htdflMap/index.tsx new file mode 100644 index 000000000..8b6f4513b --- /dev/null +++ b/apps/wr/app/store/map/htdflMap/index.tsx @@ -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); + } + }, + }; +}; diff --git a/apps/wr/app/store/map/ldrmntCoMap/index.tsx b/apps/wr/app/store/map/ldrmntCoMap/index.tsx new file mode 100644 index 000000000..f7b610e77 --- /dev/null +++ b/apps/wr/app/store/map/ldrmntCoMap/index.tsx @@ -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); + } + }, + }; +}; diff --git a/apps/wr/app/store/map/pbnstMap/index.tsx b/apps/wr/app/store/map/pbnstMap/index.tsx new file mode 100644 index 000000000..e2789d744 --- /dev/null +++ b/apps/wr/app/store/map/pbnstMap/index.tsx @@ -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) + } + }, + } + } \ No newline at end of file diff --git a/apps/wr/app/store/map/rainMap/index.tsx b/apps/wr/app/store/map/rainMap/index.tsx new file mode 100644 index 000000000..93b6bf9a4 --- /dev/null +++ b/apps/wr/app/store/map/rainMap/index.tsx @@ -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); + } + }, + }; +}; diff --git a/apps/wr/app/store/map/rswtMap/index.tsx b/apps/wr/app/store/map/rswtMap/index.tsx new file mode 100644 index 000000000..b7b2f0651 --- /dev/null +++ b/apps/wr/app/store/map/rswtMap/index.tsx @@ -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); + } + }, + }; +}; diff --git a/apps/wr/app/store/map/ruseMap/index.tsx b/apps/wr/app/store/map/ruseMap/index.tsx new file mode 100644 index 000000000..f5145cbf3 --- /dev/null +++ b/apps/wr/app/store/map/ruseMap/index.tsx @@ -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); + } + }, + }; +}; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index d138a8dfe..3712b4dd1 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -97,7 +97,7 @@ export const pubFacStateExport: pubFacState = { }, }; -const checkWrRegList = async () => { +export const checkWrRegList = async () => { const wrRegList = await getFetch("wr", `/reuseFc/pubFc`); return wrRegList; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 7f905dd49..f14101626 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -87,7 +87,7 @@ export const pbnstSttnStateExport: pbnstSttnState = { }, }; -const hasuListFetch = async ( +export const hasuListFetch = async ( page: string, total: string, reurnValue: ReturnType, diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index 284f300c5..349dd8865 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -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), }; }); }; diff --git a/apps/wr/components/ui/map/LayerPopUp/CoSttnMap/CoSttnMap.tsx b/apps/wr/components/ui/map/LayerPopUp/CoSttnMap/CoSttnMap.tsx new file mode 100644 index 000000000..13e928506 --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/CoSttnMap/CoSttnMap.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/map/LayerPopUp/HasuFacilty/HasuFacility.tsx b/apps/wr/components/ui/map/LayerPopUp/HasuFacilty/HasuFacility.tsx new file mode 100644 index 000000000..4f9d052de --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/HasuFacilty/HasuFacility.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/map/LayerPopUp/HedfFacilty/HtdfFacilty.tsx b/apps/wr/components/ui/map/LayerPopUp/HedfFacilty/HtdfFacilty.tsx new file mode 100644 index 000000000..bca9128e1 --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/HedfFacilty/HtdfFacilty.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/map/LayerPopUp/LdrmntCoMap/LdrmntCoMap.tsx b/apps/wr/components/ui/map/LayerPopUp/LdrmntCoMap/LdrmntCoMap.tsx new file mode 100644 index 000000000..56e42368f --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/LdrmntCoMap/LdrmntCoMap.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/map/LayerPopUp/RainFacility/RainFacility.tsx b/apps/wr/components/ui/map/LayerPopUp/RainFacility/RainFacility.tsx new file mode 100644 index 000000000..348cf6b9e --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/RainFacility/RainFacility.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/map/LayerPopUp/RswtFacilty/RswtFacilty.tsx b/apps/wr/components/ui/map/LayerPopUp/RswtFacilty/RswtFacilty.tsx new file mode 100644 index 000000000..64d558b44 --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/RswtFacilty/RswtFacilty.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/map/LayerPopUp/RuseFacilty/RuseFacility.tsx b/apps/wr/components/ui/map/LayerPopUp/RuseFacilty/RuseFacility.tsx new file mode 100644 index 000000000..4fd9c684f --- /dev/null +++ b/apps/wr/components/ui/map/LayerPopUp/RuseFacilty/RuseFacility.tsx @@ -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> + </> + ); +} diff --git a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx index 1a16c1fef..4212032f0 100644 --- a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx +++ b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx @@ -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 { diff --git a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx index 7522fdbfd..4ff4ab14e 100644 --- a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx @@ -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"; diff --git a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx index 6f3a46b34..6fc2c0632 100644 --- a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx @@ -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"; diff --git a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx index 2bb3a645f..aa74ad2c2 100644 --- a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx @@ -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"; diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx index 07e7c1e8d..2e056a401 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx @@ -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"; diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index b13160e8b..18c065ee2 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -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";