From aa7ef37aaf353a46eeab4fe9ce23afebf362f300 Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Fri, 4 Jul 2025 10:33:09 +0900 Subject: [PATCH 001/159] =?UTF-8?q?=EC=83=81=EC=84=B8=20/=20=ED=98=84?= =?UTF-8?q?=ED=99=A9=ED=8C=9D=EC=97=85=20=EB=B6=84=EB=A6=AC=EC=9E=91?= =?UTF-8?q?=EC=97=85=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 128 +++++++++++++++++------------ 1 file changed, 76 insertions(+), 52 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 777c3dcf2..5946199a7 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -16,11 +16,13 @@ import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import HtdflPrfmncSttnPopup from "@/app/map/htdflPrfmncSttnPopup"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import { getFetch } from "@/components/lib/api"; +import { useGisContext } from "@common/business_components/ui/map/Gis"; interface NewWindowPopupProps { featureData: any; checkedLayers?: string[]; checkedLayersData?: any[]; + seletectedLayerNm?: string onClose: () => void; } @@ -38,12 +40,16 @@ const NewWindowPopup: React.FC = ({ featureData, checkedLayers = [], checkedLayersData = [], + seletectedLayerNm, onClose }) => { + const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]); const [activeTab, setActiveTab] = useState('0'); // swcho : useState의 true, false 값 변경하여 목록, 상태 테스트 하였음 - const [showDetailView, setShowDetailView] = useState(false); // 상세정보 화면 표시 상태 추가 + const [showDetailView, setShowDetailView] = useState(true); // 상세정보 화면 표시 상태 추가 + const [showListView, setShowListView] = useState(false) + const [viewMode, setViewMode] = useState<"detail" | "list">("detail"); // "detail" 또는 "list"로 상태 관리 // onClose 함수를 useCallback으로 메모이제이션 const memoizedOnClose = useCallback(() => { @@ -56,8 +62,6 @@ const NewWindowPopup: React.FC = ({ pbnstSttn, pbnstSttnSearch, pbnSttnInit, - getPbnStnDetail, - pbnNmSearch, } = useWrStore((state) => state); const [bdstTable, setBdstTable] = useState(); const [pageNation, setPageNation] = useState(1); @@ -98,11 +102,7 @@ const NewWindowPopup: React.FC = ({ const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); - if (!featureData) { - return null; - } - - // 물재이용시설 cellClick 이벤트 (상세정보) + // 재이용시설 cellClick 이벤트 (상세정보) const pbnstCellClick = (index: number | undefined) => { if ( index !== undefined && @@ -112,36 +112,51 @@ const NewWindowPopup: React.FC = ({ setPbnstRuseFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - setShowDetailView(true); // 상세정보 화면 표시 상태 변경 + setViewMode('detail') } }; - - useEffect(() => { - if (!pbnstSttn.isInit) { - pbnSttnInit("1", "13",{ - partValue: "A", - sidoValue: "0", - sigunValue: "", - regionValue: "", - unitWaterShedValue: "", - middleRegionValue: "", - envPartValue: "", - sidoText: "", - sigunText: "" - }, String(new Date().getFullYear())); + const getSelectedLayers = () => { + let result = null; + const layers = gisMap ? gisMap.getLayers().getArray() : []; // gisMap이 null인지 확인 후 레이어 가져오기 + let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 + layers.forEach((layer: any) => { + const source = layer.getSource(); + if (source && source.hasFeature && featureData + && typeof featureData.getId === 'function' && source.hasFeature(featureData)) { + featureLayer = layer; // 피처가 속한 레이어 찾기 } - }, [pbnstSttn.isInit]); + }); + result = featureLayer.get('lyrNm'); - useEffect(() => { - setBdstTable(pbnstSttn.pbnstSttnRes); - }, [pbnstSttn.pbnstSttnRes]); + return result; + }; + // 재이용 현황 초기값 + useEffect(() => { + if (!pbnstSttn.isInit) { + pbnSttnInit("1", "13", { + partValue: "A", + sidoValue: "0", + sigunValue: "", + regionValue: "", + unitWaterShedValue: "", + middleRegionValue: "", + envPartValue: "", + sidoText: "", + sigunText: "" + }, String(new Date().getFullYear())); + } + }, [pbnstSttn.isInit]); -// 재이용시설 상세정보 - const setTabDataFunc = (res:any, pk:string) => { + useEffect(() => { + setBdstTable(pbnstSttn.pbnstSttnRes); + }, [pbnstSttn.pbnstSttnRes]); + + // 재이용시설 상세정보 + const setTabDataFunc = (res: any, pk: string) => { setTabData((prev) => { if (prev.some((tab) => tab.id === pk)) { return prev; // 이미 존재하는 탭이면 추가하지 않음 - } + } return [...prev, { id: pk, name: `재이용시설 ${prev.length + 1}`, data: res }]; }); } @@ -175,17 +190,25 @@ const NewWindowPopup: React.FC = ({ String(new Date().getFullYear()) ); }, []); - // useEffect(() => { - // if (featureData) { - // const selectedVal = featureData.getProperties(); - // const featureCd = selectedVal?.swtrmt_fclt_cd; - // if (featureCd && featureCd !== pbnstRuseFcltPk) { - // setPbnstRuseFcltPk(featureCd); // 현재 호출된 featureCd 저장 - // setActiveTab(featureCd) - // fetchpbnstDetail(featureCd); // 상세정보 가져오기 - // } - // } - // }, [featureData]); + useEffect(() => { + if (seletectedLayerNm && seletectedLayerNm === getSelectedLayers()) { + console.log('레이어명이 일치하여 상세보기 비활성화'); // 디버깅 로그 추가 + setViewMode('list') + } + }, [seletectedLayerNm]); + + useEffect(() => { + if (featureData) { + const selectedVal = featureData.getProperties(); + const featureCd = selectedVal?.swtrmt_fclt_cd; + if (featureCd && featureCd !== pbnstRuseFcltPk) { + setPbnstRuseFcltPk(featureCd); // 현재 호출된 featureCd 저장 + setActiveTab(featureCd) + fetchpbnstDetail(featureCd); // 상세정보 + setViewMode("detail"); // 상세 보기 활성화 + } + } + }, [featureData]); useEffect(() => { if (pbnstSttn.pbnstDetail) { @@ -248,18 +271,19 @@ const NewWindowPopup: React.FC = ({ layer.data?.lyrNm?.includes('하수처리') || layer.data?.lyrNm?.includes('재이용시설') ); const actTabData = tabData.find((tab) => tab.id === activeTab); - console.log('tavbData',actTabData) + const layerId = getSelectedLayers() // swcho : true, false 값 변경하여 시설 변경하여 테스트하였음 // 재이용시설 - const isPbnst = true; + let isPbnst = layerId == '하수처리시설'; // 빗물이용시설 - const isRain = false; + let isRain = layerId == '빗물이용시설'; // 중수도시설 - const isRswt = false; + let isRswt = layerId == '중수도시설'; // 온배수시설 - const isHtdfl = false; + let isHtdfl = layerId == '온배수시설'; + if (isPbnst) { - if (showDetailView) { + if (viewMode=='detail') { // 재이용시설 상세 return ( <> @@ -278,7 +302,7 @@ const NewWindowPopup: React.FC = ({ /> tab.id === activeTab)?.data[0] || ({} as customPbnst)} + data={actTabData?.data[0] || ({} as customPbnst)} titleVisible={false} /> @@ -311,7 +335,7 @@ const NewWindowPopup: React.FC = ({ ); } } - + if (isRain) { if (showDetailView) { // 빗물이용시설 상세 @@ -351,7 +375,7 @@ const NewWindowPopup: React.FC = ({ ); } } - + if (isRswt) { if (showDetailView) { // 중수도시설 상세 @@ -391,7 +415,7 @@ const NewWindowPopup: React.FC = ({ ); } } - + if (isHtdfl) { if (showDetailView) { // 온배수시설 상세 @@ -431,7 +455,7 @@ const NewWindowPopup: React.FC = ({ ); } } - + return null; // 조건에 맞는 콘텐츠가 없을 경우 }; From 916c0687062b9d4d24f221876e78bb048420f0e1 Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Fri, 4 Jul 2025 11:00:34 +0900 Subject: [PATCH 002/159] =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/htdflSttn/page.tsx | 3 ++- apps/wr/app/map/newWindowPopup.tsx | 24 ++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/apps/wr/app/map/htdflSttn/page.tsx b/apps/wr/app/map/htdflSttn/page.tsx index e74d055d8..5702e0179 100644 --- a/apps/wr/app/map/htdflSttn/page.tsx +++ b/apps/wr/app/map/htdflSttn/page.tsx @@ -4,7 +4,7 @@ import Gis from "@common/business_components/ui/map/Gis"; import { useEffect, useRef, useState, useCallback } from "react"; import FeatureClickEventPopup from "../featureClickEventPopup"; import { mapService } from "../service"; -import { MapSearchBar } from "../mapSearchBar"; +// import { MapSearchBar } from "../mapSearchBar"; import NewWindowPopup from "../newWindowPopup"; import GisApp from "@common/business_components/ui/map/lib/gis.core"; @@ -141,6 +141,7 @@ const Map = () => { onClose={handlePopupClose} // 메모이제이션된 함수 사용 checkedLayers={checkedLayers} checkedLayersData={checkedLayersData} + seletectedLayerNm={""} {...props} /> )} diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 5946199a7..976cd052b 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -23,6 +23,8 @@ interface NewWindowPopupProps { checkedLayers?: string[]; checkedLayersData?: any[]; seletectedLayerNm?: string + viewMode?:string + setViewMode?:React.Dispatch>; onClose: () => void; } @@ -41,15 +43,15 @@ const NewWindowPopup: React.FC = ({ checkedLayers = [], checkedLayersData = [], seletectedLayerNm, + viewMode, + setViewMode, onClose }) => { const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]); const [activeTab, setActiveTab] = useState('0'); // swcho : useState의 true, false 값 변경하여 목록, 상태 테스트 하였음 - const [showDetailView, setShowDetailView] = useState(true); // 상세정보 화면 표시 상태 추가 - const [showListView, setShowListView] = useState(false) - const [viewMode, setViewMode] = useState<"detail" | "list">("detail"); // "detail" 또는 "list"로 상태 관리 + // const [viewMode, setViewMode] = useState<"detail" | "list">("detail"); // "detail" 또는 "list"로 상태 관리 // onClose 함수를 useCallback으로 메모이제이션 const memoizedOnClose = useCallback(() => { @@ -112,7 +114,7 @@ const NewWindowPopup: React.FC = ({ setPbnstRuseFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - setViewMode('detail') + setViewMode && setViewMode("detail") } }; const getSelectedLayers = () => { @@ -190,12 +192,6 @@ const NewWindowPopup: React.FC = ({ String(new Date().getFullYear()) ); }, []); - useEffect(() => { - if (seletectedLayerNm && seletectedLayerNm === getSelectedLayers()) { - console.log('레이어명이 일치하여 상세보기 비활성화'); // 디버깅 로그 추가 - setViewMode('list') - } - }, [seletectedLayerNm]); useEffect(() => { if (featureData) { @@ -205,7 +201,7 @@ const NewWindowPopup: React.FC = ({ setPbnstRuseFcltPk(featureCd); // 현재 호출된 featureCd 저장 setActiveTab(featureCd) fetchpbnstDetail(featureCd); // 상세정보 - setViewMode("detail"); // 상세 보기 활성화 + setViewMode && setViewMode("detail"); // 상세 보기 활성화 } } }, [featureData]); @@ -337,7 +333,7 @@ const NewWindowPopup: React.FC = ({ } if (isRain) { - if (showDetailView) { + if (viewMode == 'detail') { // 빗물이용시설 상세 return ( <> @@ -377,7 +373,7 @@ const NewWindowPopup: React.FC = ({ } if (isRswt) { - if (showDetailView) { + if (viewMode == 'detail') { // 중수도시설 상세 return ( <> @@ -417,7 +413,7 @@ const NewWindowPopup: React.FC = ({ } if (isHtdfl) { - if (showDetailView) { + if (viewMode == 'detail') { // 온배수시설 상세 return ( <> From bf32364514aa3fb68fd7d1016c83b386000d973a Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Fri, 4 Jul 2025 17:36:12 +0900 Subject: [PATCH 003/159] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=20=EB=AA=85?= =?UTF-8?q?=20=EC=9A=B0=EC=B8=A1=EC=97=90=20=ED=81=B4=EB=A6=AD=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=ED=98=84?= =?UTF-8?q?=ED=99=A9=20/=20=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=82=98=EB=89=98=EC=96=B4=EC=84=9C=20=EB=82=98=EC=98=A4?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/htdflSttn/page.tsx | 5 ++-- apps/wr/app/map/newWindowPopup.tsx | 39 +++++++++++------------------- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/apps/wr/app/map/htdflSttn/page.tsx b/apps/wr/app/map/htdflSttn/page.tsx index 5702e0179..535c08d69 100644 --- a/apps/wr/app/map/htdflSttn/page.tsx +++ b/apps/wr/app/map/htdflSttn/page.tsx @@ -136,16 +136,15 @@ const Map = () => { // /> // ) // } - detailView={(props: any) => ( + detailView={(props: any) =>( )} - onFeatureSelect={undefined} + onFeatureSelect={onFeatureSelect} setIsOpen={setIsOpen} setFeatureData={setFeatureData} featureData={featureData} diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 976cd052b..d29b0fe0f 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -23,8 +23,7 @@ interface NewWindowPopupProps { checkedLayers?: string[]; checkedLayersData?: any[]; seletectedLayerNm?: string - viewMode?:string - setViewMode?:React.Dispatch>; + viewMode?:'list' | 'detail' onClose: () => void; } @@ -43,15 +42,12 @@ const NewWindowPopup: React.FC = ({ checkedLayers = [], checkedLayersData = [], seletectedLayerNm, - viewMode, - setViewMode, onClose }) => { const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]); const [activeTab, setActiveTab] = useState('0'); - // swcho : useState의 true, false 값 변경하여 목록, 상태 테스트 하였음 - // const [viewMode, setViewMode] = useState<"detail" | "list">("detail"); // "detail" 또는 "list"로 상태 관리 + const [viewMode,setViewMode] = useState<'list' | 'detail'>('list'); // onClose 함수를 useCallback으로 메모이제이션 const memoizedOnClose = useCallback(() => { @@ -65,8 +61,7 @@ const NewWindowPopup: React.FC = ({ pbnstSttnSearch, pbnSttnInit, } = useWrStore((state) => state); - const [bdstTable, setBdstTable] = useState(); - const [pageNation, setPageNation] = useState(1); + const [bdstTable, setBdstTable] = useState() const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState(''); const [pbnDetaileData, setPbnDetaileData] = useState<{ isModal: boolean; @@ -114,7 +109,7 @@ const NewWindowPopup: React.FC = ({ setPbnstRuseFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - setViewMode && setViewMode("detail") + setViewMode("detail") } }; const getSelectedLayers = () => { @@ -194,26 +189,18 @@ const NewWindowPopup: React.FC = ({ }, []); useEffect(() => { - if (featureData) { + if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); const featureCd = selectedVal?.swtrmt_fclt_cd; if (featureCd && featureCd !== pbnstRuseFcltPk) { setPbnstRuseFcltPk(featureCd); // 현재 호출된 featureCd 저장 setActiveTab(featureCd) fetchpbnstDetail(featureCd); // 상세정보 - setViewMode && setViewMode("detail"); // 상세 보기 활성화 + setViewMode("detail") } - } + }else if(seletectedLayerNm){setViewMode("list")} }, [featureData]); - useEffect(() => { - if (pbnstSttn.pbnstDetail) { - setPbnDetaileData({ - isModal: true, - data: pbnstSttn.pbnstDetail, - }); - } - }, [pbnstSttn.pbnstDetail]); // 빗물재이용시설 cellClick 이벤트 (상세정보) const rainCellClick = (index: number | undefined, headId: string) => { @@ -267,8 +254,10 @@ const NewWindowPopup: React.FC = ({ layer.data?.lyrNm?.includes('하수처리') || layer.data?.lyrNm?.includes('재이용시설') ); const actTabData = tabData.find((tab) => tab.id === activeTab); - const layerId = getSelectedLayers() - // swcho : true, false 값 변경하여 시설 변경하여 테스트하였음 + let layerId = getSelectedLayers(); + if(layerId === null || layerId === undefined) { + layerId = seletectedLayerNm || ''; + } // 재이용시설 let isPbnst = layerId == '하수처리시설'; // 빗물이용시설 @@ -365,7 +354,7 @@ const NewWindowPopup: React.FC = ({ cellClick={(index: number | undefined, headId: string) => { rainCellClick(index ?? undefined, headId); }} - onPageChange={setPageNation} + onPageChange={()=>{}} /> ); @@ -405,7 +394,7 @@ const NewWindowPopup: React.FC = ({ cellClick={(index: number | undefined, headId: string) => { rswtCellClick(index, headId); }} - onPageChange={setPageNation} + onPageChange={()=>{}} /> ); @@ -445,7 +434,7 @@ const NewWindowPopup: React.FC = ({ cellClick={(index: number | undefined, headId: string) => { htdflCellClick(index ?? undefined, headId); }} - onPageChange={setPageNation} + onPageChange={()=>{}} /> ); From 5b71fa6dfea3cd4b618b6831e9e784c3f5acb08c Mon Sep 17 00:00:00 2001 From: jyha00 Date: Mon, 7 Jul 2025 10:34:22 +0900 Subject: [PATCH 004/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=A4=EC=A0=81=20=ED=98=84=ED=99=A9=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=98=A4=EB=A6=84=EC=B0=A8=EC=88=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncSttn/pbnstPrfmncSttn/page.tsx | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index 3e860d744..03e523faf 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -6,13 +6,11 @@ import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, import { excelPrfmncSttnParsing } from "@/app/store/prfmncSttn/pbnstPrfmncSttn/excel"; import { excelDownload, yearOptions } from "@/components/lib/func/commom"; import SearchInputText from "@/components/ui/searchInput/searchInput"; -import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ChartConfig, type ReturnType } from "@common/business_components"; +import { CHART_FORM, ContentsDiv, MainChart, SearchBaseForm, SelectBox, Title, UiTable, type ChartConfig, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, Label, Table, TableBody, TableHeader } from "@common/components/ui"; +import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; import toast, { Toaster } from "react-hot-toast"; -import { headMakeprfmnc } from "../../prfmncReg/chkgdnReg/TableHead"; -import { InputTableBody } from "@/components/lib/func/TableData"; export default function PbnstPrfmncSttn() { const { @@ -306,6 +304,24 @@ export default function PbnstPrfmncSttn() { dnOutData.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "#C5D3E8" }); dnOutData.push({ label: "공업용수", val: indstUswtr, fill: "#D0E8C5" }); + // 라인차트 데이터 월별 오름차순 정렬 + const sortFn = (a: { label: string }, b: { label: string }) => parseInt(a.label) - parseInt(b.label); + wshwtrData.sort(sortFn); + coolUswtrData.sort(sortFn); + cleanUswtrData.sort(sortFn); + drwtUswtrData.sort(sortFn); + dltnUswtrData.sort(sortFn); + ithlRswtrData.sort(sortFn); + ithlEtcUswtrData.sort(sortFn); + cleanToilUswtrData.sort(sortFn); + resnData.sort(sortFn); + lndwtrData.sort(sortFn); + hydUswtrData.sort(sortFn); + ugwtChrData.sort(sortFn); + farmUswtrData.sort(sortFn); + rvrKeepUswtrData.sort(sortFn); + indstUswtrData.sort(sortFn); + // 라인차트 데이터 setInLineData({ chartData1: wshwtrData, @@ -326,6 +342,7 @@ export default function PbnstPrfmncSttn() { chartData7: rvrKeepUswtrData, chartData8: indstUswtrData, }); + barData.sort((a, b) => parseInt(a.label) - parseInt(b.label)); setBarData(barData); setChartData(dnData); setDnInUsage(dnInData); From 02ada9925a2b25ab182ba70233db4c1fa3a17a99 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Mon, 7 Jul 2025 13:12:20 +0900 Subject: [PATCH 005/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=A4=EC=A0=81=20=ED=98=84=ED=99=A9=20=EC=9B=94?= =?UTF-8?q?=EB=B3=84=20=EC=98=A4=EB=A6=84=EC=B0=A8=EC=88=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncSttn/pbnstPrfmncSttn/page.tsx | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index 3e860d744..da0b7871d 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -306,6 +306,24 @@ export default function PbnstPrfmncSttn() { dnOutData.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "#C5D3E8" }); dnOutData.push({ label: "공업용수", val: indstUswtr, fill: "#D0E8C5" }); + // 라인차트 데이터 월별 오름차순 정렬 + const sortFn = (a: { label: string }, b: { label: string }) => parseInt(a.label) - parseInt(b.label); + wshwtrData.sort(sortFn); + coolUswtrData.sort(sortFn); + cleanUswtrData.sort(sortFn); + drwtUswtrData.sort(sortFn); + dltnUswtrData.sort(sortFn); + ithlRswtrData.sort(sortFn); + ithlEtcUswtrData.sort(sortFn); + cleanToilUswtrData.sort(sortFn); + resnData.sort(sortFn); + lndwtrData.sort(sortFn); + hydUswtrData.sort(sortFn); + ugwtChrData.sort(sortFn); + farmUswtrData.sort(sortFn); + rvrKeepUswtrData.sort(sortFn); + indstUswtrData.sort(sortFn); + // 라인차트 데이터 setInLineData({ chartData1: wshwtrData, @@ -326,6 +344,7 @@ export default function PbnstPrfmncSttn() { chartData7: rvrKeepUswtrData, chartData8: indstUswtrData, }); + barData.sort((a, b) => parseInt(a.label) - parseInt(b.label)); setBarData(barData); setChartData(dnData); setDnInUsage(dnInData); @@ -471,7 +490,13 @@ export default function PbnstPrfmncSttn() { }, []); useEffect(() => { - setbdstTable(prfmncRes); + setbdstTable(prfmncRes.map((e, idx) => { + + return ({ + ...e, + number: String(idx + 1) + }) + })) if (prfmncRes?.[0]?.pbnstRuseFcltPk) setChartId(prfmncRes[0].pbnstRuseFcltPk) }, [prfmncRes]); From 46c3f504329b3aaf7e9d112675bc4995bff5ef52 Mon Sep 17 00:00:00 2001 From: bicochan Date: Mon, 7 Jul 2025 13:58:29 +0900 Subject: [PATCH 006/159] =?UTF-8?q?[apps/cs]=20refactor:=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EB=B0=8F=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/entities/menu/api/menu-service.ts | 37 +++++++- apps/cs/src/entities/menu/index.ts | 9 +- .../src/entities/menu/model/menu-interface.ts | 58 +++++++++++++ apps/cs/src/pages/menu/api/menu-service.ts | 65 -------------- .../src/pages/menu/api/tree-menu-service.ts | 33 +++++++ apps/cs/src/pages/menu/lib/utils.ts | 2 +- .../cs/src/pages/menu/model/menu-interface.ts | 86 ------------------- .../pages/menu/model/tree-menu-interface.ts | 29 +++++++ apps/cs/src/pages/menu/ui/base-menu-form.tsx | 2 +- apps/cs/src/pages/menu/ui/menu-form.tsx | 14 ++- apps/cs/src/pages/menu/ui/menu-node.tsx | 6 +- apps/cs/src/pages/menu/ui/menu-page.tsx | 17 ++-- apps/cs/src/pages/menu/ui/menu-tree.tsx | 7 +- apps/cs/src/pages/menu/ui/type-menu-form.tsx | 2 +- 14 files changed, 194 insertions(+), 173 deletions(-) delete mode 100644 apps/cs/src/pages/menu/api/menu-service.ts create mode 100644 apps/cs/src/pages/menu/api/tree-menu-service.ts delete mode 100644 apps/cs/src/pages/menu/model/menu-interface.ts create mode 100644 apps/cs/src/pages/menu/model/tree-menu-interface.ts diff --git a/apps/cs/src/entities/menu/api/menu-service.ts b/apps/cs/src/entities/menu/api/menu-service.ts index 4424f8d37..7dd0aecd9 100644 --- a/apps/cs/src/entities/menu/api/menu-service.ts +++ b/apps/cs/src/entities/menu/api/menu-service.ts @@ -1,6 +1,11 @@ import { client } from "@/shared/api"; import { ENDPOINT } from "@/shared/config"; -import type { MenuItem, MenuService } from "../model/menu-interface"; +import type { + MenuService, + Menu, + MenuItem, + MenuFormData, +} from "../model/menu-interface"; export class MenuApiService implements MenuService { async getMenuRoles(siteId: string): Promise { @@ -9,6 +14,36 @@ export class MenuApiService implements MenuService { ); return response.data; } + + public async getMenuInfo(menuCd: number): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`, + ); + return response.data; + } + + public async createMenu(data: MenuFormData): Promise { + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.MENUS}`, + data, + ); + return response.data; + } + + public async updateMenu( + menuCd: number, + data: Omit, + ): Promise { + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`, + data, + ); + return response.data; + } + + public async deleteMenu(menuCd: number): Promise { + await client.delete(`${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`); + } } export const MenuApi = new MenuApiService(); diff --git a/apps/cs/src/entities/menu/index.ts b/apps/cs/src/entities/menu/index.ts index 04f63e38b..e4a9cec40 100644 --- a/apps/cs/src/entities/menu/index.ts +++ b/apps/cs/src/entities/menu/index.ts @@ -1,2 +1,9 @@ +export { MenuApi } from "./api/menu-service"; +export { + MENU_TYPE, + menuFormSchema, + type MenuType, + type MenuItem, + type MenuFormData, +} from "./model/menu-interface"; export { MenuWrapper } from "./lib/menu-wrapper"; -export type { MenuItem } from "./model/menu-interface"; diff --git a/apps/cs/src/entities/menu/model/menu-interface.ts b/apps/cs/src/entities/menu/model/menu-interface.ts index 12c7d007a..285c28b04 100644 --- a/apps/cs/src/entities/menu/model/menu-interface.ts +++ b/apps/cs/src/entities/menu/model/menu-interface.ts @@ -1,3 +1,16 @@ +import { z } from "zod"; + +export const MENU_TYPE = { + EMPTY: "EMPTY", + CONTENTS: "CONTENTS", + BOARD: "BOARD", + INSIDE: "INSIDE", + OUTSIDE: "OUTSIDE", + BOTTOM: "BOTTOM", +} as const; + +export type MenuType = (typeof MENU_TYPE)[keyof typeof MENU_TYPE]; + export interface MenuItem { menuCd: number; menuKornNm: string; @@ -18,6 +31,51 @@ export interface MenuItem { requiredUrlPath: boolean; } +export const menuFormSchema = z.object({ + siteId: z.string(), + menuKornNm: z.string(), + menuSubKornNm: z.string().nullish(), + menuEngNm: z.string().nullish(), + menuSubEngNm: z.string().nullish(), + levelNo: z.number(), + urlPath: z.string().nullish(), + iconNm: z.string().nullish(), + menuLnkgTypeCd: z.enum([ + MENU_TYPE.EMPTY, + MENU_TYPE.CONTENTS, + MENU_TYPE.BOARD, + MENU_TYPE.INSIDE, + MENU_TYPE.OUTSIDE, + MENU_TYPE.BOTTOM, + ]), + menuLnkgSn: z.number().nullish(), + otptYn: z.string().default("Y"), + prntMenuCd: z.number().nullish(), + sortSeq: z.number(), + evlUseYn: z.string().default("Y"), + qrcd: z.string().nullish(), + useYn: z.string().default("Y"), + newWndwYn: z.string().nullish(), + menuLnkgSnNm: z.string().nullish(), + menuPicUserUnqId: z.string().nullish(), + menuPicUserUnqIdNm: z.string().nullish(), + menuPicDsgnYmd: z.string().nullish(), +}); + +export type MenuFormData = z.infer; + +export type Menu = Omit & { + menuCd: number; + iconName?: string; +}; + export interface MenuService { getMenuRoles(siteId: string): Promise; + getMenuInfo: (menuCd: number) => Promise; + createMenu: (data: MenuFormData) => Promise; + updateMenu: ( + menuCd: number, + data: Omit, + ) => Promise; + deleteMenu: (menuCd: number) => Promise; } diff --git a/apps/cs/src/pages/menu/api/menu-service.ts b/apps/cs/src/pages/menu/api/menu-service.ts deleted file mode 100644 index dbb67cb3e..000000000 --- a/apps/cs/src/pages/menu/api/menu-service.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import type { - Menu, - MenuFormData, - MenuService, - TreeMenu, - TreeNode, -} from "../model/menu-interface"; - -export class MenuApiService implements MenuService { - public async getMenuInfo(menuCd: number): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`, - ); - return response.data; - } - - public async createMenu(data: MenuFormData): Promise { - const response = await client.post( - `${ENDPOINT.CMS_SERVICE.MENUS}`, - data, - ); - return response.data; - } - - public async updateMenu( - menuCd: number, - data: Omit, - ): Promise { - const response = await client.put( - `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`, - data, - ); - return response.data; - } - - public async deleteMenu(menuCd: number): Promise { - await client.delete(`${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`); - } - - public async getTreeMenuList(siteId: string): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree`, - ); - return response.data; - } - - public async updateTreeMenu(siteId: string, data: TreeNode[]): Promise { - const response = await client.put( - `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree`, - data, - ); - return response.data; - } - - public async updateMenuName(menuCd: number, name: string): Promise { - const response = await client.put( - `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}/${name}`, - ); - return response.data; - } -} - -export const MenuApi = new MenuApiService(); diff --git a/apps/cs/src/pages/menu/api/tree-menu-service.ts b/apps/cs/src/pages/menu/api/tree-menu-service.ts new file mode 100644 index 000000000..9f36f5383 --- /dev/null +++ b/apps/cs/src/pages/menu/api/tree-menu-service.ts @@ -0,0 +1,33 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import type { + TreeMenuService, + TreeMenu, + TreeNode, +} from "../model/tree-menu-interface"; + +export class TreeMenuApiService implements TreeMenuService { + public async getTreeMenuList(siteId: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree`, + ); + return response.data; + } + + public async updateTreeMenu(siteId: string, data: TreeNode[]): Promise { + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree`, + data, + ); + return response.data; + } + + public async updateMenuName(menuCd: number, name: string): Promise { + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}/${name}`, + ); + return response.data; + } +} + +export const TreeMenuApi = new TreeMenuApiService(); diff --git a/apps/cs/src/pages/menu/lib/utils.ts b/apps/cs/src/pages/menu/lib/utils.ts index f6d13be33..0e219047d 100644 --- a/apps/cs/src/pages/menu/lib/utils.ts +++ b/apps/cs/src/pages/menu/lib/utils.ts @@ -3,7 +3,7 @@ import type { TreeUserOrganization, TreeUser, } from "@/entities/user-organization"; -import type { TreeMenu, TreeNode } from "../model/menu-interface"; +import type { TreeMenu, TreeNode } from "../model/tree-menu-interface"; export const generateMenuTreeData = ( data: TreeMenu[], diff --git a/apps/cs/src/pages/menu/model/menu-interface.ts b/apps/cs/src/pages/menu/model/menu-interface.ts deleted file mode 100644 index f9650e0e2..000000000 --- a/apps/cs/src/pages/menu/model/menu-interface.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { z } from "zod"; - -export const MENU_TYPE = { - EMPTY: "EMPTY", - CONTENTS: "CONTENTS", - BOARD: "BOARD", - INSIDE: "INSIDE", - OUTSIDE: "OUTSIDE", - BOTTOM: "BOTTOM", -} as const; - -export type MenuType = (typeof MENU_TYPE)[keyof typeof MENU_TYPE]; - -export interface TreeNode { - menuCd?: number; - name?: string; - sortSeq?: number; - parentId?: number | null; - levelNo?: number; - icon?: string; - children?: TreeNode[]; -} - -export interface TreeMenu extends Omit { - menuKornNm: string; - menuEngNm?: string; - iconNm?: string; - children?: TreeMenu[]; - urlPath?: string; - menuLnkgTypeCd: string; - menuLnkgSn?: number; - qrcd?: string; - useYn: string; - otptYn: string; - requiredUrlPath?: boolean; -} - -export const menuFormSchema = z.object({ - siteId: z.string(), - menuKornNm: z.string(), - menuSubKornNm: z.string().nullish(), - menuEngNm: z.string().nullish(), - menuSubEngNm: z.string().nullish(), - levelNo: z.number(), - urlPath: z.string().nullish(), - iconNm: z.string().nullish(), - menuLnkgTypeCd: z.enum([ - MENU_TYPE.EMPTY, - MENU_TYPE.CONTENTS, - MENU_TYPE.BOARD, - MENU_TYPE.INSIDE, - MENU_TYPE.OUTSIDE, - MENU_TYPE.BOTTOM, - ]), - menuLnkgSn: z.number().nullish(), - otptYn: z.string().default("Y"), - prntMenuCd: z.number().nullish(), - sortSeq: z.number(), - evlUseYn: z.string().default("Y"), - qrcd: z.string().nullish(), - useYn: z.string().default("Y"), - newWndwYn: z.string().nullish(), - menuLnkgSnNm: z.string().nullish(), - menuPicUserUnqId: z.string().nullish(), - menuPicUserUnqIdNm: z.string().nullish(), - menuPicDsgnYmd: z.string().nullish(), -}); - -export type MenuFormData = z.infer; -export type Menu = Omit & { - menuCd: number; - iconName?: string; -}; - -export interface MenuService { - getMenuInfo: (menuCd: number) => Promise; - createMenu: (data: MenuFormData) => Promise; - updateMenu: ( - menuCd: number, - data: Omit, - ) => Promise; - deleteMenu: (menuCd: number) => Promise; - getTreeMenuList: (siteId: string) => Promise; - updateTreeMenu: (siteId: string, data: TreeNode[]) => Promise; - updateMenuName: (menuCd: number, name: string) => Promise; -} diff --git a/apps/cs/src/pages/menu/model/tree-menu-interface.ts b/apps/cs/src/pages/menu/model/tree-menu-interface.ts new file mode 100644 index 000000000..39a6f92c9 --- /dev/null +++ b/apps/cs/src/pages/menu/model/tree-menu-interface.ts @@ -0,0 +1,29 @@ +export interface TreeNode { + menuCd?: number; + name?: string; + sortSeq?: number; + parentId?: number | null; + levelNo?: number; + icon?: string; + children?: TreeNode[]; +} + +export interface TreeMenu extends Omit { + menuKornNm: string; + menuEngNm?: string; + iconNm?: string; + children?: TreeMenu[]; + urlPath?: string; + menuLnkgTypeCd: string; + menuLnkgSn?: number; + qrcd?: string; + useYn: string; + otptYn: string; + requiredUrlPath?: boolean; +} + +export interface TreeMenuService { + getTreeMenuList: (siteId: string) => Promise; + updateTreeMenu: (siteId: string, data: TreeNode[]) => Promise; + updateMenuName: (menuCd: number, name: string) => Promise; +} diff --git a/apps/cs/src/pages/menu/ui/base-menu-form.tsx b/apps/cs/src/pages/menu/ui/base-menu-form.tsx index fceb66549..eeae63255 100644 --- a/apps/cs/src/pages/menu/ui/base-menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/base-menu-form.tsx @@ -10,8 +10,8 @@ import { TableHead, TableRow, } from "@common/components"; +import { MENU_TYPE, type MenuFormData } from "@/entities/menu"; import { FormItem, FormControl, FormField } from "@/shared/ui/form"; -import { MENU_TYPE, type MenuFormData } from "../model/menu-interface"; import { InfoTooltip } from "@/shared/ui/info-tooltip"; interface BaseMenuFormProps { diff --git a/apps/cs/src/pages/menu/ui/menu-form.tsx b/apps/cs/src/pages/menu/ui/menu-form.tsx index 0a45214eb..1cba9ddf3 100644 --- a/apps/cs/src/pages/menu/ui/menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/menu-form.tsx @@ -1,9 +1,9 @@ import type { UseFormReturn } from "react-hook-form"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { Button } from "@common/components"; -import { Form } from "@/shared/ui/form"; +import type { MenuFormData } from "@/entities/menu"; import { ManagementAuthorityDialog } from "@/entities/menu-authority"; -import type { MenuFormData } from "../model/menu-interface"; +import { Form } from "@/shared/ui/form"; import { BaseMenuForm } from "./base-menu-form"; import { TypeMenuForm } from "./type-menu-form"; @@ -69,7 +69,15 @@ function MenuForm({

{isModifyMode ? "메뉴 수정" : "메뉴 등록"}

- +
+ + + +
diff --git a/apps/cs/src/pages/menu/ui/menu-node.tsx b/apps/cs/src/pages/menu/ui/menu-node.tsx index 5cda4f522..4a2b3624f 100644 --- a/apps/cs/src/pages/menu/ui/menu-node.tsx +++ b/apps/cs/src/pages/menu/ui/menu-node.tsx @@ -4,8 +4,8 @@ import type { NodeModel, TreeMethods } from "@minoru/react-dnd-treeview"; import { Button, cn } from "@common/components"; import { useMutationWrapper } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; -import { MenuApi } from "../api/menu-service"; -import type { TreeMenu } from "../model/menu-interface"; +import { TreeMenuApi } from "../api/tree-menu-service"; +import type { TreeMenu } from "../model/tree-menu-interface"; import { EditableNode } from "./editable-node"; type MenuNodeProps = { @@ -37,7 +37,7 @@ function MenuNode({ const { mutateAsync: updateMenuName } = useMutationWrapper({ mutationFn: (nodeName: string) => { const encodedName = encodeURIComponent(nodeName); - return MenuApi.updateMenuName(id as number, encodedName); + return TreeMenuApi.updateMenuName(id as number, encodedName); }, onSuccess: () => { queryClient.invalidateQueries({ diff --git a/apps/cs/src/pages/menu/ui/menu-page.tsx b/apps/cs/src/pages/menu/ui/menu-page.tsx index d212dc970..2d3dedc16 100644 --- a/apps/cs/src/pages/menu/ui/menu-page.tsx +++ b/apps/cs/src/pages/menu/ui/menu-page.tsx @@ -14,19 +14,20 @@ import { SelectTrigger, SelectValue, } from "@common/components"; -import { SiteApi } from "@/entities/site"; -import { ENDPOINT } from "@/shared/config"; -import { useAlertStore, useMutationWrapper } from "@/shared/lib"; -import type { TreeMenu } from "../model/menu-interface"; -import { MenuApi } from "../api/menu-service"; import { + MenuApi, MENU_TYPE, menuFormSchema, type MenuFormData, -} from "../model/menu-interface"; +} from "@/entities/menu"; +import { SiteApi } from "@/entities/site"; +import { ENDPOINT } from "@/shared/config"; +import { useAlertStore, useMutationWrapper } from "@/shared/lib"; +import { generateMenuTreeData } from "../lib/utils"; +import { TreeMenuApi } from "../api/tree-menu-service"; +import type { TreeMenu } from "../model/tree-menu-interface"; import { MenuTree } from "./menu-tree"; import { MenuForm } from "./menu-form"; -import { generateMenuTreeData } from "../lib/utils"; function MenuPage() { const queryClient = useQueryClient(); @@ -46,7 +47,7 @@ function MenuPage() { const { data: menuTreeData } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId], - queryFn: () => MenuApi.getTreeMenuList(siteId), + queryFn: () => TreeMenuApi.getTreeMenuList(siteId), select: (data) => { const treeData = generateMenuTreeData(data); const defaultSortSeq = diff --git a/apps/cs/src/pages/menu/ui/menu-tree.tsx b/apps/cs/src/pages/menu/ui/menu-tree.tsx index a1fa4dacb..5ef15062c 100644 --- a/apps/cs/src/pages/menu/ui/menu-tree.tsx +++ b/apps/cs/src/pages/menu/ui/menu-tree.tsx @@ -11,8 +11,9 @@ import { import { Button } from "@common/components"; import { ENDPOINT } from "@/shared/config"; import { useMutationWrapper } from "@/shared/lib"; -import { MenuApi } from "../api/menu-service"; -import type { MenuFormData, TreeMenu, TreeNode } from "../model/menu-interface"; +import type { MenuFormData } from "@/entities/menu"; +import { TreeMenuApi } from "../api/tree-menu-service"; +import type { TreeMenu, TreeNode } from "../model/tree-menu-interface"; import { handleDropNode, handleSelectNode } from "../lib/utils"; import { MenuNode } from "./menu-node"; import { EditableNode } from "./editable-node"; @@ -41,7 +42,7 @@ function MenuTree({ const { mutate: updateTreeMenu } = useMutationWrapper({ mutationFn: (newTree: TreeNode) => - MenuApi.updateTreeMenu(siteId, [newTree]), + TreeMenuApi.updateTreeMenu(siteId, [newTree]), onSuccess: () => { queryClient.invalidateQueries({ queryKey: [ENDPOINT.CMS_SERVICE.MENUS], diff --git a/apps/cs/src/pages/menu/ui/type-menu-form.tsx b/apps/cs/src/pages/menu/ui/type-menu-form.tsx index ac62e2520..eeb50e805 100644 --- a/apps/cs/src/pages/menu/ui/type-menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/type-menu-form.tsx @@ -16,8 +16,8 @@ import { import type { BoardPopup } from "@/entities/board"; import type { Contents } from "@/entities/content"; import type { TreeUser } from "@/entities/user-organization"; +import type { MenuFormData, MenuType } from "@/entities/menu"; import { FormItem, FormControl, FormField } from "@/shared/ui/form"; -import type { MenuFormData, MenuType } from "../model/menu-interface"; import { OrganizationSearchDialog } from "./organization-search-dialog"; import { ContentSearchDialog } from "./content-search-dialog"; import { BoardSearchDialog } from "./board-search-dialog"; From b3a8c6af3603c7882bf9d17f3987146fc31146e2 Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Mon, 7 Jul 2025 15:23:17 +0900 Subject: [PATCH 007/159] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=EA=B9=8C=EC=A7=80=20=ED=8C=9D=EC=97=85=EB=9C=A8?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=99=84=EB=A3=8C(=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EA=B5=AC=ED=98=84=ED=95=84=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 200 ++++++++++++++++++------ apps/wr/app/map/rainPrfmncSttnPopup.tsx | 12 +- 2 files changed, 162 insertions(+), 50 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 15bab32c6..747f53971 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -1,7 +1,7 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload } from "@/components/lib/func/commom"; +import { excelDownload, tableData } from "@/components/lib/func/commom"; import { Title, UiTable, UITab, ContentsDiv } from '@common/business_components'; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Button } from "@common/components/ui"; @@ -24,7 +24,7 @@ interface NewWindowPopupProps { checkedLayers?: string[]; checkedLayersData?: any[]; seletectedLayerNm?: string - viewMode?:'list' | 'detail' + viewMode?: 'list' | 'detail' onClose: () => void; } @@ -55,7 +55,9 @@ const NewWindowPopup: React.FC = ({ const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]); const [activeTab, setActiveTab] = useState('0'); - const [viewMode,setViewMode] = useState<'list' | 'detail'>('list'); + const [viewMode, setViewMode] = useState<'list' | 'detail'>('list'); + const [fcltPk, setFcltPk] = useState(''); + // onClose 함수를 useCallback으로 메모이제이션 const memoizedOnClose = useCallback(() => { @@ -70,11 +72,6 @@ const NewWindowPopup: React.FC = ({ pbnSttnInit, } = useWrStore((state) => state); const [bdstTable, setBdstTable] = useState() - const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState(''); - const [pbnDetaileData, setPbnDetaileData] = useState<{ - isModal: boolean; - data: customPbnst; - }>({ isModal: false, data: {} as customPbnst }); // 빗물재이용시설 변수 const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( @@ -86,6 +83,7 @@ const NewWindowPopup: React.FC = ({ isOpen: boolean; chBuilding: chgBuilding[]; }>({ isOpen: false, chBuilding: [] }); + const [rainPage, setRainPage] = useState(1) const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }); // 중수도시설 변수 @@ -99,6 +97,7 @@ const NewWindowPopup: React.FC = ({ isOpen: boolean; chBuilding: chgBuilding[]; }>({ isOpen: false, chBuilding: [] }); + const [rswtrPage, setRswtrPage] = useState(1); // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); @@ -106,7 +105,40 @@ const NewWindowPopup: React.FC = ({ const [htdflTable, setHtdflTable] = useState(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); + if(!featureData) return ; + ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// + useEffect(() => { + if (featureData && typeof featureData.getProperties === "function") { + const selectedVal = featureData.getProperties(); + const layerId = getSelectedLayers(); + let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' ? selectedVal?.bdst_nm : ''; + if (featureCd && featureCd !== fcltPk) { + if (layerId == '하수재이용시설') { + featureCd = selectedVal?.swtrmt_fclt_cd; + setFcltPk(featureCd); // 현재 호출된 featureCd 저장 + setActiveTab(featureCd) + fetchpbnstDetail(featureCd); // 상세정보 + } + else if (layerId == '빗물이용시설') { + featureCd = selectedVal?.bdst_nm; + setFcltPk(featureCd) + rainSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + setRainDetailModal({ isOpen: true, data: rainSttn.rainSttnRes[0] }); + } + else if (layerId == '중수도시설') { + featureCd = selectedVal?.bdst_nm; + console.log(featureCd) + setFcltPk(featureCd) + rswtSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); + } + setViewMode("detail") + } + } else if (seletectedLayerNm) { setViewMode("list") } + }, [featureData]); + ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// + ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// // 재이용시설 cellClick 이벤트 (상세정보) const pbnstCellClick = (index: number | undefined) => { if ( @@ -114,7 +146,7 @@ const NewWindowPopup: React.FC = ({ pbnstSttn.pbnstSttnRes && pbnstSttn.pbnstSttnRes[index] ) { - setPbnstRuseFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); + setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setViewMode("detail") @@ -150,11 +182,11 @@ const NewWindowPopup: React.FC = ({ sigunText: "" }, String(new Date().getFullYear())); } - }, [pbnstSttn.isInit]); + }, [seletectedLayerNm, pbnstSttn.isInit]); useEffect(() => { setBdstTable(pbnstSttn.pbnstSttnRes); - }, [pbnstSttn.pbnstSttnRes]); + }, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]); // 재이용시설 상세정보 const setTabDataFunc = (res: any, pk: string) => { @@ -195,22 +227,19 @@ const NewWindowPopup: React.FC = ({ String(new Date().getFullYear()) ); }, []); - - useEffect(() => { - if (featureData && typeof featureData.getProperties === "function") { - const selectedVal = featureData.getProperties(); - const featureCd = selectedVal?.swtrmt_fclt_cd; - if (featureCd && featureCd !== pbnstRuseFcltPk) { - setPbnstRuseFcltPk(featureCd); // 현재 호출된 featureCd 저장 - setActiveTab(featureCd) - fetchpbnstDetail(featureCd); // 상세정보 - setViewMode("detail") - } - }else if(seletectedLayerNm){setViewMode("list")} - }, [featureData]); - + const excelClick = useCallback(() => { + // if (codeData) pbnstSttnSearch(1, "10000", codeData); + excelDownload( + [[]], + "하수재이용시설 현황", + "sample_pbnstSttn.xlsx", + "A1:U2" + ); + }, [pbnstSttnSearch]); + ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// + ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// // 빗물재이용시설 cellClick 이벤트 (상세정보) const rainCellClick = (index: number | undefined, headId: string) => { if ( @@ -218,23 +247,114 @@ const NewWindowPopup: React.FC = ({ rainTable !== undefined && headId !== 'chBuildingYn') { setRainDetailModal({ isOpen: true, data: rainTable[index] }) + setViewMode('detail') } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); } } + useEffect(() => { + if (!rainSttn.isInit) { + rainSttnInit(1, "20", "0", '', 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(() => { + rainSttnSearch(rainPage, "20", '', '', code.cityCd, code.sggCd); + }, [rainPage]); + ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// + + ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// // 중수도시설 cellClick 이벤트 (상세정보) const rswtCellClick = (index: number | undefined, headId: string) => { if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { - setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] }) + setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] }); + setViewMode('detail') } else if (headId === 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { if (rswtrTable[index] && rswtrTable[index]?.chBuildingYn === 'Y') { setRswtrBdstChgProps({ isOpen: true, chBuilding: rswtrTable[index].chgBuilding }); } } } + useEffect(() => { + if (!rswtSttn.isInit) { + rswtSttnInit(1, "20", "0", '', code.cityCd, code.sggCd); + } + }, [rswtSttn.isInit, rswtSttnInit]); + useEffect(() => { + 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]); +// 엑셀 관련 + const rswtSttnExcelDownload = useCallback(()=>{ + console.log('excel', rswtSttn.excelList, rswtrTable) + if (rswtSttn.excelList.length > 0) { + if (rswtSttn.excelList.length === 0) return; + excelDownload( + rswtSttn.excelList, + "중수도시설 현황", + "sample_rswtSttn.xlsx", + "A1:W3", + ); + } + },[rswtSttn.excelList]) + + useEffect(() => { + rswtSttnSearch(rswtrPage, "20", '', '', code.cityCd, code.sggCd); + }, [rswtrPage]); + ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// + + ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 온배수시설 cellClick 이벤트 (상세정보) const htdflCellClick = (index: number | undefined, headId: string) => { if ( @@ -245,16 +365,8 @@ const NewWindowPopup: React.FC = ({ setHtdflDetailModal({ isOpen: true, data: htdflTable[index] }); } }; - - const excelClick = useCallback(() => { - // if (codeData) pbnstSttnSearch(1, "10000", codeData); - excelDownload( - [[]], - "하수재이용시설 현황", - "sample_pbnstSttn.xlsx", - "A1:U2" - ); - }, [pbnstSttnSearch]); + + ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { @@ -264,20 +376,20 @@ const NewWindowPopup: React.FC = ({ ); const actTabData = tabData.find((tab) => tab.id === activeTab); let layerId = getSelectedLayers(); - if(layerId === null || layerId === undefined) { + if (layerId === null || layerId === undefined) { layerId = seletectedLayerNm || ''; } // 재이용시설 - let isPbnst = layerId == '하수처리시설'; + let isPbnst = layerId == '하수재이용시설'; // 빗물이용시설 let isRain = layerId == '빗물이용시설'; // 중수도시설 let isRswt = layerId == '중수도시설'; // 온배수시설 let isHtdfl = layerId == '온배수시설'; - + if (isPbnst) { - if (viewMode=='detail') { + if (viewMode == 'detail') { // 재이용시설 상세 return ( <> @@ -363,7 +475,7 @@ const NewWindowPopup: React.FC = ({ cellClick={(index: number | undefined, headId: string) => { rainCellClick(index ?? undefined, headId); }} - onPageChange={()=>{}} + onPageChange={setRainPage} /> ); @@ -388,7 +500,7 @@ const NewWindowPopup: React.FC = ({
<div className="flex gap-2 mt-8"> - <Button className={btnClass} color="primary" onClick={excelClick}> + <Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}> 엑셀다운로드 </Button> </div> @@ -403,7 +515,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={(index: number | undefined, headId: string) => { rswtCellClick(index, headId); }} - onPageChange={()=>{}} + onPageChange={setRswtrPage} /> </> ); @@ -443,7 +555,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={(index: number | undefined, headId: string) => { htdflCellClick(index ?? undefined, headId); }} - onPageChange={()=>{}} + onPageChange={() => { }} /> </> ); diff --git a/apps/wr/app/map/rainPrfmncSttnPopup.tsx b/apps/wr/app/map/rainPrfmncSttnPopup.tsx index 18cdac8e6..b6ebf11ef 100644 --- a/apps/wr/app/map/rainPrfmncSttnPopup.tsx +++ b/apps/wr/app/map/rainPrfmncSttnPopup.tsx @@ -261,7 +261,7 @@ export default function RainPrfmncSttnPopup({ handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} - readOnly={filtrTrtmfctYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -279,7 +279,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={filtrTrtmfctYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -328,7 +328,7 @@ export default function RainPrfmncSttnPopup({ handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} - readOnly={instlCstSprtYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -371,7 +371,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={grntchBdstCertYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -389,7 +389,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={grntchBdstCertYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -407,7 +407,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={grntchBdstCertYn !== "Y"} + readOnly={true} /> </FormUi> )} From 4e9770e197becabced38597e876d7bac76a70c5e Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Mon, 7 Jul 2025 15:53:57 +0900 Subject: [PATCH 008/159] =?UTF-8?q?=EC=98=A8=EB=B0=B0=EC=88=98=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=20=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 33 ++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 747f53971..d2b44bbb3 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -105,6 +105,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); + const [htdflPage,setHtdflPage] = useState(1) if(!featureData) return ; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// useEffect(() => { @@ -132,6 +133,12 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ rswtSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); } + else if(layerId == '온배수시설'){ + featureCd = selectedVal?.bdst_nm; + setFcltPk(featureCd) + htdflSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); + } setViewMode("detail") } } else if (seletectedLayerNm) { setViewMode("list") } @@ -363,9 +370,31 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ htdflTable !== undefined ) { setHtdflDetailModal({ isOpen: true, data: htdflTable[index] }); + setViewMode('detail') } }; - + useEffect(() => { + if (!htdflSttn.isInit) { + initHtdfl(1, "20", "0", '', code.cityCd, code.sggCd); + } + }, [htdflSttn.isInit, initHtdfl]); + + useEffect(() => { + 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(() => { + htdflSttnSearch(htdflPage, "20", '', '', code.cityCd, code.sggCd); + }, [htdflPage]); ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 @@ -555,7 +584,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={(index: number | undefined, headId: string) => { htdflCellClick(index ?? undefined, headId); }} - onPageChange={() => { }} + onPageChange={setHtdflPage} /> </> ); From 37eb11f303233b054afcd80af6a7726596616073 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 7 Jul 2025 16:25:26 +0900 Subject: [PATCH 009/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=EB=93=B1=EB=A1=9D=20=EA=B2=B0?= =?UTF-8?q?=ED=95=A8=20=EC=88=98=EC=A0=95=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltReg/pbnstReg/headList.tsx | 2 +- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 2 + .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 69 ++++++++++--------- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 4 +- .../fcltReg/bdstRegModal/bdstRegModal.tsx | 6 +- .../ruseMngTableForm/ruseMngTableForm.tsx | 12 ++-- 6 files changed, 50 insertions(+), 45 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index d77f4d7f0..bb1cade10 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -50,7 +50,7 @@ export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [ { id: "orgwtWtritQnt", title: "원수취수량" }, { id: "tmsYn", title: "하수처리량TMS 전후" }, { id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​" }, - { id: "dtlPstnExpln", title: "상세위치 설명" }, + { id: "dtlPstnExpln", title: "상세위치", edit: true }, ]; export const fcOrgwtsHeadListExport: TableUpperProps[] = [ { id: "choose", title: "선택", type: "checkbox" }, diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index e4bedff60..66c8c4dc8 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -124,6 +124,7 @@ if(searchTxt){ const hasuList = rainRes.data.map((item: any) => { return { ...item, + fctCpc: Number(item.fctCpc) || 0, ruse: item.ruse === false ? "N" : "Y", }; }); @@ -181,6 +182,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { const pbnstHasuRes = await hasuListFetch(page, sggOrCity); + return set((state: pubFacState) => ({ ...state, pbnst: { diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index e1454342b..b1bbffc34 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -64,7 +64,7 @@ export function PbnstMngForm({ const { fields: fcOpersField, - append, + prepend, remove, } = useFieldArray({ control: form.control, @@ -77,7 +77,7 @@ export function PbnstMngForm({ }); const plusHist = () => { - append({ + prepend({ choose: false, pbnstRuseFcltFk: form.getValues(`items.${indexMng}.pbnstRuseFcltPk`) ?? "", @@ -310,42 +310,43 @@ export function PbnstMngForm({ </div> <div> + {/* <div className="h-[200px] overflow-y-auto"> */} + <div className="flex justify-between items-center mx-3 mb-3"> + <span className={formTableName}>재이용시설 운영정보</span> + {formType === "sttn" ? ( + <></> + ) : ( + <div> + <Button + type="button" + size={commonButonSize} + className="!text-xl" + onClick={plusHist} + > + 추가등록 + </Button> + <Button + type="button" + size={commonButonSize} + className="!text-xl !bg-red-500 !text-white ml-1" + onClick={removeSelected} + > + 삭제 + </Button> + </div> + )} + </div> <div className="h-[200px] overflow-y-auto"> - <div className="flex justify-between items-center mx-3 mb-3"> - <span className={formTableName}>재이용시설 운영정보</span> - {formType === "sttn" ? ( - <></> - ) : ( - <div> - <Button - type="button" - size={commonButonSize} - className="!text-xl" - onClick={plusHist} - > - 추가등록 - </Button> - <Button - type="button" - size={commonButonSize} - className="!text-xl !bg-red-500 !text-white ml-1" - onClick={removeSelected} - > - 삭제 - </Button> - </div> - )} - </div> <RuseMngTableForm - tableData={form.getValues(`items.${indexMng}.fcOpers`) || []} + tableData={fcOpersField} headList={ formType === "sttn" ? pbnst.pbnstMngUpHeadList.map((item) => { - return { - ...item, - readonly: true, - }; - }) + return { + ...item, + readonly: true, + }; + }) : pbnst.pbnstMngUpHeadList } upHeadList={pbnst.pbnstMngNm} @@ -356,7 +357,7 @@ export function PbnstMngForm({ indexMng={indexMng} form={form} formNm={"fcOpers"} - // ref={ref} + // ref={ref} ></RuseMngTableForm> </div> </div> diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index 7333f6091..bc3a6a74d 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -13,7 +13,7 @@ import { } from "@/components/lib/func/commom"; import { DatePicker, FormUi } from "@common/business_components"; import { Form, FormField, SelectBox } from "@common/business_components/ui"; -import { Button, Checkbox, Input, Label } from "@common/components/ui"; +import { Button, Checkbox, Input, Label, ScrollArea } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; @@ -158,6 +158,7 @@ export default function RainRegForm({ )} </div> </div> + <ScrollArea className="h-[37vh]"> {isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>} {isModal ? ( <h1 className="pl-3 text-xl col-span-10 mt-4"> @@ -583,6 +584,7 @@ export default function RainRegForm({ /> </div> </div> + </ScrollArea> </form> </Form> </div> diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index c534c38af..25e5ef976 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -114,7 +114,7 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg > {" "} </SelectBox> - <Label className="w-full text-xl text-gray-600 text-right">건축물명</Label> + <Label className="w-full text-xl text-gray-600 text-right">시설명</Label> <Input className="w-full h-full !text-xl col-span-2 col-start-8" type="text" value={searchTxt || ''} onChange={(e) => setSearchTxt(e.target.value)}/> <Button className="" size={"sm"} onClick={()=>{searchBdst(searchTxt)}}>조회</Button> </div> @@ -142,7 +142,7 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg </div> </ScrollArea> <div className="border-t border-gray-300 my-4"></div> - <ScrollArea className="h-[40vh]"> + {/* <ScrollArea className="h-[40vh]"> */} <div> { moType === 'RNB'? <RainRegForm rainForm={rainBdstForm as customRainBdst} isModal={isModal} setIsModal={setIsModal} /> @@ -152,7 +152,7 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg } </div> - </ScrollArea> + {/* </ScrollArea> */} </div> </> ); diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index 6f4832c68..e746ab1f5 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -76,20 +76,20 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( <TableBody> {tableData.map((item, i) => ( - <TableRow key={i}> + <TableRow key={item.id}> {headList.map((head, j) => ( <TableCell key={`${head.id}-${j}`} className="text-center whitespace-nowrap" - onClick={() => {}} + onClick={() => { }} > <FormField control={form.control} name={ typeof indexMng === "number" && - indexMng >= 0 && - typeof indexBiz === "number" && - indexBiz >= 0 + indexMng >= 0 && + typeof indexBiz === "number" && + indexBiz >= 0 ? `items.${indexMng}.fcBizs.${indexBiz}.${formNm}.${i}.${head.id}` : typeof indexMng === "number" && indexMng >= 0 ? `items.${indexMng}.${formNm}.${i}.${head.id}` @@ -134,7 +134,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( } }} readOnly={head.readonly ? true : false} - // Disabled prop removed as SelectBox does not support it + // Disabled prop removed as SelectBox does not support it ></SelectBox> ) : head.type === "date" ? ( <DatePicker From b7f345fdf779c4f4bbacd147035fa56ccca84baf Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Mon, 7 Jul 2025 16:58:53 +0900 Subject: [PATCH 010/159] =?UTF-8?q?=EC=A7=80=EB=8F=84=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/.env.local | 4 +- apps/wr/middleware.ts | 43 +++++++++++++++++-- .../src/ui/map/lib/gis.core.js | 3 -- .../src/ui/map/lib/gis.layer.js | 32 ++++++-------- 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/apps/wr/.env.local b/apps/wr/.env.local index 858181f32..6cbb4ec6f 100644 --- a/apps/wr/.env.local +++ b/apps/wr/.env.local @@ -9,6 +9,6 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token -NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API -#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 +#NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API +NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정 diff --git a/apps/wr/middleware.ts b/apps/wr/middleware.ts index 5acc41863..9b0c8dc84 100644 --- a/apps/wr/middleware.ts +++ b/apps/wr/middleware.ts @@ -6,6 +6,7 @@ const CLAIM_NAME = "Authorization"; const AUTH_USER_ID = "token-id"; const serverApiUrl = CS_URL; const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || ""; +const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || ""; const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || ""; export function middleware(req: NextRequest) { @@ -48,10 +49,44 @@ export function middleware(req: NextRequest) { } if (pathname.startsWith("/geoserver")) { - const queryParams = searchParams.toString(); - const newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${ - queryParams ? `?${queryParams}` : "" - }`; + let queryParams = searchParams.toString(); + const typename = searchParams.get("TYPENAME"); + console.log("typename ", typename); + + let newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`; + + if ( + typename == "hasudo:tb_il_swage_prcs_fclt" //하수처리시설 + || typename == "hasudo:tb_ms_swage_prcs_zone" //하수처리구역 + || typename == "hasudo:tb_ms_sbmrg_dngr_map" //침수위험지도 + || typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도 + ) { + newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`; + } + else if ( + typename == "hasudo:tb_ms_swage_ppl" //관로 + || typename == "hasudo:tb_ms_swage_mhl" //맨홀 + || typename == "hasudo:tb_ms_swage_pmstn" //펌프장 + || typename == "hasudo:tb_ms_stofcbr" //우수토실 + ) { + newUrl = `${LX_GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`; + } + else if ( + typename == "hasudo:om_dt_untrt_swg_rain" //중점우수토실 + || typename == "hasudo:om_wqlt_station" //관측소 + || typename == "hasudo:tb_wr_bdst_ruse_fclt" //재이용시설 + || typename == "hasudo:tb_wr_rnwtr_utztn_fclt" //빗물이용시설 + || typename == "hasudo:tb_wr_rswtr_fclt" //중수도시설 + || typename == "hasudo:tb_wr_htdfl_fclt" //온배수시설 + || typename == "hasudo:tb_wr_ruse_fclt_dmd_co" //수요처 + || typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처 + ){ + const url = req.nextUrl.clone(); + url.searchParams.set('TYPENAME', typename.replace("hasudo:","")); + queryParams = url.searchParams.toString(); + newUrl = `${SEWERAGE_API_URL}/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`; + } + console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`); return NextResponse.rewrite(new URL(newUrl)); } diff --git a/packages/common/business_components/src/ui/map/lib/gis.core.js b/packages/common/business_components/src/ui/map/lib/gis.core.js index ddfcec3a1..b1b02a732 100644 --- a/packages/common/business_components/src/ui/map/lib/gis.core.js +++ b/packages/common/business_components/src/ui/map/lib/gis.core.js @@ -31,8 +31,6 @@ const GisApp = {}; //레이어 정보 GisApp.layerInfos = []; //기본정보 -//GisApp.GEOSERVER_URL = 'http://rsone.iptime.org:10010/geoserver/hasudo/ows'; -//GisApp.GEOSERVER_WMS_URL = 'http://rsone.iptime.org:10010/geoserver/hasudo/wms'; GisApp.GEOSERVER_URL = '/geoserver/hasudo/ows'; GisApp.SN_GEOSERVER_URL = '/sewerage-service/api/v1/map/geometry'; GisApp.GEOSERVER_WMS_URL = '/geoserver/hasudo/wms'; @@ -56,7 +54,6 @@ GisApp.OPENSTREET_URL = '//tile.openstreetmap.org/{z}/{x}/{y}.png'; GisApp.BASE_MAP_TYPES = []; GisApp.FROM_PROJ = 'EPSG:4326'; -// GisApp.TO_PROJ = 'EPSG:3857'; GisApp.TO_PROJ = 'EPSG:5179'; //ngii 좌표계 GisApp.TO_DATA_PROJ = 'EPSG:4326'; GisApp.CONTEXT_LAYER_PATH = '/images/map/layericon/'; diff --git a/packages/common/business_components/src/ui/map/lib/gis.layer.js b/packages/common/business_components/src/ui/map/lib/gis.layer.js index 097c90ba5..7790aa5dc 100644 --- a/packages/common/business_components/src/ui/map/lib/gis.layer.js +++ b/packages/common/business_components/src/ui/map/lib/gis.layer.js @@ -77,19 +77,6 @@ GisOlLayer.prototype = { let lyrTyNm = options.lyrTyNm; let typename = this.storageNm + lyrTyNm; - if(options.lyrTyNm == "om_dt_untrt_swg_rain" //중점우수토실 - || options.lyrTyNm == "om_wqlt_station" //관측소 - || options.lyrTyNm == "tb_wr_bdst_ruse_fclt" //재이용시설 - || options.lyrTyNm == "tb_wr_rnwtr_utztn_fclt" //빗물이용시설 - || options.lyrTyNm == "tb_wr_rswtr_fclt" //중수도시설 - || options.lyrTyNm == "tb_wr_htdfl_fclt" //온배수시설 - || options.lyrTyNm == "tb_wr_tmpr_dmd_co" //잠재수요처 - ) - { - url = GisApp.SN_GEOSERVER_URL; - typename = lyrTyNm; - } - const params = {}; params['TYPENAME'] = typename; params['SERVICE'] = 'WFS'; @@ -97,16 +84,23 @@ GisOlLayer.prototype = { params['REQUEST'] = 'GetFeature'; params['SRS'] = toProj; params['OUTPUTFORMAT'] = 'application/json'; - if (options?.flterSql && options?.flterSql?.trim() !== 'null') { - params['CQL_FILTER'] = options?.flterSql; - } - const strParams = new URLSearchParams(params).toString(); + let source = new VectorSource({ format: new GeoJSON(), url: function (extent) { + + const [minX, minY, maxX, maxY] = extent; + const bboxFilter = `BBOX(geom, ${minX}, ${minY}, ${maxX}, ${maxY}, '${toProj}')`; + const filter = options?.flterSql && options.flterSql && options.flterSql.trim() !== '' + ? `(${options.flterSql}) AND ${bboxFilter}` + : bboxFilter; + + params['CQL_FILTER'] = filter; + + const strParams = new URLSearchParams(params).toString(); return url + '?' + strParams; }, - strategy: all, + strategy: bbox, }); return source; }, @@ -212,7 +206,7 @@ GisOlLayer.prototype = { return null; } let vectorSource = new VectorSource({ - strategy: all, + strategy: bbox, }); if (feature) { if (Object.prototype.toString.call(feature).slice(8, -1).indexOf('Object') > -1) { From 711739df33c4384a57cc81512df24f2133e28d89 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 7 Jul 2025 17:13:37 +0900 Subject: [PATCH 011/159] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=ED=86=B5=EA=B3=84=20=EA=B1=B4=EC=B6=95=EB=AC=BC?= =?UTF-8?q?=EB=A9=B4=EC=A0=81=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/stats/rswtStat/page.tsx | 4 +-- apps/wr/app/store/stats/rswtStat/excel.tsx | 2 +- apps/wr/app/store/stats/rswtStat/headList.tsx | 25 ++++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/apps/wr/app/stats/rswtStat/page.tsx b/apps/wr/app/stats/rswtStat/page.tsx index 997e95ca5..39d5bc00a 100644 --- a/apps/wr/app/stats/rswtStat/page.tsx +++ b/apps/wr/app/stats/rswtStat/page.tsx @@ -33,7 +33,7 @@ export default function RswtStat() { data: (excelData as unknown as JSON[]) ?? [], fileName: "중수도재이용통계", sheetNameArray: ["Sheet1"], - headerRange: "A1:O1" + headerRange: "A1:N1" }) } @@ -59,7 +59,7 @@ export default function RswtStat() { return { "시도": item.cityText, "개소": item.ctpvCnt, - "건축연면적(m³)": item.archArea, + // "건축연면적(m³)": item.archArea, "처리용량(m³)": item.filtrTrtmfctCpct, "물사용량(m³/년)": item.wtrUsqty, "중수도+대체수이용량(m³/년)": item.rswtAltSum, diff --git a/apps/wr/app/store/stats/rswtStat/excel.tsx b/apps/wr/app/store/stats/rswtStat/excel.tsx index 35f567253..7c6e2b4cc 100644 --- a/apps/wr/app/store/stats/rswtStat/excel.tsx +++ b/apps/wr/app/store/stats/rswtStat/excel.tsx @@ -25,7 +25,7 @@ export const excelRswtStat = (excelList:RswtStatProps[]) : (string | number)[][] //String(item.instlCst) ?? "", "", //건축물면적 - item.archArea ?? "", + // item.archArea ?? "", //처리용량 item.filtrTrtmfctCpct ?? "", //물사용량 diff --git a/apps/wr/app/store/stats/rswtStat/headList.tsx b/apps/wr/app/store/stats/rswtStat/headList.tsx index 877089092..c0860fea7 100644 --- a/apps/wr/app/store/stats/rswtStat/headList.tsx +++ b/apps/wr/app/store/stats/rswtStat/headList.tsx @@ -13,21 +13,22 @@ export const rswtStatHeadListExport :TableUpperProps[]=[ row:0, rowSpan:2 }, - { - id: "a", - title: "시설현황", - row:0, - colSpan:2 - }, - { - id: "archArea", - title: "건축연면적(m³)", - row:1, - }, + // { + // id: "a", + // title: "시설현황", + // row:0, + // colSpan:2 + // }, + // { + // id: "archArea", + // title: "건축연면적(m³)", + // row:1, + // }, { id: "filtrTrtmfctCpct", title: "처리용량(m³)", - row:1, + row:0, + rowSpan:2 }, { id: "wtrUsqty", From 7fc94abf86b47592246fabdfe6e50fa16b277972 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 7 Jul 2025 19:18:29 +0900 Subject: [PATCH 012/159] =?UTF-8?q?=EC=9B=90=EC=88=98=EC=B7=A8=EC=88=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltReg/pbnstReg/headList.tsx | 2 +- .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 27 ++++++++++++------- .../pbnstReg/ruseMngTable/ruseMngTable.tsx | 3 +++ .../ruseMngTableForm/ruseMngTableForm.tsx | 11 ++++++-- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index bb1cade10..46287aa2c 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -47,7 +47,7 @@ export const pbnstDemandHeadListExport: TableUpperProps[] = [ export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [ { id: "ruseUtztnFcltNm", title: "하수처리장명" }, - { id: "orgwtWtritQnt", title: "원수취수량" }, + { id: "orgwtWtritQnt", title: "원수취수량" , type:'number'}, { id: "tmsYn", title: "하수처리량TMS 전후" }, { id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​" }, { id: "dtlPstnExpln", title: "상세위치", edit: true }, diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index a1d433f2d..4d4ad91d8 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -179,10 +179,6 @@ export function PbnstBuseForm({ appendBiz(newItem); setIndexBiz(pbnstBizCycle); // 새로 추가된 차수로 포커스 이동 } - useEffect(() => { - //console.log("form ", form.watch()); - }, [form.formState]); - const { fields: fcDemands, append: appendDemand, @@ -209,6 +205,9 @@ export function PbnstBuseForm({ prevDemandsLengthRef.current = fcDemands.length; }, [fcDemands.length]); + const fcOrgwtWatch = form.watch( `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`) + const pplInstlsWatch = form.watch( `items.${indexMng}.fcBizs.${indexBiz}.pplInstls`) + const { fields: fcOrgwtFiled } = useFieldArray({ control: form.control, name: `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, @@ -304,7 +303,7 @@ export function PbnstBuseForm({ console.log("form errors:", form.formState.errors); }, [form.formState.errors]); - useEffect(() => { + useEffect(() => { const pplSum = form.watch(`items.${indexMng}.fcBizs.${indexBiz}.pplInstls`); if (!pplSum) return; let sum = 0; @@ -314,6 +313,11 @@ export function PbnstBuseForm({ setSumCpct(sum); }, [form.formState, indexMng, indexBiz]); +useEffect(() =>{ + + console.log('form.formState ', form.formState) +}, [form.formState]); + const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`); return ( <> @@ -417,17 +421,18 @@ export function PbnstBuseForm({ 추가등록 </Button> </div> - <RuseMngTable + <RuseMngTableForm key={`fcOrgwts-${indexMng}-${indexBiz}`} // 이게 핵심! tableData={ - form.getValues( - `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts` - ) ?? [] + form.getValues( `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`)||[] + // fcOrgwtWatch||[] } + form={form} headList={pbnst.pbnstOrgwtHeadList} upHeadList={[]} indexMng={indexMng} + formNm={"fcOrgwts"} indexBiz={indexBiz} /> </div> @@ -479,6 +484,7 @@ export function PbnstBuseForm({ form.getValues( `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` ) ?? [] + // pplInstlsWatch||[] } headList={pbnst.pplInstlsHeadLisat} code={ppiSelectList ?? []} @@ -489,9 +495,10 @@ export function PbnstBuseForm({ formNm={"pplInstls"} upHeadList={[]} onTableSet={(val) => { - const pplSum = form.getValues( + const pplSum = form.watch( `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` ); + if (!pplSum) return; let sum = 0; pplSum.forEach((item) => { diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx index e4ffc1f8d..715e91d8c 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx @@ -35,11 +35,14 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>( { tableData, headList, upHeadList, code, onTableSet, indexMng, indexBiz }, ref ) => { + + const [tableState, setTableState] = useState([...tableData]); useEffect(() => { if (ref && typeof ref === "object" && "current" in ref) { ref.current = tableState; } + if (onTableSet) onTableSet(tableState); }, [tableState, onTableSet]); diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index e746ab1f5..577e7ce46 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -76,7 +76,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( <TableBody> {tableData.map((item, i) => ( - <TableRow key={item.id}> + <TableRow key={`${item.id }-${i}` } > {headList.map((head, j) => ( <TableCell key={`${head.id}-${j}`} @@ -161,7 +161,14 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( }} ></Checkbox> ) : ( - `${item[head.id] || ""}` + ( + + <span className="text-black">{ + head.type === "number" + ? formatCommaNumber(field.value) + : field.value || "" + }</span> + ) )} </FormUi> )} From f7580defc97f31a07903a8959b5bc62285563987 Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Mon, 7 Jul 2025 19:37:57 +0900 Subject: [PATCH 013/159] =?UTF-8?q?ENV=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/.env.development | 2 +- apps/wr/.env.local | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/wr/.env.development b/apps/wr/.env.development index dccfb1453..e6bd4bf83 100644 --- a/apps/wr/.env.development +++ b/apps/wr/.env.development @@ -3,7 +3,7 @@ NEXT_PUBLIC_PORT = 11301 NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11301 NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver -NEXT_PUBLIC_TEMP_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver #TODO 운영에서 바꿔야 함 +NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver NEXT_PUBLIC_CLAIM_NAME = Authorization NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token diff --git a/apps/wr/.env.local b/apps/wr/.env.local index 6cbb4ec6f..125bcc824 100644 --- a/apps/wr/.env.local +++ b/apps/wr/.env.local @@ -3,7 +3,7 @@ NEXT_PUBLIC_PORT = 3001 NEXT_PUBLIC_PROXY_HOST = http://localhost:3001 NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver -NEXT_PUBLIC_TEMP_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver #TODO 운영에서 바꿔야 함 +NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver NEXT_PUBLIC_CLAIM_NAME = Authorization NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token From 8e7d32a48bd15c0e941e7e21c5cd1bfb0a310c26 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Mon, 7 Jul 2025 19:56:56 +0900 Subject: [PATCH 014/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=20=ED=98=84=ED=99=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 139 ++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 42 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index d2b44bbb3..c6ca97042 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -1,8 +1,8 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; -import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import type { customPbnst, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { excelDownload, tableData } from "@/components/lib/func/commom"; -import { Title, UiTable, UITab, ContentsDiv } from '@common/business_components'; +import { Title, UiTable, UITab, ContentsDiv, ScrollArea } from '@common/business_components'; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Button } from "@common/components/ui"; import React, { useCallback, useState, useEffect } from 'react'; @@ -18,13 +18,14 @@ import HtdflPrfmncSttnPopup from "@/app/map/htdflPrfmncSttnPopup"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import { getFetch } from "@/components/lib/api"; import { useGisContext } from "@common/business_components/ui/map/Gis"; +import ListDiv from "@common/business_components/ui/list_div"; interface NewWindowPopupProps { featureData: any; checkedLayers?: string[]; checkedLayersData?: any[]; seletectedLayerNm?: string - viewMode?: 'list' | 'detail' + viewMode?: 'list' | 'detail' | 'nothing' onClose: () => void; } @@ -55,7 +56,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ 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'>('list'); + const [viewMode, setViewMode] = useState<'list' | 'detail' | 'nothing'>('list'); const [fcltPk, setFcltPk] = useState<string>(''); @@ -105,14 +106,27 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); - const [htdflPage,setHtdflPage] = useState(1) - if(!featureData) return ; + const [htdflPage, setHtdflPage] = useState(1) + + const { + pbnst, + pubHasuInit, + pubHasuSearch, + } = useWrStore((state) => state); + const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; + const [isRuseReg, setIsRuseReg] = useState<{ + isModal: boolean; + }>({ isModal: false }); + const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); + const [selectRow, setSelectRow] = useState<pubHasuType>(); + const [hasuPage, setHasuPage] = useState<number>(1); + if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// useEffect(() => { if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); const layerId = getSelectedLayers(); - let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' ? selectedVal?.bdst_nm : ''; + let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? 'a' : null; if (featureCd && featureCd !== fcltPk) { if (layerId == '하수재이용시설') { featureCd = selectedVal?.swtrmt_fclt_cd; @@ -125,6 +139,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setFcltPk(featureCd) rainSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setRainDetailModal({ isOpen: true, data: rainSttn.rainSttnRes[0] }); + setViewMode("detail") } else if (layerId == '중수도시설') { featureCd = selectedVal?.bdst_nm; @@ -132,14 +147,16 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setFcltPk(featureCd) rswtSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); + setViewMode("detail") } - else if(layerId == '온배수시설'){ + else if (layerId == '온배수시설') { featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) htdflSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); + setViewMode("detail") } - setViewMode("detail") + else if(layerId =='하수처리시설') setViewMode('nothing') } } else if (seletectedLayerNm) { setViewMode("list") } }, [featureData]); @@ -342,8 +359,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setRswtrTable(chData); }, [code, rswtSttnRes]); -// 엑셀 관련 - const rswtSttnExcelDownload = useCallback(()=>{ + // 엑셀 관련 + const rswtSttnExcelDownload = useCallback(() => { console.log('excel', rswtSttn.excelList, rswtrTable) if (rswtSttn.excelList.length > 0) { if (rswtSttn.excelList.length === 0) return; @@ -354,14 +371,14 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ "A1:W3", ); } - },[rswtSttn.excelList]) + }, [rswtSttn.excelList]) useEffect(() => { rswtSttnSearch(rswtrPage, "20", '', '', code.cityCd, code.sggCd); }, [rswtrPage]); ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// - ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// + ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 온배수시설 cellClick 이벤트 (상세정보) const htdflCellClick = (index: number | undefined, headId: string) => { if ( @@ -374,29 +391,43 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } }; useEffect(() => { - if (!htdflSttn.isInit) { - initHtdfl(1, "20", "0", '', code.cityCd, code.sggCd); - } - }, [htdflSttn.isInit, initHtdfl]); - - useEffect(() => { - 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]); + if (!htdflSttn.isInit) { + initHtdfl(1, "20", "0", '', code.cityCd, code.sggCd); + } + }, [htdflSttn.isInit, initHtdfl]); - useEffect(() => { - htdflSttnSearch(htdflPage, "20", '', '', code.cityCd, code.sggCd); - }, [htdflPage]); + useEffect(() => { + 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(() => { + htdflSttnSearch(htdflPage, "20", '', '', code.cityCd, code.sggCd); + }, [htdflPage]); ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// + useEffect(() => { + if (code.sggCd.length && pbnstHasuRes.length > 0) { + setHasuTable(tableData(pbnstHasuRes, { code })); + } + }, [code, pbnstHasuRes]); + useEffect(() => { + if (!pbnst.isInit) { + pubHasuInit("1", "41"); + } + }, [pbnst.isInit, pubHasuInit]); + useEffect(() => { + pubHasuInit(String(hasuPage), "41"); + }, [hasuPage, pubHasuInit]); + // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { // 특정 레이어가 체크되었는지 확인 @@ -408,6 +439,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (layerId === null || layerId === undefined) { layerId = seletectedLayerNm || ''; } + //하수처리시설 + let isPrcsFclt = layerId == '하수처리시설' // 재이용시설 let isPbnst = layerId == '하수재이용시설'; // 빗물이용시설 @@ -416,7 +449,28 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ let isRswt = layerId == '중수도시설'; // 온배수시설 let isHtdfl = layerId == '온배수시설'; - + if (isPrcsFclt) { + if (viewMode == 'list') { + return ( + <> + <div className="flex justify-between items-center mb-4"> + <Title title="하수처리시설 현황" /> + </div> + {/* 높이 조정 */} + <UiTable + tableData={bdstTable || []} + headlist={pubFacHeadList} + pageSize={10} + total={100000} + headName={""} + cellClick={()=>{}} + onPageChange={setHasuPage} + children={undefined} + /> + </> + ) + } + } if (isPbnst) { if (viewMode == 'detail') { // 재이용시설 상세 @@ -448,11 +502,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <> <div className="flex justify-between items-center"> <Title title="하수재이용시설 현황" /> - <div className="flex gap-2 mt-8"> + {/* <div className="flex gap-2 mt-8"> <Button className={btnClass} color="primary" onClick={excelClick}> 엑셀다운로드 </Button> - </div> + </div> */} </div> <UiTable headName={[]} @@ -488,11 +542,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <> <div className="flex justify-between items-center"> <Title title="빗물이용시설 현황" /> - <div className="flex gap-2 mt-8"> + {/* <div className="flex gap-2 mt-8"> <Button className={btnClass} color="primary" onClick={excelClick}> 엑셀다운로드 </Button> - </div> + </div> */} </div> <UiTable headName={[]} @@ -528,11 +582,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <> <div className="flex justify-between items-center"> <Title title="중수도시설 현황" /> - <div className="flex gap-2 mt-8"> + {/* <div className="flex gap-2 mt-8"> <Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}> 엑셀다운로드 </Button> - </div> + </div> */} </div> <UiTable headName={[]} @@ -568,11 +622,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <> <div className="flex justify-between items-center"> <Title title="온배수시설 현황" /> - <div className="flex gap-2 mt-8"> + {/* <div className="flex gap-2 mt-8"> <Button className={btnClass} color="primary" onClick={excelClick}> 엑셀다운로드 </Button> - </div> + </div> */} </div> <UiTable headName={[]} @@ -595,6 +649,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; return ( + viewMode == 'nothing' ? <></> : <NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보"> {/* 체크된 레이어에 따른 조건부 렌더링 */} {renderConditionalContent()} From 04b365b94df0982984cde1ea5b6c4562286957af Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 7 Jul 2025 20:29:01 +0900 Subject: [PATCH 015/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=ED=98=84=ED=99=A9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=A1=B0=EA=B1=B4=20=EB=B3=80=EA=B2=BD,=20=EC=97=91?= =?UTF-8?q?=EC=85=80=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 65 +++++++------ .../ruseFcltMng/fcltReg/rainReg/index.tsx | 10 +- .../fcltSttn/htdflSttn/headList.tsx | 6 +- .../fcltSttn/pbnstSttn/headList.tsx | 32 +++---- .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 92 ++++++++++--------- 5 files changed, 114 insertions(+), 91 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 7a7a125d2..13a71263e 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -38,16 +38,18 @@ export default function PbnstSttn() { ); const [isChHead, setIsChHead] = useState(false); const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>(); + const [pageNation, setPageNation] = useState(1); const [pbnDetaileData, setPbnDetaileData] = useState<{ isModal: boolean; data: customPbnst; }>({ isModal: false, data: {} as customPbnst }); + const [returnType, setReturnType] = useState<ReturnType>({} as ReturnType); const [pbnRuseNm, setPbnRuseNm] = useState<string>(""); const excelClick = useCallback(() => { - pbnstSttnSearch("1", "10000", ref.current, "", searchYear); - }, [pbnstSttnSearch, searchYear, ref.current]); + pbnstSttnSearch(true, "1", "20", ref.current, "", searchYear); + }, [pbnstSttnSearch]); const cellCLick = useCallback( (index: number | undefined) => { @@ -75,7 +77,7 @@ export default function PbnstSttn() { }, [pbnstSttn.excelList]); useEffect(() => { if (!pbnstSttn.isInit) { - pbnSttnInit("1", "13", ref.current, searchYear); + pbnSttnInit("1", "20", ref.current, searchYear); } }, [pbnstSttn.isInit, pbnSttnInit, ref.current]); useEffect(() => { @@ -91,6 +93,10 @@ export default function PbnstSttn() { // pbnNmSearch(String(pageNation), "23", ref.current, pbnRuseNm, searchYear); // }, [pbnRuseNm,pageNation]); + useEffect(() => { + pbnstSttnSearch(false, String(pageNation), "20", returnType, pbnRuseNm, searchYear); + }, [pageNation]); + useEffect(() => { if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk) setPbnDetaileData({ @@ -127,34 +133,36 @@ export default function PbnstSttn() { } 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-64 mt-2 mx-4 text-xl text-gray-600"> - {"하수처리시설명 "} - </Label> - <SearchInput - className={"text-2xl w-full ㅍ"} - label="" - textValue={pbnRuseNm || ""} - setText={(e) => { - setPbnRuseNm(e || ""); - }} - /> - </div> + <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-64 mt-2 mx-4 text-xl text-gray-600"> + {"하수처리시설명 "} + </Label> + <SearchInput + className={"text-2xl w-full ㅍ"} + label="" + textValue={pbnRuseNm || ""} + setText={(e) => { + setPbnRuseNm(e || ""); + }} + /> + </div> } queryClick={function (returnType: ReturnType): void { - pbnstSttnSearch("1", "20", returnType, pbnRuseNm, searchYear); + console.log("시군구코드", returnType) + setReturnType(returnType); + pbnstSttnSearch(false, "1", "20", returnType, pbnRuseNm, searchYear); }} excelClick={excelClick} - initClick={function (): void {}} + initClick={function (): void { }} btnClass={btnClass} ref={ref} isAdmin={false} @@ -178,8 +186,9 @@ export default function PbnstSttn() { }} onPageChange={(page: number) => { pbnstSttnSearch( + false, String(page), - String(13), + String(20), ref.current, pbnRuseNm, searchYear diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index 6ceb75531..ce30e3893 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -1,5 +1,5 @@ import type { TableUpperProps } from "@/app/store/common/type/header"; -import { getFetch, postFectch, putFectch } from "@/components/lib/api"; +import { getFetch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api"; import { z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; import toast from "react-hot-toast"; @@ -95,7 +95,9 @@ export const rainFacStateExport: rainFacState = { }; const initFetch = async (code:string|number) => { - const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/1/10/${code}`); + // const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/1/10/${code}`); + const rainRes =await getFetchWithCount("wr", `/reuseFc/rainyInfoList/1/10/${code}`); + console.log("데이터", rainRes) return rainRes; }; export const rainFacActionsExport: (set: any) => rainFacSActions = ( @@ -143,7 +145,9 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( rainSearch: async(txt:string,pageNation:number) =>{ try{ - const rainRes = await getFetch('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:'')) + // const rainRes = await getFetch('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:'')) + const rainRes = await getFetchWithCount('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:'')) + console.log("rainRes", rainRes) set((state: rainFacState) => { return { rain: { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx index 756c47b9b..bb58b6ea5 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx @@ -105,7 +105,7 @@ export const htdflSttHeadListExport: z.infer<typeof sttnHeadListType> = [ export const htdflSttNodeListExport: CommonTableProps[] = [ { id: "bdnstInfo", - title: "1.건축물정보", + title: "건축물정보", visible: true, row: 1, rowSpan: 1, @@ -113,7 +113,7 @@ export const htdflSttNodeListExport: CommonTableProps[] = [ }, { id: "htdflFcltInfo", - title: "2.온배수 시설현황", + title: "온배수 시설현황", visible: true, row: 1, rowSpan: 1, @@ -121,7 +121,7 @@ export const htdflSttNodeListExport: CommonTableProps[] = [ }, { id: "htdflMngInfo", - title: "3.온배수운영현황", + title: "온배수운영현황", visible: true, row: 1, rowSpan: 1, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx index 7c2953932..075b91261 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx @@ -100,7 +100,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 3, }, { - id: "operMngCd", + id: "rgnNm", title: "환경청", visible: true, row: 1, @@ -116,7 +116,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 2, }, { - id: "bdnstNm", + id: "bscFctNm", title: "시설명", visible: true, row: 1, @@ -124,7 +124,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "locDiv", + id: "efflWqltStndrdNm", title: "지역구분", visible: true, row: 1, @@ -148,7 +148,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "rusNm", + id: "ruseUtztnFcltNm", title: "재이용시설명", visible: true, row: 1, @@ -180,7 +180,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 4, }, { - id: "a", + id: "rvbsn", title: "권역", upName: "catchment", visible: true, @@ -189,7 +189,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "aaa", + id: "lgbsn", title: "단위유역", upName: "catchment", visible: true, @@ -198,7 +198,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "aaaa", + id: "mdmbsn", title: "중권역", upName: "catchment", visible: true, @@ -207,7 +207,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "cityText", + id: "sido", title: "시도", upName: "adminDiv", visible: true, @@ -216,7 +216,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "sggText", + id: "gugun", title: "시군구", upName: "adminDiv", visible: true, @@ -234,7 +234,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "trbt", + id: "splyExtraCpct", title: "하수처리량(m³/일)", upName: "rusSup", visible: true, @@ -252,7 +252,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "total", + id: "usageTotal", title: "합계", upName: "yearResult", visible: true, @@ -261,7 +261,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "ithlWtr", + id: "inUsage", title: "장내용수", upName: "yearResult", visible: true, @@ -270,7 +270,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "othlWtr", + id: "outUsage", title: "장외용수", upName: "yearResult", visible: true, @@ -279,7 +279,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "mngMeth", + id: "operMthd", title: "운영방식", upName: "mngInfo", visible: true, @@ -297,7 +297,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "firstDay", + id: "bgngDt", title: "시작일", upName: "mngInfo", visible: true, @@ -306,7 +306,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "LastDay", + id: "endDt", title: "종료일", upName: "mngInfo", visible: true, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 33bce5520..76a13943f 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -1,6 +1,6 @@ import type { CommonTableProps, TableUpperProps } from "@/app/store/common/type/header"; import type { z } from "zod"; -import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList"; +import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList"; import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import { controlHeadView } from "../rainSttn"; import type { sttnHeadListType } from "../rainSttn/headList"; @@ -21,12 +21,12 @@ export type pbnstSttnState = { pbnstSttHeadList: CommonTableProps[]; pbnstSttNodeList: CommonTableProps[]; pbnstDetail: customPbnst; - ruseFcltNodeList:TableUpperProps[] - ruseSplyHeadList:TableUpperProps[] - rusePplHeadList:TableUpperProps[] - ruseGuranteeHeadList:TableUpperProps[] - ruseDmdHeadList:TableUpperProps[] - ruseFcltHeadList:TableUpperProps[] + ruseFcltNodeList: TableUpperProps[] + ruseSplyHeadList: TableUpperProps[] + rusePplHeadList: TableUpperProps[] + ruseGuranteeHeadList: TableUpperProps[] + ruseDmdHeadList: TableUpperProps[] + ruseFcltHeadList: TableUpperProps[] excelList: []; isInit: boolean; }; @@ -35,11 +35,12 @@ export type pbnstSttnState = { type pbnstSttnActions = { pbnstChSttnHead: (headList: z.infer<typeof sttnHeadListType>) => void; pbnstSttnSearch: ( + isExcel: boolean, page: string, total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string + year: string, ) => void; pbnSttnInit: ( page: string, @@ -63,12 +64,12 @@ export const pbnstSttnStateExport: pbnstSttnState = { pbnstSttn: { pbnstSttHeadList: pbnstSttHeadList, pbnstSttNodeList: pbnstSttNodeList, - ruseFcltNodeList:ruseFcltNodeListExport, - ruseSplyHeadList:ruseSplyHeadListExport, - rusePplHeadList:rusePplHeadListExport, - ruseGuranteeHeadList:ruseGuranteeHeadListExport, - ruseDmdHeadList:ruseDmdHeadListExport, - ruseFcltHeadList:ruseFcltHeadListExport, + ruseFcltNodeList: ruseFcltNodeListExport, + ruseSplyHeadList: ruseSplyHeadListExport, + rusePplHeadList: rusePplHeadListExport, + ruseGuranteeHeadList: ruseGuranteeHeadListExport, + ruseDmdHeadList: ruseDmdHeadListExport, + ruseFcltHeadList: ruseFcltHeadListExport, pbnstSttnRes: [], pbnstDetail: {} as customPbnst, pbnstSearchData: [], @@ -84,33 +85,39 @@ const hasuListFetch = async ( searchNm: string | undefined, year: string ) => { + let url = ""; if (reurnValue.partValue === "A") { url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${ - reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue + // reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue + reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue }/0/1/SW` } else if (reurnValue.partValue === "R") { - url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${ - reurnValue.regionValue - ? reurnValue.regionValue - : reurnValue.unitWaterShedValue - ? reurnValue.unitWaterShedValue - : reurnValue.middleRegionValue + url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${reurnValue.regionValue + ? reurnValue.regionValue + : reurnValue.unitWaterShedValue + ? reurnValue.unitWaterShedValue + : reurnValue.middleRegionValue }/0/1/SW` } else { url = `/prcsFclt/info/${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue}/0/1/SW` - + } - if( searchNm&& searchNm?.length>0){ - url+="/"+searchNm + if (searchNm && searchNm?.length > 0) { + url += "/" + searchNm } + + console.log("주소", url) const pbnList = await getFetch(fetchType.COMMON, url); + console.log("pbnList", pbnList) const arrayList = pbnList.map((item: pubHasuType) => item.bscFctCd); + console.log("어레이리스트", arrayList) const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}`, arrayList, fetchType.WR ); + console.log("getRuseList", getRuseList) const checkWrRegListRes = getRuseList.data; const data: WaterReuseFacility[] = checkWrRegListRes.map( @@ -167,11 +174,11 @@ const hasuListFetch = async ( outUsage: usage.outUsage, operMthd: item.operList[0]?.operMthd, rprtvBzenty: item.operList[0]?.rprtvBzenty, - bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", + bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "", searchNm: findData.bscFctNm, searchPk: findData.bscFctCd, - prfList:item?.prfList??[] + prfList: item?.prfList ?? [] }; } ); @@ -196,13 +203,15 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( })); }, pbnstSttnSearch: async ( + isExcel: boolean, page: string, total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string + year: string, ) => { try { + console.log("여기") const pbnstSttnRes = await hasuListFetch( page, total, @@ -210,9 +219,12 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( searchNm, year ); + console.log("pbnstSttnRes", pbnstSttnRes); - if (Number(total) > 9000) { + // if (Number(total) > 9000) { + if (isExcel) { const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes); + set((state: pbnstSttnState) => { return { ...state, @@ -253,7 +265,6 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( year ); - console.log('pbnstSttnRes ', pbnstSttnRes) set((state: pbnstSttnState) => { return { ...state, @@ -271,10 +282,9 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( getPbnStnDetail: async (pbnstRuseFcltPk: string) => { try { let pbnstDetail = await getFetch("wr", `/reuseFc/pubFc/${pbnstRuseFcltPk}`); - if(pbnstDetail.length>=0){ - pbnstDetail= pbnstDetail.find((item: customPbnst) =>item.pbnstRuseFcltPk === pbnstRuseFcltPk) + if (pbnstDetail.length >= 0) { + pbnstDetail = pbnstDetail.find((item: customPbnst) => item.pbnstRuseFcltPk === pbnstRuseFcltPk) } - console.log( 'pbnstDetail ', pbnstDetail) set((state: pbnstSttnState) => { return { ...state, @@ -294,16 +304,16 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( reurnValue: ReturnType, searchNm: string | undefined, year: string - ) => { + ) => { try { - - const pbnstSttnRes = await hasuListFetch( - page, - total, - reurnValue, - searchNm, - year - ); + + const pbnstSttnRes = await hasuListFetch( + page, + total, + reurnValue, + searchNm, + year + ); set((state: pbnstSttnState) => { return { From 5ec33d01653870a5f435b7a6989ba36dc1f29087 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 7 Jul 2025 20:31:35 +0900 Subject: [PATCH 016/159] =?UTF-8?q?=EC=88=98=EC=9A=94=EC=B2=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B3=80=EA=B2=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 38 +++++++++-- apps/wr/app/store/common/searchCode/index.ts | 40 ++++++++---- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 65 ++++++++----------- .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 6 +- 4 files changed, 89 insertions(+), 60 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 9f243627c..ab8df5d8f 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -110,9 +110,37 @@ export default function PublicReuseFaciltyInsert() { fcOpers: fclt.fcOpers, }; }); - await pbnstRuseFcltUpdate(pbnst as customPbnst[]) - await pbnstRuseBizUpdate(bizs); + + Promise.allSettled([ + pbnstRuseFcltUpdate(pbnst as customPbnst[]), + pbnstRuseBizUpdate(bizs) + ]).then(([resFclt, resBiz]) => { + const isFcltSuccess = resFclt.status === "fulfilled"; + const isBizSuccess = resBiz.status === "fulfilled"; + + if (isFcltSuccess && isBizSuccess) { + toast.success('하수 재이용 시설 및 사업이 수정되었습니다. ') + // 메시지 표시, 페이지 이동 등 + } else { + + let message ='' + // ✅ 각각 어떤 항목이 실패했는지도 로그/알림 처리 + if (!isFcltSuccess) { + message = '하수재이용 시설 ' + } + if (!isBizSuccess) { + message += '하수재이용 시설 사업 ' + } + + toast.error(message+'오류 입니다 ') + pubHasuInit("1", "41"); + } + + + }); + + }; // 폼 유효성 검사 실패 시 호출될 함수 @@ -199,9 +227,6 @@ export default function PublicReuseFaciltyInsert() { useEffect(() => { if (pbnst.pbnstRes && pbnst.pbnstRes?.length > 0) { - - - form.reset({ items: pbnst.pbnstRes }); } else { @@ -214,6 +239,9 @@ export default function PublicReuseFaciltyInsert() { } }, [indexMng]); + + + useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); diff --git a/apps/wr/app/store/common/searchCode/index.ts b/apps/wr/app/store/common/searchCode/index.ts index 656bc33d9..4e383b4a4 100644 --- a/apps/wr/app/store/common/searchCode/index.ts +++ b/apps/wr/app/store/common/searchCode/index.ts @@ -7,12 +7,12 @@ import { import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; import type { conCostFeeType, rateFeeType } from "./type"; +import toast from "react-hot-toast"; export const comFcltStateExport: comFcltState = { searchFclts: [] as pubHasuType[], demandCompList: [], - dmdIsSucees: '', checkDemand: { index: 0, dmdInfoPk: "", @@ -52,7 +52,6 @@ export type comFcltType = comFcltState & comFcltActions; export type comFcltState = { searchFclts: pubHasuType[]; demandCompList: DemandCompType[]; - dmdIsSucees: string; checkDemand: DemandCompType; constCostRes:conCostFeeType[], rateFeeRes:rateFeeType[], @@ -110,19 +109,20 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => { data, fetchType.WR ); - let message = ""; if (response.status === 200) { - message = "success"; - } else { - message = "fail"; + toast.success('수요처가 등록되었습니다. ') + set((state: comFcltState) => { + + return { + ...state, + dmdIsSucees: "success" + } + }); } - - - set((state: comFcltState) => { - return state.dmdIsSucees = message; - }); } catch (err) { console.log(err); + toast.error('수요처가 등록 오류입니다.. ') + } }, updateDemandCompany: async (data: DemandCompType) => { @@ -137,7 +137,10 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => { } set((state: comFcltState) => { - return state.dmdIsSucees = message; + return { + ...state, + dmdIsSucees: message + } }); } catch (err) { console.log(err); @@ -149,7 +152,11 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => { const rateFeeRes = await getFetch(fetchType.COMMON, url); set((state: comFcltState) => { - return state.rateFeeRes = rateFeeRes;; + + return { + ...state, + rateFeeRes: rateFeeRes + } }); } catch (e) { console.log(" error ", e); @@ -159,7 +166,12 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => { const url = `/prcsFclt/CstRuse/${year}`; const constCost = await getFetch(fetchType.COMMON, url); set((state: comFcltState) => { - return state.constCostRes = constCost;; + + return { + ...state, + constCostRes: constCost + } + }); }catch (e) { } diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 66c8c4dc8..3057cec7f 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -60,14 +60,11 @@ export type pubFacState = { type pubFacActions = { pubHasuInit: (page: string, sggOrCity: string) => void; pbnstRegClick: (pubHasuRes: pubHasuType) => void; - pbnstReg: (txt: string | undefined) => void; + //pbnstReg: (txt: string | undefined) => void; pbnstInsert(pbnstRes: customPbnst): Promise<void>; appendRuseFclt(array: customPbnst[]): void; fileDelete: (atflCd: string) => void; fileDownLoad: (atflCd: string) => void; - //pbnstMngData: (data: customPbnst[]) => void; - //pbnstBizData(data: fcBizType): void; - // getBizCycle: (pbnstObj: customPbnst) => void; getpbnstInsertIndex: (data: pbnstInsertIndex) => void; pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; @@ -226,21 +223,21 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } }, - pbnstReg: async (txt: string | undefined) => { - try { - const pbnstRes = await hasuListFetch("11", "11"); - return set((state: pubFacState) => ({ - ...state, - pbnst: { - ...state.pbnst, - pbnstRes: pbnstRes, - isInit: false, - }, - })); - } catch (errorHasu) { - console.log(errorHasu); - } - }, + // pbnstReg: async (txt: string | undefined) => { + // try { + // const pbnstRes = await hasuListFetch("11", "11"); + // return set((state: pubFacState) => ({ + // ...state, + // pbnst: { + // ...state.pbnst, + // pbnstRes: pbnstRes, + // isInit: false, + // }, + // })); + // } catch (errorHasu) { + // console.log(errorHasu); + // } + // }, pbnstInsert: async (pbnstRes: customPbnst) => { try { @@ -272,14 +269,9 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { `/reuseFc/pubFc`, ruseRes ); - - if(response){ - - toast.success(` 하수재이용 시설 정보가 수정되었습니다.`); - } + } catch (error) { console.error("Error pbnstRuseFcltUpdate:", error); - toast.error(` 하수재이용 시설 정보가 수정오류입니다.`); } } ,pbnstRuseBizUpdate : async(ruseRes:fcBizType[])=>{ try { @@ -290,22 +282,19 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { ruseRes ); - if(response){ - toast.success(` 하수재이용 시설 사업이 수정되었습니다.`); - } - const pbnstRes = await hasuListFetch("11", "11"); + // const pbnstRes = await hasuListFetch("11", "11"); - return set((state: pubFacState) => ({ - ...state, - pbnst: { - ...state.pbnst, - pbnstRes: pbnstRes, - isInit: false, - }, - })); + // return set((state: pubFacState) => ({ + // ...state, + // pbnst: { + // ...state.pbnst, + // pbnstRes: pbnstRes, + // isInit: false, + // }, + // })); } catch (error) { console.error("Error pbnstRuseFcltUpdate:", error); - toast.error(` 하수재이용 시설 사업이 수정이 실패되엇습니다..`); + // toast.error(` 하수재이용 시설 사업이 수정이 실패되엇습니다..`); } } , getBizCycle: async (pbnstObj: customPbnst) => { diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 4d4ad91d8..2a2e9defe 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -134,7 +134,6 @@ export function PbnstBuseForm({ (orgwt) => orgwt.bscFctCd === item.swtrmtFcltFk )?.bscFctNm; - console.log("orgwtNm ", orgwtNm); if (orgwtNm) { form.setValue( `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts.${index}.ruseUtztnFcltNm`, @@ -205,8 +204,6 @@ export function PbnstBuseForm({ prevDemandsLengthRef.current = fcDemands.length; }, [fcDemands.length]); - const fcOrgwtWatch = form.watch( `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`) - const pplInstlsWatch = form.watch( `items.${indexMng}.fcBizs.${indexBiz}.pplInstls`) const { fields: fcOrgwtFiled } = useFieldArray({ control: form.control, @@ -319,6 +316,9 @@ useEffect(() =>{ }, [form.formState]); const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`); + + + return ( <> {pbnstBiz && pbnstBiz?.length > 0 ? ( From b0861e5182347d5c4517c81dec122955ff91a791 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 09:30:57 +0900 Subject: [PATCH 017/159] =?UTF-8?q?=EC=A7=80=EB=8F=84=ED=8C=9D=EC=97=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/.env.local | 4 ++-- apps/wr/app/map/newWindowPopup.tsx | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/wr/.env.local b/apps/wr/.env.local index 125bcc824..18cb6fe85 100644 --- a/apps/wr/.env.local +++ b/apps/wr/.env.local @@ -9,6 +9,6 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token -#NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API -NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 +NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API +# NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정 diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index c6ca97042..1fbd0df33 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -133,6 +133,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setFcltPk(featureCd); // 현재 호출된 featureCd 저장 setActiveTab(featureCd) fetchpbnstDetail(featureCd); // 상세정보 + setViewMode("detail") } else if (layerId == '빗물이용시설') { featureCd = selectedVal?.bdst_nm; @@ -184,8 +185,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const source = layer.getSource(); if (source && source.hasFeature && featureData && typeof featureData.getId === 'function' && source.hasFeature(featureData)) { - featureLayer = layer; // 피처가 속한 레이어 찾기 + featureLayer = layer; // 피처가 속한 레이어 찾기) } + console.log('layernm',layer.get('lyrNm')) }); result = featureLayer.get('lyrNm'); @@ -234,6 +236,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 재이용시설 페이징처리 관련 함수 const onPageChangeHandler = useCallback((page: number) => { pbnstSttnSearch( + true, String(page), String(13), { From 43c50d694f5f5a6683e36a27e3428a4c337a0930 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 09:48:19 +0900 Subject: [PATCH 018/159] =?UTF-8?q?=EC=9E=AC=EC=9D=B4=EC=9A=A9=20=ED=98=84?= =?UTF-8?q?=ED=99=A9=20=EB=82=98=EC=98=A4=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 1fbd0df33..ee6216b28 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -198,8 +198,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (!pbnstSttn.isInit) { pbnSttnInit("1", "13", { partValue: "A", - sidoValue: "0", - sigunValue: "", + sidoValue: '0', + sigunValue: "0", regionValue: "", unitWaterShedValue: "", middleRegionValue: "", @@ -242,7 +242,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ { partValue: "A", sidoValue: "0", - sigunValue: "", + sigunValue: "0", regionValue: "", unitWaterShedValue: "", middleRegionValue: "", From 1e524ba9c565fa9659f4521aa5de390b0dddb18e Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Tue, 8 Jul 2025 09:51:59 +0900 Subject: [PATCH 019/159] =?UTF-8?q?[apps/cs]=20feat:=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=20=EC=9E=84=EC=8B=9C=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EB=B6=88?= =?UTF-8?q?=EB=9F=AC=EC=98=A4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/entities/menu/api/menu-service.ts | 21 ++++++++ .../src/entities/menu/model/menu-interface.ts | 14 ++++++ apps/cs/src/pages/menu/ui/menu-form.tsx | 49 +++++++++++++++++-- apps/cs/src/shared/config/api.ts | 2 +- 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/apps/cs/src/entities/menu/api/menu-service.ts b/apps/cs/src/entities/menu/api/menu-service.ts index 7dd0aecd9..33ad06837 100644 --- a/apps/cs/src/entities/menu/api/menu-service.ts +++ b/apps/cs/src/entities/menu/api/menu-service.ts @@ -5,6 +5,7 @@ import type { Menu, MenuItem, MenuFormData, + MenuTemporarilyStoredData, } from "../model/menu-interface"; export class MenuApiService implements MenuService { @@ -44,6 +45,26 @@ export class MenuApiService implements MenuService { public async deleteMenu(menuCd: number): Promise<void> { await client.delete(`${ENDPOINT.CMS_SERVICE.MENUS}/${menuCd}`); } + + public async menuTemporaryStorage( + menuCd: number, + data: MenuFormData, + ): Promise<void> { + const response = await client.post<void>( + `${ENDPOINT.CMS_SERVICE.MENU_TEMPORARY_STORAGE}/${menuCd}`, + data, + ); + return response.data; + } + + public async getMenuTemporarilyStoredData( + menuCd: number, + ): Promise<MenuTemporarilyStoredData[]> { + const response = await client.get<MenuTemporarilyStoredData[]>( + `${ENDPOINT.CMS_SERVICE.MENU_TEMPORARY_STORAGE}/menu/${menuCd}/user`, + ); + return response.data; + } } export const MenuApi = new MenuApiService(); diff --git a/apps/cs/src/entities/menu/model/menu-interface.ts b/apps/cs/src/entities/menu/model/menu-interface.ts index 285c28b04..b1693f616 100644 --- a/apps/cs/src/entities/menu/model/menu-interface.ts +++ b/apps/cs/src/entities/menu/model/menu-interface.ts @@ -31,6 +31,16 @@ export interface MenuItem { requiredUrlPath: boolean; } +export interface MenuTemporarilyStoredData { + tmprStrgSn: number; + menuCd: number; + menuTmprStrg: string; + regDt: string; + rgtr: string; + mdfcnDt: string; + mdfr: string; +} + export const menuFormSchema = z.object({ siteId: z.string(), menuKornNm: z.string(), @@ -78,4 +88,8 @@ export interface MenuService { data: Omit<MenuFormData, "siteId">, ) => Promise<void>; deleteMenu: (menuCd: number) => Promise<void>; + menuTemporaryStorage: (menuCd: number, data: MenuFormData) => Promise<void>; + getMenuTemporarilyStoredData: ( + menuCd: number, + ) => Promise<MenuTemporarilyStoredData[]>; } diff --git a/apps/cs/src/pages/menu/ui/menu-form.tsx b/apps/cs/src/pages/menu/ui/menu-form.tsx index 1cba9ddf3..f1400a369 100644 --- a/apps/cs/src/pages/menu/ui/menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/menu-form.tsx @@ -1,11 +1,14 @@ import type { UseFormReturn } from "react-hook-form"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { Button } from "@common/components"; -import type { MenuFormData } from "@/entities/menu"; +import { MenuApi, menuFormSchema, type MenuFormData } from "@/entities/menu"; import { ManagementAuthorityDialog } from "@/entities/menu-authority"; import { Form } from "@/shared/ui/form"; import { BaseMenuForm } from "./base-menu-form"; import { TypeMenuForm } from "./type-menu-form"; +import { useAlertStore, useMutationWrapper } from "@/shared/lib"; +import { ENDPOINT } from "@/shared/config"; +import { useQuery } from "@tanstack/react-query"; interface MenuFormProps { form: UseFormReturn<MenuFormData>; @@ -31,6 +34,20 @@ function MenuForm({ const isModifyMode = !!menuCd; const { confirm } = useConfirm(); + const alert = useAlertStore((state) => state.setMessage); + + const { data: menuTemporarilyStoredData } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENU_TEMPORARY_STORAGE, menuCd], + queryFn: () => MenuApi.getMenuTemporarilyStoredData(menuCd!), + enabled: !!menuCd, + }); + + const { mutate: menuTemporaryStorage } = useMutationWrapper({ + mutationFn: () => MenuApi.menuTemporaryStorage(menuCd!, form.getValues()), + onSuccess: () => { + alert("메뉴 임시 저장이 완료되었습니다."); + }, + }); const onSubmit = async (data: MenuFormData) => { if (isModifyMode) { @@ -58,6 +75,22 @@ function MenuForm({ } }; + const handleMenuTemporaryStorage = () => { + if (!menuCd || !menuFormSchema.parse(form.getValues())) return; + menuTemporaryStorage(); + }; + + const handleLoadTemporaryData = () => { + if (!menuTemporarilyStoredData?.[0]?.menuTmprStrg) { + alert("불러올 임시 저장 데이터가 없습니다."); + return; + } + + const storedData = menuTemporarilyStoredData[0].menuTmprStrg; + const parsedData = JSON.parse(storedData); + form.reset(parsedData); + }; + const menuType = form.watch("menuLnkgTypeCd"); const isSubmitDisabled = !form.watch("siteId"); @@ -70,10 +103,20 @@ function MenuForm({ {isModifyMode ? "메뉴 수정" : "메뉴 등록"} </h3> <div className="flex items-center gap-2"> - <Button color="white" disabled={!isModifyMode}> + <Button + color="white" + type="button" + disabled={!isModifyMode} + onClick={handleLoadTemporaryData} + > 불러오기 </Button> - <Button color="gray" disabled={!isModifyMode}> + <Button + color="gray" + type="button" + disabled={!isModifyMode} + onClick={handleMenuTemporaryStorage} + > 임시저장 </Button> <ManagementAuthorityDialog menuCd={menuCd} /> diff --git a/apps/cs/src/shared/config/api.ts b/apps/cs/src/shared/config/api.ts index 3159eb23c..28dac3d20 100644 --- a/apps/cs/src/shared/config/api.ts +++ b/apps/cs/src/shared/config/api.ts @@ -22,7 +22,6 @@ export const ENDPOINT = { LOGINLOG: "/user-service/api/v1/login-logs", APILOG: "/user-service/api/v1/api-logs", PRIVACYLOG: "/user-service//api/v1/prvc-inq-logs", - }, CMS_SERVICE: { SITES: "/cms-service/api/v1/sites", @@ -33,6 +32,7 @@ export const ENDPOINT = { MENUS: "/cms-service/api/v1/menus", MENU_ROLES: "/cms-service/api/v1/menu-roles", MENU_AUTHRTS: "/cms-service/api/v1/menu-authrts", + MENU_TEMPORARY_STORAGE: "/cms-service/api/v1/menu-tmpr-strg", CONTENTS: "/cms-service/api/v1/contents", CONTENTS_DETAILS: "/cms-service/api/v1/contents-details", ORGANIZATIONS: "/cms-service/api/v1/ognzs", From 2642f734320a30a1d4db4e1ebb6064327d3054a2 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 09:54:08 +0900 Subject: [PATCH 020/159] =?UTF-8?q?=EC=9E=AC=EC=9D=B4=EC=9A=A9=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=ED=98=84=ED=99=A9=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=AD=EB=AA=A9=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20=ED=97=A4=EB=93=9C=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=B2=88=ED=98=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 2 +- .../fcltSttn/rainSttn/headList.tsx | 6 +- .../fcltSttn/rswtSttn/headList.tsx | 6 +- .../ui/modal/sttn/headChModal/headChModal.tsx | 141 +++++++++++------- 4 files changed, 92 insertions(+), 63 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 13a71263e..e2d54d6f8 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -173,7 +173,7 @@ export default function PbnstSttn() { <div className="col-span-6"> <ListDiv> <UiTable - headName={[]} + headName={undefined} tableData={bdstTable || []} children={ <HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} /> diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx index 8dd2a4d6f..ad2223473 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx @@ -136,7 +136,7 @@ export const rainSttHeadListExport: z.infer<typeof sttnHeadListType> = [ export const rainSttNodeListExport: CommonTableProps[] = [ { id: "bdnstInfo", - title: "1.건축물정보", + title: "건축물정보", visible: true, row: 1, rowSpan: 1, @@ -144,7 +144,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [ }, { id: "rainFcltInfo", - title: "2.빗물이용시설정보", + title: "빗물이용시설정보", visible: true, row: 1, rowSpan: 1, @@ -152,7 +152,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [ }, { id: "insenInfo", - title: "3.인센티브 정보", + title: "인센티브 정보", visible: true, row: 1, rowSpan: 1, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx index 804617ad8..9989290e7 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx @@ -130,7 +130,7 @@ export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [ export const rswtSttNodeListExport: CommonTableProps[] = [ { id: "bdnstInfo", - title: "1.건축물정보", + title: "건축물정보", visible: true, row: 1, rowSpan: 1, @@ -138,7 +138,7 @@ export const rswtSttNodeListExport: CommonTableProps[] = [ }, { id: "rswtFcltInfo", - title: "2.중수도시설정보", + title: "중수도시설정보", visible: true, row: 1, rowSpan: 1, @@ -146,7 +146,7 @@ export const rswtSttNodeListExport: CommonTableProps[] = [ }, { id: "insenInfo", - title: "3.인센티브 정보", + title: "인센티브 정보", visible: true, row: 1, rowSpan: 1, diff --git a/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx b/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx index 83a5a3523..4b3c8aa75 100644 --- a/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx +++ b/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx @@ -1,5 +1,5 @@ import { useWrStore } from "@/app/store"; -import { sttnHeadListType } from "@/app/store/ruseFcltMng/fcltSttn/rainSttn/headList"; +import { sttnHeadListType } from "@/app/store/ruseFcltMng/fcltSttn/rainSttn/headList"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@common/business_components/ui"; import { Button, Checkbox } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -7,33 +7,54 @@ import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; -export default function HeadChModal({headList, type }:{headList : z.infer<typeof sttnHeadListType> ,type:string }) { - const { rainChSttnHead , rswtChSttnHead, htdflChSttnHead, pbnstChSttnHead} = useWrStore((state) => state); - - - let items = headList.map(item => ({id:item.id, title:item.title, val:item.visible })); - - - const form = useForm<z.infer<typeof sttnHeadListType>>({ - resolver: zodResolver(sttnHeadListType), - defaultValues: [], - }) +export default function HeadChModal({ headList, type }: { headList: z.infer<typeof sttnHeadListType>, type: string }) { + const { rainChSttnHead, rswtChSttnHead, htdflChSttnHead, pbnstChSttnHead } = useWrStore((state) => state); - useEffect(() =>{ - form.reset(headList) + let items = headList.map(item => ({ id: item.id, title: item.title, val: item.visible })); - },[headList]) + /*const form = useForm<z.infer<typeof sttnHeadListType>>({ + resolver: zodResolver(sttnHeadListType), + defaultValues: [], + }) - const onSubmit = (valueList : z.infer<typeof sttnHeadListType> ) =>{ - if(type==='RNB'){ + + useEffect(() =>{ + form.reset(headList) + + + },[headList])*/ + + const form = useForm<z.infer<typeof sttnHeadListType>>({ + resolver: zodResolver(sttnHeadListType), + defaultValues: headList, + }); + + useEffect(() => { + form.reset(headList); + }, [headList, form]); + + const rawValues = form.watch(); + const values: Array<{ visible: boolean }> = Array.isArray(rawValues) + ? rawValues + : Object.values(rawValues); + + const allChecked = values.every((v) => v.visible); + + const toggleAll = (checked: boolean) => { + const newValues = values.map((v) => ({ ...v, visible: checked })); + form.reset(newValues); + }; + + const onSubmit = (valueList: z.infer<typeof sttnHeadListType>) => { + if (type === 'RNB') { rainChSttnHead(valueList) - }else if(type=== 'RST'){ + } else if (type === 'RST') { rswtChSttnHead(valueList) - }else if(type === 'HTB'){ + } else if (type === 'HTB') { htdflChSttnHead(valueList) - }else if(type === 'PBN'){ + } else if (type === 'PBN') { pbnstChSttnHead(valueList) } } @@ -42,42 +63,50 @@ export default function HeadChModal({headList, type }:{headList : z.infer<typeo <> <div> <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8"> - - <div className="mb-4"> - <h3>조회항목 설정</h3> - </div> - {items.map((item,index) => ( - <FormField - key={`${index}.id`} - control={form.control} - name={`${index}.visible`} - render={({ field }) => - { - return ( - <FormItem - key={`${index}.id`+'item'} - className="flex flex-row items-start space-x-3 space-y-0" - > - <FormControl> - <Checkbox - checked={field.value} - onCheckedChange={(checked) => - { - field.onChange(checked); - return; - } - } - /> - </FormControl> - <FormLabel className="text-xl"> - {item.title} - </FormLabel> - </FormItem> - ); - }} - /> - ))} + <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6"> + + <div className="mb-4"> + <h3>조회항목 설정</h3> + </div> + {/* 전체 선택/해제 체크박스 */} + <FormItem className="flex flex-row items-start space-x-3"> + <FormControl> + <Checkbox + checked={allChecked} + onCheckedChange={(checked) => toggleAll(checked as boolean)} + /> + </FormControl> + <FormLabel className="text-xl font-bold">전체</FormLabel> + </FormItem> + {items.map((item, index) => ( + <FormField + key={`${index}.id`} + control={form.control} + name={`${index}.visible`} + render={({ field }) => { + return ( + <FormItem + key={`${index}.id` + 'item'} + className="flex flex-row items-start space-x-3 space-y-0" + > + <FormControl> + <Checkbox + checked={field.value} + onCheckedChange={(checked) => { + field.onChange(checked); + return; + } + } + /> + </FormControl> + <FormLabel className="text-xl"> + {item.title} + </FormLabel> + </FormItem> + ); + }} + /> + ))} <Button type="submit">항목 표출 변경</Button> </form> </Form> From 234f2bc0a7d9a7e760e48e4e85eacea09bafe89b Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Tue, 8 Jul 2025 10:25:54 +0900 Subject: [PATCH 021/159] =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/htdflSttn/headList.tsx | 4 ++-- .../ruseFcltMng/fcltSttn/rainSttn/headList.tsx | 2 +- .../ui/modal/sttn/headChModal/headChModal.tsx | 13 ------------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx index bb58b6ea5..e1a8daec6 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx @@ -125,7 +125,7 @@ export const htdflSttNodeListExport: CommonTableProps[] = [ visible: true, row: 1, rowSpan: 1, - colSpan: 11, + colSpan: 10, }, { @@ -255,7 +255,7 @@ export const htdflSttNodeListExport: CommonTableProps[] = [ { id: "prcsProcsYn", title: "처리공정여부", - upName: "prcsProcs", + upName: "htdflMngInfo", visible: true, row: 2, rowSpan: 2, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx index ad2223473..fd8c2173e 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx @@ -343,7 +343,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [ id: "filtrTrtmfct", title: "여과등 처리시설", visible: true, - upName: "insenInfo", + upName: "rainFcltInfo", row: 2, rowSpan: 1, colSpan: 3, diff --git a/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx b/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx index 4b3c8aa75..2cf90416c 100644 --- a/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx +++ b/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx @@ -13,19 +13,6 @@ export default function HeadChModal({ headList, type }: { headList: z.infer<type let items = headList.map(item => ({ id: item.id, title: item.title, val: item.visible })); - - /*const form = useForm<z.infer<typeof sttnHeadListType>>({ - resolver: zodResolver(sttnHeadListType), - defaultValues: [], - }) - - - useEffect(() =>{ - form.reset(headList) - - - },[headList])*/ - const form = useForm<z.infer<typeof sttnHeadListType>>({ resolver: zodResolver(sttnHeadListType), defaultValues: headList, From 3bba3dce98200f52bfbf8126eb67c2545fb63874 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 10:32:56 +0900 Subject: [PATCH 022/159] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=EB=AA=85=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=AC=EB=95=8C=20=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=EB=90=9C=20=EA=B0=92=EB=A7=8C=20=EA=B0=80=EC=A0=B8=EC=98=A4?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index ee6216b28..c60c3b537 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -123,9 +123,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// useEffect(() => { + const layerId = getSelectedLayers(); if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); - const layerId = getSelectedLayers(); let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? 'a' : null; if (featureCd && featureCd !== fcltPk) { if (layerId == '하수재이용시설') { @@ -157,9 +157,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); setViewMode("detail") } - else if(layerId =='하수처리시설') setViewMode('nothing') + else if(layerId =='하수처리시설') onClose(); } - } else if (seletectedLayerNm) { setViewMode("list") } + } else if (layerId === null && seletectedLayerNm) { setViewMode("list") } }, [featureData]); ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// @@ -179,7 +179,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; const getSelectedLayers = () => { let result = null; - const layers = gisMap ? gisMap.getLayers().getArray() : []; // gisMap이 null인지 확인 후 레이어 가져오기 + const layers = gisMap ? gisMap.getLayers().getArray().filter((l:any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 layers.forEach((layer: any) => { const source = layer.getSource(); From 2abbf857c0fcde937ae54da4ff51d2ce0111fd92 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 11:24:25 +0900 Subject: [PATCH 023/159] =?UTF-8?q?=ED=8C=9D=EC=97=85=20=ED=81=AC=EA=B8=B0?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 22 ++++------------------ apps/wr/app/map/newWindowPortal.tsx | 2 +- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index c60c3b537..43a122f02 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -19,6 +19,7 @@ import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import { getFetch } from "@/components/lib/api"; import { useGisContext } from "@common/business_components/ui/map/Gis"; import ListDiv from "@common/business_components/ui/list_div"; +import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; interface NewWindowPopupProps { featureData: any; @@ -532,12 +533,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (viewMode == 'detail') { // 빗물이용시설 상세 return ( - <> - <div className="flex justify-between items-center mb-4"> - <Title title="빗물이용시설 상세정보" /> - </div> - <RainPrfmncSttnPopup rainForm={rainDetailModal.data as customRainBdst} isModal={false} /> - </> + <SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} /> ); } else { // 빗물이용시설 목록 @@ -572,12 +568,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (viewMode == 'detail') { // 중수도시설 상세 return ( - <> - <div className="flex justify-between items-center mb-4"> - <Title title="중수도시설 상세정보" /> - </div> - <RswtrPrfmncsSttnPopup rswtForm={rswtrDetailModal.data as customRswtBdst} isModal={false} /> - </> + <SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst}/> ); } else { // 중수도시설 목록 @@ -612,12 +603,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (viewMode == 'detail') { // 온배수시설 상세 return ( - <> - <div className="flex justify-between items-center mb-4"> - <Title title="온배수시설 상세정보" /> - </div> - <HtdflPrfmncSttnPopup htdflForm={htdflDetailModal.data as customHtdflBdst} isModal={false} /> - </> + <SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst}/> ); } else { // 온배수시설 목록 diff --git a/apps/wr/app/map/newWindowPortal.tsx b/apps/wr/app/map/newWindowPortal.tsx index 49949e0f4..51c6d5d8f 100644 --- a/apps/wr/app/map/newWindowPortal.tsx +++ b/apps/wr/app/map/newWindowPortal.tsx @@ -48,7 +48,7 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti if (newWindowRef.current && !newWindowRef.current.closed) return; // 1. 새 창을 열고 참조를 저장합니다. - newWindowRef.current = window.open('', title, 'width=1400,height=1024,resizable=yes,scrollbars=yes'); + newWindowRef.current = window.open('', title, 'width=1000,height=800,resizable=yes,scrollbars=yes'); if (newWindowRef.current) { newWindowRef.current.document.title = title; From 66eb77385bee235db4efa20f1588b47cbc9fb3be Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 11:24:28 +0900 Subject: [PATCH 024/159] =?UTF-8?q?=EC=98=A8=EB=B0=B0=EC=88=98=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=20=EC=8B=A0=EA=B7=9C=EB=93=B1=EB=A1=9D=20=EB=B0=9C?= =?UTF-8?q?=EC=A0=84=EC=9C=A0=ED=98=95=20=EC=B6=94=EA=B0=80,=20=EB=B0=9C?= =?UTF-8?q?=EC=A0=84=EC=9C=A0=ED=98=95=20=EC=84=A0=ED=83=9D=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/htdflReg/page.tsx | 8 +- apps/wr/app/store/common/code/basicCode.tsx | 16 + .../ui/form/fcltReg/bdstReg/bdstReg.tsx | 8 +- .../ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 1066 +++++++++-------- 4 files changed, 564 insertions(+), 534 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx index 9b3688e61..d3333f676 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -43,7 +43,7 @@ export default function Home() { useEffect(() => { if (!htdfl.isInit) { - initHtdflReg('41') + initHtdflReg('0') } }, [htdfl.isInit, initHtdflReg]); useEffect(() => { @@ -89,7 +89,7 @@ export default function Home() { // setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding }); // }; useEffect(() => { - getHtdflBdstData(pageNation, "41"); + getHtdflBdstData(pageNation, "0"); }, [pageNation]); return ( @@ -115,9 +115,9 @@ export default function Home() { size={"sm"} onClick={() => { if(searchTxt&&searchTxt.length>0){ - htdflNmSearch(String(41),searchTxt) + htdflNmSearch(String(0),searchTxt) }else{ - initHtdflReg(String(41) ); + initHtdflReg(String(0) ); } }} diff --git a/apps/wr/app/store/common/code/basicCode.tsx b/apps/wr/app/store/common/code/basicCode.tsx index 56c59b502..b80dfb3b2 100644 --- a/apps/wr/app/store/common/code/basicCode.tsx +++ b/apps/wr/app/store/common/code/basicCode.tsx @@ -181,10 +181,26 @@ export const rswtPrscCdMthdCd = [ ]; export const htdPowerMthdCd= [ + { + val: "해당없음", + text: "해당없음", + }, { val: "석탄화력발전", text: "석탄화력발전", }, + { + val: "화력발전", + text: "화력발전", + }, + { + val: "수력발전", + text: "수력발전", + }, + { + val: "태양관발전", + text: "태양관발전", + }, ]; //(공업용수/양식장/농업용수) diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index 31e8dbacb..886dd2da9 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -89,7 +89,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { return ( <> - <h1 className={formH1Class}> { type !== "HTB"?"건축물 기본 정보": '발전소 기본 정보'}</h1> + <h1 className={formH1Class}> { type !== "HTB"?"건축물 기본 정보": '시설 기본 정보'}</h1> <div className="grid grid-cols-6 gap-2 mt-4"> <div className="col-span-3"> <FormField @@ -140,10 +140,10 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { control={form.control} name="bdstNm" render={({ field }) => ( - <FormUi label={ type !== "HTB"?"건축물명": '발전소명'}> + <FormUi label={ type !== "HTB"?"건축물명": '시설명'}> <Input className={selectClass} - placeholder= {type !== "HTB"?"건축물 명 입력하세요":'발전소명 입력하세요' } + placeholder= {type !== "HTB"?"건축물 명 입력하세요":'시설명 입력하세요' } type="text" {...field} /> @@ -156,7 +156,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { control={form.control} name="daddr" render={({ field }) => ( - <FormUi label= { type !== "HTB"?"건축물 주소": '발전소 주소'} > + <FormUi label= { type !== "HTB"?"건축물 주소": '시설 주소'} > <Input className={selectClass} placeholder="위치를 입력해주세요" diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index 83051672d..b81090423 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -6,7 +6,7 @@ import { FormUi, SelectBox, } from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; +import { Button, Input, ScrollArea } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { z } from "zod"; @@ -46,6 +46,9 @@ export default function HtdflRegForm({ }); const [regCtpvCd, regSggcd] = form.watch(["ctpvCd", "sggCd"]); + const bdstNm = form.watch("bdstNm"); + const isPowerPlant = bdstNm?.includes("발전소"); + const onSubmit = (values: z.infer<typeof hdtflZod>) => { if (isModal) { const data = regCtpvCd ? regCtpvCd : regSggcd ? regSggcd : "noCd"; @@ -54,7 +57,7 @@ export default function HtdflRegForm({ toast.error("시도/시군구 코드를 선택해야합니다."); return; } - htdflBdstReg(values,data); + htdflBdstReg(values, data); if (setIsModal) setIsModal(false); } else { @@ -98,7 +101,7 @@ export default function HtdflRegForm({ form.reset(cleanHtdflData(htdflForm)); } // Case 2: 데이터가 없는 순수 신규 등록 모드인 경우 - if(isModal) { + if (isModal) { const firstYnValue = code.yn?.[0]?.val; const firstHtdPowerMthdCd = code.htdPowerMthdCd?.[0]?.val; const firstHtdUtztnUsgCd = code.htdUtztnUsgCd?.[0]?.val; @@ -117,6 +120,16 @@ export default function HtdflRegForm({ } }, [htdflForm, code, form]); + useEffect(() => { + if (!isPowerPlant) { + form.setValue( + "reuseBuilding.0.htdflObj.etgtType", + "해당없음", // 빈 문자열로 초기화 + { shouldDirty: true } // dirty 상태로 남길지 여부는 취사선택 + ); + } + }, [isPowerPlant, form]); + return ( <div className="!mx-[1.6rem] !p-0r"> <Form {...form}> @@ -138,549 +151,550 @@ export default function HtdflRegForm({ )} </div> </div> + <ScrollArea className="h-[37vh]"> + {isModal && htdflForm != undefined ? ( + <BdstReg form={form} type="HTB" /> + ) : ( + <></> + )} + {isModal ? ( + <div className=" my-4"> + <h1 className={formH1Class}>온배수 시설 정보 </h1> + </div> + ) : ( + <></> + )} - {isModal && htdflForm != undefined ? ( - <BdstReg form={form} type="HTB" /> - ) : ( - <></> - )} - {isModal ? ( + <div className="grid grid-cols-6 gap-2 mt-4"> + <div className="col-span-2"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.etgtType" + render={({ field }) => ( + <FormUi label="발전유형"> + <SelectBox + className={""} + label={""} + selectClass={selectClass} + selectArray={code.htdPowerMthdCd} + onSelectValue={readonly ? () => { } : field.onChange} + // value={field.value ?? ""} + value={field.value || code.htdPowerMthdCd[0].val} + readOnly={readonly || !isPowerPlant} + /> + </FormUi> + )} + /> + </div> + + <div className="col-span-2"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.fclCpct" // 이름 이상함. + render={({ field }) => ( + <FormUi label="설비용량(KW)"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-2"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.plwtYn" + render={({ field }) => ( + <FormUi label="담수화 여부"> + <SelectBox + className={""} + label={""} + selectClass={selectClass} + selectArray={code.yn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? ""} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + </div> <div className=" my-4"> - <h1 className={formH1Class}>온배수 시설 정보 </h1> - </div> - ) : ( - <></> - )} - - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.etgtType" - render={({ field }) => ( - <FormUi label="발전유형"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.htdPowerMthdCd} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? ""} - readOnly={readonly} - /> - </FormUi> - )} - /> + <h1 className={formH1Class}>온배수 시설 운영현황</h1> </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.fclCpct" // 이름 이상함. - render={({ field }) => ( - <FormUi label="설비용량(KW)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.plwtYn" - render={({ field }) => ( - <FormUi label="담수화 여부"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.yn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? ""} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> - <div className=" my-4"> - <h1 className={formH1Class}>온배수 시설 운영현황</h1> - </div> - - <div className="grid grid-cols-10 gap-1 mt-4"> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.orgwtWtritSpt" - render={({ field }) => ( - <FormUi label="원수취수 지점"> - <Input - className={selectClass} - placeholder="" - type="text" - value={field.value ?? ''} - onChange={(e) => { - if (!readonly) field.onChange((e.target.value)); - }} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.orgwtOcrnProcs" - render={({ field }) => ( - <FormUi label="원수발생 공정"> - <Input - className={selectClass} - placeholder="" - type="text" - value={field.value ?? ""} - onChange={(e) => { - if (!readonly) field.onChange(e.target.value); - }} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.wtritEntrcTp" - render={({ field }) => ( - <FormUi label="취수구 온도(℃)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.emsnExitTp" - render={({ field }) => ( - <FormUi label="배출구 온도(℃)"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.amtgnr" - render={({ field }) => ( - <FormUi label="발생량(m³/년)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.prcsProcsYn" - render={({ field }) => ( - <FormUi label="처리공정 유무"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.yn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? ""} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.prcsFcltCpct" - render={({ field }) => ( - <FormUi label="처리시설 용량(m³/년)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.fmYn" - render={({ field }) => ( - <FormUi label="유량계유무"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? ""} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.utztnCpct" - render={({ field }) => ( - <FormUi label="이용량(m³/년)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.utztnUsg" - render={({ field }) => ( - <FormUi label="이용용도"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.htdUtztnUsgCd} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? ""} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className=" my-2"> - <h1 className={formH1Class}>수질</h1> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.grssClfg" - render={({ field }) => ( - <FormUi label="총대장균군"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className="grid grid-cols-10 gap-1 mt-4"> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.orgwtWtritSpt" + render={({ field }) => ( + <FormUi label="원수취수 지점"> + <Input + className={selectClass} + placeholder="" + type="text" + value={field.value ?? ''} + onChange={(e) => { + if (!readonly) field.onChange((e.target.value)); + }} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.orgwtOcrnProcs" + render={({ field }) => ( + <FormUi label="원수발생 공정"> + <Input + className={selectClass} + placeholder="" + type="text" + value={field.value ?? ""} + onChange={(e) => { + if (!readonly) field.onChange(e.target.value); + }} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.wtritEntrcTp" + render={({ field }) => ( + <FormUi label="취수구 온도(℃)"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.emsnExitTp" + render={({ field }) => ( + <FormUi label="배출구 온도(℃)"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.amtgnr" + render={({ field }) => ( + <FormUi label="발생량(m³/년)"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.prcsProcsYn" + render={({ field }) => ( + <FormUi label="처리공정 유무"> + <SelectBox + className={""} + label={""} + selectClass={selectClass} + selectArray={code.yn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? ""} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.prcsFcltCpct" + render={({ field }) => ( + <FormUi label="처리시설 용량(m³/년)"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.fmYn" + render={({ field }) => ( + <FormUi label="유량계유무"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.yn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? ""} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.utztnCpct" + render={({ field }) => ( + <FormUi label="이용량(m³/년)"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.utztnUsg" + render={({ field }) => ( + <FormUi label="이용용도"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.htdUtztnUsgCd} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? ""} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> </div> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.tn" - render={({ field }) => ( - <FormUi label="총질소"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.combResdch" - render={({ field }) => ( - <FormUi label="결합잔류염소"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className=" my-2"> + <h1 className={formH1Class}>수질</h1> </div> - <div className="col-span-6 "> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.tph" - render={({ field }) => ( - <FormUi label="총인"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> + <div className="grid grid-cols-12 gap-4"> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.grssClfg" + render={({ field }) => ( + <FormUi label="총대장균군"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.trbt" - render={({ field }) => ( - <FormUi label="탁도"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.tn" + render={({ field }) => ( + <FormUi label="총질소"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> </div> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.ph" - render={({ field }) => ( - <FormUi label="수소이온농도"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> + <div className="grid grid-cols-12 gap-4"> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.combResdch" + render={({ field }) => ( + <FormUi label="결합잔류염소"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.bod" - render={({ field }) => ( - <FormUi label="생물학적 산소요구량"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className="col-span-6 "> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.tph" + render={({ field }) => ( + <FormUi label="총인"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> </div> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.clIonQnt" - render={({ field }) => ( - <FormUi label="염화물"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> + <div className="grid grid-cols-12 gap-4"> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.trbt" + render={({ field }) => ( + <FormUi label="탁도"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.smll" - render={({ field }) => ( - <FormUi label="냄새"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.ph" + render={({ field }) => ( + <FormUi label="수소이온농도"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> </div> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.cdtnv" - render={({ field }) => ( - <FormUi label="전기전도도"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> + <div className="grid grid-cols-12 gap-4"> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.bod" + render={({ field }) => ( + <FormUi label="생물학적 산소요구량"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.crmty" - render={({ field }) => ( - <FormUi label="색도"> - <Input - className={selectClass} - placeholder="10" - type="text" - onChange={(e) => { - if (!readonly) - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.clIonQnt" + render={({ field }) => ( + <FormUi label="염화물"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> </div> - </div> + <div className="grid grid-cols-12 gap-4"> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.smll" + render={({ field }) => ( + <FormUi label="냄새"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.cdtnv" + render={({ field }) => ( + <FormUi label="전기전도도"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + </div> + + <div className="grid grid-cols-12 gap-4"> + <div className="col-span-6"> + <FormField + control={form.control} + name="reuseBuilding.0.htdflObj.crmty" + render={({ field }) => ( + <FormUi label="색도"> + <Input + className={selectClass} + placeholder="10" + type="text" + onChange={(e) => { + if (!readonly) + handleCommaNumberChange(e, field.onChange); + }} + value={formatCommaNumber(field.value)} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + </div> + </ScrollArea> </form> </Form> </div> From ff13d7b50907212fccfb95df3cc36334f85cefe1 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 11:25:53 +0900 Subject: [PATCH 025/159] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=EC=8B=9C=EC=84=A4=20=EC=8B=A0=EA=B7=9C?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EC=A0=80=EC=9E=A5=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltReg/rainReg/index.tsx | 2 +- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 635 +++++++++--------- 2 files changed, 319 insertions(+), 318 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index ce30e3893..294bb517c 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -134,7 +134,7 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state, rain: { ...state.rain, - rainRes: rainRes, + rainRes: rainRes.data, isInit: false, }, })); diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index 0fbffbf59..3178da01f 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -19,7 +19,7 @@ import { FormUi, SelectBox, } from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; +import { Button, Input, ScrollArea } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect } from "react"; import { useForm, type UseFormReturn } from "react-hook-form"; @@ -64,7 +64,7 @@ export default function RswtrRegForm({ }; const filtrTrtmfctCpct = form.watch('reuseBuilding.0.rswtrObj.filtrTrtmfctCpct') - const cleanRswtData = (raw: any): z.infer<typeof rswtZod> => { + const cleanRswtData = (raw: any): z.infer<typeof rswtZod> => { console.log('raw ', raw) return { @@ -82,7 +82,7 @@ export default function RswtrRegForm({ : new Date(), // item?.instlCmptnDt가 유효하지 않으면 현재 날짜로 초기화 operMngCd: item?.operMngCd ?? "", // null → "" instlCstSprtYn: item?.instlCstSprtYn || code.yn[0]?.val, // null → "Y" - grntchBdstCertYn: item?.grntchBdstCertYn|| code.yn[0]?.val, + grntchBdstCertYn: item?.grntchBdstCertYn || code.yn[0]?.val, rswtrObj: { ...item?.rswtrObj, filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn || code.yn[0]?.val, @@ -96,10 +96,10 @@ export default function RswtrRegForm({ // useEffect(() =>{ // console.log(' formform ', form.watch()) // },[form.formState]) - useEffect(() =>{ + useEffect(() => { console.log(' filtrTrtmfctCpct ', filtrTrtmfctCpct) - },[filtrTrtmfctCpct]) - + }, [filtrTrtmfctCpct]) + useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); @@ -119,7 +119,7 @@ export default function RswtrRegForm({ form.setValue("reuseBuilding.0.grntchBdstCertGrd", "확인불가"); } else if (instlCstSprtYn === "D") { form.setValue("reuseBuilding.0.instlCstSprtAmt", -1); - } + } }, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs, form]); @@ -148,334 +148,335 @@ export default function RswtrRegForm({ )} </div> </div> - - {isModal && rswtForm != undefined ? <BdstReg form={form} /> : <></>} - {isModal ? ( - <h1 className="pl-3 text-xl col-span-10 mt-4 "> - 중수도 시설 정보{" "} - </h1> - ) : ( - <></> - )} - <h1 className={formH1Class}>기본정보</h1> - <div className="grid grid-cols-4 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCmptnDt" - render={({ field }) => ( - <FormUi label="설치완료일"> - <DatePicker - mode="single" - field={{ - value: - field.value && !isNaN(new Date(field.value).getTime()) - ? new Date(field.value) - : new Date(), // Provide a default Date value - onChange: (date) => field.onChange(date), - }} - selectClass={"w-full"} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCst" - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 - return ( - <FormUi label="설치비"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - value={ - isUnknown ? "확인불가" : formatCommaNumber(value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); + <ScrollArea className="h-[37vh]"> + {isModal && rswtForm != undefined ? <BdstReg form={form} /> : <></>} + {isModal ? ( + <h1 className="pl-3 text-xl col-span-10 mt-4 "> + 중수도 시설 정보{" "} + </h1> + ) : ( + <></> + )} + <h1 className={formH1Class}>기본정보</h1> + <div className="grid grid-cols-4 gap-2 mt-4"> + <div className="col-span-2"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCmptnDt" + render={({ field }) => ( + <FormUi label="설치완료일"> + <DatePicker + mode="single" + field={{ + value: + field.value && !isNaN(new Date(field.value).getTime()) + ? new Date(field.value) + : new Date(), // Provide a default Date value + onChange: (date) => field.onChange(date), }} + selectClass={"w-full"} readOnly={readonly} /> </FormUi> - ); - }} - /> - </div> - </div> - <div className=" my-4"> - <h1 className={formH1Class}>중수도 시설 정보</h1> - </div> - - <div className="grid grid-cols-12 gap-1 mt-4"> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.filtrTrtmfctCpct" - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 - - return ( - <FormUi label="처리시설 용량"> - <Input - className={selectClass} - placeholder="" - type="text" - value={ - isUnknown ? "확인불가" : formatCommaNumber(value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - - console.log('value') - field.onChange(""); // 초기화 + )} + /> + </div> + <div className="col-span-2"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCst" + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 + return ( + <FormUi label="설치비"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + value={ + isUnknown ? "확인불가" : formatCommaNumber(value) } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); - }} + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} + readOnly={readonly} + /> + </FormUi> + ); + }} + /> + </div> + </div> + <div className=" my-4"> + <h1 className={formH1Class}>중수도 시설 정보</h1> + </div> + + <div className="grid grid-cols-12 gap-1 mt-4"> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rswtrObj.filtrTrtmfctCpct" + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 + + return ( + <FormUi label="처리시설 용량"> + <Input + className={selectClass} + placeholder="" + type="text" + value={ + isUnknown ? "확인불가" : formatCommaNumber(value) + } + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + + console.log('value') + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} + readOnly={readonly} + /> + </FormUi> + ); + }} + /> + </div> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rswtrObj.orgwtKndCd" + render={({ field }) => ( + <FormUi label="원수 종류"> + <SelectBox + className={""} + label={""} + selectClass={selectClass} + selectArray={code.orgwtKndCd} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.orgwtKndCd[0]?.val} readOnly={readonly} /> </FormUi> - ); - }} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.orgwtKndCd" - render={({ field }) => ( - <FormUi label="원수 종류"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.orgwtKndCd} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.orgwtKndCd[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.filtrTrtmfctProcs" - render={({ field }) => ( - <FormUi label="주요처리공정"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.rswtPrscCdMthdCd} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.rswtPrscCdMthdCd[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className=" my-2"> - <h1 className={formH1Class}>인센티브 정보</h1> - </div> - <div> - <h2 className={formH2Class}>설치비 지원</h2> - </div> - <div className="grid grid-cols-2 gap-2 mt-4"> - <div className="col-span-1"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtYn" - render={({ field }) => ( - <FormUi label="설치비 지원여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstIncenYn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.bdstIncenYn[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-1"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtAmt" - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 - return ( - <FormUi label="지원금액(원)"> - <Input - className={selectClass} - placeholder="" - type="text" - readOnly={readonly || isUnknown} - value={ - isUnknown ? "확인불가" : formatCommaNumber(value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); - }} - disabled={instlCstSprtYn === "N"||instlCstSprtYn === "D"} + )} + /> + </div> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rswtrObj.filtrTrtmfctProcs" + render={({ field }) => ( + <FormUi label="주요처리공정"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.rswtPrscCdMthdCd} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.rswtPrscCdMthdCd[0]?.val} + readOnly={readonly} /> </FormUi> - ); - }} - /> + )} + /> + </div> </div> - </div> - <div> - <h2 className={formH2Class}>녹색건축물 인증</h2> - </div> - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYn" - render={({ field }) => ( - <FormUi label="인증여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstIncenYn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value || code.yn[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div className=" my-2"> + <h1 className={formH1Class}>인센티브 정보</h1> </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYr" - render={({ field }) => - { - const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1 - return ( - <FormUi label="인증년도"> - <Input - className={selectClass} - placeholder="2024" - type="" - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - value={ - isUnknown?'확인불가':field.value ?? ""} - onChange={(e) => { - if (readonly) return - if (e.target.value === '확인불가') { - field.onChange('0000'); - }else{ - field.onChange(e.target.value); - } - }} - disabled={grntchBdstCertYn == "N" || grntchBdstCertYn == "D"} - max={4} - /> - </FormUi> - )}} - /> + <div> + <h2 className={formH2Class}>설치비 지원</h2> </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertNo" - render={({ field }) => - { + <div className="grid grid-cols-2 gap-2 mt-4"> + <div className="col-span-1"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCstSprtYn" + render={({ field }) => ( + <FormUi label="설치비 지원여부"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstIncenYn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.bdstIncenYn[0]?.val} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-1"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCstSprtAmt" + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 + return ( + <FormUi label="지원금액(원)"> + <Input + className={selectClass} + placeholder="" + type="text" + readOnly={readonly || isUnknown} + value={ + isUnknown ? "확인불가" : formatCommaNumber(value) + } + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} + disabled={instlCstSprtYn === "N" || instlCstSprtYn === "D"} + /> + </FormUi> + ); + }} + /> + </div> + </div> + + <div> + <h2 className={formH2Class}>녹색건축물 인증</h2> + </div> + <div className="grid grid-cols-6 gap-2 mt-4"> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertYn" + render={({ field }) => ( + <FormUi label="인증여부"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstIncenYn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value || code.yn[0]?.val} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertYr" + render={({ field }) => { const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1 - return ( - <FormUi label="인증번호"> - <Input - className={selectClass} - placeholder="ab1234678" - type="" - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - value={ - isUnknown?'확인불가':field.value ?? ""} - onChange={(e) => { - if (readonly) return - - if (e.target.value === '확인불가') { - field.onChange(''); - }else{ - field.onChange(e.target.value); - } - }} - disabled={grntchBdstCertYn == "N" || grntchBdstCertYn == "D"} - + return ( + <FormUi label="인증년도"> + <Input + className={selectClass} + placeholder="2024" + type="" + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + value={ + isUnknown ? '확인불가' : field.value ?? ""} + onChange={(e) => { + if (readonly) return + if (e.target.value === '확인불가') { + field.onChange('0000'); + } else { + field.onChange(e.target.value); + } + }} + disabled={grntchBdstCertYn == "N" || grntchBdstCertYn == "D"} + max={4} + /> + </FormUi> + ) + }} + /> + </div> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertNo" + render={({ field }) => { + const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1 + return ( + <FormUi label="인증번호"> + <Input + className={selectClass} + placeholder="ab1234678" + type="" + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + value={ + isUnknown ? '확인불가' : field.value ?? ""} + onChange={(e) => { + if (readonly) return + + if (e.target.value === '확인불가') { + field.onChange(''); + } else { + field.onChange(e.target.value); + } + }} + disabled={grntchBdstCertYn == "N" || grntchBdstCertYn == "D"} - /> - </FormUi> - )}} - /> + + /> + </FormUi> + ) + }} + /> + </div> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertGrd" + render={({ field }) => ( + <FormUi label="인증등급"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstGrntchClass} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.bdstGrntchClass[0]?.val} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertGrd" - render={({ field }) => ( - <FormUi label="인증등급"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstGrntchClass} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.bdstGrntchClass[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - </div> + </ScrollArea> </form> </Form> </div> From 75feb78baf2010782e1c656e559b00e52bc1fde3 Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Tue, 8 Jul 2025 11:27:31 +0900 Subject: [PATCH 026/159] =?UTF-8?q?=EB=B9=88=20=EB=A0=88=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/business_components/src/ui/map/lib/gis.core.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/common/business_components/src/ui/map/lib/gis.core.js b/packages/common/business_components/src/ui/map/lib/gis.core.js index b1b02a732..1a6b74c96 100644 --- a/packages/common/business_components/src/ui/map/lib/gis.core.js +++ b/packages/common/business_components/src/ui/map/lib/gis.core.js @@ -561,15 +561,17 @@ GisApp.core.prototype = { */ setLayerOnMap: function (layerIds, visible, addQurryFlter) { for (let i in layerIds) { + let id = layerIds[i]; let layer = this.getLayerById(id); if (layer) { layer.setVisible(visible); } else if (visible) { const layerCode = GisApp.layerCode[id]; + if(!layerCode.lyrTyNm) continue; const queryFlter = layerCode?.flterSql || '' + ' ' + (addQurryFlter || ''); layerCode['flterSql'] = queryFlter; - //layer = this.addWmsLayer(layerCode); + //layer = this.addWmsLayer(layerCode); layer = this.addWfsLayer(layerCode); } } From 221a9331f7e5e445a89a4bebd573b93b33a23f5a Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 14:16:37 +0900 Subject: [PATCH 027/159] =?UTF-8?q?=ED=95=98=EC=88=98/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84=EC=8B=9C=EC=84=A4=20=ED=98=84=ED=99=A9=20=EC=97=91?= =?UTF-8?q?=EC=85=80=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 2 +- .../ruseFcltMng/fcltSttn/rswtSttn/page.tsx | 8 ++++---- .../ruseFcltMng/fcltSttn/rswtSttn/excel.tsx | 8 ++++---- .../ruseFcltMng/fcltSttn/rswtSttn/index.tsx | 7 +++---- apps/wr/public/sample_rswtSttn.xlsx | Bin 10806 -> 10848 bytes 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index e2d54d6f8..baafd8053 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -48,7 +48,7 @@ export default function PbnstSttn() { const [pbnRuseNm, setPbnRuseNm] = useState<string>(""); const excelClick = useCallback(() => { - pbnstSttnSearch(true, "1", "20", ref.current, "", searchYear); + pbnstSttnSearch(true, String(pageNation), "20", ref.current, "", searchYear); }, [pbnstSttnSearch]); const cellCLick = useCallback( diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index ee7a344f8..d101200d7 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -137,11 +137,11 @@ export default function RswtSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - rswtSttnSearch(1, "10000", String(con), fcltNm, code.cityCd, code.sggCd); - }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd]); + rswtSttnSearch(true, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm]); useEffect(() => { - rswtSttnSearch(pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + rswtSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); }, [pageNation]); return ( @@ -188,7 +188,7 @@ export default function RswtSttn() { size={"sm"} onClick={() => { const con = getConValue(); - rswtSttnSearch(pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + rswtSttnSearch(false, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); }} > 조회 diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx index ac57a8016..d24671ee4 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx @@ -15,21 +15,21 @@ export const excelRSwtSttnParsing = ( sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", item.bdstNm ?? "", item.daddr ?? "", - String(item.bdstUsgText ?? ""), + String(item.bdstUsgCd === -1 || item.bdstUsgCd === undefined ? "확인불가" : item.bdstUsgCd ?? ""), //건축물용도 String(item.frstArchPrmsnDt ?? ""), - String(item.archArea ?? ""), + String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]), String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량 String(item.chgBuilding.length > 0 ? "Y" : "N"), //중축・개축・재축여부 String(item.reuseBuilding?.[0]?.lawTrgtYn ?? ""), //법적의무대상여부 String(item.reuseBuilding?.[0]?.rswtrObj.oblgTrgtWtrUsqty ?? ""), //의무대상물사용량 String(item.reuseBuilding?.[0]?.instlCmptnDt ?? ""), //설치완료일시 - String(item.reuseBuilding?.[0]?.instlCst ?? ""), //설치비용 + String(item.reuseBuilding?.[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding?.[0]?.instlCst ?? ""), //설치비용 item.reuseBuilding?.[0]?.rswtrObj?.orgwtKndCd ?? "", //원수종류 String(item.reuseBuilding?.[0]?.rswtrObj.filtrTrtmfctCpct ?? ""), //처리시설용량 String(item.reuseBuilding?.[0]?.rswtrObj?.filtrTrtmfctProcs ?? ""), //주요처리공정 String(item.reuseBuilding?.[0]?.rswtrObj?.filtrTrtmfctUsgCd ?? ""), //이용용도 String(item.reuseBuilding?.[0]?.instlCstSprtYn ?? ""), //설치지원비용여부 - String(item.reuseBuilding?.[0]?.instlCstSprtAmt ?? ""), //설치지원비용 + String(item.reuseBuilding?.[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding?.[0]?.instlCstSprtAmt ?? ""), //설치지원비용 String(item.reuseBuilding?.[0]?.grntchBdstCertYn ?? ""), String(item.reuseBuilding?.[0]?.grntchBdstCertYr ?? ""), String(item.reuseBuilding?.[0]?.grntchBdstCertNo ?? ""), diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index 8fbe2c26d..8f0ac261a 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -31,7 +31,7 @@ type rswtSttnActions = { rswtSttnInit: (page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => void; - rswtSttnSearch: (page: number, total: string, con: string, txt: string, + rswtSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => void; rswtChSttnHead: ( @@ -84,11 +84,10 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( console.log(e) } }, - rswtSttnSearch: async (page: number, total: string, con: string, txt: string, + rswtSttnSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - console.log("헐", page) const rswtSttnRes = await getFetch( fetchType.WR, `/reuseFc/waterreuseFc` + @@ -97,7 +96,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (con ? `/${con}` : "/0") + (txt ? `/${txt}` : "") ); - if (Number(total) > 9000) { + if (isExcel) { const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); set((state: rswtSttnState) => { return { diff --git a/apps/wr/public/sample_rswtSttn.xlsx b/apps/wr/public/sample_rswtSttn.xlsx index f64b37ea34efcb3e8a75dfe170def88a3aeba7cd..d97a79b6de6b52df015f9960225de3d41cd5921a 100644 GIT binary patch delta 3865 zcmY+HXE+;-7RN)x-m9@{6RK(xYEvVvnNlOF_KsN;jn&wSST$pm8nrjIT6<HYReP3F zp&B)B-}l44&pn^c^PK<rbk6fX=hp;Zh1XD#p^A;Mq(=k*z#b3)paB2?0dDvFk>0L0 zNTjQ1fV*2UMiIFvMvKN1UeOTYpQP-A(bhsvOU$Q6L<tP{%$@e^=(eMDjnb}u1{JT* z#bhud26=@P@wnx?KNEFRo?7RMwPC;Ty(N;8ZJfLaSMumw7J+!>eb3S<D!>YQ{;EO+ z-*`a5K?^KCT%?m#*!Oru9$#WJHZwbuTB=j3Uw9kmgpb)5srlLnuo|+<Dml>*FZixK zcwhl8aVCnIK;y|9IJuemPQab6nmglCeJkO{qqolw(QLEaHiE@RrKE2)aKRtu`|EN) zHN5_E@Fsqn$(+n1K{6qqOPD31V;Ch1!-%jMi)JJw9Z99<)>K`L!;g4`l1KmCYdkWz z<(sG_*&Ro*=%4?B8z-GTRwDFhSlQ^CMfh;f;May;_k8KXVl?`68flPIZ$UKb=$sBB z6u2;aQIi$;gyo>NX`=iR$-x^m%L-4p49)*g6FNpeY$obuf8SBTe<B$6;tq<UZMZ@! z%09+*b^#1SJbPs+y->dIZ*;V$M*jT$iE?yLz@SpkuK`-E3qPS@d#7K51Q8b&KRo#c z-cL5NkjL8kwADlfd|+xsQph7l4Fx5ZLx8o&5Y=0p%*|7HkbEL>TeQMdE&uJ_7CX6! zXHQ9Hg=$+>K346&LwH{&NDfh{Q>-#8#lKI^8ECkq!V~}*$zovNGRX-6fHRB`1skdu z-s3T&Li>RiM>DrvrcOhebZ}dk+iL^BY0d9pD`Xb+gLuk9mwpqH3<;-gZsaa}`)*L% zV-FrPxZ-)DcOB*&Pw49oFKb@Pl|`<MXPdci*f$n-)a;Euf2Vg?#T0EbRcKuIy-6=m zF~oOA$q+2-JX9(7d3q?ZZxHQuk&fyIn~G&f<fcNa72%IfL@XX--b1D1Z0ttLOdlmK zo;MA<_>G9v*4g7+G!ge056d3UlxPUaQw{soU57%bT$GVdvMYe<woL_IwzvX{B2@{p zXJ-iG)`GH(9cK|}+?ownZ|m7yD{Dj%wBvBcp}VInU?x39K<Sf*ZacV52lYA9np#mg zYFi3DbvO$i4l`ZjzbUQygt}w~-MC$8^C%;_2WW4JQTAyX+py9kaT4lB*6zv{G-fAU zu;Eq~7YD>nth??eo`3ln&aXE574mfYWeZ6aNxs5*oM2yno*Y@Nfp*fV+pqOiMG@7Z zKSWolq~YM|QE_|zJy!;5JgQjO&tY<}%A6ovD2Iq1H8D}wz9Wbs4T6Q2rkO8inDCY! z(;u4edH)!HK}uOfxyC~w+<(}cZ3PPr@K1mE_VCj9<CIFy0IbBEWhZa3PtebPq~Owv ztTYW0T#C*o@RQ*<zc}IAQ^t@j>{dk$&*Z5LAa$dgns(x>_)0>yNCkX_uPyuU0sdKy zdIhRU5|C9GlR^}RmWdTL=CL6|+j(nOfwV*6ymo5=z11fl6AEh53@cWtZg}|RlToqi zlvz+5;RQKGLo@SkfeI%UIlI)U9+hf0aw^bNpU5B+rG0sEM&*d+8JI!U4rcnm?DRmd zlTh2-QAZl_LirlI7uhXSs(MvooVEgTF_S5qyM3$s)#t6|65c39ehny~=Y;f8TGpwh ztbPgK$3Jf}>8S6PC9#+oq%z3n>x2)q-cA*lJ?d!6el~0vHaU_Kq9P%(GU}M1VJBI+ z8!b_uPD}wcn+}p*Q(LD4mQ!@SVsKn*wl^5FE^iVTa^lexHS#0IR%sh&CAn82n)lc3 z5{PPO)Q{EYDacVhBv)|HG=-Q<AEp8Utn2g#S<8;CS`WfpY~egMzstu%JR%Fw8u5}R zGbu5=kJu~(@zLu+>}}4Q%cJkj`0*9g)irMCsjqRY<Z!xX5sP~R{P#Gd^3CCvi_EMW z@4F{s3-<vlzaEu5*|uimUpr(D1}#B}k3*)x1>Q-q5+*2%?}av#B)mo%$6)i^<0}Vf z1pk)xPmrtA*DpalxM`Z+E0WFdsalhR&0dI+-UGVWjl-kfE_qooX$Ny@^sB&7F<$P0 z)rPb+A_6WZzX&DXGQuSt`8Ru|^pa=F^txeQH0QRlg5kC$vxtOuuZfT(1Bppl;kG6w zCMj`a`P`^dL7|-mpU5@a-5*duv}p&P-H`N;3JXmC_%}VW=!AMm=KPS}rRe0=kWckE zd3z0v4)6K$l7HFv-Gu13@7h1|t^>0+RYjZJyKX8tHi_1Ao$dveU)>a2Z0#|$E#md? zO!5opyp7Ubxoz77JLVkr+y2=~+Qy5_*8z@&f?}vo#<BjD8#9t?9gjAAwf2jkgT|=G z*FK8(mzxg~FLrQ(a+{Fg;#tw^F;5D8Qrr3SwoCQ4w%C2oF&@9O`*D(|F6`XV@4naQ zo|4a>9XGc4-2#QMRTnWWNH1Xja9KJgr`NB2iND*G>&VMv%aC#>;(@={Y1s22rd~(a zDuXUmOxZ^`>xj7IuH0~&l+?3Wzd!s%40*{m-PqR^g_2Auoj@**WnFBpc5zWktiWkj zGyR0eVDH0HQ@7;h4|D#w`P%LT>Du@%WIG|(3+Gm1-^@7|hPs@t)BTmYrBJm+kduXI z=mE1`JHZzZWyB)K*|+BetNwoNG<2TTwH5%>VhC3a0vL8+%Cab1u+v2HhL)5_(Iq)8 zp=DTDZG9J>L3(wvHm{HBs6J3Hg4)L(Pke#{d^(<JIgeIf>h6%eIU93f_AC?E!R3@? zKemmW`?-=Np6giSllq~vs9B9An)LljoYmc29l%uVJk(CNd*%&{wSco4y|Xk@A?Jkh z?RZu?<&sh}MHQ8iP~#`w(GlNnwTife!=9Xn`|@KfLEQ9Rvm-2g(nCfIDVL{hqH2x3 zuDMVfiC9Z4VrQA^>+;AXp4DsSgzde|p_KfA!$P#Wa*JCt+VmOwTuT(q!=z)&m1_E8 z=9de`QoQlUx~6I9y+$k_WSKXTxsTMT7vWe%bq)IWZ0&Zaxj!NT0Aw)(EZnFO?{#_F zrIqqOBpLXK+G7pSL%Q2xe6;l1bute^?=)@QiMzkOkAz9cGz3>Th-ZiDC+fkLv<^zH z_V2{x(g++!mvYP_r4UhXxu0r%Z`$Y-(NeBP2xh3ZQQPFzC0>kq<4y4c$_M(Q%O@PR z(*&=iezqtGN$v#(w%F<<$p)bMjm{>}aePTfkS41<GUm$DLcZVH^?~2{Ra4s@gvBaP zt!6)BtRtYolfmB7(TPy={ZL-fG<#_P>s3yM5#l;0UZU?0sn{^}C11`JR$(H2>mId| znuzCIj40FeMl`*w*~CB?@9(gE0YE3*J}dc*xCUZByI1qdh3U5QE|j1)eg~gF-+r;w zG(O?_N$I5MXCkEu1#`VYopkDuAN<@jr|Zr-5mo@QorPtLFnGXOIkDcdp+^Qkddgv| zy9*yU8s=JhetJdgS?nrvYdp(6JVYe_&rYW1Vs7N1DU~;Yv%wea{!fAtbqFvL2@m2V zlGtqm-S}b)Yi93Lq$;C=b;m8W;u=`7bca4e7^5?kM*D%m(63azfe*eMr0E~cl-oAz z4nn$re+>8b!KzT7W+@R9gTXe|kzp2;@#11V-5kV+;z!n@cOJWcm?<MzEq`3vF0Z&W zYGA&VrA0X^eq;yeGOG#{r9FE`h{z{4XJj|3GB+QLd(~k+Xc2}2cZIR(!XV1mR4_=c zF-$6%mpXo$?l=97?@+fxl5zi}Lr$*51DTD>R4-RaQ9Tyh?64n7wJd`Y{xZPX^JRwy zJv`1DY^sIE8K(Q8zPD^Hz?F3OD+O?n>eteYsSANrAp75C4qcGO3G_NAo}QE6-_W!C zPMb*5hQeM^B&v%sXD_AGd@x%zx-)ed*BH9(goulCofUFzKPV6{w{IIum;I{sxU;MP zD}krls_QrbQc{YG^>*JS?gwXDuTlf?-~h31!wM-t+1Hs$x#hrF*1L8d-1;DILusvu z?v-*`o{D>vTbG&PIh~aST%}!~4U%S_Qh{8a9)O@6C^YDCK#j3xS&m1Jz16{XNRC+T zEQ9J{WN`KJ7f;*v19}<bLB#?C;BE#fii=VA*~XSe*qNkSfvC()^5lR#dkJU2ow?l$ zMk`yHYswiTj%D6o4=jKOrTUP7Z*wfP<R;BH?t;|-HcmS7{$`woTF;G)5;vnIa>GZh z2P1Qh(tya-Z+Aqh>DS@-3nmTSf*(RGmD##@8AUl(t+t{(6c&5j?iJBK=%mtrn<bc5 z-6;tUHeTLw#sO9Dj)vdOCbnUF+saU%kax9u$~79i;P%cGH1Sy@0Q4K-MW(*I=1j7o z9O10@D2_H}<fD2)yR~;d)GSH7Hu|OdQTo2;Bf6f*vYm^>Y%gw2TAgSu-i5cBm5mfU z((md|4M;_;V-;WCAMKPKex~=6vc!$VvW{>3VbF*Ueu#WshktS;;|DCERbEqj_73XU z_XhZnzks;sE|41ay0`fVP?0H5VIRd9`&K|*>O(=<4YRGUnt*AFP}*+>!4yMFCT`P7 z8toxLGs+cdWJ=q4J}CS*SlyPPNzW~?#hkE~mxci#cD@jP!R{_w;h9LdpGjX?&a}Bp z#C$hyzarjs*cCWYGG}c`CUeARFEkI8mn#+OPv=yTU<-^oUayj&PJ!M?1y!=#SO;~J zaZ6$@IF(Qhacd_7XYN<Orr)!smw#X)f!l=}dxW-rWwf9W_=r&p>WDRK{_Ve<#&xJ4 zu~T;lMf|u;%yXpb#CcKKQ9|=Nn@N~H<r~_LS-?)+K}yHDE&w@jy@!lA1wkoqG6HU; z{6T-43{c(hRl5(2rF<HUUS|UUZf<}80~nBq5rBCQB(3k@q9q~wFHd4-1*O>k%MyQ$ znei`O{x8@mFrpO97zKzh;S(y14i!Hp9wJO&j%kJnu>bpE{_VIC005}|*YY=mFk${c zINAT}^?$42{}X&=!Hlx7V)TS)+5R2aU$Qm(%QAHTCqiHXg_H;vxG=+9LYQ?SVFD`* Nl`t<cpWr{L{{S~EK5+m5 delta 3814 zcmY+HXHXML7ls2Nlz@UX5s-jVLJ^2m=^dm5q<2FRq=zOo2I+<(5-tc*r3om#gMebF zDpd%HG$TZ$N|Yw$!~5gTeEaLn?mN3P=j?fRpC!vy%lZopXb-Em(yLSe009U9FarR9 za9^pgfFK{&fB+xKa6jKN?5ICcnniaXbi_=v4-=Y&F=?8QE8X~Ea;X{K{WGybkJClX zGP8QKciRkOudpEaJ<)WHiM)_|yj8|=2>N8?1I~l98urmU+-{QkPC6R>7|RN2uWE0k z1xM1FZjYe%w|7fJlL}hsVgV#ZLj1T#YQ#j$>O)rt>2M2&%80(#M43gUrGEkdvDUtM zg25FXvLXELTXIYev*vwoI0|UlXp@0BpxUBB<L~PxDYHwmVM(=bE?KuF<8KS~cO;p= z&}}8~tRKK#2$jDc2$FWeugj4$L?vSuT%x}7%5$`^gh^7?Xm>WakamtCfEeI72*t4C zPzR2~04q&$dyD=7xi56H5-!$l;@RY-Wp_A;q0=9~#bvv$cl5DIKg-gL0#A_3lS$O= zi_R|d5=1mYtN@<jG39bpEvN@8=+KS1(Sa8}-;|Fx%77BtP|sY_knTX(>7%5?5I9E& zI@b@PIx_i$7`2mxAZ{l7Iws62B#-HS$ad-M$0q(BogP);+{4C~o{9T^$(+*58{uQb z_yzUYLjI7_UTIm3ueql8WGrup524t=od@;pn{IcD|5*32oERJ5rB-*1D#Hf{I_u_$ z2Ijs`aIkt~<9lp^6ne3uh-3a^j&O4TX7^HIOMvVb)%a^)texM3NE!fu9e_23a-vf$ zCooeQ?5NAfNz&WG^WYbm?hu+@4R!uzlKi-_w+IJnonUEikJR;P>Uu1>)!E1@Kr}H* zIpJBn*><)R0t{U<c3<=e`jj8FrJD1-tFEAP7pzdV$qL+jDO83q53G@&lNqOYnr^G= zfPYJvxBQTNOB)#{N|4)Lm=OKVjy}yc1AbPi`)NCMzdZ43O0_?bExjB0JbmS-Pq1le zns94%b7BK|x+SRUmqxI}bN=$Lt;wFnyVuK_lTR8GihR|cDYcl)%Y;pD+)S8D#u+JI zX{fQBRk4_zLBOFk$UUk^s;KRLews65cvqd4EFHRoThLd{@>|(wvKn2Z7n+H5ml!H9 zk00BTr>!&!SCELN(!czrVCO!!7Gd<B4aqsXS-^gm6YMT&t~j?iFk=zHQ}?@f4}?<7 zp8IY}4$F=|r0RKp3?M!GNQj+ufB#zmY@6Tc!lU#jXu)IvT|?pLq~bl=2!U?<T>X3v z!B|AR+zo;37%V&FpqOcVJy`20ievUO@?&4WvpHfLYedH^Sdz`18~L-+svv%fYAhAg zP8yYG0oM-=3-n`8`Ll4U^i5vx!i<W^*v{G<(^AAP^|tjE_-nQtHA%-cfB2>EqyvcJ za0LO8YC25YoIdF7KW6+}{U(nK<8&a#`mz_vSY-}w^xXiWJPR69zs<ihKLK$__p_D! zAxI4l!Ns`uIeX<cJ~l7YoT!?2(dgBBwCM*rl14xfi{6_({pnfmqrq&-RiyZj+7hQ- zf39xB^$Tmye4oO|c|-YNK7q6M+837}b6Kc89yhfKERD-|bWs~HMzWR&4No+^-Cz72 z+~WQX9b}js6hkw1UDnEbCU{;YH<O7h;;N^ZTBhY;t7!rM5-rTYM~=KR@THGJ@J|%g z2PHUXZ)gkl@BWUSG0>6k$D~6`y}j-Wh!{mm2|F67xB^0#+mK%+j$4_;E>`%Y+}2|g z4SHJ5#{UB&Th1^yKnU%UgwJHfY@9$3OV&Z?gr&HLV(lXZIv+YPW^6Bg#^203b}u*Z zQ5O`u&J-8*hStL33IQE)53fDTNRRzUYloWe57fh4DLRcjJM32`7xk(?JlYIX&H9?! zcn@~pn&-wpO)}u93eOI16PzE-Rq^zX%Hs;bSkdfTcs+*pF5RAM^S5YLh-EOX6@HF; z=vS>%x`V~cdS%JqV5v$gl+Qu54kK?D7^kJ1gZFg4mP6wINDYBX-Ch%hbMKVpr(R<p zoL|mG2YL@pXLx<)Vqc|;zrt{fw(>QT2z`wCgu-{3OtJBTGHlhUl`HL;zLu!;mL}Tx zrw;N%b7u|5?|+sym++U&Es!5ZMhuY+hiI84S#0KDp*RyC&~pp~=zjNxjL{m38nKPc zY|9Df!G;;M!oqUQc(A>Og$|+C_yi|RJBZRB@Uuc26-Y{_b5;0L>6IB4)Zq8$q+)?z zpJm%%J99Ad4D#Em16<OD+77?-{geDJcI^q54};vp5{kD}HhhlYd4$%TBxN>LbgTfM zMYs0VqC)yrKdwP#d&mb(KIQ7;?a1(U{Db}z$_~?35WCvAf6lB&dxA)OgAvN<^p=wo zF0|9*sZw+yE;kaE&f-2DVqYE^?-PA!`=v7_u_tY|ilf=bJ#O{Qccql(Z;75Vt<iF0 zdO8EbLN>x_{_lPOH(15X#%63w&}eK0+``K~eYuzdU7r~*6P?*4r^3VaFrYZK+PqJe z21lIqYrm||yXsoOKbEpp``u5&ALw!>7A!RAMpB&7H3y;TNbSn(P4sBcammU7F`J~` z!rObw>C$v|G(!himqSF+@Ay5T>e<xnYf}aH*?83~zHlOz#%#La+vd@+(d{+_R7U+g z9W_yoMWv-Q|Mnw|$<l1QxuKd@HwDurLm!X#Zl4_-le_XDsjFF{BfS|GRCy$vl95}_ zuDFwk`>ukxWbq{I_RsvPn$L*%nKAVYSb-;^W91cOt;H-+=X?hDD!W!N#uqorD<-rw zn`^{fa#u33a-Nc+h`t}v?NT}6omoF|A&Hz;A1be+{-n!!so=z3-1Z0)BxK<T5@qfE zJbHy)ZrB{pdc4vprPVTE<aEnb4C5H%G`Mhqus|8#=MJ2r@Vu7al2zLDz$a^~D+aVB zUUuP~sZZLM$k=sUtOJ*EKEzwdUQgXMwD~9T$D3lo`wQ3NIT>*G-#OXTUN{B*H7ADD zAx7w(^JnQk_U9D=G%@I_A`5D<`h+fLk<RTYj~D`jWDpb((0JDbqjqe#Q70IbTeq0) z%hasmK&cNnKu*tl7x=f>tM_K&4-r~=Dt=uLUvDW%TsTxRZ1dX>g&hZyl*~bEO34u; zge?W^*4U>-bc<R?c#iTw7Le0??m?L0y=jVjyW4Gk9~C#W=yB8XH3s%*%xe*ux3MjD zS?~F(X6w2Ilg$;{G;l@urROH>jcUyM3`SP|I`xWXEWKZJb5(4O-l@ZKXuhI~PUs^t zA3e5W*Z)D}3M~*UBl(T!)?-{2@1E+i@cBMx9*t&Ah&AfDBPUH>c|?fvk2GPH2(@3Q ze^5NNMc?X$?s6)Ulya<_x_KCpg0ECL+<b|U^Mo;SIP}9h(&1+qN|*^R(2_1?lBF5P zZ#hA?-k|8;)i#TaJ>!Dxu<?eMCrvHV1!xB&ES6u*3F8O72h{Z?2wUv!Z>pWNz#+ol zkGjU(>Gc7%K4~|%9u~*Kjdo1w;B4=*?222KEhf>(t8S%Le(_ON;pT*sv<bNQv_~fa zP86yIeiGcElv)HtKv<$}rTv+i@CA00{TdJ;kckO~OnP*Qc7UsWun$Pf7u+ZKK}Ttr z>MSJe^l+;XJQ6t3lwf@0Te(JRMQV**x?}#gr}<HN<WwV6zQ-^%u#PLdzwahpZR(^3 zJ-VD5k#v^A-CPhXC!4{2G1dISUS<kK2=zQL;u9A>wI+CA+{3X*X3KZr<1IILne$y5 zKJMI+`(k63QN||*HDG*l3pCRDN(mwqnQ2kn%PR_PFy%-$^C%LBLR+T5;E_!u-F9e4 zQ~uZfv<In|%fp<Jd4sIb=zg4S?KLO~T?ZPJvUy`S)Tohc#g*Y&BP|*5km$|qbVo`? zb&rcvX@v*|E3G)gVVb#^Z8t>BBLUhiY3X-;T)=&<@V-8`i}|u6t}=tGzbyGHK0jM3 zy5a6EAO&)*eb+6uYC!oF^K_Dodm(d)ze=iF(O|vKidS&2Ef$FS72asDIhr4gu67Ty z><S}1D48ev?RV;(l7z?T;*Z5lpW*W~wUh)F*VhXVkf0pot?s^$v?rX)Y(?)>-AOWB z52|-0OWO2OhTu=k%&Pq=O`-HN19b7R{(jL0(4pCZZF&#~@!*-+cx{>~1L)q|0b@yV z9p;1;T!0(69Ith^{^z9<GaY&KLsMv0dYU>5n8Tg)BwkCvDxa|gD|Y<Y?4{WAGh^s9 z=hDI*<^t>1IFUyfEiO(46{|?51mVganP)i`3nZ_fwd0IUh*9B3c)h9+*H)O@bw}Q7 zMH1_BsK-0T%-GrD4;(hq5Wb!VJKhLs`X8EXDuJN~(2Y;I1W!1pyYYuRrFWNj4RcfI z6D=qb_q(oKHl%q<jh2mt;==u=FRvXIzNXVcQc<?o$S&@Q4biL0^R!O#yk=x-`Da^L zj&SoxFB?gG4quu{P=;z<^!3nF&|i-My^X;vYcwJG1gX%enWOOjzsO^7to;q;DuM!7 zXBx(IzF=j2t+62ym8bVU{T|Qcsp_XvftM1tky`~aVR~>IeLK)ygs)u<6Yi2G71TM! zoZ||?Z+7_x_?4SseYJH)37c*6NL`(It!Ui^mFM<xfkOB`Y*x9W=l7-j3ND9-fMMTn zS4UF*5H1?59#65`%ACFh_b~_<VFmcr0_-mLlb`$~uCA3k$Vpg5iC=`8f-1iNf?I~e zIE^tP347rjP5z|qZYj+#MYLo0=7T%&s!TddapP)xb`b@tD*m%jQ-enO;hV-o*%Dqi zONZy9l=p1VJg=mNTn^M9D`b6Gi-rjlQbk~-)U;18{LKh<P?V)~kDrd=KS0EuiOBN& zKPH^>;(vn`3x{e_-N0r*&8VcX%TQsFfB%!`zI`SP09^P__cu6U{}(iaLn3_d1!G-A z*m?f*_;VrG|7q*7PNL#G|JLUmPwc1xfJ^_ku7E8SRim!u$Nu6M#WIPBQORNz#IDmG JogWGS{0|&y9pnH2 From f93ca3d71f5190655f932299632e6df9f7a63d40 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 14:17:29 +0900 Subject: [PATCH 028/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=EC=8B=9C=EC=84=A4=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=EC=83=81=EC=84=B8=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=EB=AA=85=20=ED=91=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 5 ++++- apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx | 3 +++ apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index b81090423..edd5bb1b5 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -120,7 +120,7 @@ export default function HtdflRegForm({ } }, [htdflForm, code, form]); - useEffect(() => { + useEffect(() => { if (!isPowerPlant) { form.setValue( "reuseBuilding.0.htdflObj.etgtType", @@ -136,6 +136,9 @@ export default function HtdflRegForm({ <form onSubmit={form.handleSubmit(onSubmit)}> {/* <div className="flex justify-between items-center mx-3"> */} <div> + <h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1"> + {readonly && `(${htdflForm.bdstNm})`} + </h1> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> 온배수 시설 등록 diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index bc3a6a74d..da8011efd 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -143,6 +143,9 @@ export default function RainRegForm({ <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)}> <div> + <h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1"> + {readonly && `(${rainForm.bdstNm})`} + </h1> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> {isModal ? "건축물 정보" : "빗물이용시설 정보"} diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index 3178da01f..3c8af831d 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -133,6 +133,9 @@ export default function RswtrRegForm({ <form onSubmit={form.handleSubmit(onSubmit)}> {/* <div className="flex justify-between items-center mx-3"> */} <div> + <h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1"> + {readonly && `(${rswtForm.bdstNm})`} + </h1> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> 건축물 운영정보 From c1d1c2e27e502cd898d5244b5ebe11a234514800 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Tue, 8 Jul 2025 14:42:39 +0900 Subject: [PATCH 029/159] =?UTF-8?q?=EA=B2=B0=ED=95=A8=EB=8C=80=EC=A4=91=20?= =?UTF-8?q?=EC=A4=91=20=EB=93=B1=EB=A1=9D=20=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EB=B0=8F=20=EC=88=98=EC=9A=94?= =?UTF-8?q?=EC=B2=98=EA=B4=80=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/coSttn/page.tsx | 49 +++++++------ .../app/ruseFcltMng/fcltReg/htdflReg/page.tsx | 42 ++++------- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 2 +- .../app/ruseFcltMng/fcltReg/rainReg/page.tsx | 12 ++- .../app/ruseFcltMng/fcltReg/rswtReg/page.tsx | 44 ++++++----- apps/wr/app/store/matDmd/coSttn/excel.tsx | 11 +-- apps/wr/app/store/matDmd/coSttn/index.tsx | 7 +- .../prfmncReg/chkgdnReg/rainChkgdn/excel.tsx | 69 +++++++++++++++++- .../ruseFcltMng/fcltReg/htdflReg/index.tsx | 38 +++++----- .../ruseFcltMng/fcltReg/rainReg/index.tsx | 23 +++--- .../ruseFcltMng/fcltReg/rswtReg/index.tsx | 29 +++++--- apps/wr/components/lib/api/index.ts | 3 + .../ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx | 20 ++++- apps/wr/public/sample_coSttn.xlsx | Bin 8550 -> 8186 bytes 14 files changed, 226 insertions(+), 123 deletions(-) diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index e828f4226..163ed1b40 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -2,6 +2,7 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; +import { excelCoSttnParsing } from "@/app/store/matDmd/coSttn/excel"; import { fetchType, getFetch } from "@/components/lib/api"; import { excelDownload, @@ -42,7 +43,6 @@ export default function CoSttn() { updateDemandCompany, coSttnTxtSearch, demandCompList, - dmdIsSucees } = useWrStore((state) => state); const [bdstTable, setBdstTable] = useState<DemandCompType[]>(); @@ -116,31 +116,36 @@ export default function CoSttn() { coSttn.excelList, "수요처 관리", "sample_coSttn.xlsx", - "A1:F1", + "A1:G1", 2 ); } }, [coSttn.excelList]); - useEffect(() => { - const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city ? objSearch.city : "0"; - if(con){ - coSttnSearch(String(pageNation), "13", String(con)); - } - }, [coSttnSearch, objSearch.city, objSearch.sgg, pageNation]); + const excelClick = useCallback(() => { - const con = objSearch.sgg ? objSearch.sgg : objSearch.city; - if (con) coSttnSearch("1", "10000", String(con)); - }, [coSttnSearch, objSearch.city, objSearch.sgg]); + // const con = objSearch.sgg ? objSearch.sgg : objSearch.city; + // if (con) coSttnSearch("1", "10000", String(con)); + if(bdstTable){ + const excelData = excelCoSttnParsing(bdstTable); + excelDownload( + excelData as [], + "수요처 관리", + "sample_coSttn.xlsx", + "A1:F1", + 2 + ); + } + // }, [coSttnSearch, objSearch.city, objSearch.sgg]); +}, [excelDownload, bdstTable]); const searchClick = () => { const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; if (con) { if (seartchTxt && seartchTxt?.length > 0) { - console.log(' seartchTxt ', seartchTxt) coSttnTxtSearch("1", "13", String(con), seartchTxt ?? ""); } else { coSttnSearch("1", "13", String(con)); @@ -233,7 +238,7 @@ export default function CoSttn() { headName={[]} tableData={bdstTable || []} headlist={coSttn.coSttHeadList} - pageSize={bdstTable?.length ? Math.ceil(bdstTable.length / 13) : 0} + pageSize={20} total={ coSttnResCount || 0 } cellClick={(index: number | undefined, headId: string) => { setUpdateData(coSttnRes[index as number]); @@ -258,22 +263,24 @@ export default function CoSttn() { getDemandCompList(searchText, pageCnt); }} rtnInputData={ async(data) => { + const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; + if(upadateData?.dmdInfoPk){ - updateDemandCompany(data as DemandCompType) + + await updateDemandCompany(data as DemandCompType) + coSttnInit("1", "13", String(con)); + setIsDmdModal({ isMoal: false, data: data as DemandCompType }); }else{ const dmd= await getFetch(fetchType.WR,`/reuseFc/request/${data.dmdInfoPk}`) if(dmd) { toast.error(`사업자번호 ${dmd.dmdInfoPk}는 이미 등록되었습니다. 다시등록해주세요`) return } - regDemandCompany(data as DemandCompType); - } - if(dmdIsSucees ==='success'){ - toast.success(`수요처 등록 및 수정 완료되었습니다..`) - setIsDmdModal({ isMoal: false, data: data as DemandCompType }); - }else{ - toast.error(`수요처 등록 및 수정 에러입니다.`) + await regDemandCompany(data as DemandCompType); + coSttnInit("1", "13", String(con)); + setIsDmdModal({ isMoal: false, data: data as DemandCompType }); } + }} bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"} diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx index d3333f676..873ad85f3 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -24,9 +24,8 @@ import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal import { Toaster } from "react-hot-toast"; export default function Home() { - const { code, htdfl, initHtdflReg, getHtdflBdstData ,htdflNmSearch} = useWrStore( - (state) => state - ); + const { code, htdfl, initHtdflReg, getHtdflBdstData, htdflNmSearch } = + useWrStore((state) => state); const [searchTxt, setSearchTxt] = useState(""); const [pageNation, setPageNation] = useState(1); @@ -43,26 +42,26 @@ export default function Home() { useEffect(() => { if (!htdfl.isInit) { - initHtdflReg('0') + initHtdflReg("0"); } }, [htdfl.isInit, initHtdflReg]); useEffect(() => { - if (htdflRes&&htdflRes.length>0) { - - console.log('htdflRes ', htdflRes) + if (htdflRes && htdflRes.length > 0) { const htdflData = tableData(htdflRes, { code }).map( (item: customHtdflBdst) => { - let archArea = item?.archArea.split('.')[0]!=='-1'?item?.archArea.split('.')[0]:'확인불가' + let archArea = + item?.archArea.split(".")[0] !== "-1" + ? item?.archArea.split(".")[0] + : "확인불가"; return { ...item, - archArea:archArea - + archArea: archArea, }; } ); setbdstTable(htdflData); - }else{ + } else { setbdstTable([]); } }, [code, htdflRes]); @@ -114,11 +113,10 @@ export default function Home() { <Button size={"sm"} onClick={() => { - if(searchTxt&&searchTxt.length>0){ - htdflNmSearch(String(0),searchTxt) - }else{ - initHtdflReg(String(0) ); - + if (searchTxt && searchTxt.length > 0) { + htdflNmSearch(String(0), searchTxt); + } else { + initHtdflReg(String(0)); } }} > @@ -175,17 +173,7 @@ export default function Home() { }} /> -<Toaster position="top-center" /> -{/* <UiModal - bodyClass={""} - open={bdstChgProps.isOpen} - body={ - <BdstChgModal chgBuilding={bdstChgProps.chgBuilding}></BdstChgModal> - } - onOpenChange={(open) => { - setBdstChgProps({ ...bdstChgProps, isOpen: open }); - }} - /> */} + <Toaster position="top-center" /> </ContentsDiv> </> ); diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index ab8df5d8f..6a9189876 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -357,7 +357,7 @@ export default function PublicReuseFaciltyInsert() { headlist={pubFacHeadList} pageSize={10} total={100000} - headName={"공공 하수처리시설 등록"} + headName={"공공 하수처리시설 목록"} cellClick={cellClick} onPageChange={setPageNation} children={undefined} diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index 8ecc1221f..6c97f6c8c 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -29,7 +29,7 @@ export default function Home() { return state; } ); - const { rainRes } = rain; + const { rainRes,rainResCount } = rain; const [rainForm, setRainForm] = useState<customRainBdst>(); const [issNewReg, setIsNewReg] = useState<boolean>(false); const [pageNation, setPageNation] = useState(1); @@ -48,7 +48,10 @@ export default function Home() { }, [rain.isInit, initRain]); useEffect(() => { - if (code.sggCd.length > 0) { + if (code.sggCd.length > 0) { + + if(rainRes&& rainRes.length>0){ + const rainData = tableData(rainRes, { code }).map( (item: customRainBdst) => { let archArea = item?.archArea.split('.')[0]!=='-1'?item?.archArea.split('.')[0]:'확인불가' @@ -62,6 +65,9 @@ export default function Home() { ); setbdstTable(rainData); + }else{ + setbdstTable([]); + } } }, [code, rainRes]); const cellClick: (val: number | undefined, headId: string) => void = ( @@ -139,7 +145,7 @@ export default function Home() { tableData={bdstTable || []} headlist={rain.upHeadList} pageSize={20} - total={10000} + total={rainResCount} headName={"건축물 목록"} cellClick={(val, headId) => { cellClick(val, headId); diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx index 94224d40d..b2ff99104 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx @@ -36,30 +36,36 @@ export default function Home() { isOpen: boolean; chgBuilding: chgBuilding[]; }>({ isOpen: false, chgBuilding: [] }); - const { rswtRes } = rswt; + const { rswtRes, rswtResCount } = rswt; useEffect(() => { if (!rswt.isInit) { initRswt("41"); } }, [rswt.isInit, initRswt]); useEffect(() => { - if (code.sggCd.length > 0 && rswtRes?.length > 0) { - const rswtData = tableData(rswtRes, { code })?.map( - (item: customRswtBdst) => { - let archArea = - item?.archArea.split(".")[0] !== "-1" - ? item?.archArea.split(".")[0] - : "확인불가"; - return { - ...item, - archArea: archArea, - bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N", - bdstUsgCd: item.reuseBuilding[0]?.bdstUsgCd, - }; - } - ); - setbdstTable(rswtData); - setRswtForm(rswtRes[selectVal ?? 0]); + if (code.sggCd.length > 0) { + + if( rswtRes?.length > 0){ + const rswtData = tableData(rswtRes, { code })?.map( + (item: customRswtBdst) => { + let archArea = + item?.archArea.split(".")[0] !== "-1" + ? item?.archArea.split(".")[0] + : "확인불가"; + return { + ...item, + archArea: archArea, + bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N", + bdstUsgCd: item.reuseBuilding[0]?.bdstUsgCd, + }; + } + ); + setbdstTable(rswtData); + setRswtForm(rswtRes[selectVal ?? 0]); + }else{ + setbdstTable([]); + setRswtForm({} as customRswtBdst); + } } }, [code, rswtRes, selectVal]); const cellClick: (val: number | undefined, headId: string) => void = ( @@ -137,7 +143,7 @@ export default function Home() { tableData={bdstTable || []} headlist={rswt.upHeadList} pageSize={20} - total={10000} + total={rswtResCount} headName={"건축물 목록"} cellClick={cellClick} onPageChange={setPageNation} diff --git a/apps/wr/app/store/matDmd/coSttn/excel.tsx b/apps/wr/app/store/matDmd/coSttn/excel.tsx index 39d669664..05b45711a 100644 --- a/apps/wr/app/store/matDmd/coSttn/excel.tsx +++ b/apps/wr/app/store/matDmd/coSttn/excel.tsx @@ -1,16 +1,17 @@ -import type { customCoSttnBdst } from "."; +import moment from "moment"; -export const excelCoSttnParsing = (data: customCoSttnBdst[]): string[][] => { +export const excelCoSttnParsing = (data: any[]): string[][] => { const excelExportData: string[][] = []; data.forEach((item) => { excelExportData.push([ - String(item.ctpvCd), - String(item.sggCd), + String(item.cityText)??'', + String(item.sggText)??'', item.dmdCoNm ?? "", item.daddr ?? "", String(item.dmdInfoPk ?? ""), - item.telno ?? "" + item.telno ?? "", + moment(item.regDt).format("YYYY-MM-DD") ?? "" ]); }); return excelExportData; diff --git a/apps/wr/app/store/matDmd/coSttn/index.tsx b/apps/wr/app/store/matDmd/coSttn/index.tsx index 5e8baf859..4c9a7fcce 100644 --- a/apps/wr/app/store/matDmd/coSttn/index.tsx +++ b/apps/wr/app/store/matDmd/coSttn/index.tsx @@ -53,6 +53,8 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( `/reuseFc/request/${pageNo}/${pageCnt}/${con}` ); + console.log('coSttnRes ', coSttnRes) + set((state: coSttnState) => { return { ...state, @@ -104,7 +106,7 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( }, coSttnTxtSearch: async (pageNo:string, pageCnt:string, con: string, txt: string) => { try { - const coSttnRes = await getFetch( + const coSttnRes = await getFetchWithCount( fetchType.WR, `/reuseFc/request/${pageNo}/${pageCnt}/${con}/${txt}`) set((state: coSttnState) => { @@ -112,7 +114,8 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( ...state, coSttn: { ...state.coSttn, - coSttnRes: coSttnRes, + coSttnRes: coSttnRes.data, + coSttnResCount: coSttnRes.count, isInit: false, }}}) } catch (erTxt) { diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx index 58e8d6bf0..53b43e0f3 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx @@ -85,7 +85,11 @@ export const buildingToExcelType = ( }; export const excelToRainChkData = (excelData: any, year: string) => { + const errors: string[] = []; const rainChkgdData: rainChkZodType[] = excelData.map((item: any) => { + + + console.log('item ', item) if (item["점검일"] !== undefined) { const checkYmd = item["점검일"].replace(/\./g, "") let vltnDt = item["과태료 부과일(위반일)"] @@ -108,7 +112,7 @@ export const excelToRainChkData = (excelData: any, year: string) => { }); return { - + bdstNm:item["시설명"] ?? "", bdstRuseFcltFk: Number(item["NO"]), chckYmd: checkYmd, spwtPositn: item["유량측정방법"] ?? "", @@ -133,5 +137,66 @@ export const excelToRainChkData = (excelData: any, year: string) => { }; } }).filter((el: any) => el !== undefined); - return rainChkgdData; + + // ✨ 오류 검사 - 가공된 데이터 기준 + const isInvalidNumber = (val: any) => + val !== undefined && val !== null && val !== "" && isNaN(Number(val)); + + const isInvalidDate = (val: any) => + typeof val === "string" && !/^\d{4}\.\d{2}\.\d{2}$/.test(val.trim()); + + const buildErrorMessage = (item: any, issues: string[]): string => { + const 시설명 = item.bdstNm ?? ""; + const 점검일 = item.chckYmd ?? ""; + const 이용용도 = item.utztnUsgCd ?? ""; + return `시설명: ${시설명}, 점검일: ${점검일}, 이용용도: ${이용용도} (=> ${issues.join(", ")})`; + }; + + if (rainChkgdData.length > 0) { + rainChkgdData.forEach((rain: any) => { + const item = rain.__origin; // 원본 item + const issues: string[] = []; + + if (rain.chckYmd && isInvalidDate(rain.chckYmd)) { + issues.push(`점검일: 날짜 형식 아님 (${rain.chckYmd})`); + } + + if (rain.vltnDt && isInvalidDate(rain.vltnDt)) { + issues.push(`과태료 부과일(위반일): 날짜 형식 아님 (${rain.vltnDt})`); + } + + // [ + // "연간운영비(원/년)", "PH", "탁도", "총대장균군수", "과태료부과금액(천원)" + // ].forEach((key) => { + // if (isInvalidNumber(item[key])) { + // issues.push(`${key}: 숫자 형식 아님 (${item[key]})`); + // } + // } + + // ); + + for (let i = 1; i <= 12; i++) { + const month = `${i}월`; + if (isInvalidNumber(item[`대체_${month}`])) { + issues.push(`대체_${month}: 숫자 형식 아님 (${item[`대체_${month}`]})`); + } + if (isInvalidNumber(item[`빗물_${month}`])) { + issues.push(`빗물_${month}: 숫자 형식 아님 (${item[`빗물_${month}`]})`); + } + } + + if (issues.length > 0) { + errors.push(buildErrorMessage(item, issues)); + } + }); + } + + if (errors.length > 0) { + return { rainChkgdData: [], errors }; + } + + return { rainChkgdData, errors: [] }; }; + + + diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx index 317f68e10..feaefc03f 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx @@ -1,4 +1,4 @@ -import { getFetch, postFectch, putFectch } from "@/components/lib/api"; +import { getFetch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api"; import { upHeadList, type chgBuilding } from "../rainReg"; import { z } from "zod"; @@ -96,6 +96,7 @@ export type htdflFacState = { isInit: boolean; upHeadList: TableUpperProps[]; htdflRes: customHtdflBdst[]; + htdflResCount:number }; }; type htdflFacSActions = { @@ -114,19 +115,18 @@ export const htdflFacStateExport: htdflFacState = { isInit: false, upHeadList: htdTableHeadList, htdflRes: htdflRes, + htdflResCount:1, }, }; const initFetch = async (code: string) => { - - console.log(' initFetch code ', code) - let url = `/drain/facilityList/1/20` + let url = `/drain/facilityList/1/10` url+=`/${code}` - const rswtRes = await getFetch("wr", url); + const rswtRes = await getFetchWithCount("wr", url); return rswtRes; }; export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( @@ -135,15 +135,16 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( return { getHtdflBdstData: async (pageNation: number, code: string | number) => { try { - const rswtRes = await getFetch( + const htdflRes = await getFetchWithCount( "wr", - `/drain/facilityList/${pageNation}/20/${code}` + `/drain/facilityList/${pageNation}/10/${code}` ); return set((state: htdflFacState) => ({ ...state, htdfl: { ...state.htdfl, - htdflRes: rswtRes, + htdflRes: htdflRes.data, + htdflResCount:htdflRes.count, isInit: false, }, })); @@ -159,7 +160,8 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( ...state, htdfl: { ...state.htdfl, - htdflRes: htdflRes, + htdflRes: htdflRes.data, + htdflResCount:htdflRes.count, isInit: false, }, }; @@ -170,24 +172,21 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( }, htdflBdstUpdate: async (data: customHtdflBdst, code: string | number) => { try { - - const chData = await makeMdfr(data); const res = await putFectch("/drain/facility", chData); - if (res.status) { toast.success("온배수 건축물 수정이 완료되었습니다."); } - const htdflRes = await getFetch( "wr", - `/drain/facilityList/1/20/${code}` + `/drain/facilityList/1/10/${code}` ); set((state: htdflFacState) => ({ ...state, htdfl: { ...state.htdfl, - htdflRes: htdflRes, + htdflRes: htdflRes.data, + htdflResCount:htdflRes.count, isInit: false, }, })); @@ -210,7 +209,8 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( ...state, htdfl: { ...state.htdfl, - htdflRes: htdflRes, + htdflRes: htdflRes.data, + htdflResCount:htdflRes.count, isInit: false, }, })); @@ -220,14 +220,14 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( } },htdflNmSearch :async(code:string | number, fcltNm:string) =>{ try { - - const htdflRes = await getFetch("wr", `/drain/facilityList/1/20/${code}/${fcltNm}`); + const htdflRes = await getFetchWithCount("wr", `/drain/facilityList/1/10/${code}/${fcltNm}`); set((state: htdflFacState) => { return { ...state, htdfl: { ...state.htdfl, - htdflRes: htdflRes, + htdflRes: htdflRes.data, + htdflResCount:htdflRes.count, isInit: false, }, }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index 294bb517c..67ea71cb6 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -1,6 +1,6 @@ import type { TableUpperProps } from "@/app/store/common/type/header"; import { getFetch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api"; -import { z } from "zod"; +import { number, z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; import toast from "react-hot-toast"; import { baseReuseBuildingSchema, chgBuildingSchema, validationMessages } from "./type"; @@ -74,6 +74,7 @@ export type rainFacState = { isInit: boolean; upHeadList: TableUpperProps[]; rainRes: customRainBdst[]; + rainResCount:number; }; }; type rainFacSActions = { @@ -90,6 +91,7 @@ export const rainFacStateExport: rainFacState = { rain: { isInit: false, rainRes: rainRes, + rainResCount:1, upHeadList: upHeadList, }, }; @@ -97,7 +99,6 @@ export const rainFacStateExport: rainFacState = { const initFetch = async (code:string|number) => { // const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/1/10/${code}`); const rainRes =await getFetchWithCount("wr", `/reuseFc/rainyInfoList/1/10/${code}`); - console.log("데이터", rainRes) return rainRes; }; export const rainFacActionsExport: (set: any) => rainFacSActions = ( @@ -106,15 +107,15 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( return { getRainData: async(pageNation:number, code:string|number) =>{ try{ - const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/${pageNation}/10/${code}`); - - + const rainRes =await getFetchWithCount("wr", `/reuseFc/rainyInfoList/${pageNation}/10/${code}`); + // 여기서 상태 업데이트 return set((state: rainFacState) => ({ ...state, rain: { ...state.rain, - rainRes: rainRes, + rainRes: rainRes.data, + rainResCount:rainRes.count, isInit: false, }, })); @@ -135,6 +136,7 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( rain: { ...state.rain, rainRes: rainRes.data, + rainResCount:rainRes.count, isInit: false, }, })); @@ -152,7 +154,8 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( return { rain: { ...state.rain, - rainRes: rainRes, + rainRes: rainRes.data, + rainResCount:rainRes.count, isInit: false, }, }; @@ -194,7 +197,8 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state, rain: { ...state.rain, - rainRes: rainRes, + rainRes: rainRes.data, + rainResCount:rainRes.count, isInit: false, }, })); @@ -217,7 +221,8 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state, rain: { ...state.rain, - rainRes: rainRes, + rainRes: rainRes.data, + rainResCount:rainRes.count, isInit: false, }, })); diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx index d39412d8d..475c1797d 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx @@ -1,4 +1,4 @@ -import { getFetch, postFectch, putFectch } from "@/components/lib/api"; +import { getFetch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api"; import { upHeadList, type chgBuilding } from "../rainReg"; import type { TableUpperProps } from "@/app/store/common/type/header"; @@ -57,6 +57,7 @@ export type rswtFacState = { isInit: boolean; upHeadList: TableUpperProps[]; rswtRes: customRswtBdst[]; + rswtResCount:number; }; }; type rswtFacSActions = { @@ -78,11 +79,12 @@ export const rswtFacStateExport: rswtFacState = { isInit: false, upHeadList: upHeadList, rswtRes: rswtRes, + rswtResCount:1, }, }; const initFetch = async (code: string | number) => { - const rswtRes = await getFetch("wr", `/reuseFc/waterreuseFc/1/10/${code}`); + const rswtRes = await getFetchWithCount("wr", `/reuseFc/waterreuseFc/1/10/${code}`); return rswtRes; }; export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( @@ -95,9 +97,9 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( code: string | number ) => { try { - const rswtRes = await getFetch( + const rswtRes = await getFetchWithCount( "wr", - `/reuseFc/waterreuseFc/${pageNation}/20/${code}` + + `/reuseFc/waterreuseFc/${pageNation}/10/${code}` + (txt ? `/${txt}` : "") ); set((state: rswtFacState) => { @@ -105,7 +107,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state, rswt: { ...state.rswt, - rswtRes: rswtRes, + rswtRes: rswtRes.data, + rswtResCount:rswtRes.count, isInit: false, }, }; @@ -116,7 +119,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( }, getRswtBdstData: async (pageNation: number, code: string | number) => { try { - const rswtRes = await getFetch( + const rswtRes = await getFetchWithCount( "wr", `/reuseFc/waterreuseFc/${pageNation}/10/${code}` ); @@ -126,7 +129,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state, rswt: { ...state.rswt, - rswtRes: rswtRes, + rswtRes: rswtRes.data, + rswtResCount:rswtRes.count, isInit: false, }, })); @@ -141,7 +145,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state, rswt: { ...state.rswt, - rswtRes: rswtRes, + rswtRes: rswtRes.data, + rswtResCount:rswtRes.count, isInit: false, }, })); @@ -160,7 +165,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state, rswt: { ...state.rswt, - rswtRes: rswtRes, + rswtRes: rswtRes.data, + rswtResCount:rswtRes.count, isInit: false, }, })); @@ -198,12 +204,13 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( }else{ toast.error("건축물 등록이 완료되었습니다."); } - const rainRes = await initFetch(code); + const rswtRes = await initFetch(code); set((state: rswtFacState) => ({ ...state, rain: { ...state.rswt, - rswtRes: rswtRes, + rswtRes: rswtRes.data, + rswtResCount:rswtRes.count, isInit: false, }, })); diff --git a/apps/wr/components/lib/api/index.ts b/apps/wr/components/lib/api/index.ts index 452788eb0..cee42b905 100644 --- a/apps/wr/components/lib/api/index.ts +++ b/apps/wr/components/lib/api/index.ts @@ -66,11 +66,14 @@ export const getFetchWithCount = async (type: string, url: string) => { if (!response.ok) { console.log(`오류 발생: ${response.status}`); } + const contentType = response.headers.get("content-type") ?? ""; if (contentType.includes("application/json")) { // JSON 응답 처리 const res = await response.json(); + + return res; } else { // 파일 응답 처리 (ex. PDF, Excel 등) diff --git a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx index 5aa67fd3a..a7b66d811 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx @@ -16,7 +16,6 @@ import { SelectBox, Title, } from "@common/business_components/ui"; -import { Card } from "@common/business_components/ui/chart/lib/card"; import { Button, Input } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; @@ -72,13 +71,25 @@ export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setI if (file) if (type === "RNB") { filePicked(file, 0).then((res) => { - if (res !== undefined) - setExcelData(excelToRainChkData(res, form.getValues("chckYr"))); + if (res !== undefined){ + + const excelData = excelToRainChkData(res, form.getValues("chckYr")) + + if( excelData&&excelData.errors.length>0){ + + excelData.errors.forEach((err) =>{ + toast.error(err) + }) + }else{ + + setExcelData(excelData.rainChkgdData) + } + } + }); } else if (type === "RST") { filePickedArray(file, 0).then((res) => { if (res && res?.length > 1) { - const excelArray = []; const guideData = excelToRswtGuideData( res[0], form.getValues("chckYr") @@ -154,6 +165,7 @@ export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setI return; } else { + rainChkExcelDataUPload(excelData as rainChkZodType[]); setIsRegExcel(false) } diff --git a/apps/wr/public/sample_coSttn.xlsx b/apps/wr/public/sample_coSttn.xlsx index 836ee002eb3d159176d8c8ef6c00ee06fc168bff..222813c49c5aef4501b23702d7e7de58b1db9826 100644 GIT binary patch literal 8186 zcmaKR1yoyIw{37KG@)pLB0&npt+>0pyE}nEaWC#(q_`KS#f!UJvEo*|xJxhnzW=@6 za^HO!Bj;qF>^aBITzjmwGnaxi96S~P5r7O}bllc5m&)#42LJ$kumHfb$Gbk%)W(s4 z{`WO9u3fH^5iRIY;;V4N?XH~!a&~@`OuVzO1&^=f!doj$aY@9@0~Fk>2|V8K5BIm9 zHxKNfxvsg%v>p^Qs&oi$!#y{0{U0U`&q-W{4~8#N#D+xU-3j8TWcjG)wg`z};(qoU ze&UE>NKDG@)ajTN6yP-wuPom42x;XtVL8PT&o$vm<))S+_DgbgoY#`|m^K&Z)5n8h zH9ZL$dehZ`^EqE-pUF8Pk+n2aiVG%40o#Upg?Yk^b7FbVKQ{uA#s7!Ij9&|udg%0E z=mY<R&aq>rWq?amC(Y>*I^1V=3qBZyzqHUQ;Bl#f0RYP3007XV7A6p51t`Sck-^a3 zp5E2gCSAGRZk`dX892+2*U0YdZ-@swCmNfxZ72%YWjmTGGcRN-8KaTAI1?Qgqhjgt zJu><*)E!Liea$7`4Ld@UYhA0SS_+_(Ej&~B9DMO(4Y$dr#b@2aoR&jn<r!DD*RYsK z6P+}JcygdVMp@`iWE#Q?Ct=GQJ<0mFC#Hyzn+2b|la9i&xVP!|i%F!h>z+M8#z*>A zM)_+YI6T%@i8b+Yuse#wOEMkQ`U~Rh-G=Z2dOyNQd}Qb>rqfhaRb%-JuI#YnB*;aD zWrCQ0NUpk83UwgKCT)ESh3msDJfg!IAZ?}CvQxU5Q}*H&m^m{#X&W4c|5fJHNQnT$ ze~UDqYVBvw<C3xA!8De_#-J=P8`_S-E!O&SO}^(HQwr=7K9+Kc8FI!lOl#A;?10!N z(*_bX<?J|B6#WwB9gfKCr)Gt3;w>xAFrhuzdiQ~;wi?IcuE=nub3$;K_?9t(NdghC z_r}@EIzqXGbvl@aOx;So1JvV_{2dJ?D1jm$o5I<zZZmHD^^<kC%yNTG*gmV1*xtO3 zKJIp!557UtV%)YMmb2xiurMf$p16biJG>QG&@;}*@V<Q9>KOk$yv7iy>F@a3#x_50 zc&tDd@+H!fj9JM<RLx=<m|YPHaxK4E+O67}kXM6mWt)x>htO<zU?B)VzxbrFoT!<t zkB1NScn}rrvUV=bJq#&KfAClieZF4QnCIJ2hOy-IOzaK?MeX{U8kjwbdMfyu+>VH` z0S{p&XCs8LCUOoZ5N?g?LhuBA)#_R(1B`h9S{3Z5^iNJZzp9;3i)dQWXx7o%T|j=D zf*<U`E4g^AUv9h_n{tR;n{CB;%lI6Yblr0Miv+Jdj3-$oS+;wSPYbUM-5qDj@TCuU zW?(_qhsK6<^DNbZe!#&TEESEFmRg&iZ8%pe+30Eu*OnaDLPBm0rur3-WnzZ$%Uko_ z>q11WIy}`|5iGO(reW{=+xDq*8-ES4Y97kY<PDa%3EDz(ADbp(IE|SfS1xnFzjaQ# z&HbqGsI$hS&cH{VU2Pa#AW&-~2*mog%8`nKk1B({k{u%rx}@e&A$;OW1d+J=NhMtD z_oVfFG8V6$Pgwr!oG`J(QD$z=(!`Q7EFTFLuav_dws<Q=4Wo-sdLA`?I5odWmX2G; z{&{5fema@A-R%IctQk@$xi)~0|5L00AyUTFrju8wNm|F+@0mK>l^Df3YdSglhtvyH z<y&HOW!35cTxBBsu@>B_tomMST{>;?a7_yAQV+O*x&tJL?|8oAf|NL4F5ntfT_LCb zv_i-o6d?yneO``#F~&!nCxr7Z{@Lo<zK<n}k}y6-pvLqIu1j`o5>DGZoC4!BZ~x+l zj~M>+%mmb)!`mD_eW%%%&!OrbcbJ+F0kV4TZUNZK%&9?XLEVNh9pO_<7CfYCImW2t z&SH}LbYnOz2P$iw^ddNCU>21-EddI)5D++L13yV8ahoH7Dk=Ju_R|^s2yhF#^>6W0 z+V*~KJc_>hC_etb;{Th{|9c4jN$+KGqgIdUz31?K%lmOJhlxlgv2?wGteJ8Tz&e$K zg%N@DUS?fIzkw`i@N+1WXWadcxn#+C!(kT&S<MnPRW%_z*Luk`8*0mC=ICK1J+6Go zE9cb7SJk#8u|%9o1}UAv2`01`sm#P<`7#H_6`cLEeObeT>{K7z9w^sm;Rd+ntIDvt zY*l?{^<nwe4)z+^>W_aEiuYntZ1nfSX^O}daJ}tAeGnoKmWicU>jL)@e-zUm3GFF1 zb?wB@BOLJoH4jOOc<#j5NwnS^Uwj=wHGbE%8*co)lWCHJC(@Z+;!VZh+61)IwbCI0 z0F=Z40Or5iI9Zt5nlk)zW%|824>YyI=f$wR8P52To4NPG$>*g%8Vov5n6aZ&#mDtl z@zhdsPvBX8CBTHG$Q~1-#+sP;Ahdj<AO(lcdX~>`Mw%^qOYCme6DQVU!9GVvLD5uc zoyocU5i;_T)0`fcVHsHD5R#i*S!t?9pCAhtOhgcG|D72Eyv+}?>>>;_7SRmR{sG%t z;BY+=OpJ#+PJij(i@r@7;i5Qr#+iBWbH9ryMA6f4*dEyy69*xrbH<{PC29=gjBqU7 zs$qX0J|v(3BL~3M!ju9668QLBZ0;3irhSN8^1zY_;K6~77K0mS9}&#^d6flbT@&4( z=;ILiV(OpG#ErjpyTD2n#>x6+sQM13PcDa+pMEs~vLm{e&EPZbt|8Qmq}orG8l?nI zGS!yz2vtCr&Q<zw@=l^+$<cj;%cMA*2k4noznio#_j$5r#xS+zroP>%ZmCSQRxrQC ze|oxSrndX=ZP7P%1#9&0hfR#6^I1yzf(L9xrc)*5HRx~7vA=1)pB_9YS6xO-yy2r* zZO5;);bwDrAFp(PlB>=RPOF`&P@j=C10eUYwgj%CJiD&70FLqEoC^w4DRoI&9Cf3~ z#~?lH7fpx&8|}vy1GD*sNy7zo%9Cz4@$ax(lkUEpW$X)_1;kEAu7$-~9Ie$L%9l$B zPJ}dv47m>8;mM?=t_|WcL=p4yd!OwculM#wd+WW3%Vx0eCsDpr#gcn>w^ykD>-@g3 zC$shL=%$}NY~(HBM&1xih4;<c6r?q?hp_(j`{uigxst6>J@3mYVtzjA%IT;viC}a| zU*mNyK4!Zr0HFdSA5YlQbIvo2e$rTAEvn3UeI}faK8aS|a=Y8iawv%#4ovyb;bsr> zQ7-3egoyHM!RM8ucn6h5V}>*ENVY*ir}kPhZ&LSe>OfqyYa2O?xE#&bXrG=@Gq2uo zut%g}1ro|Sgfx(TpM~i`(5si0u+zH;#jQ$~t#|l<_eum+mxDZ4r_F4ogxvR97Yid8 zG;j_56*X@7rH@<JGg-XtMC6Nsy|9eq&sP5*gb1RPK~z~c0SBZ%anX$`LwIysaUDal zs0)U+BOM5F4Iv^c#B|B!f~mC63%weVPeMZC--8J}LYQ8Sn<AA*`)gvD2?*);dSVf` zO$hYJ_JkYU(zY6PyClnFW#EaqAddu&?_kc_7Ey6c(E>yVdESIX(j;$A4;u)+M&7EX zz-rUceJ0^*6st`Qx$x0gLPhjx2`rmcu(MjO&Z{9)svoN;$EuD$`xU%d68>XV7LCTm zqrpeN8QRo&Iko3?E>(B4rQR$z!28R4cwhiag%RUq_Zww2d;2umLVyC-%CoRbBexe} z*{;#IBv>47@BJsA1*8CpRSP7wO_uuo3NYec;bE+2f_?%$S>HQma+K#RT7Lb)5*hh2 ze3gT$+tOusfSd_Fc)+c4v`0#-I7AxLRKK4>yo)8WI^C*EiJo;uV?Y%s$7_ot)UCU; z(bl$6SIi?vxgi392r00%MjFtWR)!kzTJvEG?!-Ep&C;68f+(j5u^0o8Wz6ww>kw_C zv<qxuu-YnbK;6b{msu#N1DAtsu@2A-!91R3G;qCx1Y*pv0R51`X_AG>=VSy$Wwdn> zATm-BGQTKj6WL0!C6WZB!Q6-3!-v0a5|QGMm5H|v!51H<m0(4@k;3BBfewjfJCw3l zJGXm2>t;cW>kFVki3)OW%*}TA#+;stZn%@JIry=S4$BkG43t^L@tuS#@R?<Fco)*k z<Dne~obIpTM*6ae`|=3N6C^|M0qcEP<Q6F%@}aNuHQd8G;`|cH=F~sMOfMPU$V#Lg z5_!eeL$d>3W9~cf*0Y8t)19kM^8+9^l<g_I12Zh(ar!i274*B~Sf-rQZ5)44-5&Pp z9aHG)+Ls(NBbgOHu<W$vT?Lj?RimNc_T>Y!N+RKSN_3Jc`(VA&r=-RUK<r5z9YU1k zVu6PnEA~9LF7!gwJ(cJzQj}%hrRWoK)cEJ@S(j21VLa)^Jw>8%<-rEKoG;%KWxK^P zB+FiGOx(vO)udT#dYFdSW;>UopG973;QtzW5PL9krST4mHAz%VD9h7TO;>$Lc^}u| z4Et*`K`zoS{$-3(L(rMRoB{_sGhkJ-Rs*1~%R!P#j)d?s_C!<F=gK74BWA7fsEws? zjT#G70+z73TxG_(n1pMnl8c{iRQW_74F_QUfnk{f9B`h8megv$Vc*y5|D?I8)M+;( zWjkN4>h7GsaG*jgw7cr9P&G9OA+~ebF}i-B*|dhV2}0Yw+Kt<v$3wnyLp@K>>y;MI z5P7g5Uke0D<oWDB-J6xoIY<p_HR)G3ri&HtaHT8FIP5KY&(shMKL}59Bn+rE{m_!D zP=vlI*RK9powaO{w5wM0y>|CNY}6{83GhBqP$JWxCGJ<~E%}u6FTmf`6?@DjqzV}T z@RS1p(EqKjj!teirjEbs>Xgo+^}HIE5AnVaD2TVV)`UAWcs<S)W8W0*d%MAYJ8>8p zrL>q@;}?1B8MN<Zl|t3EWG@%Dx3z9!*fe*9Z-Lz>zbYLo_<lCjmeO!X(e{FF2l$p- z9Y>~`XUg^F_wXlVhkx!RHDttB;6UTdYD;VFoTnZ27ZoZ>H_NB^9*VxZ*uDII{z}%7 zJd5#mui;hij#ujFr8c)#-FU0jIV<MUT<yMHr(gDB|D{Lmw8bTg;!Gb+V24!8{MfKg znbl9{sq)DWTGQn_rCX@>)Q9>ds&#bn&G~&tL=8$M7Z7Q70z@jwnjyFkV(O>#=z2WR zXrGu7`AqcZ&mCWU6`wj;KG-cVoh+dnthDKeiDX+5X4vHYvGj|Q0(}E3lpP+*6Xjgk zkfA&Udrx3aV9}D~Yxr>umZ|CE#py}h7Tk#J2Qn%!k>5H!A#~YMFN6|FqQxS>(*nC! zl(k_cfgvOy4;m-H@!Uaja|p!-!#j-~KFmr{R~MsuE9c_Mm8>JoN~+^q<kToC#@qlI zL@ufL46;z|7EJRhm(nG`Z5~cmAqsWk>!!-?SUA{#&xey{Q@W-XC<|Zyt~_T1Wv1kf zn}N>c$V{+gh#lT)M7{=i@<sjQ@5YbHohv|v>-X_mR|EdQEikn*F?!DjAd8j|_+CX& zXOb^t;<W2D!n|~ocE`;@Y92FNht|wXUs0|3p-!!sTWn*sVdQQDgJ$=fb#rPjQ7Y^N z3!7-Cf1WB{-2G&iM%&7ZhS$wEY07ES)>dtztx*3$in=~76zb&8?)<Jsskqb)`x5%u zTgU08h&m2gV{-MBWnTWF0jQ>E7Cdg*ixVoxUAr_yleht+7#>FVBHh_0cKeHQT8~rT zsP<oztar};eqbqcdjA#S4{FX>8WOYW++;atJDY@Di)>O2T+uC2MYkomfIC@=FLQD3 z>+^9gB|_W&Rj|pShAXy>U^u`Mw>{nCJ~EfBjk(~@*HSDt5f{gp7^g(i93MAivrr&J z^kv0Ry{EsMyg#B73nj9X+|R+bdAw=}k+yDQd=LO^KUJw0aIS5Evv=?iUh+~$CM3sf zM(aWxbp#zUoZ5WbJ1;|LV5P3lDycbNv<m?GgM%jA5Hm^S<A?d_JCEG8JJ34G`vpR% zU-*OKWr+Pa!jCfqgu<C5nZu8Fb%esJV&>@Vw3}q#(|SM^d%lv{;9y2-(-nkPYRj-T zZz{yaNHQ8Vc92xP_|&LIb)}u<s0w}&ZnKJTQHM#@@57hktw3$@42jkv$RVAO<jS4f zW;-9%*94+{QhU!2iB|@^m<t5zb+|YFnpj^)x0(vdb{Q%+<Jy?@&#mi=^~FJBgM{<9 z*70`K!8e5&^(f`eu-Mtc4;6ErO;FbONA?Tx<NNj4oaNhcY7J(aQ}<;D6~7DA&NNlT zHuD(Fu|heq(sT+GEqNSM&`MTq2c$Dqw9Fp7Wz)_t4E>R;FJYRzMwd1q;;}rqVy}i{ z_=3OKy;#Sq(X-;k75z()0ky-N3Z*T0V9+-#RKR!ivq+;SNt=*-URaE?reds9B^3i~ z(C2cniofKWo>6sr{v+m3N+27xe3DVhosa%%Ca5b&1Z#s|{8hBF)D#-XYP3o#6xfkO zlPgFHakon((FrD8<J7DMMCCKSJxC~-h)I4s0^HMnW#Y1nT7b`wsVwS+`C0vm!phON zv(ze->y@C9*px^lT+;0aL20Vxm*@Er!Xt~cCNzUpsS7rw%2q}u(9gj`R{iG(GM4?M zES>jAWGqeS$YhwTBNl8zT5pcHa<z<1Ixa_&gogK>NeEB(-;$J?I^P0=haNx4{rwF0 z<oCB`7(8j?&jXC~hV0-vw9M*$*^`di!GTY+4N&aW4D_a%)rlYr9`jcgNct(3aQffp zGu&Qh)(`NL`X)JYB6pk%_|~obxJIO(+^m!Jc}0Vld+!Zxi#eD%)Ts3)Fj<{MSl>c# zsUv76_)hc@00`P3N8t1nXh!rF+9JAA24<^MoIFF^<IFz_brR*`=XCnT<KXj^I2E7| zNJwpJgej~H8O*Y~9@^1F?cz%XUUfSL3hgql3AZ%$3DIo8HLM>~$I%LTP8Y1hP10ln zEgK``LjjhkUTri)#MNcd*QGMONR(83#7m>5v6<5GYoY}_L-a)}$Ig*QDC?pGSdUCd z_*<D6e6)HdLg802nC!|&hR5JZU=PyBq)c~kceu%$wa;9yh;bPHp-`vn4(~No4Cwrg z;CUVnCX9NVzviIvV%0tX7>=8HNTJvg{rk~rGx@;f?^$0n2f_T}Dndm43S(;+cu-{H zyd%6IrKA|R@aNG>Impe~&uQs-?6N&6zWIp;41p97L*ED&!G$9nO1h&mlv93ey%z9R z-8yf|(m0vT={+&tkw0v3k%u)(5%&iRb*%ivyd2?&Ve=%^t_T4$y1FsCVk?~jd~IV~ zw}5gFuf8^K5e1%kGKcW+bMO*8oaq;F%A*-X;Qn0l;B&3vU+~%HbLH~{-4HQ@xU*<s ztD1hjXZ3X7CJH7r$#@Umu>W;`G_GjSBax2zQqZ!M+LIvWbPQ8f^76R<IxW7vLi|NC zMkPtSdjcS==u1QN=)&>{V&P%l>MG{tmCe=B{YrQGYWfU}Fi}jKmpG)3?L=7vyywkt z59Eip+5SW+Eps!8?qIq4P{r?h;UXYg8(F0awrL!VLafjW`sS$!FoU&M+_g`Vtoxq4 zTg^zHz(ZTgoS6`_Dw!9os``Tk?kFXIhqjnGn%Xzm_pTyyaa|vFbX-)=tP#w5e}EB% zuRpTGkl5W#xZ8fTBS@9@tO2=~h;D#_hzVRM{Jd$jlYH$M3_BmtwHg^*%}ni(EWHv% zHR>&1e!>6u*(O>3y!q_$OymD(YhnH8Y-3>vH8oLof?C>{|8vCoTvgFGtVktI_hw{h z^s_4SHx>mYiDBsx`Tim4I#pD3hshd+>bmvKYHE6VMZlY3np)KXDr)M=i5UjD5s6`0 z+UY?CiD9^byiMFq$|OL8=*~?yf@pClb@$8SVu}XN8!<#gvzvy{6gMf<{_A`<idv~8 zDb#$ol)(Jr5yqBuS%-pj+0ezbpPUu9+BRp>`!;8SVEb`(ZT7F<8xeKa4oWlFWv%rp ztVBP!*0}AZxk)e6E}a&XAvG<O(4kj+D06ErUO$L<wf$y^*20b35%oD|sTr*9v6=hh zT+B*qcV4&ky+Ft1p+z_qze*Wmydvi(CqSIZ<Z`D+bs`?$WdEx4+jVlZFg0~@Wcb&H z`e*Qu)$)%Cr5Yjq9F`P>a7nr3ceZ5N6Uc;^oQ{;d4TD@OK**OJdVE#=&2)2$rp9xE za_JjKQmJ7EIr2a`kI@DG&$_);wD7sZZ&GOoovR?4aEF0X(lb4VkbPK+LFM9v-V<87 zIlfA_(&^^X*E~{g9T)R}+#?37mcK(Q%~*3t`)HOSApih)|6|dAmYc3JA2rDc@)BPo zrfrRvu9$z*Z)K?|0E?nXKWfKiSt@H|EI%JuVZNWIo6}O67A!+ZoZ0Y7-uZU+?LP9f zWEnI=48=T4syW^&^Yn1}=kmhQ{MvcRe%`_R5}25Am`$i2S*j^vQ+1G9y##^67iG(N z)V%z~-VqH@lYNoxnqu70nwms6cToO4@pIir@3Mv-NJq6VLCXqDt)niz?izbQesF!2 z68L7zW#`0eKvT!0{Tzt$`f`+AxN1=Vj-n&##g8HL+Nqm%IR1%>04iO8tCV66PX}r$ z<yOY@J*u2L@VHwvme(tDaWUA)v&sf3k%RS0HIvVGVMfB+e4O=I9{I~R^z>|YYl?S< zU79pR?|J)QO~Vt5@62{8qh|APd^;HR4rcLc6MJ(7FP=rh5b<iJehcjJBUSwKxPOMz zg-p5RsA%mLzO3E=+d)HLM#IDhs3K9ep2;XDea^VkNd)0~IYM^2wO>wODIZf@5u^b_ z?`Q`)l5)7{igB%`a9Ctc<hUgWBh{oA+Y9brBa_V8$ADB|?0~8o#Ug@2&e@FKihOMn z8ww7&weE5XLB=Qk0d*AYQc3tc*7PPti$*{*u8*c{Y?&D9*NVQOvy-THZ-K(hZUoE> zT$J9_fWyY73H_0$KED`h=l4C}7kNaP*ozxC)k#K}PtGqQcVzO}_{z4cJx<V9+8N2v zW+U%}Nolv8H6-K7&>}t(*p8!yl775mo(y|p$<pNo2KhWDj_k)B_S<&U7KYe4nc6w& ztGL;lI_m!ZdsL<}X!rin6Ib8mCn?9^*vbC%h9sCT$~Lcncx8=3<BDS5?cNI)SrMPj zkE#I>bUswcvSiX23)b*^r&GfEv1^?XkZ9dA1x9b(IviK#82)(}cRlU<tWu+amA09E zG@$+~yrga^I@O($1x;~pzAi}kG>qPtC!#l+d}iSNNo)mE2d!J6KYbu@>Fre`MJ<UA z-q$aIZ0h(*#_*%X;)W*qvl!A}j6)pEmDi>07LZLzVCI<aq*XtBG{Xn96&0F;9>za~ z`){>5wIs|2Ygi!~eQP7Mx)&j!H3tn9ofE4V0sF*2(Xv4oT%n`khlO@+jr8vVG$(jp zDRQ@Buar~1>wz^bhd)y4qT4n=x3(=IE-TS4DVpkvgR;q>q_Thh&e5T2xRa`t?6*7K zrApBqc$9oY^vydyn@=50!$g5eW7N=xkt<hTTW_tRiUHyPSXj6g-Z%7Wzng)vs9u+F zY<d9Q4X+dVB<Fa6pth^flEy04L%uzrC8gcPGX-gw#|-elH$@+V26znMe_sEsMfw!@ zw1fB?@h=eV@%FTz_!RxLLG=f{_qe?Oi~c|Ds;BU$eV0FQW%&Qmg?S2o+Bf(E9(&xj zk1d@4rHk;C=c&j3hi4!0AD*X<`%{9aHo_kQsptO?{4o`tLZ4RYKTt~Cf1yun_EUzZ z73>d#%wui%Pb2I9SI?djKCLc)2w`46CHzxsp0Yg6Ab(hl3I3n?L_r$iQSILy{bzvj M$GwC3>i6is0NHzt-T(jq literal 8550 zcmeHMg<DkH`W^(NWf%s8p^<J78M?crq#LD&?mkL40@5AQAl;>OOM`$&cgRS|Z#?JT zd(QFr`wQ+}`+4@-GkbsEv-eu>yS{I|pQ-{f3K(!7fDQlvr~syi8J31f06;7X0Duob zzo#bwvv;wucQMlNbg*zXVDqrErOZXS$B+%Uhj{*f?Z0>g%3cpC_izBE;IcOoUs&ar zYDCeW90c`&n4SuE_9lENG1JSmvbxI*y9SEq5LiR2L1RnaTqh%zHTHJ(L7^X7)UYE0 z`#UuaNuccS`}S!&9umhp>FOM1gGod=iH(e+o~HrcI5zaCaZ9d=$(KPa2?&J))-x9R zwD49wG+~$M7W4HlcC9LFeZu1%d^-hPpTPfUZN=zqc(%?ehY~^Uy+r6{SfEO!t<Gqw z*5q`RtkCYv(D-=T*zDdXj^Nm~2g{=?_gmVb<VxI-nz!NSCAuGCZJ0ZJ^nJWK7@{N2 zRj-<P2rP|Q^)f{Rse&fw0ID_-wS?td_G7-iA_RGgL&x2e%h$AP_@uonB<9VTF|p># zMAUXHs|9_Tk}7;qrXatf{((l`PL%^QQXl)m3A8ULQs3^t7kE3(XPx4}flewK-;jgV z{v84D{qYUG-wscbcKo@%-v<Eh?vMehf1_ocCdZ?51lAN0tiwXk(#Xle)|s8{$N7JB z{4eI<Up~DoUP+~g13UOg_9mnsKD`_Z6jyK;lWn2W@C%Sz!mW$Sqaj)DpeF@tKz>7( z@o)3H8C+ZzjN0v|y7<gp76AeaJgRpu4^F;vbVXyLb4rqSEL-cvbDRD;eUTy~@5$iS z7Q<B9Se&CUu<}TH>O`^{IL7u2f`MN^8cZmZ5~%w@N#~R4w+f_barJ}p;Hm~__HM#h zn*VH4;SP>SD4*i~WC}sQv+0ZZ3ZH&ks;`$2O?68?t18n>Cw^*ABXir%Gs(0L{97MZ z<@A0vYHrXst}&TD+U&3Xy0zRVLm8gEP>i0^{^Nn52#VrQhzRvhk^~CBPCi47NHc;Y z5CA%ohb{XbJaLCP*_gs$Hb0`*zd3`12w?~>|J|)jO-Z4b1K5W3J%qzO&5ZzW-i4id zUvm!^eV~?ck&f!I-}wp&Q?r5gi~>6{EZFmCq|Xih<iTfT{I6Zi#o-_nFMQi00aVz? z*$6Va=|MSpkPIq5Xn%LF^Z@HYsxy9*aC|>YCYX2g8v`wINM0ee<ayI%Ft_z6hbx!0 z^ElZc0y9IkUjnXPs_&Nv)iyLxrZPU?xNDMFyttng<Vi7cMvNgRh~o*E*#1bx{H;ss z0{yi0=DCvRs7+Vi74`;csRDV)6Cs~q7s`-+847>Kc;}7WlorjSH5c*gLB@{7Q<kCg zqvu}+`leS9GyPA<<N`jtXGOpz1d;CGBA!4%=C5EW(-?}L;s7r{I>AkXTahanJx!Q6 z4=jE;Zn-^d+w4eIRJ}Xb<z~s;+u@u6WN>+m&eQHkzT!Mux8=SipUtjFQeht6BNl*{ zps}G(u69%FyQRd*mDHb(POB5nKD^qpe~@-5x3g~e_R&3nm72b;9(_B^a)8P7e#vu? z7G?pnsYx+z``agvniz@SB_8Kd5?vFlf!xu<{BVMqFqP-!Ckjm`-6&HrOsRa;PZ!QD z34C$%rOvD03YC;VC@=IKysgAIODt>nWD5oi0SC^!yKy<*$OeujiBDgV0bZ}rdiFrE zZ#ecDUYrGCT`Ubm%NqF8B(_Ky(}Y&<rRyaXd0<Ppnsz8{7aDTwcUlwmJq@_sFCxH& zY?M((Rq1i$goH$`^P)>M;L9#!4b{>lu_o4Lui<{Z)2t-))?so$6RH`*nZ*w89!MI= zq2;FXJ`=SKgRrW#D!QrM-)=atFHlxvD2`fA?Ef;;)e)Pb+Bb{VZJ=gwr*b;Klz9C3 z1^t<VG*oiyA)B+SJf~pjkmlV-<&NW}q|v|$@Jve+Jd#2_?Xwk!mBC46_F`@b^FpY( z%>_LiDDGjvW}lu#wDVFz26j5b+94txmTg>tb@0KF8!IH5LSPa1Lp`3$2IF_ghpt<i zH}4Ir$fH|5_#;}a1S4B5TEl1Z2E6JFBinCR)b4vHe1|&dBuOro)19OH_djAL>=m_g ze@SV?kvq0<q++r1%f-m&>zzFw;*LB5UEn{E<!ou<WMQuE;$&t2!uiKqlpo(F-zy4! z<=y2@WPhZ*WQv!P!b*rDfaM!Nm9mUY<8Jz#+Md29d^ITQRd^_+E(@b1j`lanOHVWz zRU^ucH7DUwK7AfxWqhZ6r&1iJIZ_l+a4_8@@47=($Gd9OUjDE+MQo-A&K4#tGqZ2% zqCMDkA5=Tf^AzwzYBC*knq%HtSf6U}v!4;y=~S4Tn-%D%j++1@Et#I&!%zy0?m?Fg zysA=75Mg~Y9mF?b_zC(9OFF|?XCI%J>~O=}di+3|G+1;=@T_`V5&QcLfQjhV@eY4? zx2|GPIQGzfJ~L@#w+uJmuW}(|>td%=$mnA0BL)44!hEZN3pA_k!c*U+Vb+)T<6Y3V zUnV`GxTpLXh&xe`AA6DC$?0NgVQ0bq`<e5{2=43XMUX(je(dKW*k^~|c-DtNu&O?{ z`Vo6jjj}wsh28~2DRD|%D+&HR+MIE5M)2fhviQoWsys3d_j!THbE+JrYYMM?V(<LA z^brg7$@nKMk5g4-vPSu?Tm<~r+$1w3(jB@#C+P`4b0Q;+nS0YamE`R^&d#kLf(4Gj zv*5IE!Wv%2TBPuEAh!zx%FG2`ajuB7Lcyl>nk=Vy;75MZBM#UrbSz=90kh`1r1ab9 z`_i@AjEUCo(c|V^O~HZl%n2C8CR;~i?LOa+o!z~y+GKLVv>kLfatGRLqoSBF1%w$C zP>hZP=tik>Ssy|m@A8n^S@lDx*;XZnSl@~?H2SuO*4M~u*cO*g@0E6x8ETpMs6Mr$ zn_4S*I(F8k>uq6#RIJ_ib+=8ovc9GWV96bnS*Y)l=2tYob49F$To6OJxa`%S%X6H1 zy9?Q>XZOEv7^rsr3DUlT+ZplWx)pXJ*9P+Vap_}+W5iz9Vz}JNtST$#Qx(j1S!Z3f ze}Ktl;?jo+yE5!B9EjXv=nvL(8=#|OAxv{(6>rd<L<>MsqmkVYeUGg&jy}mN`WhSm z^M1S)dKgrKb6r)x<n>hn(@nC7iV$N=Hfv<<Li|IHH5;k;m>wC7l(3|0PHopG{ZsTR z(MLkU?eM*m+v`5K-{^u?VWgJ;L+0++Op%+b$|Dii?>8GETe$6VX~JP!{NLwQj0CR_ z;15$m$hRsyt`72E#83#`9+ryu`50G!QXW?g!Igd4<V;M#H>-_8R(ssn^JUr^TU;^{ z!ho_!I3<J!=^Vn6v}=68W8m=!DX|)feH2El5AQK&3oY1CFfj+fiSo#jw8<Rg>I*zQ zIAV$}J|r|nw*-&plpg@zO9yzL5%)7!r(lcQj<?D`Wf=$eY4e_v2z1U(wxqoz@>_nC z_tKFEZ&c~C3$VJ`Tr^mkdLz+I7R6C#4qdz$XJvocfj@G=Yx#W$9Vi$zm+%x>5eI50 z=^RL%Hh>gfe0Xd?BTh1KE5$YGD8xoNsjiqZMPfE;=UPECZp6BsENZfEvXU3kFG&|f zI%j)G{lUdNnGA(0{JGXB%>&ncnHzu_nD1FiRTumXpZFJnUZnRVJ-)vgKUyln>T(4> z%TUXtJRK6O?meY`zUiSqj?pb|A$pA?7bELa(w?R2cDM4>twlO3uy7HlBP_K6-;_*U zfS%h2|4^iO$$&ei(v*m0@A0hnnjibp;hkY4G-~5r@}7Q<SnF9`vu=|N$-_f@@tt;U z)z+cug^Zq7?n8;31&!j24eLixtToO>I-*9aAPq8llh63n-M7FI<3J;=#c{?lMU|$< zW~4K>CE5p}Cm4&?aE_RZIo{>Uq#-9*YB-t<H9PxdsneWIDA=HM%eyMkv#vCwr0q05 zpzNB7ruKs(NE0jUss@;QObse|@uEA|%48yTGdV|B+HnIjyFMI~C7o2;zD|EdVGPMw z;S~e<5O0CZy`k;F)pV<TC||-ZF`zWm;{KO7d-)2I7JBdG!UYA%1<IU)G&ymF9$=JX zQpQ!+fX;{Jl#q|v^aj<WIDAoF>vp}m;r$qP+0_+bZntP%`|{nMwK?<=-9wa%+hd{; zO7}+nV`~0aQ}5zrCz0;>2e}j)x2eesA3V!VC=ruHQ6`noO=5287`zW*#(BClNC154 zo}`a&zG3hPO$_>5Bt5<$$ZM_+w6k+g02ZFc+<T^Z`?afvE={5l-g6T7IRESmBnW)A zXR*`Cx#n=AuH42)=aAV1su8?XR#Z&c-$e^&3Ym10d_gt%9BeSG-Uyl?Ap2T>8hDZP zm6){ouzO8Ixe6w@mnp2NFlLpTGL{lt(yuecRtST|&uVWZ6n8Nt+Sl2wHqAUq)<p}m z&Y)FJaWyg(A1~gBBK}CT?n<1Lnvt0LanwO9+cUSm3s%b4y&E>0ahdaJpezx;*U8{5 z$Y|MT+a2H51FJU=tEkhNsS%TQNstDe(07N=iHU?m(mujA3SDJXkct(qJOJ|+dyk7* z5WK?dp;@V6`R%|u=iqwUX^cI&Ib+b^jkY9F;_dlN0WR88m$>D&;?uh8WJ}K(H~ZdP zYIQiXl$8E*$7|;L>*T;zBS*4(xz0seJJ8Y*<?`{e`fJq6MJsTsSh@Q4OpsT@3eJu6 zJO5eN2Ly9A&yXu;Y{1qVlnfqq@%by3gu8|XlNY-O(qlF&BT1a&XBxs>MgiUgl?VR6 zOf{7zg6l$%0RTn}008G-34x2Jt;HXifYwO#A`h?~ZCe1n)#j_&P&JO6SgRot5-7XV zKETi_EI#a5CVM+7Jy+DwB=CIZ9v@0S@_BjcIT?RGjY3ypxqC|p0Uu4r<z^c3<jK3F z$6HCo!SZq0tKBjW@S0ePi$UjCbk52BR@{WB&(&g4$mD*@ED#Y4Bk?u=;-wPm1`y}Q zSg<ju6sjD6zg*uGpONg8XC&x@6qcN(>f-5hZvtN!ZeL@?m@%n_RBc}JQIeKILl#D8 zE2|3y28)GtS-u?m+~$JR*2s`c>^S<GrtV`AJRmRI$;4N7rX|tY#R7aa*O^RT+G;-4 zA|I8Z3GgLV1A6++p=N$405>~2c>?*x9*aWrXJIdWn7Q7e@QE!~aNB?4Yj_h#D{2VY zikI841d^E65eD+@xcOZAz`w%bqgnnwH>YdQ-Zk~6*O)aBElhcrLHZ5Qh$<pSo>$1M zf?c?!$2drd_J=D1-w(57?MxkxbgZ9|d_(fO1bmT^GHc@j5?I*g`n`}fV_;Ew-ETa- z(+BN?m=lg8XE0QqXSFcDiV-8q@XwBmB&1uOE>Nl{al;s_ncn1T^s+Xg8&<St!MYAK zc2gr5@0Z|w1^AdU`6f<Hq6S=ku~}+?bLXyRQw-;3W2ngQ95(mn<rKnr2srl&Iw$vX zWoXURdw$0PUC)O*Zek4eP4b-qfD|5Cp1D}3*PIt!K`wkI`wJ+S>YkHh=LUNGpF1B{ z7=bZ@N+-^{IZzI+O^P(3a%RJpw7huZdXiSDY0)Dl^38763aXyFm1n|^wjj7epR%5C zK$plG8qkb_NI%ug*qGv&On-LYl8xT^;QTS~<58Y^VBh7LSll5O3F?A^)C$tLWbSn? zAB>;^CTp{t0uo|GPgPQbD}7eJC$JeLKW^mS;d^`T2kJc(O)1Px7|zaA20WjLwpdMD znAw!7Ms+&9H?0~AqIlEJ$4X~O+Chyf<N&N*`TD3WaY390@dq~<F-s(F=&=Pd4vNuM zwq=lC`+}f>U1iO<!Btv;KvrD8fmB*K$p|}i(XRef;_ftgVCq7IoaY)_VjlI(wP*EG z-M32Ua&ICjdmuj#)<R*a(p1^~>P`^T2by*nC}6Z&(4s#~4UGtLXn6yx$Yn`&h#|jx zePsy5R<R<Hv{B+S(ZFtkaB<g(#~WX<i+M=UwVptgub{tVY!R-tpe!PN$3X=Ei2h*g zkIkX8rG<ryGyCt|?@4H+h5>AW1MHhsduM#v#)%}4cCUm`s~k6>&{vqGkBYE5WB&eN z$4YgAhJ~%QQ5D%JAAEBOe+-u8qV!<W(_$oOb3OoM^^*1VJll565$-bzhLgawpxK#z zR3SMPSn|=zNX*QE53L2IDu<s~DKM4T%uqwkIcr`Ta-*(W<k>l4mjX-wB1OHEii7qW z#*{ws0@Lu49=ELy6V<HNejRrXfn&`k((SeUllEs*pIMz!TbA3KKw8k)xnkW{>YxJ2 zi23yy?LO#}PuGkT&J#98J+E4|x^-Yfv0~A6QHJejua$^jC!L9};p86l4mgP&oz6=r z&pTz_T)zD>(J`0M30*N~m5N3EASqYtZ+5_TkK)7<Ae9Ap8W)lMz=?LxOYDgL&FYZ` zvL4uYjKJ{l+8Wo&*oc(Td;sqH%{nG4e?be$f`0x9OQ`a2_>`_!AYQf$Pk2rD%y=jJ z1m;snx7hdBGkHwns8<X_AwZxvMcMahq5Wc3tB-M27x`(nr<hhtaaC^lYu_|MSF#5t z2XdFCG`uOY+SeC_^BpZ_<zxf9PjG$s+%IH-j>Dr+K|hX5Z2pPaiF1*P?orvMi1c2R zIkWMQ4dc-VZ!))m@Z``N(&}bO>@mDOh2Cw_lM@i9unc9Fzq{9Mq_IP`ioT7U`kFF^ zJf&U16RJ(3YK)@$6zSE>Hq8-?&-2&xE>l{{xiUZ2C^og^^wv#~n$Mvv_HutRE+ip| zt^TgDwh+g`MMscmyN!Ed<I&!q^y_$0Lh=z+2(f|GK_Czhp=O!G%v7CV4$kamFei(D z)nWc8Vj*Z58E>S}!vTK3g4!W5;GI^RCn3HVIG9O_ZqLyE>We)VkCklha(mlO*7Tsy zF(*9zx@F5ytxUNjy1kQsej8MPA%<u93H>cD?SkFx30Zjh3*D;b3Dw-kytO6vFid*} z7>nTIhk&mjeX#7pQ+s)r^G~XgWFkSPY#0y7dVS3Z&ep7O=QzH1JqUO#o}?Z4BFHmX zz}S|K8WI<zB70`FM^4Eb3;|mnIi%))>)Y#Mg1?Zc98Q<NdWRtp<+x?rh34p#m7X4H zw@7!88-sUR^v&+<e6kXvu)G|OT!Puf*wE=?R+@pVx2lsPU^tS#@>1Z4HuU;zyQu<A znZi3DFjO4K-`mbm84=QV0MR5KIDNxn77vq?pNeFwf!ps_erKCgRb4;!$A6a|?<3s` zD7k0k8@x;MD>+Oq+RZN=fjN9co&x+U=1d$M{s%b(*8bJf<GYlXIDo-Ni5?;S?lU^N zRJBf#<7&M*n$H$qwd^VK5Jub0OVlpvRkFeWG2>{fIjdy+a=r1dGQHAL?q-k1%p#_g z%-#{2a(yDO<sZ<wuY5h(=-O4G^)Q5<MWI;#ZJE1j6)TM!6RvQm)HxD0M3z{pQKJgN zIn1ll94uXcF%bQFuuqz*&T+(7lNe{qaD`_zmSW?QGXy7yIY$t?MU;nTRQG0Od~z?E z-Jr5QFra`Js|!*dYtPsLA@e;Yc%B7?l&zXQ1ulcm?YJ8gn^xDgSn6sxii~v_(?pMF z0~=AMS?zKZ71e5aZN&0obhtz;?POT4D?l#1s5YA1gH$H2^*K8>Bp~Ta7k~K8+1S)k z$d*w|P=W;!d}B_iVuYUW07qk=q$L39)l1+0L@}%#y*gFAyDmYp$8c=qlYn<+NDjQt z!?Q-I%3cXVa3xiHh3<+g(<P;5OlJQIpdn$i2zW?WieU%G4QmCbm-c{bfz8~Ixgq%U z{h8r*=AGBKbtf;u0g=t~n!J?N$_}0Hh$#Jsz>9Q`6(PC(x}yE>8T@zui~6>z!rvYI zz4rER!ykPzf+l~d#Qkje_j<%%4O<ba*8g9f_}S0TBK4o1ju1urpCs#_jepi5|1_4v z`rY^+s^rfeewN|>^bm>tOHuA;2S4w8{&b*=ko6Gn@BE*A(9fnnr(l1YVn6)Pr~e}% z``OFiL+PJB0Dy2}0N@{i^=I?HuZn*)|BhHi|6~5IHBwap6*0R204CxHK*a8G@*ltc E5A?FDasU7T From ff563600d756f0a64dccd5d652a03b29010060d2 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 14:42:46 +0900 Subject: [PATCH 030/159] =?UTF-8?q?=EC=98=A8=EB=B0=B0=EC=88=98=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=ED=98=84=ED=99=A9=20=EC=97=91?= =?UTF-8?q?=EC=85=80=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/htdflSttn/page.tsx | 8 ++++---- .../ruseFcltMng/fcltSttn/htdflSttn/index.tsx | 11 ++++++----- apps/wr/public/sample_htdflSttn.xlsx | Bin 10139 -> 10523 bytes 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index 959367202..b943e8b4f 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -61,11 +61,11 @@ export default function HtdflSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - htdflSttnSearch(1, "10000", String(con), fcltNm, code.cityCd, code.sggCd); + htdflSttnSearch(true, 1, "20", String(con), fcltNm, code.cityCd, code.sggCd); }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd]); useEffect(() => { - htdflSttnSearch(pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + htdflSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); }, [pageNation]); const getSelCity = (val: string | number) => { @@ -113,7 +113,7 @@ export default function HtdflSttn() { htdflSttn.excelList, "온배수시설 현황", "sample_htdflSttn.xlsx", - "A1:S3" + "A1:R3" ); } }, [htdflSttn.excelList, code]); @@ -182,7 +182,7 @@ export default function HtdflSttn() { size={"sm"} onClick={() => { const con = getConValue(); - htdflSttnSearch(pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + htdflSttnSearch(false, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); }} > 조회 diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx index eb37d0d73..229b4fe2a 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx @@ -6,6 +6,7 @@ import { controlHeadView } from "../rainSttn"; import type { customHtdflBdst } from "../../fcltReg/htdflReg"; import { fetchType, getFetch } from "@/components/lib/api"; import type { SelectDataType } from "@common/business_components/ui"; +import { excelHtdflSttnParsing } from "./excel"; const htdflSttHeadList = htdflSttHeadListExport; const htdflSttNodeList = htdflSttNodeListExport; @@ -24,7 +25,7 @@ type htdflSttnActions = { initHtdfl: (page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => void; - htdflSttnSearch: (page: number, total: string, con: string, txt: string, + htdflSttnSearch: (isExcel:boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => void; htdflChSttnHead: ( @@ -81,11 +82,10 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( console.log(error); } }, - htdflSttnSearch: async (page: number, total: string, con: string, txt: string, + htdflSttnSearch: async (isExcel:boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - console.log("page", page) const htdflSttnRes = await getFetch( fetchType.WR, `/drain/facilityList` + @@ -95,13 +95,14 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( (txt ? `/${txt}` : "") ); - if (Number(total) > 9000) { + if (isExcel) { + const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode); set((state: htdflSttnState) => { return { ...state, htdflSttn: { ...state.htdflSttn, - excelList: htdflSttnRes, + excelList: htdflExcel, }, }; }); diff --git a/apps/wr/public/sample_htdflSttn.xlsx b/apps/wr/public/sample_htdflSttn.xlsx index fd1dc5a8917a8538bf940cc9f9f957f37408230b..463c1ca8752ad59f164b2f8f5c8413c36d46bf73 100644 GIT binary patch literal 10523 zcmeHN1y>x|wr(JJBZ0=9;2tEnG!lZl1_;&!cXta;AO!b7fZ)NM;4Z-l1PiW>6a4ke zo%=Gw%zJ;}-s-ig)>&Qq>#kGZ-rqiZA7wd&M<4(a00jU5PyxWafupu?0Kg+e000+& z0{>FN&ej=X>-<XH!ye+K&*pApO_}ouo*^3m54-=r$A9n)l&JUHc5q;~XzhqfwrYld z2rVi?A#EgmNwbBV>>j60Q@c*YaN|R7rlL`S(oU;lJ^GUFM2N6-j!s8hY}K0WN=J#t z5WOI})bU98_C=Od;Kvfp=&IOAo@_!4C=_X;23fv-&X~=T`ktB=pQjp)YqR}Waa+7N zOjLrlg=wP*{&IF#xW7XOUXIa)(3sCXNR^dXc2TRjS%s5Jlcqe)iA;kn{vw(YRH58Z zeMKR&GcXRy)~_%p5|E$}vnYZ4WWz}T<O)H>u6PPMrhM&>#QtQVaiE?Pt#i)Z+i+K! zurXt`tk&h#jbPwdY?MZ}(p05egXLNb`bmn@$sTuKUTHY%fG%WD@dEYEoe<)EX2<gJ zgdkvai!$?R?2$)HFp5(Mw#5Qqv2p+LDXCK_{1)obsU|PMA;EP#=G#d=zL@kmK$4pg z!MienGvK2D;GTq|`RsWV>1FXe=0Zjem|{8c2$SRv=4bc!2ms~3xM__B$CFbS_vB&U zqQl(ul_SL3iJk4Y^MBp*KiDV#^ynpV3QC<Ez!2z*o6x?CsfAc<aXB~eizX^{Uw@hJ zST)hPG$adO=t;5FiGvWN{aSo)2Id!pqIdeJ&VO*1MB;!1pVYdQh9q4%xF9ppIVL`L zC|T)x>^gNeb)F(E>%rjK62nwn|LKEV|I(A^6GxI2*rRM(#HhG=q#^jiDFM1Y3Ob9% zKg-~z#MSmoLq6B>X79WoP4k;c%-_Zk4da*J8&AROb25JYt<1a6n(FM5SVPU6-{P}z zrlSD0$179owiC&;FSxhftcvM<s?^*#KRHLGdug-J{B*0ij|MY5x_D7Li~A1y10yLu zEy5J*?@kgR5}$Men~_GClMn+?;M}d*|K%rcc8*rYc6L_3soB4M1`Z}^FqHr7qeN9f zt_v2@(eFYz+|pd}9)ELYr{2@p#X{+?W}K&^;_^LRB4KLO*PfPRN3aX=fDZS%UhrW4 zK)^j~XZ{p{^T-p|8Y+lrH+(XTfMUE~N**YUh>Nqgvs=86j+yF&+aMCx$C3%++xW>q zOB9-$Pc3=cFdo8fIl|$>Y3cNpYyifY!Rj^tt6;Ug(!lDvI?7Z=v-SH1iTQJ+tUwQn zu@fRx86gZ0z}VI#74y$_sdJR$<{L8wj}fc(+$-QZX|Wu65s$EUh%;qqpEQLZW1Q1^ zPD+yobj4ZxdVulE{4vYmDb#GOzjta0_NM<%8Q<?lkSQ1qS`h#MEZ7||%KVuuAJr6` zCSdc!)#>+jYq4*H22rR&Ft#HWeIlT?VJ)X`R~y%dP^PE<%WDV^cB-79-p8q#iPj5O z0$$|OK6ZNpUA1xVI2HKkv%0DJG86}2^jZqKkZmo?N&@1@+b7a?_S3oz7ksVuGb#O# zXl*36(0ZE9!A_zTWQ0N%B@;r+<NL`_(!;qr0GRpNaHUm#12;Dn=zx~6*5af8OJ+|D zIvQ-`2xR%Cy2=xJZdL>Mf`<8vg@n(I5@Dt4oTSpqvegWlf+l23OdoyvHt9`)?AbM- z5zqNxRPl=VHN+($6OT*=t;pw0?(&tmi!Mv`Z@)0ef-Y8^SP>>^TYB=yma{Ns+_F3i z54p33^NAo+6wC*t;7v-Sg}U+bETM>`*imV`HX?FE3k9*u%;5W1h0pgOR%3+6WWML) zaMKd%CA!OfQtfqjZ$lGL6%(9wtjUEqDSC%X$)YN?@zc0`F7rIfm6Id;lBibV)g!Xr zm*ZD>QqThL$^#u_Fs&>s1>-?pEAIGMtLM7YA6U1YpZSGuT0oim^hsm|?qg#@K67nV zEFMKV(3zcHO7Fq#74wzmypOLJH(u6s5ux+*q^-vp(@g)-9qen_vcvn23}|aUo!W#k zU>e2%(7zbqWNzdLF;#PRw6J~c^jpk`S5vZ@6a#%h_YE~t+;1PALwqbVE&;}7CkKrh zxy@l%(^;8m?%6;JjAcFuJKN0B5!#PwYHBa+=^BYD#H1uamuX(=@@%)u86IDsY+Nh~ z`P@cNfXl;st&@m<`j)<Z{6V1(GQo=Q#r^K*qC^y7o%!HSeLSIi8b`D3VoNSp&%1F| zv*l--3(~1QsWv~fOEz3lHTv>*`SG=+?c_}KW3*YP>4F8xY)TFMviTDgo?12v4`4J; zw|$b{*AlLDxb2)wvDx`9|An4|V&Dk=$A@&f#vTRz!4I@RUlikbL~211b|ZS!M|Q;( z&oOe)u_K4F`XYtZZ8CjkHN*r+I>+k#hSzC=wcDD6FI@`M-6xd_xEh`;pC01t6TWW$ z{1NxbrCeKo!%cnD@#(sy%r5<*NZ(tm6?2x&+qj!kvG&6gmV4iA32$X%P%>IDCExpN z<8@V_tVZ_d{u2ypJPDWON~l&hq2#4-Mo4~KnWp`+G^J=v60W#bA&4YLidHZxL0<rG z&|bq=#c|c~<#6EpiF2vT5!~d^OFp{}t%Rdaw2Fv#BXqKQI~MPb8&&+G^5-=LJNGxZ zuxuLRMJ)=G-acMBD3Z!K2$3tt$FlMh-Bv<BD~aH|-_I^=;r4^Q`oD(;K^soFb{HYV zVdQx7D>OKnLm<vhe+bL(gQx#1E5R}C5gi;LsSAWV33spe({F$hYP{6-8k-2lS93`7 zNwF88TdyioNZb0l{pk9$v}>V45;M$qER&7!Z`Mo*%s(G`&9Qy~SMcq82cfbG#Trep zwWcB{D$0iU#%klCSG-Z7xh3rM?fO>n7PT-|WaFDmxCcl7WhBYhk|Il+<5$Sl?20u| zmNg%(AOT@jox8oaJ`_T>xnD+J9FGRe@W&d8<h<bTliEM_HwN#zoo8D4U_Q#X85%q} zNByT6;J^yA+D8Ha7Ri2F8~z>~oy{RO5cc2Czd!b#j+`9{FLo=zmLKJLrgkN5?=x!T zL>5|`A6=glK>VsrlWZmjj$qYV7v?yV0C=g1oFw>`Gv#WGSU}6iFFiI9&k&CZ1ZcF1 z^Q0~l9{ETidr>R_H;0K1rmR94C9Wl33{+_<f6+t7?iVK?W3feayKa$VhKoac{n$+C zNvWZ{slCnZ?M2xSo`l$V%IwiKVq3&;)yuh#K;X*L#3T<zPIull>TWb!sb*|cZ-BR2 z?Pu*`R`!p{W^e=cXx30*C^yZgavh{y+zoxCx|Fypa9>xMnF1+VQ1tl@F;#D6=cBpa z61+Bn$D&*BCGaRi@&XA;v(0?lJFcb>n>DeY@`Tok&v1PSETarN#~)6mCXbJt_KKcj zPNVfhFto&<*>@FO@a!K2*b@fkYbG*{KDWzT%sedd-&<#aDwgV4)&E4h&m&6Fn%{SI zs)_C9<e~KXmfT)GnMgtsiMi;{(#juXSIsMs0YSDC!~Y@_1l8Bkx2<<akR=>GH~TvG zp~axRB^b!xwDP7L;GL)0R=^Mz!r6F=BavC?QIYrqS??5(9ROrbrQ#Xs#}38rCQHYB z)a?n^{M>#$+6Od{BJIgaBLQ}rLK7K!YT6aQRJ^(L#q$o-;(52WwNjNEDoQ5o>3n)9 zJvd0!98gs+`}25y^zP=$<g|Cf&Oqd@BPL1Xrd-tfcyKi9Iv^IT7H;5uxmNdD$-w(; z8@eQX-p2cgTz$nS6(`*GJwkP-+Sg&io`iH@*CoRhYCa~SqJLeeixw^B;W;4}MVW%$ z>H@B^kayc|F7n%wrf@>W9i2<FIDt0S5uG&jayZ+a8YcXMn9A8N^@JJ@f`riP>4W7V z2OGC|iK+BQc_!D2;-pXOh(<tfWuAk^p+Cu~$oCJ_c4l27LjvVQ)VD;WY~)+$wkHB` zU#R7fa3g++@(~CsCY!fjkgyr?*0qcCAwWe9NRj?2V)T}%eDz&NVGM+#pv3a<r8cby zm0K@$$&W_WfC7^azMbcivJ}H)a95h?zPJ)C$BjOb(P{*YpoNp8<~RK1)V!Al^z9Z0 z2`OeWc-H~ngRr~J)0io|Bb$hFpzT<EX}bqr@q7m&E!f}lDxQpUi=C#uJN$VpuwpCn z_8T^?8YKIpV1hv2HyKEp%BOkgz_}^KyuZRwk`V7(yj_oaKcn!)u3YOhG0h=c6)4kb z6B^mgCi7{tp6`i^hi=3NStT!<36BCN5-1hKS}U5UfmQ*^YJ?EsdH5BGXvWEcTp<)N zm^18VU(ptVgjyz&!}LwT9@EEbA?jTPi*_&0x?V@KIeA(@BI&Blb9J=Rrj%!Co|qL0 z62>*%Pp;hy1?&>7hfayoQd}#)#+lhqcPExLFB-crPw7=P6ir2&=Q9WtB`^hHz19c{ z&Exq{1^$W^kdS1wH&fZ!97Ggey|B+B;t*+Y#oF-c>l{<ua+o#&e++Y3G0BpGxH*nK z`Ao)W>XaD2J_;`Wdxx`*=b0SI#5x5F71qW&JayV3n7ZwjP8CGi*qfz>DDT<y^7;7` zb_}qq2;WAE(^^kvrbg1u<r9}*<rZOv5<GinmNOu;s`sKM9AfNaZh%*2oRTsaeG@qx zf?3O(>yI&s{-UB9p6a+x2F}%4UoJ!fr>LlkS!t-^4IC&THU{*#Nygb9$(qKMqn^UL z=q&tGFarAfuUANlGu1W2%yqT+E~TFN5c_j}GmpSX%R;5sbVRRL=$2%OhB6YS!;l+2 zAiM(^ukbRC>|_%x3GYYM$L8VEDOsfE5U5BG(4w4MYvI|{J3gSTqhff$kF?0|`<n;g z>bhg}gg!Alc@^t(yR?zMZZuAe1g?=Vp<%G5XL=lLEuq6X=7v_~S#hSFSYl{OT|`|r zR62`LsiggCrVXMWgb*+GDa}$f9xh0b-0#5W9XLq)g5iF$r<?A?!_BRwVIH%8JgXwX zTs^`U!mNE($3@ResP=fI5^iwYvDSFlym>ag>10c@bZ&Ib9y9oqV)p(MO3JOl2i{4M zrGUAJ<&z*ha<KZVaSaUW7X&Z7c>G&?MXK9B>U_hC*f?c%1+O>8<`Gz^k6P?ihC3!X zIUcRGZg}^wvFyz@5=)b-1-*_b_+%SH=M?4;b@^4}7QY)At8FaJen-^!d^dh*Wn>N9 z$|~=S;m*y*mQqbp7A+v$IZFo#1wM|(q(AAc0O$UkReSc#|Jf6qN4hfgYb3;a;$+E) zg$t~5Ke{Kv<<P1)<M-lbNk3f@wp~<+n+ngRB)D+Bu9?=tm8;luk#|K}(b?ciaT^gR z?%&IH&&g#o<aBYb>_?LeI5I=PYPClLb{5_mAf~-#Wuh~kx&OzKOvH+?V=gRnNCg4_ z7=I*=&K}l~-!sPVTElPWpZ%tbf+)>aXC{LcKpAke0UX?TcAIU0fkk*__@Q+6R&;uf zm;sfTmsJ2c+9@oWC|qHZsmA4XKPzk+rrIXgT#LQgAQ=I^P8YJ}cd`w)`~+e|WAk3a zR_Tk2(2r<s=wG09B#xE}PXW<LNsnjueoJ~q6D`8&*g`KU2%t&@?bnoPWzK-SIvkv+ ztf&q1;v!5i)M`#rbsy_J+rWNpuyu_dW5T2y`uRsUKP71~LFgPSO?gHB%YjcKx-4sl z#%Ip-A3I(msm~j}MK8d>XCmd+9uuZb$CrIpIZgoB=`YGbY#8M^H^w4(g3~4fWDFA$ z-2;xs$)YXry%9pm$RWxm880RfZv{2zz-MLKY9(@)r@tH$!=YxEL+k(O$gTHmmY6WS zE!|mg@$P(MVYEC$)c1aUA4@bf56x-d?Lv;QP0J*719UL7cMMDe&*ML$kFN3yu)Dzb zDj^Pw&b0T&^7S|H1+HP~m_%E)F%8VF<qLun#jq`MBr%H>MO*o&?epM&w3uMX-Pd~+ z96m+KJ;CCR8yl~8b+aHVbe#vSdo;HK%gA+-QMp!$2RnS*l1tTTY4)-CoB%tLIvp?a z+Fc?J&Nqr7825FmR$==rjEsvi0Vzl4_Qsw#ab(8=Ql3~I{Eu`-S?l}~(^STH`A&k@ zO}5iL0AX0oqe5dumnm~UEq-o*m?%~Tu73uav!a;H(3Q28DpFZx*3>$71#IexvZ_5w z=oJ#}#O`RJa9#PPAU~@(Ca{NUeM+faQ0fV(FZ*_M8DJMaV6(onG<~6h;qRh^S2Xkj zZ_VxLu$Ap+(&Ba@-c@UxDvxwgBWHTPZA?>C^8674rYkgmc{~Qg3<lGPy8LeSW7U<b zkZR40hR?O0_Zs)FF4N-tdJD3?-KJ?StNpO6!aTN)8*)><jE{f2Ev|aHnU=M9d*x}| zbuN~Y|HE#akYmu*o6uX$u-al}@4dq~JXAu4$=mR1qdGaq;RcU!JD|5f|JB6HLRQI$ z9)~(BTW7HlA*<|&_8ESL)EsEpbj*)o4e~}gzZU0BE}RC3>c#r88^@M!YZVk%NlQwe z{r6vG=2{8HIg`tYk#6&MqW2Y=$svrX@|h_`wrRpx=1L8{D;<6~h^=X(H*Fd0hvWKe zX7AFZ!Sy;rGg>O-3iZ-hd-^`?C?ShA7&!^~=^RW*uQ13{W!q&qZv7wkfOb*sZdBgg z!a5y)&-ODfO=w18-kgXI01*By+y9m4r)%mv%?V)peBrvqBK|^PLTeF$w1q8#gF_iy zozaT+L=1QSI6+e6Y8NVt`AD;sE2C8>G`Ff)II?=*uH55!=9_1#co_^9+)t<@)Jsh( zwk1VdV?_L-!z!A!kL2-ka9dDueRh4X3T|^w-+x0hLS+Eu<Jy$6>X4>6GdtQ67l9CO zDm4W*@e@69(^S!0kJFA>@`pE)_%<uUm=N>tB_&E{IPnk?4jffxWhEn{UiK|nLoCiM zJ+9~-`Dc`xj-85*acB}b-=7ahKBrOo=B~ytoJ5p<&BMRBZ7|Ocf2o(ROH@;f5gS=7 z*~wM+LlY>wa4y?{s`o7%e^+r*P8&L-19F>h6%);Ke=5Dyb-bS2Cu!M@<{c4Me6Lza zFHMRt`AB9JRWYtWQzWvruTqg)j=}wBdCZSiDoO7!hntod-s8++9-VNWC5Y<>1KZ&5 z)~t_Ot-qo(1QjE_Y{3YYX-5iM{Q1JCjTKs3<4Lv5U}`CQaP`E9;H#d&$Ely9(YAsv zO`f(d=>wa=^KJc^O~bA?!2Wz_RIxCE;%eRLQ;xPaY=m46Sx4e^V!MX+HonR10^&ON zK{6yd!enE^kN_{>(9=Wz07N9uF980@i@jJE;56BdQ|Sr8U4u=*UB;99^Qa)dmBh#i z)}UChN@*z7`e0!ngQ*_%s6@|<T8~1Xc?M?>)e|s=_e%-zf}55E7&&uNStR|`FUmrS zU+_3JN34n%Z*9g01M!lp{6qGR=%ljpB>_)-%vIJY9qG26=Y-7(!Ni9PT+=0u7a#gs zeWi}-3fWHp2ok_34*Tc;5@6I*`^W%6pgadhslSsO^jiLPvO`P&KN2~|XFhl)r6T&g z#%re!ymv=WX*2{cM3gUt$d-4y)6|dxD4Byrm649by}?Am7!L0IE0$PCDjmy>m`4sB z%WNfMANB^W!;iPskZeP5;2?&cVOWd^P^;q)KwZkNa>gJ<lp~UXY%0s+0^k*OmmOo! zIm(gXK(?H?w>S~ET-Yc>5I*V=Bjl?bm9G+!GxqXPD0IQK;f=@G0H`OdhN*-^WjV`c zNtQ4lZAz>A`s?<yMDHj0dUmEpFX*OyGwXvNgS8~2t5)ze6YgF$sZSSu_p>!h2XU}* zF9=m=4jd3bQ)4;~WL1w<x1=vg;OnS!s)NJ3M<X*nsn1!mu?8FCa89l!K!Mvxq7}rJ zrQGsTy@R(ji2A$=eM3q%AKj4hXoSr{vTb*$w4$R%=|N@m-E6PK-FHttH=5jC)Z)wW z(Qqi}b`JbtF8=o*kdgH>LK(K)_kaohV^{&%)XqfN(azq9-Neoj@<%K5zjb5S)J4Uq zD0NbT-YhBHU|~R6ofp23SF@;8(I+L>ORbUwG(~GO!0FBSvG3RF=3<FBLK`SH^%xTA zHKe3JD^52`T8Jw@N}Unk@d>X@(`XiZcOs9jIYlfx87Lv=>7{1>{$#GBsuV+;y<IBc zqyC6OIObv+sYx$ZcCuWcc<4r1ZN#O0wU;&Fy`fhduK2-c_|ZovK)1G8prkVxO@wk7 zrkVcBgiOlWEu9u|KkQ18i@#?f_`Lq8K3+#>+Bi#Ag(%94eAeF&p5;~;H*JYt7VWm% zEl3ivWO1ou#tg#`-24uIQj@3eJCRug9}}?v&%ALXu;)n+{$A(2+lK$st>wKg-@rk% z`80EgNqs?#ODj+k6t%IbJu_l;eps(VB|!CFM}Fg}j&&c)=(x9lAC%=b85)&^zGJ+% z)WwMU_3;r}cFSs3)*D|K+5S$$E#;^+FieY1F#!Pje`%3DtQP4Eaa4miJO5UcWPdPz z%4Td~yQej(gbN1U&E-74AyOg_r)PVEkM^Q7ui7xNdSQ+=I0!lE0Q8KdDQ$lmKMEE3 zfR6l@M9BTHZMf+^0M##?;MS}WPd6+g@l*S^p`o-oyCv_F^Oo{?Qg0M@^PG;SVqrAX zPu~jVdkmW-I!2H4(HR<H>ab*wIJ{Tt$0w1|6YU8S495!V<%r<r<>F=OvL_%p;@gaN z4>Z9ff(WNm;WxZ<O81HHAgJw49jj9SGnWf@f%o_-_|8wy1`442zJiS&uQDy#?CpiS za&O$u2&9&&p_l$W&kJjrR+fS&yaH%7<x=rDdmY|fW~%GFGNh$#NCgMX(Ucw!Fv$$V zyKpsc@E7P<@LQT4#gX&O*u9afjl^rw<vgvi^d*{t<SMfm57!`!#jAFoN*T^x!#4nB zJ1U3gGDoGDPk}38o+vGN&wbHyjB3-dix<thzvFlsh6A3PHzpEke?@p%|AA;OGcv-U zRKrO(`oN-qRLCObE!n|`J;bK`pyo|JGluM>glLsbeYZ$A{Q&VnH%Vkji+o$oHb3in zwer}8Y9VHm_Z+%x<`nYj51G$=NF}e)@)iYOmaA9CWWCa$+uGUZSq{^$l^DrQx2vG2 zXfkb7cg|RJNgE=FL$6ByF-6mB^M1wENHufKS`C*W^Ym->I?W9EnVR`Yrkw3515ZO{ z{slL=itJH~(%9>47I7ZiGYds%Rp;&bmPF;}JRuA3Y5Km4JrSO0rw(qt?~G=-U94mG zEC)zOsZqgUpP>x#^vMOI+2pPzv>V*3cY?{Z18yqmP4ru#x0|a%$rKCTi5?Z569vdQ z-b7Co-(~m;XJz?GFz$X1_2Lk`^R@-{==?ay`A&C$$+d84L{_VVZsRDKcE(-Eq&t0! zB+F2wr%yRCNbHn5V8KaFN0fK1a3;S$L4%%db9=<^N6{}97vw2OTrex|c?wft+Mh~H ziB@q`3YleI)cq}${g?J1uYG9O6=~d@s3J9<TjCODos8v#(ys54#%f7UMan5kbq2NH z*w5}p4Qtp&-fSf;-5%Gy8lcyUgS<hVjvn6Q;yZBCFx5<%l)0U<Y`GaDMEB{tZ@*iA z;rovnVda1!LCkOd2@?bCKZ}8pz5Rc+02Y@1IMU-36n8m5Z#G}-Q5~lXAO<V16H@th z0Zy4}ICw`COjhRJ`Go75*`e(L65HSxa|Xy46{uy=qLLS~a#u%t@uedh6f9B3+><I+ zC?TkP`%bH7L`|8QP|`}89LI*rMQ~3d_P2N67jagXnNiFs=}cFQdt|#TyF4aohcrmP z&W+_C8kNP)ajdp7M1`o8LpPUWq50czp@@NlR7-`^Atg?vQ$Jr$eBTXWUzAV6gOhX6 z)0j4Y<1FU^aXuU)NKR+v)^5L+13Tk>y=Y%n%@4eI`E+cc1C?k{{2NN3A7&TgC%Wni zPAXZI)lW##A~a({%GOOR4H}P$)1#)C2-jmj6YIcgL8a744W1sp_t&+ao<4pz^n5an z4lmEAZs+y}jhM5I)n*Bu8LDT4(}}CG??EPbhsYa7Sq+e_Fu`;gRR5*JIl&3=s}lC; zrpTG8$t<Sen8RnG#;QdC{`D42H(_jo_?Mrf`(+Bh1COzWFQiT;c^CW=JA=TDN#o4t zW`TZpdY2UcmJ&F4R#+$NpEr2@`=$N+`VZT^l;!>k@Yk&;|2F*XS^(3iKW#*LX!zH5 z{GSbnU`>VpyE*?5=V6cb7t%d!58H!|?L*^-?Y&>daIlpg%=mB3zJ~}8`#`@Ch+$=) zKYsrI>k2&teArg`1xN}Ld>G)vCd)&Bhn1&a00MabdZz!aLp?NoxXk@!ibC}8VSX)o zAENv<PyU4gD}=#XMSshhADTbRZ+-#9!$=I9fCt&l!}0Ig&O^|@hU;IDu&p3Z{`8;z Y2;Rzah%gQU06^G>4o2f8+TTY11N2}@jQ{`u literal 10139 zcmaia1yCMKw=M1(BtUQrZo%DMJ{*F(ySux)TX5F^!QI{6HMl!ma?ZW){D=2$y{~F| zYI?r4s%!P`?mc^NfCMNQDi8z^6i}B>#djm|oc?VfARulKARyTHyOynixg9OdpEe@4 zQ@WcDF7QmWMIip^x1}glPJXjwoTGp-r?=P&vnh&*7{u-g^ylm;46dcum#5m@6HD7% z=iFo}H<EcpYH*j)zDMc7q-mWSe5cWq(c2W^5urHOFR^4&+~kY<*to#4r-M2rtkJXy ziMieCT?>4?T-qX4#Yb+z?Ogibu24mC^*K{H$ffao5}oaqze~Bz8HsRfVE{84Tn3I% z^mL)u<|`c2JH{t4mSu^v0|x@o%*i(xrVQDp){lI1!y&%;?upL(w4o}8%ngUU@=U2; z*kzgcJ4JR=UY)~(*0LCL0|Wl0#rFbEr)ppzpbAhRAf$IK^sV#&wpP}5v^v(-G|m?0 z8S<T$%XDz9hzmRzO)QSSIv5~}LNPxMbc8^AEXGqMm-#KkqE&KN=c8hy6-?ZgBBIVh zTnWiNAJ}DjLB=R^&FVE3%Ydk*3a<gRLAQHbpPS9wytdtps8|&?VA*p#Mui2NsU>Jd zk^{7m%R>$$(!f923z$4=iZwD{8bCzs7L<4<o`+_09MBvW<4d45z`j~djty*#^VD0R zbDG^J{EUkQIg}k;lk6hbS`lIC)dAzx+zZ9`lB71COH))-jNvJ`w?vf|B^DBp3}o07 z+jOqt?}C&{+@A>n9r#>$PK`Q5&`z>%DfhT2@4>}8f317jF+2|TR&L)!3J%Qk1i74Q z=3~w2l)2+ZKas*jE6=+S(h1EW+>W^=)8{~+0<wmMDqm^{mAMYw-n=X|B)m(%14&N0 zFi93kvxf4FF1S$A3YZaT+i(O9=|j_e2}re2xe#%N0xetQ2Svd$iRMe>4gY#H$yDAI z!Y-iRML%NTQs(Ke9GB>8rz1*=D45<H#&Z9Z`RJ>atg&yH8>G)vtBh~)_%-UH*M2$Z z5%N3Tfia%61qX?-c45@iGw8pkcLLPxfa`sFao$ZG`9G&u&&t-|&-_}%@Vy&6lF*&# z3c)3}O)R>CYB447?@)13RG$Ua+q$2@IK#|R&D#)Vs#V)iE1|eQq`&irHDSN;SQ)m3 zO^PQ>ekzMg!2LlbCJUCT%>VlViA%Eo0x06(LA4WpGa-OO4YNwqH;g~m(LasgyR#Kk zUnDIreG*s@!d6*L=mTJhjXAu%ifw~ainbbL9PA2?rDMTfuucSKjbOBtTFrX{LmZIZ z+N~P9$x{hgx-uB3#AZ!#I1eHH9eh0`!);gJsO*Tn*zE*M=M9cW%JOVkUavUAC>8XF z6gPTeO-RfwjJpcDFN&ql!_XAzms-sPaBgSwREfQ3;vVie{EE5j{TIEf8*~fqcC|Sk zCZy%<;3X$P9j%(?Q)Sm<jdjWX;5`#h<iZzLJjvSdYe?eJthB>^pruH*SDhyCe{20> z<?ju6*IM~qYs7c0oy}>TtZdD6t*p%cC><f&Dc41Z)XK5Vqi>reS62i_{w<Q-R@P9E zHONrnTb|fgXw<hgDN|(2OlGU~+mp8W!($anTcD%7$?yU{0+MW4qP#VR$Di)4F4?uu zkETml&C3|IM68uKxe0fp#A52Qe50!!jM*{d5#_%`j2lACsH`_BfV4{W8L=bdQYEA~ z0zzJ*0?8#*J8H>qnT*#%Q~)d6KPzG*av$pAVU#j}yVCYD<~t6$$Sm`T@MOK+11ZU5 zR~|kSa6t*5A*G_zU^%XHp5*hRJH&n4eBSZWftK^YLJm+-`t<#d1r49AA|JiL;My^~ z*fR^smzlwg+`adJta-eq?GD0L&E*-z<ThAJ)7izFWSx#3j^!q-8^qtJRBytWzf7<n z)zhMX4qGEXej%hMC?kw<K&YVdzS>*P6p27UaFB$mkz&G{OqS}4fr-K)RQg%vuouw3 z#ZT!tI^B5}ee+#>tiQ$odt3j{DfnxPFOMBJec$5y&ivZ^COvGXBIt!PG>5Y1E8Kv# z$!v^uzepTqHB=62OA!Pi*wVYlz8o5fmEQb1>p>>^xkgS_gAK;MT{_1E({`6NepW^E zS*8@nF?AZJ#sWVEmrYJPr8_8IpXxT10dFE-@<gwaZE#^Adz6obEXn1SbbA4Gh(o5j z9JR+n(R)D)gnR4csEMiZVy{r7ABALRupd-aP`ZGfc>v~>pEyV|hGeUUupcj7SZyq% zuh_u38!Hcc%nPY?L`=~AFxpbI{qf?qWei5oq33s)-cmRHG%II>Ba0|S<-fK0_I%B^ z3-Ny5;R6Ao{H=|>v4MpF?O!eZALBexm9Sc7MQWq1dh?k8aWm8Fk6JKUCA`dCw3vpd zUKWa~lT<S&lg&OLe!b(s7H2?Pv|V!W(T%~@4N14cP2U`ec73@e__PyQ96#*5!KB5^ z*|o(><J^MfoMjaEnJX$UwGWm;e*|JJFdx_DY42`*z|6Hm0G%ELd+RzKp#^ZX^Snb0 zubo^#YtW^etR{{o3twsKPy@KeWfj@lshd2=6pZi34KV===b=vG)YdmtakaAD(*v%o zmLBEBpP8vLBmtYEu}ljjT+I{68NfjUMckp<c?st-j)F=xO~!DBe+C^8lMau<R6pQS z$3{STF0~%W4qKL=5h&jaARHBI_F^7FawJ3vt>afF*uHRPwNxU&q=pAkK`AYzEap07 zdcldsc70MwU^TbLI%x&uHB2b=wzZu-Wq2y82CZ?|Q%-2+F1N9+LJGOUo+xBnyy>zY zpZXED1~^hq463#-ufYmE0?zO2K^Qx~r6?Gn&q$EdI1##eA2XE<Py>O~1X~d~lk2t8 zE)hLSl|Un5@bfW6g{%>qi-9hP2w;t(6)K@iV^Ij>eB$UYN`aah67+5!CF7mqy%0of zX-9$i;y}4G&Vx%DH$6%DZ1GbQ`Dua<v^;Qq%yazstjfTPmb9|WxSNBeCfY`9dzJ{( z(`$xtVpFx*hk+(gFMiW0H3PH-Un=4H<eqE&+*F3W9278sL1NsnojX%23+vUq+P6^k zTPu9Yp^OGKqq)qGQ<wZ<;B+t|T$_&`{#X;1S(zs=Js>_Qnh{Ku=|>+s6)?ADQBm%l z>Y|huD)AC~NApcXEcG;?oT+m1zyl)zNLda>t7Hk>&C1@og;}k?)HQ!*DZf4Ex<a~; zAVLC|N%Jcp<kF&kI;cB3VWbhAan8P1w;&`Xu3-d~ec_&CQ;UuEVK)>~yuh}2P+8i2 z$SldaZ$BS@&6m~%>~(df9Nr&bLS5O0q!rpUi&@>w08-C@#?&{OOh*02(KN?cf<m7g zV~um`^Sf#+_)r*}=7n_@iI0+$7?V~dbxwzeTm|oI@|wKp@1L9YB+RmyIgIV)aTh+~ zhlIkHju=y9#odxF*iFgpQ)&xX@#+#9kj=5XIA&{|S&ZBm!dk490h7}x3r1}e#ZB<M z-)faC%{vgt6zhWf9d@Oxi>%P!)Yr^MgT7zG#y7wkbNpt0+0Fgo82sv`G9+w|qxEf} z_vz}@j^x{J)d5Tv<)R%4rSGP5!ZG0VVeRoJwW=zQ(YU4aK*%lbPNI5n@fy@ELGKj+ z#=wQ%htIFu3{^>;h?szLsYP}~8=c%oDU=ZON8W4Dku}y77(&1vjZbFfl;ju%Nr>bo zJ6I5`<LwslXRvt=Y-U2u0{fB4c^DSIBHUSJTb)8RLw26Et;Sh6D>GgTceTxGhR>@E zR9O^l4oX!#vG)bC_k)*dDK#6*8J8KmVn-v8?wg>-<j{<H8)-Bv0hk8(BgNXVN7VS> zFwNE}GLr%Q*H&0l;KSJF=soNhB6x0%Av9x9za<&bmo^xja3PfzWV5Znu$6rZ?-ypX zJw*L1P_es*Q+_Jaromm3(FZR`p%9YZfmW`woj4O`4|b^W6TwBvf^^2E8fJx}t?WT8 z5yK4-%ZO6){)`B0(<{a-7X)2FM_*g|3{O%VB7PHGkQ2e2UNbiKm2L_gjI)O;)oBUX z3wxYfWrlEkac74{yrOq{*6aqq#gpqsa*3=LMvX=_d-cFZc*JyhzKm|*r=ckp&FP?e z*(`j3Gea{7oW?ooDKNc!%I8K2me<bWcU!D)aifi}cT5i@&QqPFgYJR=j{IK9`gtdS zfpz-;TKJR^r2N@4jqVD2u;8T4xqeU|_a4ys9d<hosO^$Wd_?+-v)mzozcSXJGnwq* zj$Vcjzq1f4Indd!QtG~RA>%~8<B%>YM_W~=#CsUbqgz?frYMhHAzVX%wCA3)qc%lR zV<*`T9h2uvnA+}i4;H<VljMlx?MW&`9}&SZw4_3C)iio|aDU8q&vE8ecZ2WTPGO01 zMltor^@Gdbv=v8GLM-{8#5}U4AjnR6nE01z2=)(D<m;y`1eTXi6oZ{gl-fnfINUJI z*=ob()jArMJd9v<rgLxlDw<rD7O?=Oz^o0%s3?tx#Cv$C_7xyH?UAVnI;2+k4Jh{u zCJX$GU2`rv%QU*5>TuEp1XAvFJDgwzx#0EO2Z;L2OP?PG3ZX>8x;z%R^uaq1p5$M) znX5Tot`y)sS9nt7#ZRmC4g$K@fG49+0xwKG2Lx&EHP&A2Y4+Fg<%G{etf@!(?RhzI zeN!KSly|JZr)^ck$DvG|;0i%oy?$`lrn)fcl-@u8Fg$>O;Qu}q?d)C54eb7$hqD^1 zR@;5ZUbGW$K7h%#-D?Xqu4SL{WFb5(umLnOq#eFQW3?h;m`@q^m+=y3AjB5l5Uea> zo3J!Op^QPCjlayIgLd%P#oh#r9)8vm{%X!k+!+Efm%SW$cHCpB&5FO(YQ>5QcPd+S zH<m%5xZ(I2sw4GytIf*BQ}le1`7orpJKL@Gs_S*Sf~RVwsgkJY-J|ab_+_1bXjMAv z^45iQx94<R%;e)VcD&fQ-?4k#!k#r&wx%uZ-<NBetF&Ak>DDc_Ywcyr#@s))a<H6) zvY##ImsIj<7W8Cv>)$qO-08NH(Eak@*2mF`>}@Zr#3x~8?n3)gz>>N4GCOOt|MOAf z&BdufvDxhYv&d@P_wzoR=Cw98dfv5wQ!@<2ueT!}KdqvUQ#N@^sj7C{6mEc=+i5i> z8LD{Afqs%|>vGB)dmHW-LZYE~nx3OLNCq230h%ys7<1{QF>C6Wx~68JBz&N8P;#Rw zggVYmmKoFbP9uY9!9h(^v49z(9JRtE%$ajxu91qF48wzlvZJ`i#7@5spTok@|F+2^ z2bCy<#gUf`P4Y7+)M(OjFX^$L6DUZcqAPTgx(rro#TTALctUKQeAw-|&p1(sd#cE0 z(Y!ul#|%Hm#!)QtJV?bH+Dem2l38QX<o0TEcF$<D$QTIL6$r?Ozg{J{#ooi|o+L}p zV_eoJ1*yb7m2r#I8zm)G$9TPRyDOyANM1k*8!?#Ri3V<_Bu3)Ox;dTyQW0@g!2ur9 zcM<Oac_)fVHFh#-&AWs;yL8gDsZ|>^SU#oMuzZMWT&dHQ%jza#aY;6&>9pT-oQY~Q z&e+`CyTrkEirOjD-foJvA#OT^*#t}I<j9dRmN~Dumlhy9Z9%t6-fv&Kq4YT>vCXej zLA6?_AS{xaLBrm>HOGly5VT+@^slFw!ykIhYU)xD@&>)=DKzZ$1NM{EtCTeL+9hQR zgwsO(e{~AMUA?@bOD3SH={Fs`cL(&&WfgXr*UjBH2EZKJe~SRD{$d?DmN{7jV&?LL zA0S=yxz^-(H%OzZWtE%Pk-+`WJ40_r3-XQDURg_#dQqD&Tm<5(LV?XTt^l81!kUXg zDs&u{fo^K2h14>r0AflX>)}xAFJDhc^vmD&C*bXW^VKt5)$Pb%7cHM;V!I$Hn^~H} z2PSPNCxSCU84$JS4=5scZS0B*%BUi<b!ijD`ganlw_irbQdet3ir3hv2v*oQLrc`y zECefTL)`8j22+7D3`WlOFv?J&T4bw`7KG>$SQ5z>y0>smuawR{6M?Co^u~silW*PD zzKsWbGNWx0rBoZDN6W2_IHIi*lpGc$EcpVdklnZm!uKiR3a&!GY;cH3w1!Zf78okN z8H+#Gf&@Oj%->XbXi4Zb5pA)^h7G{NWeJqCw2u9|PfhL1R1Ye<WeHeBq_SO|0B(qY zRyBaJPd5c4DKy~PSU(j>XT3xOQMBkxRmHmZC*)bbel07Q*zFE^UjRuZM2^u4ekC6l zIE#~M%E7J$(fTl~?B2j|Hc|)_b)~()H4s?mR$6baAkCTTUdL?U+E%x?MuK3s>dutP zF`>&2AX;X#I6H$7RMsh!m^m<BnR?e2#(kfrpwoXID`Jh91?KsXO8vW;gEpzVgQ0W( zlNS$u;S0QNEVnaEklu4)Chpmmbvp}IrcB>l4?)9M)^2XL$MqnIVU7Z=R(7@NW#8IX z-CkiUcAQlnnD}Pvm88g3r3o|JCP)onUDunw5y!H&?X_=wi3sv~0WS#_J}?qP%OF3& zDPfj<(H#34z$wI4wl?nlN0XH+wIXH8Qx4ad^61);^i{OinFqjH&kT5Fh6$Z{id|DA zJ%-jx^X4oukvH(?>-k892*-vyLInvs-lheIvY_Zfq5`16Ccz00&9_^i{3mb-6?}<< zpD)B;eS-ABe3S|1>O_H!;_&woL*bO30Rr~qWZEV!*}sc2zZHo)DB|4g0{K6}Oyvt| zkvPorHV`Wqc9K+P&O87=)pZ8Da^UksScZnidNs|-LPFL}qmlgH_6}_NA-IZ-Br6|Z zgc@7Z2u_wGX&PD+NvLT=3gb$`7B~opR_7a%GI%|;^h4j(q8z|5GSm3fIpV*cy2oZ% z(Ds5TTx|8`m$C>nkQ$ioQ*4Fkue&zU0NO=%bK;d8eY6ZrPj_?TV?A<n;!P*+@q|aZ z^XSM6C+Xpak80O=!aI)ul{?e$)=6OXdl`6^z{J;Ju#8~bET%M+<)oF`z0Pf&6i+n9 z^KPw?9k%`=_vzaId)LbwKtNxpeC)VEYoT`2EnCW&9Y1VV?@bhlxZ|-&)01qVMs$OF zyv&hqqeXJ(I>6rxtwHiqMYOF0)fXty1nI8sc(}(u7`d_u+=Ue19h&qI7%u_*YbsLl zb5%e#YQeA}_K!AsC}?4Pa|lYfLjGhr$Tf)nY@iKwU_z;+q8me#G9w(4V={U(y72Yx z!w05v@%?;Qkz#cDTZu4^qa7-F4dPTa2y;E_bufqd>Qc_eT&LaU(9%T%XyR5lN54es zjPLscA_+?XpmFi{Opr5T&x8`ARE8$LBtezPnDmCkDhQFH(y*5ZN1@?GERwJY{E9d` zflzEQ%DdgzgyVeWLzQgVdsTe1toj1X#6-ln^8~r9|MODgctTqCZXr1Qnqh7p+dX53 zE7ne%%FpC3S?7>C)#L}g9KyRI!Ga1)958%>{P8hLFa$!+a_o7+`V4W%vFeuw`3?fJ zGlKAv1z_LQ*5M<9;IL;(g30&S6mUdz^S4I;x)O9wW8_vOik|wl#U-}ALPTZ|b3~{y z6^G(Fg6?sYaHIywy|IBM^ycYKKQtm!<7Js(!?uPcDHU(z2#6K+yaJ*XT*xEMQv?c! zWH<q*mORI2xo$U$95>z5KoAd(t$yOUw`SXD+q)+>m!-?QTHG+o=^JSj;nTyLP~7X$ z$Jfnx*<w+j@NX_$yG96HqHdxqpCod=!sRtrg`6MfPoq4xiACzja+M3SbLp^=H2l!x z;yAqaZxsl;v0HvA>7f&q<!OlB0>?tmBxP&wxVlQsq|-c&A^DAWCm}0$kaI!U&6yYE zE-nbe#i+T%i8TwF1so%e81cCd>1a`^FsSdHM{Q?6BhR^-)4yBl*|GdE=R((I0rkRK z>iu8C-HE|LX0FC93+`4SmmYt*@VhTQ?LMXAV$sfxTf}5(ea%v!<1a;n@*nt0uNXfH zLKgT;7KGJxADe>h3uFM01C5{>b|>?W#WI#u9TPZ=o8ircz5<_tA#;82!d8`O%3|*> z{Yu;Zmf}7>>%;?*qwfOE(hq~g>DBnW!Hh)emJG#1HG7%=8PC1V{XB~|wd`2eL>3Hv zom-O=HeVH_Bj%IO;qn`er*mTq^zNeICl}9)=icAlZvg|UI`~BE_m`XVVMb9(QQWGY z&o{rfC+?{0;VqCulA_jFl(f`ov;46JG$|c(0No-y<=m~%sntqELJ`&m>m{u?!L>6e ziVM3&4Ycj;8qY6%-iBZl13ggNpA&j_jc60!oU5H*bE}(P-5+*(f5&B^uXCz!-O~UD zK7Fdwf`bGNbMLJ!a(HuZX?bM>Y_AatG%Mdd4LY0re7>CAI&23usVNInBiY)!JRIFx zY{+3$L*-5JR<E#U<tMpoAljzeOhiV6Ep-zhv0&4040l#h9OT+sXrlY3ey$@{UYic$ z3RU)YR5|?B3zk!aIWWd%0U1g3&Dt-wFVPOrmlWt)^|)nYoJLQ*RsA*0HpC!&;1GJp z=nGIjLCACb5FJs;)EO(!Gta-nQoV!PlBw@$hm3dc8}+{(aAO@?1ATdWTN6v8zx?o@ z%33nh08}rQ3l2sPU&wjj7_!A7KWJ_Y6g)=maoGkEwJ-~UzCvX7TIdjr4zz_X)Sal5 zL2n;5hIY8NlS~iD@e`a?*JWTtN0Zd!%yqVXr`HubE4|t?J5?RA$%ycRzTOZ~1yod~ z;!&d+1$Flu+tW@W8>KccT0@KiZ@_GDn8~zyattw1ijplf(GO}e3h^~lR~nryEiMvF z*rwQImZ?zPy_zX~Mt17mPne3Ru}eQp`+5)ie^eD2u2ECStbnr_>hC0z-?b%X*Uz>V z2|OrEGVCS`&Zn3YPH|au?V=YuAqkA7acVR0FBwpjGwbYwDN$<UfDsiE0xW!H56hWF z&7`0pa)2)vw=y<N?|%5ex%fy#K2x1DESz=pGkMO=^41?fznaHJz##gD!7zrwEm3}M zj^I?_5cTc9iO68gsUI00SVXVjpC!E^RUPggVu(N5VHn>wZd+nDSJU^RUVs&dt`CU! zSQ637Hjd+k*cjL#iz*I01HbG>m~%urA~KIZTD?M8WDWS1hCQe1;bDk9K?g#?1owo% zO4X%#h``$KcJ~Y-aFJu?0tes5WGn<4Uj3|#?l`ZCU{%(Q6zL=gW1&J0j|J8IP=#e~ z4pxUevFrn|RXScQ=RodQvR6}w31X%*1EHd^GM`YC9%x~WPDGq3;vMbMK(BkDK)+?G z1cr1eBP3U;Y91Vhs#Pk!G53lo2UX%MJ71`s-{xMOB|Y_9yEU}tA|)!bbE}_SzP0+X z>Yxy~-hVCCFwAa+Ycwy7a=eTD7)gqgeM_(896oQDC`)q<tUL$v*+&|(I!q73I)a<_ z+`t_v@zY}CJs^HZMQ+%%DZ6m3r}x*dqO08D$Mk|!xLeK`De96g`B6!uSOroxrSvQP zJ{3{ogvMaVz?=h#P_if0oc>L8+bMz4S~&x?bBgxg5y)uKZHS+huxlhbhU0DWsAJP& zs|NctR&GM}kQ{V!F0LN#F7<OS`_vyHaKC4ddmRVLs$%2rfP5)o#N|vE-ucE$Ff-zs zY@O2UXH+@E)v$mKRl&oR5y+ck<Irk{ol!bft}$e(00kSdZlN($VL!$-2;W;9^O(d9 ziHs#N|C1#wZ_-<$1zi(SgI!*uD2OBoF5)0L$Tx|)KHZ<?hqf;nTts|-Y0|XRRnQ>6 z-tJ!Ka8VY?-fdH00jH#4)nmhX2;}3_WWcmcv3IVOHec5n^#k6&*E0Haa)tf-8V-NI zi2h#7e**7z#s&uVcC>#-;{SU1E86^599}V80s({o3H*+9&F6Z}q%VLTA~^#x`2ZNI zo)?=tC*<P3X2xK5mhz|j6zSRwYhsyBCNb1d1*h&U)@j4hCS2I!*^GGFN%tlaWth!S z8NszCZSXM&$*_EJeE%gC^&)qbOW9m&*;h_+m#*7opxkp>)3$#PT2i4fun!CfNd7%2 zj`4pD`k&!us4Uz5W=8cmlYHykzI!C31BSQm<AoxQMq*8>w~9pGVAK9p?>+75(O|xK z|AXG2v&ZlxKYw|tChs&!E2!0$P-jQBy)ZR3hoZ;naOtXn>t=cW0?*<`;_Ys|$q4H; z+|i#79OhnDW|baYTO(=(hmAEx7<5ZOU!dEsd&8)4HW#0GjGe}Q;b?&F`(x*YJCkh3 zCN-9Q?S(qSkJAfY_rzd-{WCga%epIH(G#b6+#ctrglKcu5{s=)BtD*NPnL@3W|1-3 zQw^Q5{?Ox);Q_3sGKv-}y!h9h9&%oYU}1WnFm{?NX?@Y#r%d*}rb!+ft_zNt9HWGt z^=X*?3vViZ11aV)oAJbJPJ%VZ{_OXB)mD3BG0my~=6xkLXEL;eBEneZz02*K`RD0T zi2bw){W}bL*LwoO68<Rjvj=@)X|U83d+updXlmzz?}z}0+Udh&Zx8V!KI6`Bv!=!; zw;Cs=uz%h;HIx$7NglXS%uQh3F@;B2b3T$b6|Jr^*2a`{N-Qx8G}|$Z8kRuN7Gv#{ z>#XX*f4jl-LN*<kSVG*07*F$SCdX_@pFPbAm@y-jv|O5w3@jVRP?ou*7@LggPWNQV zGXkH(P2M82z85#t9rg`(Vl%bFz{gM<0JJrwKN>3Y@R>IIG9aO9l7a>?SQCTdfiDbw z#)GBPvdGmayAvy5jwzNRF_p?Kx}}nLi}Cq}$(rO-$#6~$TrS+!4vTqD1DeEOP10eg zd1VH||7!FtNL=9lgnjqPVJPY-o~Kg&wMqKniM<y+u>9yJHMZI?GDO8L6wkb^f2$c= z*U3-p&D-yhbY9dV_brJ;=32wZs(@i+G1*~cHo0MBa`|CoOod@&XvJaVhxhAHY4{hx z)A5(7@iv0D<1e2k+6X``#9)|1OY=MgU=S=tJ3HaYS;-3UVSBd<x*;i_OglXVZ)dlx zTa-r<+oo)JL@^(%ltMMoM<6I}y@+$-0}o{RP0$tlK7}ggaf*?Z6B-caaH5jSL+8uq zaehTbxkX=8VUlR|jIj~-NQFk=q+!oTA2&#!`g+K;y<@m1<^3T1Js(qpI3416xduWd zKeA=mUK~eNoV9$av4R-;Xe!26KqrdQjx5NH!W_1?FL8;!h(R0|lQg`m&5XDcmt;Z3 zmrJZF1T0OwY9H*|@&nF57+kuT_&5qx`?6U=;I<+^c|?C&SyKR<dy<a?W+R19Kyd_O z`(Wm;fQMJ6HHNQ7TlW(wqZXy+kvq}p<{gN{D}DQiqBe(<LHzhDXNJ~};rnjTtlCK+ zdMH<jUQBdM^lx&Cpv+zFFQpKHP<HZ)phW(^YD;`X{C~BU_|SK)=*@PZbgdZAc7W-e z)|+aF(lw|vorlxiX)vAp(%oq?(Fr6!RbnL*jVNcDZouoDmYQn&(A_C9ok!B$DKk|G zCcBkksSu2KKmc>4sWm=9InI0?vD>WC7x3t_($!{PYzICp=EjlJQkU-~0X34?lWx3u z7F~>kPac@S)ux7vYfjjK%mp^?SX5EuCi8=hyPij&DS*PhgB$f-2$XYt03Y4jqU?(F z`NRqgt-R(n0mkY-HQ}dLbbnb~2*IeIvt6A>wD_X(=JoHrk2)_P(Ca-}odf=NPEbw2 z%F^Dz(q2o!#oEA5<4+8<Tw&PKj}ECt`8N-K1v2YlP6-8m5O<_SUIE_57KzF|$+F9f z$7d*6EG8eaUqFF3BURtl^qXP`ReT)OOBvI9w&{Qp%=%^t;oJAmCgoX2PtRf>=DcC6 zRDLm1wX%%+H@1L@X_Uc}J<AzW7We0CAPHQB(s*-*_eT-W5BXijRMK}*xdiyq1R$<4 z-#3xe<Evw|)CDjpW69}(jTejP=;tpWOVsHF+Zf4ji(9Th8Q=pi(mzWmCZ!u<0d*7= z8X>(-mW284ci6YZF9fNWLg>zPV4J=OexWi#8Y#NLQ_w{m5JrlU3cO_x84o)vwCrf2 zaqw52;=+;TXh++qAa&>iF{l7Lm+PTE(1tg&D8(x;RVyu;?TNKzl7voWsa<02Qq(z2 z{hsXed$LE7q&MI^`4M-<GcJc)8BRqXK(8{c<3-1wE2E~lRas4IWdpRb@*r@m<I(v% z4{ThsEo#^Niu63Xjq8>C!vo3IV$-&?sao-j`v}p5)bbV<AOZZI%l_Z1mfjC6p!W&< z@85saFnt7mEb;k+_!|iKe*0MP^AY{Ag5)3c(fjcJ5Bh)VNj}0q7DfC6SAIWvKa@y( z1b<BG{{x<RH`{mc|B~YW$n!A){twUjds_UR=VLnjBf-a9!9N5L2!9d$lR5YZ{rHvh z4>Sn#Z|KKwo{tP4eXD;M<Z=FD`2TrY9|=GDJ^v6w;eI6i#|!$%@^J_GhXw521N?vN YCjbfXceVeN+`$4(zS~Y6@t>#v0%#Ijd;kCd From 131dad82306d8f2006d16e79e067628d382138b7 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 14:43:05 +0900 Subject: [PATCH 031/159] =?UTF-8?q?=ED=98=84=ED=99=A9=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=85=80=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EC=9E=91=EC=97=85=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 50 ++++++++++++----------------- apps/wr/app/map/newWindowPortal.tsx | 2 +- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 43a122f02..5d724cecf 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -1,24 +1,17 @@ import { useWrStore } from "@/app/store"; -import { btnClass } from "@/app/store/common/code"; import type { customPbnst, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { excelDownload, tableData } from "@/components/lib/func/commom"; import { Title, UiTable, UITab, ContentsDiv, ScrollArea } from '@common/business_components'; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import { Button } from "@common/components/ui"; import React, { useCallback, useState, useEffect } from 'react'; import NewWindowPortal from '@/app/map/newWindowPortal'; -import PbnstPrfmncSttnPopup from "@/app/map/pbnstPrfmncSttnPopup"; import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; import type { chgBuilding, customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import RainPrfmncSttnPopup from "@/app/map/rainPrfmncSttnPopup"; -import RswtrPrfmncsSttnPopup from "@/app/map/rswtrPrfmncSttnPopup"; import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; -import HtdflPrfmncSttnPopup from "@/app/map/htdflPrfmncSttnPopup"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import { getFetch } from "@/components/lib/api"; import { useGisContext } from "@common/business_components/ui/map/Gis"; -import ListDiv from "@common/business_components/ui/list_div"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; interface NewWindowPopupProps { @@ -27,6 +20,7 @@ interface NewWindowPopupProps { checkedLayersData?: any[]; seletectedLayerNm?: string viewMode?: 'list' | 'detail' | 'nothing' + onFeatureSelect: (data: any) => void; onClose: () => void; } @@ -52,6 +46,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ checkedLayers = [], checkedLayersData = [], seletectedLayerNm, + onFeatureSelect, onClose }) => { const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; @@ -127,38 +122,37 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const layerId = getSelectedLayers(); if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); - let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? 'a' : null; + let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설'? selectedVal?.bdst_nm : layerId == '하수처리시설' ? 'a' : null; if (featureCd && featureCd !== fcltPk) { if (layerId == '하수재이용시설') { featureCd = selectedVal?.swtrmt_fclt_cd; setFcltPk(featureCd); // 현재 호출된 featureCd 저장 setActiveTab(featureCd) fetchpbnstDetail(featureCd); // 상세정보 - setViewMode("detail") } else if (layerId == '빗물이용시설') { featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) rainSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setRainDetailModal({ isOpen: true, data: rainSttn.rainSttnRes[0] }); - setViewMode("detail") } else if (layerId == '중수도시설') { featureCd = selectedVal?.bdst_nm; - console.log(featureCd) setFcltPk(featureCd) rswtSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); - setViewMode("detail") } else if (layerId == '온배수시설') { featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) htdflSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); - setViewMode("detail") } - else if(layerId =='하수처리시설') onClose(); + else if(layerId =='하수처리시설') { + + }; + setViewMode("detail") + } } else if (layerId === null && seletectedLayerNm) { setViewMode("list") } }, [featureData]); @@ -173,9 +167,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnstSttn.pbnstSttnRes[index] ) { setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); - fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - setViewMode("detail") + // fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) + onFeatureSelect(pbnstSttn.pbnstSttnRes[index]); + // setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) + // setViewMode("detail") + onClose() } }; const getSelectedLayers = () => { @@ -188,7 +184,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ && typeof featureData.getId === 'function' && source.hasFeature(featureData)) { featureLayer = layer; // 피처가 속한 레이어 찾기) } - console.log('layernm',layer.get('lyrNm')) }); result = featureLayer.get('lyrNm'); @@ -274,8 +269,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ index !== undefined && rainTable !== undefined && headId !== 'chBuildingYn') { - setRainDetailModal({ isOpen: true, data: rainTable[index] }) - setViewMode('detail') + // setRainDetailModal({ isOpen: true, data: rainTable[index] }) + // setViewMode('detail') + onFeatureSelect(rainTable[index]); + onClose(); } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); @@ -365,7 +362,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [code, rswtSttnRes]); // 엑셀 관련 const rswtSttnExcelDownload = useCallback(() => { - console.log('excel', rswtSttn.excelList, rswtrTable) if (rswtSttn.excelList.length > 0) { if (rswtSttn.excelList.length === 0) return; excelDownload( @@ -425,19 +421,15 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [code, pbnstHasuRes]); useEffect(() => { if (!pbnst.isInit) { - pubHasuInit("1", "41"); + pubHasuInit("1", "0"); } }, [pbnst.isInit, pubHasuInit]); useEffect(() => { - pubHasuInit(String(hasuPage), "41"); - }, [hasuPage, pubHasuInit]); + pubHasuInit(String(hasuPage), "0"); + }, [hasuPage]); // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { - // 특정 레이어가 체크되었는지 확인 - const hasWaterTreatmentLayer = checkedLayersData.some(layer => - layer.data?.lyrNm?.includes('하수처리') || layer.data?.lyrNm?.includes('재이용시설') - ); const actTabData = tabData.find((tab) => tab.id === activeTab); let layerId = getSelectedLayers(); if (layerId === null || layerId === undefined) { @@ -462,7 +454,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ </div> {/* 높이 조정 */} <UiTable - tableData={bdstTable || []} + tableData={hasuTable || []} headlist={pubFacHeadList} pageSize={10} total={100000} diff --git a/apps/wr/app/map/newWindowPortal.tsx b/apps/wr/app/map/newWindowPortal.tsx index 51c6d5d8f..6bc1cd047 100644 --- a/apps/wr/app/map/newWindowPortal.tsx +++ b/apps/wr/app/map/newWindowPortal.tsx @@ -48,7 +48,7 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti if (newWindowRef.current && !newWindowRef.current.closed) return; // 1. 새 창을 열고 참조를 저장합니다. - newWindowRef.current = window.open('', title, 'width=1000,height=800,resizable=yes,scrollbars=yes'); + newWindowRef.current = window.open('', title, 'width=900,height=800,resizable=yes,scrollbars=yes'); if (newWindowRef.current) { newWindowRef.current.document.title = title; From ef1643e9da4cb71ac202ac995157136023ef7bb2 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 16:09:01 +0900 Subject: [PATCH 032/159] =?UTF-8?q?=EC=83=81=EC=84=B8=20=EB=82=98=EC=98=A4?= =?UTF-8?q?=EA=B2=8C=20=EC=9A=B0=EC=84=A0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 5d724cecf..e1a26267f 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -167,11 +167,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnstSttn.pbnstSttnRes[index] ) { setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); - // fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - onFeatureSelect(pbnstSttn.pbnstSttnRes[index]); - // setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - // setViewMode("detail") - onClose() + fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) + // onFeatureSelect(pbnstSttn.pbnstSttnRes[index]); + setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) + setViewMode("detail") + // onClose() } }; const getSelectedLayers = () => { @@ -269,10 +269,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ index !== undefined && rainTable !== undefined && headId !== 'chBuildingYn') { - // setRainDetailModal({ isOpen: true, data: rainTable[index] }) - // setViewMode('detail') - onFeatureSelect(rainTable[index]); - onClose(); + setRainDetailModal({ isOpen: true, data: rainTable[index] }) + setViewMode('detail') + // onFeatureSelect(rainTable[index]); + // onClose(); } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); From 46565c1820d541389be69046b626d7b7c23615c7 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 17:23:52 +0900 Subject: [PATCH 033/159] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=EC=97=91=EC=85=80=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=88=98=EC=A0=95=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/rswtSttn/page.tsx | 22 +++--- .../ruseFcltMng/fcltSttn/rswtSttn/excel.tsx | 5 +- .../ruseFcltMng/fcltSttn/rswtSttn/index.tsx | 67 ++++++++++++++----- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index d101200d7..f35efa121 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -38,7 +38,7 @@ export default function RswtSttn() { ); const [pageNation, setPageNation] = useState(1); - const { rswtSttnRes } = rswtSttn; + const { rswtSttnRes, rswtSttnResCount } = rswtSttn; const [isChHead, setIsChHead] = useState(false); const ref = useRef<ReturnType>({} as ReturnType); const [bdstTable, setBdstTable] = useState<customRswtBdst[]>(); @@ -96,7 +96,7 @@ export default function RswtSttn() { useEffect(() => { if (!rswtSttn.isInit) { - rswtSttnInit(1, "20", "0", fcltNm, code.cityCd, code.sggCd); + rswtSttnInit(false, 1, "20", "0", fcltNm, code.cityCd, code.sggCd); } }, [rswtSttn.isInit, rswtSttnInit]); @@ -111,7 +111,7 @@ export default function RswtSttn() { 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]:'확인불가' + archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가' } }) .filter( @@ -137,8 +137,8 @@ export default function RswtSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - rswtSttnSearch(true, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); - }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm]); + rswtSttnSearch(true, pageNation, String(rswtSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm, rswtSttnResCount]); useEffect(() => { rswtSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); @@ -158,7 +158,10 @@ export default function RswtSttn() { label="시도" selectClass={""} selectArray={code.cityCd} - onSelectValue={getSelCity} + onSelectValue={(val) => { + getSelCity(val) + setPageNation(1) + }} /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-4" @@ -166,7 +169,10 @@ export default function RswtSttn() { selectClass={""} selectArray={selectSgg || []} value={objSearch.sgg} // value props 추가 - onSelectValue={getSgg} + onSelectValue={(val) => { + getSgg(val) + setPageNation(1) + }} /> <div className="col-span-2 flex flex-row space-x-2"> <Label className="w-28 mt-2 text-xl text-gray-600"> @@ -225,7 +231,7 @@ export default function RswtSttn() { } headlist={rswtSttn.rswtSttHeadList} pageSize={20} - total={10000} + total={rswtSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} ></UiTable> diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx index d24671ee4..9c3eb4a14 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx @@ -3,13 +3,12 @@ import type { customRswtBdst } from "../../fcltReg/rswtReg"; import { useWrStore } from "@/app/store"; export const excelRSwtSttnParsing = ( - data: customRswtBdst[], + excel: customRswtBdst[], sidoCode: SelectDataType[], sggCode: SelectDataType[] ): string[][] => { const excelExportData: string[][] = []; - - data.forEach((item) => { + excel.data.forEach((item) => { excelExportData.push([ sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index 8f0ac261a..fd38b5bf3 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -1,5 +1,5 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; -import { fetchType, getFetch } from "@/components/lib/api"; +import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api"; import type { z } from "zod"; import type { customRswtBdst } from "../../fcltReg/rswtReg"; import { controlHeadView } from "../rainSttn"; @@ -24,11 +24,12 @@ export type rswtSttnState = { rswtSttNodeList: CommonTableProps[]; excelList: []; isInit: boolean; + rswtSttnResCount: number; }; }; type rswtSttnActions = { - rswtSttnInit: (page: number, total: string, con: string, txt: string, + rswtSttnInit: (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => void; rswtSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string, @@ -48,6 +49,7 @@ export const rswtSttnStateExport: rswtSttnState = { rswtSttnRes: rswtSttnRes, excelList: [], isInit: false, + rswtSttnResCount: 1, }, }; @@ -57,12 +59,11 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( set: any ) => { return { - rswtSttnInit: async (page: number, total: string, con: string, txt: string, + rswtSttnInit: async (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - - const rswtSttnRes = await getFetch( + const rswtSttnRes = await getFetchWithCount( fetchType.WR, `/reuseFc/waterreuseFc` + (page ? `/${page}` : "/1") + @@ -70,16 +71,46 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (con ? `/${con}` : "/0") + (txt ? `/${txt}` : "") ); - set((state: rswtSttnState) => { - return { - ...state, - rswtSttn: { - ...state.rswtSttn, - rswtSttnRes: rswtSttnRes, - isInit: false, - }, - }; - }); + console.log("rswtSttnResㅇㅇ", rswtSttnRes) + if (isExcel) { + const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); + set((state: rswtSttnState) => { + return { + ...state, + rswtSttn: { + ...state.rswtSttn, + excelList: rswtExcel, + rswtSttnResCount: rswtSttnRes.count, + }, + }; + }); + } else + set((state: rswtSttnState) => { + + return { + ...state, + rswtSttn: { + ...state.rswtSttn, + rswtSttnRes: rswtSttnRes.data, + rswtSttnResCount: rswtSttnRes.count, + isInit: false, + }, + }; + }); + // } + + // set((state: rswtSttnState) => { + // return { + // ...state, + // rswtSttn: { + // ...state.rswtSttn, + // rswtSttnRes: rswtSttnRes.data, + // rswtSttnResCount: rswtSttnRes.count, + // excelList: rswtExcel, + // isInit: false, + // }, + // }; + // }); } catch (e) { console.log(e) } @@ -88,7 +119,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - const rswtSttnRes = await getFetch( + const rswtSttnRes = await getFetchWithCount( fetchType.WR, `/reuseFc/waterreuseFc` + (page ? `/${page}` : "/1") + @@ -104,6 +135,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( rswtSttn: { ...state.rswtSttn, excelList: rswtExcel, + rswtSttnResCount: rswtSttnRes.count, }, }; }); @@ -114,7 +146,8 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( ...state, rswtSttn: { ...state.rswtSttn, - rswtSttnRes: rswtSttnRes, + rswtSttnRes: rswtSttnRes.data, + rswtSttnResCount: rswtSttnRes.count, isInit: false, }, }; From 21610c9c9f68fb28080c17a50a6afeec0ac9281a Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 18:31:08 +0900 Subject: [PATCH 034/159] =?UTF-8?q?=EC=9E=A0=EC=9E=AC=EC=88=98=EC=9A=94?= =?UTF-8?q?=EC=B2=98=20=EC=97=91=EC=85=80=20=EB=8B=A4=EC=9A=B4=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wr/app/matMng/coMng/ldrmntCoSttn/page.tsx | 101 +++++++----------- .../app/store/matDmd/ldrmntCoSttn/index.tsx | 88 +++++++++------ .../coReg/coRegExcel/coRegExcelModal.tsx | 35 +++--- 3 files changed, 109 insertions(+), 115 deletions(-) diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx index eb43b29bf..271754938 100644 --- a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -3,11 +3,10 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import { type customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn"; -import { ldrmntHeadListExport, ldrmntNodeListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList"; +import { ldrmntHeadListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList"; import { excelDownload, getCity, - getCityOrSgg, tableData } from "@/components/lib/func/commom"; import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcelModal"; @@ -24,42 +23,62 @@ import { Title, UiModal, UiTable, - type ReturnType, type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button } from "@common/components/ui"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; +import { Toaster } from "react-hot-toast"; export default function LdrmntCoSttn() { const { code, ldrmnt, ldrmntInit, ldrmntSearch, } = useWrStore( (state) => state ); - const { ldrmntRes, excelList } = ldrmnt; + const { ldrmntRes, excelList, ldrmntResCount } = ldrmnt; const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customLdrmnt | undefined }>({ data: undefined, isOpen: false }) const [pageNation, setPageNation] = useState(1); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); const [bdstTable, setBdstTable] = useState<customLdrmnt[]>(); const [searchTxt, setSearchTxt] = useState<string>(); - const ref = useRef<ReturnType>({} as ReturnType); const [excelData, setExcelData] = useState<any[]>(); const [isExcelDownload, setIsExcelDownload] = useState(false); const excelClick = useCallback(() => { excelDownload( [[]], - "잠재수요처 관리", + "잠재수요처 등록양식", "sample_ldrmntCoSttn.xlsx", "A1:AL1", 2 ); }, []); - const excelDownloadClick = () => { - ldrmntSearch(1, "10000", "0", ""); + 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 excelDownloadClick = useCallback(() => { + const cityNm = computeCityNm(); + ldrmntSearch(true, pageNation, String(ldrmntResCount), cityNm, searchTxt || ""); setIsExcelDownload(true); - } + }, [objSearch, pageNation, searchTxt, code, ldrmntSearch, computeCityNm]); useEffect(() => { if (isExcelDownload && excelData && excelData.length > 0) { @@ -141,33 +160,8 @@ export default function LdrmntCoSttn() { }, [excelList]) useEffect(() => { - let cityTxt = '' - let sggTxt = '' - - if (objSearch?.city.toString().length > 0) { - cityTxt = code.cityCd.find((item) => item.val === objSearch?.city)?.text ?? ''; - } - - if (objSearch?.sgg.toString().length > 1) { - sggTxt = code.sggCd.find((item) => item.val === objSearch?.sgg)?.text ?? ''; - } - - if (cityTxt === '전체' || cityTxt === '') { - cityTxt = '0' - } - - let cityNm = "" - - if (sggTxt !== "0") { - cityNm = cityTxt + " " + sggTxt - } else { - cityNm = cityTxt - } - if (cityNm) { - ldrmntSearch(pageNation, '20', cityNm, searchTxt || ""); - } else { - ldrmntSearch(pageNation, '20', '0', searchTxt || ""); - } + const cityNm = computeCityNm(); + ldrmntSearch(false, pageNation, '20', cityNm, searchTxt || ""); }, [pageNation]); return ( @@ -210,32 +204,8 @@ export default function LdrmntCoSttn() { <Button size={"sm"} onClick={(e) => { - - let cityTxt = '' - let sggTxt = '' - - if (objSearch?.city.toString().length > 0) { - cityTxt = code.cityCd.find((item) => item.val === objSearch?.city)?.text ?? ''; - } - - if (objSearch?.sgg.toString().length > 1) { - sggTxt = code.sggCd.find((item) => item.val === objSearch?.sgg)?.text ?? ''; - } - - if (cityTxt === '전체' || cityTxt === '') { - cityTxt = '0' - } - - let cityNm = "" - - if (sggTxt !== "0") { - cityNm = cityTxt + " " + sggTxt - } else { - cityNm = cityTxt - } - if (cityNm) { - ldrmntSearch(pageNation, '20', cityNm, searchTxt || ""); - } + const cityNm = computeCityNm(); + ldrmntSearch(false, pageNation, '20', cityNm, searchTxt || ""); }} > 조회 @@ -273,7 +243,7 @@ export default function LdrmntCoSttn() { <div className="overflow-x-auto"> <ListDiv className="min-w-max"> <UiTable - headName={[]} + headName={undefined} tableData={bdstTable || []} headlist={ldrmntHeadListExport} pageSize={20} @@ -299,8 +269,9 @@ export default function LdrmntCoSttn() { setIsExcelOpen({ isModal: !isExcelOpen.isModal }) }} bodyClass={"w-[40vw] max-w-none"} - body={<CoRegExcel />} + body={<CoRegExcel isModal={(isOpen) => setIsExcelOpen({ isModal: isOpen })} />} /> + <Toaster position="top-center"></Toaster> </div> diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx index 6a5f18247..734aca547 100644 --- a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx @@ -1,5 +1,5 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; -import { deleteFectch, fetchType, getFetch, postFectch, putFectch } from "@/components/lib/api"; +import { deleteFectch, fetchType, getFetch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api"; import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { z } from "zod"; import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg"; @@ -20,6 +20,8 @@ export type ldrmntState = { excelList: ExcelType[]; isInit: boolean; ldrmntRes: customLdrmnt[]; + isLoading: boolean; + ldrmntResCount: number; }; }; @@ -32,9 +34,10 @@ const excelDownList: ExcelType[] = []; type ldrmntActions = { ldrmntRegData: (data: any[]) => void, ldrmntInit: (con: string) => void - ldrmntSearch: (page: number, sggCd: string, total: string, coNm: string) => void; + ldrmntSearch: (isExcel:boolean, page: number, sggCd: string, total: string, coNm: string) => void; ldrmntUpdate: (ldrmntRes: customLdrmnt) => void; ldrmntDelete: () => void; + loadingOpen: (isOpen: boolean) => void }; export type ldrmntType = ldrmntState & ldrmntActions; @@ -46,6 +49,8 @@ export const ldrmntStateExport: ldrmntState = { excelList: [], isInit: false, ldrmntRes: ldrmntRes, + isLoading: false, + ldrmntResCount: 1, }, }; @@ -75,33 +80,32 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( console.log(e) } }, - ldrmntRegData: async (data) => { - try { - const response = await postFectch( - "/reuseFc/request/temp", - data, - fetchType.WR - ); - - console.log('response ', response) - - if (response.status === 200) { - ToastFormUi({ - body: "잠재수요처 등록이 완료되었습니다. ", - title: "잠재수요처 등록", - }); - - } - } catch (e) { - console.log(e) - ToastFormUi({ - body: "잠재수요처 등록이 실패하였습니다. ", - title: "잠재수요처 등록", - }); - - } + loadingOpen: (isOpen) => { + return set((state: ldrmntState) => { + return { + ...state, + ldrmnt: { + ...state.ldrmnt, + isLoading: isOpen, + }, + }; + }); }, - ldrmntSearch: async (page: number, total: string, sggCd: string, coNm: string) => { + ldrmntRegData: async (data) => { + await deleteFectch( + `/reuseFc/request/temp`, + ); + + const response = await postFectch( + "/reuseFc/request/temp", + data, + fetchType.WR + ); + + console.log('response ', response) + + }, + ldrmntSearch: async (isExcel:boolean, page: number, total: string, sggCd: string, coNm: string) => { let searchUrl = ""; if (sggCd !== "") { @@ -112,14 +116,14 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( } } try { - const ldrmntRes = await getFetch( + const ldrmntRes = await getFetchWithCount( fetchType.WR, searchUrl ); - if (Number(total) > 5000) { + if (isExcel) { let excelDownList: ExcelType[] = []; - ldrmntRes.forEach((item: customLdrmnt) => { + ldrmntRes.data.forEach((item: customLdrmnt) => { excelDownList.push({ ctpvCd: item.ctpvCd, sggCd: item.sggCd, @@ -146,7 +150,8 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( ...state, ldrmnt: { ...state.ldrmnt, - ldrmntRes: ldrmntRes, + ldrmntRes: ldrmntRes.data, + ldrmntResCount: ldrmntRes.count, isInit: false, }, }; @@ -178,11 +183,30 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( }, ldrmntDelete: async () => { try { + set((state: ldrmntState) => { + return { + ...state, + ldrmnt: { + ...state.ldrmnt, + isLoading: true, + }, + }; + }); const response = await deleteFectch( `/reuseFc/request/temp`, ); } catch (error) { + console.log("error", error) + set((state: ldrmntState) => { + return { + ...state, + ldrmnt: { + ...state.ldrmnt, + isLoading: false, + }, + }; + }); console.error("Error ldrmntDelete:", error); } }, diff --git a/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx b/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx index 89f15a3cc..36645003e 100644 --- a/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx +++ b/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx @@ -4,32 +4,32 @@ import type { customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn"; import { names } from "@/app/store/matDmd/ldrmntCoSttn/excel"; import { filePicked, FileUpload, FormUi, Title } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; +import LoadingOverlay from "@common/business_components/ui/loadingBar"; import { Button, Progress } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; +import toast from "react-hot-toast"; import type { z } from "zod"; -export default function CoRegExcel() { - - +export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => void }) { + const { ldrmnt,loadingOpen } = useWrStore((state) => state); + const { isLoading } = ldrmnt; const form = useForm<z.infer<typeof coRegExcel>>({ resolver: zodResolver(coRegExcel), }); const { ldrmntRegData, ldrmntDelete } = useWrStore((state) => state); const [excelData, setExcelData] = useState<customLdrmnt[]>(); - const [file, setFiles] = useState<File | undefined>(); const onSubmit = (values: z.infer<typeof coRegExcel>) => { - ldrmntDelete(); + loadingOpen(true); if (file) { - filePicked(file, 0).then((res) => { - //TODO:loading + filePicked(file, 0).then(async (res) => { + try { let array: { [key: string]: string | number }[] = [] - let isError = false; if (Array.isArray(res)) { res.some((item, index) => { let object: { [key: string]: string | number } = {} @@ -43,26 +43,24 @@ export default function CoRegExcel() { } return false; }) - if (isError === true) - return true; + array.push(object) - if (index != 0 && index % 5000 == 0) { - ldrmntRegData(array); - array = [] - array.length = 0; - } return false; }) } - if (isError === false) - ldrmntRegData(array); + await ldrmntRegData(array); + isModal(false); + loadingOpen(false); + toast.success(`잠재수요처 등록이 완료되었습니다.`); } catch (e) { console.log(e) + loadingOpen(false); alert(e) return true; } - + }).catch((e)=>{ + console.log("file", e); }); }; } @@ -70,6 +68,7 @@ export default function CoRegExcel() { return ( <> <div> + <LoadingOverlay isLoading={isLoading}></LoadingOverlay> <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)}> <div> From 657361a1413e61317d0b6d515fb494c2959a5541 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 18:44:45 +0900 Subject: [PATCH 035/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=20=EC=97=91=EC=85=80=20?= =?UTF-8?q?=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=B2=98=EB=A6=AC=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/htdflSttn/page.tsx | 20 ++-- .../ruseFcltMng/fcltSttn/rainSttn/page.tsx | 24 +++-- .../ruseFcltMng/fcltSttn/htdflSttn/excel.tsx | 4 +- .../ruseFcltMng/fcltSttn/htdflSttn/index.tsx | 64 ++++++++----- .../ruseFcltMng/fcltSttn/rainSttn/excel.tsx | 4 +- .../ruseFcltMng/fcltSttn/rainSttn/index.tsx | 93 +++++++++++-------- .../ruseFcltMng/fcltSttn/rswtSttn/index.tsx | 15 --- 7 files changed, 129 insertions(+), 95 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index b943e8b4f..344234af5 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -39,7 +39,7 @@ export default function HtdflSttn() { const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore( (state) => state ); - const { htdflSttnRes } = htdflSttn; + const { htdflSttnRes, htdflSttnResCount } = htdflSttn; const ref = useRef<ReturnType>({} as ReturnType); @@ -61,8 +61,8 @@ export default function HtdflSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - htdflSttnSearch(true, 1, "20", String(con), fcltNm, code.cityCd, code.sggCd); - }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd]); + htdflSttnSearch(true, pageNation, String(htdflSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm, htdflSttnResCount]); useEffect(() => { htdflSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); @@ -120,7 +120,7 @@ export default function HtdflSttn() { useEffect(() => { if (!htdflSttn.isInit) { - initHtdfl(1, "20", "0", fcltNm, code.cityCd, code.sggCd); + initHtdfl(false, 1, "20", "0", fcltNm, code.cityCd, code.sggCd); } }, [htdflSttn.isInit, initHtdfl]); @@ -152,7 +152,10 @@ export default function HtdflSttn() { label="시도" selectClass={""} selectArray={code.cityCd} - onSelectValue={getSelCity} + onSelectValue={(val) => { + getSelCity(val) + setPageNation(1) + }} /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-4" @@ -160,7 +163,10 @@ export default function HtdflSttn() { selectClass={""} selectArray={selectSgg || []} value={objSearch.sgg} // value props 추가 - onSelectValue={getSgg} + onSelectValue={(val) => { + getSgg(val) + setPageNation(1) + }} /> <div className="col-span-2 flex flex-row space-x-2"> <Label className="w-28 mt-2 text-xl text-gray-600"> @@ -219,7 +225,7 @@ export default function HtdflSttn() { } headlist={htdflSttn.htdflSttHeadList} pageSize={20} - total={100000} + total={htdflSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId); }} diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx index 0b6dffe07..27d7dfa94 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -39,7 +39,7 @@ export default function RainSttn() { const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( (state) => state ); - const { rainSttnRes } = rainSttn; + const { rainSttnRes, rainSttnResCount } = rainSttn; const ref = useRef<ReturnType>({} as ReturnType); const [pageNation, setPageNation] = useState(1); @@ -96,7 +96,7 @@ export default function RainSttn() { useEffect(() => { if (!rainSttn.isInit) { - rainSttnInit(1, "20", "0", fcltNm, code.cityCd, code.sggCd); + rainSttnInit(false, 1, "20", "0", fcltNm, code.cityCd, code.sggCd); } }, [rainSttn.isInit, rainSttnInit]); @@ -132,7 +132,7 @@ export default function RainSttn() { }, [code, rainSttnRes, rainSttn.rainSttHeadList]); useEffect(() => { - rainSttnSearch(pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + rainSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); }, [pageNation]); useEffect(() => { @@ -150,8 +150,8 @@ export default function RainSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - rainSttnSearch(1, "10000", String(con), fcltNm, code.cityCd, code.sggCd); - }, [rainSttnSearch, objSearch, code.cityCd, code.sggCd]); + rainSttnSearch(true, pageNation, String(rainSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + }, [rainSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm, rainSttnResCount]); return ( <> @@ -167,7 +167,10 @@ export default function RainSttn() { label="시도" selectClass={""} selectArray={code.cityCd} - onSelectValue={getSelCity} + onSelectValue={(val) => { + getSelCity(val) + setPageNation(1) + }} /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-4" @@ -175,7 +178,10 @@ export default function RainSttn() { selectClass={""} selectArray={selectSgg || []} value={objSearch.sgg} // value props 추가 - onSelectValue={getSgg} + onSelectValue={(val) => { + getSgg(val) + setPageNation(1) + }} /> <div className="col-span-2 flex flex-row space-x-2"> <Label className="w-28 mt-2 text-xl text-gray-600"> @@ -197,7 +203,7 @@ export default function RainSttn() { size={"sm"} onClick={() => { const con = getConValue(); - rainSttnSearch(pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + rainSttnSearch(false, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); }} > 조회 @@ -234,7 +240,7 @@ export default function RainSttn() { } headlist={rainSttn.rainSttHeadList} pageSize={20} - total={100000} + total={rainSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} ></UiTable> diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx index 591623911..1ae5f56cc 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx @@ -2,13 +2,13 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customHtdflBdst } from "../../fcltReg/htdflReg"; export const excelHtdflSttnParsing = ( - data: customHtdflBdst[], + excel: customHtdflBdst[], sidoCode: SelectDataType[], sggCode: SelectDataType[] ): string[][] => { const excelExportData: string[][] = []; - data.forEach((item) => { + excel.data.forEach((item) => { excelExportData.push([ sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx index 229b4fe2a..29f68a6d6 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx @@ -4,7 +4,7 @@ import type { sttnHeadListType } from "../rainSttn/headList"; import type { z } from "zod"; import { controlHeadView } from "../rainSttn"; import type { customHtdflBdst } from "../../fcltReg/htdflReg"; -import { fetchType, getFetch } from "@/components/lib/api"; +import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api"; import type { SelectDataType } from "@common/business_components/ui"; import { excelHtdflSttnParsing } from "./excel"; @@ -18,16 +18,16 @@ export type htdflSttnState = { htdflSttNodeList: CommonTableProps[]; htdflSttnRes: customHtdflBdst[] excelList: []; - + htdflSttnResCount: number; }; }; type htdflSttnActions = { - initHtdfl: (page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; - htdflSttnSearch: (isExcel:boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + initHtdfl: (isExcel: boolean, page: number, total: string, con: string, txt: string, + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => void; + htdflSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string, + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => void; htdflChSttnHead: ( headList: z.infer<typeof sttnHeadListType>, ) => void; @@ -42,12 +42,13 @@ export const htdflSttnStateExport: htdflSttnState = { htdflSttnRes: [], excelList: [], isInit: false, + htdflSttnResCount: 1, }, }; const initFetch = async (page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { - const htdflRes = await getFetch( + const htdflRes = await getFetchWithCount( "wr", `/drain/facilityList` + (page ? `/${page}` : "/1") + @@ -63,30 +64,45 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( set: any ) => { return { - initHtdfl: async (page: number, total: string, con: string, txt: string, + initHtdfl: async (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { const htdflSttnRes = await initFetch(page, total, con, txt, sidoCode, sggCode); - set((state: htdflSttnState) => { - return { - ...state, - htdflSttn: { - ...state.htdflSttn, - htdflSttnRes: htdflSttnRes, - isInit: false, - }, - }; - }); + if (isExcel) { + const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode); + set((state: htdflSttnState) => { + return { + ...state, + htdflSttn: { + ...state.htdflSttn, + excelList: htdflExcel, + htdflSttnResCount: htdflSttnRes.count + }, + }; + }); + } else { + set((state: htdflSttnState) => { + return { + ...state, + htdflSttn: { + ...state.htdflSttn, + htdflSttnRes: htdflSttnRes.data, + htdflSttnResCount: htdflSttnRes.count, + isInit: false, + }, + }; + }); + } } catch (error) { console.log(error); } }, - htdflSttnSearch: async (isExcel:boolean, page: number, total: string, con: string, txt: string, + htdflSttnSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - const htdflSttnRes = await getFetch( + const htdflSttnRes = await getFetchWithCount( fetchType.WR, `/drain/facilityList` + (page ? `/${page}` : "/1") + @@ -103,6 +119,7 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( htdflSttn: { ...state.htdflSttn, excelList: htdflExcel, + htdflSttnResCount: htdflSttnRes.count }, }; }); @@ -112,7 +129,8 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( ...state, htdflSttn: { ...state.htdflSttn, - htdflSttnRes: htdflSttnRes, + htdflSttnRes: htdflSttnRes.data, + htdflSttnResCount: htdflSttnRes.count, isInit: false, }, }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx index 13530a81f..d2e39aa28 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx @@ -2,13 +2,13 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customRainBdst } from "../../fcltReg/rainReg"; export const excelRainSttnParsing = ( - data: customRainBdst[], + excel: customRainBdst[], sidoCode: SelectDataType[], sggCode: SelectDataType[] ): string[][] => { const excelExportData: string[][] = []; - data.forEach((item) => { + excel.data.forEach((item) => { excelExportData.push([ sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx index eb2c08d37..3ad7090ec 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx @@ -1,5 +1,5 @@ import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; -import { fetchType, getFetch } from "@/components/lib/api"; +import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api"; import { type customRainBdst, } from "../../fcltReg/rainReg"; @@ -96,15 +96,16 @@ export type rainSttnState = { rainChkRes: rainChkZodType excelList: []; isInit: boolean; + rainSttnResCount: number; }; }; type rainSttnActions = { - rainSttnInit: (page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void - rainSttnSearch: (page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + rainSttnInit: (isExcel: boolean, page: number, total: string, con: string, txt: string, + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => void + rainSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string, + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => void; rainChSttnHead: ( headList: z.infer<typeof sttnHeadListType>, ) => void; @@ -123,6 +124,7 @@ export const rainSttnStateExport: rainSttnState = { rainChkRes: rainChkRes, excelList: [], isInit: false, + rainSttnResCount: 1, }, }; @@ -130,12 +132,12 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( set: any ) => { return { - rainSttnInit: async (page: number, total: string, con: string, txt: string, + rainSttnInit: async (isExcel: boolean, page: number, total: string, con: string, txt: string, sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - const rainSttnRes = await getFetch( + const rainSttnRes = await getFetchWithCount( fetchType.WR, `/reuseFc/rainyInfoList` + (page ? `/${page}` : "/1") + @@ -143,33 +145,7 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( (con ? `/${con}` : "/0") + (txt ? `/${txt}` : "") ); - set((state: rainSttnState) => { - return { - ...state, - rainSttn: { - ...state.rainSttn, - rainSttnRes: rainSttnRes, - isInit: false, - }, - }; - }); - } catch (e) { - console.log(e) - } - }, - rainSttnSearch: async (page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { - try { - const rainSttnRes = await getFetch( - fetchType.WR, - `/reuseFc/rainyInfoList` + - (page ? `/${page}` : "/1") + - (total ? `/${total}` : "/20") + - (con ? `/${con}` : "/0") + - (txt ? `/${txt}` : "") - ); - if (Number(total) > 9000) { + if (isExcel) { const rainExcel = excelRainSttnParsing(rainSttnRes, sidoCode, sggCode); set((state: rainSttnState) => { return { @@ -177,6 +153,48 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( rainSttn: { ...state.rainSttn, excelList: rainExcel, + rainSttnResCount: rainSttnRes.count, + }, + }; + }); + } else { + set((state: rainSttnState) => { + return { + ...state, + rainSttn: { + ...state.rainSttn, + rainSttnRes: rainSttnRes.data, + rainSttnResCount: rainSttnRes.count, + isInit: false, + }, + }; + }); + } + } catch (e) { + console.log(e) + } + }, + rainSttnSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string, + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => { + try { + const rainSttnRes = await getFetchWithCount( + fetchType.WR, + `/reuseFc/rainyInfoList` + + (page ? `/${page}` : "/1") + + (total ? `/${total}` : "/20") + + (con ? `/${con}` : "/0") + + (txt ? `/${txt}` : "") + ); + if (isExcel) { + const rainExcel = excelRainSttnParsing(rainSttnRes, sidoCode, sggCode); + set((state: rainSttnState) => { + return { + ...state, + rainSttn: { + ...state.rainSttn, + excelList: rainExcel, + rainSttnResCount: rainSttnRes.count, }, }; }); @@ -186,7 +204,8 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( ...state, rainSttn: { ...state.rainSttn, - rainSttnRes: rainSttnRes, + rainSttnRes: rainSttnRes.data, + rainSttnResCount: rainSttnRes.count, isInit: false, }, }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index fd38b5bf3..716b4d517 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -71,7 +71,6 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (con ? `/${con}` : "/0") + (txt ? `/${txt}` : "") ); - console.log("rswtSttnResㅇㅇ", rswtSttnRes) if (isExcel) { const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); set((state: rswtSttnState) => { @@ -97,20 +96,6 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( }, }; }); - // } - - // set((state: rswtSttnState) => { - // return { - // ...state, - // rswtSttn: { - // ...state.rswtSttn, - // rswtSttnRes: rswtSttnRes.data, - // rswtSttnResCount: rswtSttnRes.count, - // excelList: rswtExcel, - // isInit: false, - // }, - // }; - // }); } catch (e) { console.log(e) } From 13ac6d638b5b07927698b7533880d0c90dd6e2e0 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Tue, 8 Jul 2025 19:18:41 +0900 Subject: [PATCH 036/159] =?UTF-8?q?[apps/cs]=20feat:=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EC=9D=B4=EB=A0=A5=20=EB=B3=B4=EA=B8=B0?= =?UTF-8?q?=20=EB=B0=8F=20=EB=90=98=EB=8F=8C=EB=A6=AC=EA=B8=B0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/management-authority-dialog.tsx | 1 - .../pages/menu/api/menu-history-service.ts | 28 +++ .../pages/menu/model/menu-history-columns.tsx | 71 ++++++++ .../menu/model/menu-history-interface.ts | 30 ++++ apps/cs/src/pages/menu/ui/menu-form.tsx | 44 +++-- .../src/pages/menu/ui/menu-history-dialog.tsx | 162 ++++++++++++++++++ apps/cs/src/shared/config/api.ts | 1 + 7 files changed, 317 insertions(+), 20 deletions(-) create mode 100644 apps/cs/src/pages/menu/api/menu-history-service.ts create mode 100644 apps/cs/src/pages/menu/model/menu-history-columns.tsx create mode 100644 apps/cs/src/pages/menu/model/menu-history-interface.ts create mode 100644 apps/cs/src/pages/menu/ui/menu-history-dialog.tsx diff --git a/apps/cs/src/entities/menu-authority/ui/management-authority-dialog.tsx b/apps/cs/src/entities/menu-authority/ui/management-authority-dialog.tsx index a9ba18333..1a6bc08ce 100644 --- a/apps/cs/src/entities/menu-authority/ui/management-authority-dialog.tsx +++ b/apps/cs/src/entities/menu-authority/ui/management-authority-dialog.tsx @@ -74,7 +74,6 @@ function ManagementAuthorityDialog({ menuCd }: ManagementAuthorityDialogProps) { <Dialog open={open} onOpenChange={setOpen}> <DialogTrigger asChild> <Button className="gap-3" disabled={!menuCd}> - <i className="diveicon di-personal-information" /> 권한관리 </Button> </DialogTrigger> diff --git a/apps/cs/src/pages/menu/api/menu-history-service.ts b/apps/cs/src/pages/menu/api/menu-history-service.ts new file mode 100644 index 000000000..ecb31878b --- /dev/null +++ b/apps/cs/src/pages/menu/api/menu-history-service.ts @@ -0,0 +1,28 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import type { PageableList } from "@/shared/model"; +import type { + MenuHistory, + MenuHistorySearchParams, + MenuHistoryService, +} from "../model/menu-history-interface"; + +export class MenuHistoryApiService implements MenuHistoryService { + public async getMenuHistoryList( + params: MenuHistorySearchParams, + ): Promise<PageableList<MenuHistory>> { + const response = await client.get<PageableList<MenuHistory>>( + `${ENDPOINT.CMS_SERVICE.MENU_HISTORY}`, + { params }, + ); + return response.data; + } + + public async rollbackMenu(hstrySn: number): Promise<void> { + await client.post(`${ENDPOINT.CMS_SERVICE.MENU_HISTORY}/rollback`, { + hstrySn, + }); + } +} + +export const MenuHistoryApi = new MenuHistoryApiService(); diff --git a/apps/cs/src/pages/menu/model/menu-history-columns.tsx b/apps/cs/src/pages/menu/model/menu-history-columns.tsx new file mode 100644 index 000000000..b542e0ff7 --- /dev/null +++ b/apps/cs/src/pages/menu/model/menu-history-columns.tsx @@ -0,0 +1,71 @@ +import type { ColumnDef } from "@tanstack/react-table"; +import { Checkbox } from "@common/components"; +import type { MenuHistory } from "./menu-history-interface"; +import dayjs from "dayjs"; + +export const columns: ColumnDef<MenuHistory>[] = [ + { + id: "select", + cell: ({ row }) => ( + <Checkbox + checked={row.getIsSelected()} + onCheckedChange={(value) => row.toggleSelected(!!value)} + aria-label="행 선택" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "chgTypeNm", + header: "이력구분", + meta: { + width: 80, + }, + }, + { + accessorKey: "menuKornNm", + header: "메뉴명", + meta: { + width: 100, + }, + }, + { + accessorKey: "bchgData", + header: "이전 데이터", + cell: ({ row }) => { + const parsed = JSON.parse(row.original.bchgData); + const stringified = JSON.stringify(parsed, null, 2); + return <pre className="break-all text-left">{stringified}</pre>; + }, + meta: { + width: 250, + }, + }, + { + accessorKey: "achgData", + header: "변경 데이터", + cell: ({ row }) => { + const parsed = JSON.parse(row.original.achgData); + const stringified = JSON.stringify(parsed, null, 2); + return <pre className="break-all text-left">{stringified}</pre>; + }, + meta: { + width: 250, + }, + }, + { + accessorKey: "regDt", + header: "변경일시", + cell: ({ row }) => { + return dayjs(row.original.regDt).format("YYYY-MM-DD HH:mm:ss"); + }, + }, + { + accessorKey: "rgtrNm", + header: "변경자", + meta: { + width: 80, + }, + }, +]; diff --git a/apps/cs/src/pages/menu/model/menu-history-interface.ts b/apps/cs/src/pages/menu/model/menu-history-interface.ts new file mode 100644 index 000000000..e3e35446d --- /dev/null +++ b/apps/cs/src/pages/menu/model/menu-history-interface.ts @@ -0,0 +1,30 @@ +import type { PageableParams, PageableList } from "@/shared/model"; + +export interface MenuHistorySearchParams extends PageableParams { + keyword?: string; + searchType?: string; + menuCd?: number; + chgTypeCd?: string; + startDt?: string; + endDt?: string; +} + +export interface MenuHistory { + hstrySn: number; + menuCd: number; + chgTypeCd: string; + chgTypeNm: string; + bchgData: string; + achgData: string; + rgtr: string; + regDt: string; + rgtrNm: string; + menuKornNm: string; +} + +export interface MenuHistoryService { + getMenuHistoryList: ( + params: MenuHistorySearchParams, + ) => Promise<PageableList<MenuHistory>>; + rollbackMenu: (hstrySn: number) => Promise<void>; +} diff --git a/apps/cs/src/pages/menu/ui/menu-form.tsx b/apps/cs/src/pages/menu/ui/menu-form.tsx index f1400a369..43331067e 100644 --- a/apps/cs/src/pages/menu/ui/menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/menu-form.tsx @@ -1,14 +1,15 @@ +import { useQuery } from "@tanstack/react-query"; import type { UseFormReturn } from "react-hook-form"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { Button } from "@common/components"; import { MenuApi, menuFormSchema, type MenuFormData } from "@/entities/menu"; import { ManagementAuthorityDialog } from "@/entities/menu-authority"; import { Form } from "@/shared/ui/form"; +import { ENDPOINT } from "@/shared/config"; +import { useAlertStore, useMutationWrapper } from "@/shared/lib"; import { BaseMenuForm } from "./base-menu-form"; import { TypeMenuForm } from "./type-menu-form"; -import { useAlertStore, useMutationWrapper } from "@/shared/lib"; -import { ENDPOINT } from "@/shared/config"; -import { useQuery } from "@tanstack/react-query"; +import { MenuHistoryDialog } from "./menu-history-dialog"; interface MenuFormProps { form: UseFormReturn<MenuFormData>; @@ -103,22 +104,7 @@ function MenuForm({ {isModifyMode ? "메뉴 수정" : "메뉴 등록"} </h3> <div className="flex items-center gap-2"> - <Button - color="white" - type="button" - disabled={!isModifyMode} - onClick={handleLoadTemporaryData} - > - 불러오기 - </Button> - <Button - color="gray" - type="button" - disabled={!isModifyMode} - onClick={handleMenuTemporaryStorage} - > - 임시저장 - </Button> + <MenuHistoryDialog menuCd={menuCd} /> <ManagementAuthorityDialog menuCd={menuCd} /> </div> </div> @@ -128,6 +114,26 @@ function MenuForm({ </div> </div> <div className="flex justify-center gap-4 pb-12 pt-10"> + {isModifyMode && ( + <Button + size="lg" + color="white" + type="button" + onClick={handleLoadTemporaryData} + > + 불러오기 + </Button> + )} + {isModifyMode && ( + <Button + size="lg" + color="gray" + type="button" + onClick={handleMenuTemporaryStorage} + > + 임시저장 + </Button> + )} <Button size="lg" type="submit" disabled={isSubmitDisabled}> 저장 </Button> diff --git a/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx b/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx new file mode 100644 index 000000000..7a81ad002 --- /dev/null +++ b/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx @@ -0,0 +1,162 @@ +import { useEffect, useState } from "react"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { + getCoreRowModel, + type PaginationState, + type RowSelectionState, +} from "@tanstack/react-table"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { + Button, + Dialog, + DialogClose, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, + Input, + Label, +} from "@common/components"; +import { ENDPOINT } from "@/shared/config"; +import { useAlertStore, useDataTable, useMutationWrapper } from "@/shared/lib"; +import { MenuHistoryApi } from "../api/menu-history-service"; +import type { MenuHistorySearchParams } from "../model/menu-history-interface"; +import { columns } from "../model/menu-history-columns"; + +type MenuHistoryDialogProps = { + menuCd?: number; +} & React.ComponentProps<typeof Dialog>; + +function MenuHistoryDialog({ menuCd }: MenuHistoryDialogProps) { + const { confirm } = useConfirm(); + const queryClient = useQueryClient(); + const alert = useAlertStore((state) => state.setMessage); + + const [open, setOpen] = useState(false); + const [pagination, setPagination] = useState<PaginationState>({ + pageIndex: 0, + pageSize: 10, + }); + const [searchParams, setSearchParams] = useState<MenuHistorySearchParams>({ + keyword: "", + searchType: "menuKornNm", + }); + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); + const selectedHistoryId = parseInt(Object.keys(rowSelection)[0] ?? "0"); + + const query = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENU_HISTORY, pagination], + queryFn: () => + MenuHistoryApi.getMenuHistoryList({ + ...searchParams, + menuCd, + page: pagination.pageIndex, + size: pagination.pageSize, + }), + enabled: !!menuCd && open, + }); + + const { mutateAsync: rollbackMenu } = useMutationWrapper({ + mutationFn: (hstrySn: number) => MenuHistoryApi.rollbackMenu(hstrySn), + onSuccess: () => { + alert("메뉴가 성공적으로 복원되었습니다."); + queryClient.invalidateQueries({ + queryKey: [ENDPOINT.CMS_SERVICE.MENUS], + }); + setOpen(false); + }, + }); + + const handleRollback = async (hstrySn: number) => { + if (!(await confirm("메뉴를 '이전 데이터'로 되돌리시겠습니까?"))) return; + await rollbackMenu(hstrySn); + }; + + const { tableComponent } = useDataTable({ + query, + tableOptions: { + columns, + state: { pagination, rowSelection }, + manualPagination: true, + enableRowSelection: true, + enableMultiRowSelection: false, + onPaginationChange: setPagination, + onRowSelectionChange: setRowSelection, + getCoreRowModel: getCoreRowModel(), + getRowId: (row) => row.hstrySn.toString(), + }, + dataTableOptions: { + viewPagination: true, + }, + }); + + const handleSearch = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + e.stopPropagation(); + query.refetch(); + }; + + useEffect(() => { + if (open) { + setSearchParams({ + ...searchParams, + keyword: "", + }); + setPagination({ + ...pagination, + pageIndex: 0, + }); + setRowSelection({}); + } + }, [open]); + + return ( + <Dialog open={open} onOpenChange={setOpen}> + <DialogTrigger asChild> + <Button color="white" disabled={!menuCd}> + 이력보기 + </Button> + </DialogTrigger> + <DialogContent className="max-w-[100rem]" aria-describedby={undefined}> + <DialogHeader> + <DialogTitle>메뉴 이력 관리</DialogTitle> + </DialogHeader> + + <form onSubmit={handleSearch}> + <div className="mb-4 flex items-center gap-2"> + <Label>메뉴명</Label> + <Input + placeholder="검색어를 입력하세요" + value={searchParams.keyword ?? ""} + onChange={(e) => + setSearchParams({ ...searchParams, keyword: e.target.value }) + } + className="w-[36rem]" + /> + <Button type="submit">조회</Button> + </div> + </form> + + <div className="max-h-[56rem] overflow-auto">{tableComponent}</div> + + <DialogFooter className="!justify-center"> + <DialogClose asChild> + <Button size="lg" color="white"> + 닫기 + </Button> + </DialogClose> + <Button + size="lg" + onClick={() => handleRollback(selectedHistoryId)} + disabled={!selectedHistoryId} + > + 되돌리기 + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ); +} + +export { MenuHistoryDialog }; diff --git a/apps/cs/src/shared/config/api.ts b/apps/cs/src/shared/config/api.ts index 28dac3d20..7001b97aa 100644 --- a/apps/cs/src/shared/config/api.ts +++ b/apps/cs/src/shared/config/api.ts @@ -33,6 +33,7 @@ export const ENDPOINT = { MENU_ROLES: "/cms-service/api/v1/menu-roles", MENU_AUTHRTS: "/cms-service/api/v1/menu-authrts", MENU_TEMPORARY_STORAGE: "/cms-service/api/v1/menu-tmpr-strg", + MENU_HISTORY: "/cms-service/api/v1/menu-hstry", CONTENTS: "/cms-service/api/v1/contents", CONTENTS_DETAILS: "/cms-service/api/v1/contents-details", ORGANIZATIONS: "/cms-service/api/v1/ognzs", From 49a699f5332804a25edf761e710c5da282dca5da Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Tue, 8 Jul 2025 19:22:05 +0900 Subject: [PATCH 037/159] =?UTF-8?q?[apps/cs]=20chore:=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EC=B2=AD=20=EC=BD=94=EB=93=9C=20=ED=95=84=ED=84=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/users/ui/users-form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cs/src/pages/users/ui/users-form.tsx b/apps/cs/src/pages/users/ui/users-form.tsx index d69e918b0..0ddfde713 100644 --- a/apps/cs/src/pages/users/ui/users-form.tsx +++ b/apps/cs/src/pages/users/ui/users-form.tsx @@ -140,7 +140,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ }, [laeSeCd, watchDtlInstCd]); const enoCdSelectData = useMemo( - () => laeSeCd?.filter((code) => code.unit?.startsWith("G2")) ?? [], + () => laeSeCd?.filter((code) => code.lwpoCd?.startsWith("G2")) ?? [], [laeSeCd], ); From 0dd5744229f65aede814bd79505e153474a5cae2 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Tue, 8 Jul 2025 19:31:43 +0900 Subject: [PATCH 038/159] =?UTF-8?q?=EA=B2=B0=ED=95=A8=20=EB=8C=80=EC=9E=A5?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/coSttn/page.tsx | 26 +- .../app/ruseFcltMng/fcltReg/htdflReg/page.tsx | 10 +- .../app/ruseFcltMng/fcltReg/rainReg/page.tsx | 39 +-- apps/wr/app/store/common/code/index.ts | 8 + apps/wr/app/store/matDmd/coSttn/excel.tsx | 1 - .../ruseFcltMng/fcltReg/htdflReg/index.tsx | 2 +- .../ruseFcltMng/fcltReg/pbnstReg/headList.tsx | 2 +- .../ruseFcltMng/fcltReg/rainReg/index.tsx | 5 +- .../ruseFcltMng/fcltReg/rainReg/type.tsx | 5 +- .../ruseFcltMng/fcltReg/rswtReg/index.tsx | 6 +- .../ui/form/fcltReg/bdstReg/bdstReg.tsx | 45 +++- .../ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 2 +- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 2 +- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 4 +- .../fcltReg/bdstRegModal/bdstRegModal.tsx | 232 ++++++++++++------ 15 files changed, 255 insertions(+), 134 deletions(-) diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index 163ed1b40..d9fb09031 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -109,18 +109,18 @@ export default function CoSttn() { } }, [coSttnRes, code]); - useEffect(() => { - if (coSttn.excelList.length > 0) { - if (coSttn.excelList.length === 0) return; - excelDownload( - coSttn.excelList, - "수요처 관리", - "sample_coSttn.xlsx", - "A1:G1", - 2 - ); - } - }, [coSttn.excelList]); + // useEffect(() => { + // if (coSttn.excelList.length > 0) { + // if (coSttn.excelList.length === 0) return; + // excelDownload( + // coSttn.excelList, + // "수요처 관리", + // "sample_coSttn.xlsx", + // "A1:H1", + // 2 + // ); + // } + // }, [coSttn.excelList]); @@ -133,7 +133,7 @@ export default function CoSttn() { excelData as [], "수요처 관리", "sample_coSttn.xlsx", - "A1:F1", + "A1:G1", 2 ); } diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx index 873ad85f3..c80d5b4b4 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -38,7 +38,7 @@ export default function Home() { chgBuilding: chgBuilding[]; }>({ isOpen: false, chgBuilding: [] }); - const { htdflRes } = htdfl; + const { htdflRes ,htdflResCount} = htdfl; useEffect(() => { if (!htdfl.isInit) { @@ -101,7 +101,7 @@ export default function Home() { <SearchFormLeft> <SearchInput className="col-span-3 my-7 !text-3xl" - label="건물명" + label="시설명" textValue={searchTxt || ""} setText={(e) => { setSearchTxt(e); @@ -137,9 +137,9 @@ export default function Home() { <UiTable tableData={bdstTable || []} headlist={htdfl.upHeadList} - pageSize={100} - total={10} - headName={"건축물 목록"} + pageSize={20} + total={htdflResCount} + headName={"시설물 목록"} cellClick={(val, headId) => { cellClick(val || undefined, headId); }} diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index 6c97f6c8c..5b358977b 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -29,7 +29,7 @@ export default function Home() { return state; } ); - const { rainRes,rainResCount } = rain; + const { rainRes, rainResCount } = rain; const [rainForm, setRainForm] = useState<customRainBdst>(); const [issNewReg, setIsNewReg] = useState<boolean>(false); const [pageNation, setPageNation] = useState(1); @@ -48,26 +48,27 @@ export default function Home() { }, [rain.isInit, initRain]); useEffect(() => { - if (code.sggCd.length > 0) { + if (code.sggCd.length > 0) { + if (rainRes && rainRes.length > 0) { + const rainData = tableData(rainRes, { code }).map( + (item: customRainBdst) => { + let archArea = + item?.archArea.split(".")[0] !== "-1" + ? item?.archArea.split(".")[0] + : "확인불가"; + return { + ...item, + archArea: archArea, - if(rainRes&& rainRes.length>0){ + bdstChgYn: item.chgBuilding.length > 0 ? "Y" : "N", + }; + } + ); - const rainData = tableData(rainRes, { code }).map( - (item: customRainBdst) => { - let archArea = item?.archArea.split('.')[0]!=='-1'?item?.archArea.split('.')[0]:'확인불가' - return { - ...item, - archArea:archArea, - - bdstChgYn: item.chgBuilding.length > 0 ? "Y" : "N", - }; - } - ); - - setbdstTable(rainData); - }else{ - setbdstTable([]); - } + setbdstTable(rainData); + } else { + setbdstTable([]); + } } }, [code, rainRes]); const cellClick: (val: number | undefined, headId: string) => void = ( diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index b3cf48603..5eecb83c4 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -3,6 +3,11 @@ import type { EnvPartSelectDataType, SelectDataType } from "@common/business_com import { bdstFilterYn, bdstGrntchClass, bdstIncenYn, bdstUsgCd, chBuCd, dmdUszCd, erctUswtrPrcsMeth, htdPowerMthdCd, htdUtztnUsgCd, orgwtKndCd, pplLenght, pplQulity, rainFcltCd, rswtPrscCdMthdCd, ruseBizMthdCd, ruseMngMtd, rusePrcsMthdCd, ruseSeCd, yn } from "./basicCode"; export const btnClass = "p-4 m-2 text-white rounded-sm text-lg font-medium " + +const laeSecd = '41' +const ogdpSeCd = '0' + + export const buildingType = { RST:"RST", RNB:"RNB", @@ -167,6 +172,8 @@ export type comCodeState = { rswtPrscCdMthdCd:SelectDataType[]; htdPowerMthdCd:SelectDataType[] htdUtztnUsgCd:SelectDataType[] + userSiSggCd : string; + }; }; @@ -203,6 +210,7 @@ export const comCodeStateExport: comCodeState = { rswtPrscCdMthdCd:rswtPrscCdMthdCd, htdPowerMthdCd:htdPowerMthdCd, htdUtztnUsgCd:htdUtztnUsgCd, + userSiSggCd:laeSecd, }, }; diff --git a/apps/wr/app/store/matDmd/coSttn/excel.tsx b/apps/wr/app/store/matDmd/coSttn/excel.tsx index 05b45711a..3b6d73c8b 100644 --- a/apps/wr/app/store/matDmd/coSttn/excel.tsx +++ b/apps/wr/app/store/matDmd/coSttn/excel.tsx @@ -2,7 +2,6 @@ import moment from "moment"; export const excelCoSttnParsing = (data: any[]): string[][] => { const excelExportData: string[][] = []; - data.forEach((item) => { excelExportData.push([ String(item.cityText)??'', diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx index feaefc03f..b241fe7f1 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx @@ -177,7 +177,7 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( if (res.status) { toast.success("온배수 건축물 수정이 완료되었습니다."); } - const htdflRes = await getFetch( + const htdflRes = await getFetchWithCount( "wr", `/drain/facilityList/1/10/${code}` ); diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index 46287aa2c..569fad381 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -7,7 +7,7 @@ export const pubFacHeadListExport: TableUpperProps[] = [ { id: "bscFctNm", title: "시설명" }, { id: "addr", title: "위치" }, { id: "efflWqltStndrdNm", title: "지역구분" }, - { id: "fctCpc", title: "시설용량" }, + { id: "fctCpc", title: "시설용량(m³/일)" }, { id: "ruse", title: "재이용여부" }, { id: "rswtrYn", title: "등록여부" }, ]; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index 67ea71cb6..b0ea5fd37 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -28,8 +28,8 @@ const rainyObjSchema = z.object({ export const rainZod = z.object({ bdstInfoPk: z.number().optional(), - ctpvCd: z.number().default(0), - sggCd: z.number().default(0), + ctpvCd: z.number().optional(), + sggCd: z.number().optional(), daddr: z.string().default(""), bdstNm: z.string().default(""), frstArchPrmsnDt: z.date().default(() => new Date()), @@ -83,6 +83,7 @@ type rainFacSActions = { rainSearch: (txt:string,pageNation:number,code:string|number) => void; rainBdstReg: (data: customRainBdst, code:string|number) => void; rainBdstUpdate: (data: customRainBdst, code:string|number) => void; + }; export type rainFacType = rainFacState & rainFacSActions; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx index 2d17b4601..80811d7ce 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/type.tsx @@ -11,7 +11,10 @@ export const baseReuseBuildingSchema = z.object({ bdstRuseFcltPk: z.number().nullish(), bdstInfoFk: z.number().nullish(), instlCmptnDt: z.coerce.date().default(() => new Date()), - instlCst: z.number().nullish(), + instlCst: z + .number() + .max(9_999_999, { message: "최대 9,999,999까지 입력 가능합니다." }) + .nullish(), operMngCd: z.string().optional().default(""), anlOperCst: z.number().default(0), instlCstSprtYn: z.string().default("Y"), diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx index 475c1797d..8c3579a5d 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx @@ -30,8 +30,8 @@ import toast from "react-hot-toast"; export const rswtZod = z.object({ bdstInfoPk: z.number().nullish(), - ctpvCd: z.number().default(0), - sggCd: z.number().default(0), + ctpvCd: z.number(), + sggCd: z.number(), daddr: z.string().default(""), bdstNm: z.string().default(""), frstArchPrmsnDt: z.date().default(() => new Date()), @@ -182,7 +182,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( const chData = await makeRstr(data); const res = await postFectch("/reuseFc/waterreuseFc", chData); if (res.status===200) { - if(data.chgBuilding.length > 0){ + if(data.chgBuilding ){ const chPK = res?.data?.bdstInfoPk const makeCh= res.data.chgBuilding.map((item: chgBuilding) => diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index 886dd2da9..bceee1a17 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -24,6 +24,10 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { return state; }); + const {userSiSggCd } =code + const [useCityCd, setUserCityCd] = useState<SelectDataType[]>([]) + const [useSggCd, setUserSggCd] = useState<SelectDataType[]>([]) + const { fields, append, remove } = useFieldArray({ name: "chgBuilding", control: form?.control, // Provide a fallback to avoid errors @@ -52,6 +56,33 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { city: "", }); + useEffect(() =>{ + if(userSiSggCd.length===2 && code.cityCd.length>0){ + const city = code.cityCd.filter((item) => item.val === userSiSggCd) + const sgg = code.sggCd.filter((item) => item.val.slice(0,2) === userSiSggCd ) + sgg.unshift({text:'전체' , val:'0'}) + setUserCityCd(city) // Fix: Ensure city is of type SelectDataType[] + setUserSggCd(sgg) + if (city[0]?.val) { + // 여기 중요 + queueMicrotask(() => { + form.setValue("ctpvCd", Number(city[0]?.val), { shouldDirty: true, shouldTouch: true, shouldValidate: true }); + }); + } + }else if(userSiSggCd.length===5 && code.cityCd.length>0 && code.sggCd.length>0) { + const city = code.cityCd.filter((item) => item.val === userSiSggCd.slice(0,2)) + const sgg = code.sggCd.filter((item) => item.val === userSiSggCd) + setUserSggCd(sgg) + setUserCityCd(city) + form.setValue('ctpvCd',Number(city[0]?.val) ) + form.setValue('sggCd',Number(sgg[0]?.val) ) + + } + },[form, userSiSggCd, code.cityCd, code.sggCd]) + + + + const getSelCity = (val: string) => { const data = getCity(val, code.sggCd); setSelectSgg(data); @@ -87,6 +118,12 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { ); }; + useEffect(() =>{ + + console.log('form.formState ', form.watch()) + + },[form.formState]) + return ( <> <h1 className={formH1Class}> { type !== "HTB"?"건축물 기본 정보": '시설 기본 정보'}</h1> @@ -101,12 +138,11 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { className="col-span-3" label={""} selectClass={selectClass} - selectArray={code.cityCd} + selectArray={useCityCd} onSelectValue={(val) => { - getSelCity(String(val)); field.onChange(Number(val)); }} - value={field.value} + value={typeof field.value !== "undefined" ? field.value : useCityCd[0]?.val} /> </FormUi> )} @@ -122,9 +158,8 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { className="col-span-3" label={""} selectClass={`w-full min-h-[2.9rem] ${selectClass}`} - selectArray={selectSgg ? selectSgg : code.sggCd || []} + selectArray={useSggCd} onSelectValue={(val) => { - getSgg(val); field.onChange(Number(val)); }} value={field.value} diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index edd5bb1b5..5e0786f8b 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -61,7 +61,7 @@ export default function HtdflRegForm({ if (setIsModal) setIsModal(false); } else { - htdflBdstUpdate(values, "41"); + htdflBdstUpdate(values, "0"); } }; diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index da8011efd..974d9269c 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -39,7 +39,7 @@ export default function RainRegForm({ const defaultValues: z.infer<typeof rainZod> = rainZod.parse({}); const form = useForm<z.infer<typeof rainZod>>({ resolver: zodResolver(rainZod), - defaultValues: defaultValues, + // defaultValues: defaultValues, }); const instlCst = form.watch(`reuseBuilding.0.instlCst`); diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index 3c8af831d..f70f4548c 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -41,11 +41,11 @@ export default function RswtrRegForm({ (state) => state ); - const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({}); + // const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({}); const form = useForm<z.infer<typeof rswtZod>>({ resolver: zodResolver(rswtZod), - defaultValues: defaultValues, + // defaultValues: defaultValues, }); const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs] = form.watch([ diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index 25e5ef976..a049772e8 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -4,7 +4,12 @@ import { selectClass, type customRainBdst, } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { ScrollArea, SelectBox, UiTable, type SelectDataType } from "@common/business_components"; +import { + ScrollArea, + SelectBox, + UiTable, + type SelectDataType, +} from "@common/business_components"; import { Button, Input, Label } from "@common/components"; import { useEffect, useState } from "react"; import { getCity, tableData } from "@/components/lib/func/commom"; @@ -15,83 +20,117 @@ import RswtrRegForm from "@/components/ui/form/fcltReg/rswtrReg/rswtrRegForm"; import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm"; export type objSearchType = { - sgg: string|number; - city: string|number; - }; + sgg: string | number; + city: string | number; +}; //RNB(빗물), RST(중수도), HTB(온배수) - type MoType = 'RNB' | 'RST' | 'HTB'; // 여기에 'htdf' 추가 +type MoType = "RNB" | "RST" | "HTB"; // 여기에 'htdf' 추가 - type BdstTypeMap = { +type BdstTypeMap = { RNB: customRainBdst; RST: customRswtBdst; - HTB: customRswtBdst; // 해야해// 아직 아노딤 + HTB: customRswtBdst; // 해야해// 아직 아노딤 }; - interface BdstRegProps<T extends MoType> { +interface BdstRegProps<T extends MoType> { moType: T; - isModal:boolean; + isModal: boolean; + siSggCode?: string; setIsModal?: (open: boolean) => void; } -export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstRegProps<T>) { - const { rain, code, bdst,findBdst } = useWrStore((state) => { +export function BdstReg<T extends MoType>({ + moType, + setIsModal, + siSggCode, + isModal, +}: BdstRegProps<T>) { + const { rain, code, bdst, findBdst } = useWrStore((state) => { return state; }); + + const { userSiSggCd } = code; + const [bdstTable, setbdstTable] = useState<BdstTypeMap[T][]>(); - const [rainBdstForm, setRainBdstForm] = useState<BdstTypeMap[T]>({} as BdstTypeMap[T]); - const [searchTxt, setSearchTxt] = useState<string>() - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() - const [objSearch, setObjSearch] = useState<objSearchType>({sgg:"",city:""}); + const [rainBdstForm, setRainBdstForm] = useState<BdstTypeMap[T]>( + {} as BdstTypeMap[T] + ); + const [searchTxt, setSearchTxt] = useState<string>(); + const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(); + const [objSearch, setObjSearch] = useState<objSearchType>({ + sgg: "", + city: "", + }); + const [useCityCd, setUserCityCd] = useState<SelectDataType[]>([]); + const [useSggCd, setUserSggCd] = useState<SelectDataType[]>([]); + const [dataCode, setDataCode] = useState<string>(); - const getSelCity = (val: string | number) => { - const cityValue = String(val); // Ensure val is treated as a string - const data = getCity(cityValue, code.sggCd); + const searchBdst = (searchTxt: string | undefined) => { + let data = objSearch.city; - setSelectSgg(data); - // getSgg(data[0]?.val || ""); - setObjSearch({ city: cityValue, sgg: '' }); + if (objSearch.sgg !== "" && objSearch.sgg !== "0") { + data = objSearch.sgg; + } + //RNB(빗물), RST(중수도), HTB(온배수) + findBdst(String(data), searchTxt || "", moType); }; - const getSgg = (val: string | number) => { - setObjSearch({...objSearch,sgg: String(val)}) - }; - - const searchBdst=(searchTxt: string | undefined)=>{ - let data =objSearch.city; - if(objSearch.city==="" ){ - - data = String(code.cityCd[0]?.val) - } - if(objSearch.sgg !=="" ){ - data = objSearch.sgg - } - - //RNB(빗물), RST(중수도), HTB(온배수) - findBdst(String(data), searchTxt || "",moType ) - - } - useEffect(() => { if (code.sggCd.length > 0) { - - setbdstTable( tableData(bdst.bdstBase, { code })); - } - }, [ bdst]); + const bdstData = bdst.bdstBase.map((bdst) => { + let archArea = + bdst?.archArea.split(".")[0] !== "-1" + ? bdst?.archArea.split(".")[0] + : "확인불가"; + return { + ...bdst, + archArea: archArea, + }; + }); + setbdstTable(tableData(bdstData, { code })); + } + }, [bdst]); + useEffect(() => { + if (userSiSggCd.length === 2 && code.cityCd.length > 0) { + const city = code.cityCd.filter((item) => item.val === userSiSggCd); + const sgg = code.sggCd.filter( + (item) => item.val.slice(0, 2) === userSiSggCd + ); + sgg.unshift({ text: "전체", val: "0" }); + setUserCityCd(city); // Fix: Ensure city is of type SelectDataType[] + setObjSearch({ ...objSearch, city: String(city[0]?.val) }); + setUserSggCd(sgg); + } else if ( + userSiSggCd.length === 5 && + code.cityCd.length > 0 && + code.sggCd.length > 0 + ) { + const city = code.cityCd.filter( + (item) => item.val === userSiSggCd.slice(0, 2) + ); + setUserCityCd(city); + const sgg = code.sggCd.filter((item) => item.val === userSiSggCd); + setUserSggCd(sgg); + setObjSearch({ city: String(city[0]?.val), sgg: String(sgg[0]?.val) }); + } + }, [userSiSggCd, code.cityCd, code.sggCd]); - const tableClick: (val: number | undefined , headId:string) => void = (val ,headId) => { - - if(val!==undefined && bdst?.bdstBase.length>0){ - const data:BdstTypeMap[T] =bdst?.bdstBase[val] - if (data) { - setRainBdstForm(data); - } + const tableClick: (val: number | undefined, headId: string) => void = ( + val, + headId + ) => { + if (val !== undefined && bdst?.bdstBase.length > 0) { + const data: BdstTypeMap[T] = bdst?.bdstBase[val]; + if (data) { + setRainBdstForm(data); } - } + } + }; - useEffect(()=>{ - setbdstTable([]) // 초기화 작업 - },[]) + useEffect(() => { + setbdstTable([]); // 초기화 작업 + }, []); return ( <> <div className="grid grid-cols-12 gap-4 mt-4 items-center"> @@ -99,31 +138,50 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg className="col-span-3 h-full" label={"시도"} selectClass={selectClass} - selectArray={code.cityCd || []} - onSelectValue={getSelCity} - > - {""} - </SelectBox> + selectArray={useCityCd} + onSelectValue={(val) => { + setObjSearch({ ...objSearch, city: String(val) }); + }} + value={objSearch.city || useCityCd[0]?.val} + ></SelectBox> <SelectBox className="col-span-3 h-full" label={"시군구"} selectClass={selectClass} - selectArray={selectSgg || []} - onSelectValue={getSgg} - value={objSearch.sgg || ""} + selectArray={useSggCd || []} + onSelectValue={(val) => { + if (val) setObjSearch({ ...objSearch, sgg: String(val) }); + }} + value={objSearch.sgg || useSggCd[0]?.val} > {" "} </SelectBox> - <Label className="w-full text-xl text-gray-600 text-right">시설명</Label> - <Input className="w-full h-full !text-xl col-span-2 col-start-8" type="text" value={searchTxt || ''} onChange={(e) => setSearchTxt(e.target.value)}/> - <Button className="" size={"sm"} onClick={()=>{searchBdst(searchTxt)}}>조회</Button> + <Label className="w-full text-xl text-gray-600 text-right"> + 시설명 + </Label> + <Input + className="w-full h-full !text-xl col-span-2 col-start-8" + type="text" + value={searchTxt || ""} + onChange={(e) => setSearchTxt(e.target.value)} + /> + <Button + className="" + size={"sm"} + onClick={() => { + searchBdst(searchTxt); + }} + > + 조회 + </Button> </div> <div className="border-t border-gray-300 my-4"></div> <div className="h-auto"> <h1 className="text-2xl font-medium text-label pl-8"> 건축물 목록 <span className="!text-2xl text-base text-blue-500"> - (유의 사항: 신규등록하려는 건축물이 목록에 없을 경우 하단 건축물 정보에 추가하여 주시기 바랍니다.) + (유의 사항: 신규등록하려는 건축물이 목록에 없을 경우 하단 건축물 + 정보에 추가하여 주시기 바랍니다.) </span> </h1> <ScrollArea className="h-[30vh]"> @@ -134,24 +192,40 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg pageSize={-10} total={-1} headName={undefined} - cellClick={(idx, headId) => (tableClick(idx, headId || ""))} + cellClick={(idx, headId) => tableClick(idx, headId || "")} onPageChange={function (page: number): void { throw new Error("Function not implemented."); - }}> - </UiTable> + }} + ></UiTable> </div> </ScrollArea> <div className="border-t border-gray-300 my-4"></div> {/* <ScrollArea className="h-[40vh]"> */} - <div> - { moType === 'RNB'? - <RainRegForm rainForm={rainBdstForm as customRainBdst} isModal={isModal} setIsModal={setIsModal} /> - :moType==='RST' - ? <RswtrRegForm rswtForm={rainBdstForm as customRswtBdst} isModal={isModal} setIsModal={(open) =>{setIsModal && setIsModal(open)}}></RswtrRegForm> - :<HtdflRegForm htdflForm={rainBdstForm as unknown as customHtdflBdst} isModal={true} setIsModal={(open) =>{setIsModal && setIsModal(open)}}></HtdflRegForm> - } - - </div> + <div> + {moType === "RNB" ? ( + <RainRegForm + rainForm={rainBdstForm as customRainBdst} + isModal={isModal} + setIsModal={setIsModal} + /> + ) : moType === "RST" ? ( + <RswtrRegForm + rswtForm={rainBdstForm as customRswtBdst} + isModal={isModal} + setIsModal={(open) => { + setIsModal && setIsModal(open); + }} + ></RswtrRegForm> + ) : ( + <HtdflRegForm + htdflForm={rainBdstForm as unknown as customHtdflBdst} + isModal={true} + setIsModal={(open) => { + setIsModal && setIsModal(open); + }} + ></HtdflRegForm> + )} + </div> {/* </ScrollArea> */} </div> </> From 1a4b287b7a9caeeda4e76c962b07a6368f3f3a22 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Tue, 8 Jul 2025 19:42:07 +0900 Subject: [PATCH 039/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=20=EC=83=81=EC=84=B8=20=ED=8C=9D=EC=97=85=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 148 +++++++++++++++++++---------- 1 file changed, 100 insertions(+), 48 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index e1a26267f..cd9bb8e00 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -10,9 +10,10 @@ import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstS import type { chgBuilding, customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { getFetch } from "@/components/lib/api"; +import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import { useGisContext } from "@common/business_components/ui/map/Gis"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; +import { set } from "react-hook-form"; interface NewWindowPopupProps { featureData: any; @@ -104,25 +105,26 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); const [htdflPage, setHtdflPage] = useState(1) + //하수처리시설 변수 const { - pbnst, - pubHasuInit, - pubHasuSearch, - } = useWrStore((state) => state); - const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; - const [isRuseReg, setIsRuseReg] = useState<{ - isModal: boolean; - }>({ isModal: false }); - const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); - const [selectRow, setSelectRow] = useState<pubHasuType>(); - const [hasuPage, setHasuPage] = useState<number>(1); + pbnst, + pubHasuInit, + pubHasuSearch, + } = useWrStore((state) => state); + let { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; + const [isRuseReg, setIsRuseReg] = useState<{ + data:any | undefined; + }>({ data: undefined }); + const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); + const [selectRow, setSelectRow] = useState<pubHasuType>(); + const [hasuPage, setHasuPage] = useState<number>(1); if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// useEffect(() => { const layerId = getSelectedLayers(); if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); - let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설'? selectedVal?.bdst_nm : layerId == '하수처리시설' ? 'a' : null; + let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null; if (featureCd && featureCd !== fcltPk) { if (layerId == '하수재이용시설') { featureCd = selectedVal?.swtrmt_fclt_cd; @@ -148,8 +150,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ htdflSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); } - else if(layerId =='하수처리시설') { - + else if (layerId == '하수처리시설') { + featureCd = selectedVal?.swtrmt_fclt_nm; + setFcltPk(featureCd); // 현재 호출된 featureCd 저장 + const res = fetchHasuDetail(featureCd,selectedVal?.swtrmt_fclt_cd); }; setViewMode("detail") @@ -176,7 +180,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; const getSelectedLayers = () => { let result = null; - const layers = gisMap ? gisMap.getLayers().getArray().filter((l:any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 + const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 layers.forEach((layer: any) => { const source = layer.getSource(); @@ -414,19 +418,38 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [htdflPage]); ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// - useEffect(() => { - if (code.sggCd.length && pbnstHasuRes.length > 0) { - setHasuTable(tableData(pbnstHasuRes, { code })); - } - }, [code, pbnstHasuRes]); - useEffect(() => { - if (!pbnst.isInit) { - pubHasuInit("1", "0"); - } - }, [pbnst.isInit, pubHasuInit]); - useEffect(() => { - pubHasuInit(String(hasuPage), "0"); - }, [hasuPage]); + useEffect(() => { + if (code.sggCd.length && pbnstHasuRes.length > 0) { + setHasuTable(tableData(pbnstHasuRes, { code })); + } + }, [code, pbnstHasuRes]); + useEffect(() => { + if (!pbnst.isInit) { + pubHasuInit("1", "0"); + } + }, [pbnst.isInit, pubHasuInit]); + useEffect(() => { + pubHasuInit(String(hasuPage), "0"); + }, [hasuPage]); + const fetchHasuDetail = async (featureCd: string,data:string) => { + try { + const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`,[data],fetchType.COMMON); + const hasuList = rainRes.data.map((item: any) => { + return { + ...item, + fctCpc: Number(item.fctCpc) || 0, + ruse: item.ruse === false ? "N" : "Y", + }; + }); + pbnstHasuRes = hasuList + // console.log(hasuList) + if(pbnstHasuRes.length >0)setIsRuseReg({ data:[pbnstHasuRes[0]] }); + console.log(pbnstHasuRes) + + } catch (error) { + console.error("Error fetching data:", error); + } + }; // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { @@ -452,17 +475,46 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <div className="flex justify-between items-center mb-4"> <Title title="하수처리시설 현황" /> </div> - {/* 높이 조정 */} - <UiTable - tableData={hasuTable || []} - headlist={pubFacHeadList} - pageSize={10} - total={100000} - headName={""} - cellClick={()=>{}} - onPageChange={setHasuPage} - children={undefined} - /> + {/* 높이 조정 */} + <UiTable + tableData={hasuTable || []} + headlist={pubFacHeadList} + pageSize={10} + total={100000} + headName={""} + cellClick={() => { }} + onPageChange={setHasuPage} + children={undefined} + /> + </> + ) + } else { + return ( + <> + <div className="flex justify-between items-center mb-4"> + <Title title="하수처리시설 상세정보" /> + </div> + {/* 높이 조정 */} + <UiTable + tableData={isRuseReg?.data || []} + headlist={pubFacHeadList.slice(0,4)} + pageSize={1} + total={null} + headName={"위치정보"} + cellClick={() => { }} + onPageChange={() => { }} + children={undefined} + /> + <UiTable + tableData={isRuseReg?.data || []} + headlist={pubFacHeadList.slice(4)} + pageSize={1} + total={null} + headName={"기본정보"} + cellClick={() => { }} + onPageChange={() => { }} + children={undefined} + /> </> ) } @@ -525,7 +577,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (viewMode == 'detail') { // 빗물이용시설 상세 return ( - <SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} /> + <SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} /> ); } else { // 빗물이용시설 목록 @@ -560,7 +612,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (viewMode == 'detail') { // 중수도시설 상세 return ( - <SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst}/> + <SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} /> ); } else { // 중수도시설 목록 @@ -595,7 +647,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (viewMode == 'detail') { // 온배수시설 상세 return ( - <SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst}/> + <SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} /> ); } else { // 온배수시설 목록 @@ -630,11 +682,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; return ( - viewMode == 'nothing' ? <></> : - <NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보"> - {/* 체크된 레이어에 따른 조건부 렌더링 */} - {renderConditionalContent()} - </NewWindowPortal> + viewMode == 'nothing' ? <></> : + <NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보"> + {/* 체크된 레이어에 따른 조건부 렌더링 */} + {renderConditionalContent()} + </NewWindowPortal> ); }; From e314369cbb77f083abc2ab5a6b2f588ea2dc1657 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 19:54:53 +0900 Subject: [PATCH 040/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=EB=93=B1=EB=A1=9D=20=EC=8B=9C?= =?UTF-8?q?=EC=84=A4/=EC=B0=A8=EC=88=98=EB=B3=84=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 103 +++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 6a9189876..29b65c9c8 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -93,7 +93,7 @@ export default function PublicReuseFaciltyInsert() { if (!isDirty) { toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시 return; - } const data = writeRgtrAndMdfr(valuse.items); + } const data = writeRgtrAndMdfr(valuse.items); let bizs = [] as fcBizType[]; data.forEach((fclt) => { bizs = [...bizs, ...fclt.fcBizs]; @@ -118,22 +118,22 @@ export default function PublicReuseFaciltyInsert() { ]).then(([resFclt, resBiz]) => { const isFcltSuccess = resFclt.status === "fulfilled"; const isBizSuccess = resBiz.status === "fulfilled"; - + if (isFcltSuccess && isBizSuccess) { - toast.success('하수 재이용 시설 및 사업이 수정되었습니다. ') + toast.success('하수 재이용 시설 및 사업이 수정되었습니다. ') // 메시지 표시, 페이지 이동 등 } else { - let message ='' + let message = '' // ✅ 각각 어떤 항목이 실패했는지도 로그/알림 처리 if (!isFcltSuccess) { message = '하수재이용 시설 ' } if (!isBizSuccess) { - message += '하수재이용 시설 사업 ' + message += '하수재이용 시설 사업 ' } - - toast.error(message+'오류 입니다 ') + + toast.error(message + '오류 입니다 ') pubHasuInit("1", "41"); } @@ -146,45 +146,45 @@ export default function PublicReuseFaciltyInsert() { // 폼 유효성 검사 실패 시 호출될 함수 const onInvalid = (errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }>) => { console.log("errors:", errors); - + const findAllErrors = ( errorObject: any, path: (string | number)[] = [] ): { message: string; path: (string | number)[] }[] => { if (!errorObject) return []; - + return Object.keys(errorObject).flatMap((key) => { const value = errorObject[key]; const currentKey = !isNaN(parseInt(key)) ? parseInt(key) : key; const newPath = [...path, currentKey]; - + if (value && typeof value === "object") { if (value.message) { return [{ message: value.message, path: newPath }]; } - + return findAllErrors(value, newPath); } return []; }); }; - + const errorList = findAllErrors(errors); - + if (errorList.length > 0) { errorList.forEach((errorInfo) => { const { message, path } = errorInfo; let prefix = ""; - + const itemsIndex = path.indexOf("items"); - + if (itemsIndex > -1 && path.length > itemsIndex + 1) { const itemIdx = path[itemsIndex + 1] as number; const facilityName = form.getValues(`items.${itemIdx}.ruseUtztnFcltNm`); if (facilityName) { prefix += `[${facilityName}] `; } - + const fcBizsIndex = path.indexOf("fcBizs"); if (fcBizsIndex > -1 && path.length > fcBizsIndex + 1) { const bizIdx = path[fcBizsIndex + 1] as number; @@ -194,7 +194,7 @@ export default function PublicReuseFaciltyInsert() { } } } - + // 최종 오류 메시지 출력 toast.error(`${prefix}${message}`); }); @@ -239,7 +239,7 @@ export default function PublicReuseFaciltyInsert() { } }, [indexMng]); - + useEffect(() => { @@ -266,7 +266,7 @@ export default function PublicReuseFaciltyInsert() { // ] as fcBizType[], // }) // ); - append(createDefaultPbnstItem(selecTableRow, pbnstRes.length)); + append(createDefaultPbnstItem(selecTableRow, pbnstRes.length)); setIsRuseReg({ isModal: true }); } @@ -366,24 +366,24 @@ export default function PublicReuseFaciltyInsert() { </ListDiv> </div> <ListDiv className="col-span-2 pr-6 "> - <ScrollArea className="h-[60vh]"> - {formWatch && formWatch[0]?.pbnstRuseFcltPk ? ( - <Tabs defaultValue="mng" onValueChange={handleTabChange}> - <TabsList className=""> - <TabsTrigger className="!text-xl" value="mng"> - 시설정보 - </TabsTrigger> - <TabsTrigger className="!text-xl" value="buse"> - 차수별정보 - </TabsTrigger> - <Button - size={"sm"} - onClick={form.handleSubmit(onSubmit, onInvalid)} - className="!justify-end" // 저장 버튼 위치 조정 - > - 저장 - </Button> - </TabsList> + {formWatch && formWatch[0]?.pbnstRuseFcltPk ? ( + <Tabs defaultValue="mng" onValueChange={handleTabChange}> + <TabsList className=""> + <TabsTrigger className="!text-xl" value="mng"> + 시설정보 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="buse"> + 차수별정보 + </TabsTrigger> + <Button + size={"sm"} + onClick={form.handleSubmit(onSubmit, onInvalid)} + className="!justify-end" // 저장 버튼 위치 조정 + > + 저장 + </Button> + </TabsList> + <ScrollArea className="h-[60vh]"> <TabsContent className="max-h-full" value="mng"> <PbnstMngForm formType="update" @@ -406,17 +406,19 @@ export default function PublicReuseFaciltyInsert() { indexBiz={indexBiz} /> </TabsContent> - </Tabs> - ) : ( - <> + + </ScrollArea> + </Tabs> + ) : ( + <> <div className="card-header text-2xl"> - 등록된 재이용시설 정보가 없습니다. + 등록된 재이용시설 정보가 없습니다. </div> - <div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 border rounded-md"> - <p className="text-3xl mb-4"> - 신규등록 버튼을 클릭하여 재이용시설을 등록해주세요. - </p> - <Button + <div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 border rounded-md"> + <p className="text-3xl mb-4"> + 신규등록 버튼을 클릭하여 재이용시설을 등록해주세요. + </p> + <Button size={"sm"} className="" onClick={() => { @@ -433,11 +435,10 @@ export default function PublicReuseFaciltyInsert() { > 신규등록 </Button> - </div> - </> + </div> + </> - )} - </ScrollArea> + )} </ListDiv> <UiModal body={ @@ -450,7 +451,7 @@ export default function PublicReuseFaciltyInsert() { } }} - onInvalid ={onInvalid} + onInvalid={onInvalid} ></PbnstRegModal> } bodyClass="w-[68vw] max-w-none h-[90vh]" From e30130dc8f54918924e5221b7b4103f8b0afb2ca Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Tue, 8 Jul 2025 20:59:35 +0900 Subject: [PATCH 041/159] =?UTF-8?q?=EC=9E=A0=EC=9E=AC=EC=88=98=EC=9A=94?= =?UTF-8?q?=EC=B2=98=20=EC=97=91=EC=85=80=20=EB=8B=A4=EC=9A=B4=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95,=20=ED=8E=98=EC=9D=B4=EC=A7=95?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wr/app/matMng/coMng/ldrmntCoSttn/page.tsx | 14 +++++----- .../app/store/matDmd/ldrmntCoSttn/index.tsx | 9 +++--- .../ruseFcltMng/fcltSttn/htdflSttn/index.tsx | 2 -- .../ruseFcltMng/fcltSttn/rainSttn/index.tsx | 2 -- .../ruseFcltMng/fcltSttn/rswtSttn/excel.tsx | 3 +- .../ruseFcltMng/fcltSttn/rswtSttn/index.tsx | 8 ++++-- .../coReg/coRegExcel/coRegExcelModal.tsx | 28 +++++++++++-------- 7 files changed, 37 insertions(+), 29 deletions(-) diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx index 271754938..5ce69d508 100644 --- a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -42,7 +42,7 @@ export default function LdrmntCoSttn() { const [bdstTable, setBdstTable] = useState<customLdrmnt[]>(); const [searchTxt, setSearchTxt] = useState<string>(); const [excelData, setExcelData] = useState<any[]>(); - const [isExcelDownload, setIsExcelDownload] = useState(false); + // const [isExcelDownload, setIsExcelDownload] = useState(false); const excelClick = useCallback(() => { excelDownload( @@ -77,20 +77,20 @@ export default function LdrmntCoSttn() { const excelDownloadClick = useCallback(() => { const cityNm = computeCityNm(); ldrmntSearch(true, pageNation, String(ldrmntResCount), cityNm, searchTxt || ""); - setIsExcelDownload(true); - }, [objSearch, pageNation, searchTxt, code, ldrmntSearch, computeCityNm]); + // setIsExcelDownload(true); + }, [objSearch, pageNation, searchTxt, code, ldrmntSearch, computeCityNm, ldrmntResCount]); useEffect(() => { - if (isExcelDownload && excelData && excelData.length > 0) { + if (/*isExcelDownload &&*/ excelData && excelData.length > 0) { downloadExcel({ data: excelData, fileName: "잠재수요처 관리", sheetNameArray: ["Sheet1"], headerRange: "A1:F1" }); - setIsExcelDownload(false); + // setIsExcelDownload(false); } - }, [excelData, isExcelDownload]); + }, [excelData, /*isExcelDownload*/]); const [isExcelOpen, setIsExcelOpen] = useState<{ isModal: boolean; @@ -247,7 +247,7 @@ export default function LdrmntCoSttn() { tableData={bdstTable || []} headlist={ldrmntHeadListExport} pageSize={20} - total={10000} + total={ldrmntResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} /> diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx index 734aca547..73c1bad7d 100644 --- a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx @@ -60,7 +60,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( return { ldrmntInit: async (con: string) => { try { - const ldrmntRes = await getFetch( + const ldrmntRes = await getFetchWithCount( fetchType.WR, `/reuseFc/request/temp/1/20/${con}` ); @@ -70,7 +70,8 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( ...state, ldrmnt: { ...state.ldrmnt, - ldrmntRes: ldrmntRes, + ldrmntRes: ldrmntRes.data, + ldrmntResCount: ldrmntRes.count, isInit: false, excelList: excelDownList, }, @@ -120,7 +121,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( fetchType.WR, searchUrl ); - +console.log("알이에스", ldrmntRes) if (isExcel) { let excelDownList: ExcelType[] = []; ldrmntRes.data.forEach((item: customLdrmnt) => { @@ -139,7 +140,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( ldrmnt: { ...state.ldrmnt, excelList: excelDownList, - + ldrmntResCount: ldrmntRes.count, }, }; }); diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx index 29f68a6d6..fb264f669 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx @@ -77,7 +77,6 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( htdflSttn: { ...state.htdflSttn, excelList: htdflExcel, - htdflSttnResCount: htdflSttnRes.count }, }; }); @@ -119,7 +118,6 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( htdflSttn: { ...state.htdflSttn, excelList: htdflExcel, - htdflSttnResCount: htdflSttnRes.count }, }; }); diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx index 3ad7090ec..6c987298f 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx @@ -153,7 +153,6 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( rainSttn: { ...state.rainSttn, excelList: rainExcel, - rainSttnResCount: rainSttnRes.count, }, }; }); @@ -164,7 +163,6 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( rainSttn: { ...state.rainSttn, rainSttnRes: rainSttnRes.data, - rainSttnResCount: rainSttnRes.count, isInit: false, }, }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx index 9c3eb4a14..442b027e3 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx @@ -1,6 +1,7 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customRswtBdst } from "../../fcltReg/rswtReg"; import { useWrStore } from "@/app/store"; +import { bdstUsgCd } from "@/app/store/common/code/basicCode"; export const excelRSwtSttnParsing = ( excel: customRswtBdst[], @@ -14,7 +15,7 @@ export const excelRSwtSttnParsing = ( sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", item.bdstNm ?? "", item.daddr ?? "", - String(item.bdstUsgCd === -1 || item.bdstUsgCd === undefined ? "확인불가" : item.bdstUsgCd ?? ""), //건축물용도 + bdstUsgCd.find((cd)=> cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 String(item.frstArchPrmsnDt ?? ""), String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]), String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량 diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index 716b4d517..e76095bd5 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -79,7 +79,6 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( rswtSttn: { ...state.rswtSttn, excelList: rswtExcel, - rswtSttnResCount: rswtSttnRes.count, }, }; }); @@ -112,6 +111,12 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (con ? `/${con}` : "/0") + (txt ? `/${txt}` : "") ); + console.log("주소",`/reuseFc/waterreuseFc` + + (page ? `/${page}` : "/1") + + (total ? `/${total}` : "/20") + + (con ? `/${con}` : "/0") + + (txt ? `/${txt}` : "")) + console.log("rswtSttnRes", rswtSttnRes) if (isExcel) { const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); set((state: rswtSttnState) => { @@ -120,7 +125,6 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( rswtSttn: { ...state.rswtSttn, excelList: rswtExcel, - rswtSttnResCount: rswtSttnRes.count, }, }; }); diff --git a/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx b/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx index 36645003e..24fef023c 100644 --- a/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx +++ b/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx @@ -5,7 +5,7 @@ import { names } from "@/app/store/matDmd/ldrmntCoSttn/excel"; import { filePicked, FileUpload, FormUi, Title } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; -import { Button, Progress } from "@common/components/ui"; +import { Button, Input, Progress } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; @@ -13,7 +13,7 @@ import toast from "react-hot-toast"; import type { z } from "zod"; export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => void }) { - const { ldrmnt,loadingOpen } = useWrStore((state) => state); + const { ldrmnt, loadingOpen } = useWrStore((state) => state); const { isLoading } = ldrmnt; const form = useForm<z.infer<typeof coRegExcel>>({ resolver: zodResolver(coRegExcel), @@ -23,6 +23,13 @@ export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => vo const [file, setFiles] = useState<File | undefined>(); + const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { + const selectedFile = e.target.files?.[0]; + if (selectedFile) { + setFiles(selectedFile); + } + }; + const onSubmit = (values: z.infer<typeof coRegExcel>) => { loadingOpen(true); if (file) { @@ -59,7 +66,7 @@ export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => vo alert(e) return true; } - }).catch((e)=>{ + }).catch((e) => { console.log("file", e); }); }; @@ -90,14 +97,13 @@ export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => vo name="file" render={({ field }) => ( <FormUi label=""> - <FileUpload - files={file ? [file] : []} - setFiles={(files: File[] | null) => { - if (files && files?.length === 1) setFiles(files[0]); - }} - fileTypes="" - maxFiles={1} - ></FileUpload> + <div className="space-y-4 p-4"> + <Input + type="file" + onChange={handleFileChange} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" + /> + </div> </FormUi> )} /> From fa258323ecc12919a0d5a21d685234528c9a02e8 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Tue, 8 Jul 2025 22:15:05 +0900 Subject: [PATCH 042/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=ED=98=84=ED=99=A9=20=EC=9D=BC?= =?UTF-8?q?=EB=8B=A8=20=EC=A1=B0=ED=9A=8C=EB=A7=8C=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/coSttn/page.tsx | 26 ++++- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 12 ++- .../prfmncReg/pbnstPrfmncReg/page.tsx | 8 +- .../prfmncReg/chkgdnReg/rainChkgdn/excel.tsx | 101 +++++++++--------- .../store/prfmncReg/pbnstPrfmncReg/index.tsx | 2 +- .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 83 ++++++++------ .../ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx | 28 ++--- 7 files changed, 157 insertions(+), 103 deletions(-) diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index d9fb09031..781a02210 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -71,6 +71,7 @@ export default function CoSttn() { const getSgg = useCallback((val: string | number) => { setObjSearch((prev) => ({ ...prev, sgg: String(val) })); + setPageNation(1) }, []); useEffect(() => { @@ -146,12 +147,19 @@ export default function CoSttn() { if (con) { if (seartchTxt && seartchTxt?.length > 0) { - coSttnTxtSearch("1", "13", String(con), seartchTxt ?? ""); + coSttnTxtSearch(String(pageNation), "13", String(con), seartchTxt ?? ""); } else { - coSttnSearch("1", "13", String(con)); + coSttnSearch(String(pageNation), "13", String(con)); } } }; + + useEffect(() =>{ + + },[pageNation]) + + + return ( <> <ContentsDiv> @@ -166,7 +174,10 @@ export default function CoSttn() { label="시도" selectClass={""} selectArray={code.cityCd || []} - onSelectValue={getSelCity} + onSelectValue={(val)=>{ + getSelCity(val) + setPageNation(1) + } } value={objSearch.city} /> <SelectBox @@ -196,7 +207,6 @@ export default function CoSttn() { size={"sm"} className={btnClass} onClick={() => { - setUpdateData(undefined); setIsDmdModal({ ...isDmdModal, isMoal: true }); }} @@ -243,7 +253,13 @@ export default function CoSttn() { cellClick={(index: number | undefined, headId: string) => { setUpdateData(coSttnRes[index as number]); }} - onPageChange={setPageNation} + onPageChange={(page) =>{ + const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; + setPageNation(page) + coSttnSearch( String(page), "13", String(con)); + + + } } ></UiTable> </ListDiv> </div> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index baafd8053..338ac71f9 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -30,6 +30,7 @@ export default function PbnstSttn() { pbnSttnInit, getPbnStnDetail, pbnNmSearch, + getFlcts } = useWrStore((state) => state); const ref = useRef<ReturnType>({} as ReturnType); @@ -77,13 +78,20 @@ export default function PbnstSttn() { }, [pbnstSttn.excelList]); useEffect(() => { if (!pbnstSttn.isInit) { - pbnSttnInit("1", "20", ref.current, searchYear); + getFlcts() + } }, [pbnstSttn.isInit, pbnSttnInit, ref.current]); useEffect(() => { + + console.log('pbnstSttn.pbnstSttnRes ' ,pbnstSttn.pbnstSttnRes ) setBdstTable(pbnstSttn.pbnstSttnRes); }, [pbnstSttn.pbnstSttnRes]); + useEffect(() =>{ + pbnSttnInit("1", "20", ref.current, searchYear, pbnstSttn.fclts); + },[pbnstSttn.fclts]) + // useEffect(() => { // pbnstSttnSearch("1", "20", ref.current, pbnRuseNm, searchYear); // }, [pageNation, ref.current, pbnRuseNm, searchYear, pbnstSttnSearch]); @@ -94,7 +102,7 @@ export default function PbnstSttn() { // }, [pbnRuseNm,pageNation]); useEffect(() => { - pbnstSttnSearch(false, String(pageNation), "20", returnType, pbnRuseNm, searchYear); + // pbnstSttnSearch(false, String(pageNation), "20", returnType, pbnRuseNm, searchYear); }, [pageNation]); useEffect(() => { diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index c54725ff2..20e3652dd 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -37,7 +37,6 @@ import { type PrfType, } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; -import data from "@common/components/ui/icon-finder/data"; export default function prfmncPrfmncReg() { const { code, prfmnc, prfmncHasuInit, prfmnRegData } = useWrStore( @@ -169,7 +168,12 @@ export default function prfmncPrfmncReg() { } }, [prfmnc.isInit, prfmncHasuInit]); useEffect(() => { - setbdstTable(prfmncRes); + + + if(prfmncRes&&prfmncRes.length>0){ + + setbdstTable(prfmncRes); + } // cellNum이 0일 경우(첫 번째 행)도 유효한 인덱스이므로 undefined 여부만 체크합니다. if (cellNum !== undefined) { diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx index 53b43e0f3..408d746e3 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx @@ -87,9 +87,6 @@ export const buildingToExcelType = ( export const excelToRainChkData = (excelData: any, year: string) => { const errors: string[] = []; const rainChkgdData: rainChkZodType[] = excelData.map((item: any) => { - - - console.log('item ', item) if (item["점검일"] !== undefined) { const checkYmd = item["점검일"].replace(/\./g, "") let vltnDt = item["과태료 부과일(위반일)"] @@ -110,7 +107,6 @@ export const excelToRainChkData = (excelData: any, year: string) => { flg: "RNB", }; }); - return { bdstNm:item["시설명"] ?? "", bdstRuseFcltFk: Number(item["NO"]), @@ -138,64 +134,67 @@ export const excelToRainChkData = (excelData: any, year: string) => { } }).filter((el: any) => el !== undefined); - // ✨ 오류 검사 - 가공된 데이터 기준 - const isInvalidNumber = (val: any) => - val !== undefined && val !== null && val !== "" && isNaN(Number(val)); + return rainChkgdData; + // // ✨ 오류 검사 - 가공된 데이터 기준 + // const isInvalidNumber = (val: any) => + // val !== undefined && val !== null && val !== "" && isNaN(Number(val)); - const isInvalidDate = (val: any) => - typeof val === "string" && !/^\d{4}\.\d{2}\.\d{2}$/.test(val.trim()); + // const isInvalidDate = (val: any) => + // typeof val === "string" && !/^\d{4}\.\d{2}\.\d{2}$/.test(val.trim()); - const buildErrorMessage = (item: any, issues: string[]): string => { - const 시설명 = item.bdstNm ?? ""; - const 점검일 = item.chckYmd ?? ""; - const 이용용도 = item.utztnUsgCd ?? ""; - return `시설명: ${시설명}, 점검일: ${점검일}, 이용용도: ${이용용도} (=> ${issues.join(", ")})`; - }; + // const buildErrorMessage = (item: any, issues: string[]): string => { + // const 시설명 = item.bdstNm ?? ""; + // const 점검일 = item.chckYmd ?? ""; + // const 이용용도 = item.utztnUsgCd ?? ""; + // return `시설명: ${시설명}, 점검일: ${점검일}, 이용용도: ${이용용도} (=> ${issues.join(", ")})`; + // }; - if (rainChkgdData.length > 0) { - rainChkgdData.forEach((rain: any) => { - const item = rain.__origin; // 원본 item - const issues: string[] = []; + // if (rainChkgdData.length > 0) { + // rainChkgdData.forEach((rain: any) => { + // const item = rain.__origin; // 원본 item + // const issues: string[] = []; - if (rain.chckYmd && isInvalidDate(rain.chckYmd)) { - issues.push(`점검일: 날짜 형식 아님 (${rain.chckYmd})`); - } + // if (rain.chckYmd && isInvalidDate(rain.chckYmd)) { + // issues.push(`점검일: 날짜 형식 아님 (${rain.chckYmd})`); + // } - if (rain.vltnDt && isInvalidDate(rain.vltnDt)) { - issues.push(`과태료 부과일(위반일): 날짜 형식 아님 (${rain.vltnDt})`); - } + // if (rain.vltnDt && isInvalidDate(rain.vltnDt)) { + // issues.push(`과태료 부과일(위반일): 날짜 형식 아님 (${rain.vltnDt})`); + // } - // [ - // "연간운영비(원/년)", "PH", "탁도", "총대장균군수", "과태료부과금액(천원)" - // ].forEach((key) => { - // if (isInvalidNumber(item[key])) { - // issues.push(`${key}: 숫자 형식 아님 (${item[key]})`); - // } - // } + // // [ + // // "연간운영비(원/년)", "PH", "탁도", "총대장균군수", "과태료부과금액(천원)" + // // ].forEach((key) => { + // // if (isInvalidNumber(item[key])) { + // // issues.push(`${key}: 숫자 형식 아님 (${item[key]})`); + // // } + // // } - // ); + // // ); - for (let i = 1; i <= 12; i++) { - const month = `${i}월`; - if (isInvalidNumber(item[`대체_${month}`])) { - issues.push(`대체_${month}: 숫자 형식 아님 (${item[`대체_${month}`]})`); - } - if (isInvalidNumber(item[`빗물_${month}`])) { - issues.push(`빗물_${month}: 숫자 형식 아님 (${item[`빗물_${month}`]})`); - } - } + // for (let i = 1; i <= 12; i++) { + // const month = `${i}월`; + // if (isInvalidNumber(item[`대체_${month}`])) { + // issues.push(`대체_${month}: 숫자 형식 아님 (${item[`대체_${month}`]})`); + // } + // if (isInvalidNumber(item[`빗물_${month}`])) { + // issues.push(`빗물_${month}: 숫자 형식 아님 (${item[`빗물_${month}`]})`); + // } + // } - if (issues.length > 0) { - errors.push(buildErrorMessage(item, issues)); - } - }); - } + // if (issues.length > 0) { + // errors.push(buildErrorMessage(item, issues)); + // } + // }); + // } - if (errors.length > 0) { - return { rainChkgdData: [], errors }; - } + // if (errors.length > 0) { + // return { rainChkgdData: [], errors }; + // } - return { rainChkgdData, errors: [] }; + // return { rainChkgdData, errors: [] }; + + return rainChkgdData; }; diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx index 387f56eb7..87007d5f6 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx @@ -68,7 +68,7 @@ const hasuListFetch = async (page: number, sggOrCity: string) => { prfList: data.prfList, }); } - }); + }).filter(Boolean); // undefined 값을 제거합니다. return findData; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 76a13943f..939d2c37a 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -1,5 +1,5 @@ import type { CommonTableProps, TableUpperProps } from "@/app/store/common/type/header"; -import type { z } from "zod"; +import { any, type z } from "zod"; import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList"; import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import { controlHeadView } from "../rainSttn"; @@ -28,6 +28,7 @@ export type pbnstSttnState = { ruseDmdHeadList: TableUpperProps[] ruseFcltHeadList: TableUpperProps[] excelList: []; + fclts:string[] isInit: boolean; }; }; @@ -40,13 +41,15 @@ type pbnstSttnActions = { total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string, + year: string ) => void; + getFlcts:()=>void; pbnSttnInit: ( page: string, total: string, reurnValue: ReturnType, - year: string + year: string, + flcts:string[] ) => void; getPbnStnDetail: (pbnstRuseFcltPk: string) => void; pbnNmSearch: ( @@ -74,6 +77,7 @@ export const pbnstSttnStateExport: pbnstSttnState = { pbnstDetail: {} as customPbnst, pbnstSearchData: [], excelList: [], + fclts:[], isInit: false, }, }; @@ -83,46 +87,49 @@ const hasuListFetch = async ( total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string + year: string, + flcts:string[] ) => { + let url = `/prcsFclt/ruseInfo/`; - let url = ""; if (reurnValue.partValue === "A") { - url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${ + url+=`${page}/${total}/${reurnValue.partValue}/${ // reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue }/0/1/SW` } else if (reurnValue.partValue === "R") { - url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${reurnValue.regionValue + url += `${page}/${total}/${reurnValue.partValue}/${reurnValue.regionValue ? reurnValue.regionValue : reurnValue.unitWaterShedValue ? reurnValue.unitWaterShedValue : reurnValue.middleRegionValue }/0/1/SW` - } else { - url = `/prcsFclt/info/${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue}/0/1/SW` + } else if( reurnValue.partValue === 'G2120'){ + url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue}/0/1/SW` + + }else{ + url += `1/2/A/0/0/1/SW` } if (searchNm && searchNm?.length > 0) { url += "/" + searchNm } - console.log("주소", url) - const pbnList = await getFetch(fetchType.COMMON, url); - console.log("pbnList", pbnList) - const arrayList = pbnList.map((item: pubHasuType) => item.bscFctCd); - console.log("어레이리스트", arrayList) + + const pbnList = await postFectch(url, flcts,fetchType.COMMON); + + const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}`, - arrayList, + flcts, fetchType.WR ); - console.log("getRuseList", getRuseList) const checkWrRegListRes = getRuseList.data; + const count = getRuseList.count; const data: WaterReuseFacility[] = checkWrRegListRes.map( (item: FcPrfType) => { - const findData = pbnList.find( + const findData = pbnList.data.find( (fclt: pubHasuType) => fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11) ); @@ -182,6 +189,8 @@ const hasuListFetch = async ( }; } ); + + console.log('data ', data) return data; }; @@ -189,6 +198,15 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( set: any ) => { return { + getFlcts:async ()=>{ + const fclts= await getFetch(fetchType.WR,'/reuseFc/pubFc') + return set((state: pbnstSttnState) => ({ + pbnstSttn: { + ...state.pbnstSttn, + fclts:fclts + }, + })); + }, pbnstChSttnHead: async ( headList: z.infer<typeof sttnHeadListType> ): Promise<void> => { @@ -211,16 +229,20 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( year: string, ) => { try { - console.log("여기") + + let fclts = [] as any + set((state: pbnstSttnState) => { + fclts = state.pbnstSttn.fclts + }); const pbnstSttnRes = await hasuListFetch( page, total, reurnValue, searchNm, - year + year, + fclts, ); - console.log("pbnstSttnRes", pbnstSttnRes); // if (Number(total) > 9000) { if (isExcel) { const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes); @@ -249,23 +271,24 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log("error", erTxt); } }, - pbnSttnInit: async ( + pbnSttnInit: async( page: string, total: string, reurnValue: ReturnType, - year: string + year: string, + fclts:string[] ) => { try { - const pbnstSttnRes = await hasuListFetch( - page, - total, - reurnValue, - undefined, - year - ); + page, + total, + reurnValue, + undefined, + year, + fclts + ); - set((state: pbnstSttnState) => { + set( (state: pbnstSttnState) => { return { ...state, pbnstSttn: { diff --git a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx index a7b66d811..6ebbe4c6c 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx @@ -71,22 +71,26 @@ export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setI if (file) if (type === "RNB") { filePicked(file, 0).then((res) => { - if (res !== undefined){ + // if (res !== undefined){ - const excelData = excelToRainChkData(res, form.getValues("chckYr")) - - if( excelData&&excelData.errors.length>0){ + const excelData = excelToRainChkData(res, form.getValues("chckYr")) + if(res !== undefined) + setExcelData(excelData) + + // if( excelData&&excelData.errors.length>0){ - excelData.errors.forEach((err) =>{ - toast.error(err) - }) - }else{ + // excelData.errors.forEach((err) =>{ + // toast.error(err) + // }) + // }else{ - setExcelData(excelData.rainChkgdData) - } - } + // } + + // } - }); + + + }) } else if (type === "RST") { filePickedArray(file, 0).then((res) => { if (res && res?.length > 1) { From e0e2530a56d6047365f0b99bff3110b39c5afe7f Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 00:55:28 +0900 Subject: [PATCH 043/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=20=EC=8B=9C=EC=84=A4=ED=98=84=ED=99=A9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C,=20=EC=97=91=EC=85=80=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 60 ++++---- .../ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx | 8 +- .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 145 +++++++++--------- 3 files changed, 109 insertions(+), 104 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 338ac71f9..50f0afeea 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -33,6 +33,7 @@ export default function PbnstSttn() { getFlcts } = useWrStore((state) => state); + const { pbnstSttnRes, fclts,pbnstSttnResCount} =pbnstSttn const ref = useRef<ReturnType>({} as ReturnType); const [searchYear, setSearchYear] = useState<string>( String(new Date().getFullYear()) @@ -49,21 +50,21 @@ export default function PbnstSttn() { const [pbnRuseNm, setPbnRuseNm] = useState<string>(""); const excelClick = useCallback(() => { - pbnstSttnSearch(true, String(pageNation), "20", ref.current, "", searchYear); - }, [pbnstSttnSearch]); + pbnstSttnSearch(true, String(pageNation), "100000", ref.current, pbnRuseNm, searchYear,fclts ); + }, [pbnstSttnSearch,fclts,pbnRuseNm]); const cellCLick = useCallback( (index: number | undefined) => { if ( index !== undefined && - pbnstSttn.pbnstSttnRes && - pbnstSttn.pbnstSttnRes[index] + pbnstSttnRes && + pbnstSttnRes[index] ) { - const pbnstRuseFcltPk = pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk; + const pbnstRuseFcltPk = pbnstSttnRes[index].pbnstRuseFcltPk; getPbnStnDetail(pbnstRuseFcltPk); } }, - [getPbnStnDetail, pbnstSttn.pbnstSttnRes] + [getPbnStnDetail, pbnstSttnRes] ); useEffect(() => { @@ -72,7 +73,8 @@ export default function PbnstSttn() { pbnstSttn.excelList, "하수재이용시설 현황", "sample_pbnstSttn.xlsx", - "A1:U2" + "A1:U2", + 3 ); } }, [pbnstSttn.excelList]); @@ -83,27 +85,16 @@ export default function PbnstSttn() { } }, [pbnstSttn.isInit, pbnSttnInit, ref.current]); useEffect(() => { - - console.log('pbnstSttn.pbnstSttnRes ' ,pbnstSttn.pbnstSttnRes ) - setBdstTable(pbnstSttn.pbnstSttnRes); - }, [pbnstSttn.pbnstSttnRes]); + if(pbnstSttnRes && pbnstSttnRes.length>0) { + setBdstTable(pbnstSttnRes); + }else{ + setBdstTable([]); + } + }, [pbnstSttnRes]); useEffect(() =>{ - pbnSttnInit("1", "20", ref.current, searchYear, pbnstSttn.fclts); - },[pbnstSttn.fclts]) - - // useEffect(() => { - // pbnstSttnSearch("1", "20", ref.current, pbnRuseNm, searchYear); - // }, [pageNation, ref.current, pbnRuseNm, searchYear, pbnstSttnSearch]); - - // useEffect(() => { - // if (pbnRuseNm.length > 1) - // pbnNmSearch(String(pageNation), "23", ref.current, pbnRuseNm, searchYear); - // }, [pbnRuseNm,pageNation]); - - useEffect(() => { - // pbnstSttnSearch(false, String(pageNation), "20", returnType, pbnRuseNm, searchYear); - }, [pageNation]); + pbnSttnInit("1", "15", ref.current, searchYear, pbnstSttn.fclts); + },[fclts]) useEffect(() => { if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk) @@ -165,12 +156,14 @@ export default function PbnstSttn() { </div> } queryClick={function (returnType: ReturnType): void { - console.log("시군구코드", returnType) setReturnType(returnType); - pbnstSttnSearch(false, "1", "20", returnType, pbnRuseNm, searchYear); + pbnstSttnSearch(false, "1", "15", returnType, pbnRuseNm, searchYear, fclts); }} excelClick={excelClick} - initClick={function (): void { }} + initClick={function (): void { + setPbnRuseNm('') + + }} btnClass={btnClass} ref={ref} isAdmin={false} @@ -187,8 +180,8 @@ export default function PbnstSttn() { <HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} /> } headlist={pbnstSttn.pbnstSttHeadList} - pageSize={20} - total={100000} + pageSize={15} + total={pbnstSttnResCount} cellClick={(index: number | undefined, headId: string) => { cellCLick(index); }} @@ -196,10 +189,11 @@ export default function PbnstSttn() { pbnstSttnSearch( false, String(page), - String(20), + String(15), ref.current, pbnRuseNm, - searchYear + searchYear, + fclts ); }} ></UiTable> diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx index 8a1db05a2..d39a63680 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx @@ -13,15 +13,19 @@ export const excelPbnstSttnParsing = (data: any[]): string[][] => { String(item.gugun ?? ""), String(item.bscFctNm ?? ""), String(item.efflWqltStndrdNm ?? ""), - String(item.fctCpc ?? ""), String(item.tel ?? ""), + String(item.fctCpc ?? ""), String(item.ruseUtztnFcltNm ?? ""), String(item.fcltCpct ?? ""), String(item.splyExtraCpct ?? ""), String(item.ruseCpct ?? ""), String(item.usageTotal ?? ""), String(item.inUsage ?? ""), - String(item.outUsage ?? ""), + String(item.outUsage ?? ""), + String(item.operMthd ?? ""), + String(item.rprtvBzenty ?? ""), + String(item.bgngDt ?? ""), + String(item.endDt ?? ""), ]) }) return excelExportData; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 939d2c37a..f54eb5cbd 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -27,6 +27,7 @@ export type pbnstSttnState = { ruseGuranteeHeadList: TableUpperProps[] ruseDmdHeadList: TableUpperProps[] ruseFcltHeadList: TableUpperProps[] + pbnstSttnResCount:number; excelList: []; fclts:string[] isInit: boolean; @@ -41,7 +42,8 @@ type pbnstSttnActions = { total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string + year: string, + fclts:string[] ) => void; getFlcts:()=>void; pbnSttnInit: ( @@ -74,6 +76,7 @@ export const pbnstSttnStateExport: pbnstSttnState = { ruseDmdHeadList: ruseDmdHeadListExport, ruseFcltHeadList: ruseFcltHeadListExport, pbnstSttnRes: [], + pbnstSttnResCount:1, pbnstDetail: {} as customPbnst, pbnstSearchData: [], excelList: [], @@ -104,21 +107,21 @@ const hasuListFetch = async ( ? reurnValue.unitWaterShedValue : reurnValue.middleRegionValue }/0/1/SW` - } else if( reurnValue.partValue === 'G2120'){ - url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue}/0/1/SW` + } else if( reurnValue.partValue === 'G'){ + + console.log('reurnValue.sigunValue ', reurnValue.sidoValue) + + console.log('reurnValue.sigunValue ', reurnValue.sigunValue) + url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW` }else{ url += `1/2/A/0/0/1/SW` - } + if (searchNm && searchNm?.length > 0) { url += "/" + searchNm } - - const pbnList = await postFectch(url, flcts,fetchType.COMMON); - - const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}`, flcts, @@ -133,64 +136,66 @@ const hasuListFetch = async ( (fclt: pubHasuType) => fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11) ); + if(findData){ - const usage = item.prfList.reduce( - (acc, cur) => { - acc.inUsage += - cur.wshwtr + - cur.coolUswtr + - cur.cleanUswtr + - cur.drwtUswtr + - cur.dltnUswtr + - cur.ithlRswtr + - cur.ithlEtcUswtr + - cur.cleanToilUswtr + - cur.resn; - acc.outUsage += - cur.lndwtr + - cur.hydUswtr + - cur.ugwtChr + - cur.farmUswtr + - cur.rvrKeepUswtr + - cur.indstUswtr; - acc.total = acc.inUsage + acc.outUsage; + const usage = item.prfList.reduce( + (acc, cur) => { + acc.inUsage += + cur.wshwtr + + cur.coolUswtr + + cur.cleanUswtr + + cur.drwtUswtr + + cur.dltnUswtr + + cur.ithlRswtr + + cur.ithlEtcUswtr + + cur.cleanToilUswtr + + cur.resn; + acc.outUsage += + cur.lndwtr + + cur.hydUswtr + + cur.ugwtChr + + cur.farmUswtr + + cur.rvrKeepUswtr + + cur.indstUswtr; + acc.total = acc.inUsage + acc.outUsage; + + return acc; + }, + { total: 0, inUsage: 0, outUsage: 0 } + ); + + return { + rvbsn: findData?.rvbsn ||'-', + lgbsn: findData?.lgbsn||'-', + mdmbsn: findData?.mdmbsn||'-', + rgnNm: findData?.rgnNm||'-', + sido: findData?.sido||'-', + gugun: findData?.gugun||'-', + bscFctNm: findData?.bscFctNm||'-', + efflWqltStndrdNm: findData?.efflWqltStndrdNm||'-', + fctCpc: Number(findData?.fctCpc)||0, + tel: findData?.tel ?? "-", + ruseUtztnFcltNm: item?.ruseUtztnFcltNm||'-', + fcltCpct: item?.fcltCpct||'-', + splyExtraCpct: item?.splyExtraCpct||'-', + ruseCpct: item?.ruseCpct||'-', + pbnstRuseFcltPk: item.pbnstRuseFcltPk||'-', + usageTotal: usage?.total, + inUsage: usage?.inUsage, + outUsage: usage?.outUsage, + operMthd: item.operList[0]?.operMthd||'-', + rprtvBzenty: item.operList[0]?.rprtvBzenty, + bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", + endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "", + searchNm: findData?.bscFctNm||'-', + searchPk: findData?.bscFctCd||'-', + prfList: item?.prfList ?? [] + }; + } - return acc; - }, - { total: 0, inUsage: 0, outUsage: 0 } - ); - - return { - rvbsn: findData?.rvbsn, - lgbsn: findData?.lgbsn, - mdmbsn: findData?.mdmbsn, - rgnNm: findData?.rgnNm, - sido: findData?.sido, - gugun: findData?.gugun, - bscFctNm: findData?.bscFctNm, - efflWqltStndrdNm: findData?.efflWqltStndrdNm, - fctCpc: findData.fctCpc, - tel: findData?.tel ?? "-", - ruseUtztnFcltNm: item.ruseUtztnFcltNm, - fcltCpct: item.fcltCpct, - splyExtraCpct: item.splyExtraCpct, - ruseCpct: item.ruseCpct, - pbnstRuseFcltPk: item.pbnstRuseFcltPk, - usageTotal: usage.total, - inUsage: usage.inUsage, - outUsage: usage.outUsage, - operMthd: item.operList[0]?.operMthd, - rprtvBzenty: item.operList[0]?.rprtvBzenty, - bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", - endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "", - searchNm: findData.bscFctNm, - searchPk: findData.bscFctCd, - prfList: item?.prfList ?? [] - }; } - ); + ).filter(Boolean); - console.log('data ', data) return data; }; @@ -227,13 +232,11 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( reurnValue: ReturnType, searchNm: string | undefined, year: string, + fclts:string[] ) => { try { - let fclts = [] as any - set((state: pbnstSttnState) => { - fclts = state.pbnstSttn.fclts - }); + const pbnstSttnRes = await hasuListFetch( page, total, @@ -246,7 +249,6 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( // if (Number(total) > 9000) { if (isExcel) { const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes); - set((state: pbnstSttnState) => { return { ...state, @@ -256,17 +258,20 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }, }; }); - } else + } else{ + set((state: pbnstSttnState) => { return { ...state, pbnstSttn: { ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes, - isInit: false, + pbnstSttnResCount:pbnstSttnRes.length + // isInit: false, }, }; }); + } } catch (erTxt) { console.log("error", erTxt); } @@ -294,6 +299,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( pbnstSttn: { ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes, + pbnstSttnResCount:pbnstSttnRes.length, isInit: false, }, }; @@ -344,6 +350,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( pbnstSttn: { ...state.pbnstSttn, pbnstSearchData: pbnstSttnRes, + pbnstSttnResCount:pbnstSttnRes.length, }, }; }); From 8b6ade0541e7473a597a5c5dc52e001a9cbc8274 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 01:35:29 +0900 Subject: [PATCH 044/159] =?UTF-8?q?=EC=88=98=EC=9A=94=EC=B2=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/coSttn/page.tsx | 55 ++++++++------------ apps/wr/app/store/common/searchCode/index.ts | 3 ++ apps/wr/app/store/matDmd/coSttn/excel.tsx | 7 +-- apps/wr/app/store/matDmd/coSttn/index.tsx | 5 +- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index 781a02210..20a0fa945 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -110,40 +110,32 @@ export default function CoSttn() { } }, [coSttnRes, code]); - // useEffect(() => { - // if (coSttn.excelList.length > 0) { - // if (coSttn.excelList.length === 0) return; - // excelDownload( - // coSttn.excelList, - // "수요처 관리", - // "sample_coSttn.xlsx", - // "A1:H1", - // 2 - // ); - // } - // }, [coSttn.excelList]); + useEffect(() => { + if (coSttn.excelList.length > 0) { + if (coSttn.excelList.length === 0) return; - - const excelClick = useCallback(() => { - // const con = objSearch.sgg ? objSearch.sgg : objSearch.city; - // if (con) coSttnSearch("1", "10000", String(con)); - if(bdstTable){ - const excelData = excelCoSttnParsing(bdstTable); + const coExcel = excelCoSttnParsing(coSttn.excelList, code.cityCd, code.sggCd); excelDownload( - excelData as [], + coExcel as [], "수요처 관리", "sample_coSttn.xlsx", - "A1:G1", + "A1:H1", 2 ); } + }, [coSttn.excelList, code]); - // }, [coSttnSearch, objSearch.city, objSearch.sgg]); -}, [excelDownload, bdstTable]); - const searchClick = () => { + const excelClick = useCallback(() => { const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; + if (con) coSttnSearch("1", "10000", String(con)); + + + }, [coSttnSearch, objSearch.city, objSearch.sgg]); +// }, [excelDownload, bdstTable]); + const searchClick = () => { + const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; if (con) { if (seartchTxt && seartchTxt?.length > 0) { @@ -154,12 +146,6 @@ export default function CoSttn() { } }; - useEffect(() =>{ - - },[pageNation]) - - - return ( <> <ContentsDiv> @@ -249,7 +235,7 @@ export default function CoSttn() { tableData={bdstTable || []} headlist={coSttn.coSttHeadList} pageSize={20} - total={ coSttnResCount || 0 } + total={ coSttnResCount+10 || 0 } cellClick={(index: number | undefined, headId: string) => { setUpdateData(coSttnRes[index as number]); }} @@ -265,7 +251,10 @@ export default function CoSttn() { </div> </div> <UiModal - bodyClass={"w-[40vw] max-w-none h-[90vh]"} + bodyClass={"w-[40vw] max-w-none h-[80vh] "// +upadateData?.dmdInfoPk?'h-[60vh]':'h-[90vh]' + + } + open={isDmdModal.isMoal} onOpenChange={() => { setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); @@ -280,9 +269,9 @@ export default function CoSttn() { }} rtnInputData={ async(data) => { const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; - + console.log('data ', data) if(upadateData?.dmdInfoPk){ - + console.log('data ', data) await updateDemandCompany(data as DemandCompType) coSttnInit("1", "13", String(con)); setIsDmdModal({ isMoal: false, data: data as DemandCompType }); diff --git a/apps/wr/app/store/common/searchCode/index.ts b/apps/wr/app/store/common/searchCode/index.ts index 4e383b4a4..9c0f266ab 100644 --- a/apps/wr/app/store/common/searchCode/index.ts +++ b/apps/wr/app/store/common/searchCode/index.ts @@ -132,6 +132,7 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => { let message = ""; if (response.status === 200) { message = "success"; + toast.success('수요처 정보가 변경되었습니다. ' ) } else { message = "fail"; } @@ -144,6 +145,8 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => { }); } catch (err) { console.log(err); + toast.success('수요처 정보가 오류입니다. ' ) + } }, getRateFee: async (year: string) => { diff --git a/apps/wr/app/store/matDmd/coSttn/excel.tsx b/apps/wr/app/store/matDmd/coSttn/excel.tsx index 3b6d73c8b..e22f71367 100644 --- a/apps/wr/app/store/matDmd/coSttn/excel.tsx +++ b/apps/wr/app/store/matDmd/coSttn/excel.tsx @@ -1,11 +1,12 @@ +import type { SelectDataType } from "@common/business_components/ui"; import moment from "moment"; -export const excelCoSttnParsing = (data: any[]): string[][] => { +export const excelCoSttnParsing = (data: any[],sidoCode:SelectDataType[] , sggCode:SelectDataType[]): string[][] => { const excelExportData: string[][] = []; data.forEach((item) => { excelExportData.push([ - String(item.cityText)??'', - String(item.sggText)??'', + sidoCode.find((sido) => sido.val === item.ctpvCd.toString().trim() )?.text ?? "", + sggCode.find((sgg) => sgg.val === item.sggCd.toString().trim() )?.text ?? "", item.dmdCoNm ?? "", item.daddr ?? "", String(item.dmdInfoPk ?? ""), diff --git a/apps/wr/app/store/matDmd/coSttn/index.tsx b/apps/wr/app/store/matDmd/coSttn/index.tsx index 4c9a7fcce..d80b36420 100644 --- a/apps/wr/app/store/matDmd/coSttn/index.tsx +++ b/apps/wr/app/store/matDmd/coSttn/index.tsx @@ -77,14 +77,13 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( `/reuseFc/request/${pageNo}/${pageCnt}/${con}` ); if (Number(pageCnt) >= 10000) { - const coExcel = excelCoSttnParsing(coSttnRes.data); set((state: coSttnState) => { return { ...state, coSttn: { ...state.coSttn, - excelList: coExcel, - isInit: false, + excelList: coSttnRes.data, + //isInit: false, }, }; }); From 779cc442e84acbcc48a78c91ea936a33cc867e56 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 09:44:19 +0900 Subject: [PATCH 045/159] =?UTF-8?q?=EC=8B=9C=EC=84=A4=EB=AA=85=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx | 3 ++- .../app/store/ruseFcltMng/fcltReg/htdflReg/headList.tsx | 2 +- apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index 5b358977b..426ca7f61 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -118,7 +118,8 @@ export default function Home() { className="" size={"sm"} onClick={(e) => { - rainSearch(searchTxt || "", pageNation, "41"); + rainSearch(searchTxt || "", 1, "41"); + //rainSearch(searchTxt || "", pageNation, "41"); }} > 조회 diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/headList.tsx index da1fa6f09..53c18f56d 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/headList.tsx @@ -3,7 +3,7 @@ import type { TableUpperProps } from "@/app/store/common/type/header"; export const htdTableHeadList: TableUpperProps[] = [ { id: "cityText", title: "시도" }, { id: "sggText", title: "시군구" }, - { id: "bdstNm", title: "발전소명" }, + { id: "bdstNm", title: "시설명" }, { id: "daddr", title: "위치" }, { id: "frstArchPrmsnDt", title: "준공년도" }, { id: "archArea", title: "건축면적" }, diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index bceee1a17..6462231b9 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -180,7 +180,10 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { className={selectClass} placeholder= {type !== "HTB"?"건축물 명 입력하세요":'시설명 입력하세요' } type="text" - {...field} + onChange={(e) => { + field.onChange(e.target.value) + }} + value={field.value} /> </FormUi> )} @@ -215,6 +218,9 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { value: field.value ?? new Date(), onChange: (date: Date | undefined) => field.onChange(date), }} + // modifiers={{ + // disabled: { after: new Date() } + // }} selectClass={"w-full"} ></DatePicker> </FormUi> From 2413cdeb6c25bf5440e7adb136037ab483c6f3ef Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Wed, 9 Jul 2025 10:05:06 +0900 Subject: [PATCH 046/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A1=A4=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 2 +- apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx | 5 ++++- apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index 5e0786f8b..e114d842b 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -154,7 +154,7 @@ export default function HtdflRegForm({ )} </div> </div> - <ScrollArea className="h-[37vh]"> + <ScrollArea className={readonly ? "h-[62vh]" : "h-[53vh]"}> {isModal && htdflForm != undefined ? ( <BdstReg form={form} type="HTB" /> ) : ( diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index 974d9269c..a0d0f5405 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -81,6 +81,9 @@ export default function RainRegForm({ })), }; }; + useEffect(()=>{ + console.log("이즈모달", isModal) + }, []) useEffect(() => { if (grntchBdstCertYn === "N") { @@ -161,7 +164,7 @@ export default function RainRegForm({ )} </div> </div> - <ScrollArea className="h-[37vh]"> + <ScrollArea className={readonly ? "h-[62vh]" : "h-[53vh]"}> {isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>} {isModal ? ( <h1 className="pl-3 text-xl col-span-10 mt-4"> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index f70f4548c..e124ecc6f 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -151,7 +151,7 @@ export default function RswtrRegForm({ )} </div> </div> - <ScrollArea className="h-[37vh]"> + <ScrollArea className={readonly ? "h-[60vh]" : "h-[53vh]"}> {isModal && rswtForm != undefined ? <BdstReg form={form} /> : <></>} {isModal ? ( <h1 className="pl-3 text-xl col-span-10 mt-4 "> From bb70090766287a484d307896f54817d7f1fe59f8 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 10:32:57 +0900 Subject: [PATCH 047/159] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EC=8B=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/ruseFcltMng/fcltReg/rswtReg/index.tsx | 10 ++++++---- .../ui/form/fcltReg/bdstReg/bdstReg.tsx | 11 +++++++---- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 16 ++++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx index 8c3579a5d..e969c7405 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx @@ -30,8 +30,8 @@ import toast from "react-hot-toast"; export const rswtZod = z.object({ bdstInfoPk: z.number().nullish(), - ctpvCd: z.number(), - sggCd: z.number(), + ctpvCd: z.number({ required_error: '시도를 선택하세요.' }), + sggCd: z.number({ required_error: '시군구를 선택하세요.' }), daddr: z.string().default(""), bdstNm: z.string().default(""), frstArchPrmsnDt: z.date().default(() => new Date()), @@ -182,7 +182,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( const chData = await makeRstr(data); const res = await postFectch("/reuseFc/waterreuseFc", chData); if (res.status===200) { - if(data.chgBuilding ){ + if(data.chgBuilding.length>0 ){ const chPK = res?.data?.bdstInfoPk const makeCh= res.data.chgBuilding.map((item: chgBuilding) => @@ -194,7 +194,9 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( const chch= await postFectch("/reuseFc/chgBuilding", makeCh); if(chch.status ===200) { - toast.success("건축물 등록이 완료되었습니다."); + + console.log('chch.status' , chch.status) + toast.success("건축물 및 증축/개축/중축 등록이 완료되었습니다."); }else{ toast.error("건축물 증축/개축/중축 오류입니다."); } diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index 6462231b9..188b1380a 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -183,7 +183,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { onChange={(e) => { field.onChange(e.target.value) }} - value={field.value} + value={field.value||''} /> </FormUi> )} @@ -199,7 +199,10 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { className={selectClass} placeholder="위치를 입력해주세요" type="search" - {...field} + onChange={(e) => { + field.onChange(e.target.value) + }} + value={field.value||''} /> </FormUi> )} @@ -266,7 +269,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { onChange={(e) => { field.onChange(e.target.value) }} - value={field.value} + value={field.value||''} /> </FormUi> )} @@ -364,7 +367,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { placeholder="-" type="text" onChange={(e) => f.onChange} - value={f.value} + value={f.value||''} className={selectClass} /> </FormUi> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index f70f4548c..d37049445 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -80,7 +80,7 @@ export default function RswtrRegForm({ instlCmptnDt: item?.instlCmptnDt ? new Date(item.instlCmptnDt) : new Date(), // item?.instlCmptnDt가 유효하지 않으면 현재 날짜로 초기화 - operMngCd: item?.operMngCd ?? "", // null → "" + operMngCd: item?.operMngCd || "", // null → "" instlCstSprtYn: item?.instlCstSprtYn || code.yn[0]?.val, // null → "Y" grntchBdstCertYn: item?.grntchBdstCertYn || code.yn[0]?.val, rswtrObj: { @@ -192,7 +192,7 @@ export default function RswtrRegForm({ const value = field.value; const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 return ( - <FormUi label="설치비"> + <FormUi label="설치비(원)"> <Input className={selectClass} placeholder="1,000,000" @@ -271,7 +271,7 @@ export default function RswtrRegForm({ selectClass={selectClass} selectArray={code.orgwtKndCd} onSelectValue={readonly ? () => { } : field.onChange} - value={field.value ?? code.orgwtKndCd[0]?.val} + value={field.value || code.orgwtKndCd[0]?.val} readOnly={readonly} /> </FormUi> @@ -290,7 +290,7 @@ export default function RswtrRegForm({ label={""} selectArray={code.rswtPrscCdMthdCd} onSelectValue={readonly ? () => { } : field.onChange} - value={field.value ?? code.rswtPrscCdMthdCd[0]?.val} + value={field.value || code.rswtPrscCdMthdCd[0]?.val} readOnly={readonly} /> </FormUi> @@ -303,7 +303,7 @@ export default function RswtrRegForm({ <h1 className={formH1Class}>인센티브 정보</h1> </div> <div> - <h2 className={formH2Class}>설치비 지원</h2> + <h2 className={formH2Class}>설치비(원) 지원</h2> </div> <div className="grid grid-cols-2 gap-2 mt-4"> <div className="col-span-1"> @@ -311,14 +311,14 @@ export default function RswtrRegForm({ control={form.control} name="reuseBuilding.0.instlCstSprtYn" render={({ field }) => ( - <FormUi label="설치비 지원여부"> + <FormUi label="설치비(원) 지원여부"> <SelectBox className={""} selectClass={selectClass} label={""} selectArray={code.bdstIncenYn} onSelectValue={readonly ? () => { } : field.onChange} - value={field.value ?? code.bdstIncenYn[0]?.val} + value={field.value || code.bdstIncenYn[0]?.val} readOnly={readonly} /> </FormUi> @@ -471,7 +471,7 @@ export default function RswtrRegForm({ label={""} selectArray={code.bdstGrntchClass} onSelectValue={readonly ? () => { } : field.onChange} - value={field.value ?? code.bdstGrntchClass[0]?.val} + value={field.value || code.bdstGrntchClass[0]?.val} readOnly={readonly} /> </FormUi> From 1846873602aa904a28ee0b1c424ad5b6479dc419 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Wed, 9 Jul 2025 10:57:02 +0900 Subject: [PATCH 048/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A1=A4=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=9E=AC=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 14 ++++++++++++-- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 13 ++++++++++++- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 15 ++++++++++++--- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index e114d842b..34163d65f 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -16,7 +16,7 @@ import { hdtflZod, type customHtdflBdst, } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import BdstReg from "../bdstReg/bdstReg"; import { formatCommaNumber, @@ -89,6 +89,16 @@ export default function HtdflRegForm({ })), }; }; + const [divStyle, setDivStyle] = useState("h-[53vh]"); + useEffect(()=>{ + if(isModal===true){ + setDivStyle("h-[53vh] max-h-[37vh]") + }else if(readonly===true){ + setDivStyle("h-[62vh]") + }else{ + setDivStyle("h-[53vh]") + } + },[isModal,readonly]); useEffect(() => { console.log("form errors:", form.formState.errors); @@ -154,7 +164,7 @@ export default function HtdflRegForm({ )} </div> </div> - <ScrollArea className={readonly ? "h-[62vh]" : "h-[53vh]"}> + <ScrollArea className={divStyle}> {isModal && htdflForm != undefined ? ( <BdstReg form={form} type="HTB" /> ) : ( diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index a0d0f5405..099d9efb1 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -49,6 +49,17 @@ export default function RainRegForm({ "reuseBuilding.0.rainyObj.filtrTrtmfctYn", ]); + const [divStyle, setDivStyle] = useState("h-[53vh]"); + useEffect(()=>{ + if(isModal===true){ + setDivStyle("h-[53vh] max-h-[37vh]") + }else if(readonly===true){ + setDivStyle("h-[62vh]") + }else{ + setDivStyle("h-[53vh]") + } + },[isModal,readonly]); + const cleanRainData = (raw: any): z.infer<typeof rainZod> => { const buildings = raw?.reuseBuilding && raw.reuseBuilding.length > 0 @@ -164,7 +175,7 @@ export default function RainRegForm({ )} </div> </div> - <ScrollArea className={readonly ? "h-[62vh]" : "h-[53vh]"}> + <ScrollArea className={divStyle}> {isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>} {isModal ? ( <h1 className="pl-3 text-xl col-span-10 mt-4"> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index e124ecc6f..3a10bf839 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -21,7 +21,7 @@ import { } from "@common/business_components/ui"; import { Button, Input, ScrollArea } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useForm, type UseFormReturn } from "react-hook-form"; import { z } from "zod"; import BdstReg from "../bdstReg/bdstReg"; @@ -40,7 +40,16 @@ export default function RswtrRegForm({ const { rswt, code, rswtBdstUpdate, rswtBdstReg } = useWrStore( (state) => state ); - + const [divStyle, setDivStyle] = useState("h-[53vh]"); + useEffect(()=>{ + if(isModal===true){ + setDivStyle("h-[53vh] max-h-[37vh]") + }else if(readonly===true){ + setDivStyle("h-[62vh]") + }else{ + setDivStyle("h-[53vh]") + } + },[isModal,readonly]); // const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({}); const form = useForm<z.infer<typeof rswtZod>>({ @@ -151,7 +160,7 @@ export default function RswtrRegForm({ )} </div> </div> - <ScrollArea className={readonly ? "h-[60vh]" : "h-[53vh]"}> + <ScrollArea className={divStyle}> {isModal && rswtForm != undefined ? <BdstReg form={form} /> : <></>} {isModal ? ( <h1 className="pl-3 text-xl col-span-10 mt-4 "> From b444f24d41ae6a300fb32abb9345ac9bd618b5a6 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 11:37:46 +0900 Subject: [PATCH 049/159] =?UTF-8?q?=EC=A7=80=EB=8F=84=EC=A0=90=EA=B2=80=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EB=93=B1=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/prfmncReg/chkgdnReg/page.tsx | 35 +++++++++++-------- .../prfmncReg/chkgdnReg/rainChkgdn/index.tsx | 20 +++++------ .../prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx | 15 ++++---- .../ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx | 10 +++--- .../ui/modal/chkgd/chkgdModal/chkgdModal.tsx | 1 + 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index 0ac9145a5..ecd2fd0f6 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -92,6 +92,7 @@ export default function Page() { commonCd, fcltNm ); + setRainPageNation(1); } else { rainChkInit(rainPageNation, rainPageSize, searchYear, commonCd); } @@ -104,6 +105,7 @@ export default function Page() { commonCd, fcltNm ); + setRswtPageNation(1); } else { rswtChkgdnInit(rswtPageNation, rswtPageSize, searchYear, commonCd); } @@ -202,22 +204,22 @@ export default function Page() { const clickDelete = (data: number[], selFcltDiv: string) => { if (data.length > 0) { if (selFcltDiv === "RNB") { - rainChkDelete(data); + rainChkDelete(data, searchYear); } else { - rswtChkDelete(data); + rswtChkDelete(data, searchYear); } } }; const chkUpdateTable = (selFcltDiv: string) => { if (selFcltDiv === "RNB") { if (updateRainDetail && updateRainDetail.length > 0) { - rainChkDetilUpdate(updateRainDetail); - } else { + rainChkDetilUpdate(updateRainDetail, searchYear); + } else { toast.error("수정을 원하는 행을 선택하고 저장버튼을 눌러주세요 "); } } else { if (updateRswtDetail && updateRswtDetail.length > 0) { - rswtChkDetilsUpdate(updateRswtDetail); + rswtChkDetilsUpdate(updateRswtDetail, searchYear); } else { toast.error("수정을 원하는 행을 선택하고 저장버튼을 눌러주세요 "); } @@ -297,14 +299,14 @@ export default function Page() { <TooltipProvider> <Tooltip> <TooltipTrigger asChild> - <Button - size={"sm"} - onClick={() => { - chkUpdateTable(selFcltDiv); - }} - > - 저장 - </Button> + <Button + size={"sm"} + onClick={() => { + chkUpdateTable(selFcltDiv); + }} + > + 저장 + </Button> </TooltipTrigger> <TooltipContent side="bottom" sideOffset={5}> <h2 className="text-xl"> @@ -314,7 +316,6 @@ export default function Page() { </Tooltip> </TooltipProvider> - <Button size={"sm"} onClick={() => { @@ -343,7 +344,8 @@ export default function Page() { rainChkData={rainChkgdn.rainChk} pageNation={rainPageNation} onPageChange={rainPageChange} - pageCount={rainChkgdn.rainChkCount} /> + pageCount={rainChkgdn.rainChkCount} + /> ) : ( <RswtChkgdTable detaiRswtlUpdate={setUpdateRSwtDetail} @@ -380,6 +382,9 @@ export default function Page() { <ChkgdExcel type={selFcltDiv} setIsRegExcel={setIsRegExcel} + setYearChange={(year) => { + setSearchYear(year); + }} ></ChkgdExcel> } /> diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx index 069f1f760..11a88b9ef 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx @@ -68,14 +68,14 @@ type rainChkgdnActions = { sggCd: string, searchTxt: string ) => void; - rainChkDetilUpdate(rainChk: rainChkZodType[]): Promise<void>; + rainChkDetilUpdate(rainChk: rainChkZodType[] ,year:string) : Promise<void>; rainChkGuidUpdate(rainChk: rainChkZodType): Promise<void>; rainChkExcelDownload( sidoCode: SelectDataType[], sggCode: SelectDataType[] ): Promise<void>; - rainChkExcelDataUPload(excelData: rainChkZodType[]): Promise<void>; - rainChkDelete(chkgdnPks: number[]): Promise<void>; + rainChkExcelDataUPload(excelData: rainChkZodType[] ,year :string) : Promise<void>; + rainChkDelete(chkgdnPks: number[] ,year :string): Promise<void>; rainChkHeadChange: (rainChkgdn: rainChkgdnState, isEdit: boolean) => void; rainChkNmSearch: ( pageNo: number, @@ -165,7 +165,7 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( }, })); }, - rainChkExcelDataUPload: async (excelData: rainChkZodType[]) => { + rainChkExcelDataUPload: async (excelData: rainChkZodType[] ,year:string) => { set((state: rainChkgdnType) => ( { rainChkgdn: { ...state.rainChkgdn, isLoading: true } })); try { @@ -175,7 +175,7 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( const rainChkRes = await initFetch( 1, rainPageSize, - currentYear, + year, commonCd ); set((state: rainChkgdnState) => ({ @@ -255,7 +255,7 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( console.log(error); } }, - rainChkDetilUpdate: async (rainChk: rainChkZodType[]) => { + rainChkDetilUpdate: async (rainChk: rainChkZodType[] ,year:string) => { try { const chData = await makeMdfrChk(rainChk, "rain", "rainDetil"); @@ -264,11 +264,10 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( toast.success( "지도점검 대체수 및 밋물이용량 수정이 완료되었습니다. " ); - const currentYear = new Date().getFullYear().toString(); const rainChkRes = await initFetch( 1, rainPageSize, - currentYear, + year, "41" ); return set((state: rainChkgdnState) => ({ @@ -317,18 +316,17 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( toast.error("지도점검 수질 및 과태료 수정 오류입니다."); } }, - rainChkDelete: async (chkgdnPks: number[]) => { + rainChkDelete: async (chkgdnPks: number[] ,year :string) => { try { const res = await deleteFectch(`/reuseChk/rainy`, chkgdnPks); if (res) { toast.success("삭제가 완료되었습니다. "); - const currentYear = new Date().getFullYear().toString(); const rainChkRes = await initFetch( 1, rainPageSize, - currentYear, + year, "41" ); return set((state: rainChkgdnState) => ({ diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx index 4f647da1e..d43abb49e 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx @@ -78,8 +78,8 @@ type rswtChkgdnActions = { sggCode: SelectDataType[] ): Promise<void>; rswtChkExceDataUpload: (excelData: rswtChkZodType[]) => void; - rswtChkDelete: (chkgdnPks: number[]) => void; - rswtChkDetilsUpdate: (rswtChkDetails: rswtrChkDetailsZodType[]) => void; + rswtChkDelete: (chkgdnPks: number[] ,year:string) => void; + rswtChkDetilsUpdate: (rswtChkDetails: rswtrChkDetailsZodType[] ,year:string) => void; rswtChkPolAndGuide: (chkGdnPk: number) => void; rswtChkPolInit: () => void; rwstPolAndGuideUpdate: (rswtChk: rswtChkZodType[]) => void; @@ -189,7 +189,6 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( try { const rswtChkRes = await initFetch(pageNo, cnt, year, sggCd); - console.log("rswtChkRes", rswtChkRes) set((state: rswtChkgdnState) => ({ ...state, @@ -271,7 +270,7 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( } }, - rswtChkDetilsUpdate: async (rswtChk: rswtrChkDetailsZodType[]) => { + rswtChkDetilsUpdate: async (rswtChk: rswtrChkDetailsZodType[] ,year:string) => { try { const chData = await makeMdfrChk(rswtChk); @@ -279,8 +278,7 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( if (res.ok) { toast.success("지도점검 과태료 수정이 완료되었습니다. ",) } - const currentYear = new Date().getFullYear().toString(); - const rswtChkRes = await initFetch(1, rswtPageSize, currentYear, "0"); + const rswtChkRes = await initFetch(1, rswtPageSize, year, "0"); return set((state: rswtChkgdnState) => ({ ...state, rswtChkgdn: { @@ -295,15 +293,14 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( } }, - rswtChkDelete: async (chkgdnPks: number[]) => { + rswtChkDelete: async (chkgdnPks: number[] ,year:string) => { try { const res = await deleteFectch(`/reuseChk/reuseWater`, chkgdnPks); if (res) { toast.success("삭제가 완료되었습니다.") } - const currentYear = new Date().getFullYear().toString(); - const rswtChkRes = await initFetch(1, rswtPageSize, currentYear, "0"); + const rswtChkRes = await initFetch(1, rswtPageSize, year, "0"); return set((state: rswtChkgdnState) => ({ ...state, rswtChkgdn: { diff --git a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx index 6ebbe4c6c..7d8883805 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx @@ -23,7 +23,7 @@ import { useForm } from "react-hook-form"; import toast from "react-hot-toast"; import type { z } from "zod"; -export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setIsRegExcel:(open:boolean) =>void }) { +export default function ChkgdExcel({ type,setIsRegExcel ,setYearChange }: { type: string, setIsRegExcel:(open:boolean) =>void ,setYearChange:(year:string)=> void }) { const { rswtChkgdn, rainChkExcelDataUPload, rswtChkExceDataUpload } = useWrStore((state) => { return state; @@ -76,7 +76,6 @@ export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setI const excelData = excelToRainChkData(res, form.getValues("chckYr")) if(res !== undefined) setExcelData(excelData) - // if( excelData&&excelData.errors.length>0){ // excelData.errors.forEach((err) =>{ @@ -169,9 +168,9 @@ export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setI return; } else { - - rainChkExcelDataUPload(excelData as rainChkZodType[]); + rainChkExcelDataUPload(excelData as rainChkZodType[] , form.getValues("chckYr")) ; setIsRegExcel(false) + setYearChange(form.getValues("chckYr")) } } else if (type === "RST") { if (excelRswtData === undefined || excelRswtData?.length === 0) { @@ -181,10 +180,11 @@ export default function ChkgdExcel({ type,setIsRegExcel }: { type: string, setI } else { rswtChkExceDataUpload(excelRswtData as rswtChkZodType[]); setIsRegExcel(false) + setYearChange(form.getValues("chckYr")) + } } } - }; return ( <> diff --git a/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx b/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx index edbd9e570..2b74cf8af 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx @@ -213,6 +213,7 @@ export default function ChkgdModal({ type, obj, setIsModal }: { type: string; ob }); obj.guideDetails = realGuideDetail; if (type === "RNB") { + rainChkGuidUpdate(obj); setIsModal(false) } else { From 9b2e7c19e661606ba7afdf6bf9896efa1b10308b Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Wed, 9 Jul 2025 11:41:53 +0900 Subject: [PATCH 050/159] =?UTF-8?q?=ED=98=84=ED=99=A9=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=85=80=20=ED=81=B4=EB=A6=AD=ED=95=98=EB=A9=B4=20=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=ED=99=95=EB=8C=80=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 65 ++++++++++++++++-------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index cd9bb8e00..92b3100aa 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -116,7 +116,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ data:any | undefined; }>({ data: undefined }); const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); - const [selectRow, setSelectRow] = useState<pubHasuType>(); const [hasuPage, setHasuPage] = useState<number>(1); if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// @@ -141,19 +140,19 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ else if (layerId == '중수도시설') { featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) - rswtSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + rswtSttnSearch(true,1, '20', '', featureCd, code.cityCd, code.sggCd); setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); } else if (layerId == '온배수시설') { featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) - htdflSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + htdflSttnSearch(true,1, '20', '', featureCd, code.cityCd, code.sggCd); setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); } else if (layerId == '하수처리시설') { featureCd = selectedVal?.swtrmt_fclt_nm; setFcltPk(featureCd); // 현재 호출된 featureCd 저장 - const res = fetchHasuDetail(featureCd,selectedVal?.swtrmt_fclt_cd); + fetchHasuDetail(featureCd,selectedVal?.swtrmt_fclt_cd); }; setViewMode("detail") @@ -171,11 +170,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnstSttn.pbnstSttnRes[index] ) { setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); - fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - // onFeatureSelect(pbnstSttn.pbnstSttnRes[index]); - setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - setViewMode("detail") - // onClose() + // fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) + onFeatureSelect(pbnstSttn.pbnstSttnRes[index]); + // setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) + // setViewMode("detail") + onClose() } }; const getSelectedLayers = () => { @@ -273,10 +272,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ index !== undefined && rainTable !== undefined && headId !== 'chBuildingYn') { - setRainDetailModal({ isOpen: true, data: rainTable[index] }) - setViewMode('detail') - // onFeatureSelect(rainTable[index]); - // onClose(); + // setRainDetailModal({ isOpen: true, data: rainTable[index] }) + // setViewMode('detail') + onFeatureSelect(rainTable[index]); + onClose(); } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); @@ -329,8 +328,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 중수도시설 cellClick 이벤트 (상세정보) const rswtCellClick = (index: number | undefined, headId: string) => { if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { - setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] }); - setViewMode('detail') + // setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] }); + // setViewMode('detail') + onFeatureSelect(rswtrTable[index]); + onClose(); } else if (headId === 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { if (rswtrTable[index] && rswtrTable[index]?.chBuildingYn === 'Y') { setRswtrBdstChgProps({ isOpen: true, chBuilding: rswtrTable[index].chgBuilding }); @@ -339,7 +340,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } useEffect(() => { if (!rswtSttn.isInit) { - rswtSttnInit(1, "20", "0", '', code.cityCd, code.sggCd); + rswtSttnInit(false,1, "20", "0", '', code.cityCd, code.sggCd); + console.log('rswtSttnInit', rswtSttnRes); } }, [rswtSttn.isInit, rswtSttnInit]); @@ -361,8 +363,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ (item: customRswtBdst) => item.reuseBuilding[0]?.rswtrObj !== undefined ); - - setRswtrTable(chData); + setRswtrTable(chData); }, [code, rswtSttnRes]); // 엑셀 관련 const rswtSttnExcelDownload = useCallback(() => { @@ -378,20 +379,18 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [rswtSttn.excelList]) useEffect(() => { - rswtSttnSearch(rswtrPage, "20", '', '', code.cityCd, code.sggCd); + rswtSttnSearch(false,rswtrPage, "20", '', '', code.cityCd, code.sggCd); }, [rswtrPage]); ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 온배수시설 cellClick 이벤트 (상세정보) const htdflCellClick = (index: number | undefined, headId: string) => { - if ( - headId !== "chBuildingYn" && - index !== undefined && - htdflTable !== undefined - ) { - setHtdflDetailModal({ isOpen: true, data: htdflTable[index] }); - setViewMode('detail') + if (index !== undefined && htdflTable !== undefined) { + // setHtdflDetailModal({ isOpen: true, data: htdflTable[index] }); + // setViewMode('detail') + onFeatureSelect(htdflTable[index]); + onClose(); } }; useEffect(() => { @@ -414,10 +413,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]); useEffect(() => { - htdflSttnSearch(htdflPage, "20", '', '', code.cityCd, code.sggCd); + htdflSttnSearch(true,htdflPage, "20", '', '', code.cityCd, code.sggCd); }, [htdflPage]); ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// + ///////////////////////////////////////////// 하수처리 시설 ////////////////////////////////////////////////// useEffect(() => { if (code.sggCd.length && pbnstHasuRes.length > 0) { setHasuTable(tableData(pbnstHasuRes, { code })); @@ -442,14 +442,19 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; }); pbnstHasuRes = hasuList - // console.log(hasuList) if(pbnstHasuRes.length >0)setIsRuseReg({ data:[pbnstHasuRes[0]] }); - console.log(pbnstHasuRes) } catch (error) { console.error("Error fetching data:", error); } }; + const hasuCellClick = (index: number | undefined, headId: string) => { + if (index !== undefined && pbnstHasuRes !== undefined) { + onFeatureSelect(pbnstHasuRes[index]); + onClose(); + } + }; +///////////////////////////////////////////// 하수처리 시설 ////////////////////////////////////////////////// // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { @@ -482,7 +487,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pageSize={10} total={100000} headName={""} - cellClick={() => { }} + cellClick={hasuCellClick} onPageChange={setHasuPage} children={undefined} /> From 618e838d6abf41c22860369a5b2db171692f33e3 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Wed, 9 Jul 2025 13:19:16 +0900 Subject: [PATCH 051/159] =?UTF-8?q?=ED=8C=9D=EC=97=85=20=ED=98=84=ED=99=A9?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=84=A0=ED=83=9D=20=EC=8B=9C=20=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=ED=99=95=EB=8C=80=20=EC=9D=B4=EB=8F=99=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/htdflSttn/page.tsx | 1 + apps/wr/app/map/newWindowPopup.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/wr/app/map/htdflSttn/page.tsx b/apps/wr/app/map/htdflSttn/page.tsx index b3a030421..b7935ee99 100644 --- a/apps/wr/app/map/htdflSttn/page.tsx +++ b/apps/wr/app/map/htdflSttn/page.tsx @@ -152,6 +152,7 @@ const Map = () => { isOpen={isOpen} isSearchModalOpen={isSearchModalOpen} onCheckedLayersChange={handleCheckedLayersChange} + imgVisble={true} /> </div> ); diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 92b3100aa..c46276e15 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -235,7 +235,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 재이용시설 페이징처리 관련 함수 const onPageChangeHandler = useCallback((page: number) => { pbnstSttnSearch( - true, + false, String(page), String(13), { From 6d18785c9cb4da59b2f041577813e5cabfc23315 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 13:54:32 +0900 Subject: [PATCH 052/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=20=EC=8B=9C=EC=84=A4=20=EB=93=B1=EB=A1=9D=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=84=A4=EC=9D=B4=EC=85=98=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncReg/pbnstPrfmncReg/page.tsx | 29 ++++++--- .../store/prfmncReg/pbnstPrfmncReg/index.tsx | 62 ++++++++++++++----- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 20e3652dd..5ea418634 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -39,10 +39,10 @@ import { import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; export default function prfmncPrfmncReg() { - const { code, prfmnc, prfmncHasuInit, prfmnRegData } = useWrStore( + const { code, prfmnc, prfmncHasuInit, prfmnRegData,prfmncHasuNmSearch } = useWrStore( (state) => state ); - const { pbnstPrfmncHeadList, monthHeadList, prfmncRes } = prfmnc; + const { pbnstPrfmncHeadList, monthHeadList, prfmncRes,prfmncResCount } = prfmnc; const [bdstTable, setbdstTable] = useState<FcPrfType[]>(); const [searchTxt, setSearchTxt] = useState<string>(); const [isExcelOpen, setIsExcelOPen] = useState<{ @@ -164,7 +164,8 @@ export default function prfmncPrfmncReg() { useEffect(() => { if (!prfmnc.isInit) { - prfmncHasuInit(1, "41"); + const year = new Date().getFullYear() + prfmncHasuInit(1, "41",String(year)); } }, [prfmnc.isInit, prfmncHasuInit]); useEffect(() => { @@ -221,7 +222,17 @@ export default function prfmncPrfmncReg() { <SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> <div className="space-y"> <div className="flex flex-row space-x-2"> - <Button size={"sm"} onClick={(e) => {}}> + <Button size={"sm"} onClick={(e) => { + + if(searchTxt&&searchTxt?.length>0){ + prfmncHasuNmSearch(1,'41',searchYear,searchTxt) + setPageNation(1) + }else{ + prfmncHasuInit(1,'41',searchYear) + setPageNation(1) + } + + }}> 조회 </Button> <Button @@ -264,13 +275,17 @@ export default function prfmncPrfmncReg() { tableData={bdstTable || []} headlist={pbnstPrfmncHeadList} pageSize={10} - total={10000} + total={prfmncResCount} headName={"하수재이용시설 목록"} cellClick={(index: number | undefined, headId: string) => { cellClick(index); setCellNum(index ?? 0); }} - onPageChange={setPageNation} + onPageChange={ + (page) =>{ + prfmncHasuInit(page, "41",searchYear); + setPageNation(page) + }} children={undefined} /> </ScrollArea> @@ -303,11 +318,11 @@ export default function prfmncPrfmncReg() { data={isExcelOpen.data} setIsExcelOPen={(open) => { setIsExcelOPen({ ...isExcelOpen, isModal: open }) - }} setModalExcelData={ async(excelData ) =>{ await prfmnRegData(pageNation,'41', excelData, + searchYear ); // 데이터 저장 후 UI 업데이트는 useEffect가 감지하여 처리하므로 여기서는 호출하지 않습니다. } diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx index 87007d5f6..eea31c334 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx @@ -15,6 +15,7 @@ export type pbnstPrfmncState = { pbnstPrfmncHeadList: TableUpperProps[]; monthHeadList: TableUpperProps[]; prfmncRes: FcPrfType[]; + prfmncResCount:number; excelList: Number[]; pageKey:number }; @@ -26,6 +27,7 @@ export const pbnstPrfmncStateExport: pbnstPrfmncState = { pbnstPrfmncHeadList: pbnstPrfmncHeadList, monthHeadList: monthHeadList, prfmncRes: [], + prfmncResCount:1, excelList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], pageKey:1 }, @@ -34,16 +36,23 @@ export const pbnstPrfmncStateExport: pbnstPrfmncState = { export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions; type pbnstPrfmncActions = { - prfmncHasuInit: (page: number, sggOrCity: string) => void; - prfmnRegData: (page:number,sggOrCity:string, data: PrfType) => void; + prfmncHasuInit: (page: number, sggOrCity: string ,year:string) => void; + prfmncHasuNmSearch: (page: number, sggOrCity: string , txt:string ,year:string) => void; + prfmnRegData: (page:number,sggOrCity:string, data: PrfType,year:string) => void; }; -const checkWrRegList = async () => { - const wrRegList = await getFetch("wr", `/reuseFc/pubDetailList`); +const checkWrRegList = async (year:string) => { + + let url =`/reuseFc/pubDetailList` + + if(year&& year.length>0){ + // url+=`/${year}` + } + const wrRegList = await getFetch("wr", url); return wrRegList; }; -const hasuListFetch = async (page: number, sggOrCity: string) => { - const checkWrRegListRes = await checkWrRegList(); +const hasuListFetch = async (page: number, sggOrCity: string , year:string,searchNm?:string ) => { + const checkWrRegListRes = await checkWrRegList(year); const rainRes = await postFectch( `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`, checkWrRegListRes?.fcltCds, @@ -51,7 +60,7 @@ const hasuListFetch = async (page: number, sggOrCity: string) => { ); - const findData = rainRes.data.map((item: pubHasuType) => { + let findData = rainRes.data.map((item: pubHasuType) => { const data = checkWrRegListRes?.fcPrfList.find( (fclt: FcPrfType) => fclt.pbnstRuseFcltPk.substring(0, 11) === item?.bscFctCd @@ -70,20 +79,26 @@ const hasuListFetch = async (page: number, sggOrCity: string) => { } }).filter(Boolean); // undefined 값을 제거합니다. - return findData; + if(searchNm){ + + findData= findData.filter((ruse:any) => ruse.ruseUtztnFcltNm.includes(searchNm)) + } + + return {data:findData, count:findData.length}; }; export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = ( set: any ) => { return { - prfmncHasuInit: async (page: number, sggOrCity: string) => { + prfmncHasuInit: async (page: number, sggOrCity: string,year:string) => { try { - const prfmncRes = await hasuListFetch(page, sggOrCity); + const prfmncRes = await hasuListFetch(page, sggOrCity, year); return set((state: pbnstPrfmncState) => ({ ...state, prfmnc: { ...state.prfmnc, - prfmncRes: prfmncRes, + prfmncRes: prfmncRes.data, + prfmncResCount: prfmncRes.count, isInit: false, }, })); @@ -91,7 +106,23 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = ( console.log(errorHasu); } }, - prfmnRegData: async (page:number,sggOrCity:string,data: PrfType) => { + prfmncHasuNmSearch: async (page: number, sggOrCity: string,fcltNm:string ,year:string)=> { + try { + const prfmncRes = await hasuListFetch(page, sggOrCity,fcltNm ,year); + return set((state: pbnstPrfmncState) => ({ + ...state, + prfmnc: { + ...state.prfmnc, + prfmncRes: prfmncRes.data, + prfmncResCount: prfmncRes.count, + isInit: false, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, + prfmnRegData: async (page:number,sggOrCity:string,data: PrfType,year:string) => { try { const ressponse = await postFectch( "/reuseFc/pubFcPrf", @@ -102,12 +133,15 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = ( if (ressponse.status === 200) { toast.success("하수재이용 시설 실적 등록이 완료되었습니다."); - const prfmncRes = await hasuListFetch(page, sggOrCity); + const prfmncRes = await hasuListFetch(page, sggOrCity,year) ; + + return set((state: pbnstPrfmncState) => ({ ...state, prfmnc: { ...state.prfmnc, - prfmncRes: prfmncRes, + prfmncRes: prfmncRes.data, + prfmncResCount: prfmncRes.count, isInit: false, pageKey: state.prfmnc.pageKey + 1 }, From 38461d8a40b9bcdb2dc96d823baf7746bf54bba7 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Wed, 9 Jul 2025 13:55:32 +0900 Subject: [PATCH 053/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=EC=8B=9C=EC=84=A4=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/htdflSttn/page.tsx | 21 +++++++-------- .../ruseFcltMng/fcltSttn/rainSttn/page.tsx | 21 +++++++-------- .../ruseFcltMng/fcltSttn/rswtSttn/page.tsx | 26 ++++++++++--------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index 344234af5..e7685ebbd 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -45,6 +45,7 @@ export default function HtdflSttn() { const [pageNation, setPageNation] = useState(1); const [isChHead, setIsChHead] = useState(false); + const [resetPage, isResetPage] = useState(false); const [bdstTable, setBdstTable] = useState<customRainBdst[]>(); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); @@ -61,11 +62,12 @@ export default function HtdflSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - htdflSttnSearch(true, pageNation, String(htdflSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); - }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm, htdflSttnResCount]); + htdflSttnSearch(true, 1, String(htdflSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, htdflSttnResCount]); useEffect(() => { htdflSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + isResetPage(false) }, [pageNation]); const getSelCity = (val: string | number) => { @@ -152,10 +154,7 @@ export default function HtdflSttn() { label="시도" selectClass={""} selectArray={code.cityCd} - onSelectValue={(val) => { - getSelCity(val) - setPageNation(1) - }} + onSelectValue={getSelCity} /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-4" @@ -163,10 +162,7 @@ export default function HtdflSttn() { selectClass={""} selectArray={selectSgg || []} value={objSearch.sgg} // value props 추가 - onSelectValue={(val) => { - getSgg(val) - setPageNation(1) - }} + onSelectValue={getSgg} /> <div className="col-span-2 flex flex-row space-x-2"> <Label className="w-28 mt-2 text-xl text-gray-600"> @@ -187,8 +183,8 @@ export default function HtdflSttn() { <Button size={"sm"} onClick={() => { - const con = getConValue(); - htdflSttnSearch(false, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + htdflSttnSearch(false, 1, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + isResetPage(true) }} > 조회 @@ -230,6 +226,7 @@ export default function HtdflSttn() { cellClick(index ?? undefined, headId); }} onPageChange={setPageNation} + resetPageNo={resetPage} ></UiTable> </ListDiv> </div> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx index 27d7dfa94..c7798e118 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -46,6 +46,7 @@ export default function RainSttn() { const [isChHead, setIsChHead] = useState(false); const [bdstTable, setBdstTable] = useState<customRainBdst[]>(); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() + const [resetPage, isResetPage] = useState(false); const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }) const [bdstChgProps, setBdstChgProps] = useState<{ @@ -133,6 +134,7 @@ export default function RainSttn() { useEffect(() => { rainSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + isResetPage(false) }, [pageNation]); useEffect(() => { @@ -150,8 +152,8 @@ export default function RainSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - rainSttnSearch(true, pageNation, String(rainSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); - }, [rainSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm, rainSttnResCount]); + rainSttnSearch(true, 1, String(rainSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + }, [rainSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, rainSttnResCount]); return ( <> @@ -167,10 +169,7 @@ export default function RainSttn() { label="시도" selectClass={""} selectArray={code.cityCd} - onSelectValue={(val) => { - getSelCity(val) - setPageNation(1) - }} + onSelectValue={getSelCity} /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-4" @@ -178,10 +177,7 @@ export default function RainSttn() { selectClass={""} selectArray={selectSgg || []} value={objSearch.sgg} // value props 추가 - onSelectValue={(val) => { - getSgg(val) - setPageNation(1) - }} + onSelectValue={getSgg} /> <div className="col-span-2 flex flex-row space-x-2"> <Label className="w-28 mt-2 text-xl text-gray-600"> @@ -202,8 +198,8 @@ export default function RainSttn() { <Button size={"sm"} onClick={() => { - const con = getConValue(); - rainSttnSearch(false, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + rainSttnSearch(false, 1, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + isResetPage(true) }} > 조회 @@ -243,6 +239,7 @@ export default function RainSttn() { total={rainSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} + resetPageNo={resetPage} ></UiTable> </ListDiv> </div> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index f35efa121..edf1f6ac0 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -40,6 +40,7 @@ export default function RswtSttn() { const { rswtSttnRes, rswtSttnResCount } = rswtSttn; const [isChHead, setIsChHead] = useState(false); + const [resetPage, isResetPage] = useState(false); const ref = useRef<ReturnType>({} as ReturnType); const [bdstTable, setBdstTable] = useState<customRswtBdst[]>(); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() @@ -137,11 +138,13 @@ export default function RswtSttn() { const excelClick = useCallback(() => { // 최신 검색 조건 반영 const con = getConValue(); - rswtSttnSearch(true, pageNation, String(rswtSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); - }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, pageNation, fcltNm, rswtSttnResCount]); + + rswtSttnSearch(true, 1, String(rswtSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, rswtSttnResCount]); useEffect(() => { rswtSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + isResetPage(false) }, [pageNation]); return ( @@ -158,10 +161,9 @@ export default function RswtSttn() { label="시도" selectClass={""} selectArray={code.cityCd} - onSelectValue={(val) => { - getSelCity(val) - setPageNation(1) - }} + onSelectValue={ + getSelCity + } /> <SelectBox className="col-span-2 w-1/6 h-full text-2xl ml-4" @@ -169,10 +171,9 @@ export default function RswtSttn() { selectClass={""} selectArray={selectSgg || []} value={objSearch.sgg} // value props 추가 - onSelectValue={(val) => { - getSgg(val) - setPageNation(1) - }} + onSelectValue={ + getSgg + } /> <div className="col-span-2 flex flex-row space-x-2"> <Label className="w-28 mt-2 text-xl text-gray-600"> @@ -193,8 +194,8 @@ export default function RswtSttn() { <Button size={"sm"} onClick={() => { - const con = getConValue(); - rswtSttnSearch(false, pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd); + rswtSttnSearch(false, 1, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); + isResetPage(true) }} > 조회 @@ -234,6 +235,7 @@ export default function RswtSttn() { total={rswtSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} + resetPageNo={resetPage} ></UiTable> </ListDiv> </div> From eef73f36ff018e4382941f25fa4bcedbbde27071 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Wed, 9 Jul 2025 14:19:10 +0900 Subject: [PATCH 054/159] =?UTF-8?q?[apps/cs]=20feat:=20=EC=9E=84=EC=8B=9C?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EB=A9=94=EB=89=B4=20=EB=AF=B8=EB=A6=AC?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/menu/ui/menu-form.tsx | 131 +++++++++++------- packages/common/components/src/api/menu.ts | 11 ++ packages/common/components/src/config/api.ts | 1 + packages/common/components/src/ui/index.ts | 1 + .../common/components/src/ui/lnb/index.tsx | 47 +++++-- 5 files changed, 129 insertions(+), 62 deletions(-) diff --git a/apps/cs/src/pages/menu/ui/menu-form.tsx b/apps/cs/src/pages/menu/ui/menu-form.tsx index 43331067e..a0d262b9d 100644 --- a/apps/cs/src/pages/menu/ui/menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/menu-form.tsx @@ -1,7 +1,15 @@ +import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import type { UseFormReturn } from "react-hook-form"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { Button } from "@common/components"; +import { + Button, + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + LNB, +} from "@common/components"; import { MenuApi, menuFormSchema, type MenuFormData } from "@/entities/menu"; import { ManagementAuthorityDialog } from "@/entities/menu-authority"; import { Form } from "@/shared/ui/form"; @@ -33,7 +41,7 @@ function MenuForm({ handleDelete, }: MenuFormProps) { const isModifyMode = !!menuCd; - + const [open, setOpen] = useState(false); const { confirm } = useConfirm(); const alert = useAlertStore((state) => state.setMessage); @@ -96,55 +104,82 @@ function MenuForm({ const isSubmitDisabled = !form.watch("siteId"); return ( - <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> - <div className="card card-border"> - <div className="card-header"> - <h3 className="text-2xl font-medium text-label"> - {isModifyMode ? "메뉴 수정" : "메뉴 등록"} - </h3> - <div className="flex items-center gap-2"> - <MenuHistoryDialog menuCd={menuCd} /> - <ManagementAuthorityDialog menuCd={menuCd} /> + <> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)}> + <div className="card card-border"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label"> + {isModifyMode ? "메뉴 수정" : "메뉴 등록"} + </h3> + <div className="flex items-center gap-2"> + <MenuHistoryDialog menuCd={menuCd} /> + <ManagementAuthorityDialog menuCd={menuCd} /> + </div> + </div> + <div className="card"> + <BaseMenuForm form={form} menuCd={menuCd} /> + <TypeMenuForm form={form} menuType={menuType} /> </div> </div> - <div className="card"> - <BaseMenuForm form={form} menuCd={menuCd} /> - <TypeMenuForm form={form} menuType={menuType} /> + <div className="flex justify-center gap-4 pb-12 pt-10"> + {isModifyMode && ( + <Button + size="lg" + color="white" + type="button" + onClick={handleLoadTemporaryData} + > + 불러오기 + </Button> + )} + {isModifyMode && ( + <Button + size="lg" + color="gray" + type="button" + onClick={handleMenuTemporaryStorage} + > + 임시저장 + </Button> + )} + {isModifyMode && ( + <Button + size="lg" + color="emerald" + type="button" + onClick={() => setOpen(true)} + > + 미리보기 + </Button> + )} + <Button size="lg" type="submit" disabled={isSubmitDisabled}> + 저장 + </Button> + {isModifyMode && ( + <Button size="lg" color="red" type="button" onClick={onDelete}> + 삭제 + </Button> + )} </div> - </div> - <div className="flex justify-center gap-4 pb-12 pt-10"> - {isModifyMode && ( - <Button - size="lg" - color="white" - type="button" - onClick={handleLoadTemporaryData} - > - 불러오기 - </Button> - )} - {isModifyMode && ( - <Button - size="lg" - color="gray" - type="button" - onClick={handleMenuTemporaryStorage} - > - 임시저장 - </Button> - )} - <Button size="lg" type="submit" disabled={isSubmitDisabled}> - 저장 - </Button> - {isModifyMode && ( - <Button size="lg" color="red" type="button" onClick={onDelete}> - 삭제 - </Button> - )} - </div> - </form> - </Form> + </form> + </Form> + <Dialog open={open} onOpenChange={setOpen}> + <DialogContent className="max-h-[90vh]"> + <DialogHeader> + <DialogTitle>메뉴 미리보기</DialogTitle> + </DialogHeader> + <div className="flex h-full min-h-[60vh] flex-col gap-4"> + <LNB + currentPath={form.watch("urlPath") ?? ""} + propSiteId={form.watch("siteId")} + previewMode + classNames={{ wrapper: "static h-full border-none p-0" }} + /> + </div> + </DialogContent> + </Dialog> + </> ); } diff --git a/packages/common/components/src/api/menu.ts b/packages/common/components/src/api/menu.ts index bd8fe1599..8d58a3499 100644 --- a/packages/common/components/src/api/menu.ts +++ b/packages/common/components/src/api/menu.ts @@ -21,6 +21,10 @@ export interface MenuItem { requiredUrlPath: boolean; } +export interface TreeMenu extends MenuItem { + menuHlpCn: string; +} + const client = getApiClient(); export const getMenuList = async (siteId: string) => { @@ -29,3 +33,10 @@ export const getMenuList = async (siteId: string) => { ); return response.data; }; + +export const getPreviewTreeMenuList = async (siteId: string) => { + const response = await client.get<TreeMenu[]>( + `${ENDPOINT.CMS_SERVICE.MENUS}/${siteId}/tree/preview`, + ); + return response.data; +}; diff --git a/packages/common/components/src/config/api.ts b/packages/common/components/src/config/api.ts index 12efdd8bd..0ead6b0bc 100644 --- a/packages/common/components/src/config/api.ts +++ b/packages/common/components/src/config/api.ts @@ -1,5 +1,6 @@ export const ENDPOINT = { CMS_SERVICE: { + MENUS: "/cms-service/api/v1/menus", MENU_ROLES: "/cms-service/api/v1/menu-roles", SITES: "/cms-service/api/v1/sites", POPUPS: "/cms-service/api/v1/popups", diff --git a/packages/common/components/src/ui/index.ts b/packages/common/components/src/ui/index.ts index 8839d2298..75231add8 100644 --- a/packages/common/components/src/ui/index.ts +++ b/packages/common/components/src/ui/index.ts @@ -15,6 +15,7 @@ export * from "./icon-finder"; export * from "./input"; export * from "./label"; export * from "./layout"; +export * from "./lnb"; export * from "./loading"; export * from "./page-title"; export * from "./popover"; diff --git a/packages/common/components/src/ui/lnb/index.tsx b/packages/common/components/src/ui/lnb/index.tsx index 552a7d67a..20376af24 100644 --- a/packages/common/components/src/ui/lnb/index.tsx +++ b/packages/common/components/src/ui/lnb/index.tsx @@ -3,9 +3,7 @@ import { useState, useEffect, useRef } from "react"; import { useQuery } from "@tanstack/react-query"; import { ChevronRight } from "lucide-react"; -import { ENDPOINT } from "../../config"; -import { cn, setCookie } from "../../lib"; -import { getMenuList, type MenuItem } from "../../api"; +import { getParentIds } from "./lib"; import { Sidebar, SidebarContent, @@ -22,29 +20,47 @@ import { CollapsibleContent, CollapsibleTrigger, } from "../collapsible"; -import { getParentIds } from "./lib"; -import { getCookie } from "../../lib"; - -const siteId = getCookie("site-id-key") ?? ""; +import { ENDPOINT } from "../../config"; +import { cn, getCookie, setCookie } from "../../lib"; +import { getMenuList, getPreviewTreeMenuList, type MenuItem } from "../../api"; export function LNB({ viewOnly, currentPath, + propSiteId, + previewMode, + classNames, handleMenuClick, }: { viewOnly?: boolean; currentPath?: string; + propSiteId?: string; + previewMode?: boolean; + classNames?: { + wrapper?: string; + }; handleMenuClick?: (item: MenuItem) => void; }) { - const { data: menuList } = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES], - queryFn: () => getMenuList(siteId), - enabled: !viewOnly, - }); - const [defaultOpenMenuIds, setDefaultOpenMenuIds] = useState<number[]>([]); const prevPathRef = useRef(currentPath); + const cookieSiteId = getCookie("site-id-key") ?? ""; + const siteId = propSiteId ?? cookieSiteId; + + const { data: menuListData } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES], + queryFn: () => getMenuList(siteId), + enabled: !viewOnly && !previewMode, + }); + + const { data: previewTreeMenuListData } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId, "preview"], + queryFn: () => getPreviewTreeMenuList(siteId), + enabled: previewMode, + }); + + const menuList = previewMode ? previewTreeMenuListData : menuListData; + function isPathMatched(path: string) { if (!path) return false; return currentPath?.startsWith(path); @@ -191,7 +207,10 @@ export function LNB({ return ( <Sidebar collapsible="icon" - className="border-border bg-background px-4 py-[6rem]" + className={cn( + "border-border bg-background px-4 py-[6rem]", + classNames?.wrapper, + )} > <SidebarContent className="bg-background"> <SidebarMenu className="gap-0"> From 8944fa8f819587d927a59cd76cd8cfbff9fe8d6f Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Wed, 9 Jul 2025 14:47:47 +0900 Subject: [PATCH 055/159] =?UTF-8?q?=EA=B1=B4=EC=B6=95=EB=AC=BC=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/prfmncReg/pbnstPrfmncReg/index.tsx | 4 --- .../ruseFcltMng/fcltReg/htdflReg/index.tsx | 8 +++--- .../ruseFcltMng/fcltReg/rswtReg/index.tsx | 8 +++--- .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 25 +++++++++++++------ 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx index eea31c334..17c73c363 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx @@ -42,9 +42,7 @@ type pbnstPrfmncActions = { }; const checkWrRegList = async (year:string) => { - let url =`/reuseFc/pubDetailList` - if(year&& year.length>0){ // url+=`/${year}` } @@ -58,8 +56,6 @@ const hasuListFetch = async (page: number, sggOrCity: string , year:string,searc checkWrRegListRes?.fcltCds, fetchType.COMMON ); - - let findData = rainRes.data.map((item: pubHasuType) => { const data = checkWrRegListRes?.fcPrfList.find( (fclt: FcPrfType) => diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx index b241fe7f1..9c5d8e215 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx @@ -175,7 +175,7 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( const chData = await makeMdfr(data); const res = await putFectch("/drain/facility", chData); if (res.status) { - toast.success("온배수 건축물 수정이 완료되었습니다."); + toast.success("온배수 시설물 수정이 완료되었습니다."); } const htdflRes = await getFetchWithCount( "wr", @@ -191,7 +191,7 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( }, })); } catch (errorUpdate) { - toast.error("온배수 건축물 수정 오류입니다.."); + toast.error("온배수 시설물 수정 오류입니다.."); } }, htdflBdstReg: async (data: customHtdflBdst, code: string | number) => { @@ -202,7 +202,7 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( const chData = makeRstr(data); const res = await postFectch("/drain/facility", chData); if (res.status ===200) { - toast.success("온배수 건축물 등록이 완료되었습니다."); + toast.success("온배수 시설 등록이 완료되었습니다."); } const htdflRes = await initFetch(String(code)); set((state: htdflFacState) => ({ @@ -215,7 +215,7 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = ( }, })); } catch (errorReg) { - toast.error("온배수 건축물 등록 오류입니다.."); + toast.error("온배수 시설물 등록 오류입니다.."); } },htdflNmSearch :async(code:string | number, fcltNm:string) =>{ diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx index e969c7405..99ba724ad 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx @@ -196,15 +196,15 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( if(chch.status ===200) { console.log('chch.status' , chch.status) - toast.success("건축물 및 증축/개축/중축 등록이 완료되었습니다."); + toast.success("건축물(중수도) 및 증축/개축/중축 등록이 완료되었습니다."); }else{ - toast.error("건축물 증축/개축/중축 오류입니다."); + toast.error("건축물(중수도 증축/개축/중축 오류입니다."); } } else { - toast.success("건축물 등록이 완료되었습니다."); + toast.success("건축물(중수도 등록이 완료되었습니다."); } }else{ - toast.error("건축물 등록이 완료되었습니다."); + toast.error("건축물(중수도) 등록이 완료하였습니다."); } const rswtRes = await initFetch(code); set((state: rswtFacState) => ({ diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index f54eb5cbd..24f94dc58 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -59,7 +59,8 @@ type pbnstSttnActions = { total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string + year: string, + flcts:string[] ) => void; }; @@ -109,9 +110,7 @@ const hasuListFetch = async ( }/0/1/SW` } else if( reurnValue.partValue === 'G'){ - console.log('reurnValue.sigunValue ', reurnValue.sidoValue) - console.log('reurnValue.sigunValue ', reurnValue.sigunValue) url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW` }else{ @@ -121,6 +120,8 @@ const hasuListFetch = async ( if (searchNm && searchNm?.length > 0) { url += "/" + searchNm } + + console.log(' flcts ' ,flcts) const pbnList = await postFectch(url, flcts,fetchType.COMMON); const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}`, @@ -130,12 +131,16 @@ const hasuListFetch = async ( const checkWrRegListRes = getRuseList.data; const count = getRuseList.count; + + const data: WaterReuseFacility[] = checkWrRegListRes.map( (item: FcPrfType) => { const findData = pbnList.data.find( (fclt: pubHasuType) => fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11) ); + + console.log(' pbnList ', pbnList) if(findData){ const usage = item.prfList.reduce( @@ -163,7 +168,7 @@ const hasuListFetch = async ( }, { total: 0, inUsage: 0, outUsage: 0 } ); - + console.log('findData ', findData) return { rvbsn: findData?.rvbsn ||'-', lgbsn: findData?.lgbsn||'-', @@ -196,6 +201,10 @@ const hasuListFetch = async ( } ).filter(Boolean); + + console.log( ' checkWrRegListRes ', getRuseList.data) + console.log( ' data ', data) + return data; }; @@ -292,7 +301,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( year, fclts ); - + console.log('pbnstSttnRes ' , pbnstSttnRes) set( (state: pbnstSttnState) => { return { ...state, @@ -332,7 +341,8 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( total: string, reurnValue: ReturnType, searchNm: string | undefined, - year: string + year: string, + flcts:string[] ) => { try { @@ -341,7 +351,8 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( total, reurnValue, searchNm, - year + year, + flcts ); set((state: pbnstSttnState) => { From 3444a03f31fd68acba462b1fab79093f2f781bd5 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Wed, 9 Jul 2025 17:39:14 +0900 Subject: [PATCH 056/159] =?UTF-8?q?=EC=8B=9C=EC=84=A4=EB=B3=84=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EC=83=81=EC=84=B8=20=EB=82=B4=EC=9A=A9=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 96 +++++++++---------- .../ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 2 +- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 2 +- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 2 +- .../sttn/sttnDetailModal/sttnDetailModal.tsx | 5 +- 5 files changed, 52 insertions(+), 55 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index c46276e15..e98c84aea 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -75,7 +75,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( (state) => state ); - const { rainSttnRes } = rainSttn; + let { rainSttnRes } = rainSttn; const [rainTable, setRainTable] = useState<customRainBdst[]>(); const [rainBdstChgProps, setRainBdstChgProps] = useState<{ isOpen: boolean; @@ -88,7 +88,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const { rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore( (state) => state ); - const { rswtSttnRes } = rswtSttn; + let { rswtSttnRes } = rswtSttn; const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>(); const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false }); const [rswtrBdstChgProps, setRswtrBdstChgProps] = useState<{ @@ -99,7 +99,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); - const { htdflSttnRes } = htdflSttn; + let { htdflSttnRes } = htdflSttn; const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); @@ -113,7 +113,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } = useWrStore((state) => state); let { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; const [isRuseReg, setIsRuseReg] = useState<{ - data:any | undefined; + data: any | undefined; }>({ data: undefined }); const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); const [hasuPage, setHasuPage] = useState<number>(1); @@ -131,31 +131,17 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setActiveTab(featureCd) fetchpbnstDetail(featureCd); // 상세정보 } - else if (layerId == '빗물이용시설') { - featureCd = selectedVal?.bdst_nm; - setFcltPk(featureCd) - rainSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); - setRainDetailModal({ isOpen: true, data: rainSttn.rainSttnRes[0] }); - } - else if (layerId == '중수도시설') { - featureCd = selectedVal?.bdst_nm; - setFcltPk(featureCd) - rswtSttnSearch(true,1, '20', '', featureCd, code.cityCd, code.sggCd); - setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); - } - else if (layerId == '온배수시설') { - featureCd = selectedVal?.bdst_nm; - setFcltPk(featureCd) - htdflSttnSearch(true,1, '20', '', featureCd, code.cityCd, code.sggCd); - setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); - } else if (layerId == '하수처리시설') { featureCd = selectedVal?.swtrmt_fclt_nm; setFcltPk(featureCd); // 현재 호출된 featureCd 저장 - fetchHasuDetail(featureCd,selectedVal?.swtrmt_fclt_cd); - }; + fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd); + } + else{ + featureCd = selectedVal?.bdst_nm; + setFcltPk(featureCd) + detainSttn(featureCd,layerId) + } setViewMode("detail") - } } else if (layerId === null && seletectedLayerNm) { setViewMode("list") } }, [featureData]); @@ -170,10 +156,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnstSttn.pbnstSttnRes[index] ) { setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); - // fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) onFeatureSelect(pbnstSttn.pbnstSttnRes[index]); - // setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) - // setViewMode("detail") onClose() } }; @@ -281,6 +264,24 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); } } + const detainSttn = async (featureCd: string, layerNm: string) => { + if (layerNm == '빗물이용시설') { + const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`) + rainSttnRes = res + setRainDetailModal({ isOpen: true, data: rainSttnRes[0] }); + } + else if(layerNm == '중수도시설'){ + const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`) + rswtSttnRes = res + console.log('중수도', res, featureCd) + setRswtrDetailModal({isOpen:true,data:rswtSttnRes[0]}) + } + else{ + const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`) + htdflSttnRes = res + setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); + } + } useEffect(() => { if (!rainSttn.isInit) { @@ -340,8 +341,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ } useEffect(() => { if (!rswtSttn.isInit) { - rswtSttnInit(false,1, "20", "0", '', code.cityCd, code.sggCd); - console.log('rswtSttnInit', rswtSttnRes); + rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd); } }, [rswtSttn.isInit, rswtSttnInit]); @@ -363,7 +363,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ (item: customRswtBdst) => item.reuseBuilding[0]?.rswtrObj !== undefined ); - setRswtrTable(chData); + setRswtrTable(chData); }, [code, rswtSttnRes]); // 엑셀 관련 const rswtSttnExcelDownload = useCallback(() => { @@ -379,7 +379,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [rswtSttn.excelList]) useEffect(() => { - rswtSttnSearch(false,rswtrPage, "20", '', '', code.cityCd, code.sggCd); + rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd); }, [rswtrPage]); ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// @@ -387,8 +387,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 온배수시설 cellClick 이벤트 (상세정보) const htdflCellClick = (index: number | undefined, headId: string) => { if (index !== undefined && htdflTable !== undefined) { - // setHtdflDetailModal({ isOpen: true, data: htdflTable[index] }); - // setViewMode('detail') onFeatureSelect(htdflTable[index]); onClose(); } @@ -413,7 +411,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]); useEffect(() => { - htdflSttnSearch(true,htdflPage, "20", '', '', code.cityCd, code.sggCd); + htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd); }, [htdflPage]); ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// @@ -431,19 +429,19 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ useEffect(() => { pubHasuInit(String(hasuPage), "0"); }, [hasuPage]); - const fetchHasuDetail = async (featureCd: string,data:string) => { + const fetchHasuDetail = async (featureCd: string, data: string) => { try { - const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`,[data],fetchType.COMMON); - const hasuList = rainRes.data.map((item: any) => { - return { - ...item, - fctCpc: Number(item.fctCpc) || 0, - ruse: item.ruse === false ? "N" : "Y", - }; - }); - pbnstHasuRes = hasuList - if(pbnstHasuRes.length >0)setIsRuseReg({ data:[pbnstHasuRes[0]] }); - + const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON); + const hasuList = rainRes.data.map((item: any) => { + return { + ...item, + fctCpc: Number(item.fctCpc) || 0, + ruse: item.ruse === false ? "N" : "Y", + }; + }); + pbnstHasuRes = hasuList + if (pbnstHasuRes.length > 0) setIsRuseReg({ data: [pbnstHasuRes[0]] }); + } catch (error) { console.error("Error fetching data:", error); } @@ -454,7 +452,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ onClose(); } }; -///////////////////////////////////////////// 하수처리 시설 ////////////////////////////////////////////////// + ///////////////////////////////////////////// 하수처리 시설 ////////////////////////////////////////////////// // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { @@ -502,7 +500,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ {/* 높이 조정 */} <UiTable tableData={isRuseReg?.data || []} - headlist={pubFacHeadList.slice(0,4)} + headlist={pubFacHeadList.slice(0, 4)} pageSize={1} total={null} headName={"위치정보"} diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index edd5bb1b5..e344dd081 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -137,7 +137,7 @@ export default function HtdflRegForm({ {/* <div className="flex justify-between items-center mx-3"> */} <div> <h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1"> - {readonly && `(${htdflForm.bdstNm})`} + {readonly && `(${htdflForm?.bdstNm})`} </h1> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index da8011efd..d3ca1c881 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -144,7 +144,7 @@ export default function RainRegForm({ <form onSubmit={form.handleSubmit(onSubmit)}> <div> <h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1"> - {readonly && `(${rainForm.bdstNm})`} + {readonly && `(${rainForm?.bdstNm})`} </h1> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index 3c8af831d..ab97cf99a 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -134,7 +134,7 @@ export default function RswtrRegForm({ {/* <div className="flex justify-between items-center mx-3"> */} <div> <h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1"> - {readonly && `(${rswtForm.bdstNm})`} + {readonly && `(${rswtForm?.bdstNm})`} </h1> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx index 0f7dbf706..4f6deee51 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx @@ -30,7 +30,7 @@ export default function SttnDetailModal({ }); useEffect(() => { - if (type === "RNB" && formObj.reuseBuilding[0]) { + if (type === "RNB" && formObj?.reuseBuilding[0]) { rainSttnChkSearch(formObj.reuseBuilding[0].bdstRuseFcltPk); } else if (type === "RST") { @@ -41,7 +41,7 @@ export default function SttnDetailModal({ useEffect(() => { if ( type === "RNB" && - formObj.reuseBuilding[0] && + formObj?.reuseBuilding[0] && rainSttn.rainChkRes?.bdstRuseFcltFk ) { const tableTotalData = rainChkTableData([rainSttn.rainChkRes]); @@ -79,7 +79,6 @@ export default function SttnDetailModal({ useEffect(() =>{ setDetailData({data:[] , head:[], node:[]}) - },[]) return ( From 351adea87fee7c6137eda5219687ae692fa3dad2 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Wed, 9 Jul 2025 18:01:04 +0900 Subject: [PATCH 057/159] =?UTF-8?q?=EC=9E=A0=EC=9E=AC=EC=88=98=EC=9A=94?= =?UTF-8?q?=EC=B2=98=20=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=8B=9C=20=ED=86=A0=EC=8A=A4=ED=8A=B8=20=EB=9D=84?= =?UTF-8?q?=EC=9A=B0=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wr/app/matMng/coMng/ldrmntCoSttn/page.tsx | 25 +++++++++++-------- .../app/store/matDmd/ldrmntCoSttn/index.tsx | 22 ++++++++-------- .../sttn/sttnDetailModal/coDatailModal.tsx | 16 +++--------- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx index 5ce69d508..d5861e173 100644 --- a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -31,7 +31,7 @@ import { useCallback, useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; export default function LdrmntCoSttn() { - const { code, ldrmnt, ldrmntInit, ldrmntSearch, } = useWrStore( + const { code, ldrmnt, ldrmntInit, ldrmntSearch, ldrmntUpdate} = useWrStore( (state) => state ); const { ldrmntRes, excelList, ldrmntResCount } = ldrmnt; @@ -42,6 +42,7 @@ export default function LdrmntCoSttn() { const [bdstTable, setBdstTable] = useState<customLdrmnt[]>(); const [searchTxt, setSearchTxt] = useState<string>(); const [excelData, setExcelData] = useState<any[]>(); + const [resetPage, isResetPage] = useState(false); // const [isExcelDownload, setIsExcelDownload] = useState(false); const excelClick = useCallback(() => { @@ -76,9 +77,9 @@ export default function LdrmntCoSttn() { const excelDownloadClick = useCallback(() => { const cityNm = computeCityNm(); - ldrmntSearch(true, pageNation, String(ldrmntResCount), cityNm, searchTxt || ""); + ldrmntSearch(true, 1, String(ldrmntResCount), cityNm, searchTxt || ""); // setIsExcelDownload(true); - }, [objSearch, pageNation, searchTxt, code, ldrmntSearch, computeCityNm, ldrmntResCount]); + }, [objSearch, searchTxt, code, ldrmntSearch, computeCityNm, ldrmntResCount]); useEffect(() => { if (/*isExcelDownload &&*/ excelData && excelData.length > 0) { @@ -111,7 +112,6 @@ export default function LdrmntCoSttn() { } 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 }); } @@ -141,7 +141,7 @@ export default function LdrmntCoSttn() { setBdstTable(tbData); }, [ldrmntRes, code]); - + useEffect(() => { const transData = Array.isArray(excelList) ? excelList : [excelList]; const exData = tableData(transData, { code }); @@ -160,8 +160,8 @@ export default function LdrmntCoSttn() { }, [excelList]) useEffect(() => { - const cityNm = computeCityNm(); - ldrmntSearch(false, pageNation, '20', cityNm, searchTxt || ""); + ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + isResetPage(false) }, [pageNation]); return ( @@ -204,8 +204,8 @@ export default function LdrmntCoSttn() { <Button size={"sm"} onClick={(e) => { - const cityNm = computeCityNm(); - ldrmntSearch(false, pageNation, '20', cityNm, searchTxt || ""); + ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + isResetPage(true) }} > 조회 @@ -250,6 +250,7 @@ export default function LdrmntCoSttn() { total={ldrmntResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} + resetPageNo={resetPage} /> </ListDiv> </div> @@ -260,7 +261,11 @@ export default function LdrmntCoSttn() { setDetailModal({ ...detailModal, isOpen: !detailModal.isOpen }) }} bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"} - body={<CoDetailModal formObj={detailModal.data} />} + body={<CoDetailModal formObj={detailModal.data} onFormSubmit={async (value)=>{ + await ldrmntUpdate(value) + setDetailModal({ ...detailModal, isOpen: false }) + ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + }} />} /> <UiModal diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx index 73c1bad7d..f21ca753f 100644 --- a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx @@ -4,6 +4,7 @@ import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { z } from "zod"; import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg"; import { ldrmntHeadListExport, ldrmntNodeListExport, ldrmntZod } from "./headList"; +import toast from "react-hot-toast"; // 테이블 헤드 리스트 const ldrmntHeadList = ldrmntHeadListExport; @@ -34,7 +35,7 @@ const excelDownList: ExcelType[] = []; type ldrmntActions = { ldrmntRegData: (data: any[]) => void, ldrmntInit: (con: string) => void - ldrmntSearch: (isExcel:boolean, page: number, sggCd: string, total: string, coNm: string) => void; + ldrmntSearch: (isExcel: boolean, page: number, sggCd: string, total: string, coNm: string) => void; ldrmntUpdate: (ldrmntRes: customLdrmnt) => void; ldrmntDelete: () => void; loadingOpen: (isOpen: boolean) => void @@ -106,7 +107,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( console.log('response ', response) }, - ldrmntSearch: async (isExcel:boolean, page: number, total: string, sggCd: string, coNm: string) => { + ldrmntSearch: async (isExcel: boolean, page: number, total: string, sggCd: string, coNm: string) => { let searchUrl = ""; if (sggCd !== "") { @@ -121,7 +122,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = ( fetchType.WR, searchUrl ); -console.log("알이에스", ldrmntRes) + console.log("알이에스", ldrmntRes) if (isExcel) { let excelDownList: ExcelType[] = []; ldrmntRes.data.forEach((item: customLdrmnt) => { @@ -163,23 +164,20 @@ console.log("알이에스", ldrmntRes) } }, ldrmntUpdate: async (ldrmntRes: customLdrmnt) => { + if(ldrmntRes) try { ldrmntRes.rgtr = TEST_UUID; - const response = await putFectch( + const res = await putFectch( `/reuseFc/request/temp`, ldrmntRes ); - return set((state: ldrmntState) => ({ - ...state, - ldrmnt: { - ...state.ldrmnt, - ldrmntRes: ldrmntRes, - }, - })); - + if (res.ok) { + toast.success("잠재수요처 상세정보가 수정되었습니다.",) + } } catch (error) { console.error("Error ldrmntUpdate:", error); + toast.error("잠재수요처 상세정보 수정에 실패하였습니다.") } }, ldrmntDelete: async () => { diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx index b7229a559..4bb0803e8 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx @@ -11,26 +11,18 @@ import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import type { z } from "zod"; -export default function SttnDetailModal({ - formObj, +export default function CoDetailModal({ + formObj,onFormSubmit }: { formObj: any; + onFormSubmit:(values:customLdrmnt)=>void; }) { - const { ldrmntUpdate } = useWrStore( - (state) => state - ); const defaultValues: z.infer<typeof ldrmntZod> = ldrmntZod.parse({}); const form = useForm<z.infer<typeof ldrmntZod>>({ resolver: zodResolver(ldrmntZod), defaultValues: defaultValues, }); - const onSubmit = (values: customLdrmnt) => { - console.log("values", values) - if (values) - ldrmntUpdate(values) - }; - useEffect(() => { if (ldrmntZod) form.reset(formObj); }, [formObj]); @@ -55,7 +47,7 @@ export default function SttnDetailModal({ <div> <ScrollArea className="h-[85vh]"> <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> + <form onSubmit={form.handleSubmit(onFormSubmit)}> <div className="grid grid-cols-12 flex items-center card-header"> <h1 className="text-2xl font-medium text-label col-span-10"> 잠재수요처 상세정보 From 49047576af757706cfc02c021a756849ab71c20f Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Wed, 9 Jul 2025 18:12:31 +0900 Subject: [PATCH 058/159] =?UTF-8?q?=EC=9E=AC=EC=9D=B4=EC=9A=A9=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=20=ED=8C=9D=EC=97=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 69 ++++++++++++++++-------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index e98c84aea..90b9a140c 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -68,7 +68,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnstSttn, pbnstSttnSearch, pbnSttnInit, + getFlcts } = useWrStore((state) => state); + const { fclts, pbnstSttnResCount} = pbnstSttn const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>() // 빗물재이용시설 변수 @@ -104,12 +106,12 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); const [htdflPage, setHtdflPage] = useState(1) + const [htdflResetPage, isHtdflResetPage] = useState(false); //하수처리시설 변수 const { pbnst, pubHasuInit, - pubHasuSearch, } = useWrStore((state) => state); let { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; const [isRuseReg, setIsRuseReg] = useState<{ @@ -119,6 +121,21 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const [hasuPage, setHasuPage] = useState<number>(1); if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// + const getSelectedLayers = () => { + let result = null; + const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 + let featureLayer: { get: (key: string) => any } = { get: (key: string) => 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(() => { const layerId = getSelectedLayers(); if (featureData && typeof featureData.getProperties === "function") { @@ -160,38 +177,26 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ onClose() } }; - const getSelectedLayers = () => { - let result = null; - const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 - let featureLayer: { get: (key: string) => any } = { get: (key: string) => 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 (!pbnstSttn.isInit) { - pbnSttnInit("1", "13", { - partValue: "A", - sidoValue: '0', - sigunValue: "0", - regionValue: "", - unitWaterShedValue: "", - middleRegionValue: "", - envPartValue: "", - sidoText: "", - sigunText: "" - }, String(new Date().getFullYear())); + getFlcts() } }, [seletectedLayerNm, pbnstSttn.isInit]); - + useEffect(()=>{ + pbnSttnInit("1", "15", { + partValue: "A", + sidoValue: '0', + sigunValue: "0", + regionValue: "", + unitWaterShedValue: "", + middleRegionValue: "", + envPartValue: "", + sidoText: "", + sigunText: "" + }, String(new Date().getFullYear()), pbnstSttn.fclts); + },[fclts]) useEffect(() => { setBdstTable(pbnstSttn.pbnstSttnRes); }, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]); @@ -233,7 +238,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ sigunText: "", }, "", - String(new Date().getFullYear()) + String(new Date().getFullYear()),fclts ); }, []); const excelClick = useCallback(() => { @@ -285,7 +290,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ useEffect(() => { if (!rainSttn.isInit) { - rainSttnInit(1, "20", "0", '', code.cityCd, code.sggCd); + rainSttnInit(false,1, "20", "0", '', code.cityCd, code.sggCd); } }, [rainSttn.isInit, rainSttnInit]); @@ -321,7 +326,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [code, rainSttnRes, rainSttn.rainSttHeadList]); useEffect(() => { - rainSttnSearch(rainPage, "20", '', '', code.cityCd, code.sggCd); + rainSttnSearch(false,rainPage, "20", '', '', code.cityCd, code.sggCd); }, [rainPage]); ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// @@ -393,7 +398,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; useEffect(() => { if (!htdflSttn.isInit) { - initHtdfl(1, "20", "0", '', code.cityCd, code.sggCd); + initHtdfl(false,1, "20", "0", '', code.cityCd, code.sggCd); } }, [htdflSttn.isInit, initHtdfl]); From 50e6d615aed3becac08c22b0aed172a05f6dd633 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Wed, 9 Jul 2025 21:24:19 +0900 Subject: [PATCH 059/159] =?UTF-8?q?[apps/cs]=20chore:=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=20=EC=9D=B4=EB=A0=A5=20=EC=A1=B0=ED=9A=8C=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/menu/model/menu-history-interface.ts | 2 +- apps/cs/src/pages/menu/ui/menu-history-dialog.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cs/src/pages/menu/model/menu-history-interface.ts b/apps/cs/src/pages/menu/model/menu-history-interface.ts index e3e35446d..f3688123c 100644 --- a/apps/cs/src/pages/menu/model/menu-history-interface.ts +++ b/apps/cs/src/pages/menu/model/menu-history-interface.ts @@ -2,7 +2,7 @@ import type { PageableParams, PageableList } from "@/shared/model"; export interface MenuHistorySearchParams extends PageableParams { keyword?: string; - searchType?: string; + keywordType?: string; menuCd?: number; chgTypeCd?: string; startDt?: string; diff --git a/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx b/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx index 7a81ad002..4b8028d0c 100644 --- a/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx +++ b/apps/cs/src/pages/menu/ui/menu-history-dialog.tsx @@ -40,7 +40,7 @@ function MenuHistoryDialog({ menuCd }: MenuHistoryDialogProps) { }); const [searchParams, setSearchParams] = useState<MenuHistorySearchParams>({ keyword: "", - searchType: "menuKornNm", + keywordType: "menuKornNm", }); const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); const selectedHistoryId = parseInt(Object.keys(rowSelection)[0] ?? "0"); From a7b9b9d24a90dd45413bea522cfd7b2e1d64e3f1 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Wed, 9 Jul 2025 21:29:36 +0900 Subject: [PATCH 060/159] =?UTF-8?q?[apps/cs]=20fix:=20api=20log=20?= =?UTF-8?q?=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/entities/apilog/api/apilog-service.ts | 3 +-- apps/cs/src/entities/apilog/model/apilog-interface.ts | 3 ++- apps/cs/src/pages/apilog/ui/apilog-page.tsx | 2 +- apps/cs/src/shared/config/api.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/cs/src/entities/apilog/api/apilog-service.ts b/apps/cs/src/entities/apilog/api/apilog-service.ts index d7167950c..8c7bdb309 100644 --- a/apps/cs/src/entities/apilog/api/apilog-service.ts +++ b/apps/cs/src/entities/apilog/api/apilog-service.ts @@ -9,12 +9,11 @@ import type { export class ApiLogApiService implements ApiLogService { public async getApiLogList(params: ApiLogParams): Promise<ApiLogList> { const response = await client.get<ApiLogList>( - `${ENDPOINT.USER_SERVICE.APILOG}`, + `${ENDPOINT.CMS_SERVICE.APILOG}`, { params }, ); return response.data; } - } export const ApiLogApi = new ApiLogApiService(); diff --git a/apps/cs/src/entities/apilog/model/apilog-interface.ts b/apps/cs/src/entities/apilog/model/apilog-interface.ts index f00e583ad..0b41d796f 100644 --- a/apps/cs/src/entities/apilog/model/apilog-interface.ts +++ b/apps/cs/src/entities/apilog/model/apilog-interface.ts @@ -2,8 +2,9 @@ import type { PageableList, PageableParams } from "@/shared/model"; export interface ApiLogParams extends PageableParams { siteId?: string; - userId?: string; + userUnqId?: string; userNm?: string; + userId?: string; apiHttpPmhd?: string; dmndUrl?: string; ipAddr?: string; diff --git a/apps/cs/src/pages/apilog/ui/apilog-page.tsx b/apps/cs/src/pages/apilog/ui/apilog-page.tsx index 51cc960f3..4bfce86e2 100644 --- a/apps/cs/src/pages/apilog/ui/apilog-page.tsx +++ b/apps/cs/src/pages/apilog/ui/apilog-page.tsx @@ -52,7 +52,7 @@ function ApiLogPage({}) { }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.LOGINLOG, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.APILOG, pagination], queryFn: () => ApiLogApi.getApiLogList({ ...loginlogPostQuery, diff --git a/apps/cs/src/shared/config/api.ts b/apps/cs/src/shared/config/api.ts index 7001b97aa..cd639a628 100644 --- a/apps/cs/src/shared/config/api.ts +++ b/apps/cs/src/shared/config/api.ts @@ -20,7 +20,6 @@ export const ENDPOINT = { ROLE_AUTHORIZATIONS: "/user-service/api/v1/role-authorizations", ROLES: "/user-service/api/v1/roles", LOGINLOG: "/user-service/api/v1/login-logs", - APILOG: "/user-service/api/v1/api-logs", PRIVACYLOG: "/user-service//api/v1/prvc-inq-logs", }, CMS_SERVICE: { @@ -53,6 +52,7 @@ export const ENDPOINT = { GROUPS: "/cms-service/api/v1/groups", GROUP_USERS: "/cms-service/api/v1/group-users", MANAGER_IP: "/cms-service/api/v1/mgrip", + APILOG: "/cms-service/api/v1/api-logs", }, BOARD_SERVICE: { BBS: "/board-service/api/v1/bbs", From e07c29c0ada6ee337dba46e9a73188d1e12ae148 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 02:00:25 +0900 Subject: [PATCH 061/159] =?UTF-8?q?[apps/cs]=20feat:=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=20(CS=5FUT01010101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/admin/ui/admin-page.tsx | 54 +++++-- apps/cs/src/pages/banner/ui/banner-page.tsx | 37 ++++- apps/cs/src/pages/bbs/ui/bbs-page.tsx | 45 ++++-- .../cs/src/pages/code/ui/lwpocode-section.tsx | 38 +++-- apps/cs/src/pages/code/ui/upcode-section.tsx | 38 +++-- .../src/pages/contents/ui/contents-page.tsx | 33 +++- apps/cs/src/pages/file/ui/file-page.tsx | 40 +++-- apps/cs/src/pages/image/ui/image-page.tsx | 42 +++-- apps/cs/src/pages/module/ui/module-page.tsx | 56 ++++--- apps/cs/src/pages/popup/ui/popup-page.tsx | 35 ++++- apps/cs/src/pages/recent/ui/recent-page.tsx | 102 +++++++++---- apps/cs/src/pages/role/ui/role-page.tsx | 35 ++++- apps/cs/src/pages/site/ui/site-page.tsx | 40 +++-- apps/cs/src/pages/survey/ui/survey-page.tsx | 35 ++++- .../src/pages/template/ui/template-page.tsx | 54 ++++--- apps/cs/src/pages/terms/ui/terms-page.tsx | 51 ++++--- apps/cs/src/pages/users/ui/users-page.tsx | 144 ++++++++++++------ 17 files changed, 620 insertions(+), 259 deletions(-) diff --git a/apps/cs/src/pages/admin/ui/admin-page.tsx b/apps/cs/src/pages/admin/ui/admin-page.tsx index a4cd5265d..fb832b01d 100644 --- a/apps/cs/src/pages/admin/ui/admin-page.tsx +++ b/apps/cs/src/pages/admin/ui/admin-page.tsx @@ -38,10 +38,14 @@ function AdminPage() { const alert = useAlertStore((state) => state.setMessage); const { confirm } = useConfirm(); - const [adminQuery, setAdminQuery] = useState<UserSearchParams>({ + const [keywordType, setKeywordType] = useState(""); + const [keyword, setKeyword] = useState(""); + const [grpId, setGrpId] = useState(""); + const [searchParams, setSearchParams] = useState<UserSearchParams>({ keywordType: "", keyword: "", grpId: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -66,10 +70,10 @@ function AdminPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.USERS, pagination], + queryKey: [ENDPOINT.USER_SERVICE.USERS, searchParams, pagination], queryFn: () => UserApi.findPageAdminUser({ - ...adminQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -123,7 +127,24 @@ function AdminPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keywordType, + keyword, + grpId, + }); + }; + + const handleReset = () => { + setKeywordType(""); + setKeyword(""); + setGrpId(""); + setSearchParams({ + ...searchParams, + keywordType: "", + keyword: "", + grpId: "", + }); }; const handleDeleteAdmins = async () => { @@ -161,11 +182,7 @@ function AdminPage() { <form onSubmit={handleSubmit} className="flex items-center gap-6 p-2"> <div className="flex items-center gap-2"> <Label className="mr-2 text-label">관리자구분</Label> - <Select - onValueChange={(value) => - setAdminQuery({ ...adminQuery, grpId: value }) - } - > + <Select value={grpId} onValueChange={(value) => setGrpId(value)}> <SelectTrigger className="h-[3.2rem] w-[16rem] !text-[1.3rem]"> <SelectValue placeholder="그룹 선택" /> </SelectTrigger> @@ -183,9 +200,8 @@ function AdminPage() { 관리자 </Label> <Select - onValueChange={(value) => - setAdminQuery({ ...adminQuery, keywordType: value }) - } + value={keywordType} + onValueChange={(value) => setKeywordType(value)} > <SelectTrigger className="h-[3.2rem] w-[10rem] !text-[1.3rem]"> <SelectValue placeholder="선택" /> @@ -197,16 +213,22 @@ function AdminPage() { </Select> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={adminQuery.keyword} - onChange={(e) => - setAdminQuery({ ...adminQuery, keyword: e.target.value }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} placeholder="검색어 입력" /> </div> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/banner/ui/banner-page.tsx b/apps/cs/src/pages/banner/ui/banner-page.tsx index db5a5cc15..88a47ba67 100644 --- a/apps/cs/src/pages/banner/ui/banner-page.tsx +++ b/apps/cs/src/pages/banner/ui/banner-page.tsx @@ -28,17 +28,21 @@ function BannerPage() { const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); const [postingTargets, setPostingTargets] = useState<PostingTarget[]>([]); - const [bannerQuery, setBannerQuery] = useState<BannerParams>({ bnrTtl: "" }); + const [bnrTtl, setBnrTtl] = useState(""); + const [searchParams, setSearchParams] = useState<BannerParams>({ + bnrTtl: "", + sort: "regDt,desc", + }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 5, }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.BANNERS, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.BANNERS, searchParams, pagination], queryFn: () => BannerApi.getBannerList({ - ...bannerQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -46,7 +50,18 @@ function BannerPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + bnrTtl, + }); + }; + + const handleReset = () => { + setBnrTtl(""); + setSearchParams({ + ...searchParams, + bnrTtl: "", + }); }; const handleRowClick = (row: Banner) => { @@ -107,14 +122,20 @@ function BannerPage() { </Label> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={bannerQuery.bnrTtl} - onChange={(e) => - setBannerQuery({ ...bannerQuery, bnrTtl: e.target.value }) - } + value={bnrTtl} + onChange={(e) => setBnrTtl(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/bbs/ui/bbs-page.tsx b/apps/cs/src/pages/bbs/ui/bbs-page.tsx index 482966fc5..187642a46 100644 --- a/apps/cs/src/pages/bbs/ui/bbs-page.tsx +++ b/apps/cs/src/pages/bbs/ui/bbs-page.tsx @@ -29,9 +29,12 @@ function BbsPage() { const router = useRouter(); const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); - const [boardParams, setBoardParams] = useState<BoardParams>({ + const [bbsTypeCd, setBbsTypeCd] = useState(""); + const [bbsNm, setBbsNm] = useState(""); + const [searchParams, setSearchParams] = useState<BoardParams>({ bbsTypeCd: "", bbsNm: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -39,10 +42,10 @@ function BbsPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.BBS, pagination], + queryKey: [ENDPOINT.BOARD_SERVICE.BBS, searchParams, pagination], queryFn: () => BoardApi.getBoardList({ - ...boardParams, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -50,7 +53,21 @@ function BbsPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + bbsTypeCd, + bbsNm, + }); + }; + + const handleReset = () => { + setBbsTypeCd(""); + setBbsNm(""); + setSearchParams({ + ...searchParams, + bbsTypeCd: "", + bbsNm: "", + }); }; const handleRowClick = (row: Board) => { @@ -86,10 +103,8 @@ function BbsPage() { </Label> <CodeSelect upCd="BBSTYPE" - value={boardParams.bbsTypeCd} - onValueChange={(value) => - setBoardParams({ ...boardParams, bbsTypeCd: value }) - } + value={bbsTypeCd} + onValueChange={(value) => setBbsTypeCd(value)} /> <Label htmlFor="bbsNm" className="ml-4 mr-2 text-label"> 게시판명 @@ -97,14 +112,20 @@ function BbsPage() { <Input id="bbsNm" className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={boardParams.bbsNm} - onChange={(e) => - setBoardParams({ ...boardParams, bbsNm: e.target.value }) - } + value={bbsNm} + onChange={(e) => setBbsNm(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/code/ui/lwpocode-section.tsx b/apps/cs/src/pages/code/ui/lwpocode-section.tsx index b1713fa0f..da37bfb18 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-section.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-section.tsx @@ -15,8 +15,10 @@ type LwpoCodeSectionProps = { function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { const alert = useAlertStore((state) => state.setMessage); const [dialogOpen, setDialogOpen] = useState(false); - const [lwpoCodeQuery, setLwpoCodeQuery] = useState<LwpoCodeParams>({ + const [lwpoCdNm, setLwpoCdNm] = useState(""); + const [searchParams, setSearchParams] = useState<LwpoCodeParams>({ lwpoCdNm: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -24,10 +26,10 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.LWPO_CODE, upCd, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.LWPO_CODE, upCd, searchParams, pagination], queryFn: () => LwpoCodeApi.getLwpoCodeList({ - ...lwpoCodeQuery, + ...searchParams, upCd, page: pagination.pageIndex, size: pagination.pageSize, @@ -59,7 +61,18 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + lwpoCdNm, + }); + }; + + const handleReset = () => { + setLwpoCdNm(""); + setSearchParams({ + ...searchParams, + lwpoCdNm: "", + }); }; useEffect(() => { @@ -75,17 +88,20 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { </Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={lwpoCodeQuery.lwpoCdNm} - onChange={(e) => - setLwpoCodeQuery({ - ...lwpoCodeQuery, - lwpoCdNm: e.target.value, - }) - } + value={lwpoCdNm} + onChange={(e) => setLwpoCdNm(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/code/ui/upcode-section.tsx b/apps/cs/src/pages/code/ui/upcode-section.tsx index ffae0f28b..b7202178c 100644 --- a/apps/cs/src/pages/code/ui/upcode-section.tsx +++ b/apps/cs/src/pages/code/ui/upcode-section.tsx @@ -14,8 +14,10 @@ type UpCodeSectionProps = { function UpCodeSection({ handleSelectedUpCd }: UpCodeSectionProps) { const [dialogOpen, setDialogOpen] = useState(false); - const [upCodeQuery, setUpCodeQuery] = useState<UpCodeParams>({ + const [keyword, setKeyword] = useState(""); + const [searchParams, setSearchParams] = useState<UpCodeParams>({ keyword: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -23,10 +25,10 @@ function UpCodeSection({ handleSelectedUpCd }: UpCodeSectionProps) { }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.UP_CODE, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.UP_CODE, searchParams, pagination], queryFn: () => UpCodeApi.getUpCodeList({ - ...upCodeQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -40,7 +42,18 @@ function UpCodeSection({ handleSelectedUpCd }: UpCodeSectionProps) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keyword, + }); + }; + + const handleReset = () => { + setKeyword(""); + setSearchParams({ + ...searchParams, + keyword: "", + }); }; const { tableComponent, tableInstance: table } = useDataTable({ @@ -66,17 +79,20 @@ function UpCodeSection({ handleSelectedUpCd }: UpCodeSectionProps) { </Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={upCodeQuery.keyword} - onChange={(e) => - setUpCodeQuery({ - ...upCodeQuery, - keyword: e.target.value, - }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/contents/ui/contents-page.tsx b/apps/cs/src/pages/contents/ui/contents-page.tsx index 45d9f100e..c2e2704d1 100644 --- a/apps/cs/src/pages/contents/ui/contents-page.tsx +++ b/apps/cs/src/pages/contents/ui/contents-page.tsx @@ -17,8 +17,10 @@ import { columns } from "../model/table-columns"; function ContentsPage() { const router = useRouter(); - const [contentsQuery, setContentsQuery] = useState<ContentsParams>({ + const [contsTtl, setContsTtl] = useState(""); + const [searchParams, setSearchParams] = useState<ContentsParams>({ contsTtl: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -26,10 +28,10 @@ function ContentsPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.CONTENTS, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.CONTENTS, searchParams, pagination], queryFn: () => ContentsApi.getContentsList({ - ...contentsQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -38,7 +40,18 @@ function ContentsPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + contsTtl, + }); + }; + + const handleReset = () => { + setContsTtl(""); + setSearchParams({ + ...searchParams, + contsTtl: "", + }); }; const handleRowClick = (row: Contents) => { @@ -72,12 +85,20 @@ function ContentsPage() { </Label> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={contentsQuery.contsTtl} - onChange={(e) => setContentsQuery({ contsTtl: e.target.value })} + value={contsTtl} + onChange={(e) => setContsTtl(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/file/ui/file-page.tsx b/apps/cs/src/pages/file/ui/file-page.tsx index 67a313423..d717461aa 100644 --- a/apps/cs/src/pages/file/ui/file-page.tsx +++ b/apps/cs/src/pages/file/ui/file-page.tsx @@ -14,8 +14,10 @@ function FilePage() { const { confirm } = useConfirm(); const alert = useAlertStore((state) => state.setMessage); - const [attachmentQuery, setAttachmentQuery] = useState<AttachmentParams>({ + const [orgnlFileNm, setOrgnlFileNm] = useState(""); + const [searchParams, setSearchParams] = useState<AttachmentParams>({ orgnlFileNm: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -23,10 +25,10 @@ function FilePage() { }); const query = useQuery({ - queryKey: [ENDPOINT.ATTACH_SERVICE.ATTACHMENTS, pagination], + queryKey: [ENDPOINT.ATTACH_SERVICE.ATTACHMENTS, searchParams, pagination], queryFn: () => AttachmentApi.getAttachmentsList({ - ...attachmentQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -64,14 +66,20 @@ function FilePage() { }, }); - const handleAttachmentQueryChange = - (key: keyof AttachmentParams) => (value: string) => { - setAttachmentQuery({ ...attachmentQuery, [key]: value }); - }; - const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + orgnlFileNm, + }); + }; + + const handleReset = () => { + setOrgnlFileNm(""); + setSearchParams({ + ...searchParams, + orgnlFileNm: "", + }); }; return ( @@ -86,10 +94,8 @@ function FilePage() { <Input id="keyword" className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={attachmentQuery.orgnlFileNm || ""} - onChange={(e) => - handleAttachmentQueryChange("orgnlFileNm")(e.target.value) - } + value={orgnlFileNm} + onChange={(e) => setOrgnlFileNm(e.target.value)} placeholder="파일명을 입력하세요" /> </div> @@ -97,6 +103,14 @@ function FilePage() { <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/image/ui/image-page.tsx b/apps/cs/src/pages/image/ui/image-page.tsx index 3515cfbef..4b1bcd5cd 100644 --- a/apps/cs/src/pages/image/ui/image-page.tsx +++ b/apps/cs/src/pages/image/ui/image-page.tsx @@ -24,22 +24,23 @@ type PostingTarget = { function ImagePage() { const router = useRouter(); - const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); - const [postingTargets, setPostingTargets] = useState<PostingTarget[]>([]); - const [imageQuery, setImageQuery] = useState<ImageParams>({ - keyword: "" , - sort:"regDt,desc" + const [keyword, setKeyword] = useState(""); + const [searchParams, setSearchParams] = useState<ImageParams>({ + keyword: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 5, }); + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); + const [postingTargets, setPostingTargets] = useState<PostingTarget[]>([]); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.IMAGES, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.IMAGES, searchParams, pagination], queryFn: () => ImageApi.getImageList({ - ...imageQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -47,7 +48,18 @@ function ImagePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keyword, + }); + }; + + const handleReset = () => { + setKeyword(""); + setSearchParams({ + ...searchParams, + keyword: "", + }); }; const handleRowClick = (row: Image) => { @@ -99,14 +111,20 @@ function ImagePage() { </Label> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={imageQuery.keyword} - onChange={(e) => - setImageQuery({ ...imageQuery, keyword: e.target.value }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/module/ui/module-page.tsx b/apps/cs/src/pages/module/ui/module-page.tsx index 45524eba5..127aa66de 100644 --- a/apps/cs/src/pages/module/ui/module-page.tsx +++ b/apps/cs/src/pages/module/ui/module-page.tsx @@ -18,21 +18,23 @@ import { columns } from "../model/authorizations-table-columns"; function ModulePage() { const router = useRouter(); - const [authorizationQuery, setAuthorizationQuery] = - useState<AuthorizationsParams>({ - authorizationName: "", - httpMethodCode: "", - }); + const [authorizationName, setAuthorizationName] = useState(""); + const [httpMethodCode, setHttpMethodCode] = useState(""); + const [searchParams, setSearchParams] = useState<AuthorizationsParams>({ + authorizationName: "", + httpMethodCode: "", + sort: "regDt,desc", + }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10, }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.AUTHORIZATIONS, pagination], + queryKey: [ENDPOINT.USER_SERVICE.AUTHORIZATIONS, searchParams, pagination], queryFn: () => AuthorizationsApi.getAuthorizationsList({ - ...authorizationQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -60,14 +62,23 @@ function ModulePage() { }, }); - const handleAuthorizationQueryChange = - (key: keyof AuthorizationsParams) => (value: string) => { - setAuthorizationQuery({ ...authorizationQuery, [key]: value }); - }; - const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + authorizationName, + httpMethodCode, + }); + }; + + const handleReset = () => { + setAuthorizationName(""); + setHttpMethodCode(""); + setSearchParams({ + ...searchParams, + authorizationName: "", + httpMethodCode: "", + }); }; return ( @@ -81,7 +92,8 @@ function ModulePage() { </Label> <CodeSelect upCd="HTTPMHD" - onValueChange={handleAuthorizationQueryChange("httpMethodCode")} + value={httpMethodCode} + onValueChange={(value) => setHttpMethodCode(value)} /> </div> <div className="flex items-center gap-2"> @@ -91,18 +103,22 @@ function ModulePage() { <Input id="keyword" className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={authorizationQuery.authorizationName} - onChange={(e) => - handleAuthorizationQueryChange("authorizationName")( - e.target.value, - ) - } + value={authorizationName} + onChange={(e) => setAuthorizationName(e.target.value)} /> </div> </div> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/popup/ui/popup-page.tsx b/apps/cs/src/pages/popup/ui/popup-page.tsx index 475fee821..a8046c57e 100644 --- a/apps/cs/src/pages/popup/ui/popup-page.tsx +++ b/apps/cs/src/pages/popup/ui/popup-page.tsx @@ -25,8 +25,10 @@ type PostingTarget = { function PopupPage() { const router = useRouter(); - const [popupParams, setPopupParams] = useState<PopupParams>({ + const [keyword, setKeyword] = useState(""); + const [searchParams, setSearchParams] = useState<PopupParams>({ keyword: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -36,10 +38,10 @@ function PopupPage() { const [postingTargets, setPostingTargets] = useState<PostingTarget[]>([]); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.POPUPS, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.POPUPS, searchParams, pagination], queryFn: () => PopupApi.getPopupList({ - ...popupParams, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -48,7 +50,18 @@ function PopupPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keyword, + }); + }; + + const handleReset = () => { + setKeyword(""); + setSearchParams({ + ...searchParams, + keyword: "", + }); }; const handleRowClick = (row: Popup) => { @@ -99,14 +112,20 @@ function PopupPage() { </Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={popupParams.keyword} - onChange={(e) => - setPopupParams({ ...popupParams, keyword: e.target.value }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/recent/ui/recent-page.tsx b/apps/cs/src/pages/recent/ui/recent-page.tsx index 26cf3af85..4e33eab89 100644 --- a/apps/cs/src/pages/recent/ui/recent-page.tsx +++ b/apps/cs/src/pages/recent/ui/recent-page.tsx @@ -51,28 +51,43 @@ function RecentPage() { const { confirm } = useConfirm(); const alert = useAlertStore((state) => state.setMessage); - const [dateRange, setDateRange] = useState<DateRange>(); + const [dateRange, setDateRange] = useState<DateRange | undefined>({ + from: undefined, + to: undefined, + }); const [tableSort, setTableSort] = useState("regDt,desc"); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10, }); const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); - const [recentPostQuery, setRecentPostQuery] = useState<RecentPostParams>({ + + const [keywordType, setKeywordType] = useState(""); + const [keyword, setKeyword] = useState(""); + const [bbsId, setBbsId] = useState<string | null>(null); + const [delYn, setDelYn] = useState("N"); + + const [searchParams, setSearchParams] = useState<RecentPostParams>({ keywordType: "", keyword: "", bbsId: null, delYn: "N", frDateYmd: "", toDateYmd: "", + sort: "regDt,desc", }); const [isDeletePostData, setIsDeletePostData] = useState(false); const query = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, pagination, tableSort], + queryKey: [ + ENDPOINT.BOARD_SERVICE.POSTS, + searchParams, + pagination, + tableSort, + ], queryFn: () => PostApi.getRecentPostList({ - ...recentPostQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, sort: tableSort, @@ -115,14 +130,40 @@ function RecentPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - setIsDeletePostData(recentPostQuery.delYn === "Y"); - query.refetch(); + setIsDeletePostData(delYn === "Y"); + setSearchParams({ + ...searchParams, + keywordType, + keyword, + bbsId: bbsId ? parseInt(bbsId) : null, + delYn, + frDateYmd: dateRange?.from + ? dayjs(dateRange.from).format("YYYYMMDD") + : "", + toDateYmd: dateRange?.to ? dayjs(dateRange.to).format("YYYYMMDD") : "", + }); }; - const handleRecentPostParamsChange = - (key: keyof RecentPostParams) => (value: unknown) => { - setRecentPostQuery({ ...recentPostQuery, [key]: value }); - }; + const handleReset = () => { + setKeywordType(""); + setKeyword(""); + setBbsId(null); + setDelYn("N"); + setDateRange({ + from: undefined, + to: undefined, + }); + setSearchParams({ + ...searchParams, + keywordType: "", + keyword: "", + bbsId: null, + delYn: "N", + frDateYmd: "", + toDateYmd: "", + }); + setIsDeletePostData(false); + }; const handlePresetDateRange = (value: string) => { let presetDateRange: DateRange | undefined; @@ -148,16 +189,7 @@ function RecentPage() { default: presetDateRange = undefined; } - handleDateRangeChange(presetDateRange); - }; - - const handleDateRangeChange = (value: DateRange | undefined) => { - setDateRange(value); - setRecentPostQuery({ - ...recentPostQuery, - frDateYmd: dayjs(value?.from).format("YYYYMMDD") ?? "", - toDateYmd: dayjs(value?.to).format("YYYYMMDD") ?? "", - }); + setDateRange(presetDateRange); }; const onSoftDeletePost = async () => { @@ -214,10 +246,7 @@ function RecentPage() { <div className="card card-border"> <form onSubmit={handleSubmit} className="flex items-center gap-2 p-2"> <Label className="mr-2">날짜</Label> - <DateRangePicker - value={dateRange} - onValueChange={handleDateRangeChange} - > + <DateRangePicker value={dateRange} onValueChange={setDateRange}> <div className="card card-border flex items-center gap-2"> <Select onValueChange={handlePresetDateRange}> <SelectTrigger> @@ -233,7 +262,10 @@ function RecentPage() { </DateRangePicker> <Label className="ml-4 mr-2 text-label">게시판</Label> - <Select onValueChange={handleRecentPostParamsChange("bbsId")}> + <Select + value={bbsId?.toString() || ""} + onValueChange={(value) => setBbsId(value ? value : null)} + > <SelectTrigger className="w-[12rem]"> <SelectValue placeholder="선택" /> </SelectTrigger> @@ -247,7 +279,7 @@ function RecentPage() { </Select> <Label className="ml-4 mr-2 text-label">상태</Label> - <Select onValueChange={handleRecentPostParamsChange("delYn")}> + <Select value={delYn} onValueChange={(value) => setDelYn(value)}> <SelectTrigger className="w-[10rem]"> <SelectValue placeholder="선택" /> </SelectTrigger> @@ -259,8 +291,8 @@ function RecentPage() { <Label className="ml-4 mr-2 text-label">검색</Label> <Select - value={recentPostQuery.keywordType} - onValueChange={handleRecentPostParamsChange("keywordType")} + value={keywordType} + onValueChange={(value) => setKeywordType(value)} > <SelectTrigger className="h-[3.2rem] w-[10rem]"> <SelectValue placeholder="선택" /> @@ -272,15 +304,21 @@ function RecentPage() { </SelectContent> </Select> <Input - value={recentPostQuery.keyword} - onChange={(e) => - handleRecentPostParamsChange("keyword")(e.target.value) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/role/ui/role-page.tsx b/apps/cs/src/pages/role/ui/role-page.tsx index 9d864255c..7e20b3715 100644 --- a/apps/cs/src/pages/role/ui/role-page.tsx +++ b/apps/cs/src/pages/role/ui/role-page.tsx @@ -13,8 +13,10 @@ import { columns } from "../model/table-columns"; function RolePage() { const router = useRouter(); - const [roleQuery, setRoleQuery] = useState<RoleParams>({ + const [keyword, setKeyword] = useState(""); + const [searchParams, setSearchParams] = useState<RoleParams>({ keyword: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -22,10 +24,10 @@ function RolePage() { }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.ROLES, pagination], + queryKey: [ENDPOINT.USER_SERVICE.ROLES, searchParams, pagination], queryFn: () => RoleApi.getRoles({ - ...roleQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -54,7 +56,18 @@ function RolePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keyword, + }); + }; + + const handleReset = () => { + setKeyword(""); + setSearchParams({ + ...searchParams, + keyword: "", + }); }; return ( @@ -66,14 +79,20 @@ function RolePage() { </Label> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={roleQuery.keyword} - onChange={(e) => - setRoleQuery({ ...roleQuery, keyword: e.target.value }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/site/ui/site-page.tsx b/apps/cs/src/pages/site/ui/site-page.tsx index 734ba7658..046c80142 100644 --- a/apps/cs/src/pages/site/ui/site-page.tsx +++ b/apps/cs/src/pages/site/ui/site-page.tsx @@ -14,10 +14,10 @@ import { columns } from "../model/table-columns"; function SitePage() { const router = useRouter(); - - const [siteQuery, setSiteQuery] = useState<SiteParams>({ + const [siteNm, setSiteNm] = useState(""); + const [searchParams, setSearchParams] = useState<SiteParams>({ siteNm: "", - sort:"regDt,desc" + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -25,10 +25,10 @@ function SitePage() { }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.SITES, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.SITES, searchParams, pagination], queryFn: () => SiteApi.getSiteList({ - ...siteQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -37,7 +37,18 @@ function SitePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + siteNm, + }); + }; + + const handleReset = () => { + setSiteNm(""); + setSearchParams({ + ...searchParams, + siteNm: "", + }); }; const handleRowClick = (row: Site) => { @@ -65,17 +76,26 @@ function SitePage() { <div className="card card-border !mt-6"> <div className="card card-border"> <form onSubmit={handleSubmit} className="flex items-center gap-2 p-2"> - <Label htmlFor="" className="mr-2 text-label"> + <Label htmlFor="siteNm" className="mr-2 text-label"> 사이트명 </Label> <Input + name="siteNm" + value={siteNm} + onChange={(e) => setSiteNm(e.target.value)} className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={siteQuery.siteNm} - onChange={(e) => setSiteQuery({ siteNm: e.target.value })} /> - <Button className="h-[3.2rem]" type="submit"> + <Button type="submit" className="h-[3.2rem]"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/survey/ui/survey-page.tsx b/apps/cs/src/pages/survey/ui/survey-page.tsx index c34a21f6f..ff64014ce 100644 --- a/apps/cs/src/pages/survey/ui/survey-page.tsx +++ b/apps/cs/src/pages/survey/ui/survey-page.tsx @@ -25,8 +25,10 @@ type PostingTarget = { function SurveyPage() { const router = useRouter(); - const [surveyParams, setSurveyParams] = useState<SurveyParams>({ + const [srvyTtl, setSrvyTtl] = useState(""); + const [searchParams, setSearchParams] = useState<SurveyParams>({ srvyTtl: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -36,10 +38,10 @@ function SurveyPage() { const [postingTargets, setPostingTargets] = useState<PostingTarget[]>([]); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.SURVEY, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.SURVEY, searchParams, pagination], queryFn: () => SurveyApi.getSurveyList({ - ...surveyParams, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -71,7 +73,18 @@ function SurveyPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + srvyTtl, + }); + }; + + const handleReset = () => { + setSrvyTtl(""); + setSearchParams({ + ...searchParams, + srvyTtl: "", + }); }; useEffect(() => { @@ -99,14 +112,20 @@ function SurveyPage() { </Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={surveyParams.srvyTtl} - onChange={(e) => - setSurveyParams({ ...surveyParams, srvyTtl: e.target.value }) - } + value={srvyTtl} + onChange={(e) => setSrvyTtl(e.target.value)} /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/template/ui/template-page.tsx b/apps/cs/src/pages/template/ui/template-page.tsx index 59e8c8b01..de3dca8ff 100644 --- a/apps/cs/src/pages/template/ui/template-page.tsx +++ b/apps/cs/src/pages/template/ui/template-page.tsx @@ -14,22 +14,23 @@ import type { Template, TemplateParams } from "../model/template-interface"; function TemplatePage() { const router = useRouter(); - - const [templateQuery, setTemplateQuery] = useState<TemplateParams>({ - tmpltSeCd: "", + const [keyword, setKeyword] = useState(""); + const [tmpltSeCd, setTmpltSeCd] = useState(""); + const [searchParams, setSearchParams] = useState<TemplateParams>({ keyword: "", - sort:"regDt,desc" + tmpltSeCd: "", + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, - pageSize: 5, + pageSize: 10, }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.TEMPLATE, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.TEMPLATE, searchParams, pagination], queryFn: () => TemplateApi.getTemplateList({ - ...templateQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -38,7 +39,21 @@ function TemplatePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keyword, + tmpltSeCd, + }); + }; + + const handleReset = () => { + setKeyword(""); + setTmpltSeCd(""); + setSearchParams({ + ...searchParams, + keyword: "", + tmpltSeCd: "", + }); }; const handleRowClick = (row: Template) => { @@ -73,10 +88,8 @@ function TemplatePage() { </Label> <CodeSelect upCd="TMPLTCLCD" - value={templateQuery.tmpltSeCd} - onValueChange={(value) => - setTemplateQuery({ ...templateQuery, tmpltSeCd: value }) - } + value={tmpltSeCd} + onValueChange={(value) => setTmpltSeCd(value)} /> </div> <div className="flex items-center gap-2"> @@ -85,19 +98,22 @@ function TemplatePage() { </Label> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={templateQuery.keyword} - onChange={(e) => - setTemplateQuery({ - ...templateQuery, - keyword: e.target.value, - }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} /> </div> </div> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/terms/ui/terms-page.tsx b/apps/cs/src/pages/terms/ui/terms-page.tsx index 617d4eff6..31feb29f4 100644 --- a/apps/cs/src/pages/terms/ui/terms-page.tsx +++ b/apps/cs/src/pages/terms/ui/terms-page.tsx @@ -15,10 +15,12 @@ import type { TermsParams, Terms } from "../model/terms-interface"; function TermsPage() { const router = useRouter(); - const [termsQuery, setTermsQuery] = useState<TermsParams>({ + const [keyword, setKeyword] = useState(""); + const [trmsSeCd, setTrmsSeCd] = useState(""); + const [searchParams, setSearchParams] = useState<TermsParams>({ + keyword: "", trmsSeCd: "", - keyword: "", - sort:"regDt,desc" + sort: "regDt,desc", }); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, @@ -26,10 +28,10 @@ function TermsPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.TERMS, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.TERMS, searchParams, pagination], queryFn: () => TermsApi.getTermsList({ - ...termsQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -38,7 +40,21 @@ function TermsPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keyword, + trmsSeCd, + }); + }; + + const handleReset = () => { + setKeyword(""); + setTrmsSeCd(""); + setSearchParams({ + ...searchParams, + keyword: "", + trmsSeCd: "", + }); }; const handleRowClick = (row: Terms) => { @@ -73,10 +89,8 @@ function TermsPage() { </Label> <CodeSelect upCd="TRMSCLCD" - value={termsQuery.trmsSeCd} - onValueChange={(value) => - setTermsQuery({ ...termsQuery, trmsSeCd: value }) - } + value={trmsSeCd} + onValueChange={(value) => setTrmsSeCd(value)} /> </div> <div className="flex items-center gap-2"> @@ -85,19 +99,22 @@ function TermsPage() { </Label> <Input className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" - value={termsQuery.keyword} - onChange={(e) => - setTermsQuery({ - ...termsQuery, - keyword: e.target.value, - }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} /> </div> </div> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/users/ui/users-page.tsx b/apps/cs/src/pages/users/ui/users-page.tsx index 2ffe05eb4..c5e71cefd 100644 --- a/apps/cs/src/pages/users/ui/users-page.tsx +++ b/apps/cs/src/pages/users/ui/users-page.tsx @@ -2,7 +2,6 @@ import dayjs from "dayjs"; import { useState } from "react"; -import { useForm } from "react-hook-form"; import { useRouter } from "next/navigation"; import { useQuery } from "@tanstack/react-query"; import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; @@ -40,19 +39,25 @@ function UsersPage() { pageIndex: 0, pageSize: 10, }); - const [dateRange, setDateRange] = useState<DateRange>(); + const [dateRange, setDateRange] = useState<DateRange | undefined>({ + from: undefined, + to: undefined, + }); + const [keywordType, setKeywordType] = useState("all"); + const [keyword, setKeyword] = useState(""); + const [userStateCode, setUserStateCode] = useState(""); + const [aprvYn, setAprvYn] = useState(""); + const [grpId, setGrpId] = useState(""); - const { register, watch, setValue, getValues } = useForm<UserSearchParams>({ - defaultValues: { - keywordType: "all", - keyword: "", - userStateCode: "", - aprvYn: "", - grpId: "", - frDateYmd: "", - toDateYmd: "", - sort: "regDt,desc" - }, + const [searchParams, setSearchParams] = useState<UserSearchParams>({ + keywordType: "all", + keyword: "", + userStateCode: "", + aprvYn: "", + grpId: "", + frDateYmd: "", + toDateYmd: "", + sort: "regDt,desc", }); const { data: userSttsStats } = useQuery({ @@ -61,16 +66,16 @@ function UsersPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.USERS, pagination, watch("sort")], + queryKey: [ENDPOINT.USER_SERVICE.USERS, searchParams, pagination], queryFn: () => UserApi.findPageUser({ - ...getValues(), + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), }); - const { data: userStateCode } = useQuery({ + const { data: userStateCodes } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.CODE], queryFn: () => CodeApi.getCode("USERSTTS"), }); @@ -98,7 +103,40 @@ function UsersPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + keywordType, + keyword, + userStateCode, + aprvYn, + grpId, + frDateYmd: dateRange?.from + ? dayjs(dateRange.from).format("YYYYMMDD") + : "", + toDateYmd: dateRange?.to ? dayjs(dateRange.to).format("YYYYMMDD") : "", + }); + }; + + const handleReset = () => { + setKeywordType("all"); + setKeyword(""); + setUserStateCode(""); + setAprvYn(""); + setGrpId(""); + setDateRange({ + from: undefined, + to: undefined, + }); + setSearchParams({ + ...searchParams, + keywordType: "all", + keyword: "", + userStateCode: "", + aprvYn: "", + grpId: "", + frDateYmd: "", + toDateYmd: "", + }); }; const handlePresetDateRange = (value: string) => { @@ -126,8 +164,6 @@ function UsersPage() { presetDateRange = undefined; } setDateRange(presetDateRange); - setValue("frDateYmd", dayjs(presetDateRange?.from).format("YYYYMMDD")); - setValue("toDateYmd", dayjs(presetDateRange?.to).format("YYYYMMDD")); }; const getUserSttsStatsCnt = (code: string): number => { @@ -135,6 +171,21 @@ function UsersPage() { return userSttsStats.find((item) => item.sttsCd === code)?.cnt ?? 0; }; + const handleUserStateCodeChange = (code: string, checked: boolean) => { + let newUserStateCode = userStateCode; + + if (checked) { + newUserStateCode = userStateCode ? `${userStateCode},${code}` : code; + } else { + newUserStateCode = userStateCode + .split(",") + .filter((c) => c !== code) + .join(","); + } + + setUserStateCode(newUserStateCode); + }; + return ( <div className="card card-border !mt-6"> <div className="card card-border flex items-center justify-center gap-10 !bg-accent !py-6"> @@ -195,8 +246,8 @@ function UsersPage() { 회원정보 </Label> <Select - {...register("keywordType")} - onValueChange={(value) => setValue("keywordType", value)} + value={keywordType} + onValueChange={(value) => setKeywordType(value)} > <SelectTrigger className="w-[18rem]"> <SelectValue placeholder="선택" /> @@ -210,7 +261,8 @@ function UsersPage() { </SelectContent> </Select> <Input - {...register("keyword")} + value={keyword} + onChange={(e) => setKeyword(e.target.value)} className="!text-[1.3rem]" placeholder="검색어를 입력하세요" /> @@ -221,14 +273,7 @@ function UsersPage() { </div> <div className="flex items-center gap-2"> <Label className="mr-2 text-label">기간</Label> - <DateRangePicker - value={dateRange} - onValueChange={(value) => { - setDateRange(value); - setValue("frDateYmd", dayjs(value?.from).format("YYYYMMDD")); - setValue("toDateYmd", dayjs(value?.to).format("YYYYMMDD")); - }} - > + <DateRangePicker value={dateRange} onValueChange={setDateRange}> <div className="card card-border flex items-center gap-2"> <Select onValueChange={handlePresetDateRange}> <SelectTrigger> @@ -250,24 +295,14 @@ function UsersPage() { <div className="flex items-center gap-2"> <Label className="mr-2 text-label">회원상태</Label> <div className="flex gap-4"> - {userStateCode?.map((item) => ( + {userStateCodes?.map((item) => ( <div key={item.lwpoCd} className="flex items-center gap-2"> <Checkbox id={item.lwpoCd} value={item.lwpoCd} - checked={watch("userStateCode")?.includes(item.lwpoCd)} + checked={userStateCode?.includes(item.lwpoCd)} onCheckedChange={(checked) => { - setValue( - "userStateCode", - checked - ? getValues("userStateCode") - ? `${getValues("userStateCode")},${item.lwpoCd}` - : item.lwpoCd - : getValues("userStateCode") - ?.split(",") - .filter((code) => code !== item.lwpoCd) - .join(","), - ); + handleUserStateCodeChange(item.lwpoCd, !!checked); }} /> <Label htmlFor={item.lwpoCd}>{item.lwpoCdNm}</Label> @@ -276,10 +311,20 @@ function UsersPage() { </div> </div> <hr /> - <Button type="submit" className="mx-auto w-[16rem]"> - <i className="diveicon di-search" /> - 검색 - </Button> + <div className="flex justify-center gap-2"> + <Button type="submit" className="w-[16rem]"> + <i className="diveicon di-search" /> + 검색 + </Button> + <Button + type="button" + color="white" + className="w-[16rem]" + onClick={handleReset} + > + 초기화 + </Button> + </div> </form> </div> <div className="card card-border"> @@ -290,7 +335,10 @@ function UsersPage() { <Select defaultValue="regDt,desc" onValueChange={(value) => { - setValue("sort", value); + setSearchParams({ + ...searchParams, + sort: value, + }); }} > <SelectTrigger> From f1b28246d68f516a10a156b68f5333e56be7f193 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 02:03:19 +0900 Subject: [PATCH 062/159] =?UTF-8?q?[apps/cs]=20chore:=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95=20(CS=5FUT0?= =?UTF-8?q?1020105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/shared/lib/use-mutation-wrapper.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/cs/src/shared/lib/use-mutation-wrapper.tsx b/apps/cs/src/shared/lib/use-mutation-wrapper.tsx index ce119d2a7..cea1a8f83 100644 --- a/apps/cs/src/shared/lib/use-mutation-wrapper.tsx +++ b/apps/cs/src/shared/lib/use-mutation-wrapper.tsx @@ -17,15 +17,13 @@ export const useMutationWrapper = < let errorMessage = ""; if (error instanceof AxiosError) { - if (error.response?.status) - errorMessage += `status: ${error.response.status}\n`; if (error.response?.data?.message) errorMessage += `${error.response.data.message}\n`; if (error.response?.data?.errors[0]?.message) errorMessage += `${error.response.data.errors[0].message}\n`; } - alert(`[Error] ${errorMessage}`); + alert(`${errorMessage}`); }, }); }; From 5a5ed9e669677a70beb42c641fce78fa238f936b Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Thu, 10 Jul 2025 09:21:54 +0900 Subject: [PATCH 063/159] =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx index 27d7dfa94..a88054d50 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -55,7 +55,6 @@ export default function RainSttn() { const [fcltNm, setFcltNm] = useState<string>(""); const cellClick = (index: number | undefined, headId: string) => { - if (headId !== 'chBuildingYn' && index !== undefined && bdstTable !== undefined) { setDetailModal({ isOpen: true, data: bdstTable[index] }) } else if (headId === 'chBuildingYn' && index !== undefined && bdstTable !== undefined) { @@ -67,14 +66,12 @@ export default function RainSttn() { 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 }); } @@ -129,7 +126,7 @@ export default function RainSttn() { }) .filter((item: any) => item.rainyObj !== undefined); setBdstTable(chData); - }, [code, rainSttnRes, rainSttn.rainSttHeadList]); + }, [code, rainSttnRes]); useEffect(() => { rainSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); From b723c5b1efebe6a67b63f19a01bcd1a968e515ba Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Thu, 10 Jul 2025 09:30:38 +0900 Subject: [PATCH 064/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=EC=8B=A0=EA=B7=9C=EC=B8=84?= =?UTF-8?q?=EA=B0=80(=EC=B5=9C=EC=B4=88=EB=93=B1=EB=A1=9D)=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95(zod.prase=20=EC=A0=9C=EA=B1=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 29b65c9c8..1f7d88824 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -272,19 +272,20 @@ export default function PublicReuseFaciltyInsert() { } } else { if (selecTableRow) { - append( - pbnstRegZod.parse({ - pbnstRuseFcltPk: String(selecTableRow.bscFctCd) + "1", - ruseUtztnFcltNm: "", - regDt: null, - mdfcnDt: null, - fcBizs: [ - fcBizSchema.parse({ - pbnstRuseFcltFk: String(selecTableRow.bscFctCd) + "1", - cycl: 1, - }), - ] as fcBizType[], - }) + append(createDefaultPbnstItem(selecTableRow, 0) + // { + // pbnstRuseFcltPk: String(selecTableRow.bscFctCd) + "1", + // ruseUtztnFcltNm: "", + // regDt: null, + // mdfcnDt: null, + // fcBizs: [ + // fcBizSchema.parse({ + // pbnstRuseFcltFk: String(selecTableRow.bscFctCd) + "1", + // cycl: 1, + // }), + // ] as fcBizType[], + // } + // ) ); setIsRuseReg({ isModal: true }); } From 7728717e66ec2b9286ac4b389572d67f25e1f471 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 10:02:46 +0900 Subject: [PATCH 065/159] =?UTF-8?q?[apps/cs]=20feat:=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=20(CS=5FUT01010101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/apilog/ui/apilog-page.tsx | 81 +++++++------ .../src/pages/loginlog/ui/loginlog-page.tsx | 74 ++++++------ .../pages/privacylog/ui/privacylog-page.tsx | 110 +++++++++--------- 3 files changed, 137 insertions(+), 128 deletions(-) diff --git a/apps/cs/src/pages/apilog/ui/apilog-page.tsx b/apps/cs/src/pages/apilog/ui/apilog-page.tsx index 4bfce86e2..2785fbde8 100644 --- a/apps/cs/src/pages/apilog/ui/apilog-page.tsx +++ b/apps/cs/src/pages/apilog/ui/apilog-page.tsx @@ -26,36 +26,32 @@ type DateRange = { to?: Date | undefined; }; -function ApiLogPage({}) { - // 1주일 전부터 오늘까지 기본 날짜 설정 +function ApiLogPage() { const defaultDateRange: DateRange = { from: dayjs().subtract(7, "day").toDate(), to: dayjs().toDate(), }; - const [dateRange, setDateRange] = useState<DateRange>(defaultDateRange); - const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10, }); - - const [loginlogPostQuery, setLoginlogPostQuery] = useState<ApiLogParams>({ + const [dateRange, setDateRange] = useState<DateRange>(defaultDateRange); + const [userId, setUserId] = useState(""); + const [apiHttpPmhd, setApiHttpPmhd] = useState(""); + const [searchParams, setSearchParams] = useState<ApiLogParams>({ userId: "", - siteId: "", apiHttpPmhd: "", - dmndUrl: "", - ipAddr: "", dmndDtStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), dmndDtEnd: dayjs().format("YYYY-MM-DD"), - sort: "lgnDt,asc", + sort: "regDt,desc", }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.APILOG, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.APILOG, searchParams, pagination], queryFn: () => ApiLogApi.getApiLogList({ - ...loginlogPostQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -81,13 +77,27 @@ function ApiLogPage({}) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + userId, + apiHttpPmhd, + dmndDtStart: dayjs(dateRange.from).format("YYYY-MM-DD"), + dmndDtEnd: dayjs(dateRange.to).format("YYYY-MM-DD"), + }); }; - const handleLoginlogParamsChange = - (key: keyof ApiLogParams) => (value: unknown) => { - setLoginlogPostQuery({ ...loginlogPostQuery, [key]: value }); - }; + const handleReset = () => { + setUserId(""); + setApiHttpPmhd(""); + setDateRange(defaultDateRange); + setSearchParams({ + ...searchParams, + userId: "", + apiHttpPmhd: "", + dmndDtStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), + dmndDtEnd: dayjs().format("YYYY-MM-DD"), + }); + }; const handlePresetDateRange = (value: string) => { let presetDateRange: DateRange | undefined; @@ -113,19 +123,7 @@ function ApiLogPage({}) { default: presetDateRange = undefined; } - handleDateRangeChange(presetDateRange); - }; - - const handleDateRangeChange = (value: DateRange | undefined) => { - setDateRange(value || defaultDateRange); - setLoginlogPostQuery({ - ...loginlogPostQuery, - dmndDtStart: - dayjs(value?.from).format("YYYY-MM-DD") ?? - dayjs().subtract(7, "day").format("YYYY-MM-DD"), - dmndDtEnd: - dayjs(value?.to).format("YYYY-MM-DD") ?? dayjs().format("YYYY-MM-DD"), - }); + setDateRange(presetDateRange || defaultDateRange); }; return ( @@ -135,7 +133,7 @@ function ApiLogPage({}) { <Label className="mr-2">조회기간</Label> <DateRangePicker value={dateRange} - onValueChange={handleDateRangeChange} + onValueChange={(value) => setDateRange(value || defaultDateRange)} > <div className="card card-border flex items-center gap-2"> <Select onValueChange={handlePresetDateRange}> @@ -152,14 +150,15 @@ function ApiLogPage({}) { </DateRangePicker> <Label className="ml-4 mr-2 text-label">사용자ID</Label> <Input + value={userId} + onChange={(e) => setUserId(e.target.value)} className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={loginlogPostQuery.userId} - onChange={(e) => - handleLoginlogParamsChange("userId")(e.target.value) - } /> <Label className="ml-4 mr-2 text-label">상태</Label> - <Select onValueChange={handleLoginlogParamsChange("apiHttpPmhd")}> + <Select + value={apiHttpPmhd} + onValueChange={(value) => setApiHttpPmhd(value)} + > <SelectTrigger className="w-[10rem]"> <SelectValue placeholder="선택" /> </SelectTrigger> @@ -173,12 +172,20 @@ function ApiLogPage({}) { <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> <div className="card-header"> <div className="flex w-full items-center justify-between"> - <h3 className="text-2xl font-medium text-label">로그인로그 목록</h3> + <h3 className="text-2xl font-medium text-label">작업로그 목록</h3> <div className="flex gap-2"> <Select value={table.getState().pagination.pageSize.toString()} diff --git a/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx b/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx index 1672a5bd8..661ca0114 100644 --- a/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx +++ b/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx @@ -27,8 +27,7 @@ type DateRange = { to?: Date | undefined; }; -function LoginlogPage({}) { - // 1주일 전부터 오늘까지 기본 날짜 설정 +function LoginlogPage() { const defaultDateRange: DateRange = { from: dayjs().subtract(7, "day").toDate(), to: dayjs().toDate(), @@ -41,24 +40,21 @@ function LoginlogPage({}) { pageIndex: 0, pageSize: 10, }); - - const [loginlogPostQuery, setLoginlogPostQuery] = useState<LoginlogParams>({ + const [userId, setUserId] = useState(""); + const [errOcrnYn, setErrOcrnYn] = useState("N"); + const [searchParams, setSearchParams] = useState<LoginlogParams>({ userId: "", - siteId: "", errOcrnYn: "N", - remoteIp: "", - lgnMthd: "", - lgnErrCd: "", searchDateFrom: dayjs().subtract(7, "day").format("YYYY-MM-DD"), searchDateTo: dayjs().format("YYYY-MM-DD"), sort: "lgnDt,desc", }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.LOGINLOG, pagination], + queryKey: [ENDPOINT.USER_SERVICE.LOGINLOG, searchParams, pagination], queryFn: () => LoginlogApi.getLoginlogList({ - ...loginlogPostQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -85,15 +81,30 @@ function LoginlogPage({}) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); setIsManualLoading(true); + setSearchParams({ + ...searchParams, + userId, + errOcrnYn, + searchDateFrom: dayjs(dateRange.from).format("YYYY-MM-DD"), + searchDateTo: dayjs(dateRange.to).format("YYYY-MM-DD"), + }); query.refetch().finally(() => { setIsManualLoading(false); }); }; - const handleLoginlogParamsChange = - (key: keyof LoginlogParams) => (value: unknown) => { - setLoginlogPostQuery({ ...loginlogPostQuery, [key]: value }); - }; + const handleReset = () => { + setUserId(""); + setErrOcrnYn("N"); + setDateRange(defaultDateRange); + setSearchParams({ + ...searchParams, + userId: "", + errOcrnYn: "N", + searchDateFrom: dayjs().subtract(7, "day").format("YYYY-MM-DD"), + searchDateTo: dayjs().format("YYYY-MM-DD"), + }); + }; const handlePresetDateRange = (value: string) => { let presetDateRange: DateRange | undefined; @@ -119,19 +130,7 @@ function LoginlogPage({}) { default: presetDateRange = undefined; } - handleDateRangeChange(presetDateRange); - }; - - const handleDateRangeChange = (value: DateRange | undefined) => { - setDateRange(value || defaultDateRange); - setLoginlogPostQuery({ - ...loginlogPostQuery, - searchDateFrom: - dayjs(value?.from).format("YYYY-MM-DD") ?? - dayjs().subtract(7, "day").format("YYYY-MM-DD"), - searchDateTo: - dayjs(value?.to).format("YYYY-MM-DD") ?? dayjs().format("YYYY-MM-DD"), - }); + setDateRange(presetDateRange || defaultDateRange); }; return ( @@ -141,7 +140,7 @@ function LoginlogPage({}) { <Label className="mr-2">조회기간</Label> <DateRangePicker value={dateRange} - onValueChange={handleDateRangeChange} + onValueChange={(value) => setDateRange(value || defaultDateRange)} > <div className="card card-border flex items-center gap-2"> <Select onValueChange={handlePresetDateRange}> @@ -159,13 +158,14 @@ function LoginlogPage({}) { <Label className="ml-4 mr-2 text-label">사용자ID</Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={loginlogPostQuery.userId} - onChange={(e) => - handleLoginlogParamsChange("userId")(e.target.value) - } + value={userId} + onChange={(e) => setUserId(e.target.value)} /> <Label className="ml-4 mr-2 text-label">상태</Label> - <Select onValueChange={handleLoginlogParamsChange("errOcrnYn")}> + <Select + value={errOcrnYn} + onValueChange={(value) => setErrOcrnYn(value)} + > <SelectTrigger className="w-[10rem]"> <SelectValue placeholder="선택" /> </SelectTrigger> @@ -183,6 +183,14 @@ function LoginlogPage({}) { ? "조회 중..." : "조회"} </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> diff --git a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx index 5cb8bf13d..3637b80d4 100644 --- a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx +++ b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx @@ -3,65 +3,54 @@ import dayjs from "dayjs"; import { useState } from "react"; import { keepPreviousData, useQuery } from "@tanstack/react-query"; +import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; import { - getCoreRowModel, - type PaginationState, -} from "@tanstack/react-table"; -import { - Button, - DateRangePicker, - Input, + Button, + DateRangePicker, + Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, - } from "@common/components"; +} from "@common/components"; import { PrivacyLogPrivacy } from "@/entities/privacylog"; -import { type PrivacyLogParams} from "@/entities/privacylog/model/privacylog-interface"; -import { useDataTable } from "@/shared/lib"; +import type { PrivacyLogParams } from "@/entities/privacylog/model/privacylog-interface"; +import { useDataTable } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; import { columns } from "@/pages/privacylog/model/table-columns"; - - type DateRange = { from: Date | undefined; to?: Date | undefined; }; -function PrivacyLogPage({ }) { - - // 1주일 전부터 오늘까지 기본 날짜 설정 +function PrivacyLogPage() { const defaultDateRange: DateRange = { from: dayjs().subtract(7, "day").toDate(), to: dayjs().toDate(), }; - - const [dateRange, setDateRange] = useState<DateRange>(defaultDateRange); const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10, }); - - const [privacylogPostQuery, setprivacylogPostQuery] = useState< PrivacyLogParams>({ - siteId: "", - inqInfoKeywordType: "userName", - inqInfoKeyword: "", - rqstrIp: "", - inqDtStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), - inqDtEnd: dayjs().format("YYYY-MM-DD"), - sort:"inqDt,asc" + const [dateRange, setDateRange] = useState<DateRange>(defaultDateRange); + const [inqInfoKeyword, setInqInfoKeyword] = useState(""); + const [searchParams, setSearchParams] = useState<PrivacyLogParams>({ + inqInfoKeywordType: "userName", + inqInfoKeyword: "", + inqDtStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), + inqDtEnd: dayjs().format("YYYY-MM-DD"), + sort: "inqDt,asc", }); - - + const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.PRIVACYLOG, pagination], + queryKey: [ENDPOINT.USER_SERVICE.PRIVACYLOG, searchParams, pagination], queryFn: () => PrivacyLogPrivacy.getPrivacyLogList({ - ...privacylogPostQuery, + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -87,14 +76,25 @@ function PrivacyLogPage({ }) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - query.refetch(); + setSearchParams({ + ...searchParams, + inqInfoKeyword, + inqDtStart: dayjs(dateRange.from).format("YYYY-MM-DD"), + inqDtEnd: dayjs(dateRange.to).format("YYYY-MM-DD"), + }); }; - const handleprivacylogParamsChange = - (key: keyof PrivacyLogParams) => (value: unknown) => { - setprivacylogPostQuery({ ...privacylogPostQuery, [key]: value }); + const handleReset = () => { + setInqInfoKeyword(""); + setDateRange(defaultDateRange); + setSearchParams({ + ...searchParams, + inqInfoKeyword: "", + inqDtStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), + inqDtEnd: dayjs().format("YYYY-MM-DD"), + }); }; - + const handlePresetDateRange = (value: string) => { let presetDateRange: DateRange | undefined; switch (value) { @@ -119,23 +119,9 @@ function PrivacyLogPage({ }) { default: presetDateRange = undefined; } - handleDateRangeChange(presetDateRange); + setDateRange(presetDateRange || defaultDateRange); }; - - - const handleDateRangeChange = (value: DateRange | undefined) => { - setDateRange(value || defaultDateRange); - setprivacylogPostQuery({ - ...privacylogPostQuery, - inqDtStart: dayjs(value?.from).format("YYYY-MM-DD") ?? dayjs().subtract(7, "day").format("YYYY-MM-DD"), - inqDtEnd: dayjs(value?.to).format("YYYY-MM-DD") ?? dayjs().format("YYYY-MM-DD"), - }); - }; - - - - return ( <div className="flex-1"> <div className="card card-border"> @@ -143,7 +129,7 @@ function PrivacyLogPage({ }) { <Label className="mr-2">조회기간</Label> <DateRangePicker value={dateRange} - onValueChange={handleDateRangeChange} + onValueChange={(value) => setDateRange(value || defaultDateRange)} > <div className="card card-border flex items-center gap-2"> <Select onValueChange={handlePresetDateRange}> @@ -161,21 +147,29 @@ function PrivacyLogPage({ }) { <Label className="ml-4 mr-2 text-label">조회자명</Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" - value={privacylogPostQuery.inqInfoKeyword} - onChange={(e) => - handleprivacylogParamsChange("inqInfoKeyword")(e.target.value) - } + value={inqInfoKeyword} + onChange={(e) => setInqInfoKeyword(e.target.value)} /> - + <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> <div className="card-header"> <div className="flex w-full items-center justify-between"> - <h3 className="text-2xl font-medium text-label">로그인로그 목록</h3> + <h3 className="text-2xl font-medium text-label"> + 개인정보 조회 로그 목록 + </h3> <div className="flex gap-2"> <Select value={table.getState().pagination.pageSize.toString()} @@ -196,7 +190,7 @@ function PrivacyLogPage({ }) { </Select> </div> </div> - </div> + </div> <div className="card !m-[1.2rem] !p-0">{tableComponent}</div> </div> </div> From 63abf8282b6ec6c13d53597291ea26cbd7168b47 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 10:10:18 +0900 Subject: [PATCH 066/159] =?UTF-8?q?[apps/cs]=20chore:=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=20=EC=8B=9C=20pageIndex=20=EC=B4=88=EA=B8=B0=ED=99=94=20(CS=5F?= =?UTF-8?q?UT01010101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/admin/ui/admin-page.tsx | 4 ++++ apps/cs/src/pages/apilog/ui/apilog-page.tsx | 4 ++++ apps/cs/src/pages/banner/ui/banner-page.tsx | 4 ++++ apps/cs/src/pages/bbs/ui/bbs-page.tsx | 4 ++++ apps/cs/src/pages/code/ui/lwpocode-section.tsx | 4 ++++ apps/cs/src/pages/code/ui/upcode-section.tsx | 4 ++++ apps/cs/src/pages/contents/ui/contents-page.tsx | 4 ++++ apps/cs/src/pages/file/ui/file-page.tsx | 4 ++++ apps/cs/src/pages/image/ui/image-page.tsx | 4 ++++ apps/cs/src/pages/loginlog/ui/loginlog-page.tsx | 4 ++++ apps/cs/src/pages/module/ui/module-page.tsx | 4 ++++ apps/cs/src/pages/popup/ui/popup-page.tsx | 4 ++++ apps/cs/src/pages/privacylog/ui/privacylog-page.tsx | 4 ++++ apps/cs/src/pages/recent/ui/recent-page.tsx | 4 ++++ apps/cs/src/pages/role/ui/role-page.tsx | 4 ++++ apps/cs/src/pages/survey/ui/survey-page.tsx | 4 ++++ apps/cs/src/pages/terms/ui/terms-page.tsx | 4 ++++ apps/cs/src/pages/users/ui/users-page.tsx | 4 ++++ 18 files changed, 72 insertions(+) diff --git a/apps/cs/src/pages/admin/ui/admin-page.tsx b/apps/cs/src/pages/admin/ui/admin-page.tsx index fb832b01d..95d2c4e91 100644 --- a/apps/cs/src/pages/admin/ui/admin-page.tsx +++ b/apps/cs/src/pages/admin/ui/admin-page.tsx @@ -127,6 +127,10 @@ function AdminPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keywordType, diff --git a/apps/cs/src/pages/apilog/ui/apilog-page.tsx b/apps/cs/src/pages/apilog/ui/apilog-page.tsx index 2785fbde8..cbcb3dc9a 100644 --- a/apps/cs/src/pages/apilog/ui/apilog-page.tsx +++ b/apps/cs/src/pages/apilog/ui/apilog-page.tsx @@ -77,6 +77,10 @@ function ApiLogPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, userId, diff --git a/apps/cs/src/pages/banner/ui/banner-page.tsx b/apps/cs/src/pages/banner/ui/banner-page.tsx index 88a47ba67..64ee2c0e4 100644 --- a/apps/cs/src/pages/banner/ui/banner-page.tsx +++ b/apps/cs/src/pages/banner/ui/banner-page.tsx @@ -50,6 +50,10 @@ function BannerPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, bnrTtl, diff --git a/apps/cs/src/pages/bbs/ui/bbs-page.tsx b/apps/cs/src/pages/bbs/ui/bbs-page.tsx index 187642a46..509f83cb7 100644 --- a/apps/cs/src/pages/bbs/ui/bbs-page.tsx +++ b/apps/cs/src/pages/bbs/ui/bbs-page.tsx @@ -53,6 +53,10 @@ function BbsPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, bbsTypeCd, diff --git a/apps/cs/src/pages/code/ui/lwpocode-section.tsx b/apps/cs/src/pages/code/ui/lwpocode-section.tsx index da37bfb18..c6025b338 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-section.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-section.tsx @@ -61,6 +61,10 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, lwpoCdNm, diff --git a/apps/cs/src/pages/code/ui/upcode-section.tsx b/apps/cs/src/pages/code/ui/upcode-section.tsx index b7202178c..a9e5f6de8 100644 --- a/apps/cs/src/pages/code/ui/upcode-section.tsx +++ b/apps/cs/src/pages/code/ui/upcode-section.tsx @@ -42,6 +42,10 @@ function UpCodeSection({ handleSelectedUpCd }: UpCodeSectionProps) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keyword, diff --git a/apps/cs/src/pages/contents/ui/contents-page.tsx b/apps/cs/src/pages/contents/ui/contents-page.tsx index c2e2704d1..65c015c99 100644 --- a/apps/cs/src/pages/contents/ui/contents-page.tsx +++ b/apps/cs/src/pages/contents/ui/contents-page.tsx @@ -40,6 +40,10 @@ function ContentsPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, contsTtl, diff --git a/apps/cs/src/pages/file/ui/file-page.tsx b/apps/cs/src/pages/file/ui/file-page.tsx index d717461aa..8243d47d1 100644 --- a/apps/cs/src/pages/file/ui/file-page.tsx +++ b/apps/cs/src/pages/file/ui/file-page.tsx @@ -68,6 +68,10 @@ function FilePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, orgnlFileNm, diff --git a/apps/cs/src/pages/image/ui/image-page.tsx b/apps/cs/src/pages/image/ui/image-page.tsx index 4b1bcd5cd..727ce043b 100644 --- a/apps/cs/src/pages/image/ui/image-page.tsx +++ b/apps/cs/src/pages/image/ui/image-page.tsx @@ -48,6 +48,10 @@ function ImagePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keyword, diff --git a/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx b/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx index 661ca0114..cbfb53a07 100644 --- a/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx +++ b/apps/cs/src/pages/loginlog/ui/loginlog-page.tsx @@ -81,6 +81,10 @@ function LoginlogPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); setIsManualLoading(true); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, userId, diff --git a/apps/cs/src/pages/module/ui/module-page.tsx b/apps/cs/src/pages/module/ui/module-page.tsx index 127aa66de..8593ba4b5 100644 --- a/apps/cs/src/pages/module/ui/module-page.tsx +++ b/apps/cs/src/pages/module/ui/module-page.tsx @@ -64,6 +64,10 @@ function ModulePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, authorizationName, diff --git a/apps/cs/src/pages/popup/ui/popup-page.tsx b/apps/cs/src/pages/popup/ui/popup-page.tsx index a8046c57e..e55e5652b 100644 --- a/apps/cs/src/pages/popup/ui/popup-page.tsx +++ b/apps/cs/src/pages/popup/ui/popup-page.tsx @@ -50,6 +50,10 @@ function PopupPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keyword, diff --git a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx index 3637b80d4..786a5994e 100644 --- a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx +++ b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx @@ -76,6 +76,10 @@ function PrivacyLogPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, inqInfoKeyword, diff --git a/apps/cs/src/pages/recent/ui/recent-page.tsx b/apps/cs/src/pages/recent/ui/recent-page.tsx index 4e33eab89..8f188eced 100644 --- a/apps/cs/src/pages/recent/ui/recent-page.tsx +++ b/apps/cs/src/pages/recent/ui/recent-page.tsx @@ -131,6 +131,10 @@ function RecentPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); setIsDeletePostData(delYn === "Y"); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keywordType, diff --git a/apps/cs/src/pages/role/ui/role-page.tsx b/apps/cs/src/pages/role/ui/role-page.tsx index 7e20b3715..7d5453895 100644 --- a/apps/cs/src/pages/role/ui/role-page.tsx +++ b/apps/cs/src/pages/role/ui/role-page.tsx @@ -56,6 +56,10 @@ function RolePage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keyword, diff --git a/apps/cs/src/pages/survey/ui/survey-page.tsx b/apps/cs/src/pages/survey/ui/survey-page.tsx index ff64014ce..a2965d35b 100644 --- a/apps/cs/src/pages/survey/ui/survey-page.tsx +++ b/apps/cs/src/pages/survey/ui/survey-page.tsx @@ -73,6 +73,10 @@ function SurveyPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, srvyTtl, diff --git a/apps/cs/src/pages/terms/ui/terms-page.tsx b/apps/cs/src/pages/terms/ui/terms-page.tsx index 31feb29f4..fb38751c9 100644 --- a/apps/cs/src/pages/terms/ui/terms-page.tsx +++ b/apps/cs/src/pages/terms/ui/terms-page.tsx @@ -40,6 +40,10 @@ function TermsPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keyword, diff --git a/apps/cs/src/pages/users/ui/users-page.tsx b/apps/cs/src/pages/users/ui/users-page.tsx index c5e71cefd..cee94f2b3 100644 --- a/apps/cs/src/pages/users/ui/users-page.tsx +++ b/apps/cs/src/pages/users/ui/users-page.tsx @@ -103,6 +103,10 @@ function UsersPage() { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); setSearchParams({ ...searchParams, keywordType, From b1822b24ee6429aeaf6bf69c4326e0ce8f1e796e Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 10:41:22 +0900 Subject: [PATCH 067/159] =?UTF-8?q?[apps/cs]=20feat:=20=EC=9D=BC=EC=A0=95?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20(CS=5FUT02030105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/schedule/api/schedule-service.ts | 4 ++++ .../pages/schedule/model/schedule-interface.ts | 1 + apps/cs/src/pages/schedule/ui/modify-page.tsx | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/cs/src/pages/schedule/api/schedule-service.ts b/apps/cs/src/pages/schedule/api/schedule-service.ts index b333b43f4..c7e2c8806 100644 --- a/apps/cs/src/pages/schedule/api/schedule-service.ts +++ b/apps/cs/src/pages/schedule/api/schedule-service.ts @@ -34,6 +34,10 @@ class ScheduleApiService implements ScheduleService { ): Promise<void> { await client.put(`${ENDPOINT.CMS_SERVICE.SCHEDULES}/${schdlSn}`, data); } + + public async deleteSchedule(schdlSn: number): Promise<void> { + await client.delete(`${ENDPOINT.CMS_SERVICE.SCHEDULES}/${schdlSn}`); + } } export const ScheduleApi = new ScheduleApiService(); diff --git a/apps/cs/src/pages/schedule/model/schedule-interface.ts b/apps/cs/src/pages/schedule/model/schedule-interface.ts index 98b6a703a..d9e942424 100644 --- a/apps/cs/src/pages/schedule/model/schedule-interface.ts +++ b/apps/cs/src/pages/schedule/model/schedule-interface.ts @@ -71,4 +71,5 @@ export interface ScheduleService { getScheduleInfo(schdlSn: number): Promise<Schedule>; createSchedule(data: ScheduleFormData): Promise<void>; updateSchedule(schdlSn: number, data: ScheduleUpdateFormData): Promise<void>; + deleteSchedule(schdlSn: number): Promise<void>; } diff --git a/apps/cs/src/pages/schedule/ui/modify-page.tsx b/apps/cs/src/pages/schedule/ui/modify-page.tsx index e8f55534b..8b0a07a86 100644 --- a/apps/cs/src/pages/schedule/ui/modify-page.tsx +++ b/apps/cs/src/pages/schedule/ui/modify-page.tsx @@ -35,6 +35,16 @@ function ModifyPage({ schdlSn }: { schdlSn: string }) { }, }); + const { mutateAsync: deleteSchedule } = useMutationWrapper({ + mutationFn: () => ScheduleApi.deleteSchedule(parseInt(schdlSn)), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [ENDPOINT.CMS_SERVICE.SCHEDULES], + }); + alert("일정이 삭제되었습니다.", router.back); + }, + }); + const form = useForm<ScheduleUpdateFormData>({ resolver: zodResolver(scheduleUpdateFormSchema), values: { @@ -57,7 +67,12 @@ function ModifyPage({ schdlSn }: { schdlSn: string }) { <div className="card-header"> <h3 className="text-2xl font-medium text-label">스케줄 수정</h3> </div> - <ScheduleForm form={form} handleSave={handleSave} /> + <ScheduleForm + form={form} + scheduleId={schdlSn} + handleSave={handleSave} + handleDelete={deleteSchedule} + /> </div> ); } From cc21f5a044991e830549da8141c72acd1f5303f2 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 11:26:15 +0900 Subject: [PATCH 068/159] =?UTF-8?q?[common/features]=20feat:=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20(CS=5FUT01010101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/widgets/post/ui/post-page.tsx | 61 ++++++++++++++----- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/apps/common/features/src/widgets/post/ui/post-page.tsx b/apps/common/features/src/widgets/post/ui/post-page.tsx index 509087b68..7aaa390fc 100644 --- a/apps/common/features/src/widgets/post/ui/post-page.tsx +++ b/apps/common/features/src/widgets/post/ui/post-page.tsx @@ -44,7 +44,9 @@ function PostPage({ bbsId }: { bbsId: string }) { const thumbRefs = useRef<Map<number, string>>(new Map()); const [tableSort, setTableSort] = useState(""); - const [postParams, setPostParams] = useState<PostParams>({ + const [keywordType, setKeywordType] = useState("title"); + const [keyword, setKeyword] = useState(""); + const [searchParams, setSearchParams] = useState<PostParams>({ keywordType: "title", keyword: "", }); @@ -58,7 +60,7 @@ function PostPage({ bbsId }: { bbsId: string }) { queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, bbsInfo], queryFn: () => PostApi.getPostList(parseInt(bbsId), { - ...postParams, + ...searchParams, upndFixYn: bbsInfo?.upndFixUseYn, }), select: (data) => { @@ -79,10 +81,16 @@ function PostPage({ bbsId }: { bbsId: string }) { isLoading, refetch, } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pagination, tableSort], + queryKey: [ + ENDPOINT.BOARD_SERVICE.POSTS_USER, + bbsId, + searchParams, + pagination, + tableSort, + ], queryFn: () => PostApi.getPostList(parseInt(bbsId), { - ...postParams, + ...searchParams, ansUseYn: bbsInfo?.ansUseYn, page: pagination.pageIndex, size: pagination.pageSize, @@ -128,7 +136,29 @@ function PostPage({ bbsId }: { bbsId: string }) { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); - refetch(); + setPagination({ + ...pagination, + pageIndex: 0, + }); + setSearchParams({ + ...searchParams, + keywordType, + keyword, + }); + }; + + const handleReset = () => { + setKeywordType("title"); + setKeyword(""); + setPagination({ + ...pagination, + pageIndex: 0, + }); + setSearchParams({ + ...searchParams, + keywordType: "title", + keyword: "", + }); }; const handleRowClick = (row: Post) => { @@ -141,12 +171,7 @@ function PostPage({ bbsId }: { bbsId: string }) { <div className="card card-border"> <form onSubmit={handleSubmit} className="flex items-center gap-2 p-2"> <Label className="mr-2 text-label">검색</Label> - <Select - value={postParams.keywordType} - onValueChange={(keywordType) => { - setPostParams({ ...postParams, keywordType }); - }} - > + <Select value={keywordType} onValueChange={setKeywordType}> <SelectTrigger className="h-[3.2rem] w-[10rem]"> <SelectValue placeholder="선택" /> </SelectTrigger> @@ -157,15 +182,21 @@ function PostPage({ bbsId }: { bbsId: string }) { </SelectContent> </Select> <Input - value={postParams.keyword} - onChange={(e) => - setPostParams({ ...postParams, keyword: e.target.value }) - } + value={keyword} + onChange={(e) => setKeyword(e.target.value)} className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]" /> <Button className="h-[3.2rem]" type="submit"> 조회 </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> </form> </div> <div className="card card-border"> From ea0790d1c7dfb01b0f26a8383c50dbaee013a012 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 11:27:12 +0900 Subject: [PATCH 069/159] =?UTF-8?q?[apps/cs]=20feat:=20=ED=8C=9D=EC=97=85?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20(CS=5FUT02040105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/popup/api/popup-service.ts | 4 ++++ apps/cs/src/pages/popup/model/popup-interface.ts | 1 + apps/cs/src/pages/popup/ui/modify-page.tsx | 14 +++++++++++++- apps/cs/src/pages/popup/ui/popup-form.tsx | 2 +- .../src/widgets/post/ui/general-file-uploader.tsx | 2 +- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/apps/cs/src/pages/popup/api/popup-service.ts b/apps/cs/src/pages/popup/api/popup-service.ts index b82d5f473..cff4cb55e 100644 --- a/apps/cs/src/pages/popup/api/popup-service.ts +++ b/apps/cs/src/pages/popup/api/popup-service.ts @@ -41,6 +41,10 @@ export class PopupApiService implements PopupService { validatedData, ); } + + public async deletePopup(popupSn: number): Promise<void> { + await client.delete(`${ENDPOINT.CMS_SERVICE.POPUPS}/${popupSn}`); + } } export const PopupApi = new PopupApiService(); diff --git a/apps/cs/src/pages/popup/model/popup-interface.ts b/apps/cs/src/pages/popup/model/popup-interface.ts index 6952d873f..c565df8ca 100644 --- a/apps/cs/src/pages/popup/model/popup-interface.ts +++ b/apps/cs/src/pages/popup/model/popup-interface.ts @@ -68,4 +68,5 @@ export interface PopupService { getPopupInfo(popupSn: number): Promise<PopupInfo>; createPopup(data: PopupFormData): Promise<void>; updatePopup(popupSn: number, data: PopupUpdateFormData): Promise<void>; + deletePopup(popupSn: number): Promise<void>; } diff --git a/apps/cs/src/pages/popup/ui/modify-page.tsx b/apps/cs/src/pages/popup/ui/modify-page.tsx index fed70cbbb..cffce11bd 100644 --- a/apps/cs/src/pages/popup/ui/modify-page.tsx +++ b/apps/cs/src/pages/popup/ui/modify-page.tsx @@ -52,6 +52,13 @@ function ModifyPage({ popupSn }: { popupSn: number }) { }, }); + const { mutateAsync: deletePopup } = useMutationWrapper({ + mutationFn: () => PopupApi.deletePopup(popupSn), + onSuccess: () => { + alert("삭제되었습니다.", router.back); + }, + }); + const { mutateAsync: savePostingHistory } = useMutationWrapper({ mutationFn: (data: PostPayload[]) => PostingApi.savePosting(data), onSuccess: () => { @@ -101,7 +108,12 @@ function ModifyPage({ popupSn }: { popupSn: number }) { <div className="card-header"> <h3 className="text-2xl font-medium text-label">팝업 수정</h3> </div> - <PopupForm form={form} handleSave={updatePopup} /> + <PopupForm + form={form} + popupSn={popupSn} + handleSave={updatePopup} + handleDelete={deletePopup} + /> </div> <div className="card card-border"> <div className="card-header"> diff --git a/apps/cs/src/pages/popup/ui/popup-form.tsx b/apps/cs/src/pages/popup/ui/popup-form.tsx index 8e1e5783f..3147542ed 100644 --- a/apps/cs/src/pages/popup/ui/popup-form.tsx +++ b/apps/cs/src/pages/popup/ui/popup-form.tsx @@ -32,7 +32,7 @@ const Editor = dynamic( type PopupFormProps<T extends PopupFormData | PopupUpdateFormData> = { form: UseFormReturn<T>; - popupSn?: string; + popupSn?: number; handleSave: (data: T) => Promise<void>; handleDelete?: () => Promise<void>; }; diff --git a/apps/cs/src/widgets/post/ui/general-file-uploader.tsx b/apps/cs/src/widgets/post/ui/general-file-uploader.tsx index 2012201da..cbd77ca18 100644 --- a/apps/cs/src/widgets/post/ui/general-file-uploader.tsx +++ b/apps/cs/src/widgets/post/ui/general-file-uploader.tsx @@ -102,7 +102,7 @@ function GeneralFileUploader<T extends { atflCd?: string | null }>({ <span>{attachment.orgnlFileNm}</span> <Button color="lightGray" - className="flex size-7 items-center justify-center rounded-full p-0" + className="flex size-7 shrink-0 items-center justify-center rounded-full p-0" onClick={() => setDeleteAttachmentIds([...deleteAttachmentIds, atflId]) } From 2fa18b18794fa044e4475fd07d6343d519f8c99b Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 11:33:00 +0900 Subject: [PATCH 070/159] =?UTF-8?q?[apps/cs]=20feat:=20=EC=84=A4=EB=AC=B8?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20(CS=5FUT02050106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/survey/api/survey-service.ts | 4 ++++ apps/cs/src/pages/survey/ui/detail-page.tsx | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/cs/src/pages/survey/api/survey-service.ts b/apps/cs/src/pages/survey/api/survey-service.ts index 6db4ea52d..66b57561c 100644 --- a/apps/cs/src/pages/survey/api/survey-service.ts +++ b/apps/cs/src/pages/survey/api/survey-service.ts @@ -45,6 +45,10 @@ export class SurveyApiService implements SurveyService { await client.put(`${ENDPOINT.CMS_SERVICE.SURVEY}/${srvySn}`, data); } + public async deleteSurvey(srvySn: number): Promise<void> { + await client.delete(`${ENDPOINT.CMS_SERVICE.SURVEY}/${srvySn}`); + } + public async getQuestionList(params: QuestionParams): Promise<QuestionList> { const response = await client.get<QuestionList>( `${ENDPOINT.CMS_SERVICE.SURVEY_QUESTION}`, diff --git a/apps/cs/src/pages/survey/ui/detail-page.tsx b/apps/cs/src/pages/survey/ui/detail-page.tsx index de1abc783..59bf28425 100644 --- a/apps/cs/src/pages/survey/ui/detail-page.tsx +++ b/apps/cs/src/pages/survey/ui/detail-page.tsx @@ -29,6 +29,13 @@ function DetailPage({ srvySn }: { srvySn: string }) { queryFn: () => SurveyApi.getSurveyInfo(parseInt(srvySn)), }); + const { mutateAsync: deleteSurvey } = useMutationWrapper({ + mutationFn: () => SurveyApi.deleteSurvey(parseInt(srvySn)), + onSuccess: () => { + alert("삭제되었습니다.", router.back); + }, + }); + const postHistoryQuery = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.POSTINGS, srvySn], queryFn: () => @@ -77,6 +84,12 @@ function DetailPage({ srvySn }: { srvySn: string }) { }, }); + const handleDeleteSurvey = async () => { + if (await confirm("삭제하시겠습니까?")) { + deleteSurvey(); + } + }; + const handleDeletePostingHistory = async () => { const data = postingTable.getFilteredSelectedRowModel().rows.map((row) => ({ ...row.original, @@ -101,7 +114,9 @@ function DetailPage({ srvySn }: { srvySn: string }) { <Button onClick={() => router.push(`${pathname}/modify`)}> 수정 </Button> - <Button color="red">삭제</Button> + <Button color="red" onClick={handleDeleteSurvey}> + 삭제 + </Button> </div> </div> <ul className="flex flex-col"> From 46e5ef701dec472ac43a257aa6ac1f258a748ffa Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Thu, 10 Jul 2025 11:33:46 +0900 Subject: [PATCH 071/159] =?UTF-8?q?=EC=9E=AC=EC=9D=B4=EC=9A=A9=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EC=A1=B0=ED=9A=8C=20=EB=B2=84=ED=8A=BC=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=EC=97=90=EB=A7=8C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EB=90=98=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/stats/rainStat/page.tsx | 4 ++-- apps/wr/app/stats/rswtStat/page.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/stats/rainStat/page.tsx b/apps/wr/app/stats/rainStat/page.tsx index 45d32d3a4..591ea5fdf 100644 --- a/apps/wr/app/stats/rainStat/page.tsx +++ b/apps/wr/app/stats/rainStat/page.tsx @@ -29,7 +29,7 @@ export default function RainStat() { useEffect(() => { searchRainStatList(searchYear); - }, [code.cityCd, code.sggCd, searchRainStatList, searchYear]) + }, [code.cityCd, code.sggCd, searchRainStatList]) const excelDetailDownLoad=() =>{ const sidoList = new Set<string>(); @@ -237,7 +237,7 @@ export default function RainStat() { /> </div> <div className="flex flex-row space-x-2 items-center"> - <Button className="" size={"sm"} onClick={() => { }}> + <Button className="" size={"sm"} onClick={()=>{searchRainStatList(searchYear);}}> 조회 </Button> <Button className="" size={"sm"} onClick={() => excelClick()}> diff --git a/apps/wr/app/stats/rswtStat/page.tsx b/apps/wr/app/stats/rswtStat/page.tsx index 39d5bc00a..c200d0319 100644 --- a/apps/wr/app/stats/rswtStat/page.tsx +++ b/apps/wr/app/stats/rswtStat/page.tsx @@ -26,7 +26,7 @@ export default function RswtStat() { useEffect(() => { searchRswtStatList(searchYear) - }, [searchRswtStatList, searchYear]) + }, [searchRswtStatList]) const excelClick = () => { downloadExcel({ From 4358c0d41ece99ac00f50908954f7cdcc84a6062 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 12:35:03 +0900 Subject: [PATCH 072/159] =?UTF-8?q?[apps/cs]=20style:=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=ED=97=A4=EB=8D=94=20z-index=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/common/components/src/ui/table/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/common/components/src/ui/table/index.tsx b/packages/common/components/src/ui/table/index.tsx index 8ced24202..3d4e2251d 100644 --- a/packages/common/components/src/ui/table/index.tsx +++ b/packages/common/components/src/ui/table/index.tsx @@ -29,7 +29,11 @@ const TableHeader = React.forwardRef< HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement> >(({ className, ...props }, ref) => ( - <thead ref={ref} className={cn("sticky top-0 bg-secondary [&_tr]:border-b", className)} {...props} /> + <thead + ref={ref} + className={cn("sticky top-0 z-10 bg-secondary [&_tr]:border-b", className)} + {...props} + /> )); TableHeader.displayName = "TableHeader"; From 93025914fa5c413733cf3f75af9c17ba982ee001 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 13:20:46 +0900 Subject: [PATCH 073/159] =?UTF-8?q?[groups]=20=20=EA=B7=B8=EB=A3=B9?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=97=90=EC=84=9C=20=EC=B6=94=EA=B0=80=20/?= =?UTF-8?q?=EC=88=98=EC=A0=95=20/=EC=82=AD=EC=A0=9C=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=ED=9B=84=20=EC=9E=AC=EB=A1=9C=EB=94=A9=EB=93=B1=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entities/group/model/group-interface.ts | 5 ++- .../groups/model/groups-table-columns.tsx | 36 ++++++++++++------- apps/cs/src/pages/groups/ui/groups-dialog.tsx | 2 +- .../cs/src/pages/groups/ui/groups-section.tsx | 26 ++++++++++++-- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/apps/cs/src/entities/group/model/group-interface.ts b/apps/cs/src/entities/group/model/group-interface.ts index f8cc9883f..58e9a4489 100644 --- a/apps/cs/src/entities/group/model/group-interface.ts +++ b/apps/cs/src/entities/group/model/group-interface.ts @@ -56,7 +56,10 @@ export const groupFormSchema = z.object({ groupNm: z.string().min(1, { message: "그룹명을 입력해주세요." }), groupSeCd: z.string().min(1, { message: "그룹구분을 선택해주세요." }), groupExpln: z.string().optional(), - delYn: z.string().default("N"), + delYn: z + .string() + .transform((val) => (val === "" || val === undefined ? "N" : val)) + .default("N"), authrtId: z.string().min(1, { message: "권한ID를 선택해주세요." }), siteId: z.string().optional(), mngrYn: z.string().default("N"), diff --git a/apps/cs/src/pages/groups/model/groups-table-columns.tsx b/apps/cs/src/pages/groups/model/groups-table-columns.tsx index 70f91efa0..0f417a304 100644 --- a/apps/cs/src/pages/groups/model/groups-table-columns.tsx +++ b/apps/cs/src/pages/groups/model/groups-table-columns.tsx @@ -20,18 +20,30 @@ export const columns: ColumnDef<GroupListResponseDto>[] = [ { id: "actions", header: "관리", - cell: ({ row }) => ( - <div - onClick={(e) => e.stopPropagation()} - className="flex justify-center gap-2" - > - <MenuAuthorityDialog groupId={row.original.groupId} /> - <GroupsDialog groupId={row.original.groupId}> - <Button size="sm" color="white"> - 수정 + cell: ({ row, table }) => { + const onDelete = table.options.meta?.onDelete as (groupId: string) => void; + + const handleDelete = (e: React.MouseEvent) => { + e.stopPropagation(); + if (onDelete) onDelete(row.original.groupId); + }; + + return ( + <div + onClick={(e) => e.stopPropagation()} + className="flex justify-center gap-2" + > + <MenuAuthorityDialog groupId={row.original.groupId} /> + <GroupsDialog groupId={row.original.groupId}> + <Button size="sm" color="white"> + 수정 + </Button> + </GroupsDialog> + <Button size="sm" color="red" onClick={handleDelete}> + 삭제 </Button> - </GroupsDialog> - </div> - ), + </div> + ); + }, }, ]; diff --git a/apps/cs/src/pages/groups/ui/groups-dialog.tsx b/apps/cs/src/pages/groups/ui/groups-dialog.tsx index d21852886..427ba4b1b 100644 --- a/apps/cs/src/pages/groups/ui/groups-dialog.tsx +++ b/apps/cs/src/pages/groups/ui/groups-dialog.tsx @@ -43,7 +43,7 @@ const GroupsDialog = memo( const { data: group } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.GROUPS, groupId], queryFn: () => GroupApi.findGroupById(groupId!), - enabled: !!groupId, + enabled: !!groupId && open, // open 시점 groupId가 있을 때만 상세 조회 API 호출 }); const { mutateAsync: createGroup } = useMutationWrapper({ diff --git a/apps/cs/src/pages/groups/ui/groups-section.tsx b/apps/cs/src/pages/groups/ui/groups-section.tsx index f5d1e026b..2130a94c0 100644 --- a/apps/cs/src/pages/groups/ui/groups-section.tsx +++ b/apps/cs/src/pages/groups/ui/groups-section.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { keepPreviousData, useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery, useQueryClient } from "@tanstack/react-query"; import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; import { Button } from "@common/components"; import { GroupApi } from "@/entities/group"; @@ -9,6 +9,8 @@ import { ENDPOINT } from "@/shared/config"; import { useDataTable } from "@/shared/lib"; import { columns } from "../model/groups-table-columns"; import { GroupsDialog } from "./groups-dialog"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { useAlertStore, useMutationWrapper } from "@/shared/lib"; type GroupsSectionProps = { handleSelectedGroup: (groupId: string) => void; @@ -28,11 +30,28 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { size: pagination.pageSize, }), placeholderData: keepPreviousData, + }); + const { confirm } = useConfirm(); + const alert = useAlertStore((state) => state.setMessage); + const queryClient = useQueryClient(); + const { mutateAsync: deleteGroup } = useMutationWrapper({ + mutationFn: (groupId: string) => GroupApi.deleteGroup(groupId), + onSuccess: () => { + alert("삭제되었습니다."); + queryClient.invalidateQueries({ + predicate: (query) => query.queryKey[0] === ENDPOINT.CMS_SERVICE.GROUPS, + }); + }, }); + const handleDelete = async (groupId: string) => { + if (await confirm("삭제하시겠습니까?")) { + await deleteGroup(groupId); + } + }; const handleRowClick = (row: { groupId: string }) => { table.setRowSelection({ [row.groupId]: true }); - handleSelectedGroup(row.groupId); + handleSelectedGroup(row.groupId); // 1. 리스트에서 선택된 groupId 저장 }; const { tableComponent, tableInstance: table } = useDataTable({ @@ -45,6 +64,9 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { getCoreRowModel: getCoreRowModel(), onPaginationChange: setPagination, getRowId: (row) => row.groupId, + meta: { + onDelete: handleDelete, + }, }, dataTableOptions: { onRowClick: handleRowClick, From a46fbf5a5d38e716cb856b4fb8b5ef74b580bf70 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Thu, 10 Jul 2025 13:36:25 +0900 Subject: [PATCH 074/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC,=20=EC=A4=91?= =?UTF-8?q?=EC=88=98=EB=8F=84=20=EA=B1=B4=EC=B6=95=EB=AC=BC=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EB=B0=8F=20form=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/rswtReg/page.tsx | 16 +- .../ui/form/fcltReg/bdstReg/bdstAdd.tsx | 143 ++++++++++++++++++ .../ui/form/fcltReg/bdstReg/bdstReg.tsx | 114 +------------- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 5 +- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 10 +- 5 files changed, 162 insertions(+), 126 deletions(-) create mode 100644 apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx index b2ff99104..568145707 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx @@ -45,7 +45,7 @@ export default function Home() { useEffect(() => { if (code.sggCd.length > 0) { - if( rswtRes?.length > 0){ + if (rswtRes?.length > 0) { const rswtData = tableData(rswtRes, { code })?.map( (item: customRswtBdst) => { let archArea = @@ -62,12 +62,20 @@ export default function Home() { ); setbdstTable(rswtData); setRswtForm(rswtRes[selectVal ?? 0]); - }else{ + } else { setbdstTable([]); setRswtForm({} as customRswtBdst); } } - }, [code, rswtRes, selectVal]); + // }, [code, rswtRes, selectVal]); + + }, [code, rswtRes]); + useEffect(() => { + if (rswtRes && rswtRes.length > 0) { + setRswtForm(rswtRes[selectVal ?? 0]); + } + }, [rswtRes, selectVal]); + const cellClick: (val: number | undefined, headId: string) => void = ( val, headId @@ -75,7 +83,7 @@ export default function Home() { if ((bdstTable ?? []).length > 0 && val !== undefined) { { setSelect(val); - setRswtForm(rswtRes[val]); + // setRswtForm(rswtRes[val]); } } diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx new file mode 100644 index 000000000..f7b24e628 --- /dev/null +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx @@ -0,0 +1,143 @@ +"use client"; + +import { useWrStore } from "@/app/store"; +import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { formH1Class } from "@/components/lib/class/comClass"; +import { safeDate } from "@/components/lib/func/commom"; +import { DatePicker, FormField, FormUi, SelectBox } from "@common/business_components"; +import { Button, Checkbox, Input } from "@common/components"; +import { useEffect, useState } from "react"; +import { useFieldArray } from "react-hook-form"; + +export default function BdstAdd({ form, readonly }: { form: any; readonly?: boolean; }) { + + const { code } = useWrStore((state) => { + return state; + }); + + const { fields, append, remove } = useFieldArray({ + name: "chgBuilding", + control: form?.control, // Provide a fallback to avoid errors + }); + + const plusHist = () => { + append({ + bdstNm: "", + daddr: "", + bdstUsgCd: "", + }); + }; + const [selectedIds, setSelectedIds] = useState<string[]>([]); + + const toggleSelect = (id: string) => { + setSelectedIds((prev) => + prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id] + ); + }; + + const removeSelected = () => { + const idxsToRemove = fields + .map((item, idx) => (selectedIds.includes(item.id) ? idx : -1)) + .filter((index) => index > -1) + .sort((prevIndex, nextIndex) => nextIndex - prevIndex); + + remove(idxsToRemove); + setSelectedIds([]); + }; + + return ( + <> + <h1 className={formH1Class}>중축, 개축, 재축</h1> + {!readonly && ( + <div className="flex justify-end gap-2 mt-4"> + + <Button type="button" className="" size={"sm"} onClick={plusHist}> + 이력추가 + </Button> + <Button + type="button" + className="!bg-red-500 text-white" + size={"sm"} + onClick={removeSelected} + > + 삭제 + </Button> + + </div> + )} + {fields.map((field, index) => ( + <div + key={field.id} + // className="grid grid-cols-[auto,1fr,1fr,1fr] gap-2 mt-4 items-center" + className={`grid ${ + readonly ? "grid-cols-3" : "grid-cols-[auto,1fr,1fr,1fr]" + } gap-2 mt-4 items-center`} + > + {!readonly && ( + <div className="col-span-1 flex justify-center mr-4"> + <Checkbox + checked={selectedIds.includes(field.id)} + onCheckedChange={() => toggleSelect(field.id)} + /> + </div> + )} + <div className=""> + <FormField + control={form.control} + name={`chgBuilding.${index}.bdstChgNm`} + render={({ field: f }) => ( + <FormUi label="구분"> + <SelectBox + selectClass={selectClass} + selectArray={code.chBuCd} + onSelectValue={(val) => f.onChange(val)} + value={f.value ?? code.chBuCd[0]?.val} + className={""} + label={""} + /> + </FormUi> + )} + /> + </div> + + <div className=""> + <FormField + control={form.control} + name={`chgBuilding.${index}.archChgPrmsnDt`} + render={({ field: f }) => ( + <FormUi label="허가일"> + <DatePicker + mode="single" + field={{ + value: safeDate(f.value) || new Date(), + onChange: (date) => f.onChange(date), + }} + selectClass="w-full" + /> + </FormUi> + )} + /> + </div> + <div className=""> + <FormField + control={form.control} + name={`chgBuilding.${index}.archChgArea`} + render={({ field: f }) => ( + <FormUi label="면적"> + <Input + placeholder="-" + type="text" + onChange={(e) => f.onChange(e.target.value)} + value={f.value || ''} + className={selectClass} + /> + </FormUi> + )} + /> + </div> + </div> + ))} + <div className="border-b border-gray-300 my-4"> </div> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index 188b1380a..c14bd7d48 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -28,28 +28,6 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { const [useCityCd, setUserCityCd] = useState<SelectDataType[]>([]) const [useSggCd, setUserSggCd] = useState<SelectDataType[]>([]) - const { fields, append, remove } = useFieldArray({ - name: "chgBuilding", - control: form?.control, // Provide a fallback to avoid errors - }); - - const plusHist = () => { - append({ - bdstNm: "", - daddr: "", - bdstUsgCd: "", - }); - }; - const removeSelected = () => { - const idxsToRemove = fields - .map((item, idx) => (selectedIds.includes(item.id) ? idx : -1)) - .filter((index) => index > -1) - .sort((prevIndex, nextIndex) => nextIndex - prevIndex); - - remove(idxsToRemove); - setSelectedIds([]); - }; - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | undefined>(); const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", @@ -80,9 +58,6 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { } },[form, userSiSggCd, code.cityCd, code.sggCd]) - - - const getSelCity = (val: string) => { const data = getCity(val, code.sggCd); setSelectSgg(data); @@ -110,13 +85,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { return () => subscription?.unsubscribe(); }, [form.form]); - const [selectedIds, setSelectedIds] = useState<string[]>([]); - const toggleSelect = (id: string) => { - setSelectedIds((prev) => - prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id] - ); - }; useEffect(() =>{ @@ -296,88 +265,7 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { /> </div> </div> - <h1 className={formH1Class}>중축, 개축, 재축</h1> - <div className="flex justify-end gap-2 mt-4"> - <Button type="button" className="" size={"sm"} onClick={plusHist}> - 이력추가 - </Button> - <Button - type="button" - className="!bg-red-500 text-white" - size={"sm"} - onClick={removeSelected} - > - 삭제 - </Button> - </div> - {fields.map((field, index) => ( - <div - key={field.id} - className="grid grid-cols-[auto,1fr,1fr,1fr] gap-2 mt-4 items-center" - > - <div className="col-span-1 flex justify-center mr-4"> - <Checkbox - checked={selectedIds.includes(field.id)} - onCheckedChange={() => toggleSelect(field.id)} - /> - </div> - <div className=""> - <FormField - control={form.control} - name={`chgBuilding.${index}.bdstChgNm`} - render={({ field: f }) => ( - <FormUi label="구분"> - <SelectBox - selectClass={selectClass} - selectArray={code.chBuCd} - onSelectValue={(val) => f.onChange(val)} - value={f.value ?? code.chBuCd[0]?.val} - className={""} - label={""} - /> - </FormUi> - )} - /> - </div> - <div className=""> - <FormField - control={form.control} - name={`chgBuilding.${index}.archChgPrmsnDt`} - render={({ field: f }) => ( - <FormUi label="허가일"> - <DatePicker - mode="single" - field={{ - value: safeDate(f.value) || new Date(), - onChange: (date) => f.onChange(date), - }} - selectClass="w-full" - /> - </FormUi> - )} - /> - </div> - <div className=""> - <FormField - control={form.control} - name={`chgBuilding.${index}.archChgArea`} - render={({ field: f }) => ( - <FormUi label="면적"> - <Input - placeholder="-" - type="text" - onChange={(e) => f.onChange} - value={f.value||''} - className={selectClass} - /> - </FormUi> - )} - /> - </div> - </div> - ))} - <div className="border-b border-gray-300 my-4"> </div> - </> + </> ) : ( <></> )} diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index be436be82..bb62fee61 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -20,6 +20,7 @@ import { useForm } from "react-hook-form"; import { z } from "zod"; import BdstReg from "../bdstReg/bdstReg"; import toast from "react-hot-toast"; +import BdstAdd from "../bdstReg/bdstAdd"; export default function RainRegForm({ rainForm, @@ -92,9 +93,6 @@ export default function RainRegForm({ })), }; }; - useEffect(()=>{ - console.log("이즈모달", isModal) - }, []) useEffect(() => { if (grntchBdstCertYn === "N") { @@ -601,6 +599,7 @@ export default function RainRegForm({ /> </div> </div> + <BdstAdd form={form} readonly={readonly}></BdstAdd> </ScrollArea> </form> </Form> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index 33a847565..a3d849b29 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -9,8 +9,7 @@ import { import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; import { formatCommaNumber, - handleCommaNumberChange, - handleMinusNumberChange, + handleMinusNumberChange } from "@/components/lib/func/commom"; import { DatePicker, @@ -22,8 +21,9 @@ import { import { Button, Input, ScrollArea } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; -import { useForm, type UseFormReturn } from "react-hook-form"; +import { useForm } from "react-hook-form"; import { z } from "zod"; +import BdstAdd from "../bdstReg/bdstAdd"; import BdstReg from "../bdstReg/bdstReg"; export default function RswtrRegForm({ @@ -459,9 +459,6 @@ export default function RswtrRegForm({ } }} disabled={grntchBdstCertYn == "N" || grntchBdstCertYn == "D"} - - - /> </FormUi> ) @@ -488,6 +485,7 @@ export default function RswtrRegForm({ /> </div> </div> + <BdstAdd form={form} readonly={readonly}></BdstAdd> </ScrollArea> </form> </Form> From 225ebc0983a7d5e1612f989b007a1847a897220d Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 14:39:24 +0900 Subject: [PATCH 075/159] =?UTF-8?q?[apps/cs]=20fix:=20=EB=B9=8C=EB=93=9C?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../groups/model/groups-table-columns.tsx | 12 +++++++----- .../cs/src/pages/groups/ui/groups-section.tsx | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/apps/cs/src/pages/groups/model/groups-table-columns.tsx b/apps/cs/src/pages/groups/model/groups-table-columns.tsx index 0f417a304..18ad4e78a 100644 --- a/apps/cs/src/pages/groups/model/groups-table-columns.tsx +++ b/apps/cs/src/pages/groups/model/groups-table-columns.tsx @@ -4,7 +4,11 @@ import { type GroupListResponseDto } from "@/entities/group"; import { MenuAuthorityDialog } from "../ui/menu-authority-dialog"; import { GroupsDialog } from "../ui/groups-dialog"; -export const columns: ColumnDef<GroupListResponseDto>[] = [ +export const createColumns = ({ + onDelete, +}: { + onDelete: (groupId: string) => void; +}): ColumnDef<GroupListResponseDto>[] => [ { accessorKey: "groupId", header: "그룹코드", @@ -20,12 +24,10 @@ export const columns: ColumnDef<GroupListResponseDto>[] = [ { id: "actions", header: "관리", - cell: ({ row, table }) => { - const onDelete = table.options.meta?.onDelete as (groupId: string) => void; - + cell: ({ row }) => { const handleDelete = (e: React.MouseEvent) => { e.stopPropagation(); - if (onDelete) onDelete(row.original.groupId); + onDelete(row.original.groupId); }; return ( diff --git a/apps/cs/src/pages/groups/ui/groups-section.tsx b/apps/cs/src/pages/groups/ui/groups-section.tsx index 2130a94c0..8acc7f019 100644 --- a/apps/cs/src/pages/groups/ui/groups-section.tsx +++ b/apps/cs/src/pages/groups/ui/groups-section.tsx @@ -1,13 +1,17 @@ "use client"; import { useState } from "react"; -import { keepPreviousData, useQuery, useQueryClient } from "@tanstack/react-query"; +import { + keepPreviousData, + useQuery, + useQueryClient, +} from "@tanstack/react-query"; import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; import { Button } from "@common/components"; import { GroupApi } from "@/entities/group"; import { ENDPOINT } from "@/shared/config"; import { useDataTable } from "@/shared/lib"; -import { columns } from "../model/groups-table-columns"; +import { createColumns } from "../model/groups-table-columns"; import { GroupsDialog } from "./groups-dialog"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { useAlertStore, useMutationWrapper } from "@/shared/lib"; @@ -30,8 +34,8 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { size: pagination.pageSize, }), placeholderData: keepPreviousData, - }); - const { confirm } = useConfirm(); + }); + const { confirm } = useConfirm(); const alert = useAlertStore((state) => state.setMessage); const queryClient = useQueryClient(); const { mutateAsync: deleteGroup } = useMutationWrapper({ @@ -51,22 +55,19 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { }; const handleRowClick = (row: { groupId: string }) => { table.setRowSelection({ [row.groupId]: true }); - handleSelectedGroup(row.groupId); // 1. 리스트에서 선택된 groupId 저장 + handleSelectedGroup(row.groupId); // 1. 리스트에서 선택된 groupId 저장 }; const { tableComponent, tableInstance: table } = useDataTable({ query, tableOptions: { - columns, + columns: createColumns({ onDelete: handleDelete }), state: { pagination }, manualPagination: true, enableMultiRowSelection: false, getCoreRowModel: getCoreRowModel(), onPaginationChange: setPagination, getRowId: (row) => row.groupId, - meta: { - onDelete: handleDelete, - }, }, dataTableOptions: { onRowClick: handleRowClick, From 757deae40ef1de05622d45fb8e6406aa71d40333 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 14:51:25 +0900 Subject: [PATCH 076/159] =?UTF-8?q?[groups]=20=EA=B7=B8=EB=A3=B9=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EC=83=81=EB=8B=A8=EC=97=90=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=B6=95=EA=B0=80=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group-user/model/group-user-interface.ts | 1 + apps/cs/src/entities/group/index.ts | 1 + .../pages/groups/ui/group-users-section.tsx | 45 ++++++++++- .../cs/src/pages/groups/ui/groups-section.tsx | 76 ++++++++++++++++++- apps/cs/src/types/tanstack-table.d.ts | 11 +++ 5 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 apps/cs/src/types/tanstack-table.d.ts diff --git a/apps/cs/src/entities/group-user/model/group-user-interface.ts b/apps/cs/src/entities/group-user/model/group-user-interface.ts index 8935bfacc..52fa97fce 100644 --- a/apps/cs/src/entities/group-user/model/group-user-interface.ts +++ b/apps/cs/src/entities/group-user/model/group-user-interface.ts @@ -3,6 +3,7 @@ import type { PageableList, PageableParams } from "@/shared/model"; // 그룹 사용자 검색 파라미터 인터페이스 export interface GroupUserSearchParams extends PageableParams { keyword?: string; + userNm?: string; } // 그룹 사용자 목록 응답 인터페이스 diff --git a/apps/cs/src/entities/group/index.ts b/apps/cs/src/entities/group/index.ts index da1d72a41..30dc07714 100644 --- a/apps/cs/src/entities/group/index.ts +++ b/apps/cs/src/entities/group/index.ts @@ -3,4 +3,5 @@ export { groupFormSchema, type GroupFormData, type GroupListResponseDto, + type GroupSearchParams, } from "./model/group-interface"; diff --git a/apps/cs/src/pages/groups/ui/group-users-section.tsx b/apps/cs/src/pages/groups/ui/group-users-section.tsx index dc16fda60..4b7170e3a 100644 --- a/apps/cs/src/pages/groups/ui/group-users-section.tsx +++ b/apps/cs/src/pages/groups/ui/group-users-section.tsx @@ -12,7 +12,7 @@ import { type RowSelectionState, } from "@tanstack/react-table"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { Button } from "@common/components"; +import { Button,Input, Label } from "@common/components"; import { GroupUsersApi } from "@/entities/group-user"; import { ENDPOINT } from "@/shared/config"; import { useAlertStore, useDataTable } from "@/shared/lib"; @@ -32,13 +32,17 @@ function GroupUsersSection({ groupId }: GroupUsersSectionProps) { pageIndex: 0, pageSize: 10, }); + + const [userNm, setUserNm] = useState(""); + const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.GROUP_USERS, groupId, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.GROUP_USERS, groupId, pagination, userNm], queryFn: () => GroupUsersApi.findPageGroupUser({ keyword: groupId, + userNm: userNm, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -46,6 +50,20 @@ function GroupUsersSection({ groupId }: GroupUsersSectionProps) { placeholderData: keepPreviousData, }); + const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); + // userNm이 이미 state에 반영되어 있으므로 별도 처리 불필요 + // 쿼리키에 userNm이 포함되어 있어 자동 refetch됨 + }; + + const handleReset = () => { + setUserNm(""); + }; + const { tableComponent, tableInstance: table } = useDataTable({ query, tableOptions: { @@ -97,6 +115,29 @@ function GroupUsersSection({ groupId }: GroupUsersSectionProps) { return ( <div className="flex-1"> + <div className="card card-border"> + <form onSubmit={handleSubmit} className="flex items-center gap-2 p-2"> + <Label htmlFor="" className="mr-2 text-label"> + 이름 + </Label> + <Input + className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" + value={userNm} + onChange={(e) => setUserNm(e.target.value)} + /> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> + </form> + </div> <div className="card card-border"> <div className="card-header"> <h3 className="text-2xl font-medium text-label">그룹 사용자 목록</h3> diff --git a/apps/cs/src/pages/groups/ui/groups-section.tsx b/apps/cs/src/pages/groups/ui/groups-section.tsx index 2130a94c0..c316283b7 100644 --- a/apps/cs/src/pages/groups/ui/groups-section.tsx +++ b/apps/cs/src/pages/groups/ui/groups-section.tsx @@ -3,14 +3,14 @@ import { useState } from "react"; import { keepPreviousData, useQuery, useQueryClient } from "@tanstack/react-query"; import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; -import { Button } from "@common/components"; -import { GroupApi } from "@/entities/group"; +import { Button, Input, Label } from "@common/components"; +import { GroupApi , type GroupSearchParams} from "@/entities/group"; import { ENDPOINT } from "@/shared/config"; import { useDataTable } from "@/shared/lib"; import { columns } from "../model/groups-table-columns"; import { GroupsDialog } from "./groups-dialog"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { useAlertStore, useMutationWrapper } from "@/shared/lib"; +import { useAlertStore, useMutationWrapper } from "@/shared/lib"; type GroupsSectionProps = { handleSelectedGroup: (groupId: string) => void; @@ -22,10 +22,20 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { pageSize: 10, }); + const [groupNm, setGroupNm] = useState(""); + const [searchParams, setSearchParams] = useState<GroupSearchParams>({ + groupNm: "", + delYn :"N", + sort : "groupId,desc", + }); + + + const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.GROUPS, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.GROUPS,searchParams, pagination], queryFn: () => GroupApi.findPageGroup({ + ...searchParams, page: pagination.pageIndex, size: pagination.pageSize, }), @@ -49,6 +59,27 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { await deleteGroup(groupId); } }; + + const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + setPagination({ + ...pagination, + pageIndex: 0, + }); + setSearchParams({ + ...searchParams, + groupNm, + }); + }; + + const handleReset = () => { + setGroupNm(""); + setSearchParams({ + ...searchParams, + groupNm: "", + delYn:"N" + }); + }; const handleRowClick = (row: { groupId: string }) => { table.setRowSelection({ [row.groupId]: true }); handleSelectedGroup(row.groupId); // 1. 리스트에서 선택된 groupId 저장 @@ -76,6 +107,43 @@ function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) { return ( <div className="flex-1"> + <div className="card card-border"> + <form onSubmit={handleSubmit} className="flex items-center gap-2 p-2"> + <Label htmlFor="" className="mr-2 text-label"> + 그룹명 + </Label> + <Input + className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" + value={groupNm} + onChange={(e) => setGroupNm(e.target.value)} + /> + <Button className="h-[3.2rem]" type="submit"> + 조회 + </Button> + <Button + type="button" + color="white" + className="h-[3.2rem]" + onClick={handleReset} + > + 초기화 + </Button> + <Label htmlFor="delYn" className="ml-4 mr-2 text-label"> + 삭제여부 + </Label> + <input + id="delYn" + type="checkbox" + checked={searchParams.delYn === "Y"} + onChange={(e) => + setSearchParams({ + ...searchParams, + delYn: e.target.checked ? "Y" : "N", + }) + } + /> + </form> + </div> <div className="card card-border"> <div className="card-header"> <h3 className="text-2xl font-medium text-label">그룹 목록</h3> diff --git a/apps/cs/src/types/tanstack-table.d.ts b/apps/cs/src/types/tanstack-table.d.ts new file mode 100644 index 000000000..9cd9838a2 --- /dev/null +++ b/apps/cs/src/types/tanstack-table.d.ts @@ -0,0 +1,11 @@ +import '@tanstack/react-table'; + +// 오류가 표시되는 이유는 TypeScript가 meta 객체 안에 onDelete라는 속성이 존재한다는 것을 모르기 때문입니다 +declare module '@tanstack/react-table' { + // TData는 테이블의 row 데이터 타입을 의미합니다. + // interface TableMeta에 우리 프로젝트에서 사용할 커스텀 속성의 타입을 정의합니다. + interface TableMeta<TData extends RowData> { + // handleDelete 함수가 string 타입의 인자를 받으므로, 타입을 명시해줍니다. + onDelete: (groupId: string) => void; + } +} \ No newline at end of file From ffacf689f92a4fd42a3811297ff80696fb0d1403 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 15:10:41 +0900 Subject: [PATCH 077/159] =?UTF-8?q?[groups]=20tableData=20build=EC=8B=9C?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=EB=A1=9C=20=EB=8B=A4=EC=8B=9C=20=EC=98=AC?= =?UTF-8?q?=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/groups/model/groups-table-columns.tsx | 8 ++++++++ apps/cs/src/types/tanstack-table.d.ts | 11 ----------- 2 files changed, 8 insertions(+), 11 deletions(-) delete mode 100644 apps/cs/src/types/tanstack-table.d.ts diff --git a/apps/cs/src/pages/groups/model/groups-table-columns.tsx b/apps/cs/src/pages/groups/model/groups-table-columns.tsx index 0f417a304..0cb6a1f84 100644 --- a/apps/cs/src/pages/groups/model/groups-table-columns.tsx +++ b/apps/cs/src/pages/groups/model/groups-table-columns.tsx @@ -4,6 +4,14 @@ import { type GroupListResponseDto } from "@/entities/group"; import { MenuAuthorityDialog } from "../ui/menu-authority-dialog"; import { GroupsDialog } from "../ui/groups-dialog"; + +declare module "@tanstack/react-table" { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface TableMeta<TData> { + onDelete: (groupId: string) => void; + } +} + export const columns: ColumnDef<GroupListResponseDto>[] = [ { accessorKey: "groupId", diff --git a/apps/cs/src/types/tanstack-table.d.ts b/apps/cs/src/types/tanstack-table.d.ts deleted file mode 100644 index 9cd9838a2..000000000 --- a/apps/cs/src/types/tanstack-table.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import '@tanstack/react-table'; - -// 오류가 표시되는 이유는 TypeScript가 meta 객체 안에 onDelete라는 속성이 존재한다는 것을 모르기 때문입니다 -declare module '@tanstack/react-table' { - // TData는 테이블의 row 데이터 타입을 의미합니다. - // interface TableMeta에 우리 프로젝트에서 사용할 커스텀 속성의 타입을 정의합니다. - interface TableMeta<TData extends RowData> { - // handleDelete 함수가 string 타입의 인자를 받으므로, 타입을 명시해줍니다. - onDelete: (groupId: string) => void; - } -} \ No newline at end of file From 12d03e9dd1eceb2f4061a4046d1b297caa344e75 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 15:45:32 +0900 Subject: [PATCH 078/159] =?UTF-8?q?[groups]=20tableData=20build=EC=8B=9C?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=EB=A1=9C=20-=20onDelete=20=EC=98=B5?= =?UTF-8?q?=EC=85=94=EB=84=90=EB=A1=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/groups/model/groups-table-columns.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cs/src/pages/groups/model/groups-table-columns.tsx b/apps/cs/src/pages/groups/model/groups-table-columns.tsx index 0cb6a1f84..864bfafd2 100644 --- a/apps/cs/src/pages/groups/model/groups-table-columns.tsx +++ b/apps/cs/src/pages/groups/model/groups-table-columns.tsx @@ -8,7 +8,7 @@ import { GroupsDialog } from "../ui/groups-dialog"; declare module "@tanstack/react-table" { // eslint-disable-next-line @typescript-eslint/no-unused-vars interface TableMeta<TData> { - onDelete: (groupId: string) => void; + onDelete?: (groupId: string , row?: TData) => void; } } From 67023952aed67aed6e0a4f8b47220398d17dd6d9 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 15:49:22 +0900 Subject: [PATCH 079/159] =?UTF-8?q?[all]=20cs=20=EC=8B=A4=ED=96=89?= =?UTF-8?q?=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=20=EB=82=A8=EA=B8=B0=EA=B8=B0?= =?UTF-8?q?=EB=B0=8F=20=ED=84=B0=EB=AF=B8=EB=84=90=20=EC=97=86=EC=9D=B4=20?= =?UTF-8?q?=EB=9B=B0=EC=9A=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/start_cs.sh | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/cs/start_cs.sh diff --git a/apps/cs/start_cs.sh b/apps/cs/start_cs.sh new file mode 100644 index 000000000..1cd43e699 --- /dev/null +++ b/apps/cs/start_cs.sh @@ -0,0 +1 @@ +nohup pnpm start > start.log 2>&1 & \ No newline at end of file From ec91aa461ac4bace98cfba5fabd0b96c25fdd334 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 16:26:44 +0900 Subject: [PATCH 080/159] =?UTF-8?q?[all]=20cs=20=EB=B0=8F=20features=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/features/start_13000.sh | 25 +++++++++++++++++++++++++ apps/cs/start_cs.sh | 26 +++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100755 apps/common/features/start_13000.sh mode change 100644 => 100755 apps/cs/start_cs.sh diff --git a/apps/common/features/start_13000.sh b/apps/common/features/start_13000.sh new file mode 100755 index 000000000..e1ba84bbf --- /dev/null +++ b/apps/common/features/start_13000.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +PORT=13000 +LOG_FILE="start_13000.log" + +# 1. 기존 포트 사용 프로세스 종료 +PID=$(lsof -t -i :$PORT) +if [ -n "$PID" ]; then + echo "Killing process on port $PORT (PID: $PID)" + kill -9 $PID +fi + +# 2. 백그라운드로 앱 시작 (로그 파일로 리디렉션) +echo "Starting app on port $PORT..." +nohup pnpm start > $LOG_FILE 2>&1 & + +# 3. PID 확인 +sleep 1 +NEW_PID=$(lsof -t -i :$PORT) +if [ -n "$NEW_PID" ]; then + echo "App started successfully (PID: $NEW_PID)" + echo "Logs: tail -f $LOG_FILE" +else + echo "Failed to start app. Check logs: $LOG_FILE" +fi \ No newline at end of file diff --git a/apps/cs/start_cs.sh b/apps/cs/start_cs.sh old mode 100644 new mode 100755 index 1cd43e699..7fa2c18a7 --- a/apps/cs/start_cs.sh +++ b/apps/cs/start_cs.sh @@ -1 +1,25 @@ -nohup pnpm start > start.log 2>&1 & \ No newline at end of file +#!/bin/bash + +PORT=3000 +LOG_FILE="start_cs.log" + +# 1. 기존 포트 사용 프로세스 종료 +PID=$(lsof -t -i :$PORT) +if [ -n "$PID" ]; then + echo "Killing process on port $PORT (PID: $PID)" + kill -9 $PID +fi + +# 2. 백그라운드로 앱 시작 (로그 파일로 리디렉션) +echo "Starting app on port $PORT..." +nohup pnpm start > $LOG_FILE 2>&1 & + +# 3. PID 확인 +sleep 1 +NEW_PID=$(lsof -t -i :$PORT) +if [ -n "$NEW_PID" ]; then + echo "App started successfully (PID: $NEW_PID)" + echo "Logs: tail -f $LOG_FILE" +else + echo "Failed to start app. Check logs: $LOG_FILE" +fi \ No newline at end of file From bc9140206cde1c139c5bce51db2fd890558311d7 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Thu, 10 Jul 2025 16:37:05 +0900 Subject: [PATCH 081/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=EC=84=A4=20=ED=8C=8C=EC=9D=BC=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=93=B1=EB=A1=9D=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 4 +- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 94 +++---------- apps/wr/components/lib/api/index.ts | 15 +- apps/wr/components/lib/useTus_wr/useTusWr.tsx | 31 ++++- .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 3 - .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 131 ++++++++---------- 6 files changed, 125 insertions(+), 153 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 1f7d88824..0d99d15cf 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -89,7 +89,6 @@ export default function PublicReuseFaciltyInsert() { }, [pbnst.isInit, pubHasuInit]); const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => { - if (!isDirty) { toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시 return; @@ -98,6 +97,8 @@ export default function PublicReuseFaciltyInsert() { data.forEach((fclt) => { bizs = [...bizs, ...fclt.fcBizs]; }); + + const pbnst = data.map((fclt) => { return { pbnstRuseFcltPk: fclt.pbnstRuseFcltPk, @@ -390,7 +391,6 @@ export default function PublicReuseFaciltyInsert() { formType="update" form={form} setIndexMng={(index: number) => { - console.log("setIndexMng", index); setIndexMng(index); }} indexMng={indexMng} diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 3057cec7f..9f4b6e859 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -177,9 +177,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { pubHasuInit: async (page: string, sggOrCity: string) => { try { const pbnstHasuRes = await hasuListFetch(page, sggOrCity); - - - return set((state: pubFacState) => ({ ...state, pbnst: { @@ -222,22 +219,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { console.log(errorHasu); } }, - - // pbnstReg: async (txt: string | undefined) => { - // try { - // const pbnstRes = await hasuListFetch("11", "11"); - // return set((state: pubFacState) => ({ - // ...state, - // pbnst: { - // ...state.pbnst, - // pbnstRes: pbnstRes, - // isInit: false, - // }, - // })); - // } catch (errorHasu) { - // console.log(errorHasu); - // } - // }, pbnstInsert: async (pbnstRes: customPbnst) => { try { @@ -249,8 +230,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { toast.success(`${pbnstRes.ruseUtztnFcltNm} 하수재이용 시설이 등록되었습니다.`); } const pbnstHasuRes = await hasuListFetch('1', '0'); - - return set((state: pubFacState) => ({ ...state, pbnst: { @@ -276,25 +255,13 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } ,pbnstRuseBizUpdate : async(ruseRes:fcBizType[])=>{ try { - console.log('ruseRes ', ruseRes) const response = await putFectch( `/reuseFc/pubFcBiz`, ruseRes ); - // const pbnstRes = await hasuListFetch("11", "11"); - - // return set((state: pubFacState) => ({ - // ...state, - // pbnst: { - // ...state.pbnst, - // pbnstRes: pbnstRes, - // isInit: false, - // }, - // })); } catch (error) { console.error("Error pbnstRuseFcltUpdate:", error); - // toast.error(` 하수재이용 시설 사업이 수정이 실패되엇습니다..`); } } , getBizCycle: async (pbnstObj: customPbnst) => { @@ -341,50 +308,33 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { fetchType.CS, `/attach-service/api/v1/atflcd/download/${atflCd}` ); + } catch (error) { + console.error("Error downloading file:", error); + throw new Error(`Error downloading file: ${error}`); + } + }, + fileInfoUpdate:async(atflCd: string)=>{ + + const WrTableInfo={ + "lnkgDmnNm": "tbWrRuseFcltFile", + "lnkgDmnId": "fileTkn" + } + + try{ + const response = await putFectch( + `/attach-service/api/v1/atfl/attachments/${atflCd}/info`, + WrTableInfo, + fetchType.CS + ) if (!response.ok) { throw new Error(`Error downloading file: ${response.statusText}`); } - } catch (error) { - console.error("Error downloading file:", error); + }catch(e){ + } }, - // pbnstMngData: (data: customPbnst[]) => { - // if (data.length > 0) { - // } - // return set((state: pubFacState) => { - // state.pbnst.pbnstMngRegData = data; - // state.pbnst.pbnstBizCycle = - // data.length <= 0 - // ? [{ text: "없음", val: "1" }] - // : state.pbnst.pbnstBizCycle; - // return state; - // }); - // }, - - // pbnstBizData: (data: fcBizType) => { - // return set((state: pubFacState) => { - // if (state.pbnst.pbnstMngRegData) { - // const regData = state.pbnst.pbnstMngRegData.find( - // (item) => data.pbnstRuseFcltFk === item.pbnstRuseFcltPk - // ); - // if (regData) { - // const bizIdx = regData.fcBizs.findIndex( - // (item) => item.pbnstRuseFcltBizPk == data.pbnstRuseFcltBizPk - // ); - - // if (bizIdx >= 0) { - // regData.fcBizs[bizIdx] = data; - // const pbnstData = state.pbnst.pbnstMngRegData - // state.pbnst.pbnstMngRegData= [...pbnstData] - - // } - // } - // } - // return state; - // }); - // }, getpbnstInsertIndex: async (data: pbnstInsertIndex) => { return set((state: pubFacState) => { state.pbnst.pbnsUpdateIndex = data; @@ -420,9 +370,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { fcOrgwtsNmList:fcOrgwtsNmList.data??[] }, })); - - - } + }; }; diff --git a/apps/wr/components/lib/api/index.ts b/apps/wr/components/lib/api/index.ts index cee42b905..bf2c01683 100644 --- a/apps/wr/components/lib/api/index.ts +++ b/apps/wr/components/lib/api/index.ts @@ -108,8 +108,18 @@ export const postFectch = async (url: string, params: any, type?: string) => { return await response.json(); }; -export const putFectch = async (url: string, params: any) => { - const response = await fetch(DEV_URL_WR + url, { +export const putFectch = async (url: string, params: any,type?:string) => { + const div = + type === fetchType.COMMON + ? DEV_URL_FO + : type === fetchType.LOCAL + ? LOCAL_URL + : type === fetchType.CS + ? '' + : DEV_URL_WR; + + + const response = await fetch(div + url, { method: "PUT", headers: { "Content-Type": "application/json", @@ -132,7 +142,6 @@ export const deleteFectch = async (url: string, params?: any, type?: string) => ? '' : DEV_URL_WR; - console.log("deleteFectch url", div + url); const response = await fetch(div + url, { method: "DELETE", headers: { diff --git a/apps/wr/components/lib/useTus_wr/useTusWr.tsx b/apps/wr/components/lib/useTus_wr/useTusWr.tsx index b9441e6a4..aca2b1fb6 100644 --- a/apps/wr/components/lib/useTus_wr/useTusWr.tsx +++ b/apps/wr/components/lib/useTus_wr/useTusWr.tsx @@ -7,6 +7,9 @@ import { } from "tus-js-client"; import { CS_TUS_UPLOAD, CS_URL } from "../config"; import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; +import { fetchType, putFectch } from "../api"; +import { error } from "console"; +import toast from "react-hot-toast"; type UploadOptions = { handleUploadStart?: (upload: Upload) => void; @@ -60,8 +63,30 @@ export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) => onSuccess(payload: OnSuccessPayload) { options?.handleSuccess?.(payload); if (fileInfo) { - console.log('fileInfo', fileInfo); - resolve(JSON.parse(fileInfo) as ReturnFileType); + + + const WrTableInfo = { + lnkgDmnNm: "tbWrRuseFcltFile", + lnkgDmnId: "fileTkn", + }; + + console.log('fileInfo ', fileInfo) + const fileParse = JSON.parse(fileInfo) as ReturnFileType; + putFectch( + `/attach-service/api/v1/atfl/attachments/${fileParse.atflCd}/info`, + WrTableInfo, + fetchType.CS + ) + .then((res) => { + resolve(fileParse); + }) + .catch((error) => { + reject({ + causingError: { + cause: "파일 업로드 업데이트 실패", + }, + } as DetailedError); + }); } else reject({} as DetailedError); }, }); @@ -71,6 +96,8 @@ export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) => } catch (e) { console.log(e); reject(e as DetailedError); + + toast.error(String(e)); } // setUpload(uploader); }); diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 2a2e9defe..bf1160004 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -111,12 +111,9 @@ export function PbnstBuseForm({ const fcOrgwts = form.watch(`items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`); useEffect(() => { - console.log("fcOrgwts", fcOrgwts); if (fcOrgwts && fcOrgwts?.length > 0) { const swtrmtFcltFkList = fcOrgwts?.map((item) => item.swtrmtFcltFk); - console.log("swtrmtFcltFkList ", swtrmtFcltFkList); - if (swtrmtFcltFkList.length > 0) { getFcOrgwts( swtrmtFcltFkList.filter((item): item is string => item != null), diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index b1bbffc34..cef483bfb 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -9,9 +9,8 @@ import { } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import { Button, Input } from "@common/components"; -import { useEffect, useState } from "react"; -import { useFieldArray, useWatch, type UseFormReturn } from "react-hook-form"; -import { z } from "zod"; +import { useEffect, useRef, useState } from "react"; +import { useFieldArray, type UseFormReturn } from "react-hook-form"; import { commonButonSize, formH1Class, @@ -19,7 +18,6 @@ import { } from "@/components/lib/class/comClass"; import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr"; import { - pbnstRegZod, type customPbnst, type fcFileType, type PbnstRegArrrayType, @@ -50,11 +48,11 @@ export function PbnstMngForm({ indexMng: number; setIndexMng: (index: number) => void; }) { - const { code, pbnst, pbnstInsert, fileDelete, fileDownLoad } = useWrStore( + const { code, pbnst, fileDelete, fileDownLoad } = useWrStore( (state) => state ); - const { pbnstRes } = pbnst; + const fileInitRef = useRef<{ index: number; key: string } | null>(null); const [regFileList, setRegFileList] = useState<fcFileType[] | null>(null); const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null); const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null); @@ -71,11 +69,6 @@ export function PbnstMngForm({ name: `items.${indexMng}.fcOpers`, }); - const watchedItem = useWatch({ - control: form.control, - name: `items.${indexMng}`, - }); - const plusHist = () => { prepend({ choose: false, @@ -171,47 +164,49 @@ export function PbnstMngForm({ }; useEffect(() => { - if (indexMng >= 0) { - const defaultFiles = watchedItem?.fcFiles; - if (defaultFiles && defaultFiles.length > 0) { - const relationFileList = defaultFiles.filter( - (item) => item.fileKnd === "계통도" - ); + const currentItem = form.getValues(`items.${indexMng}`); + const currentKey = JSON.stringify(currentItem); - const planFileList = defaultFiles.filter( - (item) => item.fileKnd === "평면도" - ); - if (relationFileList.length > 0) - setRelationFiles( - relationFileList.map((item) => ({ - atflCd: item.fileTkn, - file: new File([] as BlobPart[], item.filePath), - })) - ); - else { - setRelationFiles(null); - } + const isNewItem = + !fileInitRef.current || + fileInitRef.current.index !== indexMng || + fileInitRef.current.key !== currentKey; - if (planFileList.length > 0) - setPlanFiles( - planFileList.map((item) => ({ - atflCd: item.fileTkn, - file: new File([] as BlobPart[], item.filePath), - })) - ); - else { - setPlanFiles(null); - } - } else { - setRelationFiles(null); - setPlanFiles(null); - } - } - }, [watchedItem, indexMng]); + if (!isNewItem) return; // + + const defaultFiles = currentItem?.fcFiles || []; + + const relationFileList = defaultFiles.filter( + (item) => item.fileKnd === "계통도" + ); + const planFileList = defaultFiles.filter( + (item) => item.fileKnd === "평면도" + ); + + setRelationFiles( + relationFileList.length > 0 + ? relationFileList.map((item) => ({ + atflCd: item.fileTkn, + file: new File([], item.filePath), + })) + : null + ); + + setPlanFiles( + planFileList.length > 0 + ? planFileList.map((item) => ({ + atflCd: item.fileTkn, + file: new File([], item.filePath), + })) + : null + ); + // ✅ 다음 루프에선 다시 안 하도록 저장 + fileInitRef.current = { + index: indexMng, + key: currentKey, + }; + }, [indexMng, form.getValues(`items.${indexMng}`)]); - useEffect(() => { - // pbnstMngData(pbnst.pbnstMngRegData); - }, [pbnst.pbnstMngRegData]); useEffect(() => { if (pbnst.pbnstRes && pbnst.pbnstRes?.length >= 0) { @@ -220,19 +215,17 @@ export function PbnstMngForm({ val: String(index), })); - console.log(" fcltNmList ", fcltNmList); if (fcltNmList) setFcltNm(fcltNmList); } else { setFcltNm(null); } }, [pbnst.pbnstRes]); - // 2. Define a submit handler. - function onSubmit(values: z.infer<typeof pbnstRegZod>) { - values.fcOpers = []; - values.fcFiles = regFileList || []; - pbnstInsert(values); - } + useEffect(() => { + if (regFileList && regFileList?.length > 0) { + form.setValue(`items.${indexMng}.fcFiles`, regFileList); + } + }, [regFileList, indexMng]); useEffect(() => { if (relationfiles) { @@ -245,20 +238,18 @@ export function PbnstMngForm({ } }, [planFiles]); + useEffect(() => { + if (regFileList && regFileList?.length > 0) { + form.setValue(`items.${indexMng}.fcFiles`, regFileList); + } + }, [regFileList, indexMng]); + useEffect(() => { if (code.ruseMngMtd) { setMngMtdCode([{ name: "ruseMngMtd", val: code.ruseMngMtd }]); } }, [code]); - useEffect(() => { - // console.log(' fcltNm ', watchedItem?.ruseUtztnFcltNm) - }, [watchedItem]); - - useEffect(() => { - console.log(" form indexMng ", indexMng); - }, [indexMng]); - return ( <div className=" !mx-[1.6rem] !p-0r"> <div> @@ -342,11 +333,11 @@ export function PbnstMngForm({ headList={ formType === "sttn" ? pbnst.pbnstMngUpHeadList.map((item) => { - return { - ...item, - readonly: true, - }; - }) + return { + ...item, + readonly: true, + }; + }) : pbnst.pbnstMngUpHeadList } upHeadList={pbnst.pbnstMngNm} @@ -357,7 +348,7 @@ export function PbnstMngForm({ indexMng={indexMng} form={form} formNm={"fcOpers"} - // ref={ref} + // ref={ref} ></RuseMngTableForm> </div> </div> From 061b565f7cdb55f773327210e272b816c0589e4c Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Thu, 10 Jul 2025 16:49:39 +0900 Subject: [PATCH 082/159] =?UTF-8?q?toast=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9=EC=9D=84=20=EC=9C=84=ED=95=9C=20i18n=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/layout.tsx | 21 ++++++++++++++++++--- apps/wr/package.json | 2 ++ apps/wr/public/locales/ko/message.json | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 apps/wr/public/locales/ko/message.json diff --git a/apps/wr/app/layout.tsx b/apps/wr/app/layout.tsx index cb930d6f7..188692837 100644 --- a/apps/wr/app/layout.tsx +++ b/apps/wr/app/layout.tsx @@ -3,23 +3,38 @@ import { BaseLayout } from "@common/components"; import "./globals.css"; import { StoreProvider } from "./store"; import { MainDiv } from "@common/business_components"; +import koBase from '../public/locales/ko/message.json'; +import i18next from "i18next"; +import { I18nextProvider } from "react-i18next"; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { + i18next.init({ + lng: 'ko', + fallbackLng: 'ko', + resources: { + ko: { + base: koBase, + }, + } + }); + return ( <html lang="en"> <body> + <I18nextProvider i18n={i18next}> <StoreProvider> <BaseLayout> - <MainDiv> + <MainDiv> {children} - </MainDiv> + </MainDiv> </BaseLayout> </StoreProvider> + </I18nextProvider> </body> - </html> + </html > ); } diff --git a/apps/wr/package.json b/apps/wr/package.json index 44ba5a06b..78f9dfa95 100644 --- a/apps/wr/package.json +++ b/apps/wr/package.json @@ -16,11 +16,13 @@ "@tanstack/react-table": "^8.21.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "i18next": "^25.3.2", "lucide-react": "^0.474.0", "moment": "^2.30.1", "next": "15.1.7", "react-hook-form": "^7.54.2", "react-hot-toast": "^2.5.2", + "react-i18next": "^15.6.0", "tailwind-merge": "^3.0.1", "tailwindcss-animate": "^1.0.7", "tus-js-client": "^4.3.1", diff --git a/apps/wr/public/locales/ko/message.json b/apps/wr/public/locales/ko/message.json new file mode 100644 index 000000000..78219a539 --- /dev/null +++ b/apps/wr/public/locales/ko/message.json @@ -0,0 +1,19 @@ +{ + "deleteMsg" : "{{name}}가 삭제되었습니다.", + "insertMsg": "{{name}}가 저장되었습니다.", + "updateMsg": "{{name}}가 수정되었습니다.", + "errorMsg": "{{name}} 중 오류가 발생했습니다.", + "fileErrMsg": "빈 파일 또는 파일 오류입니다.", + "selectErrMsg": "{{name}}을(를) 선택해주세요.", + "noChangedErrMsg": "변경사항이 없습니다.", + "dateErrMsg": "시작년도를 종료년도 이후로 설정할 수 없습니다.", + "fileDateErrMsg": "파일업로드 이전에 등록년도를 작성해주세요.", + + "alreadyInsertedErrMsg": "사업자번호 {{num}}(은)는 이미 등록되었습니다. 다시 등록해주세요.", + "saveRowErrMsg": "수정을 원하는 행을 선택하고 저장버튼을 눌러주세요.", + "costCalcErrMsg":"공사비 계산 진행 후 저장을 눌러주세요", + "maxYearErrMsg": "최대 {{year}}년까지 선택가능합니다.", + "checkQtyMsg": "요구수량(M3/d)을 확인해주세요 계산할수 없습니다." + +} + From 29bc717b2caec3a80b7ccf64b62d41e385477322 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 16:50:19 +0900 Subject: [PATCH 083/159] =?UTF-8?q?[apps/cs]=20feat:=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20(CS=5FUT05010109)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/users/ui/user-detail.tsx | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/apps/cs/src/pages/users/ui/user-detail.tsx b/apps/cs/src/pages/users/ui/user-detail.tsx index 60c1f34b8..fbfa016c2 100644 --- a/apps/cs/src/pages/users/ui/user-detail.tsx +++ b/apps/cs/src/pages/users/ui/user-detail.tsx @@ -3,6 +3,7 @@ import dayjs from "dayjs"; import { usePathname, useRouter } from "next/navigation"; import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { Button, Table, @@ -18,10 +19,11 @@ import { useAlertStore, useMutationWrapper } from "@/shared/lib"; function UserDetail({ userUnqId }: { userUnqId: string }) { const router = useRouter(); const pathname = usePathname(); + const { confirm } = useConfirm(); const queryClient = useQueryClient(); const alert = useAlertStore((state) => state.setMessage); - const { data } = useQuery({ + const { data, refetch } = useQuery({ queryKey: [ENDPOINT.USER_SERVICE.USERS, userUnqId], queryFn: () => UserApi.findByUserUnqId(userUnqId), enabled: !!userUnqId, @@ -31,9 +33,7 @@ function UserDetail({ userUnqId }: { userUnqId: string }) { mutationFn: () => UserApi.lockUser(userUnqId), onSuccess: () => { alert("계정 잠금이 활성화 되었습니다."); - queryClient.invalidateQueries({ - queryKey: [ENDPOINT.USER_SERVICE.USERS, userUnqId], - }); + refetch(); }, }); @@ -41,9 +41,7 @@ function UserDetail({ userUnqId }: { userUnqId: string }) { mutationFn: () => UserApi.unlockUser(userUnqId), onSuccess: () => { alert("계정 잠금이 해제되었습니다."); - queryClient.invalidateQueries({ - queryKey: [ENDPOINT.USER_SERVICE.USERS, userUnqId], - }); + refetch(); }, }); @@ -51,12 +49,26 @@ function UserDetail({ userUnqId }: { userUnqId: string }) { mutationFn: () => UserApi.applyUser(userUnqId), onSuccess: () => { alert("사용자 승인이 완료되었습니다."); + refetch(); + }, + }); + + const { mutateAsync: deleteUser } = useMutationWrapper({ + mutationFn: () => UserApi.deleteUser(userUnqId), + onSuccess: () => { + alert("회원이 삭제되었습니다.", router.back); queryClient.invalidateQueries({ - queryKey: [ENDPOINT.USER_SERVICE.USERS, userUnqId], + queryKey: [ENDPOINT.USER_SERVICE.USERS], }); }, }); + const handleDelete = async () => { + if (await confirm("삭제하시겠습니까?")) { + await deleteUser(); + } + }; + return ( <div className="card card-border !mt-6"> <div className="card-header"> @@ -164,7 +176,7 @@ function UserDetail({ userUnqId }: { userUnqId: string }) { <Button size="lg" onClick={() => router.push(`${pathname}/modify`)}> 수정 </Button> - <Button size="lg" color="red"> + <Button size="lg" color="red" onClick={handleDelete}> 삭제 </Button> </div> From e5b8bf2685056ee8ac01650890a495fe5411db71 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Thu, 10 Jul 2025 17:08:19 +0900 Subject: [PATCH 084/159] =?UTF-8?q?[apps/cs]=20fix:=20=ED=95=98=EC=9C=84?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=93=B1=EB=A1=9D=20=ED=8F=BC=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0=20(CS=5FUT08010104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/code/ui/lwpocode-dialog.tsx | 10 ++++++++-- apps/cs/src/pages/code/ui/lwpocode-section.tsx | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx b/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx index c11c57332..d6c6bb685 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx @@ -1,7 +1,7 @@ import { memo } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useQuery } from "@tanstack/react-query"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { Button, @@ -50,8 +50,8 @@ const LwpoCodeManagementDialog = memo( ...props }: ManagementLwpoCodeDialogProps) => { const isRegistration = !lwpoCd; - const { confirm } = useConfirm(); + const queryClient = useQueryClient(); const alert = useAlertStore((state) => state.setMessage); const { data: detailData } = useQuery({ @@ -70,6 +70,9 @@ const LwpoCodeManagementDialog = memo( mutationFn: (data: LwpoCodeFormData) => LwpoCodeApi.createLwpoCode(data), onSuccess: () => { alert("등록되었습니다.", () => onOpenChange?.(false)); + queryClient.invalidateQueries({ + queryKey: [ENDPOINT.CMS_SERVICE.LWPO_CODE, upCd], + }); }, }); @@ -251,6 +254,9 @@ const LwpoCodeManagementDialog = memo( {...field} type="number" value={field.value ?? 0} + onChange={(e) => { + field.onChange(parseInt(e.target.value)); + }} className="!text-[1.3rem]" placeholder="정렬순서를 입력해주세요" /> diff --git a/apps/cs/src/pages/code/ui/lwpocode-section.tsx b/apps/cs/src/pages/code/ui/lwpocode-section.tsx index c6025b338..15773c5f4 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-section.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-section.tsx @@ -116,6 +116,7 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { 코드갱신 </Button> <LwpoCodeManagementDialog + upCd={upCd} open={dialogOpen} onOpenChange={setDialogOpen} > From 20db7002154bc8387dddc423aa415fc972b821d5 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Thu, 10 Jul 2025 19:02:26 +0900 Subject: [PATCH 085/159] =?UTF-8?q?[code]=20=ED=95=98=EC=9C=84=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=93=B1=EB=A1=9D=ED=9B=84=20=EC=9E=AC=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20handleAft?= =?UTF-8?q?erSave=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 ++ .../code/model/lwpocode-table-columns.tsx | 89 ++++++++++--------- apps/cs/src/pages/code/ui/lwpocode-dialog.tsx | 86 +++++++++++++----- .../cs/src/pages/code/ui/lwpocode-section.tsx | 19 ++-- 4 files changed, 134 insertions(+), 68 deletions(-) create mode 100644 .idea/.gitignore diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..c3f502a19 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 디폴트 무시된 파일 +/shelf/ +/workspace.xml +# 에디터 기반 HTTP 클라이언트 요청 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/apps/cs/src/pages/code/model/lwpocode-table-columns.tsx b/apps/cs/src/pages/code/model/lwpocode-table-columns.tsx index 1bea87275..a119d88d9 100644 --- a/apps/cs/src/pages/code/model/lwpocode-table-columns.tsx +++ b/apps/cs/src/pages/code/model/lwpocode-table-columns.tsx @@ -5,56 +5,62 @@ import type { LwpoCode } from "@/entities/code"; import { LwpoCodeManagementDialog } from "../ui/lwpocode-dialog"; import { useState } from "react"; -export const columns: ColumnDef<LwpoCode>[] = [ - { - id: "no", - header: "NO", - cell: ({ row, table }) => { - const totalRows = table.getRowCount(); - const { pageIndex, pageSize } = table.getState().pagination; - return totalRows - (pageIndex * pageSize + row.index); +// columns를 함수로 변경하여 onAfterSave를 주입받음 +export function getColumns(onAfterSave: () => void) : ColumnDef<LwpoCode>[] { + return [ + { + id: "no", + header: "NO", + cell: ({ row, table }) => { + const totalRows = table.getRowCount(); + const { pageIndex, pageSize } = table.getState().pagination; + return totalRows - (pageIndex * pageSize + row.index); + }, }, - }, - { - accessorKey: "lwpoCd", - header: "하위코드", - }, - { - accessorKey: "lwpoCdNm", - header: "하위코드명", - }, - { - accessorKey: "useYn", - header: "사용 여부", - }, - { - accessorKey: "regDt", - header: "등록일", - cell: ({ row }) => { - const date = dayjs(row.original.regDt); - return date.format("YYYY-MM-DD"); + { + accessorKey: "lwpoCd", + header: "하위코드", }, - }, - { - id: "actions", - header: "관리", - cell: ({ row }) => ( - <div onClick={(e) => e.stopPropagation()}> - <LwpoCodeManageButton - lwpoCd={row.original.lwpoCd} - upCd={row.original.upCd} - /> - </div> - ), - }, -]; + { + accessorKey: "lwpoCdNm", + header: "하위코드명", + }, + { + accessorKey: "useYn", + header: "사용 여부", + }, + { + accessorKey: "regDt", + header: "등록일", + cell: ({ row }) => { + const date = dayjs(row.original.regDt); + return date.format("YYYY-MM-DD"); + }, + }, + { + id: "actions", + header: "관리", + cell: ({ row }) => ( + <div onClick={(e) => e.stopPropagation()}> + <LwpoCodeManageButton + lwpoCd={row.original.lwpoCd} + upCd={row.original.upCd} + onAfterSave={onAfterSave} + /> + </div> + ), + }, + ]; +} const LwpoCodeManageButton = ({ lwpoCd, upCd, + onAfterSave, }: { lwpoCd: string; upCd: string; + onAfterSave: () => void; }) => { const [dialogOpen, setDialogOpen] = useState(false); return ( @@ -63,6 +69,7 @@ const LwpoCodeManageButton = ({ upCd={upCd} open={dialogOpen} onOpenChange={setDialogOpen} + onAfterSave={onAfterSave} > <Button size="sm">관리</Button> </LwpoCodeManagementDialog> diff --git a/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx b/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx index c11c57332..1eb9562ec 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-dialog.tsx @@ -37,7 +37,8 @@ type ManagementLwpoCodeDialogProps = { upCd?: string; children?: React.ReactNode; open?: boolean; - onOpenChange?: (open: boolean) => void; + onOpenChange?: (open: boolean) => void; + onAfterSave?: () => void; // 콜백 추가 }; const LwpoCodeManagementDialog = memo( @@ -46,19 +47,21 @@ const LwpoCodeManagementDialog = memo( upCd, children, open, - onOpenChange, + onOpenChange, + onAfterSave, // 콜백 사용 ...props }: ManagementLwpoCodeDialogProps) => { const isRegistration = !lwpoCd; const { confirm } = useConfirm(); - const alert = useAlertStore((state) => state.setMessage); - + const alert = useAlertStore((state) => state.setMessage); + // 상세 데이터 const { data: detailData } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.LWPO_CODE, upCd, lwpoCd], queryFn: () => LwpoCodeApi.lwpoCodeDetail(upCd!, lwpoCd!), - enabled: !!upCd && !isRegistration, + enabled: !!upCd && !isRegistration && open, }); + const { data: upCodeData } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.UP_CODE, upCd], @@ -68,16 +71,22 @@ const LwpoCodeManagementDialog = memo( const { mutateAsync: createLwpoCode } = useMutationWrapper({ mutationFn: (data: LwpoCodeFormData) => LwpoCodeApi.createLwpoCode(data), - onSuccess: () => { - alert("등록되었습니다.", () => onOpenChange?.(false)); + onSuccess: async () => { + alert("등록되었습니다.", () => { + onOpenChange?.(false); + if (onAfterSave) onAfterSave(); + }); }, }); const { mutateAsync: updateLwpoCode } = useMutationWrapper({ mutationFn: (data: LwpoCodeFormData) => LwpoCodeApi.updateLwpoCode(upCd!, lwpoCd!, data), - onSuccess: () => { - alert("수정되었습니다.", () => onOpenChange?.(false)); + onSuccess: async () => { + alert("수정되었습니다.", () => { + onOpenChange?.(false); + if (onAfterSave) onAfterSave(); + }); }, }); @@ -95,16 +104,40 @@ const LwpoCodeManagementDialog = memo( delYn: "N", }, }); + - const onSubmit = - (callback: (data: LwpoCodeFormData) => void) => - async (data: LwpoCodeFormData) => { - const confirmMessage = isRegistration - ? "등록하시겠습니까?" - : "수정하시겠습니까?"; - - if (await confirm(confirmMessage)) callback(data); - }; + const handleRegister = async () => { + if (!upCd) { + alert("상위코드가 없습니다."); + return; + } + const confirmMessage = "등록하시겠습니까?"; + if (await confirm(confirmMessage)) { + const rawValues = form.getValues(); + const values = { + ...rawValues, + upCd: upCd, + sortSeq: Number(rawValues.sortSeq) || 0, + }; + await createLwpoCode(values); + } + }; + const handleSave = async () => { + if (!upCd) { + alert("상위코드가 없습니다."); + return; + } + const confirmMessage = "수정하시겠습니까?"; + if (await confirm(confirmMessage)) { + const rawValues = form.getValues(); + const values = { + ...rawValues, + upCd: upCd, + sortSeq: Number(rawValues.sortSeq) || 0, + }; + await updateLwpoCode(values); + } + }; return ( <Dialog open={open} onOpenChange={onOpenChange} {...props}> @@ -117,9 +150,14 @@ const LwpoCodeManagementDialog = memo( </DialogHeader> <Form {...form}> <form - onSubmit={form.handleSubmit( - onSubmit(isRegistration ? createLwpoCode : updateLwpoCode), - )} + onSubmit={(e) => { + e.preventDefault(); + if (isRegistration) { + handleRegister(); + } else { + handleSave(); + } + }} className="space-y-4" > <Table variant="secondary"> @@ -292,7 +330,11 @@ const LwpoCodeManagementDialog = memo( </TableBody> </Table> <DialogFooter className="!justify-center"> - <Button size="lg" type="submit"> + <Button + size="lg" + type="submit" + onClick={isRegistration ? handleRegister : handleSave} + > {isRegistration ? "등록" : "저장"} </Button> <DialogClose asChild> diff --git a/apps/cs/src/pages/code/ui/lwpocode-section.tsx b/apps/cs/src/pages/code/ui/lwpocode-section.tsx index c6025b338..3e6aaf1ca 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-section.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-section.tsx @@ -5,7 +5,7 @@ import { Button, Input, Label } from "@common/components"; import { LwpoCodeApi, type LwpoCodeParams } from "@/entities/code"; import { ENDPOINT } from "@/shared/config"; import { useAlertStore, useDataTable } from "@/shared/lib"; -import { columns } from "../model/lwpocode-table-columns"; +import { getColumns } from "../model/lwpocode-table-columns"; import { LwpoCodeManagementDialog } from "./lwpocode-dialog"; type LwpoCodeSectionProps = { @@ -24,7 +24,7 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { pageIndex: 0, pageSize: 10, }); - + const query = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.LWPO_CODE, upCd, searchParams, pagination], queryFn: () => @@ -34,10 +34,17 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { page: pagination.pageIndex, size: pagination.pageSize, }), - enabled: !!upCd, + enabled: !!upCd , placeholderData: keepPreviousData, - }); + }); + // 등록/수정 후 목록 재조회 콜백 + const handleAfterSave = () => { + query.refetch(); + }; + const columns = getColumns(handleAfterSave); + + const { mutateAsync: codeRefreshAll } = useMutation({ mutationFn: LwpoCodeApi.codeRefreshAll, onSuccess: () => { @@ -117,7 +124,9 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { </Button> <LwpoCodeManagementDialog open={dialogOpen} - onOpenChange={setDialogOpen} + upCd={upCd} + onOpenChange={setDialogOpen} + onAfterSave={handleAfterSave} > <Button>등록</Button> </LwpoCodeManagementDialog> From 16abacf292cbac545d48cc4b568bbf154380f561 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Fri, 11 Jul 2025 10:40:39 +0900 Subject: [PATCH 086/159] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 90b9a140c..e8641ca6c 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -77,7 +77,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( (state) => state ); - let { rainSttnRes } = rainSttn; + let { rainSttnRes, rainSttnResCount } = rainSttn; const [rainTable, setRainTable] = useState<customRainBdst[]>(); const [rainBdstChgProps, setRainBdstChgProps] = useState<{ isOpen: boolean; @@ -90,7 +90,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const { rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore( (state) => state ); - let { rswtSttnRes } = rswtSttn; + let { rswtSttnRes, rswtSttnResCount } = rswtSttn; const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>(); const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false }); const [rswtrBdstChgProps, setRswtrBdstChgProps] = useState<{ @@ -101,24 +101,23 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); - let { htdflSttnRes } = htdflSttn; + let { htdflSttnRes,htdflSttnResCount } = htdflSttn; const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); - const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); const [htdflPage, setHtdflPage] = useState(1) - const [htdflResetPage, isHtdflResetPage] = useState(false); //하수처리시설 변수 const { pbnst, pubHasuInit, } = useWrStore((state) => state); - let { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; + let { pubFacHeadList, pbnstHasuRes } = pbnst; const [isRuseReg, setIsRuseReg] = useState<{ data: any | undefined; }>({ data: undefined }); const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); const [hasuPage, setHasuPage] = useState<number>(1); + const [hasuRes,setHasuRes] = useState<number>() if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// const getSelectedLayers = () => { @@ -488,7 +487,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ tableData={hasuTable || []} headlist={pubFacHeadList} pageSize={10} - total={100000} + total={5000} headName={""} cellClick={hasuCellClick} onPageChange={setHasuPage} @@ -570,7 +569,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ children={<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />} headlist={pbnstSttn.pbnstSttHeadList} pageSize={20} - total={100000} + total={pbnstSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { pbnstCellClick(index); }} @@ -605,7 +604,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ children={<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />} headlist={rainSttn.rainSttHeadList} pageSize={20} - total={100000} + total={rainSttnResCount} cellClick={(index: number | undefined, headId: string) => { rainCellClick(index ?? undefined, headId); }} @@ -640,7 +639,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ children={<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />} headlist={rswtSttn.rswtSttHeadList} pageSize={20} - total={100000} + total={rswtSttnResCount} cellClick={(index: number | undefined, headId: string) => { rswtCellClick(index, headId); }} @@ -675,7 +674,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ children={<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />} headlist={htdflSttn.htdflSttHeadList} pageSize={20} - total={100000} + total={htdflSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { htdflCellClick(index ?? undefined, headId); }} From fe71d85bc62a941cf47a043365d555a979fffbfe Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Fri, 11 Jul 2025 10:54:57 +0900 Subject: [PATCH 087/159] =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pnpm-lock.yaml | 10261 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 10261 insertions(+) create mode 100644 pnpm-lock.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..e2e525373 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,10261 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + +importers: + + .: + dependencies: + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@types/node': + specifier: ^22.13.9 + version: 22.13.9 + '@types/react': + specifier: ^18.3.18 + version: 18.3.18 + '@types/react-dom': + specifier: ^18.3.5 + version: 18.3.5(@types/react@18.3.18) + turbo: + specifier: 2.4.2 + version: 2.4.2 + + apps/common/features: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../../packages/common/assets + '@common/components': + specifier: workspace:* + version: link:../../../packages/common/components + '@common/config': + specifier: workspace:* + version: link:../../../packages/common/config + '@common/network': + specifier: workspace:* + version: link:../../../packages/common/network + '@fontsource-variable/noto-sans-kr': + specifier: ^5.2.5 + version: 5.2.5 + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@minoru/react-dnd-treeview': + specifier: ^3.5.0 + version: 3.5.0(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: ^5.75.5 + version: 5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + '@tinymce/tinymce-react': + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.3.1)(react@18.3.1) + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + next: + specifier: 15.3.0 + version: 15.3.0(react-dom@18.3.1)(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@faker-js/faker': + specifier: ^9.5.0 + version: 9.5.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.13.1 + version: 22.13.9 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + steiger: + specifier: ^0.5.5 + version: 0.5.5(typescript@5.6.3) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/cs: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@common/config': + specifier: workspace:* + version: link:../../packages/common/config + '@fontsource-variable/noto-sans-kr': + specifier: ^5.2.5 + version: 5.2.5 + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@fullcalendar/core': + specifier: ^6.1.17 + version: 6.1.17 + '@fullcalendar/daygrid': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17) + '@fullcalendar/interaction': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17) + '@fullcalendar/react': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17)(react-dom@18.3.1)(react@18.3.1) + '@fullcalendar/timegrid': + specifier: ^6.1.17 + version: 6.1.17(@fullcalendar/core@6.1.17) + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@minoru/react-dnd-treeview': + specifier: 3.5.1-alpha.1 + version: 3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: ^5.75.5 + version: 5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + '@tinymce/tinymce-react': + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.3.1)(react@18.3.1) + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + next: + specifier: 15.3.0 + version: 15.3.0(react-dom@18.3.1)(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@faker-js/faker': + specifier: ^9.5.0 + version: 9.5.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.13.1 + version: 22.13.5 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + steiger: + specifier: ^0.5.5 + version: 0.5.5(typescript@5.6.3) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/sn: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/business_components': + specifier: workspace:* + version: link:../../packages/common/business_components + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + next: + specifier: 15.1.7 + version: 15.1.7(react-dom@18.3.1)(react@18.3.1) + ol: + specifier: ^7.3.0 + version: 7.5.2 + ol-ext: + specifier: ^4.0.11 + version: 4.0.31(ol@7.5.2) + proj4: + specifier: ^2.9.0 + version: 2.15.0 + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@18.3.18)(react@18.3.1) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@faker-js/faker': + specifier: ^9.5.0 + version: 9.5.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.13.1 + version: 22.13.9 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + steiger: + specifier: ^0.5.5 + version: 0.5.5(typescript@5.6.3) + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + apps/wr: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../../packages/common/assets + '@common/business_components': + specifier: workspace:* + version: link:../../packages/common/business_components + '@common/components': + specifier: workspace:* + version: link:../../packages/common/components + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + i18next: + specifier: ^25.3.2 + version: 25.3.2(typescript@5.6.3) + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + moment: + specifier: ^2.30.1 + version: 2.30.1 + next: + specifier: 15.1.7 + version: 15.1.7(react-dom@18.3.1)(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + react-hot-toast: + specifier: ^2.5.2 + version: 2.5.2(react-dom@18.3.1)(react@18.3.1) + react-i18next: + specifier: ^15.6.0 + version: 15.6.0(i18next@25.3.2)(react-dom@18.3.1)(react@18.3.1)(typescript@5.6.3) + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + tus-js-client: + specifier: ^4.3.1 + version: 4.3.1 + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.0 + '@types/webpack': + specifier: ^5.28.5 + version: 5.28.5 + eslint: + specifier: ^9 + version: 9.21.0 + eslint-config-next: + specifier: 15.1.7 + version: 15.1.7(eslint@9.21.0)(typescript@5.6.3) + postcss: + specifier: ^8 + version: 8.5.3 + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.6.3 + + packages/common/assets: + devDependencies: + '@types/node': + specifier: ^20.11.0 + version: 20.17.19 + tsup: + specifier: ^8.0.1 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ^5.3.3 + version: 5.6.3 + + packages/common/business_components: + dependencies: + '@common/components': + specifier: workspace:* + version: link:../components + '@hookform/resolvers': + specifier: ^4.1.3 + version: 4.1.3(react-hook-form@7.54.2) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-scroll-area': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-select': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + axios: + specifier: 1.8.1 + version: 1.8.1 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^3.6.0 + version: 3.6.0 + libphonenumber-js: + specifier: ^1.12.9 + version: 1.12.9 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + path: + specifier: ^0.12.7 + version: 0.12.7 + react-day-picker: + specifier: ^8.10.1 + version: 8.10.1(date-fns@3.6.0)(react@18.3.1) + react-dropzone: + specifier: ^14.3.8 + version: 14.3.8(react@18.3.1) + react-hook-form: + specifier: ^7.54.2 + version: 7.54.2(react@18.3.1) + recharts: + specifier: ^2.15.1 + version: 2.15.1(react-dom@18.3.1)(react@18.3.1) + sonner: + specifier: ^2.0.1 + version: 2.0.1(react-dom@18.3.1)(react@18.3.1) + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + xlsx: + specifier: ^0.18.5 + version: 0.18.5 + xlsx-populate: + specifier: ^1.21.0 + version: 1.21.0 + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@eslint/js': + specifier: ^9.17.0 + version: 9.21.0 + '@storybook/addon-essentials': + specifier: ^8.5.3 + version: 8.6.0(@types/react@18.3.18)(storybook@8.6.0) + '@storybook/addon-interactions': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-onboarding': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-themes': + specifier: ^8.5.4 + version: 8.6.0(storybook@8.6.0) + '@storybook/blocks': + specifier: ^8.5.3 + version: 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/manager-api': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@storybook/react': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3) + '@storybook/react-vite': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3)(vite@6.2.0) + '@storybook/test': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/theming': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(vite@6.2.0) + '@xlsx/xlsx-populate': + specifier: ^0.0.8 + version: 0.0.8 + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.5.3) + eslint: + specifier: ^9.17.0 + version: 9.21.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.21.0) + eslint-plugin-react-refresh: + specifier: ^0.4.16 + version: 0.4.19(eslint@9.21.0) + eslint-plugin-storybook: + specifier: ^0.11.2 + version: 0.11.3(eslint@9.21.0)(typescript@5.6.3) + globals: + specifier: ^15.14.0 + version: 15.15.0 + postcss: + specifier: ^8.5.3 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + storybook: + specifier: ^8.5.3 + version: 8.6.0(prettier@3.5.2) + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + tsup: + specifier: 8.3.6 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.18.2 + version: 8.25.0(eslint@9.21.0)(typescript@5.6.3) + vite: + specifier: ^6.0.5 + version: 6.2.0(@types/node@22.13.9) + vite-tsconfig-paths: + specifier: 5.1.4 + version: 5.1.4(typescript@5.6.3)(vite@6.2.0) + + packages/common/components: + dependencies: + '@common/assets': + specifier: workspace:* + version: link:../assets + '@common/config': + specifier: workspace:* + version: link:../config + '@frontend-opensource/use-react-hooks': + specifier: ^1.1.4 + version: 1.1.4 + '@minoru/react-dnd-treeview': + specifier: ^3.5.0 + version: 3.5.0(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-accordion': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-checkbox': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collapsible': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dialog': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-popover': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-progress': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-radio-group': + specifier: ^1.2.2 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-scroll-area': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-select': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-separator': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slider': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-tabs': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-tooltip': + specifier: ^1.1.8 + version: 1.1.8(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-visually-hidden': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@tanstack/react-query': + specifier: ^5.67.1 + version: 5.67.1(react@18.3.1) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@18.3.1)(react@18.3.1) + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + axios: + specifier: ^1.8.1 + version: 1.8.1 + chart.js: + specifier: ^4.4.8 + version: 4.4.8 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^3.6.0 + version: 3.6.0 + embla-carousel-react: + specifier: ^8.6.0 + version: 8.6.0(react@18.3.1) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@18.3.1) + react-chartjs-2: + specifier: ^5.3.0 + version: 5.3.0(chart.js@4.4.8)(react@18.3.1) + react-day-picker: + specifier: ^8.10.1 + version: 8.10.1(date-fns@3.6.0)(react@18.3.1) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1) + react-dnd-html5-backend: + specifier: ^16.0.1 + version: 16.0.1 + tailwind-merge: + specifier: ^3.0.1 + version: 3.0.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + devDependencies: + '@eslint/js': + specifier: ^9.17.0 + version: 9.21.0 + '@faker-js/faker': + specifier: ^9.5.0 + version: 9.5.0 + '@storybook/addon-essentials': + specifier: ^8.5.3 + version: 8.6.0(@types/react@18.3.18)(storybook@8.6.0) + '@storybook/addon-interactions': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-onboarding': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/addon-themes': + specifier: ^8.5.4 + version: 8.6.0(storybook@8.6.0) + '@storybook/blocks': + specifier: ^8.5.3 + version: 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/manager-api': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@storybook/react': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3) + '@storybook/react-vite': + specifier: ^8.5.3 + version: 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3)(vite@6.2.0) + '@storybook/test': + specifier: ^8.5.3 + version: 8.6.0(storybook@8.6.0) + '@storybook/theming': + specifier: ^8.5.5 + version: 8.6.0(storybook@8.6.0) + '@types/node': + specifier: ^22.13.1 + version: 22.13.5 + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(vite@6.2.0) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.5.3) + eslint: + specifier: ^9.17.0 + version: 9.21.0 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.1.0(eslint@9.21.0) + eslint-plugin-react-refresh: + specifier: ^0.4.16 + version: 0.4.19(eslint@9.21.0) + eslint-plugin-storybook: + specifier: ^0.11.2 + version: 0.11.3(eslint@9.21.0)(typescript@5.6.3) + globals: + specifier: ^15.14.0 + version: 15.15.0 + postcss: + specifier: ^8.5.1 + version: 8.5.3 + prettier: + specifier: ^3.4.2 + version: 3.5.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.11(prettier@3.5.2) + storybook: + specifier: ^8.5.3 + version: 8.6.0(prettier@3.5.2) + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + tsup: + specifier: 8.3.6 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.18.2 + version: 8.25.0(eslint@9.21.0)(typescript@5.6.3) + vite: + specifier: ^6.0.5 + version: 6.2.0(@types/node@22.13.5) + vite-tsconfig-paths: + specifier: 5.1.4 + version: 5.1.4(typescript@5.6.3)(vite@6.2.0) + + packages/common/config: + devDependencies: + eslint: + specifier: ^9.8.0 + version: 9.21.0 + tsup: + specifier: ^8.2.3 + version: 8.3.6(postcss@8.5.3)(typescript@5.6.3) + typescript: + specifier: ^5.5.3 + version: 5.6.3 + vite: + specifier: ^5.3.5 + version: 5.4.18(@types/node@22.13.9) + + packages/common/network: + dependencies: + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + axios: + specifier: ^1.8.1 + version: 1.8.1 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + devDependencies: + '@types/node': + specifier: ^20.11.19 + version: 20.17.19 + typescript: + specifier: ^5.3.3 + version: 5.6.3 + +packages: + + /@adobe/css-tools@4.4.2: + resolution: {integrity: sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==} + dev: true + + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@babel/code-frame@7.26.2: + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + dev: true + + /@babel/compat-data@7.26.8: + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.26.9: + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.26.9: + resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + dev: true + + /@babel/helper-compilation-targets@7.26.5: + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-module-imports@7.25.9: + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9): + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-plugin-utils@7.26.5: + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-string-parser@7.25.9: + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.25.9: + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.25.9: + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.26.9: + resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + dev: true + + /@babel/parser@7.26.9: + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.26.9 + dev: true + + /@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9): + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + dev: true + + /@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.9): + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + dev: true + + /@babel/runtime@7.26.9: + resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + + /@babel/runtime@7.27.6: + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/template@7.26.9: + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + dev: true + + /@babel/traverse@7.26.9: + resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.26.9: + resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + dev: true + + /@clack/core@0.3.5: + resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + dev: true + + /@clack/prompts@0.8.2: + resolution: {integrity: sha512-6b9Ab2UiZwJYA9iMyboYyW9yJvAO9V753ZhS+DHKEjZRKAxPPOb7MXXu84lsPFG+vZt6FRFniZ8rXi+zCIw4yQ==} + dependencies: + '@clack/core': 0.3.5 + picocolors: 1.1.1 + sisteransi: 1.0.5 + dev: true + + /@dependents/detective-less@5.0.1: + resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} + engines: {node: '>=18'} + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.1 + dev: true + + /@emnapi/runtime@1.4.3: + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + requiresBuild: true + dependencies: + tslib: 2.8.1 + dev: false + optional: true + + /@esbuild/aix-ppc64@0.21.5: + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/aix-ppc64@0.24.2: + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/aix-ppc64@0.25.0: + resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.21.5: + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.24.2: + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.25.0: + resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.21.5: + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.24.2: + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.25.0: + resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.21.5: + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.24.2: + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.25.0: + resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.21.5: + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.24.2: + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.25.0: + resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.21.5: + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.24.2: + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.25.0: + resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.21.5: + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.24.2: + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.25.0: + resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.21.5: + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.24.2: + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.25.0: + resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.21.5: + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.24.2: + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.25.0: + resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.21.5: + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.24.2: + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.25.0: + resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.21.5: + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.24.2: + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.25.0: + resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.21.5: + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.24.2: + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.25.0: + resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.21.5: + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.24.2: + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.25.0: + resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.21.5: + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.24.2: + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.25.0: + resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.21.5: + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.24.2: + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.25.0: + resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.21.5: + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.24.2: + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.25.0: + resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.21.5: + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.24.2: + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.25.0: + resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-arm64@0.24.2: + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-arm64@0.25.0: + resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.21.5: + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.24.2: + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.25.0: + resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-arm64@0.24.2: + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-arm64@0.25.0: + resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.21.5: + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.24.2: + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.25.0: + resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.21.5: + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.24.2: + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.25.0: + resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.21.5: + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.24.2: + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.25.0: + resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.21.5: + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.24.2: + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.25.0: + resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.21.5: + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.24.2: + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.25.0: + resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.1(eslint@9.21.0): + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 9.21.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.12.1: + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/config-array@0.19.2: + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/core@0.12.0: + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@types/json-schema': 7.0.15 + dev: true + + /@eslint/eslintrc@3.3.0: + resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@9.21.0: + resolution: {integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/object-schema@2.1.6: + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/plugin-kit@0.2.7: + resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/core': 0.12.0 + levn: 0.4.1 + dev: true + + /@faker-js/faker@9.5.0: + resolution: {integrity: sha512-3qbjLv+fzuuCg3umxc9/7YjrEXNaKwHgmig949nfyaTx8eL4FAsvFbu+1JcFUj1YAXofhaDn6JdEUBTYuk0Ssw==} + engines: {node: '>=18.0.0', npm: '>=9.0.0'} + deprecated: Please update to a newer version + dev: true + + /@feature-sliced/filesystem@2.4.0: + resolution: {integrity: sha512-aOFdPACNvkFXYb+gNHId8UCRD5fm7Z9/RV6JgBPlgEvm1QtLS4idg2XeHMDGnHrNRCS4ki+0RauxVZxm+g9pvw==} + dependencies: + typescript: 5.6.3 + dev: true + + /@feature-sliced/steiger-plugin@0.5.4(typescript@5.6.3): + resolution: {integrity: sha512-QzkIQUqNq94fv7aV0GY8wKmlFij9CtSQEIV+/0ed33SZGrv1FjUaySO4eHPlSCcH3Y+fH9nnpTaULtqRwwT7sw==} + dependencies: + '@feature-sliced/filesystem': 2.4.0 + fastest-levenshtein: 1.0.16 + lodash-es: 4.17.21 + pluralize: 8.0.0 + precinct: 12.2.0 + tsconfck: 3.1.5(typescript@5.6.3) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@floating-ui/core@1.6.9: + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + dependencies: + '@floating-ui/utils': 0.2.9 + dev: false + + /@floating-ui/dom@1.6.13: + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + dependencies: + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + dev: false + + /@floating-ui/react-dom@2.1.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@floating-ui/dom': 1.6.13 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@floating-ui/utils@0.2.9: + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + dev: false + + /@fontsource-variable/noto-sans-kr@5.2.5: + resolution: {integrity: sha512-dIJyVPIBRJXtvaFmQ6GKCV93J9Fx3O2Ym5C3gDRcz5zLpEigrnlEfBnsXBUv4aDBHEF/gm/Q07d40dddGxFytg==} + dev: false + + /@frontend-opensource/use-react-hooks@1.1.4: + resolution: {integrity: sha512-otCSyciL5MVCNNYmdDdg2lEL6rbZ3XX1meYQCzapUSC4V6qx2YxMk1kUbhwEM/+vdxhYzBHsVBGD0rZWl5cgrw==} + dependencies: + async-wave: 1.8.6 + fast-deep-equal: 3.1.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@fullcalendar/core@6.1.17: + resolution: {integrity: sha512-0W7lnIrv18ruJ5zeWBeNZXO8qCWlzxDdp9COFEsZnyNjiEhUVnrW/dPbjRKYpL0edGG0/Lhs0ghp1z/5ekt8ZA==} + dependencies: + preact: 10.12.1 + dev: false + + /@fullcalendar/daygrid@6.1.17(@fullcalendar/core@6.1.17): + resolution: {integrity: sha512-K7m+pd7oVJ9fW4h7CLDdDGJbc9szJ1xDU1DZ2ag+7oOo1aCNLv44CehzkkknM6r8EYlOOhgaelxQpKAI4glj7A==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + dependencies: + '@fullcalendar/core': 6.1.17 + dev: false + + /@fullcalendar/interaction@6.1.17(@fullcalendar/core@6.1.17): + resolution: {integrity: sha512-AudvQvgmJP2FU89wpSulUUjeWv24SuyCx8FzH2WIPVaYg+vDGGYarI7K6PcM3TH7B/CyaBjm5Rqw9lXgnwt5YA==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + dependencies: + '@fullcalendar/core': 6.1.17 + dev: false + + /@fullcalendar/react@6.1.17(@fullcalendar/core@6.1.17)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-AA8soHhlfRH5dUeqHnfAtzDiXa2vrgWocJSK/F5qzw/pOxc9MqpuoS/nQBROWtHHg6yQUg3DoGqOOhi7dmylXQ==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@fullcalendar/core': 6.1.17 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@fullcalendar/timegrid@6.1.17(@fullcalendar/core@6.1.17): + resolution: {integrity: sha512-K4PlA3L3lclLOs3IX8cvddeiJI9ZVMD7RA9IqaWwbvac771971foc9tFze9YY+Pqesf6S+vhS2dWtEVlERaGlQ==} + peerDependencies: + '@fullcalendar/core': ~6.1.17 + dependencies: + '@fullcalendar/core': 6.1.17 + '@fullcalendar/daygrid': 6.1.17(@fullcalendar/core@6.1.17) + dev: false + + /@hookform/resolvers@4.1.3(react-hook-form@7.54.2): + resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==} + peerDependencies: + react-hook-form: ^7.0.0 + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.54.2(react@18.3.1) + dev: false + + /@humanfs/core@0.19.1: + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + dev: true + + /@humanfs/node@0.16.6: + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/retry@0.3.1: + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + dev: true + + /@humanwhocodes/retry@0.4.2: + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + dev: true + + /@img/sharp-darwin-arm64@0.33.5: + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-darwin-arm64@0.34.1: + resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.33.5: + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.34.1: + resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.0.4: + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.1.0: + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.0.4: + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.1.0: + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.0.4: + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.1.0: + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.0.5: + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.1.0: + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-ppc64@1.1.0: + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.0.4: + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.1.0: + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.0.4: + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.1.0: + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.0.4: + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.1.0: + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.0.4: + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.1.0: + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-linux-arm64@0.33.5: + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linux-arm64@0.34.1: + resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + dev: false + optional: true + + /@img/sharp-linux-arm@0.33.5: + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + dev: false + optional: true + + /@img/sharp-linux-arm@0.34.1: + resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + dev: false + optional: true + + /@img/sharp-linux-s390x@0.33.5: + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + dev: false + optional: true + + /@img/sharp-linux-s390x@0.34.1: + resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + dev: false + optional: true + + /@img/sharp-linux-x64@0.33.5: + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linux-x64@0.34.1: + resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + dev: false + optional: true + + /@img/sharp-linuxmusl-arm64@0.33.5: + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linuxmusl-arm64@0.34.1: + resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + dev: false + optional: true + + /@img/sharp-linuxmusl-x64@0.33.5: + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-linuxmusl-x64@0.34.1: + resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + dev: false + optional: true + + /@img/sharp-wasm32@0.33.5: + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 1.4.3 + dev: false + optional: true + + /@img/sharp-wasm32@0.34.1: + resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 1.4.3 + dev: false + optional: true + + /@img/sharp-win32-ia32@0.33.5: + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-ia32@0.34.1: + resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.33.5: + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.34.1: + resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + + /@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.6.3)(vite@6.2.0): + resolution: {integrity: sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + glob: 10.4.5 + magic-string: 0.27.0 + react-docgen-typescript: 2.2.2(typescript@5.6.3) + typescript: 5.6.3 + vite: 6.2.0(@types/node@22.13.9) + dev: true + + /@jridgewell/gen-mapping@0.3.8: + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + /@jridgewell/source-map@0.3.6: + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + /@juggle/resize-observer@3.4.0: + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + dev: false + + /@kurkle/color@0.3.4: + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + dev: false + + /@mapbox/jsonlint-lines-primitives@2.0.2: + resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} + engines: {node: '>= 0.6'} + dev: false + + /@mapbox/mapbox-gl-style-spec@13.28.0: + resolution: {integrity: sha512-B8xM7Fp1nh5kejfIl4SWeY0gtIeewbuRencqO3cJDrCHZpaPg7uY+V8abuR+esMeuOjRl5cLhVTP40v+1ywxbg==} + hasBin: true + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/point-geometry': 0.1.0 + '@mapbox/unitbezier': 0.0.0 + csscolorparser: 1.0.3 + json-stringify-pretty-compact: 2.0.0 + minimist: 1.2.8 + rw: 1.3.3 + sort-object: 0.3.2 + dev: false + + /@mapbox/point-geometry@0.1.0: + resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==} + dev: false + + /@mapbox/unitbezier@0.0.0: + resolution: {integrity: sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==} + dev: false + + /@mdx-js/react@3.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.3.18 + react: 18.3.1 + dev: true + + /@minoru/react-dnd-treeview@3.5.0(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-kDHGQ0UK18w6ie5EH68NynATSP9BAzNLmWBXuVSoaGkraWWFdEdAWqQxAZiMorAixFu40MzYkn2N9/Gam6q17w==} + peerDependencies: + react: ^18.3.1 + react-dnd: 15.x || 16.x + react-dom: ^18.3.1 + dependencies: + '@juggle/resize-observer': 3.4.0 + dnd-multi-backend: 8.1.2(dnd-core@16.0.1) + framer-motion: 11.18.2(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dnd: 16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1) + react-dnd-html5-backend: 16.0.1 + react-dnd-touch-backend: 16.0.1 + react-dom: 18.3.1(react@18.3.1) + react-use-measure: 2.1.7(react-dom@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - dnd-core + dev: false + + /@minoru/react-dnd-treeview@3.5.1-alpha.1(dnd-core@16.0.1)(react-dnd@16.0.1)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-XEKBjhyltG0gzn+ioZRwhlV7+Q/uVZqTMS/tAO3On/rPNuNgqWHROFsyGdHQS/DYoENGOG8JX03chCxExOgEpA==} + peerDependencies: + react: ^18.3.1 + react-dnd: 15.x || 16.x + react-dom: ^18.3.1 + dependencies: + '@juggle/resize-observer': 3.4.0 + dnd-multi-backend: 8.1.2(dnd-core@16.0.1) + framer-motion: 11.18.2(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dnd: 16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1) + react-dnd-html5-backend: 16.0.1 + react-dnd-touch-backend: 16.0.1 + react-dom: 18.3.1(react@18.3.1) + react-use-measure: 2.1.7(react-dom@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - dnd-core + dev: false + + /@next/env@15.1.7: + resolution: {integrity: sha512-d9jnRrkuOH7Mhi+LHav2XW91HOgTAWHxjMPkXMGBc9B2b7614P7kjt8tAplRvJpbSt4nbO1lugcT/kAaWzjlLQ==} + dev: false + + /@next/env@15.3.0: + resolution: {integrity: sha512-6mDmHX24nWlHOlbwUiAOmMyY7KELimmi+ed8qWcJYjqXeC+G6JzPZ3QosOAfjNwgMIzwhXBiRiCgdh8axTTdTA==} + dev: false + + /@next/eslint-plugin-next@15.1.7: + resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} + dependencies: + fast-glob: 3.3.1 + dev: true + + /@next/swc-darwin-arm64@15.1.7: + resolution: {integrity: sha512-hPFwzPJDpA8FGj7IKV3Yf1web3oz2YsR8du4amKw8d+jAOHfYHYFpMkoF6vgSY4W6vB29RtZEklK9ayinGiCmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-arm64@15.3.0: + resolution: {integrity: sha512-PDQcByT0ZfF2q7QR9d+PNj3wlNN4K6Q8JoHMwFyk252gWo4gKt7BF8Y2+KBgDjTFBETXZ/TkBEUY7NIIY7A/Kw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@15.1.7: + resolution: {integrity: sha512-2qoas+fO3OQKkU0PBUfwTiw/EYpN+kdAx62cePRyY1LqKtP09Vp5UcUntfZYajop5fDFTjSxCHfZVRxzi+9FYQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@15.3.0: + resolution: {integrity: sha512-m+eO21yg80En8HJ5c49AOQpFDq+nP51nu88ZOMCorvw3g//8g1JSUsEiPSiFpJo1KCTQ+jm9H0hwXK49H/RmXg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@15.1.7: + resolution: {integrity: sha512-sKLLwDX709mPdzxMnRIXLIT9zaX2w0GUlkLYQnKGoXeWUhcvpCrK+yevcwCJPdTdxZEUA0mOXGLdPsGkudGdnA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@15.3.0: + resolution: {integrity: sha512-H0Kk04ZNzb6Aq/G6e0un4B3HekPnyy6D+eUBYPJv9Abx8KDYgNMWzKt4Qhj57HXV3sTTjsfc1Trc1SxuhQB+Tg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@15.1.7: + resolution: {integrity: sha512-zblK1OQbQWdC8fxdX4fpsHDw+VSpBPGEUX4PhSE9hkaWPrWoeIJn+baX53vbsbDRaDKd7bBNcXRovY1hEhFd7w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@15.3.0: + resolution: {integrity: sha512-k8GVkdMrh/+J9uIv/GpnHakzgDQhrprJ/FbGQvwWmstaeFG06nnAoZCJV+wO/bb603iKV1BXt4gHG+s2buJqZA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@15.1.7: + resolution: {integrity: sha512-GOzXutxuLvLHFDAPsMP2zDBMl1vfUHHpdNpFGhxu90jEzH6nNIgmtw/s1MDwpTOiM+MT5V8+I1hmVFeAUhkbgQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@15.3.0: + resolution: {integrity: sha512-ZMQ9yzDEts/vkpFLRAqfYO1wSpIJGlQNK9gZ09PgyjBJUmg8F/bb8fw2EXKgEaHbCc4gmqMpDfh+T07qUphp9A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@15.1.7: + resolution: {integrity: sha512-WrZ7jBhR7ATW1z5iEQ0ZJfE2twCNSXbpCSaAunF3BKcVeHFADSI/AW1y5Xt3DzTqPF1FzQlwQTewqetAABhZRQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@15.3.0: + resolution: {integrity: sha512-RFwq5VKYTw9TMr4T3e5HRP6T4RiAzfDJ6XsxH8j/ZeYq2aLsBqCkFzwMI0FmnSsLaUbOb46Uov0VvN3UciHX5A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@15.1.7: + resolution: {integrity: sha512-LDnj1f3OVbou1BqvvXVqouJZKcwq++mV2F+oFHptToZtScIEnhNRJAhJzqAtTE2dB31qDYL45xJwrc+bLeKM2Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@15.3.0: + resolution: {integrity: sha512-a7kUbqa/k09xPjfCl0RSVAvEjAkYBYxUzSVAzk2ptXiNEL+4bDBo9wNC43G/osLA/EOGzG4CuNRFnQyIHfkRgQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@15.1.7: + resolution: {integrity: sha512-dC01f1quuf97viOfW05/K8XYv2iuBgAxJZl7mbCKEjMgdQl5JjAKJ0D2qMKZCgPWDeFbFT0Q0nYWwytEW0DWTQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@15.3.0: + resolution: {integrity: sha512-vHUQS4YVGJPmpjn7r5lEZuMhK5UQBNBRSB+iGDvJjaNk649pTIcRluDWNb9siunyLLiu/LDPHfvxBtNamyuLTw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + /@nolyfill/is-core-module@1.0.39: + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + dev: true + + /@petamoriken/float16@3.9.2: + resolution: {integrity: sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==} + dev: false + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + optional: true + + /@radix-ui/number@1.1.0: + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + dev: false + + /@radix-ui/primitive@1.1.1: + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + dev: false + + /@radix-ui/react-accordion@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collapsible': 1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-checkbox@1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-collapsible@1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-context@1.1.1(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-dialog@1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-direction@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-menu': 2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-icons@1.3.2(react@18.3.1): + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^18.3.1 + dependencies: + react: 18.3.1 + dev: false + + /@radix-ui/react-id@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-label@2.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-menu@2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/rect': 1.1.0 + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-progress@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-scroll-area@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-select@2.1.6(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /@radix-ui/react-separator@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-slider@1.2.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-nNrLAWLjGESnhqBqcCNW4w2nn7LxudyMzeB6VgdyAnFLC6kfQgnAjSL2v6UkQTnDctJBlxrmxfplWS4iYjdUTw==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-slot@1.1.2(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-switch@1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-tabs@1.1.3(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-tooltip@1.1.8(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-previous@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-rect@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/rect': 1.1.0 + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-use-size@1.1.0(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + react: 18.3.1 + dev: false + + /@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==} + peerDependencies: + '@types/react': ^18.3.18 + '@types/react-dom': ^18.3.5 + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-dom': 18.3.5(@types/react@18.3.18) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/rect@1.1.0: + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + dev: false + + /@react-dnd/asap@5.0.2: + resolution: {integrity: sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==} + dev: false + + /@react-dnd/invariant@4.0.2: + resolution: {integrity: sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==} + dev: false + + /@react-dnd/shallowequal@4.0.2: + resolution: {integrity: sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==} + dev: false + + /@rollup/pluginutils@5.1.4: + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + dev: true + + /@rollup/rollup-android-arm-eabi@4.34.8: + resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.34.8: + resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.34.8: + resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.34.8: + resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-freebsd-arm64@4.34.8: + resolution: {integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-freebsd-x64@4.34.8: + resolution: {integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.34.8: + resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.34.8: + resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.34.8: + resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.34.8: + resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-loongarch64-gnu@4.34.8: + resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-powerpc64le-gnu@4.34.8: + resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.34.8: + resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.34.8: + resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.34.8: + resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.34.8: + resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.34.8: + resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.34.8: + resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.34.8: + resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rtsao/scc@1.1.0: + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + dev: true + + /@rushstack/eslint-patch@1.10.5: + resolution: {integrity: sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==} + dev: true + + /@sindresorhus/merge-streams@2.3.0: + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + dev: true + + /@standard-schema/utils@0.3.0: + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + dev: false + + /@storybook/addon-actions@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-lI03stcI28wN8trjp7zx0PzN1NRxSpU/551slzEhSM0tghcLxcfLZR/wh4Jp0T68Obj7z//YXPttZ9PBFajs6w==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 8.6.0(prettier@3.5.2) + uuid: 9.0.1 + dev: true + + /@storybook/addon-backgrounds@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-MbMPjuC19jJBXqQext8rENBACLKujDn+MuxIbNYMmn2ljzeYFp87tVxzlCB7XY7rV0zvkHxH8N/zDnPl7pBTcQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-controls@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-oc+mssxmNY+D26jyJ+IZ1u8bmzveCO2wqpUl6vtLM5MruchZAHzHqa2ZIn+H9KOEqcKlYVDF5n6oEuprcnrsdg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + dequal: 2.0.3 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-docs@8.6.0(@types/react@18.3.18)(storybook@8.6.0): + resolution: {integrity: sha512-ytYn5ec2Tp62t9emjXgm4Ds+eG7SiSg/vNeOwM6L1lM2UCV2/XdzntbqlUb/FHehSXIv9eRJDSe5BBzPieUUaw==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@mdx-js/react': 3.1.0(@types/react@18.3.18)(react@18.3.1) + '@storybook/blocks': 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/csf-plugin': 8.6.0(storybook@8.6.0) + '@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@storybook/addon-essentials@8.6.0(@types/react@18.3.18)(storybook@8.6.0): + resolution: {integrity: sha512-T3R9Q1hq6eJKy758gQgYEuAYxcddGZ8eGBLIyIJEgzpwsUnN5mF+rIqx8LoWxpWu/xiKzg17LqCBnJbLGkRZUA==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/addon-actions': 8.6.0(storybook@8.6.0) + '@storybook/addon-backgrounds': 8.6.0(storybook@8.6.0) + '@storybook/addon-controls': 8.6.0(storybook@8.6.0) + '@storybook/addon-docs': 8.6.0(@types/react@18.3.18)(storybook@8.6.0) + '@storybook/addon-highlight': 8.6.0(storybook@8.6.0) + '@storybook/addon-measure': 8.6.0(storybook@8.6.0) + '@storybook/addon-outline': 8.6.0(storybook@8.6.0) + '@storybook/addon-toolbars': 8.6.0(storybook@8.6.0) + '@storybook/addon-viewport': 8.6.0(storybook@8.6.0) + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + dev: true + + /@storybook/addon-highlight@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-xgSUzNV8ZpNDJ35bLz7wfg/q7/O/C5845wbZsn+PobUOWpOMOKeZwbGkO3Fh4+CWKeFuMhUpFiZSWkNgT+bV0g==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/addon-interactions@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-AgobFrUxmKgGHKeOismuLZdXlndP3ZDquHztiomfMiu01xOqNPxG0+xoCcegvftU7hKE+TlBRzhjCWg/bFz4LQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.0(storybook@8.6.0) + '@storybook/test': 8.6.0(storybook@8.6.0) + polished: 4.3.1 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-measure@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-ogc+VNLyXq8hGfI4Fkmh9i3JbxfiIViiINdBoldD6K0gId3yaqqrSwQ2vWhYIbfUuz+PsMxsoNS7MD4EiRXhPg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.0(prettier@3.5.2) + tiny-invariant: 1.3.3 + dev: true + + /@storybook/addon-onboarding@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-UOOvYQlHKdY31YJwR+ECX7e/BNuhp4alcJmx1fuI7m6tXqTGLtioeMJEreh2jV3FDaaDqL4DL/1UfYXqNRMp+A==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/addon-outline@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-IWxrNNZOk5rtOdnLNyK7gpqi0g0rMGYl5ju37Glbfa7iG2J1VKofG2CbkUpVyVY0uiTXqkKkhOKlc9zELhLQSg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-themes@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-dKUjFgHP9Fd2fxrXcUUjev5X3cGqVvVogzh+nCRA/QlZgf3NzA8J2VPtqtFMX3ex+vaozGsrEKrk+LQTK1B7SA==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-toolbars@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-Mg0V9RrnDt/IQe+zjggGS+4Otkv4YFqyjL/ygwnV6aKGgzL5zFpC+5rf8MeBEvNeol9+THC/XltN/Xf+jbtLEQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/addon-viewport@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-sVDF3gIjGdvfBdCM/jEBu6Nd5GlqITKBtdySiQdNDl5JI4ak77ZM+T+VQmJxB4sIqvCjWzCbQqUC45nymVObug==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + memoizerific: 1.11.3 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/blocks@8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0): + resolution: {integrity: sha512-3PNxlB5Ooj8CIhttbDxeV6kW7ui+2GEdTngtqhnsUHVjzeTKpilsk2lviOeUzqlyq5FDK+rhpZ3L3DJ9pDvioA==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/icons': 1.3.2(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + dev: true + + /@storybook/builder-vite@8.6.0(storybook@8.6.0)(vite@6.2.0): + resolution: {integrity: sha512-Bdc5fXLJbPdQo2eJ3dDNhfhWuQOME2KWvrixnsfo57IOhDa5B81jVcDBQIIgB9K1NQDRGyaWfYCcKZqy16yPlQ==} + peerDependencies: + storybook: ^8.6.0 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + dependencies: + '@storybook/csf-plugin': 8.6.0(storybook@8.6.0) + browser-assert: 1.2.1 + storybook: 8.6.0(prettier@3.5.2) + ts-dedent: 2.2.0 + vite: 6.2.0(@types/node@22.13.9) + dev: true + + /@storybook/components@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-k5MQAuLPt5KOaa5J4QvX/WKucaiFTMJiEX5lsSaY6qON6Sx8PtnLQxVwWF7BIMW/jLpd94BUxrVjVrQKlwoLKQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/core@8.6.0(prettier@3.5.2)(storybook@8.6.0): + resolution: {integrity: sha512-UzVo2sNz8PZuDp++/R9NBtjupSXhvxS8lptYcwtk51b6MvcM4AL/b4V3PGryOVJDru9sMwz+pzaj7Jg8RVFMJA==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + dependencies: + '@storybook/theming': 8.6.0(storybook@8.6.0) + better-opn: 3.0.2 + browser-assert: 1.2.1 + esbuild: 0.25.0 + esbuild-register: 3.6.0(esbuild@0.25.0) + jsdoc-type-pratt-parser: 4.1.0 + prettier: 3.5.2 + process: 0.11.10 + recast: 0.23.10 + semver: 7.7.1 + util: 0.12.5 + ws: 8.18.1 + transitivePeerDependencies: + - bufferutil + - storybook + - supports-color + - utf-8-validate + dev: true + + /@storybook/csf-plugin@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-Cd7LL4XQ8ccUDzJGxVyuzgsYuRYS5LVL4/ZNmAxikz9LtVrVFI/4RgFa5MvlQZc0twreoLtztFskziny8OiJUQ==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + unplugin: 1.16.1 + dev: true + + /@storybook/csf@0.1.13: + resolution: {integrity: sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==} + dependencies: + type-fest: 2.19.0 + dev: true + + /@storybook/global@5.0.0: + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + dev: true + + /@storybook/icons@1.3.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-t3xcbCKkPvqyef8urBM0j/nP6sKtnlRkVgC+8JTbTAZQjaTmOjes3byEgzs89p4B/K6cJsg9wLW2k3SknLtYJw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: true + + /@storybook/instrumenter@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-eEY/Hfa3Vj5Nv4vHRHlSqjoyW6oAKNK3rKIXfL/eawQwb7rKhzijDLG5YBH44Hh7dEPIqUp0LEdgpyIY7GXezg==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.9 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/manager-api@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-ddBibYrO3yQCdtZBqQYqfABjR9eS+llvt2NFDajfyQw+zmuNIZfw4BDGKH1WHE4wm/kXmlFFhPHXaHgAPTRPfQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/preview-api@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-c/sZj4Tb+DtdCndcjoFUneUwl2XUdQckqN4nf1SuIJ/BXRbAexlD04fvPJ4wzmwUNg8EQF7BhTWVNDa1RvJz2w==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/react-dom-shim@8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0): + resolution: {integrity: sha512-5Y+vMHhcx0xnaNsLQMbkmjc3zkDn/fGBNsiLH2e4POvW3ZQvOxjoyxAsEQaKwLtFgsdCFSd2tR89F6ItYrA2JQ==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/react-vite@8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3)(vite@6.2.0): + resolution: {integrity: sha512-uDQyf2u0Zki4qIavOu2jyGIlvmUOsgCpHXY+7KHr542ZIkXI3mGOi5/rwUxgNSHGD3JloYGdlt+4Md+9i5xEbA==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.6.0 + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + '@storybook/test': + optional: true + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.6.3)(vite@6.2.0) + '@rollup/pluginutils': 5.1.4 + '@storybook/builder-vite': 8.6.0(storybook@8.6.0)(vite@6.2.0) + '@storybook/react': 8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3) + '@storybook/test': 8.6.0(storybook@8.6.0) + find-up: 5.0.0 + magic-string: 0.30.17 + react: 18.3.1 + react-docgen: 7.1.1 + react-dom: 18.3.1(react@18.3.1) + resolve: 1.22.10 + storybook: 8.6.0(prettier@3.5.2) + tsconfig-paths: 4.2.0 + vite: 6.2.0(@types/node@22.13.9) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + dev: true + + /@storybook/react@8.6.0(@storybook/test@8.6.0)(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0)(typescript@5.6.3): + resolution: {integrity: sha512-go0KhCFcOhxkTdaMCxeuJxmc/5CaiaO76+SBzIoPIMWEh9tZQmKb+vojdKcFZswHjZV3zA1uJFUzyympspRffA==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.6.0 + react: ^18.3.1 + react-dom: ^18.3.1 + storybook: ^8.6.0 + typescript: '>= 4.2.x' + peerDependenciesMeta: + '@storybook/test': + optional: true + typescript: + optional: true + dependencies: + '@storybook/components': 8.6.0(storybook@8.6.0) + '@storybook/global': 5.0.0 + '@storybook/manager-api': 8.6.0(storybook@8.6.0) + '@storybook/preview-api': 8.6.0(storybook@8.6.0) + '@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1)(react@18.3.1)(storybook@8.6.0) + '@storybook/test': 8.6.0(storybook@8.6.0) + '@storybook/theming': 8.6.0(storybook@8.6.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.6.0(prettier@3.5.2) + typescript: 5.6.3 + dev: true + + /@storybook/test@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-qiiv4wh4FoxTb1PoiA/noo9HcLDqfTwL0svMoNpTy2Bxm6xajgg5zYmmIT4pKyQkMd9pfKKQKILok31VxAj8vw==} + peerDependencies: + storybook: ^8.6.0 + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.0(storybook@8.6.0) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@storybook/theming@8.6.0(storybook@8.6.0): + resolution: {integrity: sha512-te7dl0ZXnEyKS4LW+QHc3MP7nurWhWhmClY7G2WKNW9eHenb9zvXkcAQt6c4OWhrJi01CAYoXmZNJP0jEzxRRQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + dependencies: + storybook: 8.6.0(prettier@3.5.2) + dev: true + + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.15: + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + dependencies: + tslib: 2.8.1 + dev: false + + /@tanstack/query-core@5.67.1: + resolution: {integrity: sha512-AkFmuukVejyqVIjEQoFhLb3q+xHl7JG8G9cANWTMe3s8iKzD9j1VBSYXgCjy6vm6xM8cUCR9zP2yqWxY9pTWOA==} + dev: false + + /@tanstack/query-devtools@5.74.7: + resolution: {integrity: sha512-nSNlfuGdnHf4yB0S+BoNYOE1o3oAH093weAYZolIHfS2stulyA/gWfSk/9H4ZFk5mAAHb5vNqAeJOmbdcGPEQw==} + dev: false + + /@tanstack/react-query-devtools@5.75.5(@tanstack/react-query@5.67.1)(react@18.3.1): + resolution: {integrity: sha512-S31U00nJOQIbxydRH1kOwdLRaLBrda8O5QjzmgkRg60UZzPGdbI6+873Qa0YGUfPeILDbR2ukgWyg7CJQPy4iA==} + peerDependencies: + '@tanstack/react-query': ^5.75.5 + react: ^18.3.1 + dependencies: + '@tanstack/query-devtools': 5.74.7 + '@tanstack/react-query': 5.67.1(react@18.3.1) + react: 18.3.1 + dev: false + + /@tanstack/react-query@5.67.1(react@18.3.1): + resolution: {integrity: sha512-fH5u4JLwB6A+wLFdi8wWBWAYoJV5deYif2OveJ26ktAWjU499uvVFS1wPWnyEyq5LvZX1MZInvv9QRaIZANRaQ==} + peerDependencies: + react: ^18.3.1 + dependencies: + '@tanstack/query-core': 5.67.1 + react: 18.3.1 + dev: false + + /@tanstack/react-table@8.21.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==} + engines: {node: '>=12'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@tanstack/table-core': 8.21.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@tanstack/table-core@8.21.2: + resolution: {integrity: sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==} + engines: {node: '>=12'} + dev: false + + /@testing-library/dom@10.4.0: + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.9 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + dev: true + + /@testing-library/jest-dom@6.5.0: + resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + dependencies: + '@adobe/css-tools': 4.4.2 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + dev: true + + /@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0): + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + dependencies: + '@testing-library/dom': 10.4.0 + dev: true + + /@tinymce/tinymce-react@6.1.0(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-K0MP3yYVKe8+etUwsg6zyRq+q9TGLaVf005WiBHiB8JZEomAwbBPERGunhU9uOqNQ5gJs8yVOPZ68Xcd1UHclA==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + tinymce: ^7.0.0 || ^6.0.0 || ^5.5.1 + peerDependenciesMeta: + tinymce: + optional: true + dependencies: + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@types/aria-query@5.0.4: + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + dev: true + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + dev: true + + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.26.9 + dev: true + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + dev: true + + /@types/babel__traverse@7.20.6: + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + dependencies: + '@babel/types': 7.26.9 + dev: true + + /@types/d3-array@3.2.1: + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + dev: false + + /@types/d3-color@3.1.3: + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + dev: false + + /@types/d3-ease@3.0.2: + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + dev: false + + /@types/d3-interpolate@3.0.4: + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + dependencies: + '@types/d3-color': 3.1.3 + dev: false + + /@types/d3-path@3.1.1: + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + dev: false + + /@types/d3-scale@4.0.9: + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + dependencies: + '@types/d3-time': 3.0.4 + dev: false + + /@types/d3-shape@3.1.7: + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + dependencies: + '@types/d3-path': 3.1.1 + dev: false + + /@types/d3-time@3.0.4: + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + dev: false + + /@types/d3-timer@3.0.2: + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + dev: false + + /@types/doctrine@0.0.9: + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + dev: true + + /@types/eslint-scope@3.7.7: + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.6 + dev: true + + /@types/eslint@9.6.1: + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + dependencies: + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + dev: true + + /@types/estree@1.0.6: + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + dev: true + + /@types/js-cookie@3.0.6: + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/mdx@2.0.13: + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + dev: true + + /@types/node@20.17.19: + resolution: {integrity: sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==} + dependencies: + undici-types: 6.19.8 + dev: true + + /@types/node@22.13.5: + resolution: {integrity: sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==} + dependencies: + undici-types: 6.20.0 + + /@types/node@22.13.9: + resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==} + dependencies: + undici-types: 6.20.0 + + /@types/prop-types@15.7.14: + resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + + /@types/react-dom@18.3.5(@types/react@18.3.18): + resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + peerDependencies: + '@types/react': ^18.3.18 + dependencies: + '@types/react': 18.3.18 + + /@types/react@18.3.18: + resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + + /@types/resolve@1.20.6: + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + dev: true + + /@types/uuid@9.0.8: + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + dev: true + + /@types/webpack@5.28.5: + resolution: {integrity: sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw==} + dependencies: + '@types/node': 22.13.9 + tapable: 2.2.1 + webpack: 5.98.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + - webpack-cli + dev: true + + /@typescript-eslint/eslint-plugin@8.25.0(@typescript-eslint/parser@8.25.0)(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/type-utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.25.0 + eslint: 9.21.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.0.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + eslint: 9.21.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@8.25.0: + resolution: {integrity: sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + dev: true + + /@typescript-eslint/type-utils@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + debug: 4.4.0 + eslint: 9.21.0 + ts-api-utils: 2.0.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@8.25.0: + resolution: {integrity: sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@typescript-eslint/typescript-estree@8.25.0(typescript@5.6.3): + resolution: {integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree@8.25.0(typescript@5.7.3): + resolution: {integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.6.3) + eslint: 9.21.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/visitor-keys@8.25.0: + resolution: {integrity: sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@typescript-eslint/types': 8.25.0 + eslint-visitor-keys: 4.2.0 + dev: true + + /@vitejs/plugin-react@4.3.4(vite@6.2.0): + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + dependencies: + '@babel/core': 7.26.9 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 6.2.0(@types/node@22.13.9) + transitivePeerDependencies: + - supports-color + dev: true + + /@vitest/expect@2.0.5: + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.2.0 + tinyrainbow: 1.2.0 + dev: true + + /@vitest/pretty-format@2.0.5: + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + dependencies: + tinyrainbow: 1.2.0 + dev: true + + /@vitest/pretty-format@2.1.9: + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + dependencies: + tinyrainbow: 1.2.0 + dev: true + + /@vitest/spy@2.0.5: + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + dependencies: + tinyspy: 3.0.2 + dev: true + + /@vitest/utils@2.0.5: + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + dev: true + + /@vitest/utils@2.1.9: + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + dev: true + + /@vue/compiler-core@3.5.13: + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + dependencies: + '@babel/parser': 7.26.9 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-dom@3.5.13: + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + dev: true + + /@vue/compiler-sfc@3.5.13: + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + dependencies: + '@babel/parser': 7.26.9 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.3 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-ssr@3.5.13: + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + dev: true + + /@vue/shared@3.5.13: + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + dev: true + + /@webassemblyjs/ast@1.14.1: + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + dev: true + + /@webassemblyjs/floating-point-hex-parser@1.13.2: + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + dev: true + + /@webassemblyjs/helper-api-error@1.13.2: + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + dev: true + + /@webassemblyjs/helper-buffer@1.14.1: + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + dev: true + + /@webassemblyjs/helper-numbers@1.13.2: + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode@1.13.2: + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + dev: true + + /@webassemblyjs/helper-wasm-section@1.14.1: + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + dev: true + + /@webassemblyjs/ieee754@1.13.2: + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128@1.13.2: + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8@1.13.2: + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + dev: true + + /@webassemblyjs/wasm-edit@1.14.1: + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + dev: true + + /@webassemblyjs/wasm-gen@1.14.1: + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + dev: true + + /@webassemblyjs/wasm-opt@1.14.1: + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + dev: true + + /@webassemblyjs/wasm-parser@1.14.1: + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + dev: true + + /@webassemblyjs/wast-printer@1.14.1: + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + dev: true + + /@xlsx/xlsx-populate@0.0.8: + resolution: {integrity: sha512-6yu24ePaO3cnAuti77FhVPZvKkzUt6s6x3zJ9wiuBSjR0ImWu7l/SgePelZaf8Oty4SP4rg4vznQVCGQtfzu2A==} + engines: {node: '>=16'} + dev: true + + /@xtuc/ieee754@1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long@4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + + /acorn-jsx@5.3.2(acorn@8.14.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.14.0 + dev: true + + /acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + dev: false + + /ajv-formats@2.1.1(ajv@8.17.1): + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.17.1 + dev: true + + /ajv-keywords@5.1.0(ajv@8.17.1): + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + dependencies: + tslib: 2.8.1 + dev: false + + /aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + dependencies: + dequal: 2.0.3 + dev: true + + /aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + dev: true + + /array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + is-array-buffer: 3.0.5 + dev: true + + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + dev: true + + /array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + dev: true + + /arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + dev: true + + /assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + dev: true + + /ast-module-types@6.0.1: + resolution: {integrity: sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==} + engines: {node: '>=18'} + dev: true + + /ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + dev: true + + /ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.8.1 + dev: true + + /async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + dev: true + + /async-wave@1.8.6: + resolution: {integrity: sha512-wqWvr0Mrc1TrY92hN9MV0Xebxa6kt+T7QtjZ7FEMv+RUBa/Hfpz/UOgz0rB+7uqVK8TuBSXykOyU/k9gogdLkw==} + dependencies: + is-promise: 4.0.0 + lodash.add: 3.7.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + lodash.isfunction: 3.0.9 + lodash.size: 4.2.0 + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /attr-accept@2.2.5: + resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==} + engines: {node: '>=4'} + dev: false + + /autoprefixer@10.4.20(postcss@8.5.3): + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.24.4 + caniuse-lite: 1.0.30001701 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + dev: true + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.1.0 + dev: true + + /axe-core@4.10.2: + resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==} + engines: {node: '>=4'} + dev: true + + /axios@1.8.1: + resolution: {integrity: sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + dependencies: + open: 8.4.2 + dev: true + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + + /browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + dev: true + + /browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001701 + electron-to-chromium: 1.5.107 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.4) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + /bundle-require@5.1.0(esbuild@0.24.2): + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + dependencies: + esbuild: 0.24.2 + load-tsconfig: 0.2.5 + dev: true + + /busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + /call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + dev: true + + /call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + /caniuse-lite@1.0.30001701: + resolution: {integrity: sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==} + + /cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + dev: false + + /chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + dev: true + + /chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chart.js@4.4.8: + resolution: {integrity: sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==} + engines: {pnpm: '>=8'} + dependencies: + '@kurkle/color': 0.3.4 + dev: false + + /check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + dev: true + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + /chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + dependencies: + readdirp: 4.1.2 + dev: true + + /chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + dev: true + + /class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + dependencies: + clsx: 2.1.1 + dev: false + + /client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: false + + /codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + requiresBuild: true + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + optional: true + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + requiresBuild: true + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: false + optional: true + + /combine-errors@3.0.3: + resolution: {integrity: sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==} + dependencies: + custom-error-instance: 2.1.1 + lodash.uniqby: 4.5.0 + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: false + + /cosmiconfig@9.0.0(typescript@5.6.3): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 5.6.3 + dev: true + + /crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + dev: false + + /cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true + + /csscolorparser@1.0.3: + resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==} + dev: false + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + /custom-error-instance@2.1.1: + resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} + dev: false + + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + dev: false + + /d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + + /damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + + /data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + dev: false + + /dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + dev: false + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + dev: false + + /deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: true + + /define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + requiresBuild: true + dev: false + optional: true + + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + + /detective-amd@6.0.1: + resolution: {integrity: sha512-TtyZ3OhwUoEEIhTFoc1C9IyJIud3y+xYkSRjmvCt65+ycQuc3VcBrPRTMWoO/AnuCyOB8T5gky+xf7Igxtjd3g==} + engines: {node: '>=18'} + hasBin: true + dependencies: + ast-module-types: 6.0.1 + escodegen: 2.1.0 + get-amd-module-type: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /detective-cjs@6.0.1: + resolution: {integrity: sha512-tLTQsWvd2WMcmn/60T2inEJNhJoi7a//PQ7DwRKEj1yEeiQs4mrONgsUtEJKnZmrGWBBmE0kJ1vqOG/NAxwaJw==} + engines: {node: '>=18'} + dependencies: + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /detective-es6@5.0.1: + resolution: {integrity: sha512-XusTPuewnSUdoxRSx8OOI6xIA/uld/wMQwYsouvFN2LAg7HgP06NF1lHRV3x6BZxyL2Kkoih4ewcq8hcbGtwew==} + engines: {node: '>=18'} + dependencies: + node-source-walk: 7.0.1 + dev: true + + /detective-postcss@7.0.1(postcss@8.5.3): + resolution: {integrity: sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==} + engines: {node: ^14.0.0 || >=16.0.0} + peerDependencies: + postcss: ^8.4.47 + dependencies: + is-url: 1.2.4 + postcss: 8.5.3 + postcss-values-parser: 6.0.2(postcss@8.5.3) + dev: true + + /detective-sass@6.0.1: + resolution: {integrity: sha512-jSGPO8QDy7K7pztUmGC6aiHkexBQT4GIH+mBAL9ZyBmnUIOFbkfZnO8wPRRJFP/QP83irObgsZHCoDHZ173tRw==} + engines: {node: '>=18'} + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.1 + dev: true + + /detective-scss@5.0.1: + resolution: {integrity: sha512-MAyPYRgS6DCiS6n6AoSBJXLGVOydsr9huwXORUlJ37K3YLyiN0vYHpzs3AdJOgHobBfispokoqrEon9rbmKacg==} + engines: {node: '>=18'} + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 7.0.1 + dev: true + + /detective-stylus@5.0.1: + resolution: {integrity: sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==} + engines: {node: '>=18'} + dev: true + + /detective-typescript@14.0.0(typescript@5.7.3): + resolution: {integrity: sha512-pgN43/80MmWVSEi5LUuiVvO/0a9ss5V7fwVfrJ4QzAQRd3cwqU1SfWGXJFcNKUqoD5cS+uIovhw5t/0rSeC5Mw==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 + dependencies: + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /detective-vue2@2.2.0(typescript@5.7.3): + resolution: {integrity: sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA==} + engines: {node: '>=18'} + peerDependencies: + typescript: ^5.4.4 + dependencies: + '@dependents/detective-less': 5.0.1 + '@vue/compiler-sfc': 3.5.13 + detective-es6: 5.0.1 + detective-sass: 6.0.1 + detective-scss: 5.0.1 + detective-stylus: 5.0.1 + detective-typescript: 14.0.0(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + /dnd-core@16.0.1: + resolution: {integrity: sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==} + dependencies: + '@react-dnd/asap': 5.0.2 + '@react-dnd/invariant': 4.0.2 + redux: 4.2.1 + dev: false + + /dnd-multi-backend@8.1.2(dnd-core@16.0.1): + resolution: {integrity: sha512-KPDVEsiM+6gNEegqZYTWJQgJxYV4vB91tUrvoKJjaS0wwWqT/jNU0P7xJAwCue/cbasJNvk2dFZH7tC+bjX1Rg==} + peerDependencies: + dnd-core: ^16.0.1 + dependencies: + dnd-core: 16.0.1 + dev: false + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dev: true + + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: true + + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.26.9 + csstype: 3.1.3 + dev: false + + /dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + /earcut@2.2.4: + resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + dev: false + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + /effector@23.3.0: + resolution: {integrity: sha512-ZnQ3POaNARlxT9+kxrK58PO/xmStBdxfPq0rceglENg8Ryxx/yx+1RsV/ziznrFPhLkZYc7NdDA1OKxnMW98/g==} + engines: {node: '>=11.0.0'} + dev: true + + /electron-to-chromium@1.5.107: + resolution: {integrity: sha512-dJr1o6yCntRkXElnhsHh1bAV19bo/hKyFf7tCcWgpXbuFIF0Lakjgqv5LRfSDaNzAII8Fnxg2tqgHkgCvxdbxw==} + dev: true + + /embla-carousel-react@8.6.0(react@18.3.1): + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^18.3.1 + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 18.3.1 + dev: false + + /embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + dependencies: + embla-carousel: 8.6.0 + dev: false + + /embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + /empathic@1.0.0: + resolution: {integrity: sha512-qtKgI1Mv8rTacvpaTkh28HM2Lbf+IOjXb7rhpt/42kZxRm8TBb/IVlo5iL2ztT19kc/EHAFN0fZ641avlXAgdg==} + engines: {node: '>=16'} + dev: true + + /enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: true + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.18 + dev: true + + /es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + /es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + dev: true + + /es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + dev: true + + /es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + + /es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + /es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + dev: true + + /es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + dev: true + + /esbuild-register@3.6.0(esbuild@0.25.0): + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.4.0 + esbuild: 0.25.0 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + dev: true + + /esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + dev: true + + /esbuild@0.25.0: + resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.0 + '@esbuild/android-arm': 0.25.0 + '@esbuild/android-arm64': 0.25.0 + '@esbuild/android-x64': 0.25.0 + '@esbuild/darwin-arm64': 0.25.0 + '@esbuild/darwin-x64': 0.25.0 + '@esbuild/freebsd-arm64': 0.25.0 + '@esbuild/freebsd-x64': 0.25.0 + '@esbuild/linux-arm': 0.25.0 + '@esbuild/linux-arm64': 0.25.0 + '@esbuild/linux-ia32': 0.25.0 + '@esbuild/linux-loong64': 0.25.0 + '@esbuild/linux-mips64el': 0.25.0 + '@esbuild/linux-ppc64': 0.25.0 + '@esbuild/linux-riscv64': 0.25.0 + '@esbuild/linux-s390x': 0.25.0 + '@esbuild/linux-x64': 0.25.0 + '@esbuild/netbsd-arm64': 0.25.0 + '@esbuild/netbsd-x64': 0.25.0 + '@esbuild/openbsd-arm64': 0.25.0 + '@esbuild/openbsd-x64': 0.25.0 + '@esbuild/sunos-x64': 0.25.0 + '@esbuild/win32-arm64': 0.25.0 + '@esbuild/win32-ia32': 0.25.0 + '@esbuild/win32-x64': 0.25.0 + dev: true + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-config-next@15.1.7(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-zXoMnYUIy3XHaAoOhrcYkT9UQWvXqWju2K7NNsmb5wd/7XESDwof61eUdW4QhERr3eJ9Ko/vnXqIrj8kk/drYw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@next/eslint-plugin-next': 15.1.7 + '@rushstack/eslint-patch': 1.10.5 + '@typescript-eslint/eslint-plugin': 8.25.0(@typescript-eslint/parser@8.25.0)(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + eslint: 9.21.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@9.21.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.21.0) + eslint-plugin-react: 7.37.4(eslint@9.21.0) + eslint-plugin-react-hooks: 5.1.0(eslint@9.21.0) + typescript: 5.6.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.21.0): + resolution: {integrity: sha512-A0bu4Ks2QqDWNpeEgTQMPTngaMhuDu4yv6xpftBMAf+1ziXnpx+eSR1WRfoPTe2BAiAjHFZ7kSNx1fvr5g5pmQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.0 + enhanced-resolve: 5.18.1 + eslint: 9.21.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0) + get-tsconfig: 4.10.0 + is-bun-module: 1.3.0 + stable-hash: 0.0.4 + tinyglobby: 0.2.12 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.12.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0): + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + debug: 3.2.7 + eslint: 9.21.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@9.21.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0): + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@rtsao/scc': 1.1.0 + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.21.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@9.21.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jsx-a11y@6.10.2(eslint@9.21.0): + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.2 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.21.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + dev: true + + /eslint-plugin-react-hooks@5.1.0(eslint@9.21.0): + resolution: {integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + dependencies: + eslint: 9.21.0 + dev: true + + /eslint-plugin-react-refresh@0.4.19(eslint@9.21.0): + resolution: {integrity: sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==} + peerDependencies: + eslint: '>=8.40' + dependencies: + eslint: 9.21.0 + dev: true + + /eslint-plugin-react@7.37.4(eslint@9.21.0): + resolution: {integrity: sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.21.0 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + dev: true + + /eslint-plugin-storybook@0.11.3(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-gDBnBZiyk4ZG7OMSJRaHBcuJ8TMCXgMIQ3HB/XvtN0SvSio2ZOIeYD3yGj39g/DbyCe/Bg02j/ip9tWlDEs82A==} + engines: {node: '>= 18'} + peerDependencies: + eslint: '>=8' + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@storybook/csf': 0.1.13 + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + eslint: 9.21.0 + ts-dedent: 2.2.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /eslint@9.21.0: + resolution: {integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.0 + '@eslint/js': 9.21.0 + '@eslint/plugin-kit': 0.2.7 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.6 + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-equals@5.2.2: + resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} + engines: {node: '>=6.0.0'} + dev: false + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + dev: true + + /fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + dev: true + + /fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + dev: true + + /fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + dependencies: + reusify: 1.1.0 + + /fdir@6.4.3(picomatch@4.0.2): + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + dependencies: + picomatch: 4.0.2 + dev: true + + /file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + dependencies: + flat-cache: 4.0.1 + dev: true + + /file-selector@2.1.2: + resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} + engines: {node: '>= 12'} + dependencies: + tslib: 2.8.1 + dev: false + + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + dev: true + + /flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + dev: true + + /follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + /form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + dev: false + + /frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + dev: false + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: true + + /framer-motion@11.18.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + motion-dom: 11.18.1 + motion-utils: 11.18.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + /function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /geotiff@2.1.3: + resolution: {integrity: sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==} + engines: {node: '>=10.19'} + dependencies: + '@petamoriken/float16': 3.9.2 + lerc: 3.0.0 + pako: 2.1.0 + parse-headers: 2.0.6 + quick-lru: 6.1.2 + web-worker: 1.5.0 + xml-utils: 1.10.2 + zstddec: 0.1.0 + dev: false + + /get-amd-module-type@6.0.1: + resolution: {integrity: sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==} + engines: {node: '>=18'} + dependencies: + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + + /get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + /get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + dev: true + + /get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + dev: true + + /globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + dev: true + + /globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + dev: true + + /globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.3 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + dev: true + + /globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + + /gonzales-pe@4.3.0: + resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} + engines: {node: '>=0.6.0'} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /goober@2.1.16(csstype@3.1.3): + resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==} + peerDependencies: + csstype: ^3.0.10 + dependencies: + csstype: 3.1.3 + dev: false + + /gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.1 + dev: true + + /has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + dev: true + + /has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.1.0 + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + + /html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: false + + /i18next@25.3.2(typescript@5.6.3): + resolution: {integrity: sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@babel/runtime': 7.27.6 + typescript: 5.6.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + dev: true + + /ignore@7.0.3: + resolution: {integrity: sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==} + engines: {node: '>= 4'} + dev: true + + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + + /immer@10.1.1: + resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} + dev: true + + /import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + dev: true + + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + + /is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + requiresBuild: true + dev: false + optional: true + + /is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + dependencies: + async-function: 1.0.0 + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + dev: true + + /is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + dependencies: + has-bigints: 1.1.0 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + + /is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-bun-module@1.3.0: + resolution: {integrity: sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==} + dependencies: + semver: 7.7.1 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + + /is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + dev: true + + /is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + dev: false + + /is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + dev: true + + /is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + + /is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + dev: true + + /is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.18 + dev: true + + /is-url-superb@4.0.0: + resolution: {integrity: sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==} + engines: {node: '>=10'} + dev: true + + /is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + dev: true + + /is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + dev: true + + /is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + dev: true + + /is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + dev: true + + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: false + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + dev: true + + /jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 22.13.9 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + + /js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + dev: false + + /js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + engines: {node: '>=12.0.0'} + dev: true + + /jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stringify-pretty-compact@2.0.0: + resolution: {integrity: sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==} + dev: false + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + dev: true + + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: false + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + dev: true + + /language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + dependencies: + language-subtag-registry: 0.3.23 + dev: true + + /lerc@3.0.0: + resolution: {integrity: sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==} + dev: false + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /libphonenumber-js@1.12.9: + resolution: {integrity: sha512-VWwAdNeJgN7jFOD+wN4qx83DTPMVPPAUyx9/TUkBXKLiNkuWWk6anV0439tgdtwaJDrEdqkvdN22iA6J4bUCZg==} + dev: false + + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + dev: false + + /lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: true + + /lodash._baseiteratee@4.7.0: + resolution: {integrity: sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==} + dependencies: + lodash._stringtopath: 4.8.0 + dev: false + + /lodash._basetostring@4.12.0: + resolution: {integrity: sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw==} + dev: false + + /lodash._baseuniq@4.6.0: + resolution: {integrity: sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==} + dependencies: + lodash._createset: 4.0.3 + lodash._root: 3.0.1 + dev: false + + /lodash._createset@4.0.3: + resolution: {integrity: sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==} + dev: false + + /lodash._root@3.0.1: + resolution: {integrity: sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==} + dev: false + + /lodash._stringtopath@4.8.0: + resolution: {integrity: sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==} + dependencies: + lodash._basetostring: 4.12.0 + dev: false + + /lodash.add@3.7.0: + resolution: {integrity: sha512-/uxUZkB6vYiPoGSXADJJE+Ee4W2vU+bxZOFdvJdx+mDgv+qyAO76sWD84Q4FxsMgTjC1+gVFC9YNhdG243QRDw==} + dev: false + + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + dev: false + + /lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + dev: false + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.size@4.2.0: + resolution: {integrity: sha512-wbu3SF1XC5ijqm0piNxw59yCbuUf2kaShumYBLWUrcCvwh6C8odz6SY/wGVzCWTQTFL/1Ygbvqg2eLtspUVVAQ==} + dev: false + + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: false + + /lodash.uniqby@4.5.0: + resolution: {integrity: sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==} + dependencies: + lodash._baseiteratee: 4.7.0 + lodash._baseuniq: 4.6.0 + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + dev: true + + /lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lucide-react@0.474.0(react@18.3.1): + resolution: {integrity: sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==} + peerDependencies: + react: ^18.3.1 + dependencies: + react: 18.3.1 + dev: false + + /lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + dev: true + + /magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + dev: true + + /mapbox-to-css-font@2.4.5: + resolution: {integrity: sha512-VJ6nB8emkO9VODI0Fk+TQ/0zKBTqmf/Pkt8Xv0kHstoc0iXRajA00DAid4Kc3K5xeFIOoiZrVxijEzj0GLVO2w==} + dev: false + + /math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + /memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + dependencies: + map-or-similar: 1.5.0 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + /mgrs@1.0.0: + resolution: {integrity: sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==} + dev: false + + /micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + /module-definition@6.0.1: + resolution: {integrity: sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==} + engines: {node: '>=18'} + hasBin: true + dependencies: + ast-module-types: 6.0.1 + node-source-walk: 7.0.1 + dev: true + + /moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + dev: false + + /motion-dom@11.18.1: + resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==} + dependencies: + motion-utils: 11.18.1 + dev: false + + /motion-utils@11.18.1: + resolution: {integrity: sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==} + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + /nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /next@15.1.7(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.3.1 + react-dom: ^18.3.1 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + dependencies: + '@next/env': 15.1.7 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001701 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.1.7 + '@next/swc-darwin-x64': 15.1.7 + '@next/swc-linux-arm64-gnu': 15.1.7 + '@next/swc-linux-arm64-musl': 15.1.7 + '@next/swc-linux-x64-gnu': 15.1.7 + '@next/swc-linux-x64-musl': 15.1.7 + '@next/swc-win32-arm64-msvc': 15.1.7 + '@next/swc-win32-x64-msvc': 15.1.7 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /next@15.3.0(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-k0MgP6BsK8cZ73wRjMazl2y2UcXj49ZXLDEgx6BikWuby/CN+nh81qFFI16edgd7xYpe/jj2OZEIwCoqnzz0bQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.3.1 + react-dom: ^18.3.1 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + dependencies: + '@next/env': 15.3.0 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001701 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.0 + '@next/swc-darwin-x64': 15.3.0 + '@next/swc-linux-arm64-gnu': 15.3.0 + '@next/swc-linux-arm64-musl': 15.3.0 + '@next/swc-linux-x64-gnu': 15.3.0 + '@next/swc-linux-x64-musl': 15.3.0 + '@next/swc-win32-arm64-msvc': 15.3.0 + '@next/swc-win32-x64-msvc': 15.3.0 + sharp: 0.34.1 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + dev: true + + /node-source-walk@7.0.1: + resolution: {integrity: sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==} + engines: {node: '>=18'} + dependencies: + '@babel/parser': 7.26.9 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + /object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + dev: true + + /object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /ol-ext@4.0.31(ol@7.5.2): + resolution: {integrity: sha512-byh26JcXZggkLUY79+c29cxf2ovkkwz5niWJzOIN+dLPDJ+ogSn0y4Wl8fIS9O2JtQff5/cInHRImgZBvl+N1g==} + peerDependencies: + ol: '>= 5.3.0' + dependencies: + ol: 7.5.2 + dev: false + + /ol-mapbox-style@10.7.0: + resolution: {integrity: sha512-S/UdYBuOjrotcR95Iq9AejGYbifKeZE85D9VtH11ryJLQPTZXZSW1J5bIXcr4AlAH6tyjPPHTK34AdkwB32Myw==} + dependencies: + '@mapbox/mapbox-gl-style-spec': 13.28.0 + mapbox-to-css-font: 2.4.5 + ol: 7.5.2 + dev: false + + /ol@7.5.2: + resolution: {integrity: sha512-HJbb3CxXrksM6ct367LsP3N+uh+iBBMdP3DeGGipdV9YAYTP0vTJzqGnoqQ6C2IW4qf8krw9yuyQbc9fjOIaOQ==} + dependencies: + earcut: 2.2.4 + geotiff: 2.1.3 + ol-mapbox-style: 10.7.0 + pbf: 3.2.1 + rbush: 3.0.1 + dev: false + + /open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + dev: true + + /own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + + /pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + dev: false + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-headers@2.0.6: + resolution: {integrity: sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==} + dev: false + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.26.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + /path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + /path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + dev: true + + /path@0.12.7: + resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==} + dependencies: + process: 0.11.10 + util: 0.10.4 + dev: false + + /pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + dev: true + + /patronum@2.3.0(effector@23.3.0): + resolution: {integrity: sha512-BfKIOpoymVz6XnkOn8Fi5QZ1a3r/3lXdd8BcdHmYDbIXPTIRnD1EPFBFev/DheWnOge6/ZswEqgNF2ANLGOxLw==} + peerDependencies: + effector: ^23 + dependencies: + effector: 23.3.0 + dev: true + + /pbf@3.2.1: + resolution: {integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==} + hasBin: true + dependencies: + ieee754: 1.2.1 + resolve-protobuf-schema: 2.1.0 + dev: false + + /picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + dev: true + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + + /polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + dependencies: + '@babel/runtime': 7.26.9 + dev: true + + /possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@15.1.0(postcss@8.5.3): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.10 + + /postcss-js@4.0.1(postcss@8.5.3): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.3 + + /postcss-load-config@4.0.2(postcss@8.5.3): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.1.3 + postcss: 8.5.3 + yaml: 2.7.0 + + /postcss-load-config@6.0.1(postcss@8.5.3): + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + dependencies: + lilconfig: 3.1.3 + postcss: 8.5.3 + dev: true + + /postcss-nested@6.2.0(postcss@8.5.3): + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 6.1.2 + + /postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + /postcss-values-parser@6.0.2(postcss@8.5.3): + resolution: {integrity: sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==} + engines: {node: '>=10'} + peerDependencies: + postcss: ^8.2.9 + dependencies: + color-name: 1.1.4 + is-url-superb: 4.0.0 + postcss: 8.5.3 + quote-unquote: 1.0.0 + dev: true + + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + dev: false + + /postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + /preact@10.12.1: + resolution: {integrity: sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==} + dev: false + + /precinct@12.2.0: + resolution: {integrity: sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==} + engines: {node: '>=18'} + hasBin: true + dependencies: + '@dependents/detective-less': 5.0.1 + commander: 12.1.0 + detective-amd: 6.0.1 + detective-cjs: 6.0.1 + detective-es6: 5.0.1 + detective-postcss: 7.0.1(postcss@8.5.3) + detective-sass: 6.0.1 + detective-scss: 5.0.1 + detective-stylus: 5.0.1 + detective-typescript: 14.0.0(typescript@5.7.3) + detective-vue2: 2.2.0(typescript@5.7.3) + module-definition: 6.0.1 + node-source-walk: 7.0.1 + postcss: 8.5.3 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-plugin-tailwindcss@0.6.11(prettier@3.5.2): + resolution: {integrity: sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + dependencies: + prettier: 3.5.2 + dev: true + + /prettier@3.5.2: + resolution: {integrity: sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /prexit@2.3.0: + resolution: {integrity: sha512-mX+LIbtS0anKtl2PykYabxninwloblUQMRO6CubeSmjxb+kKlATuJoH9UeN8NLE4TgIEFWfBXw7V3GkWbBrSmg==} + engines: {node: '>=12'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: false + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + /proj4@2.15.0: + resolution: {integrity: sha512-LqCNEcPdI03BrCHxPLj29vsd5afsm+0sV1H/O3nTDKrv8/LA01ea1z4QADDMjUqxSXWnrmmQDjqFm1J/uZ5RLw==} + dependencies: + mgrs: 1.0.0 + wkt-parser: 1.4.0 + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + /proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + dev: false + + /protocol-buffers-schema@3.6.0: + resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + dev: false + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: false + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + /quick-lru@6.1.2: + resolution: {integrity: sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==} + engines: {node: '>=12'} + dev: false + + /quickselect@2.0.0: + resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} + dev: false + + /quote-unquote@1.0.0: + resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /rbush@3.0.1: + resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==} + dependencies: + quickselect: 2.0.0 + dev: false + + /react-chartjs-2@5.3.0(chart.js@4.4.8)(react@18.3.1): + resolution: {integrity: sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==} + peerDependencies: + chart.js: ^4.1.1 + react: ^18.3.1 + dependencies: + chart.js: 4.4.8 + react: 18.3.1 + dev: false + + /react-day-picker@8.10.1(date-fns@3.6.0)(react@18.3.1): + resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==} + peerDependencies: + date-fns: ^2.28.0 || ^3.0.0 + react: ^18.3.1 + dependencies: + date-fns: 3.6.0 + react: 18.3.1 + dev: false + + /react-dnd-html5-backend@16.0.1: + resolution: {integrity: sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==} + dependencies: + dnd-core: 16.0.1 + dev: false + + /react-dnd-touch-backend@16.0.1: + resolution: {integrity: sha512-NonoCABzzjyWGZuDxSG77dbgMZ2Wad7eQiCd/ECtsR2/NBLTjGksPUx9UPezZ1nQ/L7iD130Tz3RUshL/ClKLA==} + dependencies: + '@react-dnd/invariant': 4.0.2 + dnd-core: 16.0.1 + dev: false + + /react-dnd@16.0.1(@types/node@22.13.5)(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + dependencies: + '@react-dnd/invariant': 4.0.2 + '@react-dnd/shallowequal': 4.0.2 + '@types/node': 22.13.5 + '@types/react': 18.3.18 + dnd-core: 16.0.1 + fast-deep-equal: 3.1.3 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + dev: false + + /react-dnd@16.0.1(@types/node@22.13.9)(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + dependencies: + '@react-dnd/invariant': 4.0.2 + '@react-dnd/shallowequal': 4.0.2 + '@types/node': 22.13.9 + '@types/react': 18.3.18 + dnd-core: 16.0.1 + fast-deep-equal: 3.1.3 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + dev: false + + /react-docgen-typescript@2.2.2(typescript@5.6.3): + resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} + peerDependencies: + typescript: '>= 4.3.x' + dependencies: + typescript: 5.6.3 + dev: true + + /react-docgen@7.1.1: + resolution: {integrity: sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==} + engines: {node: '>=16.14.0'} + dependencies: + '@babel/core': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.10 + strip-indent: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /react-dom@18.3.1(react@18.3.1): + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + /react-dropzone@14.3.8(react@18.3.1): + resolution: {integrity: sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==} + engines: {node: '>= 10.13'} + peerDependencies: + react: ^18.3.1 + dependencies: + attr-accept: 2.2.5 + file-selector: 2.1.2 + prop-types: 15.8.1 + react: 18.3.1 + dev: false + + /react-hook-form@7.54.2(react@18.3.1): + resolution: {integrity: sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.3.1 + dependencies: + react: 18.3.1 + dev: false + + /react-hot-toast@2.5.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==} + engines: {node: '>=10'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + csstype: 3.1.3 + goober: 2.1.16(csstype@3.1.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /react-i18next@15.6.0(i18next@25.3.2)(react-dom@18.3.1)(react@18.3.1)(typescript@5.6.3): + resolution: {integrity: sha512-W135dB0rDfiFmbMipC17nOhGdttO5mzH8BivY+2ybsQBbXvxWIwl3cmeH3T9d+YPBSJu/ouyJKFJTtkK7rJofw==} + peerDependencies: + i18next: '>= 23.2.3' + react: ^18.3.1 + react-dom: '*' + react-native: '*' + typescript: ^5 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true + dependencies: + '@babel/runtime': 7.27.6 + html-parse-stringify: 3.0.1 + i18next: 25.3.2(typescript@5.6.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + typescript: 5.6.3 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + dev: false + + /react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + dev: true + + /react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + tslib: 2.8.1 + dev: false + + /react-remove-scroll@2.6.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1) + dev: false + + /react-smooth@4.0.4(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + fast-equals: 5.2.2 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) + dev: false + + /react-style-singleton@2.2.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /react-transition-group@4.4.5(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + '@babel/runtime': 7.26.9 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /react-use-measure@2.1.7(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + peerDependenciesMeta: + react-dom: + optional: true + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: false + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + + /readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + dev: true + + /recast@0.23.10: + resolution: {integrity: sha512-mbCmRMJUKCJ1h41V0cu2C26ULBURwuoZ34C9rChjcDaeJ/4Kv5al3O2HPwTs2m0wQ1vGhMY+tguhzU1aE8md1A==} + engines: {node: '>= 4'} + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + dev: true + + /recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + dependencies: + decimal.js-light: 2.5.1 + dev: false + + /recharts@2.15.1(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==} + engines: {node: '>=14'} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + clsx: 2.1.1 + eventemitter3: 4.0.7 + lodash: 4.17.21 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + react-smooth: 4.0.4(react-dom@18.3.1)(react@18.3.1) + recharts-scale: 0.4.5 + tiny-invariant: 1.3.3 + victory-vendor: 36.9.2 + dev: false + + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + dependencies: + '@babel/runtime': 7.26.9 + dev: false + + /reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + /regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve-protobuf-schema@2.1.0: + resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} + dependencies: + protocol-buffers-schema: 3.6.0 + dev: false + + /resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + dev: false + + /reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + /rollup@4.34.8: + resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.34.8 + '@rollup/rollup-android-arm64': 4.34.8 + '@rollup/rollup-darwin-arm64': 4.34.8 + '@rollup/rollup-darwin-x64': 4.34.8 + '@rollup/rollup-freebsd-arm64': 4.34.8 + '@rollup/rollup-freebsd-x64': 4.34.8 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.8 + '@rollup/rollup-linux-arm-musleabihf': 4.34.8 + '@rollup/rollup-linux-arm64-gnu': 4.34.8 + '@rollup/rollup-linux-arm64-musl': 4.34.8 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.8 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.8 + '@rollup/rollup-linux-riscv64-gnu': 4.34.8 + '@rollup/rollup-linux-s390x-gnu': 4.34.8 + '@rollup/rollup-linux-x64-gnu': 4.34.8 + '@rollup/rollup-linux-x64-musl': 4.34.8 + '@rollup/rollup-win32-arm64-msvc': 4.34.8 + '@rollup/rollup-win32-ia32-msvc': 4.34.8 + '@rollup/rollup-win32-x64-msvc': 4.34.8 + fsevents: 2.3.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + + /rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + + /safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-regex: 1.2.1 + dev: true + + /sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + dev: false + + /scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + dependencies: + loose-envify: 1.4.0 + + /schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + dev: true + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + dev: true + + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: false + + /sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + dev: false + optional: true + + /sharp@0.34.1: + resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.1 + '@img/sharp-darwin-x64': 0.34.1 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.1 + '@img/sharp-linux-arm64': 0.34.1 + '@img/sharp-linux-s390x': 0.34.1 + '@img/sharp-linux-x64': 0.34.1 + '@img/sharp-linuxmusl-arm64': 0.34.1 + '@img/sharp-linuxmusl-x64': 0.34.1 + '@img/sharp-wasm32': 0.34.1 + '@img/sharp-win32-ia32': 0.34.1 + '@img/sharp-win32-x64': 0.34.1 + dev: false + optional: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: true + + /side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: true + + /side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + requiresBuild: true + dependencies: + is-arrayish: 0.3.2 + dev: false + optional: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + dev: true + + /sonner@2.0.1(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==} + peerDependencies: + react: ^18.3.1 + react-dom: ^18.3.1 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /sort-asc@0.1.0: + resolution: {integrity: sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==} + engines: {node: '>=0.10.0'} + dev: false + + /sort-desc@0.1.1: + resolution: {integrity: sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==} + engines: {node: '>=0.10.0'} + dev: false + + /sort-object@0.3.2: + resolution: {integrity: sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==} + engines: {node: '>=0.10.0'} + dependencies: + sort-asc: 0.1.0 + sort-desc: 0.1.1 + dev: false + + /source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + dependencies: + frac: 1.1.2 + dev: false + + /stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + dev: true + + /steiger@0.5.5(typescript@5.6.3): + resolution: {integrity: sha512-d4eZwqJjfG7dKgwXKBwmZsNWSRqeQrRpEvEr58rhMmNbICcQsJ8cpK9n6nuish3kNjKyYzx6t2TpQYEO26xTFA==} + hasBin: true + dependencies: + '@clack/prompts': 0.8.2 + '@feature-sliced/steiger-plugin': 0.5.4(typescript@5.6.3) + chokidar: 4.0.3 + cosmiconfig: 9.0.0(typescript@5.6.3) + effector: 23.3.0 + empathic: 1.0.0 + fastest-levenshtein: 1.0.16 + globby: 14.1.0 + immer: 10.1.1 + lodash-es: 4.17.21 + micromatch: 4.0.8 + patronum: 2.3.0(effector@23.3.0) + picocolors: 1.1.1 + prexit: 2.3.0 + yargs: 17.7.2 + zod: 3.24.2 + zod-validation-error: 3.4.0(zod@3.24.2) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /storybook@8.6.0(prettier@3.5.2): + resolution: {integrity: sha512-NEHCK2nXogw7WxAkJfMwPnc5Cmh/KqVNrdaFeXBAKhC2Zr1FTZIiCR5nSUT85run44Wkpmo7qvUoKvII9GOWbA==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + dependencies: + '@storybook/core': 8.6.0(prettier@3.5.2)(storybook@8.6.0) + prettier: 3.5.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + /string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + dev: true + + /string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + dev: true + + /string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.1.0 + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /styled-jsx@5.1.6(react@18.3.1): + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: ^18.3.1 + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + client-only: 0.0.1 + react: 18.3.1 + dev: false + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + /tailwind-merge@3.0.2: + resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} + dev: false + + /tailwindcss-animate@1.0.7(tailwindcss@3.4.17): + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + tailwindcss: 3.4.17 + dev: false + + /tailwindcss@3.4.17: + resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-import: 15.1.0(postcss@8.5.3) + postcss-js: 4.0.1(postcss@8.5.3) + postcss-load-config: 4.0.2(postcss@8.5.3) + postcss-nested: 6.2.0(postcss@8.5.3) + postcss-selector-parser: 6.1.2 + resolve: 1.22.10 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + + /terser-webpack-plugin@5.3.13(webpack@5.98.0): + resolution: {integrity: sha512-JG3pBixF6kx2o0Yfz2K6pqh72DpwTI08nooHd06tcj5WyIt5SsSiUYqRT+kemrGUNSuSzVhwfZ28aO8gogajNQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 4.3.0 + serialize-javascript: 6.0.2 + terser: 5.39.0 + webpack: 5.98.0 + dev: true + + /terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + + /tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + /tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + dev: true + + /tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + dev: true + + /tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.3.1 + dev: true + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /ts-api-utils@2.0.1(typescript@5.6.3): + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + dependencies: + typescript: 5.6.3 + dev: true + + /ts-api-utils@2.0.1(typescript@5.7.3): + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + dependencies: + typescript: 5.7.3 + dev: true + + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + /tsconfck@3.1.5(typescript@5.6.3): + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.6.3 + dev: true + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + /tsup@8.3.6(postcss@8.5.3)(typescript@5.6.3): + resolution: {integrity: sha512-XkVtlDV/58S9Ye0JxUUTcrQk4S+EqlOHKzg6Roa62rdjL1nGWNUstG0xgI4vanHdfIpjP448J8vlN0oK6XOJ5g==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + bundle-require: 5.1.0(esbuild@0.24.2) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.0 + debug: 4.4.0 + esbuild: 0.24.2 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-load-config: 6.0.1(postcss@8.5.3) + resolve-from: 5.0.0 + rollup: 4.34.8 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.12 + tree-kill: 1.2.2 + typescript: 5.6.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + dev: true + + /turbo-darwin-64@2.4.2: + resolution: {integrity: sha512-HFfemyWB60CJtEvVQj9yby5rkkWw9fLAdLtAPGtPQoU3tKh8t/uzCAZKso2aPVbib9vGUuGbPGoGpaRXdVhj5g==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /turbo-darwin-arm64@2.4.2: + resolution: {integrity: sha512-uwSx1dsBSSFeEC0nxyx2O219FEsS/haiESaWwE9JI8mHkQK61s6w6fN2G586krKxyNam4AIxRltleL+O2Em94g==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /turbo-linux-64@2.4.2: + resolution: {integrity: sha512-Fy/uL8z/LAYcPbm7a1LwFnTY9pIi5FAi12iuHsgB7zHjdh4eeIKS2NIg4nroAmTcUTUZ0/cVTo4bDOCUcS3aKw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /turbo-linux-arm64@2.4.2: + resolution: {integrity: sha512-AEA0d8h5W/K6iiXfEgiNwWt0yqRL1NpBs8zQCLdc4/L7WeYeJW3sORWX8zt7xhutF/KW9gTm8ehKpiK6cCIsAA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /turbo-windows-64@2.4.2: + resolution: {integrity: sha512-CybtIZ9wRgnnNFVN9En9G+rxsO+mwU81fvW4RpE8BWyNEkhQ8J28qYf4PaimueMxGHHp/28i/G7Kcdn2GAWG0g==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /turbo-windows-arm64@2.4.2: + resolution: {integrity: sha512-7V0yneVPL8Y3TgrkUIjw7Odmwu1tHnyIiPHFM7eFcA7U+H6hPXyCxge7nC3wOKfjhKCQqUm+Vf/k6kjmLz5G4g==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /turbo@2.4.2: + resolution: {integrity: sha512-Qxi0ioQCxMRUCcHKHZkTnYH8e7XCpNfg9QiJcyfWIc+ZXeaCjzV5rCGlbQlTXMAtI8qgfP8fZADv3CFtPwqdPQ==} + hasBin: true + optionalDependencies: + turbo-darwin-64: 2.4.2 + turbo-darwin-arm64: 2.4.2 + turbo-linux-64: 2.4.2 + turbo-linux-arm64: 2.4.2 + turbo-windows-64: 2.4.2 + turbo-windows-arm64: 2.4.2 + dev: true + + /tus-js-client@4.3.1: + resolution: {integrity: sha512-ZLeYmjrkaU1fUsKbIi8JML52uAocjEZtBx4DKjRrqzrZa0O4MYwT6db+oqePlspV+FxXJAyFBc/L5gwUi2OFsg==} + engines: {node: '>=18'} + dependencies: + buffer-from: 1.1.2 + combine-errors: 3.0.3 + is-stream: 2.0.1 + js-base64: 3.7.7 + lodash.throttle: 4.1.1 + proper-lockfile: 4.1.2 + url-parse: 1.5.10 + dev: false + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + + /typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + dev: true + + /typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + dev: true + + /typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + dev: true + + /typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + dev: true + + /typescript-eslint@8.25.0(eslint@9.21.0)(typescript@5.6.3): + resolution: {integrity: sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + dependencies: + '@typescript-eslint/eslint-plugin': 8.25.0(@typescript-eslint/parser@8.25.0)(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.6.3) + eslint: 9.21.0 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + dev: true + + /typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + /typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + dev: true + + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + dev: true + + /undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + /unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + dev: true + + /unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + dependencies: + acorn: 8.14.0 + webpack-virtual-modules: 0.6.2 + dev: true + + /update-browserslist-db@1.1.3(browserslist@4.24.4): + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: false + + /use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /use-sidecar@1.1.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18.3.18 + react: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.18 + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + dependencies: + inherits: 2.0.3 + dev: false + + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.18 + dev: true + + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: true + + /victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + dev: false + + /vite-tsconfig-paths@5.1.4(typescript@5.6.3)(vite@6.2.0): + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + dependencies: + debug: 4.4.0 + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.6.3) + vite: 6.2.0(@types/node@22.13.9) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /vite@5.4.18(@types/node@22.13.9): + resolution: {integrity: sha512-1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 22.13.9 + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vite@6.2.0(@types/node@22.13.5): + resolution: {integrity: sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + dependencies: + '@types/node': 22.13.5 + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vite@6.2.0(@types/node@22.13.9): + resolution: {integrity: sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + dependencies: + '@types/node': 22.13.9 + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.34.8 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: false + + /watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + dev: true + + /web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + dev: false + + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + dev: true + + /webpack@5.98.0: + resolution: {integrity: sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.0 + browserslist: 4.24.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.1 + es-module-lexer: 1.6.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.13(webpack@5.98.0) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + + /whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + dev: true + + /which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.3 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.18 + dev: true + + /which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + dev: true + + /which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + for-each: 0.3.5 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wkt-parser@1.4.0: + resolution: {integrity: sha512-qpwO7Ihds/YYDTi1aADFTI1Sm9YC/tTe3SHD24EeIlZxy7Ik6a1b4HOz7jAi0xdUAw487duqpo8OGu+Tf4nwlQ==} + dev: false + + /wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + dev: false + + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + dev: false + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + /ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xlsx-populate@1.21.0: + resolution: {integrity: sha512-8v2Gm8BehXo6LU7KT802QoXTPkYY1SKk5V8g/UuYZnNB3JzXqud/P99Pxr2yXeKyt+sKlCatmidz6jQNie1hRw==} + dependencies: + cfb: 1.2.2 + jszip: 3.10.1 + lodash: 4.17.21 + sax: 1.4.1 + dev: false + + /xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + dev: false + + /xml-utils@1.10.2: + resolution: {integrity: sha512-RqM+2o1RYs6T8+3DzDSoTRAUfrvaejbVHcp3+thnAtDKo8LskR+HomLajEy5UjTz24rpka7AxVBRR3g2wTUkJA==} + dev: false + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /zod-validation-error@3.4.0(zod@3.24.2): + resolution: {integrity: sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.18.0 + dependencies: + zod: 3.24.2 + dev: true + + /zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + + /zstddec@0.1.0: + resolution: {integrity: sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==} + dev: false + + /zustand@5.0.3(@types/react@18.3.18)(react@18.3.1): + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': ^18.3.18 + immer: '>=9.0.6' + react: ^18.3.1 + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + dependencies: + '@types/react': 18.3.18 + react: 18.3.1 + dev: false From 87de574e35547b7ec37b174e189224aed828d3fa Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Fri, 11 Jul 2025 11:05:01 +0900 Subject: [PATCH 088/159] =?UTF-8?q?[privacylog]=20CS=5FUT06010101=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EC=9E=85=EB=A0=A5=ED=95=9C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EA=B3=BC=20=EB=AC=B4=EA=B4=80=ED=95=9C=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=20=EC=82=AC=EC=9A=A9=EC=9E=90=EA=B9=8C?= =?UTF-8?q?=EC=A7=80=20=ED=95=A8=EA=BB=98=20=EA=B2=80=EC=83=89=EB=90=98?= =?UTF-8?q?=EC=96=B4=20=EA=B2=B0=EA=B3=BC=EC=9D=98=20=EC=A0=95=ED=99=95?= =?UTF-8?q?=EB=8F=84=EA=B0=80=20=EB=96=A8=EC=96=B4=EC=A7=90.=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=EA=B0=80=20=EC=9B=90=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=8C=80=EC=83=81=EB=A7=8C=20=EC=A0=95=ED=99=95=ED=9E=88=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EB=90=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B2=80=EC=83=89=20=EC=A1=B0=EA=B1=B4=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=A0=95=EB=B0=80=ED=95=9C=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=A8=20=3D>=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=EC=9D=98=20=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EC=9E=90=EB=AA=85=EC=9D=84=20=EC=9A=94=EC=B2=AD=EC=9E=90?= =?UTF-8?q?=EB=AA=85=EC=9C=BC=EB=A1=9C=20=ED=97=A4=EB=8D=94=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=98=EA=B3=A0=20=EA=B2=80=EC=83=89=EB=AA=85?= =?UTF-8?q?=EC=9D=84=20=EC=A1=B0=ED=9A=8C=EC=9E=90=EB=AA=85=20=E2=86=92=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=A0=95=EB=B3=B4=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=B4=EC=84=9C=20=EC=B2=98=EB=A6=AC=20frontend?= =?UTF-8?q?=EB=8F=84=20=EB=B3=80=EA=B2=BD=20=EC=B2=98=EB=A6=AC=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/privacylog/model/table-columns.tsx | 2 +- apps/cs/src/pages/privacylog/ui/privacylog-page.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cs/src/pages/privacylog/model/table-columns.tsx b/apps/cs/src/pages/privacylog/model/table-columns.tsx index a5b52d796..d84b16524 100644 --- a/apps/cs/src/pages/privacylog/model/table-columns.tsx +++ b/apps/cs/src/pages/privacylog/model/table-columns.tsx @@ -27,7 +27,7 @@ export const columns: ColumnDef<PrivacyLog>[] = [ }, { accessorKey: "rqstrNm", - header: "조회자명", + header: "요청자명", }, { accessorKey: "rqstrIp", diff --git a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx index 786a5994e..a7b26dd4c 100644 --- a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx +++ b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx @@ -148,7 +148,7 @@ function PrivacyLogPage() { </Select> </div> </DateRangePicker> - <Label className="ml-4 mr-2 text-label">조회자명</Label> + <Label className="ml-4 mr-2 text-label">조회정보</Label> <Input className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]" value={inqInfoKeyword} From 12b041fdaec4549b2bdc69ce6927e706600a3973 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 11 Jul 2025 11:14:00 +0900 Subject: [PATCH 089/159] =?UTF-8?q?[apps/cs,=20common/features]=20chore:?= =?UTF-8?q?=20=ED=8F=BC=20=ED=95=84=EC=88=98=20=ED=95=AD=EB=AA=A9=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=20(CS=5FUT01010103)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/widgets/post/ui/post-form.tsx | 4 +-- apps/cs/src/pages/banner/ui/banner-form.tsx | 8 +++--- apps/cs/src/pages/bbs/ui/bbs-form.tsx | 28 +++++++++---------- .../src/pages/contents/ui/contents-form.tsx | 6 ++-- apps/cs/src/pages/groups/ui/group-form.tsx | 10 +++---- apps/cs/src/pages/image/ui/image-form.tsx | 10 +++---- apps/cs/src/pages/menu/ui/base-menu-form.tsx | 2 +- apps/cs/src/pages/menu/ui/type-menu-form.tsx | 6 ++-- apps/cs/src/pages/module/ui/module-form.tsx | 10 +++---- .../organization/ui/organization-form.tsx | 4 +-- apps/cs/src/pages/popup/ui/popup-form.tsx | 14 +++++----- apps/cs/src/pages/role/ui/role-form.tsx | 10 +++---- .../src/pages/schedule/ui/schedule-form.tsx | 6 ++-- apps/cs/src/pages/site/ui/site-form.tsx | 8 +++--- apps/cs/src/pages/survey/ui/question-form.tsx | 6 ++-- apps/cs/src/pages/survey/ui/survey-form.tsx | 4 +-- .../src/pages/template/ui/template-form.tsx | 6 ++-- apps/cs/src/pages/terms/ui/terms-form.tsx | 8 +++--- apps/cs/src/pages/users/ui/users-form.tsx | 12 ++++---- apps/cs/src/widgets/post/ui/post-form.tsx | 4 +-- 20 files changed, 83 insertions(+), 83 deletions(-) diff --git a/apps/common/features/src/widgets/post/ui/post-form.tsx b/apps/common/features/src/widgets/post/ui/post-form.tsx index ae2a84856..8025f123d 100644 --- a/apps/common/features/src/widgets/post/ui/post-form.tsx +++ b/apps/common/features/src/widgets/post/ui/post-form.tsx @@ -77,7 +77,7 @@ function PostForm<T extends PostFormData | PostUpdateFormData>({ </colgroup> <TableBody> <TableRow> - <TableHead>제목</TableHead> + <TableHead data-required>제목</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -120,7 +120,7 @@ function PostForm<T extends PostFormData | PostUpdateFormData>({ </TableRow> {!userInfo?.userUnqId && ( <TableRow> - <TableHead>비밀번호</TableHead> + <TableHead data-required>비밀번호</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/banner/ui/banner-form.tsx b/apps/cs/src/pages/banner/ui/banner-form.tsx index 7dd4a0a83..a615ab0cd 100644 --- a/apps/cs/src/pages/banner/ui/banner-form.tsx +++ b/apps/cs/src/pages/banner/ui/banner-form.tsx @@ -84,7 +84,7 @@ function BannerForm({ form, bnrSn, ...props }: BannerFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>배너명</TableHead> + <TableHead data-required>배너명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -105,7 +105,7 @@ function BannerForm({ form, bnrSn, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>배너구분</TableHead> + <TableHead data-required>배너구분</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -210,7 +210,7 @@ function BannerForm({ form, bnrSn, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>링크 열기</TableHead> + <TableHead data-required>링크 열기</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -260,7 +260,7 @@ function BannerForm({ form, bnrSn, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용여부</TableHead> + <TableHead data-required>사용여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/bbs/ui/bbs-form.tsx b/apps/cs/src/pages/bbs/ui/bbs-form.tsx index 3d7482bce..3de8342d9 100644 --- a/apps/cs/src/pages/bbs/ui/bbs-form.tsx +++ b/apps/cs/src/pages/bbs/ui/bbs-form.tsx @@ -54,7 +54,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>게시판명</TableHead> + <TableHead data-required>게시판명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -75,7 +75,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>게시판 설명</TableHead> + <TableHead data-required>게시판 설명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -96,7 +96,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>게시판 유형</TableHead> + <TableHead data-required>게시판 유형</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -116,7 +116,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>참조 사용 여부</TableHead> + <TableHead data-required>참조 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -146,7 +146,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>첨부파일 사용 여부</TableHead> + <TableHead data-required>첨부파일 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -236,7 +236,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>답글 사용 여부</TableHead> + <TableHead data-required>답글 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -295,7 +295,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>댓글 사용 여부</TableHead> + <TableHead data-required>댓글 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -329,7 +329,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>게시물평가 사용 여부</TableHead> + <TableHead data-required>게시물평가 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -359,7 +359,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>팝업 사용 여부</TableHead> + <TableHead data-required>팝업 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -389,7 +389,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>SMS알림 사용 여부</TableHead> + <TableHead data-required>SMS알림 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -419,7 +419,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>상단고정 사용 여부</TableHead> + <TableHead data-required>상단고정 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -449,7 +449,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>게시기간 사용 여부</TableHead> + <TableHead data-required>게시기간 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -479,7 +479,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>개인정보 표시 여부</TableHead> + <TableHead data-required>개인정보 표시 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -508,7 +508,7 @@ function BbsForm({ form, bbsId, ...props }: BbsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용 여부</TableHead> + <TableHead data-required>사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/contents/ui/contents-form.tsx b/apps/cs/src/pages/contents/ui/contents-form.tsx index 9db8035b0..01462925f 100644 --- a/apps/cs/src/pages/contents/ui/contents-form.tsx +++ b/apps/cs/src/pages/contents/ui/contents-form.tsx @@ -60,7 +60,7 @@ function ContentsForm({ </colgroup> <TableBody> <TableRow> - <TableHead>콘텐츠 제목</TableHead> + <TableHead data-required>콘텐츠 제목</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -82,7 +82,7 @@ function ContentsForm({ </TableCell> </TableRow> <TableRow> - <TableHead>콘텐츠 내용</TableHead> + <TableHead data-required>콘텐츠 내용</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -228,7 +228,7 @@ function ContentsForm({ </TableCell> </TableRow> <TableRow> - <TableHead>사용여부</TableHead> + <TableHead data-required>사용여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/groups/ui/group-form.tsx b/apps/cs/src/pages/groups/ui/group-form.tsx index 423718435..6c1d8b67f 100644 --- a/apps/cs/src/pages/groups/ui/group-form.tsx +++ b/apps/cs/src/pages/groups/ui/group-form.tsx @@ -37,7 +37,7 @@ function GroupForm({ form }: GroupFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>그룹코드</TableHead> + <TableHead data-required>그룹코드</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -59,7 +59,7 @@ function GroupForm({ form }: GroupFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>그룹명</TableHead> + <TableHead data-required>그룹명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -81,7 +81,7 @@ function GroupForm({ form }: GroupFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>그룹구분</TableHead> + <TableHead data-required>그룹구분</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -146,7 +146,7 @@ function GroupForm({ form }: GroupFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>관리권한</TableHead> + <TableHead data-required>관리권한</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -176,7 +176,7 @@ function GroupForm({ form }: GroupFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>권한</TableHead> + <TableHead data-required>권한</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/image/ui/image-form.tsx b/apps/cs/src/pages/image/ui/image-form.tsx index 0368ace33..649d195b8 100644 --- a/apps/cs/src/pages/image/ui/image-form.tsx +++ b/apps/cs/src/pages/image/ui/image-form.tsx @@ -90,7 +90,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>이미지명</TableHead> + <TableHead data-required>이미지명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -111,7 +111,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>정렬순서</TableHead> + <TableHead data-required>정렬순서</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -137,7 +137,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>이미지유형</TableHead> + <TableHead data-required>이미지유형</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -157,7 +157,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>첨부파일</TableHead> + <TableHead data-required>첨부파일</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -269,7 +269,7 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { </TableRow> )} <TableRow> - <TableHead>사용여부</TableHead> + <TableHead data-required>사용여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/menu/ui/base-menu-form.tsx b/apps/cs/src/pages/menu/ui/base-menu-form.tsx index eeae63255..ff27db932 100644 --- a/apps/cs/src/pages/menu/ui/base-menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/base-menu-form.tsx @@ -85,7 +85,7 @@ function BaseMenuForm({ form, menuCd }: BaseMenuFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>메뉴 유형</TableHead> + <TableHead data-required>메뉴 유형</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/menu/ui/type-menu-form.tsx b/apps/cs/src/pages/menu/ui/type-menu-form.tsx index eeb50e805..41c0741e8 100644 --- a/apps/cs/src/pages/menu/ui/type-menu-form.tsx +++ b/apps/cs/src/pages/menu/ui/type-menu-form.tsx @@ -171,7 +171,7 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) { )} {(menuType === "CONTENTS" || menuType === "BOARD") && ( <TableRow> - <TableHead>메뉴 평가 사용 여부</TableHead> + <TableHead data-required>메뉴 평가 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -237,7 +237,7 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>출력 여부</TableHead> + <TableHead data-required>출력 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -268,7 +268,7 @@ function TypeMenuForm({ form, menuType }: TypeMenuFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용 여부</TableHead> + <TableHead data-required>사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/module/ui/module-form.tsx b/apps/cs/src/pages/module/ui/module-form.tsx index 8c6e7face..c4e012722 100644 --- a/apps/cs/src/pages/module/ui/module-form.tsx +++ b/apps/cs/src/pages/module/ui/module-form.tsx @@ -38,7 +38,7 @@ function ModuleForm({ form, authorizationNo, ...props }: BannerFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>API명</TableHead> + <TableHead data-required>API명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -59,7 +59,7 @@ function ModuleForm({ form, authorizationNo, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>API URL</TableHead> + <TableHead data-required>API URL</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -80,7 +80,7 @@ function ModuleForm({ form, authorizationNo, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>요청 메소드</TableHead> + <TableHead data-required>요청 메소드</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -100,7 +100,7 @@ function ModuleForm({ form, authorizationNo, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>정렬순서</TableHead> + <TableHead data-required>정렬순서</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -126,7 +126,7 @@ function ModuleForm({ form, authorizationNo, ...props }: BannerFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용여부</TableHead> + <TableHead data-required>사용여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/organization/ui/organization-form.tsx b/apps/cs/src/pages/organization/ui/organization-form.tsx index 438ed3549..3b5d3659d 100644 --- a/apps/cs/src/pages/organization/ui/organization-form.tsx +++ b/apps/cs/src/pages/organization/ui/organization-form.tsx @@ -87,7 +87,7 @@ function OrganizationForm({ </colgroup> <TableBody> <TableRow> - <TableHead>조직명</TableHead> + <TableHead data-required>조직명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -106,7 +106,7 @@ function OrganizationForm({ )} /> </TableCell> - <TableHead>정렬순서</TableHead> + <TableHead data-required>정렬순서</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/popup/ui/popup-form.tsx b/apps/cs/src/pages/popup/ui/popup-form.tsx index 3147542ed..4580fa19e 100644 --- a/apps/cs/src/pages/popup/ui/popup-form.tsx +++ b/apps/cs/src/pages/popup/ui/popup-form.tsx @@ -80,7 +80,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </colgroup> <TableBody> <TableRow> - <TableHead>제목</TableHead> + <TableHead data-required>제목</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -101,7 +101,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>팝업 크기</TableHead> + <TableHead data-required>팝업 크기</TableHead> <TableCell className="border"> <div className="flex items-center gap-1"> <FormField @@ -149,7 +149,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>팝업 위치</TableHead> + <TableHead data-required>팝업 위치</TableHead> <TableCell className="border"> <div className="flex items-center gap-1"> <FormField @@ -197,7 +197,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>팝업 유형</TableHead> + <TableHead data-required>팝업 유형</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -216,7 +216,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>콘텐츠 유형</TableHead> + <TableHead data-required>콘텐츠 유형</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -297,7 +297,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>팝업 그만 보기 사용 여부</TableHead> + <TableHead data-required>팝업 그만 보기 사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -327,7 +327,7 @@ function PopupForm<T extends PopupFormData | PopupUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>사용 여부</TableHead> + <TableHead data-required>사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/role/ui/role-form.tsx b/apps/cs/src/pages/role/ui/role-form.tsx index cd54d1e0b..355872c9e 100644 --- a/apps/cs/src/pages/role/ui/role-form.tsx +++ b/apps/cs/src/pages/role/ui/role-form.tsx @@ -53,7 +53,7 @@ function RoleForm({ roleId, form, ...props }: RoleFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>권한ID</TableHead> + <TableHead data-required>권한ID</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -95,7 +95,7 @@ function RoleForm({ roleId, form, ...props }: RoleFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>권한명</TableHead> + <TableHead data-required>권한명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -116,7 +116,7 @@ function RoleForm({ roleId, form, ...props }: RoleFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>권한내용</TableHead> + <TableHead data-required>권한내용</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -137,7 +137,7 @@ function RoleForm({ roleId, form, ...props }: RoleFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>관리권한여부</TableHead> + <TableHead data-required>관리권한여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -166,7 +166,7 @@ function RoleForm({ roleId, form, ...props }: RoleFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용여부</TableHead> + <TableHead data-required>사용여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/schedule/ui/schedule-form.tsx b/apps/cs/src/pages/schedule/ui/schedule-form.tsx index 4b0fb4f4e..2ab172b8d 100644 --- a/apps/cs/src/pages/schedule/ui/schedule-form.tsx +++ b/apps/cs/src/pages/schedule/ui/schedule-form.tsx @@ -66,7 +66,7 @@ function ScheduleForm<T extends ScheduleFormData | ScheduleUpdateFormData>({ </colgroup> <TableBody> <TableRow> - <TableHead>제목</TableHead> + <TableHead data-required>제목</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -87,7 +87,7 @@ function ScheduleForm<T extends ScheduleFormData | ScheduleUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>일정 기간</TableHead> + <TableHead data-required>일정 기간</TableHead> <TableCell className="border"> <div className="flex items-center gap-4"> <div className="flex items-center gap-2"> @@ -243,7 +243,7 @@ function ScheduleForm<T extends ScheduleFormData | ScheduleUpdateFormData>({ </TableCell> </TableRow> <TableRow> - <TableHead>일정 유형</TableHead> + <TableHead data-required>일정 유형</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/site/ui/site-form.tsx b/apps/cs/src/pages/site/ui/site-form.tsx index ffd03e7f4..e6aabcde9 100644 --- a/apps/cs/src/pages/site/ui/site-form.tsx +++ b/apps/cs/src/pages/site/ui/site-form.tsx @@ -70,7 +70,7 @@ function SiteForm({ form, siteId, ...props }: SiteFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사이트 구분</TableHead> + <TableHead data-required>사이트 구분</TableHead> <TableCell className="border"> <div className="flex gap-2"> <FormField @@ -122,7 +122,7 @@ function SiteForm({ form, siteId, ...props }: SiteFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사이트명</TableHead> + <TableHead data-required>사이트명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -287,7 +287,7 @@ function SiteForm({ form, siteId, ...props }: SiteFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>기본 사이트 여부</TableHead> + <TableHead data-required>기본 사이트 여부</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -316,7 +316,7 @@ function SiteForm({ form, siteId, ...props }: SiteFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용 여부</TableHead> + <TableHead data-required>사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/survey/ui/question-form.tsx b/apps/cs/src/pages/survey/ui/question-form.tsx index 3ea196f8c..77a1803cb 100644 --- a/apps/cs/src/pages/survey/ui/question-form.tsx +++ b/apps/cs/src/pages/survey/ui/question-form.tsx @@ -41,7 +41,7 @@ function QuestionForm({ form, actionSlot, handleSave }: QuestionFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>문항순번</TableHead> + <TableHead data-required>문항순번</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -66,7 +66,7 @@ function QuestionForm({ form, actionSlot, handleSave }: QuestionFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>문항유형</TableHead> + <TableHead data-required>문항유형</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -87,7 +87,7 @@ function QuestionForm({ form, actionSlot, handleSave }: QuestionFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>문항내용</TableHead> + <TableHead data-required>문항내용</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/survey/ui/survey-form.tsx b/apps/cs/src/pages/survey/ui/survey-form.tsx index 015a667c3..d77952922 100644 --- a/apps/cs/src/pages/survey/ui/survey-form.tsx +++ b/apps/cs/src/pages/survey/ui/survey-form.tsx @@ -29,7 +29,7 @@ function SurveyForm({ form, ...props }: SurveyFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>설문 제목</TableHead> + <TableHead data-required>설문 제목</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -50,7 +50,7 @@ function SurveyForm({ form, ...props }: SurveyFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>설문 목적</TableHead> + <TableHead data-required>설문 목적</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/template/ui/template-form.tsx b/apps/cs/src/pages/template/ui/template-form.tsx index 8716afe00..13ef1a2c8 100644 --- a/apps/cs/src/pages/template/ui/template-form.tsx +++ b/apps/cs/src/pages/template/ui/template-form.tsx @@ -39,7 +39,7 @@ function TemplateForm({ form, tmpltSn, ...props }: TemplateFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>템플릿 구분</TableHead> + <TableHead data-required>템플릿 구분</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -59,7 +59,7 @@ function TemplateForm({ form, tmpltSn, ...props }: TemplateFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>템플릿명</TableHead> + <TableHead data-required>템플릿명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -80,7 +80,7 @@ function TemplateForm({ form, tmpltSn, ...props }: TemplateFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>템플릿 내용</TableHead> + <TableHead data-required>템플릿 내용</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/terms/ui/terms-form.tsx b/apps/cs/src/pages/terms/ui/terms-form.tsx index df436e63a..9f0b639ce 100644 --- a/apps/cs/src/pages/terms/ui/terms-form.tsx +++ b/apps/cs/src/pages/terms/ui/terms-form.tsx @@ -39,7 +39,7 @@ function TermsForm({ form, trmsSn, ...props }: TermsFormProps) { </colgroup> <TableBody> <TableRow> - <TableHead>약관 구분</TableHead> + <TableHead data-required>약관 구분</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -59,7 +59,7 @@ function TermsForm({ form, trmsSn, ...props }: TermsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>약관명</TableHead> + <TableHead data-required>약관명</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -80,7 +80,7 @@ function TermsForm({ form, trmsSn, ...props }: TermsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>약관 내용</TableHead> + <TableHead data-required>약관 내용</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -99,7 +99,7 @@ function TermsForm({ form, trmsSn, ...props }: TermsFormProps) { </TableCell> </TableRow> <TableRow> - <TableHead>사용 여부</TableHead> + <TableHead data-required>사용 여부</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/pages/users/ui/users-form.tsx b/apps/cs/src/pages/users/ui/users-form.tsx index 0ddfde713..7920ce758 100644 --- a/apps/cs/src/pages/users/ui/users-form.tsx +++ b/apps/cs/src/pages/users/ui/users-form.tsx @@ -179,7 +179,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ <TableBody> {/* 아이디 */} <TableRow> - <TableHead>아이디</TableHead> + <TableHead data-required>아이디</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -223,7 +223,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ {/* 비밀번호 */} <TableRow> - <TableHead>비밀번호</TableHead> + <TableHead data-required>비밀번호</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -270,7 +270,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ {/* 비밀번호 힌트 */} <TableRow> - <TableHead>비밀번호 힌트</TableHead> + <TableHead data-required>비밀번호 힌트</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -316,7 +316,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ {/* 이름 */} <TableRow> - <TableHead>이름</TableHead> + <TableHead data-required>이름</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -489,7 +489,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ {/* 기관구분 */} <TableRow> - <TableHead>기관구분</TableHead> + <TableHead data-required>기관구분</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -571,7 +571,7 @@ function UsersForm<T extends UserSaveData | UserUpdateData>({ {/* 소속 */} <TableRow> - <TableHead>소속</TableHead> + <TableHead data-required>소속</TableHead> <TableCell className="border"> <FormField control={form.control} diff --git a/apps/cs/src/widgets/post/ui/post-form.tsx b/apps/cs/src/widgets/post/ui/post-form.tsx index 55cd85657..2e15ef13a 100644 --- a/apps/cs/src/widgets/post/ui/post-form.tsx +++ b/apps/cs/src/widgets/post/ui/post-form.tsx @@ -77,7 +77,7 @@ function PostForm<T extends PostFormData | PostUpdateFormData>({ </colgroup> <TableBody> <TableRow> - <TableHead>제목</TableHead> + <TableHead data-required>제목</TableHead> <TableCell className="border"> <FormField control={form.control} @@ -120,7 +120,7 @@ function PostForm<T extends PostFormData | PostUpdateFormData>({ </TableRow> {!userInfo?.userUnqId && ( <TableRow> - <TableHead>비밀번호</TableHead> + <TableHead data-required>비밀번호</TableHead> <TableCell className="border"> <FormField control={form.control} From 02a6c7019ff311d562377987a7d38300bd8a6ad3 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 11 Jul 2025 11:25:11 +0900 Subject: [PATCH 090/159] =?UTF-8?q?[apps/cs]=20feat:=20=EC=BD=98=ED=85=90?= =?UTF-8?q?=EC=B8=A0=20=EB=B0=98=EB=A0=A4=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(CS=5FUT01020115)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entities/content/api/contents-service.ts | 9 ++++++ .../content/model/contents-interface.ts | 1 + apps/cs/src/pages/contents/ui/modify-page.tsx | 30 +++++++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/apps/cs/src/entities/content/api/contents-service.ts b/apps/cs/src/entities/content/api/contents-service.ts index 00d2a8c67..347764aa7 100644 --- a/apps/cs/src/entities/content/api/contents-service.ts +++ b/apps/cs/src/entities/content/api/contents-service.ts @@ -85,6 +85,15 @@ export class ContentsApiService implements ContentsService { `${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}/approve`, ); } + + public async rejectContents( + contsSn: number, + contsVer: number, + ): Promise<void> { + await client.put( + `${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}/reject`, + ); + } } export const ContentsApi = new ContentsApiService(); diff --git a/apps/cs/src/entities/content/model/contents-interface.ts b/apps/cs/src/entities/content/model/contents-interface.ts index 72456149b..7709eea08 100644 --- a/apps/cs/src/entities/content/model/contents-interface.ts +++ b/apps/cs/src/entities/content/model/contents-interface.ts @@ -97,4 +97,5 @@ export interface ContentsService { deleteContents(contsSn: number, contsVer: number): Promise<void>; requestApprove(contsSn: number, contsVer: number): Promise<void>; approveContents(contsSn: number, contsVer: number): Promise<void>; + rejectContents(contsSn: number, contsVer: number): Promise<void>; } diff --git a/apps/cs/src/pages/contents/ui/modify-page.tsx b/apps/cs/src/pages/contents/ui/modify-page.tsx index 8bf3b629d..e783e9c1c 100644 --- a/apps/cs/src/pages/contents/ui/modify-page.tsx +++ b/apps/cs/src/pages/contents/ui/modify-page.tsx @@ -97,6 +97,16 @@ function ModifyPage({ sequential }: { sequential: string }) { }, }); + const { mutateAsync: rejectContents } = useMutationWrapper({ + mutationFn: () => ContentsApi.rejectContents(contsSn, contsVer), + onSuccess: () => { + alert("반려되었습니다."); + queryClient.invalidateQueries({ + queryKey: [ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS], + }); + }, + }); + const form = useForm<ContentsFormData>({ resolver: zodResolver(contentsFormSchema), values: contentsDetail, @@ -107,14 +117,20 @@ function ModifyPage({ sequential }: { sequential: string }) { (contentsVersionList?.content?.[0]?.contsVer ?? 0) > 1; const onRequestApprove = async () => { - const message = - "승인 요청하면 더이상 내용을 수정할 수 없습니다.\n요청하시겠습니까?"; - if (await confirm(message)) requestApprove(); + if ( + await confirm( + "승인 요청하면 더이상 내용을 수정할 수 없습니다.\n요청하시겠습니까?", + ) + ) + requestApprove(); }; const onApprove = async () => { - const message = "승인하시겠습니까?"; - if (await confirm(message)) approveContents(); + if (await confirm("승인하시겠습니까?")) approveContents(); + }; + + const onReject = async () => { + if (await confirm("반려하시겠습니까?")) rejectContents(); }; useEffect(() => { @@ -158,7 +174,9 @@ function ModifyPage({ sequential }: { sequential: string }) { {approveStatus === CONTENTS_APPROVE_STATUS.REQUESTED && ( <> <Button onClick={onApprove}>승인</Button> - <Button color="gray">반려</Button> + <Button color="gray" onClick={onReject}> + 반려 + </Button> </> )} </div> From 30c037f53bee9422337fd3d94bdd7184cdeb6266 Mon Sep 17 00:00:00 2001 From: changwng <changwng@gmail.com> Date: Fri, 11 Jul 2025 11:38:35 +0900 Subject: [PATCH 091/159] =?UTF-8?q?[privacylog]=20CS=5FUT06010101=20inqDt,?= =?UTF-8?q?desc=20=EB=A1=9C=20=EC=9D=B4=EB=A0=A5=20=EC=97=AD=EC=88=9C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/privacylog/ui/privacylog-page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx index a7b26dd4c..8207ca9e6 100644 --- a/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx +++ b/apps/cs/src/pages/privacylog/ui/privacylog-page.tsx @@ -43,7 +43,7 @@ function PrivacyLogPage() { inqInfoKeyword: "", inqDtStart: dayjs().subtract(7, "day").format("YYYY-MM-DD"), inqDtEnd: dayjs().format("YYYY-MM-DD"), - sort: "inqDt,asc", + sort: "inqDt,desc", }); const query = useQuery({ From e74d554992dd00c9af0292b2b55fc7f5c812fca5 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 11 Jul 2025 11:49:48 +0900 Subject: [PATCH 092/159] =?UTF-8?q?fix:=20eslint=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/code/ui/lwpocode-section.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/cs/src/pages/code/ui/lwpocode-section.tsx b/apps/cs/src/pages/code/ui/lwpocode-section.tsx index ac3d8218c..9692c842d 100644 --- a/apps/cs/src/pages/code/ui/lwpocode-section.tsx +++ b/apps/cs/src/pages/code/ui/lwpocode-section.tsx @@ -24,7 +24,7 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { pageIndex: 0, pageSize: 10, }); - + const query = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.LWPO_CODE, upCd, searchParams, pagination], queryFn: () => @@ -34,17 +34,16 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { page: pagination.pageIndex, size: pagination.pageSize, }), - enabled: !!upCd , + enabled: !!upCd, placeholderData: keepPreviousData, - }); + }); // 등록/수정 후 목록 재조회 콜백 - const handleAfterSave = () => { + const handleAfterSave = () => { query.refetch(); }; const columns = getColumns(handleAfterSave); - - + const { mutateAsync: codeRefreshAll } = useMutation({ mutationFn: LwpoCodeApi.codeRefreshAll, onSuccess: () => { @@ -125,8 +124,7 @@ function LwpoCodeSection({ upCd }: LwpoCodeSectionProps) { <LwpoCodeManagementDialog upCd={upCd} open={dialogOpen} - upCd={upCd} - onOpenChange={setDialogOpen} + onOpenChange={setDialogOpen} onAfterSave={handleAfterSave} > <Button>등록</Button> From 6330c125c76a079295e571e5cd4c56a9d971268c Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Fri, 11 Jul 2025 16:10:10 +0900 Subject: [PATCH 093/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=EC=8B=9C=EC=84=A4?= =?UTF-8?q?=ED=98=84=ED=99=A9,=20=EC=9E=AC=EC=9D=B4=EC=9A=A9=EC=8B=A4?= =?UTF-8?q?=EC=A0=81=ED=98=84=ED=99=A9,=20=EC=A7=80=EB=8F=84=EC=A0=90?= =?UTF-8?q?=EA=B2=80=ED=98=84=ED=99=A9=20=EC=97=91=EC=85=80=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=EC=8B=9C=20=EB=B9=88=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=A9=B4=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/htdflSttn/page.tsx | 25 ++++--- .../ruseFcltMng/fcltSttn/rainSttn/page.tsx | 18 +++-- .../ruseFcltMng/fcltSttn/rswtSttn/page.tsx | 19 ++++-- .../prfmncSttn/chkgdnSttn/page.tsx | 13 +++- .../prfmncSttn/pbnstPrfmncSttn/page.tsx | 16 ++--- apps/wr/components/lib/func/TableData.tsx | 67 ++++++++++--------- apps/wr/public/locales/ko/message.json | 7 +- 7 files changed, 103 insertions(+), 62 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index e7685ebbd..d8a1cef52 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -34,6 +34,8 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { excelHtdflSttnParsing } from "@/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function HtdflSttn() { const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore( @@ -42,7 +44,8 @@ export default function HtdflSttn() { const { htdflSttnRes, htdflSttnResCount } = htdflSttn; const ref = useRef<ReturnType>({} as ReturnType); - + const isDownloadTriggered = useRef(false); + const { t } = useTranslation('base'); const [pageNation, setPageNation] = useState(1); const [isChHead, setIsChHead] = useState(false); const [resetPage, isResetPage] = useState(false); @@ -59,12 +62,6 @@ export default function HtdflSttn() { }>({ isOpen: false, chBuilding: [] }); const [fcltNm, setFcltNm] = useState<string>(""); - const excelClick = useCallback(() => { - // 최신 검색 조건 반영 - const con = getConValue(); - htdflSttnSearch(true, 1, String(htdflSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); - }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, htdflSttnResCount]); - useEffect(() => { htdflSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd); isResetPage(false) @@ -108,16 +105,27 @@ export default function HtdflSttn() { setDetailModal({ isOpen: true, data: bdstTable[index] }); } }; + + const excelClick = useCallback(() => { + isDownloadTriggered.current = true; + htdflSttnSearch(true, 1, String(htdflSttnResCount), String(getConValue()), fcltNm, code.cityCd, code.sggCd); + }, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, htdflSttnResCount]); + useEffect(() => { + if (!isDownloadTriggered.current) { + return; + } if (htdflSttn.excelList.length > 0) { - if (htdflSttn.excelList.length === 0) return; excelDownload( htdflSttn.excelList, "온배수시설 현황", "sample_htdflSttn.xlsx", "A1:R3" ); + } else { + toast.error(t('excelDownErrMsg')); } + isDownloadTriggered.current = false; }, [htdflSttn.excelList, code]); useEffect(() => { @@ -256,6 +264,7 @@ export default function HtdflSttn() { body={<SttnDetailModal type={"HTB"} formObj={detailModal.data} />} /> </ContentsDiv> + <Toaster position="top-center" /> </> ); } diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx index 78c11660c..74ea41ce0 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -34,6 +34,8 @@ import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeCo import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function RainSttn() { const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( @@ -47,6 +49,7 @@ export default function RainSttn() { const [bdstTable, setBdstTable] = useState<customRainBdst[]>(); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() const [resetPage, isResetPage] = useState(false); + const isDownloadTriggered = useRef(false); const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }) const [bdstChgProps, setBdstChgProps] = useState<{ @@ -54,7 +57,7 @@ export default function RainSttn() { chBuilding: chgBuilding[]; }>({ isOpen: false, chBuilding: [] }); const [fcltNm, setFcltNm] = useState<string>(""); - + const { t } = useTranslation('base'); const cellClick = (index: number | undefined, headId: string) => { if (headId !== 'chBuildingYn' && index !== undefined && bdstTable !== undefined) { setDetailModal({ isOpen: true, data: bdstTable[index] }) @@ -135,21 +138,25 @@ export default function RainSttn() { }, [pageNation]); useEffect(() => { + if (!isDownloadTriggered.current) { + return; + } if (rainSttn.excelList.length > 0) { - if (rainSttn.excelList.length === 0) return; excelDownload( rainSttn.excelList, "빗물재이용시설 현황", "sample_rainSttn.xlsx", "A1:W3" ); + } else { + toast.error(t('excelDownErrMsg')); } + isDownloadTriggered.current = false; }, [rainSttn.excelList]); const excelClick = useCallback(() => { - // 최신 검색 조건 반영 - const con = getConValue(); - rainSttnSearch(true, 1, String(rainSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + isDownloadTriggered.current = true; + rainSttnSearch(true, 1, String(rainSttnResCount), String(getConValue()), fcltNm, code.cityCd, code.sggCd); }, [rainSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, rainSttnResCount]); return ( @@ -276,6 +283,7 @@ export default function RainSttn() { }} /> </ContentsDiv> + <Toaster position="top-center" /> </> ); } diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index edf1f6ac0..e28286add 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -31,6 +31,8 @@ import ListDiv from "@common/business_components/ui/list_div"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; +import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function RswtSttn() { const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore( @@ -43,6 +45,7 @@ export default function RswtSttn() { const [resetPage, isResetPage] = useState(false); const ref = useRef<ReturnType>({} as ReturnType); const [bdstTable, setBdstTable] = useState<customRswtBdst[]>(); + const isDownloadTriggered = useRef(false); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false }) @@ -51,7 +54,7 @@ export default function RswtSttn() { chBuilding: chgBuilding[]; }>({ isOpen: false, chBuilding: [] }); const [fcltNm, setFcltNm] = useState<string>(""); - + const { t } = useTranslation('base'); const cellClick = (index: number | undefined, headId: string) => { if (headId !== 'chBuildingYn' && index !== undefined && bdstTable !== undefined) { @@ -124,22 +127,25 @@ export default function RswtSttn() { }, [code, rswtSttnRes]); useEffect(() => { + if (!isDownloadTriggered.current) { + return; + } if (rswtSttn.excelList.length > 0) { - if (rswtSttn.excelList.length === 0) return; excelDownload( rswtSttn.excelList, "중수도시설 현황", "sample_rswtSttn.xlsx", "A1:W3", ); + } else { + toast.error(t('excelDownErrMsg')); } + isDownloadTriggered.current = false; }, [rswtSttn.excelList]); const excelClick = useCallback(() => { - // 최신 검색 조건 반영 - const con = getConValue(); - - rswtSttnSearch(true, 1, String(rswtSttnResCount), String(con), fcltNm, code.cityCd, code.sggCd); + isDownloadTriggered.current = true; + rswtSttnSearch(true, 1, String(rswtSttnResCount), String(getConValue()), fcltNm, code.cityCd, code.sggCd); }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, rswtSttnResCount]); useEffect(() => { @@ -276,6 +282,7 @@ export default function RswtSttn() { }} /> </ContentsDiv> + <Toaster position="top-center" /> </> ); } diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx index a191de9ee..6f1bd97f5 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/chkgdnSttn/page.tsx @@ -23,7 +23,8 @@ import { import ListDiv from "@common/business_components/ui/list_div"; import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useState } from "react"; -import { Toaster } from "react-hot-toast"; +import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function Page() { const { @@ -97,7 +98,6 @@ export default function Page() { useEffect(() => { if (!rainChkSttn.isInit) { isRainSttn(true) - console.log("여기", rainPageSize) rainChkSttnInit(1, rainPageSize, new Date().getFullYear().toString(), commonCd); setIsModal({ data: {}, open: false }); } @@ -119,8 +119,13 @@ export default function Page() { }, [isModal] ); + const { t } = useTranslation('base'); const excelDown = () => { if (rainChkSttn.sttnExcelList && selFcltDiv === "RNB") { + if (!rainChkSttn.sttnExcelList || rainChkSttn.sttnExcelList.length === 0) { + toast.error(t('excelDownErrMsg')); + return; + } excelDownload( rainChkSttn.sttnExcelList, "빗물이용시설 지도점검 현황", @@ -129,6 +134,10 @@ export default function Page() { 3 ); } else if (rswtChkSttn.sttnExcelList && selFcltDiv === "RST") { + if (!rswtChkSttn.sttnExcelList || rswtChkSttn.sttnExcelList.length === 0) { + toast.error(t('excelDownErrMsg')); + return; + } excelDownload( rswtChkSttn.sttnExcelList, "중수도시설 지도점검 현황", diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index c60ba1673..731ea1511 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -11,6 +11,7 @@ import ListDiv from "@common/business_components/ui/list_div"; import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function PbnstPrfmncSttn() { const { @@ -33,12 +34,16 @@ export default function PbnstPrfmncSttn() { const ref = useRef<ReturnType>({} as ReturnType); const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>(); const [pbnRuseNm, setPbnRuseNm] = useState<string>(""); - + const { t } = useTranslation('base'); const [searchYear, setSearchYear] = useState<string>( String(new Date().getFullYear()) ); const [excelData, setExcelData] = useState<any[]>([]); const excelClick = useCallback(() => { + if (!excelData || excelData.length === 0) { + toast.error(t('excelDownErrMsg')); + return; + } excelDownload( excelData, "하수재이용실적 현황", @@ -524,14 +529,7 @@ export default function PbnstPrfmncSttn() { selectUnitWaterShedData={code.lgbsnCd} selectMiddleRegionData={code.mdmbsnCd} selectEnvPartData={code.lclgvrnmntCd} - rightChildren={<Button - className={btnClass} - onClick={() => { - setIsChHead(true); - }} - > - 조회항목설정 - </Button>} + rightChildren={undefined} leftChildren={<div className="col-span-5"> <div className="flex flex-row"> <div className="flex flex-row items-center"> diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index 8bed17187..2046bd15e 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -57,7 +57,7 @@ export const rswtChkTableData = (chkData: rswtChkZodType[]) => { const makeRswtData: any[] = []; - if(chkData&&chkData.length>0){ + if (chkData && chkData.length > 0) { chkData?.forEach((root) => { root.rswtrDetails.forEach((detail) => { @@ -99,10 +99,11 @@ export const chRowspanTable = ( let order = 0 // rowspan된 셀 렌더링 여부 추적용 const renderedMap = new Map<string, Set<number>>(); - + return ( <> - {makeTableData.map((row, rowIndex) => ( + {/* {makeTableData.map((row, rowIndex) => ( */} + {makeTableData && makeTableData.length > 0 ? (makeTableData.map((row, rowIndex) => ( <TableRow key={rowIndex}> {headList .map((head) => { @@ -177,7 +178,13 @@ export const chRowspanTable = ( })} </TableRow> - ))} + ))) : ( + <TableRow> + <TableCell colSpan={headList.length} className="h-24 text-center text-gray-500"> + 조회된 결과가 없습니다. + </TableCell> + </TableRow> + )} </> ); }; @@ -235,44 +242,44 @@ export const InputTableBody = ( } return span; }; - return ( + return ( <> {chgRes.map((data, dataIndex) => { // 소계/총합계 행 판별 const isSubTotal = data["용수명"] === "소계"; const isTotal = data["구분"] === 0; - + const bgClass = isTotal ? "bg-[#d5e1eb] font-bold" : isSubTotal - ? "bg-[#e6eef5] font-semibold" - : ""; + ? "bg-[#e6eef5] font-semibold" + : ""; return ( <TableRow key={dataIndex + "row"}> {headList.map((head, headIndex) => { - // 총합계 행이면 "구분"에서 colSpan=2로 병합 - if ( - data["구분"] === 0 && - head.id === "구분" - ) { - return ( - <TableCell - key={head.id + headIndex} - colSpan={2} - className="font-bold text-center bg-[#d5e1eb]" - > - 총합계 - </TableCell> - ); - } - // 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음 - if ( - data["구분"] === 0 && - head.id === "용수명" - ) { - return null; - } + // 총합계 행이면 "구분"에서 colSpan=2로 병합 + if ( + data["구분"] === 0 && + head.id === "구분" + ) { + return ( + <TableCell + key={head.id + headIndex} + colSpan={2} + className="font-bold text-center bg-[#d5e1eb]" + > + 총합계 + </TableCell> + ); + } + // 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음 + if ( + data["구분"] === 0 && + head.id === "용수명" + ) { + return null; + } // mergeCell 처리 if (head.mergeCell) { const rowSpan = getRowSpan(chgRes, head.id, dataIndex); diff --git a/apps/wr/public/locales/ko/message.json b/apps/wr/public/locales/ko/message.json index 78219a539..d0e6ee02f 100644 --- a/apps/wr/public/locales/ko/message.json +++ b/apps/wr/public/locales/ko/message.json @@ -8,12 +8,15 @@ "noChangedErrMsg": "변경사항이 없습니다.", "dateErrMsg": "시작년도를 종료년도 이후로 설정할 수 없습니다.", "fileDateErrMsg": "파일업로드 이전에 등록년도를 작성해주세요.", + "isDeleteMsg": "선택한 정보를 삭제하시겠습니까?", + "isUpdateMsg": "수정한 정보를 저장하시겠습니까?", + "excelDownErrMsg": "다운로드할 데이터가 없습니다.", "alreadyInsertedErrMsg": "사업자번호 {{num}}(은)는 이미 등록되었습니다. 다시 등록해주세요.", "saveRowErrMsg": "수정을 원하는 행을 선택하고 저장버튼을 눌러주세요.", - "costCalcErrMsg":"공사비 계산 진행 후 저장을 눌러주세요", + "costCalcErrMsg":"공사비 계산 진행 후 저장을 눌러주세요", "maxYearErrMsg": "최대 {{year}}년까지 선택가능합니다.", - "checkQtyMsg": "요구수량(M3/d)을 확인해주세요 계산할수 없습니다." + "checkQtyMsg": "요구수량(M3/d)을 확인해주세요 계산할 수 없습니다." } From ab606ad65d266dfe2cc89645d4de82991e9fe8c7 Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Fri, 11 Jul 2025 17:39:17 +0900 Subject: [PATCH 094/159] =?UTF-8?q?[apps/cs]=20fix:=20=EB=8B=B4=EB=8B=B9?= =?UTF-8?q?=EC=9E=90=20=EC=A1=B0=ED=9A=8C=20=EB=8B=A4=EC=9D=B4=EC=96=BC?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?(CS=5FUT01020108)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/menu/lib/utils.ts | 1 + .../menu/ui/organization-search-dialog.tsx | 58 ++++++++++++++----- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/apps/cs/src/pages/menu/lib/utils.ts b/apps/cs/src/pages/menu/lib/utils.ts index 0e219047d..a5cb921a6 100644 --- a/apps/cs/src/pages/menu/lib/utils.ts +++ b/apps/cs/src/pages/menu/lib/utils.ts @@ -153,6 +153,7 @@ export const filterUserOrganizationTreeDataByKeyword = ( ): NodeModel<TreeUserOrganization | TreeUser>[] => { return Array.from( treeData.reduce((matchedNodes, node) => { + if (node.data && "ognzSn" in node.data) return matchedNodes; // 조직 노드는 필터링 제외 if (!node.text.includes(keyword)) return matchedNodes; matchedNodes.add(node); diff --git a/apps/cs/src/pages/menu/ui/organization-search-dialog.tsx b/apps/cs/src/pages/menu/ui/organization-search-dialog.tsx index 19e3fcf87..eb942fe11 100644 --- a/apps/cs/src/pages/menu/ui/organization-search-dialog.tsx +++ b/apps/cs/src/pages/menu/ui/organization-search-dialog.tsx @@ -12,7 +12,9 @@ import { import { Button, Dialog, + DialogClose, DialogContent, + DialogFooter, DialogHeader, DialogTitle, DialogTrigger, @@ -52,10 +54,22 @@ function OrganizationSearchDialog({ }); const handleSelectNode = (node: NodeModel<TreeModel>) => { + if (node.data && "ognzSn" in node.data) return; setSelectedNode(node); handleUserSelect(node.data as TreeUser); }; + const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { + e.preventDefault(); + e.stopPropagation(); + setTree(filterUserOrganizationTreeDataByKeyword(treeData ?? [], keyword)); + }; + + const handleReset = () => { + setKeyword(""); + setTree(treeData ?? []); + }; + useEffect(() => { setTree(treeData ?? []); }, [treeData]); @@ -73,21 +87,25 @@ function OrganizationSearchDialog({ <DialogTitle>담당자 조회</DialogTitle> </DialogHeader> <div className="flex flex-col gap-4"> - <div className="card card-border !m-0 flex w-full items-center gap-2"> - <Input - className="h-[2.5rem] !text-[1.3rem]" - value={keyword} - onChange={(e) => setKeyword(e.target.value)} - /> - <Button - size="sm" - onClick={() => - setTree(filterUserOrganizationTreeDataByKeyword(tree, keyword)) - } - > - <i className="diveicon di-search text-base" /> - 조회 - </Button> + <div className="card card-border !m-0 w-full"> + <form onSubmit={handleSubmit} className="flex items-center gap-2"> + <Input + className="h-[2.5rem] !text-[1.3rem]" + value={keyword} + onChange={(e) => setKeyword(e.target.value)} + /> + <Button type="submit" size="sm"> + 조회 + </Button> + <Button + type="button" + size="sm" + color="white" + onClick={handleReset} + > + 초기화 + </Button> + </form> </div> <div className="h-[36rem] overflow-auto"> <DndProvider backend={MultiBackend} options={getBackendOptions()}> @@ -116,6 +134,16 @@ function OrganizationSearchDialog({ </DndProvider> </div> </div> + <DialogFooter> + <DialogClose asChild> + <Button color="white" onClick={() => setSelectedNode(null)}> + 취소 + </Button> + </DialogClose> + <DialogClose asChild> + <Button disabled={!selectedNode}>확인</Button> + </DialogClose> + </DialogFooter> </DialogContent> </Dialog> ); From fc424a2f46a59d170174362adce300f40cb8944a Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Fri, 11 Jul 2025 18:03:48 +0900 Subject: [PATCH 095/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84=EC=8B=9C=EC=84=A4=20=EB=93=B1=EB=A1=9D,=20=EC=9E=A0?= =?UTF-8?q?=EC=9E=AC=EC=88=98=EC=9A=94=EC=B2=98=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=EC=8B=9C=20=EC=BB=A8?= =?UTF-8?q?=ED=8E=8C=EC=B0=BD=20=EB=9D=84=EC=9A=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wr/app/matMng/coMng/ldrmntCoSttn/page.tsx | 22 +- apps/wr/components/lib/func/commom.tsx | 64 +- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 801 +++++++++--------- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 30 +- 4 files changed, 488 insertions(+), 429 deletions(-) diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx index d5861e173..e14b25b55 100644 --- a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -5,6 +5,7 @@ import { btnClass } from "@/app/store/common/code"; import { type customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn"; import { ldrmntHeadListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList"; import { + confirmToast, excelDownload, getCity, tableData @@ -29,9 +30,10 @@ import ListDiv from "@common/business_components/ui/list_div"; import { Button } from "@common/components/ui"; import { useCallback, useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function LdrmntCoSttn() { - const { code, ldrmnt, ldrmntInit, ldrmntSearch, ldrmntUpdate} = useWrStore( + const { code, ldrmnt, ldrmntInit, ldrmntSearch, ldrmntUpdate } = useWrStore( (state) => state ); const { ldrmntRes, excelList, ldrmntResCount } = ldrmnt; @@ -43,6 +45,7 @@ export default function LdrmntCoSttn() { const [searchTxt, setSearchTxt] = useState<string>(); const [excelData, setExcelData] = useState<any[]>(); const [resetPage, isResetPage] = useState(false); + const { t } = useTranslation('base'); // const [isExcelDownload, setIsExcelDownload] = useState(false); const excelClick = useCallback(() => { @@ -141,7 +144,7 @@ export default function LdrmntCoSttn() { setBdstTable(tbData); }, [ldrmntRes, code]); - + useEffect(() => { const transData = Array.isArray(excelList) ? excelList : [excelList]; const exData = tableData(transData, { code }); @@ -261,10 +264,17 @@ export default function LdrmntCoSttn() { setDetailModal({ ...detailModal, isOpen: !detailModal.isOpen }) }} bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"} - body={<CoDetailModal formObj={detailModal.data} onFormSubmit={async (value)=>{ - await ldrmntUpdate(value) - setDetailModal({ ...detailModal, isOpen: false }) - ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + body={<CoDetailModal formObj={detailModal.data} onFormSubmit={async (value) => { + // confirmToast(t('isUpdateMsg'), await ldrmntUpdate(value)) + // // await ldrmntUpdate(value) + // setDetailModal({ ...detailModal, isOpen: false }) + // ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + const handleConfirm = async () => { + await ldrmntUpdate(value); + setDetailModal({ ...detailModal, isOpen: false }); + ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || ""); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); }} />} /> diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index 7d8c2ffcc..6d96b3540 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -6,24 +6,26 @@ import { filePickedBlobArray, type SheetParameter, } from "@common/business_components/ui"; +import { Button } from "@common/components/ui"; import type { RefObject } from "react"; +import toast from "react-hot-toast"; export const getCity = (val: string, sggCd: SelectDataType[]) => { - let data:any - if(val !=='0'){ + let data: any + if (val !== '0') { data = sggCd - .filter((item) => String(item.val).substring(0, 2) === val) - .map((item) => ({ - val: item.val, - text: item.text, // 한국어 텍스트 - })); - }else{ + .filter((item) => String(item.val).substring(0, 2) === val) + .map((item) => ({ + val: item.val, + text: item.text, // 한국어 텍스트 + })); + } else { data = sggCd - .map((item) => ({ - val: item.val, - text: item.text, // 한국어 텍스트 - })); + .map((item) => ({ + val: item.val, + text: item.text, // 한국어 텍스트 + })); } data.unshift({ val: "0", text: "전체" }); return data; @@ -92,7 +94,7 @@ export const excelDownload = ( export const excelArrayDownload = ( fileNm: string, sampleFile: string, - sheetArray:SheetParameter [] + sheetArray: SheetParameter[] ) => { if (!sheetArray) return; fetch(`/${sampleFile}`, {}).then(async (response) => { @@ -113,7 +115,7 @@ export const handleCommaNumberChange = ( ) => { const raw = e.target.value.replace(/,/g, ""); if (!/^\d*$/.test(raw)) return; - onChange(raw === "" ? "" : Number(raw)); + onChange(raw === "" ? "" : Number(raw)); }; @@ -124,7 +126,7 @@ export const handleMinusNumberChange = ( ) => { const raw = e.target.value.replace(/,/g, ""); if (!/^\d*$/.test(raw)) return; - onChange(raw === "" ? -1 : Number(raw)); + onChange(raw === "" ? -1 : Number(raw)); }; // 숫자입력시 , 삽입 @@ -175,14 +177,14 @@ export const getdmdMatFlag = (flag: string | undefined | null) => { case "Matched": return "매칭완료"; case "Checked": - return '검토완료'; + return '검토완료'; default: return "신청"; } }; -export const formatPhoneNumber=(tel:string) => { +export const formatPhoneNumber = (tel: string) => { const onlyNums = tel.replace(/[^0-9]/g, ''); if (onlyNums.length === 10) { return onlyNums.replace(/(\d{2})(\d{4})(\d{4})/, '$1-$2-$3'); @@ -191,4 +193,32 @@ export const formatPhoneNumber=(tel:string) => { } else { return tel; // 유효하지 않으면 빈 문자열 } +} + +export const confirmToast = (content: string, saveFunc: () => void) => { + toast((t) => ( + <span className="flex flex-col items-center"> + <div className="mb-6"> + {content} + </div> + <div className="flex flex-row space-x-2"> + <Button + size={"sm"} + onClick={() => { + saveFunc(); + toast.dismiss(t.id); + }} + > + 확인 + </Button> + <Button + size={"sm"} + onClick={() => toast.dismiss(t.id)}>취소</Button> + </div> + </span> + ), + { + id: "global-confirm-toast", // 중복 토스트 방지 + duration: Infinity, // 자동 사라짐 방지 + }); } \ No newline at end of file diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index bb62fee61..21a0923ea 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -8,6 +8,7 @@ import { } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; import { + confirmToast, formatCommaNumber, handleMinusNumberChange, } from "@/components/lib/func/commom"; @@ -21,6 +22,7 @@ import { z } from "zod"; import BdstReg from "../bdstReg/bdstReg"; import toast from "react-hot-toast"; import BdstAdd from "../bdstReg/bdstAdd"; +import { useTranslation } from "react-i18next"; export default function RainRegForm({ rainForm, @@ -40,9 +42,10 @@ export default function RainRegForm({ const defaultValues: z.infer<typeof rainZod> = rainZod.parse({}); const form = useForm<z.infer<typeof rainZod>>({ resolver: zodResolver(rainZod), - // defaultValues: defaultValues, + // defaultValues: defaultValues, }); const instlCst = form.watch(`reuseBuilding.0.instlCst`); + const { t } = useTranslation('base'); const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn] = form.watch([ "reuseBuilding.0.grntchBdstCertYn", @@ -51,15 +54,15 @@ export default function RainRegForm({ ]); const [divStyle, setDivStyle] = useState("h-[53vh]"); - useEffect(()=>{ - if(isModal===true){ + useEffect(() => { + if (isModal === true) { setDivStyle("h-[53vh] max-h-[37vh]") - }else if(readonly===true){ + } else if (readonly === true) { setDivStyle("h-[62vh]") - }else{ + } else { setDivStyle("h-[53vh]") } - },[isModal,readonly]); + }, [isModal, readonly]); const cleanRainData = (raw: any): z.infer<typeof rainZod> => { const buildings = @@ -122,7 +125,7 @@ export default function RainRegForm({ // form 값이 변경될 때마다 로그 출력 useEffect(() => { - const subscription = form.watch((value) => {}); + const subscription = form.watch((value) => { }); return () => subscription.unsubscribe(); }, [form]); @@ -139,10 +142,16 @@ export default function RainRegForm({ return; } - rainBdstReg(values, data); - if (setIsModal) setIsModal(false); + const handleConfirm = async () => { + rainBdstReg(values, data); + if (setIsModal) setIsModal(false); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); } else { - rainBdstUpdate(values, "41"); + const handleConfirm = async () => { + rainBdstUpdate(values, "41"); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); } }; @@ -174,150 +183,97 @@ export default function RainRegForm({ </div> </div> <ScrollArea className={divStyle}> - {isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>} - {isModal ? ( - <h1 className="pl-3 text-xl col-span-10 mt-4"> - 빗물이용시설 정보{" "} - </h1> - ) : ( - <></> - )} - <h1 className={formH1Class}>기본정보</h1> - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCmptnDt" - render={({ field }) => ( - <FormUi label="설치완료일"> - <DatePicker - mode="single" - field={{ - value: - field.value && !isNaN(new Date(field.value).getTime()) - ? new Date(field.value) - : new Date(), - onChange: (date: Date | undefined) => - field.onChange(date), - }} - selectClass={"w-full"} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> + {isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>} + {isModal ? ( + <h1 className="pl-3 text-xl col-span-10 mt-4"> + 빗물이용시설 정보{" "} + </h1> + ) : ( + <></> + )} + <h1 className={formH1Class}>기본정보</h1> + <div className="grid grid-cols-6 gap-2 mt-4"> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCmptnDt" + render={({ field }) => ( + <FormUi label="설치완료일"> + <DatePicker + mode="single" + field={{ + value: + field.value && !isNaN(new Date(field.value).getTime()) + ? new Date(field.value) + : new Date(), + onChange: (date: Date | undefined) => + field.onChange(date), + }} + selectClass={"w-full"} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> - <div className="col-span-3"> - <FormField - control={form.control} - name={`reuseBuilding.0.instlCst`} - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 - return ( - <FormUi label="설치비(원)"> - <Input - placeholder="1,000,000" - type="text" - className={selectClass} - readOnly={readonly} - value={ - isUnknown ? "확인불가" : formatCommaNumber(value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 + <div className="col-span-3"> + <FormField + control={form.control} + name={`reuseBuilding.0.instlCst`} + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 + return ( + <FormUi label="설치비(원)"> + <Input + placeholder="1,000,000" + type="text" + className={selectClass} + readOnly={readonly} + value={ + isUnknown ? "확인불가" : formatCommaNumber(value) } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); - }} - /> - </FormUi> - ); - }} - /> + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} + /> + </FormUi> + ); + }} + /> + </div> </div> - </div> - <div className=""> - <h1 className={formH1Class}>빗물이용시설 정보</h1> - </div> - <div> - <h2 className={formH2Class}>집수면 및 저류조</h2> - </div> - <div className="grid grid-cols-12 gap-4 mt-4 "> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.dtfcltCpct" - render={({ field }) => { - const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1 - return ( - <FormUi label="저류조 용량(m³)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - value={ - isUnknown - ? "확인불가" - : formatCommaNumber(field.value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); - }} - readOnly={readonly} - /> - </FormUi> - ); - }} - /> + <div className=""> + <h1 className={formH1Class}>빗물이용시설 정보</h1> </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.pntfColKnd" - render={({ field }) => ( - <FormUi label="집수면 종류"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={rainFcltCd} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? rainFcltCd[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div> + <h2 className={formH2Class}>집수면 및 저류조</h2> </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.pntfColArea" - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 - return ( - <div className="flex items-center gap-2"> - <FormUi label="집수면 용량(m³)"> + <div className="grid grid-cols-12 gap-4 mt-4 "> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rainyObj.dtfcltCpct" + render={({ field }) => { + const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1 + return ( + <FormUi label="저류조 용량(m³)"> <Input className={selectClass} placeholder="1,000,000" type="text" value={ - isUnknown ? "확인불가" : formatCommaNumber(value) + isUnknown + ? "확인불가" + : formatCommaNumber(field.value) } onFocus={() => { // 입력 시 자동으로 확인불가 해제 @@ -332,274 +288,327 @@ export default function RainRegForm({ readOnly={readonly} /> </FormUi> - </div> - ); - }} - /> - </div> - </div> - - <div> - <h2 className={formH2Class}>여과 등 처리시설</h2> - </div> - <div className="grid grid-cols-12 gap-2 mt-4"> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.filtrTrtmfctYn" - render={({ field }) => ( - <FormUi label="유무"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstFilterYn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.filtrTrtmfctCpct" - render={({ field }) => { - const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1 - return ( - <FormUi label="용량(m³/일)"> - <Input - className={selectClass} - placeholder="1,000,000" - type="text" - value={ - isUnknown - ? "확인불가" - : formatCommaNumber(field.value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); - }} + ); + }} + /> + </div> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rainyObj.pntfColKnd" + render={({ field }) => ( + <FormUi label="집수면 종류"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={rainFcltCd} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? rainFcltCd[0]?.val} readOnly={readonly} - disabled={filtrTrtmfctYn !== "Y"} /> </FormUi> - ); - }} - /> + )} + /> + </div> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rainyObj.pntfColArea" + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 + return ( + <div className="flex items-center gap-2"> + <FormUi label="집수면 용량(m³)"> + <Input + className={selectClass} + placeholder="1,000,000" + type="text" + value={ + isUnknown ? "확인불가" : formatCommaNumber(value) + } + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} + readOnly={readonly} + /> + </FormUi> + </div> + ); + }} + /> + </div> </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.filtrTrtmfctPrs" - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === "-"; // 또는 Number(value) === -1 - return ( - <div className="flex items-center gap-2"> - <FormUi label="처리공정"> + <div> + <h2 className={formH2Class}>여과 등 처리시설</h2> + </div> + <div className="grid grid-cols-12 gap-2 mt-4"> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rainyObj.filtrTrtmfctYn" + render={({ field }) => ( + <FormUi label="유무"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstFilterYn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.yn[0]?.val} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rainyObj.filtrTrtmfctCpct" + render={({ field }) => { + const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1 + return ( + <FormUi label="용량(m³/일)"> <Input - className={" h-full !text-xl col-span-4"} - placeholder="처리공정 입력" + className={selectClass} + placeholder="1,000,000" type="text" - value={field.value ?? ""} - onChange={field.onChange} + value={ + isUnknown + ? "확인불가" + : formatCommaNumber(field.value) + } + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} readOnly={readonly} disabled={filtrTrtmfctYn !== "Y"} /> </FormUi> - </div> - ); - }} - /> - </div> - </div> - <div className=" my-2"> - <h1 className={formH1Class}>인센티브 정보</h1> - </div> - <div> - <h2 className={formH2Class}>설치비 지원</h2> - </div> - <div className="grid grid-cols-10 gap-2 mt-4"> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtYn" - render={({ field }) => ( - <FormUi label="지원 여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstIncenYn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtAmt" - render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 - return ( - <FormUi label="지원금액(원)"> - <Input - className={selectClass} - placeholder="" - type="text" - readOnly={readonly || isUnknown} - value={ - isUnknown ? "확인불가" : formatCommaNumber(value) - } - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - onChange={(e) => { - if (readonly) return; - handleMinusNumberChange(e, field.onChange); - }} - disabled={instlCstSprtYn !== "Y"} - /> - </FormUi> - ); - }} - /> - </div> - </div> - <div> - <h2 className={formH2Class}>녹색건축물 인증</h2> - </div> - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYn" - render={({ field }) => ( - <FormUi label="인증여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstIncenYn} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.yn[0]?.val} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYr" - render={({ field }) => { - const isUnknown = - field.value === null || field.value === "0000"; // 또는 Number(value) === -1 - return ( - <FormUi label="인증년도"> - <Input - className={selectClass} - placeholder="2024" - type="" - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - value={isUnknown ? "확인불가" : (field.value ?? "")} - onChange={(e) => { - if (readonly) return; - if (e.target.value === "확인불가") { - field.onChange("0000"); - } else { - field.onChange(e.target.value); - } - }} - disabled={grntchBdstCertYn !== "Y"} - max={4} - /> - </FormUi> - ); - }} - /> - </div> - <div className="col-span-3 "> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertNo" - render={({ field }) => { - const isUnknown = - field.value === null || field.value === "0000"; // 또는 Number(value) === -1 - return ( - <FormUi label="인증번호"> - <Input - className={selectClass} - placeholder="ab1234678" - type="" - onFocus={() => { - // 입력 시 자동으로 확인불가 해제 - if (isUnknown && !readonly) { - field.onChange(""); // 초기화 - } - }} - value={isUnknown ? "확인불가" : (field.value ?? "")} - onChange={(e) => { - if (readonly) return; + ); + }} + /> + </div> + <div className="col-span-4"> + <FormField + control={form.control} + name="reuseBuilding.0.rainyObj.filtrTrtmfctPrs" + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === "-"; // 또는 Number(value) === -1 - if (e.target.value === "확인불가") { - field.onChange(""); - } else { - field.onChange(e.target.value); - } - }} - disabled={grntchBdstCertYn !== "Y"} + return ( + <div className="flex items-center gap-2"> + <FormUi label="처리공정"> + <Input + className={" h-full !text-xl col-span-4"} + placeholder="처리공정 입력" + type="text" + value={field.value ?? ""} + onChange={field.onChange} + readOnly={readonly} + disabled={filtrTrtmfctYn !== "Y"} + /> + </FormUi> + </div> + ); + }} + /> + </div> + </div> + <div className=" my-2"> + <h1 className={formH1Class}>인센티브 정보</h1> + </div> + <div> + <h2 className={formH2Class}>설치비 지원</h2> + </div> + <div className="grid grid-cols-10 gap-2 mt-4"> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCstSprtYn" + render={({ field }) => ( + <FormUi label="지원 여부"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstIncenYn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.yn[0]?.val} + readOnly={readonly} /> </FormUi> - ); - }} - /> + )} + /> + </div> + <div className="col-span-5"> + <FormField + control={form.control} + name="reuseBuilding.0.instlCstSprtAmt" + render={({ field }) => { + const value = field.value; + const isUnknown = value === null || value === -1; // 또는 Number(value) === -1 + return ( + <FormUi label="지원금액(원)"> + <Input + className={selectClass} + placeholder="" + type="text" + readOnly={readonly || isUnknown} + value={ + isUnknown ? "확인불가" : formatCommaNumber(value) + } + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + onChange={(e) => { + if (readonly) return; + handleMinusNumberChange(e, field.onChange); + }} + disabled={instlCstSprtYn !== "Y"} + /> + </FormUi> + ); + }} + /> + </div> </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertGrd" - render={({ field }) => ( - <FormUi label="인증등급"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstGrntchClass} - onSelectValue={readonly ? () => {} : field.onChange} - value={field.value ?? code.bdstGrntchClass[0]?.val} - readOnly={readonly} - /> - </FormUi> - )} - /> + <div> + <h2 className={formH2Class}>녹색건축물 인증</h2> </div> - </div> - <BdstAdd form={form} readonly={readonly}></BdstAdd> + <div className="grid grid-cols-6 gap-2 mt-4"> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertYn" + render={({ field }) => ( + <FormUi label="인증여부"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstIncenYn} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.yn[0]?.val} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertYr" + render={({ field }) => { + const isUnknown = + field.value === null || field.value === "0000"; // 또는 Number(value) === -1 + return ( + <FormUi label="인증년도"> + <Input + className={selectClass} + placeholder="2024" + type="" + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + value={isUnknown ? "확인불가" : (field.value ?? "")} + onChange={(e) => { + if (readonly) return; + if (e.target.value === "확인불가") { + field.onChange("0000"); + } else { + field.onChange(e.target.value); + } + }} + disabled={grntchBdstCertYn !== "Y"} + max={4} + /> + </FormUi> + ); + }} + /> + </div> + <div className="col-span-3 "> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertNo" + render={({ field }) => { + const isUnknown = + field.value === null || field.value === "0000"; // 또는 Number(value) === -1 + return ( + <FormUi label="인증번호"> + <Input + className={selectClass} + placeholder="ab1234678" + type="" + onFocus={() => { + // 입력 시 자동으로 확인불가 해제 + if (isUnknown && !readonly) { + field.onChange(""); // 초기화 + } + }} + value={isUnknown ? "확인불가" : (field.value ?? "")} + onChange={(e) => { + if (readonly) return; + + if (e.target.value === "확인불가") { + field.onChange(""); + } else { + field.onChange(e.target.value); + } + }} + disabled={grntchBdstCertYn !== "Y"} + /> + </FormUi> + ); + }} + /> + </div> + <div className="col-span-3"> + <FormField + control={form.control} + name="reuseBuilding.0.grntchBdstCertGrd" + render={({ field }) => ( + <FormUi label="인증등급"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstGrntchClass} + onSelectValue={readonly ? () => { } : field.onChange} + value={field.value ?? code.bdstGrntchClass[0]?.val} + readOnly={readonly} + /> + </FormUi> + )} + /> + </div> + </div> + <BdstAdd form={form} readonly={readonly}></BdstAdd> </ScrollArea> </form> </Form> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index a3d849b29..cb661fee3 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -8,6 +8,7 @@ import { } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; import { + confirmToast, formatCommaNumber, handleMinusNumberChange } from "@/components/lib/func/commom"; @@ -25,6 +26,7 @@ import { useForm } from "react-hook-form"; import { z } from "zod"; import BdstAdd from "../bdstReg/bdstAdd"; import BdstReg from "../bdstReg/bdstReg"; +import { useTranslation } from "react-i18next"; export default function RswtrRegForm({ rswtForm, @@ -41,20 +43,20 @@ export default function RswtrRegForm({ (state) => state ); const [divStyle, setDivStyle] = useState("h-[53vh]"); - useEffect(()=>{ - if(isModal===true){ + useEffect(() => { + if (isModal === true) { setDivStyle("h-[53vh] max-h-[37vh]") - }else if(readonly===true){ + } else if (readonly === true) { setDivStyle("h-[62vh]") - }else{ + } else { setDivStyle("h-[53vh]") } - },[isModal,readonly]); - // const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({}); + }, [isModal, readonly]); + // const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({}); const form = useForm<z.infer<typeof rswtZod>>({ resolver: zodResolver(rswtZod), - // defaultValues: defaultValues, + // defaultValues: defaultValues, }); const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs] = form.watch([ @@ -63,12 +65,20 @@ export default function RswtrRegForm({ "reuseBuilding.0.rswtrObj.filtrTrtmfctProcs", ]); + const { t } = useTranslation('base'); const onSubmit = (values: z.infer<typeof rswtZod>) => { if (isModal) { - rswtBdstReg(values, "41"); - if (setIsModal) setIsModal(false); + const handleConfirm = async () => { + rswtBdstReg(values, "41"); + if (setIsModal) setIsModal(false); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); + } else { - rswtBdstUpdate(values, "41"); + const handleConfirm = async () => { + rswtBdstUpdate(values, "41"); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); } }; From f06fa0f9abb846fcb7ff1c24e3c9df4364ace56d Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Sun, 13 Jul 2025 20:54:12 +0900 Subject: [PATCH 096/159] =?UTF-8?q?=ED=95=98=EC=88=98=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=20=EC=8B=9C=EC=84=A4=20=EB=93=B1=EB=A1=9D=20=EC=9A=B4?= =?UTF-8?q?=EC=98=81=EC=A0=95=EB=B3=B4=20=EC=98=A4=EB=A5=98=EC=88=98?= =?UTF-8?q?=EC=A0=95=20,=20=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=20?= =?UTF-8?q?=EC=9E=A5=EB=82=B4,=EC=9E=A5=EC=99=B8=20=EC=95=88=EB=82=98?= =?UTF-8?q?=EB=8A=94=EA=B1=B0=20=EC=88=98=EC=A0=95=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 116 ++++++------------ .../ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx | 55 +++++---- .../prfmncReg/pbnstPrfmncReg/page.tsx | 2 +- apps/wr/app/store/common/type/header.tsx | 1 + .../store/prfmncReg/pbnstPrfmncReg/type.tsx | 37 +++++- .../prfmncSttn/pbnstPrfmncSttn/headList.tsx | 26 +++- .../prfmncSttn/pbnstPrfmncSttn/index.tsx | 34 ++--- .../ruseFcltMng/fcltReg/pbnstReg/headList.tsx | 4 +- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 29 +---- .../ruseFcltMng/fcltReg/pbnstReg/type.tsx | 33 +++-- .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 58 +++++---- .../mngRegFormDetail/mngRegFormDetail.tsx | 3 + .../fcltReg/pbnstRegModal/pbnstRegModal.tsx | 5 +- .../sttn/pbnstSttnModal/pbnstSttnModal.tsx | 38 ++++-- .../ruseMngTableForm/ruseMngTableForm.tsx | 3 +- 15 files changed, 239 insertions(+), 205 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 0d99d15cf..1b6b7e76f 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -24,7 +24,6 @@ import type { import { pbnstRegZod, pbnstRegArrayZod, - fcBizSchema, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; @@ -36,8 +35,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createDefaultPbnstItem } from "./utilsZod"; - - +import { flushSync } from "react-dom"; export default function PublicReuseFaciltyInsert() { const { @@ -55,7 +53,7 @@ export default function PublicReuseFaciltyInsert() { const [isRuseReg, setIsRuseReg] = useState<{ isModal: boolean; }>({ isModal: false }); - + const [resetPage, isResetPage] = useState(false); const [indexMng, setIndexMng] = useState<number>(0); const [indexBiz, setIndexBiz] = useState<number>(0); const [searchTxt, setSearchTxt] = useState<string>(); @@ -92,13 +90,13 @@ export default function PublicReuseFaciltyInsert() { if (!isDirty) { toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시 return; - } const data = writeRgtrAndMdfr(valuse.items); + } + const data = writeRgtrAndMdfr(valuse.items); let bizs = [] as fcBizType[]; data.forEach((fclt) => { bizs = [...bizs, ...fclt.fcBizs]; }); - const pbnst = data.map((fclt) => { return { pbnstRuseFcltPk: fclt.pbnstRuseFcltPk, @@ -112,42 +110,34 @@ export default function PublicReuseFaciltyInsert() { }; }); - Promise.allSettled([ pbnstRuseFcltUpdate(pbnst as customPbnst[]), - pbnstRuseBizUpdate(bizs) + pbnstRuseBizUpdate(bizs), ]).then(([resFclt, resBiz]) => { const isFcltSuccess = resFclt.status === "fulfilled"; const isBizSuccess = resBiz.status === "fulfilled"; - if (isFcltSuccess && isBizSuccess) { - toast.success('하수 재이용 시설 및 사업이 수정되었습니다. ') + toast.success("하수 재이용 시설 및 사업이 수정되었습니다. "); // 메시지 표시, 페이지 이동 등 } else { - - let message = '' + let message = ""; // ✅ 각각 어떤 항목이 실패했는지도 로그/알림 처리 if (!isFcltSuccess) { - message = '하수재이용 시설 ' + message = "하수재이용 시설 "; } if (!isBizSuccess) { - message += '하수재이용 시설 사업 ' + message += "하수재이용 시설 사업 "; } - - toast.error(message + '오류 입니다 ') + toast.error(message + "오류 입니다 "); pubHasuInit("1", "41"); } - - }); - - }; // 폼 유효성 검사 실패 시 호출될 함수 - const onInvalid = (errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }>) => { - console.log("errors:", errors); - + const onInvalid = ( + errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }> + ) => { const findAllErrors = ( errorObject: any, path: (string | number)[] = [] @@ -181,7 +171,9 @@ export default function PublicReuseFaciltyInsert() { if (itemsIndex > -1 && path.length > itemsIndex + 1) { const itemIdx = path[itemsIndex + 1] as number; - const facilityName = form.getValues(`items.${itemIdx}.ruseUtztnFcltNm`); + const facilityName = form.getValues( + `items.${itemIdx}.ruseUtztnFcltNm` + ); if (facilityName) { prefix += `[${facilityName}] `; } @@ -189,13 +181,14 @@ export default function PublicReuseFaciltyInsert() { const fcBizsIndex = path.indexOf("fcBizs"); if (fcBizsIndex > -1 && path.length > fcBizsIndex + 1) { const bizIdx = path[fcBizsIndex + 1] as number; - const cycle = form.getValues(`items.${itemIdx}.fcBizs.${bizIdx}.cycl`); + const cycle = form.getValues( + `items.${itemIdx}.fcBizs.${bizIdx}.cycl` + ); if (cycle) { prefix += `[${cycle}차수] `; } } } - // 최종 오류 메시지 출력 toast.error(`${prefix}${message}`); }); @@ -205,6 +198,10 @@ export default function PublicReuseFaciltyInsert() { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); + useEffect(() => { + console.log("formState", items); + }, [items]); + useEffect(() => { if (code.sggCd.length && pbnstHasuRes.length > 0) { setbdstTable(tableData(pbnstHasuRes, { code })); @@ -226,6 +223,12 @@ export default function PublicReuseFaciltyInsert() { setCurrentTab(value); }; + useEffect(() => { + if (indexMng) { + setIndexBiz(0); + } + }, [indexMng]); + useEffect(() => { if (pbnst.pbnstRes && pbnst.pbnstRes?.length > 0) { form.reset({ items: pbnst.pbnstRes }); @@ -234,67 +237,25 @@ export default function PublicReuseFaciltyInsert() { form.reset({ items: [] }); } }, [pbnst.pbnstRes]); - useEffect(() => { - if (indexMng) { - setIndexBiz(0); - } - }, [indexMng]); - - - - - useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); const appendPbnstRuseFclt = useCallback(() => { - const selecTableRow = selectRow; if (pbnstRes && pbnstRes.length > 0) { - const lastPbnst = pbnstRes[pbnstRes.length - 1]; - if (lastPbnst && selecTableRow) { - // append( - // pbnstRegZod.parse({ - // pbnstRuseFcltPk: - // String(selecTableRow.bscFctCd) + String(pbnstRes.length + 1), - // ruseUtztnFcltNm: null, - // fcBizs: [ - // fcBizSchema.parse({ - // pbnstRuseFcltFk: - // String(lastPbnst.pbnstRuseFcltPk) + - // String(pbnstRes.length + 1), - // cycl: 1, - // }), - // ] as fcBizType[], - // }) - // ); - append(createDefaultPbnstItem(selecTableRow, pbnstRes.length)); - + if (selectRow) { // pbnstRes.length를 사용하여 새로운 항목의 인덱스를 결정 + append(createDefaultPbnstItem(selectRow, pbnstRes.length)); setIsRuseReg({ isModal: true }); } } else { - if (selecTableRow) { - append(createDefaultPbnstItem(selecTableRow, 0) - // { - // pbnstRuseFcltPk: String(selecTableRow.bscFctCd) + "1", - // ruseUtztnFcltNm: "", - // regDt: null, - // mdfcnDt: null, - // fcBizs: [ - // fcBizSchema.parse({ - // pbnstRuseFcltFk: String(selecTableRow.bscFctCd) + "1", - // cycl: 1, - // }), - // ] as fcBizType[], - // } - // ) - ); + if (selectRow) { // pbnstRes가 비어있으면 첫 항목이므로 인덱스 0 + + append(createDefaultPbnstItem(selectRow, 0)); setIsRuseReg({ isModal: true }); } } - }, [pbnstRegZod, pbnstRes, append, selectRow, form]); + }, [pbnstRes, append, selectRow]); useEffect(() => { pubHasuInit(String(pageNation), "41"); + isResetPage(false); }, [pageNation, pubHasuInit]); return ( @@ -321,6 +282,7 @@ export default function PublicReuseFaciltyInsert() { searchTxt && searchTxt?.length > 0 ? pubHasuSearch(String(pageNation), "41", searchTxt) : pubHasuInit(String(pageNation), "41"); + isResetPage(true); }} > 조회 @@ -363,6 +325,7 @@ export default function PublicReuseFaciltyInsert() { cellClick={cellClick} onPageChange={setPageNation} children={undefined} + resetPageNo={resetPage} /> </ScrollArea> </ListDiv> @@ -407,7 +370,6 @@ export default function PublicReuseFaciltyInsert() { indexBiz={indexBiz} /> </TabsContent> - </ScrollArea> </Tabs> ) : ( @@ -438,7 +400,6 @@ export default function PublicReuseFaciltyInsert() { </Button> </div> </> - )} </ListDiv> <UiModal @@ -451,7 +412,6 @@ export default function PublicReuseFaciltyInsert() { setIsRuseReg({ isModal: false }); } }} - onInvalid={onInvalid} ></PbnstRegModal> } diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx index 3433a62c5..f5db32812 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx @@ -1,28 +1,37 @@ -import type { fcBizType, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import type { fcBizType, operType, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -export function createDefaultPbnstItem( - selecTableRow: pubHasuType, - index: number - ) { - const pk = String(selecTableRow.bscFctCd) + String(index + 1); - +export function createDefaultPbnstItem(row: pubHasuType, index: number) { + const pk = row.bscFctCd + String(index + 1); + + return JSON.parse(JSON.stringify({ + pbnstRuseFcltPk: pk, + swtrmtFcltFk: "", + ruseUtztnFcltNm: "", + fcltCpct: 0, + ruseCpct: 0, + splyExtraCpct: 0, + regDt: null, + rgtr: "", + mdfcnDt: null, + mdfr: "", + fcFiles: [], + fcBizs: [createDefaultBiz(pk, 1)], + fcOpers: [], // 빈 배열 강제 + })); +} + + + export function createDefaultOper(pbnstRuseFcltFk: string): operType { return { - pbnstRuseFcltPk: pk, - swtrmtFcltFk: "", - ruseUtztnFcltNm: "", // 필수 입력이므로 빈 문자열로 - fcltCpct: 0, - ruseCpct: 0, - splyExtraCpct: 0, - regDt: null, - rgtr: "test", - mdfcnDt: null, - mdfr: "test", - fcFiles: [], - fcBizs: [ - createDefaultBiz(pk, 1), // 첫 차수 - ], - fcOpers: [], - }; + pbnstRuseFcltFk, + operMthd: "", + rprtvBzenty: "", + bgngDt: new Date(), + endDt: new Date(), + choose: false, + rgtr: "", + mdfr: "", + } as operType; } diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 5ea418634..d5e9412d4 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -75,6 +75,7 @@ export default function prfmncPrfmncReg() { searchYear, pbnstRuseFcltPk ) as unknown as PrfType + ,searchYear ); // cellClick(cellNum) } @@ -298,7 +299,6 @@ export default function prfmncPrfmncReg() { {"하수처리수재이용 실적(m3) 등록결과"} </h3> </div> - <Table variant="secondary"> <TableHeader className="font-bold"> {headMakeprfmnc(monthHeadList, [])} diff --git a/apps/wr/app/store/common/type/header.tsx b/apps/wr/app/store/common/type/header.tsx index f064b7580..29780ba03 100644 --- a/apps/wr/app/store/common/type/header.tsx +++ b/apps/wr/app/store/common/type/header.tsx @@ -22,6 +22,7 @@ export type TableUpperProps = { selectData ?:string; // type 이 seelct 일경우 selectarray 정하기 위해 row?:number; mergeCell?:boolean // 셀을 합칠경우 + maxLength?:number readonly?:boolean }; diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx index f6d5ff43f..742a17c16 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx @@ -2,6 +2,20 @@ import { z } from "zod"; import type { TableUpperProps } from "../../common/type/header"; import { fcOperSchema } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; + + +type Month = `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12}월`; + +export type PrfUsageSummary = { + 구분: string; + usage: string; + 용수명?: string; + total: number; + edit?:boolean +} & Record<Month, number>; + + + export const PrfSchema = z.object({ pbnstRuseFcltFk: z.string(), ym: z.string(), // 예: "202310" @@ -44,8 +58,9 @@ export const FcPrfSchema = z.object({ export type FcPrfType = z.infer<typeof FcPrfSchema>; export type PrfType = z.infer<typeof PrfSchema>; -export const initValInUsage = [ +export const initValInUsage:PrfUsageSummary[] = [ { + 구분: "장내용수", usage: "wshwtr", 용수명: "세척수", total: 0, @@ -63,6 +78,7 @@ export const initValInUsage = [ "12월": 0, }, { + 구분: "장내용수", usage: "coolUswtr", 용수명: "냉각수", total: 0, @@ -80,6 +96,7 @@ export const initValInUsage = [ "12월": 0, }, { + 구분: "장내용수", usage: "cleanUswtr", 용수명: "청소수", total: 0, @@ -97,6 +114,7 @@ export const initValInUsage = [ "12월": 0, }, { + 구분: "장내용수", usage: "drwtUswtr", 용수명: "식수대", total: 0, @@ -114,6 +132,7 @@ export const initValInUsage = [ "12월": 0, }, { + 구분: "장내용수", usage: "dltnUswtr", 용수명: "희석용수", total: 0, @@ -131,6 +150,7 @@ export const initValInUsage = [ "12월": 0, }, { + 구분: "장내용수", usage: "ithlRswtr", 용수명: "중수도", total: 0, @@ -148,6 +168,7 @@ export const initValInUsage = [ "12월": 0, }, { + 구분: "장내용수", usage: "ithlEtcUswtr", 용수명: "기타", total: 0, @@ -166,8 +187,9 @@ export const initValInUsage = [ }, ]; -export const initValOutUsage = [ +export const initValOutUsage: PrfUsageSummary[] = [ { + 구분: "장외용수", usage: "resn", 용수명: "세척살수용수", total: 0, @@ -185,6 +207,7 @@ export const initValOutUsage = [ "12월": 0, }, { + 구분: "장외용수", usage: "cleanToilUswtr", 용수명: "청소화장실용수", total: 0, @@ -202,6 +225,7 @@ export const initValOutUsage = [ "12월": 0, }, { + 구분: "장외용수", usage: "lndwtr", 용수명: "조경용수", total: 0, @@ -219,6 +243,7 @@ export const initValOutUsage = [ "12월": 0, }, { + 구분: "장외용수", usage: "hydUswtr", 용수명: "친수용수", total: 0, @@ -236,6 +261,7 @@ export const initValOutUsage = [ "12월": 0, }, { + 구분: "장외용수", usage: "ugwtChr", 용수명: "지하수충전", total: 0, @@ -253,6 +279,7 @@ export const initValOutUsage = [ "12월": 0, }, { + 구분: "장외용수", usage: "farmUswtr", 용수명: "농업용수", total: 0, @@ -271,6 +298,7 @@ export const initValOutUsage = [ }, { + 구분: "장외용수", usage: "rvrKeepUswtr", 용수명: "하천등유지용수", total: 0, @@ -289,6 +317,7 @@ export const initValOutUsage = [ }, { + 구분: "장외용수", usage: "indstUswtr", 용수명: "공업용수", total: 0, @@ -307,7 +336,7 @@ export const initValOutUsage = [ }, ]; -export const subTotalObj = { +export const subTotalObj:PrfUsageSummary = { usage: "subtotal", 용수명: "소계", edit: false, @@ -326,7 +355,7 @@ export const subTotalObj = { "12월": 0, }; -export const totalObj = { +export const totalObj:PrfUsageSummary = { usage: "total", 용수명: "총합계", edit: false, diff --git a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx index d04ef7b20..9095d96b9 100644 --- a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx +++ b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx @@ -1,5 +1,4 @@ -import { z } from "zod"; -import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "../../common/type/header"; export const pbnstPrfmncSttnHeadListExport: TableUpperProps[] = [ { @@ -37,6 +36,7 @@ export const pbnstPrfmncSttnHeadListExport: TableUpperProps[] = [ export const pbnstYearHeadListExport: TableUpperProps[] = [ { + id: "year", title: "년도", colSpan: 3, row: 0 @@ -57,3 +57,25 @@ export const pbnstYearHeadListExport: TableUpperProps[] = [ row: 1 }, ] + + + + + +export const monthSttnHeadListExport: TableUpperProps[] = [ + { id: "구분", title: "구분", mergeCell: true }, + { id: "용수명", title: "용수명" }, + { id: "total", title: "계" }, + { id: "1월", title: "1월" }, + { id: "2월", title: "2월" }, + { id: "3월", title: "3월" }, + { id: "4월", title: "4월" }, + { id: "5월", title: "5월" }, + { id: "6월", title: "6월" }, + { id: "7월", title: "7월" }, + { id: "8월", title: "8월" }, + { id: "9월", title: "9월" }, + { id: "10월", title: "10" }, + { id: "11월", title: "11월" }, + { id: "12월", title: "12월", }, +]; \ No newline at end of file diff --git a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx index db8b6a717..4cb485e40 100644 --- a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx +++ b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx @@ -1,6 +1,6 @@ import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import type { TableUpperProps } from "../../common/type/header"; -import { pbnstPrfmncSttnHeadListExport, pbnstYearHeadListExport } from "./headList"; +import { monthSttnHeadListExport, pbnstPrfmncSttnHeadListExport, pbnstYearHeadListExport } from "./headList"; import type { FcPrfType, PrfType } from "../../prfmncReg/pbnstPrfmncReg/type"; import type { pubHasuType, selectLabel } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; import type { ReturnType } from "@common/business_components"; @@ -22,6 +22,7 @@ export type pbnstPrfmncSttnState = { isInit: boolean; rawData: any[]; selectYearList: selectLabel[] + monthSttnHeadList:TableUpperProps[]; } } @@ -34,7 +35,8 @@ export const pbnstPrfmncSttnExport: pbnstPrfmncSttnState = { prfmncRes: prfmncRes, isInit: false, rawData: [], - selectYearList: [] + selectYearList: [], + monthSttnHeadList:monthSttnHeadListExport } } @@ -147,15 +149,15 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions let outUsageSum = 0; let usageSum = 0; let year = ""; - const yearsData = [] + const yearsData = [] as any - res.data.forEach((item) => { + res.data.forEach((item : any) => { if (item.prfList.length === 0) { - const year = ""; // 연도 정보가 없으면 빈 문자열, 필요시 item에서 추출 - const yearVal = { year: year, pbnstRuseFcltPk: item.pbnstRuseFcltPk ?? "", ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" }; - yearVal[year + "inUsage"] = 0; - yearVal[year + "outUsage"] = 0; - yearVal[year + "total"] = 0; + const year: string = ""; // 연도 정보가 없으면 빈 문자열, 필요시 item에서 추출. + const yearVal: { [key: string]: any } = { year: year, pbnstRuseFcltPk: item.pbnstRuseFcltPk ?? "", ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" }; + yearVal[`${year}inUsage`] = 0; + yearVal[`${year}outUsage`] = 0; + yearVal[`${year}total`] = 0; yearsData.push(yearVal); } item.prfList.forEach((acc) => { @@ -184,14 +186,14 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions ); if (yearData) { - yearData[year + "inUsage"] += inUsageSum; - yearData[year + "outUsage"] += outUsageSum; - yearData[year + "total"] += (inUsageSum + outUsageSum); + yearData[`${year}inUsage`] += inUsageSum; + yearData[`${year}outUsage`] += outUsageSum; + yearData[`${year}total`] += (inUsageSum + outUsageSum); } else { - const yearVal = { year: year, pbnstRuseFcltPk: acc.pbnstRuseFcltFk, ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" }; - yearVal[year + "inUsage"] = inUsageSum; - yearVal[year + "outUsage"] = outUsageSum; - yearVal[year + "total"] = inUsageSum + outUsageSum; + const yearVal: { [key: string]: any } = { year: year, pbnstRuseFcltPk: acc.pbnstRuseFcltFk, ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" }; + yearVal[`${year}inUsage`] = inUsageSum; + yearVal[`${year}outUsage`] = outUsageSum; + yearVal[`${year}total`] = inUsageSum + outUsageSum; yearsData.push(yearVal); } }); diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index 569fad381..84413fbc2 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -14,8 +14,8 @@ export const pubFacHeadListExport: TableUpperProps[] = [ export const pbnstMngUpHeadListExport: TableUpperProps[] = [ { id: "choose", title: "선택", type: "checkbox" }, - { id: "operMthd", title: "운영방식",type: "select", selectData: "ruseMngMtd" }, - { id: "rprtvBzenty", title: "대행업체", edit: true }, + { id: "operMthd", title: "운영방식",type: "select", selectData: "ruseMngMtd" }, + { id: "rprtvBzenty", title: "대행업체", edit: true ,maxLength:10 }, { id: "bgngDt", title: "시작일", diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 9f4b6e859..f34353add 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -65,7 +65,6 @@ type pubFacActions = { appendRuseFclt(array: customPbnst[]): void; fileDelete: (atflCd: string) => void; fileDownLoad: (atflCd: string) => void; - getpbnstInsertIndex: (data: pbnstInsertIndex) => void; pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; pubHasuSearch :(page: string, sggOrCity: string , searchTxt:string) => void @@ -314,33 +313,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } }, - fileInfoUpdate:async(atflCd: string)=>{ - - const WrTableInfo={ - "lnkgDmnNm": "tbWrRuseFcltFile", - "lnkgDmnId": "fileTkn" - } - - try{ - const response = await putFectch( - `/attach-service/api/v1/atfl/attachments/${atflCd}/info`, - WrTableInfo, - fetchType.CS - ) - if (!response.ok) { - throw new Error(`Error downloading file: ${response.statusText}`); - } - }catch(e){ - - } - }, - - getpbnstInsertIndex: async (data: pbnstInsertIndex) => { - return set((state: pubFacState) => { - state.pbnst.pbnsUpdateIndex = data; - return state; - }); - }, + appendRuseFclt: async (array: customPbnst[]) => { try { return set((state: pubFacState) => ({ diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx index ad3496a54..a08c5301a 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -82,6 +82,10 @@ const zNum = z.preprocess( (v) => (v !== null && v !== undefined ? Number(v) : v), z.number() ); +const zNumGte = z.preprocess( + (v) => (v !== null && v !== undefined ? Number(v) : v), + z.number().gt(0, { message: "0보다 큰 숫자만 가능합니다" }) +); const zNumNullish = zNum.nullish(); const zNumDefaultZero = zNum.default(0).nullish(); @@ -151,7 +155,6 @@ const dmdColist = z.object({ export const fcBizSchema = z.object({ pbnstRuseFcltBizPk: zNumNullish, pbnstRuseFcltFk: z.string().nullish(), - superkey: z.string().default("").nullish(), cycl: zNum.default(1), seCd: z.string().max(10, "구분은 10자를 초과할 수 없습니다.").default(""), bizMthdCd: z.string().default(""), @@ -236,25 +239,31 @@ export const fcBizSchema = z.object({ export const pbnstRegZod = z.object({ pbnstRuseFcltPk: z.string().default(""), swtrmtFcltFk: z.string().default(""), - ruseUtztnFcltNm: z - .preprocess( + ruseUtztnFcltNm: //z.string().default(''), + z.preprocess( (v) => (v !== null && v !== undefined ? String(v).trim() : ""), // null/undefined → "", 공백 제거 z.string().min(1, "시설 이름을 입력하세요")), - fcltCpct: zNumDefaultZero, - ruseCpct: zNumDefaultZero, - splyExtraCpct: zNumDefaultZero, + fcltCpct: z.preprocess( + (v) => (v !== null && v !== undefined ? Number(v) : v), + z.number().gte(0, { message: "재이용시설 용량은 0보다 크거나 같아야 합니다" }) + ), + ruseCpct: z.preprocess( + (v) => (v !== null && v !== undefined ? Number(v) : v), + z.number().gte(0, { message: "재이용시설 재이용수 공급량은 0보다 크거나 같아야 합니다" }) + ), + splyExtraCpct: z.preprocess( + (v) => (v !== null && v !== undefined ? Number(v) : v), + z.number().gte(0, { message: "재이용시설 공급가능량은 0보다 크거나 같아야 합니다" }) + ), regDt: zDateDefaultNow, rgtr: z.string().default("test"), mdfcnDt: zDateDefaultNow, mdfr: z.string().default("test"), fcFiles: z.array(fcFileSchema).default([]).nullish(), fcBizs: z.array(fcBizSchema).default([]), - fcOpers: z - .array(fcOperSchema) - .refine((val) => val.length >= 1, { - message: "재이용시설의 운영정보를 최소 하나를 등록해주세요", - }) - .default([]), // 기본값 설정 + fcOpers://z.array(fcOperSchema).default([]), + z .array(fcOperSchema) + .min(1, { message: "재이용시설의 운영정보를 최소 하나를 등록해주세요" }) }); export const pbnstRegArrayZod = z.array(pbnstRegZod); diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index cef483bfb..bb7987501 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -48,7 +48,7 @@ export function PbnstMngForm({ indexMng: number; setIndexMng: (index: number) => void; }) { - const { code, pbnst, fileDelete, fileDownLoad } = useWrStore( + const { code, pbnst, fileDelete, fileDownLoad } = useWrStore( (state) => state ); const { pbnstRes } = pbnst; @@ -57,6 +57,10 @@ export function PbnstMngForm({ const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null); const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null); const [fcltNm, setFcltNm] = useState<selectLabel[] | null>(null); + const [opersKey, setOpersKey] = useState(0); + useEffect(() => { + setOpersKey((prev) => prev + 1); + }, [indexMng]); const [mngMtdCode, setMngMtdCode] = useState<{ name: string; val: SelectDataType[] }[]>(); @@ -69,6 +73,11 @@ export function PbnstMngForm({ name: `items.${indexMng}.fcOpers`, }); + const { fields: mngRegForm } = useFieldArray({ + control: form.control, + name: `items`, + }); + const plusHist = () => { prepend({ choose: false, @@ -81,6 +90,8 @@ export function PbnstMngForm({ bgngDt: new Date(), endDt: new Date(), }); + //trigger(`items.${indexMng}.fcOpers`); + }; const removeSelected = () => { @@ -166,7 +177,6 @@ export function PbnstMngForm({ useEffect(() => { const currentItem = form.getValues(`items.${indexMng}`); const currentKey = JSON.stringify(currentItem); - const isNewItem = !fileInitRef.current || fileInitRef.current.index !== indexMng || @@ -207,19 +217,21 @@ export function PbnstMngForm({ }; }, [indexMng, form.getValues(`items.${indexMng}`)]); - - useEffect(() => { - if (pbnst.pbnstRes && pbnst.pbnstRes?.length >= 0) { - const fcltNmList = pbnst.pbnstRes?.map((item, index) => ({ - text: item.ruseUtztnFcltNm, - val: String(index), - })); - - if (fcltNmList) setFcltNm(fcltNmList); - } else { - setFcltNm(null); - } - }, [pbnst.pbnstRes]); + useEffect( + () => { + //폼이 들어오면 폼에 대한 이름 셀렉트박스를만들기 위해 + if (mngRegForm && mngRegForm.length >= 0) { + const fcltNmList = mngRegForm?.map((item, index) => ({ + text: item.ruseUtztnFcltNm, + val: String(index), + })); + if (fcltNmList) setFcltNm(fcltNmList); + } else { + setFcltNm(null); + } + }, //pbnst.pbnstRes + [mngRegForm] + ); useEffect(() => { if (regFileList && regFileList?.length > 0) { @@ -238,12 +250,6 @@ export function PbnstMngForm({ } }, [planFiles]); - useEffect(() => { - if (regFileList && regFileList?.length > 0) { - form.setValue(`items.${indexMng}.fcFiles`, regFileList); - } - }, [regFileList, indexMng]); - useEffect(() => { if (code.ruseMngMtd) { setMngMtdCode([{ name: "ruseMngMtd", val: code.ruseMngMtd }]); @@ -329,7 +335,8 @@ export function PbnstMngForm({ </div> <div className="h-[200px] overflow-y-auto"> <RuseMngTableForm - tableData={fcOpersField} + key={`ruse-table-${indexMng}-${fcOpersField.length}`} // 🔥 length까지 넣어야 동기화됨 + tableData={form.getValues(`items.${indexMng}.fcOpers`) ||[]} headList={ formType === "sttn" ? pbnst.pbnstMngUpHeadList.map((item) => { @@ -365,6 +372,7 @@ export function PbnstMngForm({ <Input key={`items.${indexMng}.fcltCpct`} placeholder="" + maxLength={10} //입력제한 type="text" onChange={(e) => { if (formType !== "sttn") @@ -388,6 +396,7 @@ export function PbnstMngForm({ <Input key={`items.${indexMng}.ruseCpct`} placeholder="" + maxLength={10} //입력제한 type="text" onChange={(e) => { if (formType !== "sttn") @@ -410,6 +419,7 @@ export function PbnstMngForm({ <Input key={`items.${indexMng}.splyExtraCpct`} placeholder="" + maxLength={10} //입력제한 type="text" onChange={(e) => { if (formType !== "sttn") @@ -509,3 +519,7 @@ export function PbnstMngForm({ </div> ); } +function trigger(arg0: string) { + throw new Error("Function not implemented."); +} + diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx index 234efa7c7..5bac0c3f4 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx @@ -110,6 +110,9 @@ export default function MngRegFormDetail({ <Input placeholder="" type="text" + + + value={field.value ?? ""} onChange={field.onChange} readOnly={formHead.option === "readOnly" ? true : false} diff --git a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx index 846e427c6..f658fa485 100644 --- a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx @@ -35,9 +35,7 @@ export function PbnstRegModal({ setPbnstInsert: (data: customPbnst) => void; onInvalid:(errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }>) => void }) { - const { pbnstInsert } = useWrStore((state) => { - return state; - }); + const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>( {} as customPbnst ); @@ -126,6 +124,7 @@ export function PbnstRegModal({ }, [form.formState.errors]); useEffect(() => { + const firstForm = form.getValues("items"); if (firstForm) { setIndexMng(firstForm.length - 1); diff --git a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx index cec8babd0..498019cd7 100644 --- a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx +++ b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx @@ -1,3 +1,4 @@ +import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead"; import { useWrStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common/type/header"; import { @@ -14,8 +15,10 @@ import { type fcBizType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { formH1Class } from "@/components/lib/class/comClass"; +import { InputTableBody } from "@/components/lib/func/TableData"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { ScrollArea, Title, UiTable } from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Tabs, @@ -23,6 +26,9 @@ import { TabsTrigger, Button, TabsContent, + TableHeader, + TableBody, + Table, } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; @@ -30,7 +36,7 @@ import { set, useForm } from "react-hook-form"; import { z } from "zod"; export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titleVisible?: boolean }) { - const { code, pbnstSttn, prfmnc } = useWrStore((state) => state); + const { code, pbnstSttn, prfmnc , pbnstPrfmncSttn} = useWrStore((state) => state); const [fcltTab, setFcltTab] = useState<string>("fclt"); const [ruseTab, setRuseTab] = useState<string>("totalPrf"); const [ruseBizData, setRuseBizData] = useState<{ @@ -180,6 +186,7 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl const usageKey = inData.usage; const value = (prfItem as any)[usageKey] ?? 0; + inData[monthKey] = value; inData.total += value; @@ -231,7 +238,6 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl )?.prfList; if (prfList) { - console.log("prfList", prfList); getTablePrfData(prfList); } @@ -324,17 +330,23 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl </TabsList> <TabsContent className="max-h-full" value={ruseTab}> {prfData && ( - <UiTable - headName={undefined} - tableData={prfData[ruseTab as keyof typeof prfData] || []} - headlist={monthHeadList || []} - pageSize={0} - total={0} - cellClick={undefined} - onPageChange={function (page: number): void { - throw new Error("Function not implemented."); - }} - ></UiTable> + <ListDiv className="col-span-8 pr-6 "> + <ScrollArea className="h-[60vh]"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label"> + {"하수처리수재이용 실적(m3) 등록결과"} + </h3> + </div> + <Table variant="secondary"> + <TableHeader className="font-bold"> + {headMakeprfmnc(pbnstPrfmncSttn.monthSttnHeadList, [])} + </TableHeader> + <TableBody key={prfmnc.pageKey + 'pageKey'}> + {InputTableBody(prfData[ruseTab as keyof typeof prfData] || [], pbnstPrfmncSttn.monthSttnHeadList, setPrfData as any)} + </TableBody> + </Table> + </ScrollArea> + </ListDiv> )} </TabsContent> </Tabs> diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index 577e7ce46..efc4e1dd6 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -56,7 +56,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( ) => { return ( <> - <Table key={`table-${indexMng}-${indexBiz}`} variant="secondary"> + <Table key={`${formNm}-table-${indexMng}-${indexBiz}`} variant="secondary"> <TableHeader className="font-bold"> {upHeadList ? ( headMakeprfmnc(headList, upHeadList) @@ -114,6 +114,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( : field.value || "" } readOnly={head.readonly ? true : false} + maxLength={head.maxLength?head.maxLength:15} /> ) : head.type === "select" ? ( <SelectBox From 38c21b1ad4e0cae5e05892367f229c4515938d7a Mon Sep 17 00:00:00 2001 From: truthwing <truthplumage@gmail.com> Date: Mon, 14 Jul 2025 10:18:33 +0900 Subject: [PATCH 097/159] =?UTF-8?q?building=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=A4=91.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/pbnstPrfmncSttnPopup.tsx | 26 +--- apps/wr/app/map/rainPrfmncSttnPopup.tsx | 31 ++-- apps/wr/app/map/rswtrPrfmncSttnPopup.tsx | 31 ++-- apps/wr/app/matMng/coMat/coMatRvw/page.tsx | 23 ++- apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx | 8 +- .../wr/app/matMng/coMat/ruseRvwHstry/page.tsx | 84 ++++------- apps/wr/app/matMng/coMng/coSttn/page.tsx | 142 ++++++++++-------- apps/wr/app/matMng/coMng/drgtSttn/page.tsx | 4 +- .../src/ui/sdmInsertForm/form.tsx | 12 +- 9 files changed, 167 insertions(+), 194 deletions(-) diff --git a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx b/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx index f6d870092..46fa9ba59 100644 --- a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx +++ b/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx @@ -1,10 +1,10 @@ "use client"; import { useWrStore } from "@/app/store"; -import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; -import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SelectBox, UiTable, type ChartConfig, type ReturnType } from "@common/business_components"; +import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SelectBox, UiTable, type ChartConfig } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; interface PbnstPrfmncSttnPopupProps { @@ -12,16 +12,10 @@ interface PbnstPrfmncSttnPopupProps { } export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSttnPopupProps) { - const { code, tableHeadMaker, pbnstPrfmncSttn, pbnstPrfmncInit, pbnstPrfmncSearch, prfmnc } = useWrStore((state) => state); + const { pbnstPrfmncSttn, pbnstPrfmncInit, prfmnc } = useWrStore((state) => state); const { monthHeadList } = prfmnc - const { pbnstPrfHeadList, pbnstPrfmncRes, prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn; - const [isChHead, setIsChHead] = useState(false); - const [fromDate, setFromDate] = useState<string>(String(new Date().getFullYear())); - const [toDate, setToDate] = useState<string>(String(new Date().getFullYear())); + const { prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn; const [year, setYear] = useState<string>(String(new Date().getFullYear())); - const [bdstTable, setbdstTable] = useState<FcPrfType[]>(); - const ref = useRef<ReturnType>({} as ReturnType); - const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>(); const [chartConfig, setChartConfig] = useState<ChartConfig>({}); const [chartData, setChartData] = useState<dnChartForm[]>([]); const [dnInUsage, setDnInUsage] = useState<dnChartForm[]>([]); @@ -304,8 +298,8 @@ export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSt let indstUswtr = 0; let inUsageSum = 0; let outUsageSum = 0; - let inUsageArr = []; - let outUsageArr = []; + const inUsageArr = []; + const outUsageArr = []; if (rawData) { @@ -518,10 +512,6 @@ export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSt } }, [pbnstPrfmncSttn.isInit, pbnstPrfmncInit]); - useEffect(() => { - setbdstTable(prfmncRes); - }, [prfmncRes]); - return ( <> <ContentsDiv> @@ -581,7 +571,7 @@ export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSt total={0} cellClick={undefined} onPageChange={function (page: number): void { - throw new Error("Function not implemented."); + throw new Error("Function not implemented.", page); }}> </UiTable> </ScrollArea> diff --git a/apps/wr/app/map/rainPrfmncSttnPopup.tsx b/apps/wr/app/map/rainPrfmncSttnPopup.tsx index b6ebf11ef..7449772e8 100644 --- a/apps/wr/app/map/rainPrfmncSttnPopup.tsx +++ b/apps/wr/app/map/rainPrfmncSttnPopup.tsx @@ -4,23 +4,21 @@ import { useWrStore } from "@/app/store"; import { rainZod, selectClass, - TEST_UUID, type customRainBdst, } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { DatePicker, FormUi } from "@common/business_components"; -import { Form, FormField, SelectBox } from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useState } from "react"; -import { useForm, useWatch, type UseFormReturn } from "react-hook-form"; -import { z } from "zod"; -import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; +import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; import { formatCommaNumber, handleCommaNumberChange, } from "@/components/lib/func/commom"; -import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; -import { Label } from "@common/business_components/ui/form/lib/label"; +import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; +import { DatePicker, FormUi } from "@common/business_components"; +import { Form, FormField, SelectBox } from "@common/business_components/ui"; +import { Input } from "@common/components/ui"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; export default function RainPrfmncSttnPopup({ rainForm, @@ -29,7 +27,7 @@ export default function RainPrfmncSttnPopup({ rainForm: customRainBdst; isModal: boolean; }) { - const { code, rainBdstReg, rainBdstUpdate, rain } = useWrStore( + const { code, rainBdstReg, rainBdstUpdate } = useWrStore( (state) => state ); const { rainFcltCd } = code; @@ -81,15 +79,6 @@ export default function RainPrfmncSttnPopup({ } }, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn]); - // form 값이 변경될 때마다 로그 출력 - useEffect(() => { - const subscription = form.watch((value) => { - }); - - - return () => subscription.unsubscribe(); - }, [form]); - useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); diff --git a/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx b/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx index e7f94a3b5..161860c10 100644 --- a/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx +++ b/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx @@ -1,5 +1,17 @@ "use client"; +import { useWrStore } from "@/app/store"; +import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { + rswtZod, + type customRswtBdst, +} from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; +import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; +import { + formatCommaNumber, + handleCommaNumberChange, +} from "@/components/lib/func/commom"; +import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; import { DatePicker, Form, @@ -7,24 +19,11 @@ import { FormUi, SelectBox, } from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; +import { Input } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { - rswtZod, - type customRswtBdst, -} from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; -import { useEffect } from "react"; -import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; -import { - formatCommaNumber, - handleCommaNumberChange, -} from "@/components/lib/func/commom"; -import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; -import { Label } from "@common/business_components/ui/form/lib/label"; export default function RswtrPrfmncsSttnPopup({ rswtForm, @@ -33,7 +32,7 @@ export default function RswtrPrfmncsSttnPopup({ rswtForm: customRswtBdst; isModal: boolean; }) { - const { rswt, code, rswtBdstUpdate, rswtBdstReg } = useWrStore( + const { code, rswtBdstUpdate, rswtBdstReg } = useWrStore( (state) => state ); diff --git a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx index 15bff0b32..a1f484b83 100644 --- a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx @@ -1,13 +1,13 @@ "use client"; import { useWrStore } from "@/app/store"; +import { usageProcData } from "@/app/store/matDmd/coMatRvw/headList"; import { DmdCoReqSchema, - type DedMatUpdateType, type DmdCoReqType, type DmdMatTableType, } from "@/app/store/matDmd/coMatRvw/type"; -import { formH1Class, formTableName } from "@/components/lib/class/comClass"; +import { formH1Class } from "@/components/lib/class/comClass"; import { formatPhoneNumber, getCity, @@ -15,33 +15,30 @@ import { tableData, yearOptions, } from "@/components/lib/func/commom"; +import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, Form, FormField, FormUi, - ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, - UiModal, UiTable, type SelectDataType, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, Input, Label } from "@common/components/ui"; +import { zodResolver } from "@hookform/resolvers/zod"; +import moment from "moment"; import { useEffect, useRef, useState } from "react"; import { useForm, useWatch } from "react-hook-form"; import toast, { Toaster } from "react-hot-toast"; import { z } from "zod"; -import moment from "moment"; -import { usageProcData } from "@/app/store/matDmd/coMatRvw/headList"; -import { zodResolver } from "@hookform/resolvers/zod"; -import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm"; -import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; export default function CoMatRvw() { const { code, coRvw, coMatRvwInit, coMatRvwSearch, coMatRvwInqua } = @@ -119,7 +116,7 @@ export default function CoMatRvw() { useEffect(() => { if (coMatRvwRes&&coMatRvwRes.length > 0) { - const data = coMatRvwRes?.map((item, index) => { + const data = coMatRvwRes?.map((item) => { let flag = ""; flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg ||undefined); @@ -238,7 +235,7 @@ export default function CoMatRvw() { <div className="flex flex-row space-x-2"> <Button size={"sm"} - onClick={(e) => { + onClick={() => { if (fromDate && toDate) { const fromNum = Number(fromDate); const toNum = Number(toDate); @@ -277,12 +274,12 @@ export default function CoMatRvw() { headlist={coRvwHeadList} pageSize={20} total={coMatRvwCount} - cellClick={(index: number | undefined, headId: string) => { + cellClick={(index: number | undefined) => { if (index !== undefined && index >= 0) { TableCellClick(index); } }} - onPageChange={() => {}} + onPageChange={(val) => {setPageNatiion(val)}} ></UiTable> </ListDiv> <hr /> diff --git a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx index a81a85e19..e45a0a0f2 100644 --- a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx @@ -5,7 +5,6 @@ import { ruseUtzType } from "@/app/store/matDmd/ruseCaseMng/headList"; import { excelDownload, getCity } from "@/components/lib/func/commom"; import RuseCaseMngExcel from "@/components/ui/modal/coMat/ruseCaseMng/ruseCaseMngExcelModal"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { ContentsDiv, filePickedBlobArray, @@ -22,7 +21,7 @@ import { import ListDiv from "@common/business_components/ui/list_div"; import { Button } from "@common/components/ui"; import { useEffect, useState } from "react"; -import { toast, Toaster } from "react-hot-toast"; +import { Toaster } from "react-hot-toast"; export default function RuseCaseMng() { const { code, ruseCaseMng, selectRuseCaseMng } = useWrStore((state) => state); @@ -37,7 +36,7 @@ export default function RuseCaseMng() { // 물재이용사례 조회 const searchRuseCaseMng = async (pageNo: number, pageSize: number) => { - const res = await selectRuseCaseMng( + await selectRuseCaseMng( pageNo, pageSize, sidoCd ?? "", @@ -237,11 +236,10 @@ export default function RuseCaseMng() { <UiTable headName={"물재이용사례 현황"} tableData={ruseCaseMngList} - children={undefined} headlist={ruseCaseMng.ruseHeadList} pageSize={20} total={count} - cellClick={(index: number | undefined, headId: string) => {}} + cellClick={() => {}} onPageChange={(pageNo: number) => { searchRuseCaseMng(pageNo, 10); }} diff --git a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx index d0a6bcb93..623335c6b 100644 --- a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx @@ -10,9 +10,9 @@ import { formatPhoneNumber, getCity, getdmdMatFlag, + tableData, yearOptions, } from "@/components/lib/func/commom"; -import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, @@ -26,15 +26,12 @@ import { type SelectDataType, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, DatePicker, Input, Label } from "@common/components/ui"; +import { Button, Label } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import moment from "moment"; import { useCallback, useEffect, useState } from "react"; -import { set, useFieldArray, useForm } from "react-hook-form"; -import { z } from "zod"; -import { tableData } from "@/components/lib/func/commom"; +import { useForm } from "react-hook-form"; import toast, { Toaster } from "react-hot-toast"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; export default function RuseRvwHstry() { const { code, @@ -44,7 +41,7 @@ export default function RuseRvwHstry() { ruseRvwInqua, ruseRvwComplete, } = useWrStore((state) => state); - const { rvwHistRes, ruseHistHeadList,rvwHistCount } = ruseHist; + const { rvwHistRes, ruseHistHeadList, rvwHistCount } = ruseHist; const [pageNation, setPageNatiion] = useState<number>(1); const [dmdCoNm, setDmdCoNm] = useState<string>(""); @@ -70,18 +67,16 @@ export default function RuseRvwHstry() { setObjSearch({ city: cityValue, sgg: "0" }); }; - useEffect(() =>{ - getButtonSearch() - },[pageNation]) + useEffect(() => { + getButtonSearch(); + }, [pageNation]); - const getButtonSearch=()=>{ + const getButtonSearch = () => { if (fromDate && toDate) { const fromNum = Number(fromDate); const toNum = Number(toDate); if (fromNum > toNum) { - toast.error( - "시작년도가 종료년도 이후로 설정할 수 없습니다." - ); + toast.error("시작년도가 종료년도 이후로 설정할 수 없습니다."); } else { let con: string | number = ""; if (String(objSearch.city).length > 0) { @@ -90,16 +85,10 @@ export default function RuseRvwHstry() { if (String(objSearch.sgg).length > 0 && objSearch.sgg !== "0") { con = String(objSearch.sgg); } - getSearch( - fromNum, - toNum, - con, - dmdCoNm, - ruseUtztnFcltNm - ); + getSearch(fromNum, toNum, con, dmdCoNm, ruseUtztnFcltNm); } } - } + }; const getSgg = (val: string | number) => { console.log(val); setObjSearch({ ...objSearch, sgg: String(val) }); @@ -123,8 +112,6 @@ export default function RuseRvwHstry() { ruseUtztnFcltNm ); } else { - - ruseRvwInqua(pageNation, 13, String(startYear), String(endYear), sggCd); } }; @@ -191,33 +178,33 @@ export default function RuseRvwHstry() { useEffect(() => { if (rvwHistRes) { - const data = rvwHistRes?.map((item, index) => { + const data = rvwHistRes?.map((item) => { let flag = ""; - flag = getdmdMatFlag(item.demandMatching?.splyFcltFlg ?? ""); - const formatDate = (dateStr: string | null | undefined) => { - // null, undefined, 빈 문자열인 경우 '없음'을 반환합니다. - if (!dateStr) return "없음"; - // "YYYYMMDD" 형식으로 날짜를 파싱합니다. - const d = moment(dateStr, "YYYYMMDD"); - // 파싱된 날짜가 유효한 경우에만 포맷하고, 그렇지 않으면 '없음'을 반환합니다. - return d.isValid() ? d.format("YYYY-MM-DD") : "없음"; - }; - + flag = getdmdMatFlag(item.demandMatching?.splyFcltFlg ?? ""); + const formatDate = (dateStr: string | null | undefined) => { + // null, undefined, 빈 문자열인 경우 '없음'을 반환합니다. + if (!dateStr) return "없음"; + // "YYYYMMDD" 형식으로 날짜를 파싱합니다. + const d = moment(dateStr, "YYYYMMDD"); + // 파싱된 날짜가 유효한 경우에만 포맷하고, 그렇지 않으면 '없음'을 반환합니다. + return d.isValid() ? d.format("YYYY-MM-DD") : "없음"; + }; + return { ...item, ctpvCd: item.demandCo?.ctpvCd, sggCd: item.demandCo?.sggCd, dmdCoNm: item.demandCo?.dmdCoNm, daddr: item.demandCo?.daddr, - telno: formatPhoneNumber(item.demandCo?.telno ||''), + telno: formatPhoneNumber(item.demandCo?.telno || ""), dmndTmng: item?.dmndTmng ? moment(item?.dmndTmng).format("YYYY-MM-DD") : "없음", - rvwCmptnYmd: formatDate(item.demandMatching?.rvwCmptnYmd), - mtchnCmptnYmd: formatDate(item.demandMatching?.mtchnCmptnYmd), - - ruseUtztnFcltNm: item.ruseUtztnFcltNm, + rvwCmptnYmd: formatDate(item.demandMatching?.rvwCmptnYmd), + mtchnCmptnYmd: formatDate(item.demandMatching?.mtchnCmptnYmd), + + ruseUtztnFcltNm: item.ruseUtztnFcltNm, dmndQty: item.dmndQty, splyFcltFlg: flag, completeYn: false, @@ -228,7 +215,6 @@ export default function RuseRvwHstry() { } }, [rvwHistRes]); - useEffect(() => { console.log("변경여부 ", form.formState.isDirty); }, [form.formState]); @@ -308,8 +294,8 @@ export default function RuseRvwHstry() { <div className="flex flex-row space-x-2"> <Button size={"sm"} - onClick={(e) => { - getButtonSearch() + onClick={() => { + getButtonSearch(); }} > 조회 @@ -333,16 +319,12 @@ export default function RuseRvwHstry() { headlist={ruseHistHeadList} pageSize={20} total={rvwHistCount} - cellClick={(index: number | undefined, headId: string) => { + cellClick={(index: number | undefined) => { TableCellClick(index); }} - onPageChange={ - (page)=>{ - setPageNatiion(page) - - } - - } + onPageChange={(page) => { + setPageNatiion(page); + }} ></UiTable> {/* <hr /> <h3 className="mt-4 ml-2 text-2xl font-medium text-label"> diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index 20a0fa945..e3a204162 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -8,10 +8,9 @@ import { excelDownload, formatPhoneNumber, getCity, - tableData + tableData, } from "@/components/lib/func/commom"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { ContentsDiv, SearchDiv, @@ -60,18 +59,21 @@ export default function CoSttn() { const [seartchTxt, setSearchTxt] = useState<string>(); const [upadateData, setUpdateData] = useState<DemandCompType>(); - - const getSelCity = useCallback((val: string | number) => { + + const getSelCity = useCallback( + (val: string | number) => { const cityValue = String(val); const data = getCity(cityValue, code.sggCd); setSelectSgg(data); // 시/도를 변경하면 시/군/구는 '전체'("0")로 초기화합니다. setObjSearch({ city: cityValue, sgg: "0" }); - }, [code.sggCd]); + }, + [code.sggCd] + ); const getSgg = useCallback((val: string | number) => { setObjSearch((prev) => ({ ...prev, sgg: String(val) })); - setPageNation(1) + setPageNation(1); }, []); useEffect(() => { @@ -84,7 +86,7 @@ export default function CoSttn() { } } }, [code.cityCd, objSearch.city, getSelCity]); - + useEffect(() => { if (!coSttn.isInit) { coSttnInit("1", "13", "0"); @@ -92,15 +94,13 @@ export default function CoSttn() { }, [coSttn.isInit, coSttnInit]); useEffect(() => { - if(coSttnRes){ - + 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") - + telno: formatPhoneNumber(item.telno || undefined), + regDt: moment(item.regDt).format("YYYY-MM-DD"), })); // .filter((item: any) => item !== undefined); setBdstTable(chData); @@ -111,11 +111,14 @@ export default function CoSttn() { }, [coSttnRes, code]); useEffect(() => { - if (coSttn.excelList.length > 0) { if (coSttn.excelList.length === 0) return; - const coExcel = excelCoSttnParsing(coSttn.excelList, code.cityCd, code.sggCd); + const coExcel = excelCoSttnParsing( + coSttn.excelList, + code.cityCd, + code.sggCd + ); excelDownload( coExcel as [], "수요처 관리", @@ -127,25 +130,29 @@ export default function CoSttn() { }, [coSttn.excelList, code]); const excelClick = useCallback(() => { - const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; + const con = + objSearch.sgg && objSearch.sgg !== "0" ? objSearch.sgg : objSearch.city; if (con) coSttnSearch("1", "10000", String(con)); - - - }, [coSttnSearch, objSearch.city, objSearch.sgg]); -// }, [excelDownload, bdstTable]); + }, [coSttnSearch, objSearch.city, objSearch.sgg]); + // }, [excelDownload, bdstTable]); const searchClick = () => { - const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; + const con = + objSearch.sgg && objSearch.sgg !== "0" ? objSearch.sgg : objSearch.city; if (con) { if (seartchTxt && seartchTxt?.length > 0) { - - coSttnTxtSearch(String(pageNation), "13", String(con), seartchTxt ?? ""); + coSttnTxtSearch( + String(pageNation), + "13", + String(con), + seartchTxt ?? "" + ); } else { coSttnSearch(String(pageNation), "13", String(con)); } } }; - + return ( <> <ContentsDiv> @@ -160,10 +167,10 @@ export default function CoSttn() { label="시도" selectClass={""} selectArray={code.cityCd || []} - onSelectValue={(val)=>{ - getSelCity(val) - setPageNation(1) - } } + onSelectValue={(val) => { + getSelCity(val); + setPageNation(1); + }} value={objSearch.city} /> <SelectBox @@ -205,11 +212,12 @@ export default function CoSttn() { onClick={() => { /* 저장 로직 */ if (!upadateData) { - toast.error("수요처 변경을 원하는 행을 선택해주세요") - }else{ + toast.error("수요처 변경을 원하는 행을 선택해주세요"); + } else { setIsDmdModal({ ...isDmdModal, - isMoal: true}) + isMoal: true, + }); } }} > @@ -235,29 +243,29 @@ export default function CoSttn() { tableData={bdstTable || []} headlist={coSttn.coSttHeadList} pageSize={20} - total={ coSttnResCount+10 || 0 } - cellClick={(index: number | undefined, headId: string) => { + total={coSttnResCount + 10 || 0} + cellClick={(index: number | undefined) => { setUpdateData(coSttnRes[index as number]); }} - onPageChange={(page) =>{ - const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; - setPageNation(page) - coSttnSearch( String(page), "13", String(con)); - - - } } + onPageChange={(page) => { + const con = + objSearch.sgg && objSearch.sgg !== "0" + ? objSearch.sgg + : objSearch.city; + setPageNation(page); + coSttnSearch(String(page), "13", String(con)); + }} ></UiTable> </ListDiv> </div> </div> <UiModal - bodyClass={"w-[40vw] max-w-none h-[80vh] "// +upadateData?.dmdInfoPk?'h-[60vh]':'h-[90vh]' - + bodyClass={ + "w-[40vw] max-w-none h-[80vh] " // +upadateData?.dmdInfoPk?'h-[60vh]':'h-[90vh]' } - open={isDmdModal.isMoal} onOpenChange={() => { - setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); + setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); }} body={ <SdmInsertForm @@ -267,26 +275,38 @@ export default function CoSttn() { rtnValue={(searchText: string, pageCnt: number) => { getDemandCompList(searchText, pageCnt); }} - rtnInputData={ async(data) => { - const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city; - console.log('data ', data) - if(upadateData?.dmdInfoPk){ - console.log('data ', data) - await updateDemandCompany(data as DemandCompType) + rtnInputData={async (data) => { + const con = + objSearch.sgg && objSearch.sgg !== "0" + ? objSearch.sgg + : objSearch.city; + console.log("data ", data); + if (upadateData?.dmdInfoPk) { + console.log("data ", data); + await updateDemandCompany(data as DemandCompType); coSttnInit("1", "13", String(con)); - setIsDmdModal({ isMoal: false, data: data as DemandCompType }); - }else{ - const dmd= await getFetch(fetchType.WR,`/reuseFc/request/${data.dmdInfoPk}`) - if(dmd) { - toast.error(`사업자번호 ${dmd.dmdInfoPk}는 이미 등록되었습니다. 다시등록해주세요`) - return - } - await regDemandCompany(data as DemandCompType); - coSttnInit("1", "13", String(con)); - setIsDmdModal({ isMoal: false, data: data as DemandCompType }); + setIsDmdModal({ + isMoal: false, + data: data as DemandCompType, + }); + } else { + const dmd = await getFetch( + fetchType.WR, + `/reuseFc/request/${data.dmdInfoPk}` + ); + if (dmd) { + toast.error( + `사업자번호 ${dmd.dmdInfoPk}는 이미 등록되었습니다. 다시등록해주세요` + ); + return; + } + await regDemandCompany(data as DemandCompType); + coSttnInit("1", "13", String(con)); + setIsDmdModal({ + isMoal: false, + data: data as DemandCompType, + }); } - - }} bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"} updateList={upadateData} diff --git a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx index 55dbeb454..e11b59f16 100644 --- a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx @@ -27,8 +27,8 @@ export default function DrgtSttn() { data: customDrgt | undefined; }>({ data: undefined, isOpen: false }); - const cellClick = (index: number | undefined, headId: string) => { - if (fromDate && toDate) { + const cellClick = (index: number) => { + if (fromDate && toDate && drgtRes[index]) { drgtModalSearch(fromDate, toDate, drgtRes[index].sggNm); } else { toast.error("조회기간을 선택해주세요."); diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index e58592837..a28b36b8c 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -1,11 +1,10 @@ -import React from 'react'; -import { FormField } from "../form"; -import { SelectBox } from "../select"; -import { Input } from "@common/components"; -import { FormUi } from "../form_ui"; -import { useCallback, useEffect, useState } from "react"; +import { Input } from "@common/components"; import { AsYouType } from "libphonenumber-js"; +import React, { useCallback, useEffect, useState } from 'react'; import type { ControllerRenderProps, UseFormReturn } from "react-hook-form"; +import { FormField } from "../form"; +import { FormUi } from "../form_ui"; +import { SelectBox } from "../select"; import { SdmSearchForm } from "./sdmNameBox"; // 수요처 정보 @@ -54,7 +53,6 @@ interface FormSchema { daddr: string; telno: string; bznmTotNo?: string; - rgtr?: string; dmdAplyPswd?: string; dmdAplyPswdConfirm?: string; } From 8dc47fc8057a718abfdeaf3c3cbc425c8af6ed70 Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 14 Jul 2025 10:19:00 +0900 Subject: [PATCH 098/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=20=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EC=8B=9C,=20=EC=A7=80=EB=8F=84=EC=A0=90=EA=B2=80=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D,=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C,=20=EC=8B=A4?= =?UTF-8?q?=EC=A0=81=20=EB=93=B1=EB=A1=9D,=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EC=8B=9C=20confirm=20=EC=B0=BD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/prfmncReg/chkgdnReg/page.tsx | 13 +++- .../prfmncReg/pbnstPrfmncReg/page.tsx | 69 ++++++++++++------- .../ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 27 +++++--- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 2 +- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 2 +- apps/wr/public/locales/ko/message.json | 1 + 6 files changed, 76 insertions(+), 38 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index ecd2fd0f6..cb3f2f9ef 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -11,6 +11,7 @@ import { type rswtrChkDetailsZodType, } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; import { + confirmToast, excelArrayDownload, excelDownload, yearOptions, @@ -39,6 +40,7 @@ import { } from "@common/components/ui/tooltip"; import { useCallback, useEffect, useState } from "react"; import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function Page() { const { @@ -201,12 +203,19 @@ export default function Page() { } }, [rainChkgdn.isSttn, rswtChkgdn.isSttn]); + const { t } = useTranslation('base'); const clickDelete = (data: number[], selFcltDiv: string) => { if (data.length > 0) { if (selFcltDiv === "RNB") { - rainChkDelete(data, searchYear); + const handleConfirm = async () => { + rainChkDelete(data, searchYear); + }; + confirmToast(t('isDeleteMsg'), handleConfirm); } else { - rswtChkDelete(data, searchYear); + const handleConfirm = async () => { + rswtChkDelete(data, searchYear); + }; + confirmToast(t('isDeleteMsg'), handleConfirm); } } }; diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 5ea418634..b8d486a32 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useWrStore } from "@/app/store"; import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload, yearOptions } from "@/components/lib/func/commom"; +import { confirmToast, excelDownload, yearOptions } from "@/components/lib/func/commom"; import PbnPrfExcelModal from "@/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal"; import { ContentsDiv, @@ -37,12 +37,13 @@ import { type PrfType, } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; +import { useTranslation } from "react-i18next"; export default function prfmncPrfmncReg() { - const { code, prfmnc, prfmncHasuInit, prfmnRegData,prfmncHasuNmSearch } = useWrStore( + const { code, prfmnc, prfmncHasuInit, prfmnRegData, prfmncHasuNmSearch } = useWrStore( (state) => state ); - const { pbnstPrfmncHeadList, monthHeadList, prfmncRes,prfmncResCount } = prfmnc; + const { pbnstPrfmncHeadList, monthHeadList, prfmncRes, prfmncResCount } = prfmnc; const [bdstTable, setbdstTable] = useState<FcPrfType[]>(); const [searchTxt, setSearchTxt] = useState<string>(); const [isExcelOpen, setIsExcelOPen] = useState<{ @@ -65,20 +66,40 @@ export default function prfmncPrfmncReg() { "A1:O1" ); }, [prfmnc.excelList]); + /* + const onSave = useCallback( + async() => { + if (pbnstRuseFcltPk) { + await prfmnRegData(pageNation,'41', + excelToPbnPrfData( + inputData as unknown as JSON[], + searchYear, + pbnstRuseFcltPk + ) as unknown as PrfType + ); + // cellClick(cellNum) + } + }, [inputData, searchYear, pbnstRuseFcltPk, pageNation,cellNum]);*/ - const onSave = useCallback( - async() => { - if (pbnstRuseFcltPk) { - await prfmnRegData(pageNation,'41', + const { t } = useTranslation('base'); + const onSave = useCallback(() => { + const handleConfirm = async () => { + if (!pbnstRuseFcltPk) return; + + prfmnRegData( + pageNation, + '41', excelToPbnPrfData( inputData as unknown as JSON[], searchYear, pbnstRuseFcltPk - ) as unknown as PrfType + ) as unknown as PrfType, + searchYear ); - // cellClick(cellNum) - } - }, [inputData, searchYear, pbnstRuseFcltPk, pageNation,cellNum]); + }; + + confirmToast(t('isUpdateMsg'), handleConfirm); + }, [inputData, searchYear, pbnstRuseFcltPk, pageNation, cellNum]); const cellClick = useCallback( (index: number | undefined) => { @@ -165,13 +186,13 @@ export default function prfmncPrfmncReg() { useEffect(() => { if (!prfmnc.isInit) { const year = new Date().getFullYear() - prfmncHasuInit(1, "41",String(year)); + prfmncHasuInit(1, "41", String(year)); } }, [prfmnc.isInit, prfmncHasuInit]); useEffect(() => { - if(prfmncRes&&prfmncRes.length>0){ + if (prfmncRes && prfmncRes.length > 0) { setbdstTable(prfmncRes); } @@ -224,14 +245,14 @@ export default function prfmncPrfmncReg() { <div className="flex flex-row space-x-2"> <Button size={"sm"} onClick={(e) => { - if(searchTxt&&searchTxt?.length>0){ - prfmncHasuNmSearch(1,'41',searchYear,searchTxt) + if (searchTxt && searchTxt?.length > 0) { + prfmncHasuNmSearch(1, '41', searchYear, searchTxt) setPageNation(1) - }else{ - prfmncHasuInit(1,'41',searchYear) + } else { + prfmncHasuInit(1, '41', searchYear) setPageNation(1) } - + }}> 조회 </Button> @@ -282,8 +303,8 @@ export default function prfmncPrfmncReg() { setCellNum(index ?? 0); }} onPageChange={ - (page) =>{ - prfmncHasuInit(page, "41",searchYear); + (page) => { + prfmncHasuInit(page, "41", searchYear); setPageNation(page) }} children={undefined} @@ -303,7 +324,7 @@ export default function prfmncPrfmncReg() { <TableHeader className="font-bold"> {headMakeprfmnc(monthHeadList, [])} </TableHeader> - <TableBody key={prfmnc.pageKey+'pageKey'}> + <TableBody key={prfmnc.pageKey + 'pageKey'}> {InputTableBody(inputData ?? [], monthHeadList, setInputData)} </TableBody> </Table> @@ -319,14 +340,14 @@ export default function prfmncPrfmncReg() { setIsExcelOPen={(open) => { setIsExcelOPen({ ...isExcelOpen, isModal: open }) }} - setModalExcelData={ async(excelData ) =>{ - await prfmnRegData(pageNation,'41', + setModalExcelData={async (excelData) => { + await prfmnRegData(pageNation, '41', excelData, searchYear ); // 데이터 저장 후 UI 업데이트는 useEffect가 감지하여 처리하므로 여기서는 호출하지 않습니다. } - } + } ></PbnPrfExcelModal> } open={isExcelOpen.isModal} diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index 7e92301b8..85bb67044 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -19,11 +19,13 @@ import { import { useEffect, useState } from "react"; import BdstReg from "../bdstReg/bdstReg"; import { + confirmToast, formatCommaNumber, handleCommaNumberChange, } from "@/components/lib/func/commom"; import { formH1Class } from "@/components/lib/class/comClass"; import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function HtdflRegForm({ htdflForm, @@ -48,20 +50,25 @@ export default function HtdflRegForm({ const bdstNm = form.watch("bdstNm"); const isPowerPlant = bdstNm?.includes("발전소"); - + const { t } = useTranslation('base'); const onSubmit = (values: z.infer<typeof hdtflZod>) => { if (isModal) { const data = regCtpvCd ? regCtpvCd : regSggcd ? regSggcd : "noCd"; - if (data === "noCd") { toast.error("시도/시군구 코드를 선택해야합니다."); return; } - htdflBdstReg(values, data); - if (setIsModal) setIsModal(false); + const handleConfirm = async () => { + htdflBdstReg(values, data); + if (setIsModal) setIsModal(false); + }; + confirmToast(t('isInsertMsg'), handleConfirm); } else { + const handleConfirm = async () => { + htdflBdstUpdate(values, "0"); + }; + confirmToast(t('isUpdateMsg'), handleConfirm); - htdflBdstUpdate(values, "0"); } }; @@ -90,15 +97,15 @@ export default function HtdflRegForm({ }; }; const [divStyle, setDivStyle] = useState("h-[53vh]"); - useEffect(()=>{ - if(isModal===true){ + useEffect(() => { + if (isModal === true) { setDivStyle("h-[53vh] max-h-[37vh]") - }else if(readonly===true){ + } else if (readonly === true) { setDivStyle("h-[62vh]") - }else{ + } else { setDivStyle("h-[53vh]") } - },[isModal,readonly]); + }, [isModal, readonly]); useEffect(() => { console.log("form errors:", form.formState.errors); diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index 21a0923ea..a454f69c8 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -146,7 +146,7 @@ export default function RainRegForm({ rainBdstReg(values, data); if (setIsModal) setIsModal(false); }; - confirmToast(t('isUpdateMsg'), handleConfirm); + confirmToast(t('isInsertMsg'), handleConfirm); } else { const handleConfirm = async () => { rainBdstUpdate(values, "41"); diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index cb661fee3..34765ae9a 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -72,7 +72,7 @@ export default function RswtrRegForm({ rswtBdstReg(values, "41"); if (setIsModal) setIsModal(false); }; - confirmToast(t('isUpdateMsg'), handleConfirm); + confirmToast(t('isInsertMsg'), handleConfirm); } else { const handleConfirm = async () => { diff --git a/apps/wr/public/locales/ko/message.json b/apps/wr/public/locales/ko/message.json index d0e6ee02f..ee661980d 100644 --- a/apps/wr/public/locales/ko/message.json +++ b/apps/wr/public/locales/ko/message.json @@ -10,6 +10,7 @@ "fileDateErrMsg": "파일업로드 이전에 등록년도를 작성해주세요.", "isDeleteMsg": "선택한 정보를 삭제하시겠습니까?", "isUpdateMsg": "수정한 정보를 저장하시겠습니까?", + "isInsertMsg": "등록하시겠습니까?", "excelDownErrMsg": "다운로드할 데이터가 없습니다.", "alreadyInsertedErrMsg": "사업자번호 {{num}}(은)는 이미 등록되었습니다. 다시 등록해주세요.", From 6249a73aa3aa9ac833ddab362643b71da7e00f93 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 14 Jul 2025 10:20:37 +0900 Subject: [PATCH 099/159] =?UTF-8?q?=EB=B9=8C=EB=93=9C=20=EC=9E=A1=EB=8A=94?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncSttn/pbnstPrfmncSttn/page.tsx | 8 ++++---- .../form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 15 --------------- .../table/pbnstReg/ruseMngTable/ruseMngTable.tsx | 2 ++ .../ruseMngTableForm/ruseMngTableForm.tsx | 9 +++++---- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index c60ba1673..391fd3a40 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -84,12 +84,12 @@ export default function PbnstPrfmncSttn() { const prfTableData = (prfList: PrfType[], year: string) => { const inUsageData = structuredClone(initValInUsage).map(row => ({ - ...row, - 구분: "장내용수", + ...row + // 구분: "장내용수", })); const outUsageData = structuredClone(initValOutUsage).map(row => ({ - ...row, - 구분: "장외용수", + ...row + // 구분: "장외용수", })); const inSubtotal = { ...structuredClone(subTotalObj), 구분: "장내용수" }; const outSubtotal = { ...structuredClone(subTotalObj), 구분: "장외용수" }; diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index bf1160004..3fdccec53 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -314,8 +314,6 @@ useEffect(() =>{ const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`); - - return ( <> {pbnstBiz && pbnstBiz?.length > 0 ? ( @@ -485,24 +483,11 @@ useEffect(() =>{ } headList={pbnst.pplInstlsHeadLisat} code={ppiSelectList ?? []} - //ref={ref} indexMng={indexMng} indexBiz={indexBiz} form={form} formNm={"pplInstls"} upHeadList={[]} - onTableSet={(val) => { - const pplSum = form.watch( - `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` - ); - - if (!pplSum) return; - let sum = 0; - pplSum.forEach((item) => { - sum += Number(item.cpct) || 0; - }); - setSumCpct(sum); - }} /> </div> diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx index 715e91d8c..07e7c1e8d 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx @@ -155,4 +155,6 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>( ); } ); +RuseMngTable.displayName = "RuseMngTable"; + export default RuseMngTable; diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index efc4e1dd6..2efa1c795 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -1,7 +1,6 @@ import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead"; import type { TableUpperProps } from "@/app/store/common/type/header"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { customPbnst as OriginalCustomPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { formatCommaNumber, @@ -32,7 +31,6 @@ type RuseMngTableProps = { headList: TableUpperProps[]; upHeadList: chHeadType[]; code?: { name: string; val: SelectDataType[] }[]; - onTableSet?: (item: any) => void; indexMng?: number; indexBiz?: number; form?: any; @@ -46,7 +44,6 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( headList, upHeadList, code, - onTableSet, indexMng, form, formNm, @@ -56,7 +53,8 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( ) => { return ( <> - <Table key={`${formNm}-table-${indexMng}-${indexBiz}`} variant="secondary"> + <Table key={`${formNm}-table-${indexMng}-${indexBiz}`} variant="secondary" + ref={ref}> <TableHeader className="font-bold"> {upHeadList ? ( headMakeprfmnc(headList, upHeadList) @@ -184,4 +182,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( ); } ); + +RuseMngTableForm.displayName = "RuseMngTableForm"; + export default RuseMngTableForm; From 72b92ae9df193588ab888cd88878306e662e1294 Mon Sep 17 00:00:00 2001 From: truthwing <truthplumage@gmail.com> Date: Mon, 14 Jul 2025 10:41:29 +0900 Subject: [PATCH 100/159] =?UTF-8?q?any=20=EC=B2=B4=ED=81=AC=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=A0=9C=EA=B1=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/eslint.config.mjs | 6 +++++- apps/wr/tsconfig.json | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/wr/eslint.config.mjs b/apps/wr/eslint.config.mjs index c85fb67c4..73d6b7492 100644 --- a/apps/wr/eslint.config.mjs +++ b/apps/wr/eslint.config.mjs @@ -1,6 +1,6 @@ +import { FlatCompat } from "@eslint/eslintrc"; import { dirname } from "path"; import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -11,6 +11,10 @@ const compat = new FlatCompat({ const eslintConfig = [ ...compat.extends("next/core-web-vitals", "next/typescript"), + {rules:{ + // other rules.. + "@typescript-eslint/no-explicit-any": "off", + }}, ]; export default eslintConfig; diff --git a/apps/wr/tsconfig.json b/apps/wr/tsconfig.json index d897e147f..493584782 100644 --- a/apps/wr/tsconfig.json +++ b/apps/wr/tsconfig.json @@ -2,6 +2,7 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "../../tsconfig.base.json", "compilerOptions": { + "noImplicitAny": false, "baseUrl": ".", "target": "ES2017", "lib": ["dom", "dom.iterable", "esnext"], From a21491cffde26723125f02bfba5489575c89335d Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 14 Jul 2025 10:57:15 +0900 Subject: [PATCH 101/159] =?UTF-8?q?stat=20build=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/stats/matStat/page.tsx | 28 +++++++++++----------- apps/wr/app/store/stats/rainStat/index.tsx | 1 + apps/wr/app/store/stats/rswtStat/index.tsx | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/apps/wr/app/stats/matStat/page.tsx b/apps/wr/app/stats/matStat/page.tsx index a147ff597..bf3ad2b06 100644 --- a/apps/wr/app/stats/matStat/page.tsx +++ b/apps/wr/app/stats/matStat/page.tsx @@ -3,21 +3,21 @@ import { useWrStore } from "@/app/store"; import { yearOptions } from "@/components/lib/func/commom"; import { ContentsDiv, Title, SearchDiv, SearchFormLeft, SelectBox, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button } from "@common/components/ui"; +import { Button } from "@common/components/ui"; import { useState } from "react"; -export default function MatStat(){ -const { code, matStat } = useWrStore((state) => { +export default function MatStat() { + const { matStat } = useWrStore((state) => { return state; }); - const [pageNation, setPageNation] = useState(1); + // const [pageNation, setPageNation] = useState(1); const [searchYear, setSearchYear] = useState<string>( String(new Date().getFullYear()) ); - return( - <> - <ContentsDiv> + return ( + <> + <ContentsDiv> <div className="grid grid-cols-4 gap-4"> <div className="col-span-4"> <Title title={"재이용 통계"} /> @@ -34,13 +34,13 @@ const { code, matStat } = useWrStore((state) => { } /> <div className="flex flex-row space-x-2 items-center"> - <Button className="" size={"sm"} onClick={(e) => {}}> + <Button className="" size={"sm"} onClick={() => { }}> 조회 </Button> - <Button className="" size={"sm"} onClick={(e) => {}}> + <Button className="" size={"sm"} onClick={() => { }}> 다운로드 </Button> - <Button className="" size={"sm"} onClick={(e) => {}}> + <Button className="" size={"sm"} onClick={() => { }}> 전체통계다운로드 </Button> </div> @@ -61,14 +61,14 @@ const { code, matStat } = useWrStore((state) => { pageSize={20} total={10000} headName={"건축물 목록"} - cellClick={(val, headId) => {}} - onPageChange={setPageNation} + cellClick={() => { }} + onPageChange={() => { }} ></UiTable> {/* </ScrollArea> */} </ListDiv> </div> </div> </ContentsDiv> - </> - ) + </> + ) } \ No newline at end of file diff --git a/apps/wr/app/store/stats/rainStat/index.tsx b/apps/wr/app/store/stats/rainStat/index.tsx index d6e48a53e..c54f1542e 100644 --- a/apps/wr/app/store/stats/rainStat/index.tsx +++ b/apps/wr/app/store/stats/rainStat/index.tsx @@ -4,6 +4,7 @@ import { excelRainStat } from "./excel"; import { rainStatHeadListExport } from "./headList"; export type RainStatProps = { + cityText: string ctpvCd: string //시도 sggCd: string //시군구 areaNm: string //행정구역명 diff --git a/apps/wr/app/store/stats/rswtStat/index.tsx b/apps/wr/app/store/stats/rswtStat/index.tsx index 4e2a7ecc8..af106c3b3 100644 --- a/apps/wr/app/store/stats/rswtStat/index.tsx +++ b/apps/wr/app/store/stats/rswtStat/index.tsx @@ -4,6 +4,7 @@ import { rswtStatHeadListExport } from "./headList"; import { excelRswtStat } from "./excel"; export type RswtStatProps = { + cityText: string //시도명 ctpvCd: string //시도 sggCd : string //시군구 areaNm: string //행정구역명 @@ -72,7 +73,6 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = ( return { searchRswtStatList: async (year: string) => { const res = await getFetch(fetchType.WR, `/reuseChk/reuseWater/stat/${year}`) - const rswtStatList: RswtStatProps[] = []; const cityArr: any[] = []; res.forEach((item: RswtStatProps) => { From 1e21f76c8f6f0928579b2750868d659d718f0c5e Mon Sep 17 00:00:00 2001 From: bicochan <chanii8@naver.com> Date: Mon, 14 Jul 2025 11:31:56 +0900 Subject: [PATCH 102/159] =?UTF-8?q?[apps/cs]=20feat:=20useTus=20=ED=9B=85?= =?UTF-8?q?=EC=97=90=20=ED=8C=8C=EC=9D=BC=20=ED=99=95=EC=9E=A5=EC=9E=90=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(CS=5FUT01030102)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/image/ui/image-form.tsx | 39 ++++++++++++----------- apps/cs/src/shared/lib/use-tus.ts | 28 +++++++++++++++- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/apps/cs/src/pages/image/ui/image-form.tsx b/apps/cs/src/pages/image/ui/image-form.tsx index 649d195b8..1de7820c5 100644 --- a/apps/cs/src/pages/image/ui/image-form.tsx +++ b/apps/cs/src/pages/image/ui/image-form.tsx @@ -42,8 +42,9 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { file: uploadFile, response: uploadResponse, progress, + isValid, setFile, - } = useTus(); + } = useTus({ accept: ".jpeg,.jpg,.png" }); const setAttachmentFileCode = useAttachmentStore( (state) => state.setAttachmentFileCode, ); @@ -208,24 +209,26 @@ function ImageForm({ form, imgSn, ...props }: ImageFormProps) { customPreview={ <> <Label htmlFor="atflCd"> - <div className="relative h-[27rem] w-[48rem] overflow-hidden rounded-sm border border-border bg-accent"> - <div className="relative h-full w-full"> - {imageUrl && ( - <Image - src={imageUrl} - className="object-contain" - fill - alt="업로드된 이미지" + <div className="h-[27rem] w-[48rem] overflow-hidden rounded-sm border border-border bg-accent"> + {isValid && ( + <div className="relative size-full"> + {imageUrl && ( + <Image + src={imageUrl} + className="object-contain" + fill + alt="업로드된 이미지" + /> + )} + <p className="absolute bottom-3 left-0 z-10 p-2 text-base leading-none"> + {uploadFile?.name} + </p> + <Progress + value={progress} + className="absolute bottom-0 left-0 z-10" /> - )} - </div> - <p className="absolute bottom-3 left-0 z-10 p-2 text-base leading-none"> - {uploadFile?.name} - </p> - <Progress - value={progress} - className="absolute bottom-0 left-0 z-10" - /> + </div> + )} </div> </Label> <div className="mb-2 text-lg font-medium text-label"> diff --git a/apps/cs/src/shared/lib/use-tus.ts b/apps/cs/src/shared/lib/use-tus.ts index 30976c23b..9d4bc7c00 100644 --- a/apps/cs/src/shared/lib/use-tus.ts +++ b/apps/cs/src/shared/lib/use-tus.ts @@ -2,9 +2,15 @@ import { useEffect, useState } from "react"; import { type HttpResponse, Upload } from "tus-js-client"; import { AUTH_USER_ID, CLAIM_NAME, ENDPOINT } from "../config"; import { useAttachmentStore } from "./use-attachment-store"; +import { useAlertStore } from "./use-alert-store"; import { getCookie } from "./cookie"; -export const useTus = () => { +type TusProps = { + accept?: string; +}; + +export const useTus = ({ accept }: TusProps = {}) => { + const alert = useAlertStore((state) => state.setMessage); const { attachmentFileCode, setAttachmentFileCode } = useAttachmentStore( (state) => state, ); @@ -13,6 +19,7 @@ export const useTus = () => { const [upload, setUpload] = useState<Upload | null>(null); const [response, setResponse] = useState<HttpResponse | null>(null); const [progress, setProgress] = useState<number>(0); + const [isValid, setIsValid] = useState<boolean>(false); const metadata = { filename: file?.name ?? "", @@ -20,6 +27,23 @@ export const useTus = () => { atflCd: attachmentFileCode, }; + const validFileType = (file: File) => { + const allowedExtensions = accept?.split(",") ?? []; + const fileName = file.name; + const fileExtension = fileName + .substring(fileName.lastIndexOf(".")) + .toLowerCase(); + + if (!allowedExtensions.includes(fileExtension)) { + alert("파일 형식이 올바르지 않습니다."); + setIsValid(false); + return false; + } + + setIsValid(true); + return true; + }; + const createUpload = () => { return new Upload(file!, { endpoint: `${ENDPOINT.ATTACH_SERVICE.TUS_UPLOAD}`, @@ -48,6 +72,7 @@ export const useTus = () => { useEffect(() => { if (!file) return; + if (!validFileType(file)) return; const upload = createUpload(); upload.start(); @@ -59,6 +84,7 @@ export const useTus = () => { upload, response, progress, + isValid, setFile, }; }; From b570db8375fc3e4a34bd043f0fb008e1c82d2e92 Mon Sep 17 00:00:00 2001 From: JIeunhuh <entks301@naver.com> Date: Mon, 14 Jul 2025 13:14:29 +0900 Subject: [PATCH 103/159] =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/featureClickEventPopup.tsx | 201 ------- apps/wr/app/map/htdflPrfmncSttnPopup.tsx | 621 --------------------- apps/wr/app/map/htdflSttn/page.tsx | 2 - apps/wr/app/map/mapSearchBar.tsx | 414 -------------- apps/wr/app/map/mapSearchForm.tsx | 340 ----------- apps/wr/app/map/pbnstPrfmncSttnPopup.tsx | 596 -------------------- 6 files changed, 2174 deletions(-) delete mode 100644 apps/wr/app/map/featureClickEventPopup.tsx delete mode 100644 apps/wr/app/map/htdflPrfmncSttnPopup.tsx delete mode 100644 apps/wr/app/map/mapSearchBar.tsx delete mode 100644 apps/wr/app/map/mapSearchForm.tsx delete mode 100644 apps/wr/app/map/pbnstPrfmncSttnPopup.tsx diff --git a/apps/wr/app/map/featureClickEventPopup.tsx b/apps/wr/app/map/featureClickEventPopup.tsx deleted file mode 100644 index 8048d0997..000000000 --- a/apps/wr/app/map/featureClickEventPopup.tsx +++ /dev/null @@ -1,201 +0,0 @@ -'use client' -import { getData, putData } from "../../../sn/app/components/lib/api"; -import Modal from "../../../sn/app/components/ui/modal"; -import { VerticalTable } from "../../../sn/app/components/ui/verticalTable"; -import { useGisContext } from "@common/business_components/ui/map/Gis"; -import { Button } from "@common/components/ui"; -import { useEffect, useRef, useState } from "react"; -import { getLayerContentComponent } from "../../../sn/app/map/components/common"; -// TODO: -const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => { - const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; - // const featureId = featureData.getId(); // 피처의 id 가져오기 - const featureId = typeof featureData.getId === 'function' - ? featureData.getId() - : featureData.fid; - const [layerNm, setLayerNm] = useState<string>(""); // 레이어 이름 상태 - const [tableData, setTableData] = useState<any>(null); // 피처 데이터 - const [mntrngsData, setMntrngsData] = useState(false); // 수량/수질 측정 정보 - const [headlist, setHeadlist] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태 - const [headlist2, setHeadlist2] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태 - const [buttonChk, setButtonChk] = useState(true) - const [fetchData, setfetchData] = useState<any>(); // api 호출여부 - const contentRef = useRef<HTMLDivElement>(null); - const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열기 상태 - const [chkMainSsc, setChkMainSsc] = useState(false); // 중점우수토실 여부 - - // 피쳐데이터의 현재 레이어 이름 가져오는 함수 - const getSelectedLayers = () => { - let result = null; - const layers = gisMap.getLayers().getArray(); // gisMap에서 모든 레이어 가져오기 - let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 - layers.forEach((layer: any) => { - const source = layer.getSource(); - if (source && source.hasFeature && featureData - && typeof featureData.getId === 'function' && source.hasFeature(featureData)) { - featureLayer = layer; // 피처가 속한 레이어 찾기 - } - }); - // SearchModal 클릭 이벤트와 Gis 클릭 이벤트 구분하기 - if (featureLayer.get('lyrNm') === null) { - if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설'; - else if (featureData.lyrTypeNm === 'tb_ms_swage_prcs_zone') result = '하수처리구역'; - else if (featureData.lyrTypeNm === 'om_dt_untrt_swg_rain') result = '중점우수토실'; - } - else result = featureLayer.get('lyrNm'); - - return result; - // return featureLayer.get('lyrNm'); // 레이어 이름 출력 - }; - - useEffect(() => { - const fetchData = async () => { - if (featureId) { - const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기 - setLayerNm(selectedLayerName); // 상태 업데이트 - const layerId = featureId.split('.')[0] - let data = await getData(`v1/fclts/${featureId}?lyrTypeNm=${layerId}`); - setfetchData(data) - switch (selectedLayerName) { - case '하수처리시설': - setButtonChk(false) - break; - case '하수처리구역': - setButtonChk(false) - break; - case '중점우수토실': - setButtonChk(false) - setChkMainSsc(true) - - // 데이터 전처리: 합쳐진 필드 추가 - data = data ? { - ...data, - discharge_pipe_spec: `직경: ${data.pipe_diameter || '-'} / 높이: ${data.pipe_hg || '-'} / 길이: ${data.pipe_lt || '-'}` - } : {}; - - // 수량/수질측정 정보 데이터 호출 - const additionalResponse = await getData(`v1/onsemiro/swgRain/${data.adst_dstr_cd}/${data.manage_no}/mntrngs`); - setMntrngsData(additionalResponse.content); - break; - case '우수토실': - setButtonChk(true) - break; - case '하수관로': - setButtonChk(true) - break; - case '오수펌프': - setButtonChk(true) - break; - case '빗물펌프': - setButtonChk(true) - break; - case '하수맨홀': - setButtonChk(true) - break; - default: - break; - } - setTableData(data); - }; - } - fetchData(); - }, [featureId]); - - // 저장 시 모달 띄우기 - const handleSaveClick = () => { - setIsModalOpen(true); // 모달 열기 - }; - - const handleModalSave = () => { - setIsModalOpen(false); // 모달 닫기 - btnClickEvent(); // 저장 이벤트 실행 - }; - - const handleModalClose = () => { - setIsModalOpen(false); // 모달 닫기 - }; - - const btnClickEvent = async () => { - const bodyData: Record<string, any> = {} - if (buttonChk && contentRef.current) { - const inputElements = contentRef.current.querySelectorAll('input'); - const selectElements = contentRef.current.querySelectorAll('select'); - // 카멜케이스 변환 함수 - const toCamelCase = (str: string) => - str.replace(/_([a-z])/g, (_, char) => char.toUpperCase()); - // select 태그의 값 가져오기 - selectElements.forEach((select) => { - const camelCaseId = toCamelCase(select.id); - bodyData[camelCaseId] = select.value; - }); - // input 태그의 값 가져오기 - inputElements.forEach((input) => { - const camelCaseId = toCamelCase(input.id); - bodyData[camelCaseId] = input.value; - }); - if (layerNm === '하수관로') bodyData['lyrTypeNm'] = 'tb_ms_swage_ppl' - else if (layerNm === '우수토실') bodyData['lyrTypeNm'] = 'tb_ms_stofcbr' - else if (layerNm === '오수펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' - else if (layerNm === '빗물펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' - else if (layerNm === '하수맨홀') bodyData['lyrTypeNm'] = 'tb_ms_swage_mnhl' - bodyData['fid'] = featureId - const data = await putData(`v1/fclts/${featureId}`, bodyData); - if (data.status == 200) { - alert('저장되었습니다') - setTableData(data) - setfetchData(data) - } - } - } - type ContentComponentProps = { - featureData: any; - chkMainSsc: boolean; - additionalData: any; - }; - const ContentComponent = layerNm ? getLayerContentComponent(layerNm) as React.ComponentType<ContentComponentProps> : null; - return ( - <div id="popup" className="absolute top-0 right-0 w-[350px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-[102]"> - <div className="card-header bg-primary flex items-center justify-between p-4"> - <div className="flex mx-3 flex-col"> - <h3 className="text-2xl font-medium text-white text-label">{layerNm} 정보</h3> - <div className="font-medium text-white text-label">(00구 00리 하수관로)</div> - </div> - <button - onClick={onClose} - className="text-white hover:text-gray-700 focus:outline-none" - aria-label="닫기" - > - ✕ - </button> - </div> - <div className="overflow-y-auto overflow-x-hidden flex-1" ref={contentRef}> - <VerticalTable - headName='LX 연계정보' - tableData={[tableData]} - headlist={headlist} - pageSize={20} - total={0} - children={undefined} - cellClick={undefined} - onPageChange={function (page: number): void { - throw new Error("Function not implemented."); - }} - /> - <div className="w-full mx-5 flex items-center justify-end space-x-2"> - {buttonChk ? <Button onClick={handleSaveClick} className="px-4 mr-5 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"> - 저장 - </Button> : null} - </div> - <Modal isModalOpen={isModalOpen} title="자체입력정보 저장" setIsModalOpen={setIsModalOpen} closeModal={handleModalClose} saveModal={handleModalSave}><div className="text-lg">정보를 저장하시겠습니까?</div></Modal> - {ContentComponent && - <ContentComponent - featureData={fetchData} - chkMainSsc={chkMainSsc} - additionalData={mntrngsData} - /> - } - </div> - </div> - ) -} -export default FeatureClickEventPopup; \ No newline at end of file diff --git a/apps/wr/app/map/htdflPrfmncSttnPopup.tsx b/apps/wr/app/map/htdflPrfmncSttnPopup.tsx deleted file mode 100644 index 8d1bec486..000000000 --- a/apps/wr/app/map/htdflPrfmncSttnPopup.tsx +++ /dev/null @@ -1,621 +0,0 @@ -"use client"; - -import { - Form, - FormField, - FormUi, - SelectBox, -} from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useForm } from "react-hook-form"; -import { z } from "zod"; -import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { - hdtflZod, - type customHtdflBdst, -} from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { useEffect } from "react"; -import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; -import { - formatCommaNumber, - handleCommaNumberChange, -} from "@/components/lib/func/commom"; -import { formH1Class } from "@/components/lib/class/comClass"; - -export default function HtdflPrfmncSttnPopup({ - htdflForm, - isModal, -}: { - htdflForm: customHtdflBdst; - isModal: boolean; -}) { - const { code, htdflBdstUpdate, htdflBdstReg } = useWrStore((state) => state); - - const defaultValues: z.infer<typeof hdtflZod> = hdtflZod.parse({}); - - const form = useForm<z.infer<typeof hdtflZod>>({ - resolver: zodResolver(hdtflZod), - defaultValues: defaultValues, - }); - - const onSubmit = (values: z.infer<typeof hdtflZod>) => { - if (isModal) { - htdflBdstReg(values, '41'); - } else { - htdflBdstUpdate(values, '41'); - } - }; - - - const cleanHtdflData = (raw: any): z.infer<typeof hdtflZod> => { - return { - ...raw, - frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null), - archChgPrmsnDt: raw?.archChgPrmsnDt - ? new Date(raw?.archChgPrmsnDt) - : null, - chgBuilding: (raw?.chgBuilding || []).map((item: any) => ({ - ...item, - archChgPrmsnDt: - item?.archChgPrmsnDt === null - ? new Date() - : new Date(item?.archChgPrmsnDt), - bdstChgNm: item?.bdstChgNm ?? "", // null → "" - })), - reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({ - ...item, - instlCmptnDt: new Date(item?.instlCmptnDt), - htdflObj: { - ...item?.htdflObj, - }, - })), - }; - }; - - useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); - - useEffect(() => { - if (hdtflZod) form.reset(cleanHtdflData(htdflForm)); - }, [htdflForm]); - - return ( - <div className="!mx-[1.6rem] !p-0r"> - <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> - {/* <div className="flex justify-between items-center mx-3"> */} - <div> - <div className="grid grid-cols-12 flex items-center card-header"> - <h1 className="text-2xl font-medium text-label col-span-10">온배수 시설 정보</h1> - </div> - </div> - - {isModal && htdflForm != undefined ? <BdstReg form={form} /> : <></>} - {isModal ? ( - <h1 className="text-xl col-span-10 mt-4"> - 온배수 시설 정보{" "} - </h1> - ) : ( - <></> - )} - - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.etgtType" - render={({ field }) => ( - <FormUi label="발전유형(코드정비후 수정)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.fclCpct" // 이름 이상함. - render={({ field }) => ( - <FormUi label="설비용량"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.plwtYn" - render={({ field }) => ( - <FormUi label="담수화 여부"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - <div className=" my-4"> - <h1 className={formH1Class}> - 온배수 시설 운영현황 - </h1> - </div> - - <div className="grid grid-cols-10 gap-1 mt-4"> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.orgwtWtritSpt" - render={({ field }) => ( - <FormUi label="원수취수 지점(코드정비후 수정)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - value={field.value ?? 0} - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.orgwtOcrnProcs" - render={({ field }) => ( - <FormUi label="원수발생 공정"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.wtritEntrcTp" - render={({ field }) => ( - <FormUi label="취수구 온도"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.amtgnr" - render={({ field }) => ( - <FormUi label="발생량(m³/년)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.prcsProcsYn" - render={({ field }) => ( - <FormUi label="처리공정"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.prcsFcltCpct" - render={({ field }) => ( - <FormUi label="처리시설 용량(m³/년)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.fmYn" - render={({ field }) => ( - <FormUi label="유량계유무"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.utztnCpct" - render={({ field }) => ( - <FormUi label="이용량(m³/년)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.utztnUsg" - render={({ field }) => ( - <FormUi label="이용용도"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className=" my-2"> - <h1 className={formH1Class}> - 요구수질 - </h1> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.grssClfg" - render={({ field }) => ( - <FormUi label="총대장균군"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.tn" - render={({ field }) => ( - <FormUi label="총질소"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.combResdch" - render={({ field }) => ( - <FormUi label="결합잔류염소"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6 "> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.tph" - render={({ field }) => ( - <FormUi label="총인"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.trbt" - render={({ field }) => ( - <FormUi label="탁도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.ph" - render={({ field }) => ( - <FormUi label="수소이온농도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.bod" - render={({ field }) => ( - <FormUi label="생물학적 산소요구량"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.clIonQnt" - render={({ field }) => ( - <FormUi label="염화물"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.smll" - render={({ field }) => ( - <FormUi label="냄새"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.cdtnv" - render={({ field }) => ( - <FormUi label="전기전도도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.crmty" - render={({ field }) => ( - <FormUi label="색도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.emsnExitTp" - render={({ field }) => ( - <FormUi label="배출구온도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - </form> - </Form> - </div> - ); -} diff --git a/apps/wr/app/map/htdflSttn/page.tsx b/apps/wr/app/map/htdflSttn/page.tsx index b7935ee99..2e6833a14 100644 --- a/apps/wr/app/map/htdflSttn/page.tsx +++ b/apps/wr/app/map/htdflSttn/page.tsx @@ -2,9 +2,7 @@ import Gis from "@common/business_components/ui/map/Gis"; import { useEffect, useRef, useState, useCallback } from "react"; -import FeatureClickEventPopup from "../featureClickEventPopup"; import { mapService } from "../service"; -// import { MapSearchBar } from "../mapSearchBar"; import NewWindowPopup from "../newWindowPopup"; import GisApp from "@common/business_components/ui/map/lib/gis.core"; diff --git a/apps/wr/app/map/mapSearchBar.tsx b/apps/wr/app/map/mapSearchBar.tsx deleted file mode 100644 index b24b5d83a..000000000 --- a/apps/wr/app/map/mapSearchBar.tsx +++ /dev/null @@ -1,414 +0,0 @@ -// "use client" - -// import { useWrStore } from "@/app/store"; -// import SearchInputText from "@/components/ui/searchInput/searchInput"; -// import type { EnvPartSelectDataType, ReturnType, SelectDataType } from "@common/business_components/ui"; -// import { SelectBox } from "@common/business_components/ui"; -// import { Button, Input, Label } from "@common/components/ui"; -// import React, { useEffect, useMemo, useRef, useState } from "react"; -// import { MapSearchFormLeft } from "./mapSearchForm"; - - -// // 건물 검색 타입 정의 -// interface BuildingInfo { -// bdstInfoPk: number; -// ctpvCd: number; -// sggCd: number; -// daddr: string; -// bdstNm: string; -// frstArchPrmsnDt: string; -// archArea: number; -// ctpvNm: string | null; -// sggNm: string | null; -// lat: number | null; -// lot: number | null; -// regDt: string; -// rgtr: string | null; -// mdfcnDt: string; -// mdfr: string | null; -// } - -// type SearchBaseType = { -// searchType: string; -// selectSidoData?: SelectDataType[] | []; -// selectSigunData?: SelectDataType[] | []; -// selectRegionData?: SelectDataType[] | []; -// selectUnitWaterShedData?: SelectDataType[] | []; -// selectMiddleRegionData?: SelectDataType[] | []; -// selectEnvPartData?: EnvPartSelectDataType[] | []; -// onFeatureSelect: () => void; -// btnClass?: string; -// ref?: React.RefObject<ReturnType>; -// isAdmin?: boolean; -// leftClassName?: string; -// rightClassName?: string; -// showQueryButton?: boolean; -// showInitButton?: boolean; -// showApplyButton?: boolean; -// checkedLayers?: string[]; -// checkedLayersData?: any[]; -// } - -// const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; - -// const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`); - -// interface SearchModalProps { -// open: boolean; -// onOpenChange: (open: boolean) => void; -// onFeatureSelect: (row: any) => void; -// } - -// interface SelectedDataTypeWithSggNm { -// text: string; -// val: string; -// sggNm: string; -// } - -// export function MapSearchBar({ -// searchType, -// selectSidoData, -// selectSigunData, -// selectRegionData, -// selectUnitWaterShedData, -// selectMiddleRegionData, -// selectEnvPartData, -// btnClass, -// onFeatureSelect, -// isAdmin = false, -// leftClassName, -// rightClassName, -// showQueryButton = true, -// showInitButton = true, -// showApplyButton = true, -// checkedLayers = [], -// checkedLayersData = [], -// }: SearchBaseType) { - -// // 로딩바 -// const [isLoading, setIsLoading] = useState(false); -// // 상세 정보 조회를 위한 상태 추가 -// const [popupFeature, setPopupFeature] = useState<any>(null); -// const [isChHead, setIsChHead] = useState(false); -// const ref = useRef<ReturnType>({} as ReturnType); - -// // zustand store에서 건물 검색 함수와 데이터 가져오기 -// const { -// code, -// bdst, -// findBdst, -// wrMap, -// buildingSearchRes, -// buildingNmSearch, -// buildingNmSearchMultiple -// } = useWrStore((state) => state); - -// const [selectedBuilding, setSelectedBuilding] = useState<BuildingInfo | null>(null); -// const [buildingSearchText, setBuildingSearchText] = useState(""); -// const [buildingList, setBuildingList] = useState<BuildingInfo[]>([]); - -// // 전체 목록 -// const [partValue, setPartValue] = useState<string>("A"); -// const [sidoValue, setSidoValue] = useState<string>("0"); -// const [sigunValue, setSigunValue] = useState<string>("0"); -// const [regionValue, setRegionValue] = useState<string>("0"); -// const [untitWaterShedValue, setUntitWaterShedValue] = useState<string>("0"); -// const [middleRegionValue, setMiddleRegionValue] = useState<string>("0"); -// const [envPartValue, setEnvPartValue] = useState<string>("0"); -// const [resetTrigger, setResetTrigger] = useState(false); -// const [sidoText, setSidoText] = useState<string>("0"); -// const [sigunText, setSigunText] = useState<string>("0"); -// // 공급처 후보지 조회 필터 목록 -// const [selectedSido, setSelectedSido] = useState<SelectDataType>({ text: "전체", val: '0' }); -// const [selectedSigun, setSelectedSigun] = useState<SelectDataType>({ text: "전체", val: '0' }); -// const [selectedFclt, setSelectedFclt] = useState<SelectedDataTypeWithSggNm>({ text: "전체", val: '0', sggNm: '전체' }); // 시설명 선택 상태 -// // 전체 시설 -// let allFclt: SelectedDataTypeWithSggNm[] = [{ text: "전체", val: '0', sggNm: '전체' }]; -// const [selectedDong, setSelectedDong] = useState<SelectedDataTypeWithSggNm>({ text: "전체", val: '0', sggNm: '전체' }); // 시설명 선택 상태 // 행정동 - -// const filteredSigunData = useMemo(() => { -// if (!selectedSido || selectedSido.val === '0' || !selectedSido.val) return [{ text: "전체", val: '0' }]; -// return [ -// { text: "전체", val: '0' }, -// ...code.sggCd.filter((item: { val: string; }) => item.val.substring(0, 2) === selectedSido.val.substring(0, 2)) -// ]; -// }, [selectedSido]); - -// const filteredFcltData = useMemo(() => { -// if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) return [{ text: "전체", val: '0', sggNm: '전체' }]; -// return [ -// { text: "전체", val: '0', sggNm: '전체' }, -// ...allFclt.filter(item => item.sggNm === selectedSido.text) -// ]; -// }, [selectedSigun]); - -// const filteredDong = useMemo(() => { -// if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) return [{ text: "전체", val: '0', sggNm: '전체' }]; -// return [ -// { text: "전체", val: '0', sggNm: '전체' }, -// // ...code.dong.filter(item => item.sggNm === selectedSido.text) -// ]; -// }, [selectedSigun]); - -// // 조회 함수 -// const queryVal = () => { -// // 46 : 하수처리시설 -// // 47 : 하수재이용시설 -// // 48 : 빗물이용시설 -// // 49 : 중수도시설 -// // 50 : 온배수시설 -// console.log("조회버튼 클릭: ", checkedLayers); -// if (checkedLayers && checkedLayers.includes('48')) { -// // searchBuildings -// } -// } - -// // 초기화 함수 -// const initVal = () => { -// setPartValue("A"); -// setSidoValue("0"); -// setSigunValue("0"); -// setRegionValue("0"); -// setUntitWaterShedValue("0"); -// setMiddleRegionValue("0"); -// setEnvPartValue("0"); -// setSidoText("전체"); -// setSigunText("전체"); -// setSelectedSido({ text: "전체", val: '0' }); -// setSelectedSigun({ text: "전체", val: '0' }); -// setSelectedFclt({ text: "전체", val: '0', sggNm: '전체' }); -// setSelectedDong({ text: "전체", val: '0', sggNm: '전체' }); -// setResetTrigger(true); -// }; - -// // 적용 버튼 -// const applyVal = () => { -// onFeatureSelect(); -// }; - -// useEffect(() => { -// if (resetTrigger) { -// setResetTrigger(false); -// } -// }, [resetTrigger]); - -// // 시설 조회 -// useEffect(() => { -// const fetchData = async () => { -// setIsLoading(true); -// if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) { -// allFclt = ([{ text: "전체", val: '0', sggNm: '전체' }]); -// setIsLoading(false); -// return; -// } - -// try { -// const queryParamsFacility = new URLSearchParams({ -// lyrTypeNm: 'tb_il_swage_prcs_fclt', -// page: '0', -// size: '100000', -// sort: 'string', -// }); -// const cqlFiltersFacility: string[] = []; -// if (selectedSigun.text && selectedSigun.val !== '0') { -// cqlFiltersFacility.push(`sgg_nm ILIKE '%${selectedSigun.text}%'`); -// } -// if (cqlFiltersFacility.length > 0) { -// queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and ')); -// } -// console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`); - -// const facilityRes = await fetch(`${API_URL}/v1/fclts?${queryParamsFacility.toString()}`, { -// method: "GET", -// headers: { accept: "application/json" } -// }).then(res => res.json()); - -// const facilities = (facilityRes.data || []).map((item: any) => ({ -// text: item.swtrmtFcltNm, -// val: item.fid, -// sggNm: item.sggNm -// })); -// allFclt = (facilities); - -// } catch (error) { -// console.error("BaseLayout: 지역/시설 데이터 조회 중 오류 발생:", error); -// allFclt = ([{ text: "전체", val: '0', sggNm: '전체' }]); -// } finally { -// setIsLoading(false); -// } -// }; - -// fetchData(); -// }, [selectedSigun]); - -// useEffect(() => { -// if (ref && ref.current) { -// const customRef = ref.current; -// customRef.partValue = partValue; -// customRef.sidoValue = sidoValue; -// customRef.sigunValue = sigunValue; -// customRef.regionValue = regionValue; -// customRef.unitWaterShedValue = untitWaterShedValue; -// customRef.middleRegionValue = middleRegionValue; -// customRef.envPartValue = envPartValue; -// customRef.sidoText = selectedSido.text; -// customRef.sigunText = selectedSigun.text; -// } -// }, [partValue, sidoValue, sigunValue, regionValue, untitWaterShedValue, middleRegionValue, envPartValue, ref]); - -// // buildingSearchText가 변경될 때 API 호출 -// useEffect(() => { -// if (buildingSearchText && buildingSearchText.length > 1) { -// if (checkedLayers && checkedLayers.length > 0) { -// // 다중 레이어 검색 -// // buildingNmSearchMultiple(checkedLayers, selectedSigun.val || "", buildingSearchText); -// buildingNmSearch("RNB", selectedSigun.val, buildingSearchText); -// } else { -// // 단일 레이어 검색 -// // buildingNmSearch(checkedLayers[0], selectedSigun.val, buildingSearchText); -// } -// } else { -// // 검색 텍스트가 짧으면 리스트 초기화 -// if (checkedLayers && checkedLayers.length > 0) { -// // buildingNmSearchMultiple(checkedLayers, selectedSigun.val || "", ""); -// } else { -// buildingNmSearch("RNB", selectedSigun.val || "", ""); -// } -// } -// }, [buildingSearchText]); - -// return ( -// <div className="absolute left-1/2 -translate-x-1/2 bg-white flex items-center justify-center p-4 rounded-md shadow-lg w-auto min-w-fit"> -// <div className={leftClassName ? leftClassName : `flex items-center justify-center space-x-2 `}> -// <div className="flex gap-8 items-center"> -// {searchType == "공급처 후보지 조회" && ( -// <> -// <SelectBox -// className="flex items-center" -// label={'시도'} -// selectArray={code.cityCd} -// onSelectValue={(val) => { -// const selected = code.cityCd.find((item: { val: string | number; }) => (item.val === val)); -// setSelectedSido(selected || { text: "전체", val: '0' }); -// setSelectedSigun({ text: "전체", val: '0' }); -// }} -// value={selectedSido.val} -// selectClass={'w-32'} -// /> -// <SelectBox -// className="flex items-center" -// label={'시군구'} -// selectArray={filteredSigunData} -// onSelectValue={(val) => { -// const selected = filteredSigunData.find(item => (item.val === val)); -// setSelectedSigun(selected || { text: "전체", val: '0' }); -// setSelectedFclt({ text: "전체", val: '0', sggNm: '전체' }); -// }} -// value={selectedSigun.val} -// selectClass={'w-32'} -// /> -// <div className="flex items-center"> -// <Label className="w-20 text-xl text-gray-600">시설명</Label> -// <div className="w-64"> -// <SearchInputText -// label="시설명" -// initValue={buildingSearchText} -// setValue={(searchNm?: string) => { -// setBuildingSearchText(searchNm || ""); -// }} -// setRtnData={function (rtnData: any): void { -// // 선택된 건물 데이터 처리 -// // if (rtnData && rtnData.bdstInfoPk) { -// // setSelectedBuilding(rtnData); -// // setBuildingSearchText(rtnData.bdstNm || ""); -// // } -// }} -// searchList={buildingSearchRes || []} -// /> -// </div> -// </div> -// </> -// )} -// {searchType == "우리동네가뭄지도보기" && ( -// <> -// <SelectBox -// className="flex items-center" -// label={'시도'} -// selectArray={code.cityCd} -// onSelectValue={(val) => { -// const selected = code.cityCd.find((item: { val: string | number; }) => (item.val === val)); -// setSelectedSido(selected || { text: "전체", val: '0' }); -// setSelectedSigun({ text: "전체", val: '0' }); -// }} -// value={selectedSido.val} -// selectClass={'w-44'} -// /> -// <SelectBox -// className="flex items-center" -// label={'시군구'} -// selectArray={filteredSigunData} -// onSelectValue={(val) => { -// const selected = filteredSigunData.find(item => (item.val === val)); -// setSelectedSigun(selected || { text: "전체", val: '0' }); -// setSelectedDong({ text: "전체", val: '0', sggNm: '전체' }); -// }} -// value={selectedSigun.val} -// selectClass={'w-32'} -// /> -// <SelectBox -// className="flex items-center mr-8" -// label={'행정동'} -// selectArray={filteredDong} -// onSelectValue={(val) => { -// const selected = filteredDong.find(item => (item.val === val)); -// setSelectedDong(selected || { text: "전체", val: '0', sggNm: '전체' }); -// }} -// value={selectedDong.val} -// selectClass={'w-32'} -// /> -// </> -// )} -// {searchType == "지도보기" && ( -// <div className="flex items-center gap-2 w-[800px]"> -// <div className="flex min-w-0"> {/* SearchFormLeft 래퍼 */} -// <MapSearchFormLeft -// isShowPart={true} -// selectSidoData={code.cityCd} -// selectSigunData={filteredSigunData} -// selectRegionData={code.rvbsnCd} -// selectUnitWaterShedData={selectUnitWaterShedData} -// selectMiddleRegionData={selectMiddleRegionData} -// selectEnvPartData={selectEnvPartData} -// setRtnPartValue={setPartValue} -// setRtnSidoValue={setSidoValue} -// setRtnSigunValue={setSigunValue} -// setRtnRegionValue={setRegionValue} -// setRtnUnitWaterShedValue={setUntitWaterShedValue} -// setRtnMiddleRegionValue={setMiddleRegionValue} -// setRtnEnvPartValue={setEnvPartValue} -// setRtnEnvPartSidoValue={setSidoValue} -// setRtnEnvPartSigunValue={setSigunValue} -// setRtnSidoText={setSidoText} -// setRtnSigunText={setSigunText} -// resetTrigger={resetTrigger} -// isAdmin={isAdmin} -// children={undefined} -// /> -// </div> -// <Label className="w-auto text-xl text-gray-600 whitespace-nowrap">시설명</Label> -// <div className="w-44"> -// <Input className="mr-4" /> -// </div> -// </div> -// )} -// </div> -// {/* 버튼 부분 */} -// <div className="flex items-center justify-center gap-4"> -// {showQueryButton && <Button className={btnClass} onClick={queryVal}>조회</Button>} -// {showInitButton && <Button className={btnClass} onClick={initVal}>초기화</Button>} -// {showApplyButton && <Button className={btnClass} onClick={applyVal}>적용</Button>} -// </div> -// </div> -// </div> -// ) -// } diff --git a/apps/wr/app/map/mapSearchForm.tsx b/apps/wr/app/map/mapSearchForm.tsx deleted file mode 100644 index 70927996b..000000000 --- a/apps/wr/app/map/mapSearchForm.tsx +++ /dev/null @@ -1,340 +0,0 @@ -"use client" - -import React, { useEffect, useState } from 'react'; -import type { SelectDataType } from '@common/business_components/ui/search_input_select'; -import { SelectBox } from '@common/business_components/ui/select'; - -/** - * 검색 폼 왼쪽 컴포넌트 타입 - * - * @param isShowPart 구분 조회 여부 - * @param children 자식 컴포넌트 - * @param selectSidoData 시도 데이터 - * @param selectSigunData 시군구 데이터 - * @param selectRegionData 유역 데이터 - * @param selectUnitWaterShedData 단위유역 데이터 - * @param selectMiddleRegionData 중권역 데이터 - * @param selectEnvPartData 환경청 데이터 - * @param selectEnvPartSidoData 환경청 시도 데이터 - * @param selectEnvPartSigunData 환경청 시군구 데이터 - * @param setRtnPartValue 부분 값 변경 핸들러 - */ -type SearchFormLeftProps = { - isShowPart?: boolean | undefined; - children: React.ReactNode; - selectSidoData?: SelectDataType[] | []; - selectSigunData?: SelectDataType[] | []; - selectRegionData?: SelectDataType[] | []; - selectUnitWaterShedData?: SelectDataType[] | []; - selectMiddleRegionData?: SelectDataType[] | []; - selectEnvPartData?: EnvPartSelectDataType[] | []; - selectEnvPartSidoData?: SelectDataType[] | []; - selectEnvPartSigunData?: SelectDataType[] | []; - - setRtnPartValue?: (value: string) => void; - setRtnSidoValue?: (value: string) => void; - setRtnSigunValue?: (value: string) => void; - setRtnRegionValue?: (value: string) => void; - setRtnUnitWaterShedValue?: (value: string) => void; - setRtnMiddleRegionValue?: (value: string) => void; - setRtnEnvPartValue?: (value: string) => void; - setRtnEnvPartSidoValue?: (value: string) => void; - setRtnEnvPartSigunValue?: (value: string) => void; - setRtnSidoText?: (value: string) => void; - setRtnSigunText?: (value: string) => void; - resetTrigger?: boolean; - isAdmin?: boolean; -} - -export type EnvPartSelectDataType = SelectDataType & { - adstDliStrCd: string, -} - -const selectPartData: SelectDataType[] = [ - { text: "행정별", val: 'A' }, - { text: "유역별", val: 'R' }, - { text: "환경청별", val: 'G' }, -]; - -function MapSearchFormLeft({ isShowPart = false, children, selectSidoData = [], selectSigunData = [], selectRegionData = [], selectUnitWaterShedData = [], selectMiddleRegionData = [], selectEnvPartData = [], setRtnPartValue, setRtnSidoValue, setRtnSidoText, setRtnSigunValue, setRtnSigunText, setRtnRegionValue, setRtnUnitWaterShedValue, setRtnMiddleRegionValue, setRtnEnvPartValue, setRtnEnvPartSidoValue, setRtnEnvPartSigunValue, resetTrigger = false, isAdmin = false }: SearchFormLeftProps) { - /******************선택된 데이터******************/ - const [partValue, setPartValue] = useState<string>('A'); - //행정별 시도 시군구 - const [sidoValue, setSidoValue] = useState<string>('0'); - const [sigunValue, setSigunValue] = useState<string>('0'); - const [sidoText, setSidoText] = useState<string>(''); - const [sigunText, setSigunText] = useState<string>(''); - //유역별 - const [regionValue, setRegionValue] = useState<string>('0'); - const [unitWaterShedValue, setUnitWaterShedValue] = useState<string>('0'); - const [middleRegionValue, setMiddleRegionValue] = useState<string>('0'); - //환경청별 시도 시군구 - const [envPartValue, setEnvPartValue] = useState<string>('0'); - // 환경청 - const [filteredEnvPartSigunDataSelected, setFilteredEnvPartSigunDataSelected] = useState<SelectDataType[]>([]); - - /****************** 셀렉트 리스트 데이터. ******************/ - // 조회된 조건에 맞는 시도 시군 유역 - const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - const [filteredUnitWaterShedData, setFilteredUnitWaterShedData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - const [filteredMiddleRegionData, setFilteredMiddleRegionData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - // 조회된 조건에 맞는 환경청 시도 시군 - const [filteredEnvPartData, setFilteredEnvPartData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]); - const [filteredEnvPartSidoData, setFilteredEnvPartSidoData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]); - const [filteredEnvPartSigunData, setFilteredEnvPartSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - - // 시군구 세팅 - const initializeSigunData = (sidoCd: string) => { - if (sidoCd === '0') { - setSigunValue('0'); - setFilteredSigunData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectSigunData.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd) - ]; - setSigunValue('0'); - setFilteredSigunData(newFilteredData); - } - } - - // 단위유역 세팅 - const initializeUnitWaterShedData = (regionCd: string) => { - if (regionCd === '0') { - setUnitWaterShedValue('0'); - setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectUnitWaterShedData.filter((item: SelectDataType) => item.val.substring(0, 1) === regionCd) - ]; - setUnitWaterShedValue('0'); - setFilteredUnitWaterShedData(newFilteredData); - } - } - - // 중권역 세팅 - const initializeMiddleRegionData = (unitWaterShedCd: string) => { - if (unitWaterShedCd === '0') { - setMiddleRegionValue('0'); - setFilteredMiddleRegionData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectMiddleRegionData.filter((item: SelectDataType) => item.val.substring(0, 2) === unitWaterShedCd) - ]; - setMiddleRegionValue('0'); - setFilteredMiddleRegionData(newFilteredData); - } - } - - // 환경청 세팅 - 시도 - const initializeCityDataByEnvPartSido = (envPartCd: string) => { - const foundEnvPart = selectEnvPartData.find((item: EnvPartSelectDataType) => item.val === envPartCd); - const cityArray = foundEnvPart?.adstDliStrCd.toString().split('|').join('').split(','); - - // 시군구 데이터 - const envSigunData = selectSigunData.filter((item: SelectDataType) => cityArray?.includes(item.val)); - - // 환경청 시도 데이터 - const sidoArray = [...new Set(envSigunData.map((item: SelectDataType) => item.val.substring(0, 2)))]; - const envSidoData = selectSidoData.filter((item: SelectDataType) => sidoArray?.includes(item.val)); - setFilteredEnvPartSigunDataSelected(envSigunData); - - setFilteredEnvPartSidoData([ - { text: "전체", val: '0', adstDliStrCd: '' }, - ...envSidoData.map((item: SelectDataType) => ({ text: item.text, val: item.val, adstDliStrCd: '' })) - ]); - } - - // 환경청 세팅 - 시군구 - const initializeCityDataByEnvPartSigun = (sidoCd: string) => { - const envSigunData = filteredEnvPartSigunDataSelected.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd); - setFilteredEnvPartSigunData([ - { text: "전체", val: '0' }, - ...envSigunData.map((item: SelectDataType) => ({ text: item.text, val: item.val })) - ]); - } - - const onSelectValue = (val: string, type: string) => { - let selectedSido; - let selectedSigun; - let selectedEnvPartSido; - let selectedEnvPartSigun; - - switch (type) { - case 'part': - setPartValue(val); - if (setRtnPartValue) { - setRtnPartValue(val); - } - // 구분 - if (val == 'R') { - initializeMiddleRegionData('0'); - initializeUnitWaterShedData('0'); - } else if (val == 'G') { - setFilteredEnvPartData([ - { text: "전체", val: '0', adstDliStrCd: '' }, - ...selectEnvPartData.filter((item: EnvPartSelectDataType) => item.val !== null && item.adstDliStrCd !== '') - ]); - setEnvPartValue('0'); - initializeCityDataByEnvPartSido('0'); - } else { - initializeSigunData('0'); - onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); - } - - // 다른 selectbox 전체로 초기화 - onSelectValue(selectSidoData[0]?.val || '0', 'sido'); - onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); - break; - case 'sido': - setSidoValue(val); - selectedSido = selectSidoData.find(item => item.val === val); - setSidoText(selectedSido?.text || ''); - if (setRtnSidoValue) { - setRtnSidoValue(val); - } - if (setRtnSidoText) { - setRtnSidoText(selectedSido?.text || ''); - } - initializeSigunData(val); - onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); - break; - case 'sigun': - if (setRtnSigunValue) { - setRtnSigunValue(val); - } - setSigunValue(val); - selectedSigun = filteredSigunData.find(item => item.val === val); - if (setRtnSigunText) { - setRtnSigunText(selectedSigun?.text || ''); - } - setSigunText(selectedSigun?.text || ''); - break; - - // 유역 세팅 - case 'region': - setRegionValue(val); - if (setRtnRegionValue) { - setRtnRegionValue(val); - } - initializeUnitWaterShedData(val); - onSelectValue(selectUnitWaterShedData[0]?.val || '0', 'unitWaterShed'); - break; - case 'unitWaterShed': - setUnitWaterShedValue(val); - if (setRtnUnitWaterShedValue) { - setRtnUnitWaterShedValue(val); - } - initializeMiddleRegionData(val); - onSelectValue(selectMiddleRegionData[0]?.val || '0', 'middleRegion'); - break; - case 'middleRegion': - setMiddleRegionValue(val); - if (setRtnMiddleRegionValue) { - setRtnMiddleRegionValue(val); - } - break; - - // 환경청 세팅 - case 'envPart': - setEnvPartValue(val); - if (setRtnEnvPartValue) { - setRtnEnvPartValue(val); - } - initializeCityDataByEnvPartSido(val); - onSelectValue(filteredEnvPartSidoData[0]?.val || '0', 'envPartSido'); - break; - case 'envPartSido': - setSidoValue(val); - selectedEnvPartSido = filteredEnvPartSidoData.find(item => item.val === val); - setSidoText(selectedEnvPartSido?.text || ''); - if (setRtnEnvPartSidoValue) { - setRtnEnvPartSidoValue(val); - } - initializeCityDataByEnvPartSigun(val); - onSelectValue(filteredEnvPartSigunData[0]?.val || '0', 'envPartSigun'); - break; - case 'envPartSigun': - setSigunValue(val); - selectedEnvPartSigun = filteredEnvPartSigunData.find(item => item.val === val); - setSigunText(selectedEnvPartSigun?.text || ''); - if (setRtnEnvPartSigunValue) { - setRtnEnvPartSigunValue(val); - } - break; - } - } - - // 리셋 함수 - const resetAllValues = () => { - setPartValue('A'); - setSidoValue('0'); - setSigunValue('0'); - setRegionValue('0'); - setUnitWaterShedValue('0'); - setMiddleRegionValue('0'); - setEnvPartValue('0'); - - setFilteredSigunData([{ text: "전체", val: '0' }]); - setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]); - setFilteredMiddleRegionData([{ text: "전체", val: '0' }]); - setFilteredEnvPartData([{ text: "전체", val: '0', adstDliStrCd: '' }]); - setFilteredEnvPartSidoData([{ text: "전체", val: '0', adstDliStrCd: '' }]); - setFilteredEnvPartSigunData([{ text: "전체", val: '0' }]); - - if (setRtnPartValue) setRtnPartValue('A'); - if (setRtnSidoValue) setRtnSidoValue('0'); - if (setRtnSigunValue) setRtnSigunValue('0'); - if (setRtnRegionValue) setRtnRegionValue('0'); - if (setRtnUnitWaterShedValue) setRtnUnitWaterShedValue('0'); - if (setRtnMiddleRegionValue) setRtnMiddleRegionValue('0'); - if (setRtnEnvPartValue) setRtnEnvPartValue('0'); - if (setRtnEnvPartSidoValue) setRtnEnvPartSidoValue('0'); - if (setRtnEnvPartSigunValue) setRtnEnvPartSigunValue('0'); - }; - - // 리셋 트리거 변경 감지 - useEffect(() => { - if (resetTrigger) { - resetAllValues(); - // 리셋 후 트리거를 false로 설정 - if (setRtnPartValue) { - setRtnPartValue('0'); - } - } - }, [resetTrigger]); - - return ( - isShowPart ? ( - <div className="flex gap-5"> - <SelectBox className="w-auto whitespace-nowrap" label={'구분'} selectArray={isAdmin ? selectPartData.slice(0, 1) : selectPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'part')} value={partValue} selectClass={'w-32'} /> - {partValue === 'R' ? ( - <> - <SelectBox className="w-auto whitespace-nowrap" label={'유역'} selectArray={selectRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'region')} value={regionValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'단위유역'} selectArray={filteredUnitWaterShedData} onSelectValue={(val) => onSelectValue(val.toString(), 'unitWaterShed')} value={unitWaterShedValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'중권역'} selectArray={filteredMiddleRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'middleRegion')} value={middleRegionValue} selectClass={'w-44'} /> - </> - ) : partValue === 'G' ? ( - <> - <SelectBox className="w-auto whitespace-nowrap" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={sidoValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={sigunValue} selectClass={'w-44'} /> - </> - ) : ( - <> - <SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={selectSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={'w-44'} /> - </> - )} - </div> - ) : ( - <div className="grid grid-cols-12 gap-5 w-11/12 m-4"> - {children} - </div> - ) - ) -} - -export { MapSearchFormLeft }; diff --git a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx b/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx deleted file mode 100644 index f6d870092..000000000 --- a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx +++ /dev/null @@ -1,596 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; -import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SelectBox, UiTable, type ChartConfig, type ReturnType } from "@common/business_components"; -import ListDiv from "@common/business_components/ui/list_div"; -import { useEffect, useRef, useState } from "react"; -import { Toaster } from "react-hot-toast"; - -interface PbnstPrfmncSttnPopupProps { - isVisible?: boolean; -} - -export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSttnPopupProps) { - const { code, tableHeadMaker, pbnstPrfmncSttn, pbnstPrfmncInit, pbnstPrfmncSearch, prfmnc } = useWrStore((state) => state); - const { monthHeadList } = prfmnc - const { pbnstPrfHeadList, pbnstPrfmncRes, prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn; - const [isChHead, setIsChHead] = useState(false); - const [fromDate, setFromDate] = useState<string>(String(new Date().getFullYear())); - const [toDate, setToDate] = useState<string>(String(new Date().getFullYear())); - const [year, setYear] = useState<string>(String(new Date().getFullYear())); - const [bdstTable, setbdstTable] = useState<FcPrfType[]>(); - const ref = useRef<ReturnType>({} as ReturnType); - const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>(); - const [chartConfig, setChartConfig] = useState<ChartConfig>({}); - const [chartData, setChartData] = useState<dnChartForm[]>([]); - const [dnInUsage, setDnInUsage] = useState<dnChartForm[]>([]); - const [dnInChartConfig, setDnInChartConfig] = useState<ChartConfig>({}); - const [dnOutUsage, setDnOutUsage] = useState<dnChartForm[]>([]); - const [dnOutChartConfig, setDnOutChartConfig] = useState<ChartConfig>({}); - const [barData, setBarData] = useState<barChartForm[]>([]); - const [barChartConfig, setBarChartConfig] = useState<ChartConfig>({}); - const [prfData, setPrfData] = useState<any[]>(); - const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({}); - const [lnOutChartConfig, setLnOutChartConfig] = useState<ChartConfig>({}); - const [inLineData, setInLineData] = useState<{ - chartData1: lineChartDataProps[]; - chartData2: lineChartDataProps[]; - chartData3: lineChartDataProps[]; - chartData4: lineChartDataProps[]; - chartData5: lineChartDataProps[]; - chartData6: lineChartDataProps[]; - chartData7: lineChartDataProps[]; - chartData8: lineChartDataProps[]; - chartData9: lineChartDataProps[]; - }>(); - // const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({}); - const [outLineData, setOutLineData] = useState<{ - chartData1: lineChartDataProps[]; - chartData2: lineChartDataProps[]; - chartData3: lineChartDataProps[]; - chartData4: lineChartDataProps[]; - chartData5: lineChartDataProps[]; - chartData6: lineChartDataProps[]; - }>(); - - - - type dnChartForm = { label: string, val: number, fill?: string }; - type barChartForm = { label: string, "장내용수": number, "장외용수": number }; - type lineChartDataProps = { label: string, val: number, color: string }; - - const prfTableData = (prfList: PrfType[], year: string) => { - const inUsageData = initValInUsage; - const outUsageData = initValOutUsage; - - const inSubtotal = subTotalObj; - const outSubtotal = subTotalObj; - - console.log(' prfList ', prfList) - const prfFilter = prfList?.filter((e) => e.ym.slice(0, 4) === year) - if (prfList && prfFilter.length > 0) { - prfList?.forEach((prfItem) => { - const month = Number(prfItem?.ym?.slice(4)); // "MM" - const monthKey = `${month}월`; - - inUsageData.forEach((inData: any) => { - const usageKey = inData.usage; - const value = (prfItem as any)[usageKey] ?? 0; - - inData[monthKey] = value; - inData.total += value; - - if (inSubtotal && usageKey !== "subtotal") { - (inSubtotal as any)[monthKey] = - ((inSubtotal as any)[monthKey] ?? 0) + value; - inSubtotal.total += value; - } - }); - - outUsageData.forEach((outData: any) => { - const usageKey = outData.usage; - const value = (prfItem as any)[usageKey] ?? 0; - - outData[monthKey] = value; - outData.total += value; - - if (usageKey !== "subtotal") { - (outSubtotal as any)[monthKey] = - ((outSubtotal as any)[monthKey] ?? 0) + value; - outSubtotal.total += value; - } - }); - }); - inUsageData.push(inSubtotal); - outUsageData.push(outSubtotal); - const usageTotalObj: { [key: string]: any } = totalObj; - for (const key in usageTotalObj) { - if (["usage", "gubun", "edit"].includes(key)) continue; - const val = - (Number((inSubtotal as any)[key]) || 0) + - (Number((outSubtotal as any)[key]) || 0); - - (usageTotalObj as any)[key] = val; - } - const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; - setPrfData(tableData); - - } else { - setPrfData([]); - } - } - useEffect(() => { - let wshwtr = 0; - let coolUswtr = 0; - let cleanUswtr = 0; - let drwtUswtr = 0; - let dltnUswtr = 0; - let ithlRswtr = 0; - let ithlEtcUswtr = 0; - let cleanToilUswtr = 0; - let resn = 0; - let lndwtr = 0; - let hydUswtr = 0; - let ugwtChr = 0; - let farmUswtr = 0; - let rvrKeepUswtr = 0; - let indstUswtr = 0; - if (rawData) { - rawData.forEach((item) => { - prfTableData(item.prfList, year); - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - - wshwtr += element.wshwtr; //세척수 - coolUswtr += element.coolUswtr; //냉각수 - cleanUswtr += element.cleanUswtr; //청소수 - drwtUswtr += element.drwtUswtr; //식수대 - dltnUswtr += element.dltnUswtr //희석용수 - ithlRswtr += element.ithlRswtr //중수도 - ithlEtcUswtr += element.ithlEtcUswtr //기타 - cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 - resn += element.resn //세척살수용수 - - lndwtr += element.lndwtr; //조경용수 - hydUswtr += element.hydUswtr; //친수용수 - ugwtChr += element.ugwtChr; //지하수충전 - farmUswtr += element.farmUswtr //농업용수 - rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 - indstUswtr += element.indstUswtr //공업용수 - - }); - }) - const data: dnChartForm[] = [] - data?.push({ label: "세척수", val: wshwtr, fill: "red" }) - data?.push({ label: "냉각수", val: coolUswtr, fill: "orange" }) - data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) - data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) - data?.push({ label: "희석용수", val: dltnUswtr, fill: "skyblue" }) - data?.push({ label: "중수도", val: ithlRswtr, fill: "blue" }) - data?.push({ label: "기타", val: ithlEtcUswtr, fill: "purple" }) - data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "red" }) - data?.push({ label: "세척살수용수", val: resn, fill: "orange" }) - data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) - data?.push({ label: "친수용수", val: hydUswtr, fill: "green" }) - data?.push({ label: "지하수충전", val: ugwtChr, fill: "skyblue" }) - data?.push({ label: "농업용수", val: farmUswtr, fill: "blue" }) - data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "purple" }) - data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) - setChartData(data); - } - }, [rawData, year]) - - - useEffect(() => { - const newChartConfig = chartData.reduce((config, element) => { - config[element.label] = { - label: element.label, - fill: element.fill - }; - return config; - }, {} as Record<string, { label: string; fill?: string }>) satisfies ChartConfig; - setChartConfig(newChartConfig); - }, [chartData]); - - // 장내용수 도넛차트 - useEffect(() => { - let wshwtr = 0; - let coolUswtr = 0; - let cleanUswtr = 0; - let drwtUswtr = 0; - let dltnUswtr = 0; - let ithlRswtr = 0; - let ithlEtcUswtr = 0; - let cleanToilUswtr = 0; - let resn = 0; - if (rawData) { - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - - wshwtr += element.wshwtr; //세척수 - coolUswtr += element.coolUswtr; //냉각수 - cleanUswtr += element.cleanUswtr; //청소수 - drwtUswtr += element.drwtUswtr; //식수대 - dltnUswtr += element.dltnUswtr //희석용수 - ithlRswtr += element.ithlRswtr //중수도 - ithlEtcUswtr += element.ithlEtcUswtr //기타 - cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 - resn += element.resn //세척살수용수 - }); - }) - const data: dnChartForm[] = [] - data?.push({ label: "세척수", val: wshwtr, fill: "yellow" }) - data?.push({ label: "냉각수", val: coolUswtr, fill: "green" }) - data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) - data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) - data?.push({ label: "희석용수", val: dltnUswtr, fill: "yellow" }) - data?.push({ label: "중수도", val: ithlRswtr, fill: "green" }) - data?.push({ label: "기타", val: ithlEtcUswtr, fill: "yellow" }) - data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "green" }) - data?.push({ label: "세척살수용수", val: resn, fill: "yellow" }) - setDnInUsage(data); - } - }, [rawData, year]) - - useEffect(() => { - const newChartConfig = dnInUsage.reduce((config, element) => { - config[element.label] = { - label: element.label, - fill: element.fill - }; - return config; - }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; - setDnInChartConfig(newChartConfig); - }, [dnInUsage]); - - // 장외용수 도넛차트 - useEffect(() => { - let lndwtr = 0; - let hydUswtr = 0; - let ugwtChr = 0; - let farmUswtr = 0; - let rvrKeepUswtr = 0; - let indstUswtr = 0; - if (rawData) { - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - lndwtr += element.lndwtr; //조경용수 - hydUswtr += element.hydUswtr; //친수용수 - ugwtChr += element.ugwtChr; //지하수충전 - farmUswtr += element.farmUswtr //농업용수 - rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 - indstUswtr += element.indstUswtr //공업용수 - - }); - }) - const data: dnChartForm[] = [] - data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) - data?.push({ label: "친수용수", val: hydUswtr, fill: "black" }) - data?.push({ label: "지하수충전", val: ugwtChr, fill: "yellow" }) - data?.push({ label: "농업용수", val: farmUswtr, fill: "black" }) - data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "yellow" }) - data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) - setDnOutUsage(data); - } - }, [rawData, year]) - - useEffect(() => { - const newChartConfig = dnOutUsage.reduce((config, element) => { - config[element.label] = { - label: element.label, - fill: element.fill - }; - return config; - }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; - setDnOutChartConfig(newChartConfig); - }, [dnOutUsage]); - - //월별 장내외 용수 총 실적 막대차트 - useEffect(() => { - let wshwtr = 0; - let coolUswtr = 0; - let cleanUswtr = 0; - let drwtUswtr = 0; - let dltnUswtr = 0; - let ithlRswtr = 0; - let ithlEtcUswtr = 0; - let cleanToilUswtr = 0; - let resn = 0; - let lndwtr = 0; - let hydUswtr = 0; - let ugwtChr = 0; - let farmUswtr = 0; - let rvrKeepUswtr = 0; - let indstUswtr = 0; - let inUsageSum = 0; - let outUsageSum = 0; - let inUsageArr = []; - let outUsageArr = []; - - - if (rawData) { - const data: barChartForm[] = [] - rawData.forEach((item) => { - item.prfList - .filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - - wshwtr = element.wshwtr; //세척수 - coolUswtr = element.coolUswtr; //냉각수 - cleanUswtr = element.cleanUswtr; //청소수 - drwtUswtr = element.drwtUswtr; //식수대 - dltnUswtr = element.dltnUswtr //희석용수 - ithlRswtr = element.ithlRswtr //중수도 - ithlEtcUswtr = element.ithlEtcUswtr //기타 - cleanToilUswtr = element.cleanToilUswtr //청소화장실용수 - resn = element.resn //세척살수용수 - - lndwtr = element.lndwtr; //조경용수 - hydUswtr = element.hydUswtr; //친수용수 - ugwtChr = element.ugwtChr; //지하수충전 - farmUswtr = element.farmUswtr //농업용수 - rvrKeepUswtr = element.rvrKeepUswtr //하천등유지용수 - indstUswtr = element.indstUswtr //공업용수 - - inUsageSum = wshwtr + coolUswtr + cleanUswtr + drwtUswtr + dltnUswtr + ithlRswtr + ithlEtcUswtr + cleanToilUswtr + resn; - inUsageArr.push(inUsageSum) - outUsageSum = lndwtr + hydUswtr + ugwtChr + farmUswtr + rvrKeepUswtr + indstUswtr; - outUsageArr.push(outUsageSum) - - const month = Number(element.ym.slice(4, 6)) - data.push({ label: `${month}월`, "장내용수": inUsageSum, "장외용수": outUsageSum }) - - }, - ); - - }) - - setBarData(data); - } - }, [rawData, year]) - - useEffect(() => { - const newChartConfig = barData.reduce((config, element) => { - config[element.label] = { - label: element.label, - }; - return config; - - }, {} as Record<string, { label: string }>) satisfies ChartConfig; - setBarChartConfig(newChartConfig); - }, [barData]); - - //월별 장내 용수 실적 라인차트 - useEffect(() => { - - if (rawData) { - const wshwtrData: lineChartDataProps[] = [] - const coolUswtrData: lineChartDataProps[] = [] - const cleanUswtrData: lineChartDataProps[] = [] - const drwtUswtrData: lineChartDataProps[] = [] - const dltnUswtrData: lineChartDataProps[] = [] - const ithlRswtrData: lineChartDataProps[] = [] - const ithlEtcUswtrData: lineChartDataProps[] = [] - const cleanToilUswtrData: lineChartDataProps[] = [] - const resnData: lineChartDataProps[] = [] - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - const month = Number(element.ym.slice(4, 6)) - wshwtrData.push({ label: `${month}월`, val: element.wshwtr, color: "red" }) - coolUswtrData.push({ label: `${month}월`, val: element.coolUswtr, color: "red" }) - cleanUswtrData.push({ label: `${month}월`, val: element.cleanUswtr, color: "red" }) - drwtUswtrData.push({ label: `${month}월`, val: element.drwtUswtr, color: "red" }) - dltnUswtrData.push({ label: `${month}월`, val: element.dltnUswtr, color: "red" }) - ithlRswtrData.push({ label: `${month}월`, val: element.ithlRswtr, color: "red" }) - ithlEtcUswtrData.push({ label: `${month}월`, val: element.ithlEtcUswtr, color: "red" }) - cleanToilUswtrData.push({ label: `${month}월`, val: element.cleanToilUswtr, color: "red" }) - resnData.push({ label: `${month}월`, val: element.resn, color: "red" }) - - }, - ); - }) - const rtndata = { - chartData1: wshwtrData, - chartData2: coolUswtrData, - chartData3: cleanUswtrData, - chartData4: drwtUswtrData, - chartData5: dltnUswtrData, - chartData6: ithlRswtrData, - chartData7: ithlEtcUswtrData, - chartData8: cleanToilUswtrData, - chartData9: resnData - } - - setInLineData(rtndata) - } - }, [rawData, year]) - - useEffect(() => { - if (inLineData?.chartData1) { - const newChartConfig = { - chartData1: { - label: '세척수', - color: "red", - }, - chartData2: { - label: '냉각수', - color: "orange", - }, - chartData3: { - label: '청소수', - color: "yellow", - }, - chartData4: { - label: '식수대', - color: "pink", - }, - chartData5: { - label: '희석용수', - color: "purple", - }, - chartData6: { - label: '중수도', - color: "green", - }, - chartData7: { - label: '기타', - color: "blue", - }, - chartData8: { - label: '청소화장실용수', - color: "magenta", - }, - chartData9: { - label: '세척살수용수', - color: "skyblue", - }, - } satisfies ChartConfig; - setLnInChartConfig(newChartConfig); - } - }, [inLineData]); - - //월별 장외 용수 실적 라인차트 - useEffect(() => { - if (rawData) { - const lndwtrData: lineChartDataProps[] = [] - const hydUswtrData: lineChartDataProps[] = [] - const ugwtChrData: lineChartDataProps[] = [] - const farmUswtrData: lineChartDataProps[] = [] - const rvrKeepUswtrData: lineChartDataProps[] = [] - const indstUswtrData: lineChartDataProps[] = [] - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - const month = Number(element.ym.slice(4, 6)) - lndwtrData.push({ label: `${month}월`, val: element.lndwtr, color: "red" }) - hydUswtrData.push({ label: `${month}월`, val: element.hydUswtr, color: "red" }) - ugwtChrData.push({ label: `${month}월`, val: element.ugwtChr, color: "red" }) - farmUswtrData.push({ label: `${month}월`, val: element.farmUswtr, color: "red" }) - rvrKeepUswtrData.push({ label: `${month}월`, val: element.rvrKeepUswtr, color: "red" }) - indstUswtrData.push({ label: `${month}월`, val: element.indstUswtr, color: "red" }) - }, - ); - }) - setOutLineData({ - chartData1: lndwtrData, - chartData2: hydUswtrData, - chartData3: ugwtChrData, - chartData4: farmUswtrData, - chartData5: rvrKeepUswtrData, - chartData6: indstUswtrData, - }) - } - }, [rawData, year]) - - useEffect(() => { - if (outLineData?.chartData1) { - const newChartConfig = { - chartData1: { - label: '조경용수', - color: "red", - }, - chartData2: { - label: '친수용수', - color: "orange", - }, - chartData3: { - label: '지하수충전', - color: "yellow", - }, - chartData4: { - label: '농업용수', - color: "green", - }, - chartData5: { - label: '하천등유지용수', - color: "blue", - }, - chartData6: { - label: '공업용수', - color: "purple", - }, - } satisfies ChartConfig; - setLnOutChartConfig(newChartConfig); - } - }, [outLineData]); - - useEffect(() => { - if (!pbnstPrfmncSttn.isInit) { - pbnstPrfmncInit("1", "11"); - } - }, [pbnstPrfmncSttn.isInit, pbnstPrfmncInit]); - - useEffect(() => { - setbdstTable(prfmncRes); - }, [prfmncRes]); - - return ( - <> - <ContentsDiv> - <ListDiv> - <hr /> - <h3 className="mt-4 ml-2 text-2xl font-medium text-label">하수재이용실적 상세현황</h3> - - <SelectBox - className="w-1/12 text-2xl mt-4 ml-2" - label="연도" - selectClass={""} - selectArray={selectYearList} - value={year} - onSelectValue={(val: string | number) => setYear(String(val))} /> - <h1 className="mt-4 ml-2">장내·외 용도별 하수재이용실적 현황(계)</h1> - - <div className="flex"> - <div className="w-1/3"> - <MainChart chartConfig={chartConfig} chartData={chartData} chartTitle={"장내·외 용수 총 실적"} chartForm={CHART_FORM.DN} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={dnInChartConfig} chartData={dnInUsage} chartTitle={"장내용수 실적"} chartForm={CHART_FORM.DN} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={dnOutChartConfig} chartData={dnOutUsage} chartTitle={"장외용수 실적"} chartForm={CHART_FORM.DN} /> - </div> - </div> - <h1 className="">장내·외 월별 하수재이용실적 현황</h1> - <div className="flex"> - <div className="w-1/3"> - <MainChart chartConfig={barChartConfig} chartData={barData} chartTitle={"월별 장내·외 용수 총 실적"} chartForm={CHART_FORM.DOUBLEBAR} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={lnInChartConfig} chartData={inLineData} chartTitle={"월별 장내 용수 실적"} chartForm={CHART_FORM.LINE} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={lnOutChartConfig} chartData={outLineData} chartTitle={"월별 장외 용수 총 실적"} chartForm={CHART_FORM.LINE} /> - </div> - </div> - {/* 하수재이용실적 현황 - 조건부 렌더링 */} - {isVisible && ( - <> - <h1 className="">하수재이용실적 현황</h1> - <ListDiv className="col-span-8 pr-6 "> - <ScrollArea className="h-[60vh]"> - <div className="card-header"> - <h3 className="text-2xl font-medium text-label"> - {"하수처리수재이용 실적(m3) 등록결과"} - </h3> - </div> - - <UiTable - headName={undefined} - tableData={prfData || []} - headlist={monthHeadList} - pageSize={0} - total={0} - cellClick={undefined} - onPageChange={function (page: number): void { - throw new Error("Function not implemented."); - }}> - </UiTable> - </ScrollArea> - </ListDiv> - </> - )} - </ListDiv> - </ContentsDiv> - <Toaster position="top-center" /> - </> - ) -} From 95b77d68f660cce86ec21c9b5be1a75f3ca5426c Mon Sep 17 00:00:00 2001 From: swcho <swcho@mind-one.co.kr> Date: Mon, 14 Jul 2025 13:18:09 +0900 Subject: [PATCH 104/159] =?UTF-8?q?feat:=20pbnstPrfmncSttn.tsx=20=EB=B9=8C?= =?UTF-8?q?=EB=93=9C=20=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/featureClickEventPopup.tsx | 1 - apps/wr/app/map/pbnstPrfmncSttnPopup.tsx | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/wr/app/map/featureClickEventPopup.tsx b/apps/wr/app/map/featureClickEventPopup.tsx index 8048d0997..41a2c8924 100644 --- a/apps/wr/app/map/featureClickEventPopup.tsx +++ b/apps/wr/app/map/featureClickEventPopup.tsx @@ -17,7 +17,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, const [tableData, setTableData] = useState<any>(null); // 피처 데이터 const [mntrngsData, setMntrngsData] = useState(false); // 수량/수질 측정 정보 const [headlist, setHeadlist] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태 - const [headlist2, setHeadlist2] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태 const [buttonChk, setButtonChk] = useState(true) const [fetchData, setfetchData] = useState<any>(); // api 호출여부 const contentRef = useRef<HTMLDivElement>(null); diff --git a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx b/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx index 46fa9ba59..79e1bf009 100644 --- a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx +++ b/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx @@ -298,8 +298,6 @@ export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSt let indstUswtr = 0; let inUsageSum = 0; let outUsageSum = 0; - const inUsageArr = []; - const outUsageArr = []; if (rawData) { @@ -326,9 +324,7 @@ export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSt indstUswtr = element.indstUswtr //공업용수 inUsageSum = wshwtr + coolUswtr + cleanUswtr + drwtUswtr + dltnUswtr + ithlRswtr + ithlEtcUswtr + cleanToilUswtr + resn; - inUsageArr.push(inUsageSum) outUsageSum = lndwtr + hydUswtr + ugwtChr + farmUswtr + rvrKeepUswtr + indstUswtr; - outUsageArr.push(outUsageSum) const month = Number(element.ym.slice(4, 6)) data.push({ label: `${month}월`, "장내용수": inUsageSum, "장외용수": outUsageSum }) @@ -570,8 +566,8 @@ export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSt pageSize={0} total={0} cellClick={undefined} - onPageChange={function (page: number): void { - throw new Error("Function not implemented.", page); + onPageChange={function (): void { + throw new Error("Function not implemented."); }}> </UiTable> </ScrollArea> From bde20e9a7013b1cd4ef19a58152c49f999c57ac5 Mon Sep 17 00:00:00 2001 From: truthwing <truthplumage@gmail.com> Date: Mon, 14 Jul 2025 13:52:13 +0900 Subject: [PATCH 105/159] =?UTF-8?q?state=20=EC=B2=98=EB=A6=AC=20=ED=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 255 +++++++++++++---------------- 1 file changed, 112 insertions(+), 143 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index e8641ca6c..6da584f8e 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -1,19 +1,18 @@ -import { useWrStore } from "@/app/store"; -import type { customPbnst, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload, tableData } from "@/components/lib/func/commom"; -import { Title, UiTable, UITab, ContentsDiv, ScrollArea } from '@common/business_components'; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import React, { useCallback, useState, useEffect } from 'react'; import NewWindowPortal from '@/app/map/newWindowPortal'; -import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; -import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; -import type { chgBuilding, customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; +import { useWrStore } from "@/app/store"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; +import type { customPbnst, 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 type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; import { fetchType, getFetch, postFectch } from "@/components/lib/api"; -import { useGisContext } from "@common/business_components/ui/map/Gis"; +import { tableData } from "@/components/lib/func/commom"; +import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; -import { set } from "react-hook-form"; +import { Title, UITab, UiTable } from '@common/business_components'; +import { useGisContext } from "@common/business_components/ui/map/Gis"; +import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; +import React, { useCallback, useEffect, useState } from 'react'; interface NewWindowPopupProps { featureData: any; @@ -25,27 +24,8 @@ interface NewWindowPopupProps { onClose: () => void; } -// 탭 -const TABS = [ - { val: "0", text: "재이용시설1" }, - { val: "1", text: "재이용시설2" }, - { val: "2", text: "재이용시설n" }, -]; - -// 데이터의 속성(key)을 사용자에게 보여줄 한글 이름으로 변환하기 위한 맵 -// 실제 데이터에 맞게 이 부분을 확장해야 합니다. -const propertyNameMap: { [key: string]: string } = { - fid: '고유 ID', - fcltNm: '시설명', - opertDe: '운영일자', - addr: '주소', - // ... 필요한 만큼 속성 매핑 추가 -}; - const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ featureData, - checkedLayers = [], - checkedLayersData = [], seletectedLayerNm, onFeatureSelect, onClose @@ -77,12 +57,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( (state) => state ); - let { rainSttnRes, rainSttnResCount } = rainSttn; + const { rainSttnRes, rainSttnResCount } = rainSttn; const [rainTable, setRainTable] = useState<customRainBdst[]>(); - const [rainBdstChgProps, setRainBdstChgProps] = useState<{ - isOpen: boolean; - chBuilding: chgBuilding[]; - }>({ isOpen: false, chBuilding: [] }); const [rainPage, setRainPage] = useState(1) const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }); @@ -90,18 +66,14 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ const { rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore( (state) => state ); - let { rswtSttnRes, rswtSttnResCount } = rswtSttn; + const { rswtSttnRes, rswtSttnResCount } = rswtSttn; const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>(); const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false }); - const [rswtrBdstChgProps, setRswtrBdstChgProps] = useState<{ - isOpen: boolean; - chBuilding: chgBuilding[]; - }>({ isOpen: false, chBuilding: [] }); const [rswtrPage, setRswtrPage] = useState(1); // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); - let { htdflSttnRes,htdflSttnResCount } = htdflSttn; + const { htdflSttnRes,htdflSttnResCount } = htdflSttn; const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [htdflPage, setHtdflPage] = useState(1) @@ -111,19 +83,19 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnst, pubHasuInit, } = useWrStore((state) => state); - let { pubFacHeadList, pbnstHasuRes } = pbnst; + const { pubFacHeadList, pbnstHasuRes } = pbnst; + const [hasuList, setHasuList] = useState<pubHasuType[]>(pbnstHasuRes || []); const [isRuseReg, setIsRuseReg] = useState<{ data: any | undefined; }>({ data: undefined }); const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); const [hasuPage, setHasuPage] = useState<number>(1); - const [hasuRes,setHasuRes] = useState<number>() if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// const getSelectedLayers = () => { let result = null; const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 - let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 + let featureLayer: { get: (key: string) => any } = {get:()=> null}; layers.forEach((layer: any) => { const source = layer.getSource(); if (source && source.hasFeature && featureData @@ -135,8 +107,55 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ return result; }; - useEffect(() => { - const layerId = getSelectedLayers(); + const fetchpbnstDetail = async (featureCd: string) => { + try { + const response = await getFetch("wr", `/reuseFc/pubFc/${featureCd}`); + // 중복 데이터 추가 방지 + setTabDataFunc(response, featureCd); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + const fetchHasuDetail = async (featureCd: string, data: string) => { + try { + const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON); + //TODO : state 처리. + setHasuList( + rainRes.data.map((item: any) => { + return { + ...item, + fctCpc: Number(item.fctCpc) || 0, + ruse: item.ruse === false ? "N" : "Y", + }; + }); + ) + pbnstHasuRes = hasuList + if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] }); + + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const detainSttn = async (featureCd: string, layerNm: string) => { + if (layerNm == '빗물이용시설') { + const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`) + rainSttnRes = res + setRainDetailModal({ isOpen: true, data: rainSttnRes[0] }); + } + else if(layerNm == '중수도시설'){ + const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`) + rswtSttnRes = res + console.log('중수도', res, featureCd) + setRswtrDetailModal({isOpen:true,data:rswtSttnRes[0]}) + } + else{ + const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`) + htdflSttnRes = res + setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); + } + } + const layerId = getSelectedLayers(); if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null; @@ -160,7 +179,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setViewMode("detail") } } else if (layerId === null && seletectedLayerNm) { setViewMode("list") } - }, [featureData]); ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// @@ -182,7 +200,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ if (!pbnstSttn.isInit) { getFlcts() } - }, [seletectedLayerNm, pbnstSttn.isInit]); + }, [seletectedLayerNm, pbnstSttn.isInit, getFlcts]); useEffect(()=>{ pbnSttnInit("1", "15", { partValue: "A", @@ -210,15 +228,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }); } // 재이용시설 조회 - const fetchpbnstDetail = async (featureCd: string) => { - try { - const response = await getFetch("wr", `/reuseFc/pubFc/${featureCd}`); - // 중복 데이터 추가 방지 - setTabDataFunc(response, featureCd); - } catch (error) { - console.error("Error fetching data:", error); - } - }; // 재이용시설 페이징처리 관련 함수 const onPageChangeHandler = useCallback((page: number) => { pbnstSttnSearch( @@ -240,18 +249,18 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ String(new Date().getFullYear()),fclts ); }, []); - const excelClick = useCallback(() => { - // if (codeData) pbnstSttnSearch(1, "10000", codeData); - excelDownload( - [[]], - "하수재이용시설 현황", - "sample_pbnstSttn.xlsx", - "A1:U2" - ); - }, [pbnstSttnSearch]); +// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제. + // const excelClick = useCallback(() => { + // // if (codeData) pbnstSttnSearch(1, "10000", codeData); + // excelDownload( + // [[]], + // "하수재이용시설 현황", + // "sample_pbnstSttn.xlsx", + // "A1:U2" + // ); + // }, [pbnstSttnSearch]); ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// - ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// // 빗물재이용시설 cellClick 이벤트 (상세정보) const rainCellClick = (index: number | undefined, headId: string) => { @@ -263,29 +272,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // setViewMode('detail') onFeatureSelect(rainTable[index]); onClose(); - } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { - if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) - setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); - } - } - const detainSttn = async (featureCd: string, layerNm: string) => { - if (layerNm == '빗물이용시설') { - const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`) - rainSttnRes = res - setRainDetailModal({ isOpen: true, data: rainSttnRes[0] }); - } - else if(layerNm == '중수도시설'){ - const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`) - rswtSttnRes = res - console.log('중수도', res, featureCd) - setRswtrDetailModal({isOpen:true,data:rswtSttnRes[0]}) - } - else{ - const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`) - htdflSttnRes = res - setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); } } + useEffect(() => { if (!rainSttn.isInit) { @@ -337,10 +326,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // setViewMode('detail') onFeatureSelect(rswtrTable[index]); onClose(); - } else if (headId === 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { - if (rswtrTable[index] && rswtrTable[index]?.chBuildingYn === 'Y') { - setRswtrBdstChgProps({ isOpen: true, chBuilding: rswtrTable[index].chgBuilding }); - } } } useEffect(() => { @@ -369,18 +354,18 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ ); setRswtrTable(chData); }, [code, rswtSttnRes]); - // 엑셀 관련 - const rswtSttnExcelDownload = useCallback(() => { - if (rswtSttn.excelList.length > 0) { - if (rswtSttn.excelList.length === 0) return; - excelDownload( - rswtSttn.excelList, - "중수도시설 현황", - "sample_rswtSttn.xlsx", - "A1:W3", - ); - } - }, [rswtSttn.excelList]) + // 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(() => { rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd); @@ -433,24 +418,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ useEffect(() => { pubHasuInit(String(hasuPage), "0"); }, [hasuPage]); - const fetchHasuDetail = async (featureCd: string, data: string) => { - try { - const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON); - const hasuList = rainRes.data.map((item: any) => { - return { - ...item, - fctCpc: Number(item.fctCpc) || 0, - ruse: item.ruse === false ? "N" : "Y", - }; - }); - pbnstHasuRes = hasuList - if (pbnstHasuRes.length > 0) setIsRuseReg({ data: [pbnstHasuRes[0]] }); - - } catch (error) { - console.error("Error fetching data:", error); - } - }; - const hasuCellClick = (index: number | undefined, headId: string) => { + + const hasuCellClick = (index: number | undefined) => { if (index !== undefined && pbnstHasuRes !== undefined) { onFeatureSelect(pbnstHasuRes[index]); onClose(); @@ -466,15 +435,15 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ layerId = seletectedLayerNm || ''; } //하수처리시설 - let isPrcsFclt = layerId == '하수처리시설' + const isPrcsFclt = layerId == '하수처리시설' // 재이용시설 - let isPbnst = layerId == '하수재이용시설'; + const isPbnst = layerId == '하수재이용시설'; // 빗물이용시설 - let isRain = layerId == '빗물이용시설'; + const isRain = layerId == '빗물이용시설'; // 중수도시설 - let isRswt = layerId == '중수도시설'; + const isRswt = layerId == '중수도시설'; // 온배수시설 - let isHtdfl = layerId == '온배수시설'; + const isHtdfl = layerId == '온배수시설'; if (isPrcsFclt) { if (viewMode == 'list') { return ( @@ -491,7 +460,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ headName={""} cellClick={hasuCellClick} onPageChange={setHasuPage} - children={undefined} /> </> ) @@ -506,21 +474,19 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ tableData={isRuseReg?.data || []} headlist={pubFacHeadList.slice(0, 4)} pageSize={1} - total={null} + total={0} headName={"위치정보"} cellClick={() => { }} onPageChange={() => { }} - children={undefined} /> <UiTable tableData={isRuseReg?.data || []} headlist={pubFacHeadList.slice(4)} pageSize={1} - total={null} + total={0} headName={"기본정보"} cellClick={() => { }} onPageChange={() => { }} - children={undefined} /> </> ) @@ -542,7 +508,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ label: tab.name, onClick: () => setActiveTab(tab.id), }))} - children={undefined} /> </div> <PbnstSttnModal @@ -566,15 +531,16 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <UiTable headName={[]} tableData={bdstTable || []} - children={<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />} headlist={pbnstSttn.pbnstSttHeadList} pageSize={20} total={pbnstSttnResCount || 0} - cellClick={(index: number | undefined, headId: string) => { + cellClick={(index: number | undefined) => { pbnstCellClick(index); }} onPageChange={onPageChangeHandler} - /> + > + <HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} /> + </UiTable> </> ); } @@ -601,7 +567,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <UiTable headName={[]} tableData={rainTable || []} - children={<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />} headlist={rainSttn.rainSttHeadList} pageSize={20} total={rainSttnResCount} @@ -609,7 +574,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ rainCellClick(index ?? undefined, headId); }} onPageChange={setRainPage} - /> + > + <HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} /> + </UiTable> </> ); } @@ -636,7 +603,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <UiTable headName={[]} tableData={rswtrTable || []} - children={<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />} headlist={rswtSttn.rswtSttHeadList} pageSize={20} total={rswtSttnResCount} @@ -644,7 +610,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ rswtCellClick(index, headId); }} onPageChange={setRswtrPage} - /> + > + <HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} /> + </UiTable> </> ); } @@ -671,7 +639,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ <UiTable headName={[]} tableData={htdflTable || []} - children={<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />} headlist={htdflSttn.htdflSttHeadList} pageSize={20} total={htdflSttnResCount || 0} @@ -679,7 +646,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ htdflCellClick(index ?? undefined, headId); }} onPageChange={setHtdflPage} - /> + > + <HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} /> + </UiTable> </> ); } From af92a70f136b5f250f5c83155dd379672f7c341f Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 14 Jul 2025 13:55:10 +0900 Subject: [PATCH 106/159] =?UTF-8?q?=EB=B9=8C=EB=93=9C=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/form/coMat/conCostForm/conCostForm.tsx | 41 +- .../ui/form/fcltReg/bdstReg/bdstAdd.tsx | 2 +- .../ui/form/fcltReg/bdstReg/bdstReg.tsx | 41 +- .../ui/form/fcltReg/htdflReg/htdflRegForm.tsx | 2 +- .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 384 +++++++++--------- .../fcltReg/pbnstReg/mngReg/mngRegForm.tsx | 13 +- .../ui/form/fcltReg/rainReg/rainRegForm.tsx | 15 +- .../ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx | 2 +- .../ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx | 33 +- .../pbnPrfExcelModal/pbnPrfExcelModal.tsx | 64 +-- .../ui/modal/coMat/constCostFeeTable.tsx | 12 +- .../ui/modal/coMat/drgtDetailModal.tsx | 22 +- .../ui/modal/coMat/rateFeeModal.tsx | 15 +- .../coReg/coRegExcel/coRegExcelModal.tsx | 132 +++--- .../fcltReg/bdstChgModal/bdstChgModal.tsx | 5 +- .../fcltReg/bdstRegModal/bdstRegModal.tsx | 26 +- .../fcOrgwtsRegModal/fcOrgwtsRegModal.tsx | 4 +- .../fcltReg/pbnstRegModal/pbnstRegModal.tsx | 84 +--- 18 files changed, 383 insertions(+), 514 deletions(-) diff --git a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx index ee06893c9..a77e6f51f 100644 --- a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx +++ b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx @@ -18,7 +18,6 @@ import { Form, FormField, FormUi, - UiModal, UiTable, } from "@common/business_components/ui"; import PopoverUi from "@common/business_components/ui/popover_ui"; @@ -65,30 +64,6 @@ export default function ConCostForm({ }, [selectionVersion]); - const confrirmToast = () => { - - if (checkFinish) { - toast((t) => ( - <span className="flex flex-col items-center"> - 검토완료 변경시 공사비는 변경할수 없습니다. - <br /> - 진행하시겠습니까? - <Button - onClick={() => { - toast.dismiss(t.id); - - - }} - > - 확인 - </Button> - <Button onClick={() => toast.dismiss(t.id)}>취소</Button> - </span> - )); - } else { - - } - }; const zipDowonLoad = () => { fetch(`/2024_constarctFeeProgram.zip`, {}).then(async (response) => { @@ -105,7 +80,6 @@ export default function ConCostForm({ const dmndQtyWatch = form.watch("dmndQty"); const totalConstCost = form.watch("totalConstCost"); const cstrnCst = form.watch("demandCst.cstrnCst"); - const useUsgCdWatch = form.watch("useUsgCd"); const calculateConstCost = useCallback(() => { const usgPrcsProcs = usgPrcsProcsWatch; @@ -372,6 +346,7 @@ export default function ConCostForm({ type="number" step="0.001" onChange={(e) => { + console.log('dmndQty ', e) //field.onChange(Number(e.target.value) * 365 ); }} value={Number(field.value) * 365 || 0} @@ -398,9 +373,7 @@ export default function ConCostForm({ } childrenBody={ <> - <ConstCostFeeTable - setReturnData={(e) => {}} - ></ConstCostFeeTable> + <ConstCostFeeTable/> </> } bodyClassName={"w-[40vw] h-full"} @@ -437,9 +410,8 @@ export default function ConCostForm({ } childrenBody={ <> - <RateFeeTableModal - setReturnData={(e) => {}} - ></RateFeeTableModal> + <RateFeeTableModal/> + </> } bodyClassName={"w-[22vw]"} @@ -499,7 +471,10 @@ export default function ConCostForm({ className="mt-2" type="number" step="0.01" - onChange={(e) => {}} + onChange={(e) => { + console.log('totalConstCost ', e) + + }} value={field.value ?? 0} readOnly /> diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx index f7b24e628..bafa7566d 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstAdd.tsx @@ -6,7 +6,7 @@ import { formH1Class } from "@/components/lib/class/comClass"; import { safeDate } from "@/components/lib/func/commom"; import { DatePicker, FormField, FormUi, SelectBox } from "@common/business_components"; import { Button, Checkbox, Input } from "@common/components"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useFieldArray } from "react-hook-form"; export default function BdstAdd({ form, readonly }: { form: any; readonly?: boolean; }) { diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx index c14bd7d48..726f4e689 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/bdstReg.tsx @@ -1,13 +1,6 @@ import { useWrStore } from "@/app/store"; import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { formH1Class } from "@/components/lib/class/comClass"; -import { - formatCommaNumber, - getCity, - handleCommaNumberChange, - safeDate, -} from "@/components/lib/func/commom"; -import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { FormField, FormUi, @@ -15,9 +8,8 @@ import { SelectBox, type SelectDataType, } from "@common/business_components"; -import { Button, Checkbox, Input } from "@common/components"; +import { Input } from "@common/components"; import { useEffect, useState } from "react"; -import { useFieldArray } from "react-hook-form"; export default function BdstReg({ form, type }: { form: any; type?: string }) { const { code } = useWrStore((state) => { @@ -28,11 +20,11 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { const [useCityCd, setUserCityCd] = useState<SelectDataType[]>([]) const [useSggCd, setUserSggCd] = useState<SelectDataType[]>([]) - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | undefined>(); - const [objSearch, setObjSearch] = useState<objSearchType>({ - sgg: "", - city: "", - }); + // const [selectSgg, setSelectSgg] = useState<SelectDataType[] | undefined>(); + // const [objSearch, setObjSearch] = useState<objSearchType>({ + // sgg: "", + // city: "", + // }); useEffect(() =>{ if(userSiSggCd.length===2 && code.cityCd.length>0){ @@ -58,24 +50,13 @@ export default function BdstReg({ form, type }: { form: any; type?: string }) { } },[form, userSiSggCd, code.cityCd, code.sggCd]) - const getSelCity = (val: string) => { - const data = getCity(val, code.sggCd); - setSelectSgg(data); - const sgg = form.getValues("sggCd"); - setObjSearch({ city: val, sgg: "" }); - }; - const getSgg = (val: string | number) => { - const sgg = form.getValues("sggCd"); - setObjSearch({ ...objSearch, sgg: val != "" ? String(val) : sgg }); - }; - - useEffect(() => { - const city = form.getValues("ctpvCd"); - const sgg = form.getValues("sggCd"); - setObjSearch({ city: city, sgg: sgg }); - }, [selectSgg]); + // useEffect(() => { + // const city = form.getValues("ctpvCd"); + // const sgg = form.getValues("sggCd"); + // setObjSearch({ city: city, sgg: sgg }); + // }, [selectSgg]); useEffect(() => { const subscription = form.form?.watch((value: any) => { diff --git a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx index 85bb67044..c37ee2c48 100644 --- a/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/htdflReg/htdflRegForm.tsx @@ -199,7 +199,7 @@ export default function HtdflRegForm({ selectArray={code.htdPowerMthdCd} onSelectValue={readonly ? () => { } : field.onChange} // value={field.value ?? ""} - value={field.value || code.htdPowerMthdCd[0].val} + value={field.value || (code?.htdPowerMthdCd[0] &&code?.htdPowerMthdCd[0].val)} readOnly={readonly || !isPowerPlant} /> </FormUi> diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 3fdccec53..4a00f525d 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -22,13 +22,12 @@ import { formTableName, } from "@/components/lib/class/comClass"; import FcOrgwtsRegModal from "@/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal"; -import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable"; import { SelectBox } from "@common/business_components"; import { DatePicker, FormUi, UiModal } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; -import { Button, DataTable, Input, Label } from "@common/components"; +import { Button, Input, Label } from "@common/components"; import { useEffect, useRef, useState } from "react"; -import { useFieldArray, useForm, type UseFormReturn } from "react-hook-form"; +import { useFieldArray, type UseFormReturn } from "react-hook-form"; import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail"; import { formatCommaNumber, @@ -54,7 +53,6 @@ export function PbnstBuseForm({ indexBiz: number; setIndexBiz: (index: number) => void; }) { - const ref = useRef<ppInstlType[] | null>(null); const { code, pbnst, @@ -68,10 +66,10 @@ export function PbnstBuseForm({ control: form.control, name: `items.${indexMng}.fcBizs`, }); - const [ppiSelectList, setPpiSelectList] = - useState<[{ name: string; val: SelectDataType[] }]>(); + const [ppiSelectList, setPpiSelectList] = useState< + { name: string; val: SelectDataType[] }[] | undefined + >(); const [ppiYn, setPpiYn] = useState("Y"); - const [selectBizCycle, setSelectBizCycle] = useState< { text: string; @@ -125,7 +123,6 @@ export function PbnstBuseForm({ useEffect(() => { if (fcOrgwtsNmList && fcOrgwtsNmList.length > 0) { - fcOrgwts?.forEach((item, index) => { const orgwtNm = fcOrgwtsNmList.find( (orgwt) => orgwt.bscFctCd === item.swtrmtFcltFk @@ -175,11 +172,7 @@ export function PbnstBuseForm({ appendBiz(newItem); setIndexBiz(pbnstBizCycle); // 새로 추가된 차수로 포커스 이동 } - const { - fields: fcDemands, - append: appendDemand, - remove: removeDemand, - } = useFieldArray({ + const { fields: fcDemands, append: appendDemand } = useFieldArray({ control: form.control, name: `items.${indexMng}.fcBizs.${indexBiz}.fcDemands`, }); @@ -201,16 +194,7 @@ export function PbnstBuseForm({ prevDemandsLengthRef.current = fcDemands.length; }, [fcDemands.length]); - - const { fields: fcOrgwtFiled } = useFieldArray({ - control: form.control, - name: `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, - }); - const { - fields: pplInstls, - append: appendPpl, - remove: removePpl, - } = useFieldArray({ + const { append: appendPpl, remove: removePpl } = useFieldArray({ control: form.control, name: `items.${indexMng}.fcBizs.${indexBiz}.pplInstls`, }); @@ -286,7 +270,7 @@ export function PbnstBuseForm({ if (code.pplLenght) { ppl.push({ name: "pplQulity", val: code.pplQulity }); } - if (ppl.length > 0) { + if (ppl && ppl.length > 0) { setPpiSelectList(ppl); } else { setPpiSelectList(undefined); @@ -297,7 +281,7 @@ export function PbnstBuseForm({ console.log("form errors:", form.formState.errors); }, [form.formState.errors]); - useEffect(() => { + useEffect(() => { const pplSum = form.watch(`items.${indexMng}.fcBizs.${indexBiz}.pplInstls`); if (!pplSum) return; let sum = 0; @@ -307,10 +291,9 @@ export function PbnstBuseForm({ setSumCpct(sum); }, [form.formState, indexMng, indexBiz]); -useEffect(() =>{ - - console.log('form.formState ', form.formState) -}, [form.formState]); + useEffect(() => { + console.log("form.formState ", form.formState); + }, [form.formState]); const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`); @@ -418,10 +401,11 @@ useEffect(() =>{ </div> <RuseMngTableForm key={`fcOrgwts-${indexMng}-${indexBiz}`} // 이게 핵심! - tableData={ - form.getValues( `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`)||[] - // fcOrgwtWatch||[] + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts` + ) || [] + // fcOrgwtWatch||[] } form={form} headList={pbnst.pbnstOrgwtHeadList} @@ -445,7 +429,7 @@ useEffect(() =>{ <Label className="text-right">합계</Label> <Input type="text" - value={ formatCommaNumber(sumCpct)} + value={formatCommaNumber(sumCpct)} readOnly={true} className="w-32 border-gray-300 rounded pr-8 " /> @@ -479,7 +463,7 @@ useEffect(() =>{ form.getValues( `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` ) ?? [] - // pplInstlsWatch||[] + // pplInstlsWatch||[] } headList={pbnst.pplInstlsHeadLisat} code={ppiSelectList ?? []} @@ -532,173 +516,173 @@ useEffect(() =>{ </div> <div ref={demandsContainerRef}> {fcDemands.map((field, index) => ( - <div + <div key={field.id} // useFieldArray의 고유 id를 key로 사용 className="grid grid-cols-12 gap-4 mt-3 border-b border-gray-400 pb-3" - > - <div key={index + "keySon1"} className="col-span-4"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdCoNm`} - render={({ field: f }) => ( - <FormUi label="수요처명"> - <SearchInputText - label={"수요처"} - initValue={f.value} - setValue={(val) => { - f.onChange(val); - if (val && val.length > 2) { - getDemandCompList(val, 3); + > + <div key={index + "keySon1"} className="col-span-4"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdCoNm`} + render={({ field: f }) => ( + <FormUi label="수요처명"> + <SearchInputText + label={"수요처"} + initValue={f.value} + setValue={(val) => { + f.onChange(val); + if (val && val.length > 2) { + getDemandCompList(val, 3); + } + }} + setRtnData={(valList: any) => { + if (valList) { + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`, + valList.daddr + ); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`, + valList.useUsgCd + ); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`, + valList.splyCpct + ); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoPk`, + valList.dmdInfoPk?.toString() + ); + } + }} + searchList={demandCompList?.map((item) => { + return { + ...item, + searchNm: item.dmdCoNm, + searchPk: item.dmdInfoPk, + }; + })} + ></SearchInputText> + </FormUi> + )} + /> + </div> + <div key={index + "keySon2"} className="col-span-4"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`} + render={({ field: f }) => ( + <FormUi label="위치(주소)"> + <Input + placeholder="-" + type="text" + readOnly + onChange={(e) => f.onChange(e.target.value)} + value={f.value} + className={selectClass} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon3"} className="col-span-4"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`} + render={({ field: f }) => ( + <FormUi label="사용용도"> + <SelectBox + label={""} + selectClass={""} + className="w-full" + selectArray={code.dmdUszCd} + onSelectValue={f.onChange} + value={f.value ?? code.dmdUszCd[0]?.val} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon4"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyBgngDay`} + render={({ field: f }) => ( + <FormUi label="공급시작일"> + <DatePicker + mode={"single"} + field={{ + value: safeDate(f.value) || new Date(), + onChange: (date: Date | undefined) => + f.onChange(date), + }} + selectClass={"rounded-lg !w-full"} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon5"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyEndDay`} + render={({ field: f }) => ( + <FormUi label="공급종료일"> + <DatePicker + mode={"single"} + onSelect={(date: Date | undefined) => + f.onChange(date) } - }} - setRtnData={(valList: any) => { - if (valList) { - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`, - valList.daddr - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`, - valList.useUsgCd - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`, - valList.splyCpct - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoPk`, - valList.dmdInfoPk?.toString() - ); + field={{ + value: safeDate(f.value) || new Date(), + onChange: (date: Date | undefined) => + f.onChange(date), + }} + selectClass={"rounded-lg !w-full"} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon6"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`} + render={({ field: f }) => ( + <FormUi label="(계약)공급량(m³/일)"> + <Input + placeholder="" + type="text" + onChange={(e) => { + handleCommaNumberChange(e, f.onChange); + }} + value={formatCommaNumber(f.value)} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon7"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyFmYn`} + render={({ field: f }) => ( + <FormUi label="공급 유량계 유무"> + <SelectBox + label={""} + selectClass={""} + className="w-full" + selectArray={code.yn} + onSelectValue={(val: string | number) => + f.onChange(val) } - }} - searchList={demandCompList?.map((item) => { - return { - ...item, - searchNm: item.dmdCoNm, - searchPk: item.dmdInfoPk, - }; - })} - ></SearchInputText> - </FormUi> - )} - /> + value={f.value ?? code.yn[0]?.val} + /> + </FormUi> + )} + /> + </div> </div> - <div key={index + "keySon2"} className="col-span-4"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`} - render={({ field: f }) => ( - <FormUi label="위치(주소)"> - <Input - placeholder="-" - type="text" - readOnly - onChange={(e) => f.onChange(e.target.value)} - value={f.value} - className={selectClass} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon3"} className="col-span-4"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`} - render={({ field: f }) => ( - <FormUi label="사용용도"> - <SelectBox - label={""} - selectClass={""} - className="w-full" - selectArray={code.dmdUszCd} - onSelectValue={f.onChange} - value={f.value ?? code.dmdUszCd[0]?.val} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon4"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyBgngDay`} - render={({ field: f }) => ( - <FormUi label="공급시작일"> - <DatePicker - mode={"single"} - field={{ - value: safeDate(f.value) || new Date(), - onChange: (date: Date | undefined) => - f.onChange(date), - }} - selectClass={"rounded-lg !w-full"} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon5"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyEndDay`} - render={({ field: f }) => ( - <FormUi label="공급종료일"> - <DatePicker - mode={"single"} - onSelect={(date: Date | undefined) => - f.onChange(date) - } - field={{ - value: safeDate(f.value) || new Date(), - onChange: (date: Date | undefined) => - f.onChange(date), - }} - selectClass={"rounded-lg !w-full"} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon6"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`} - render={({ field: f }) => ( - <FormUi label="(계약)공급량(m³/일)"> - <Input - placeholder="" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, f.onChange); - }} - value={formatCommaNumber(f.value)} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon7"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyFmYn`} - render={({ field: f }) => ( - <FormUi label="공급 유량계 유무"> - <SelectBox - label={""} - selectClass={""} - className="w-full" - selectArray={code.yn} - onSelectValue={(val: string | number) => - f.onChange(val) - } - value={f.value ?? code.yn[0]?.val} - /> - </FormUi> - )} - /> - </div> - </div> ))} </div> </div> @@ -712,9 +696,11 @@ useEffect(() =>{ bodyClass={"w-[70vw] max-w-none max-h-[90vh] overflow-y-auto"} body={ <FcOrgwtsRegModal - initTableData={form.getValues( - `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts` - ) ?? []} + initTableData={ + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts` + ) ?? [] + } closeModal={() => { setIsFcOrgwts(false); }} diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index d132d2bc1..946a58eb8 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -18,7 +18,6 @@ import { } from "@/components/lib/class/comClass"; import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr"; import { - type customPbnst, type fcFileType, type PbnstRegArrrayType, type selectLabel, @@ -44,23 +43,17 @@ export function PbnstMngForm({ }: { form: UseFormReturn<{ items: PbnstRegArrrayType }>; formType: string; - firstFcltData?: customPbnst; indexMng: number; setIndexMng: (index: number) => void; }) { const { code, pbnst, fileDelete, fileDownLoad } = useWrStore( (state) => state ); - const { pbnstRes } = pbnst; const fileInitRef = useRef<{ index: number; key: string } | null>(null); const [regFileList, setRegFileList] = useState<fcFileType[] | null>(null); const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null); const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null); const [fcltNm, setFcltNm] = useState<selectLabel[] | null>(null); - const [opersKey, setOpersKey] = useState(0); - useEffect(() => { - setOpersKey((prev) => prev + 1); - }, [indexMng]); const [mngMtdCode, setMngMtdCode] = useState<{ name: string; val: SelectDataType[] }[]>(); @@ -125,6 +118,7 @@ export function PbnstMngForm({ atflCd: tusFile.atflCd.toString(), file: item, }); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions type === "relation" ? setRelationFiles(setReFiles) : setPlanFiles(setReFiles); @@ -151,6 +145,7 @@ export function PbnstMngForm({ } }); } + // eslint-disable-next-line @typescript-eslint/no-unused-expressions type === "relation" ? setRelationFiles(setReFiles) : setPlanFiles(setReFiles); @@ -517,7 +512,3 @@ export function PbnstMngForm({ </div> ); } -function trigger(arg0: string) { - throw new Error("Function not implemented."); -} - diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index a454f69c8..58552e7ae 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -14,7 +14,7 @@ import { } from "@/components/lib/func/commom"; import { DatePicker, FormUi } from "@common/business_components"; import { Form, FormField, SelectBox } from "@common/business_components/ui"; -import { Button, Checkbox, Input, Label, ScrollArea } from "@common/components/ui"; +import { Button, Input, ScrollArea } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; @@ -35,16 +35,14 @@ export default function RainRegForm({ setIsModal?: (modal: boolean) => void; readonly?: boolean; }) { - const { code, rainBdstReg, rainBdstUpdate, rain } = useWrStore( + const { code, rainBdstReg, rainBdstUpdate } = useWrStore( (state) => state ); const { rainFcltCd } = code; - const defaultValues: z.infer<typeof rainZod> = rainZod.parse({}); const form = useForm<z.infer<typeof rainZod>>({ resolver: zodResolver(rainZod), // defaultValues: defaultValues, }); - const instlCst = form.watch(`reuseBuilding.0.instlCst`); const { t } = useTranslation('base'); const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn] = form.watch([ @@ -123,11 +121,6 @@ export default function RainRegForm({ const [regCtpvCd, regSggcd] = form.watch(["ctpvCd", "sggCd"]); - // form 값이 변경될 때마다 로그 출력 - useEffect(() => { - const subscription = form.watch((value) => { }); - return () => subscription.unsubscribe(); - }, [form]); useEffect(() => { console.log("form errors:", form.formState.errors); @@ -411,8 +404,8 @@ export default function RainRegForm({ control={form.control} name="reuseBuilding.0.rainyObj.filtrTrtmfctPrs" render={({ field }) => { - const value = field.value; - const isUnknown = value === null || value === "-"; // 또는 Number(value) === -1 + // const value = field.value; + // const isUnknown = value === null || value === "-"; // 또는 Number(value) === -1 return ( <div className="flex items-center gap-2"> diff --git a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx index 34765ae9a..006306a3d 100644 --- a/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rswtrReg/rswtrRegForm.tsx @@ -39,7 +39,7 @@ export default function RswtrRegForm({ setIsModal?: (isModal: boolean) => void; readonly?: boolean; }) { - const { rswt, code, rswtBdstUpdate, rswtBdstReg } = useWrStore( + const { code, rswtBdstUpdate, rswtBdstReg } = useWrStore( (state) => state ); const [divStyle, setDivStyle] = useState("h-[53vh]"); diff --git a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx index 7d8883805..71d9dea00 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdExcel/chkgdExcel.tsx @@ -24,7 +24,7 @@ import toast from "react-hot-toast"; import type { z } from "zod"; export default function ChkgdExcel({ type,setIsRegExcel ,setYearChange }: { type: string, setIsRegExcel:(open:boolean) =>void ,setYearChange:(year:string)=> void }) { - const { rswtChkgdn, rainChkExcelDataUPload, rswtChkExceDataUpload } = + const { rainChkExcelDataUPload, rswtChkExceDataUpload } = useWrStore((state) => { return state; }); @@ -143,18 +143,18 @@ export default function ChkgdExcel({ type,setIsRegExcel ,setYearChange }: { type } }, [file]); - function findMatchingItems<T>( - arrayA: T[], - arrayB: T[], - keySelector: (item: T) => string, - condition?: (item: T) => boolean - ): T[] { - const bKeySet = new Set(arrayB.map(keySelector)); - return arrayA.filter( - (item) => - (!condition || condition(item)) && bKeySet.has(keySelector(item)) - ); - } + // function findMatchingItems<T>( + // arrayA: T[], + // arrayB: T[], + // keySelector: (item: T) => string, + // condition?: (item: T) => boolean + // ): T[] { + // const bKeySet = new Set(arrayB.map(keySelector)); + // return arrayA.filter( + // (item) => + // (!condition || condition(item)) && bKeySet.has(keySelector(item)) + // ); + // } const onSubmit = (values: z.infer<typeof chkgdRegExcel>) => { if (values.chckYr === "") { @@ -227,7 +227,6 @@ export default function ChkgdExcel({ type,setIsRegExcel ,setYearChange }: { type </FormUi> )} /> - <FormField control={form.control} name="file" @@ -236,7 +235,11 @@ export default function ChkgdExcel({ type,setIsRegExcel ,setYearChange }: { type <div className="space-y-4 p-4"> <Input type="file" - onChange={handleFileChange} + onChange={(file) =>{ + handleFileChange( file) + ////TODO : 폼 을 써야하는 지 확인 필요 + console.log(field.value) + } } accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" /> </div> diff --git a/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx b/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx index b4b87663e..8b8058a84 100644 --- a/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx +++ b/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx @@ -1,17 +1,16 @@ -import { useWrStore } from "@/app/store"; import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList"; -import type { FcPrfType, PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import type { + FcPrfType, + PrfType, +} from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { yearOptions } from "@/components/lib/func/commom"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { - FileUpload, FormField, FormUi, SelectBox, Form, Title, - type SelectDataType, filePicked, } from "@common/business_components/ui"; import { Button, Input } from "@common/components/ui"; @@ -21,9 +20,15 @@ import { useForm } from "react-hook-form"; import toast from "react-hot-toast"; import type { z } from "zod"; -export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelData}: { data: FcPrfType ,setIsExcelOPen:(open:boolean )=>void,setModalExcelData:(excelData :PrfType)=>void }) { - const { prfmnRegData } = useWrStore((state) => state); - +export default function PbnPrfExcelModal({ + data, + setIsExcelOPen, + setModalExcelData, +}: { + data: FcPrfType; + setIsExcelOPen: (open: boolean) => void; + setModalExcelData: (excelData: PrfType) => void; +}) { const [file, setFile] = useState<File | null>(null); const [excelData, setExcelData] = useState<PrfType[]>(); const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({ @@ -40,15 +45,14 @@ export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelDa } }; const onSubmit = (values: z.infer<typeof pbnPrfRegExcelZod>) => { - if (excelData) { - // prfmnRegData(1,'41', excelData as unknown as PrfType); + ////TODO: 궅이 서브밋을 써야하는 이유가 있는지 ? + console.log("values ", values); + // prfmnRegData(1,'41', excelData as unknown as PrfType); 활성화시 스토어 활성화 칠요 - setModalExcelData(excelData as unknown as PrfType) - setIsExcelOPen(false) + setModalExcelData(excelData as unknown as PrfType); + setIsExcelOPen(false); } - - }; useEffect(() => { if (data && data.bscFctNm) @@ -57,12 +61,11 @@ export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelDa form.setValue("pbnstRuseFcltNm", data.ruseUtztnFcltNm); }, [data]); - useEffect(() => { if (file) { - const isFile = file + const isFile = file; if (form.getValues("ym").length < 1) { - toast.error("파일업로드 이전에 등록년도를 작성해주세요 " ); + toast.error("파일업로드 이전에 등록년도를 작성해주세요 "); setFile(null); return; } @@ -70,7 +73,13 @@ export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelDa if (isFile) { filePicked(isFile, 0).then((res) => { if (res !== undefined) - setExcelData(excelToPbnPrfData(res as unknown as JSON[], form.getValues("ym"), form.getValues('pbnstRuseFcltFk')) as PrfType[]) + setExcelData( + excelToPbnPrfData( + res as unknown as JSON[], + form.getValues("ym"), + form.getValues("pbnstRuseFcltFk") + ) as PrfType[] + ); }); } } @@ -117,7 +126,7 @@ export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelDa <FormUi label="시설명"> <Input className="text-3xl" - value={field.value || ''} + value={field.value || ""} onChange={field.onChange} readOnly /> @@ -133,7 +142,7 @@ export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelDa <FormUi label="재이용시설명"> <Input className="flex-1 text-3xl" - value={field.value || ''} + value={field.value || ""} onChange={field.onChange} readOnly /> @@ -160,13 +169,16 @@ export default function PbnPrfExcelModal({ data ,setIsExcelOPen ,setModalExcelDa ></FileUpload> */} -<div className="space-y-4 p-4"> - <Input - type="file" - onChange={handleFileChange} - accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" + <div className="space-y-4 p-4"> + <Input + type="file" + onChange={(file) => { + console.log(" field. valus", field.value); + if (file) handleFileChange(file); + }} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" /> - </div> + </div> </FormUi> )} /> diff --git a/apps/wr/components/ui/modal/coMat/constCostFeeTable.tsx b/apps/wr/components/ui/modal/coMat/constCostFeeTable.tsx index efd47c69b..f34e777c7 100644 --- a/apps/wr/components/ui/modal/coMat/constCostFeeTable.tsx +++ b/apps/wr/components/ui/modal/coMat/constCostFeeTable.tsx @@ -9,15 +9,11 @@ import { yearOptions } from "@/components/lib/func/commom"; import { SelectBox, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Label, ScrollArea } from "@common/components/ui"; -import { useEffect, useRef, useState } from "react"; +import { Label, } from "@common/components/ui"; +import { useEffect, useState } from "react"; -export function ConstCostFeeTable({ - setReturnData, -}: { - setReturnData: (data: any) => void; -}) { - const { coRvw, constCostRes, getConstCostFee } = useWrStore((state) => state); +export function ConstCostFeeTable() { + const { coRvw, constCostRes } = useWrStore((state) => state); const [year, setYear] = useState<string>(String(new Date().getFullYear())); const [constCostData, setConstCostData] = useState<ContCostMap[]>([]); diff --git a/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx b/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx index 880c789c3..500a0cf40 100644 --- a/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx +++ b/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx @@ -11,9 +11,11 @@ import { useEffect, useState } from "react" export default function DrgtDetailModal({ data, }: { - data: customDrgt; + data: customDrgt[]; }) { - const [excelData, setExcelData] = useState<any[]>(); + + // const [isSggNm, setIsSggNm] = useState('') + const [excelData, setExcelData] = useState<any[]>(); const excelClick = () => { downloadExcel({ data: excelData ?? [], @@ -30,10 +32,14 @@ export default function DrgtDetailModal({ return { "년": item.year, "월": item.month, - "가뭄상태": item.drgtState, + "가뭄상태": item.drgtState, // Access drgtState directly from the item } }) : []; setExcelData(exData) + // if(data&&data[0].sggNm){ + ////TODO: data.sggNm [0[인지 data.sggNm 인지 사용하는지 확인필요 + // setIsSggNm(data[0].sggNm) + // } }, [data]) return ( @@ -41,7 +47,7 @@ export default function DrgtDetailModal({ <div className="grid grid-cols-4 gap-4 h-full"> <div className="col-span-4"> <div className="flex items-center justify-between"> - <Title title={`우리동네가뭄 상세내용 - ${data[0].sggNm}`} /> + <Title title={`우리동네가뭄 상세내용 - ${data[0]&&data[0].sggNm ?data[0].sggNm:'' }`} /> <div className="flex flex-row space-x-2"> <Button size={"sm"} @@ -59,11 +65,15 @@ export default function DrgtDetailModal({ <ScrollArea className="h-[63vh]"> <UiTable headName={undefined} - tableData={data} + tableData={data } headlist={drgtDetailHeadListExport} pageSize={10} total={10000} - cellClick={(index: number | undefined, headId: string) => { }} + cellClick={(index: number | undefined, headId: string) => { + console.log(' indx ' , index) + console.log(' headId ' , headId) + + }} onPageChange={() => { }} ></UiTable> </ScrollArea> diff --git a/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx b/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx index ee82420a8..c7403b2b3 100644 --- a/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx +++ b/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx @@ -2,20 +2,13 @@ import { useWrStore } from "@/app/store"; import type { rateFeeType } from "@/app/store/common/searchCode/type"; -import { yearOptions } from "@/components/lib/func/commom"; -import { SelectBox, UiTable } from "@common/business_components/ui"; +import { UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Input, Label, ScrollArea } from "@common/components/ui"; -import { Scroll } from "lucide-react"; +import { Input, Label } from "@common/components/ui"; import { useEffect, useState } from "react"; -export function RateFeeTableModal({ - setReturnData, -}: { - setReturnData: (data: any) => void; -}) { - const { code, coRvw, rateFeeRes } = useWrStore((state) => state); - const [year, setYear] = useState<string>(String(new Date().getFullYear())); +export function RateFeeTableModal() { + const { coRvw, rateFeeRes } = useWrStore((state) => state); const [reateFeeTable, setRateFeeTable] = useState<rateFeeType[]>([]); const gubunLabelMap: Record<number, string> = { diff --git a/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx b/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx index 24fef023c..66fdf91d0 100644 --- a/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx +++ b/apps/wr/components/ui/modal/coReg/coRegExcel/coRegExcelModal.tsx @@ -1,76 +1,80 @@ import { useWrStore } from "@/app/store"; import { coRegExcel } from "@/app/store/matDmd/coSttn/headList"; -import type { customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn"; import { names } from "@/app/store/matDmd/ldrmntCoSttn/excel"; -import { filePicked, FileUpload, FormUi, Title } from "@common/business_components/ui"; -import { Form, FormField } from "@common/business_components/ui/form"; +import { filePicked, Title } from "@common/business_components/ui"; +import { Form } from "@common/business_components/ui/form"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; -import { Button, Input, Progress } from "@common/components/ui"; +import { Button, Input } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useForm } from "react-hook-form"; import toast from "react-hot-toast"; import type { z } from "zod"; -export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => void }) { +export default function CoRegExcel({ + isModal, +}: { + isModal: (open: boolean) => void; +}) { const { ldrmnt, loadingOpen } = useWrStore((state) => state); const { isLoading } = ldrmnt; const form = useForm<z.infer<typeof coRegExcel>>({ resolver: zodResolver(coRegExcel), }); - const { ldrmntRegData, ldrmntDelete } = useWrStore((state) => state); - const [excelData, setExcelData] = useState<customLdrmnt[]>(); + const { ldrmntRegData } = useWrStore((state) => state); const [file, setFiles] = useState<File | undefined>(); - const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { - const selectedFile = e.target.files?.[0]; - if (selectedFile) { - setFiles(selectedFile); - } - }; + // const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { + // const selectedFile = e.target.files?.[0]; + // if (selectedFile) { + // setFiles(selectedFile); + // } + // }; - const onSubmit = (values: z.infer<typeof coRegExcel>) => { + //TODO:Onsubmit을 써야하는지 + const onSubmit = () => { loadingOpen(true); if (file) { - filePicked(file, 0).then(async (res) => { + filePicked(file, 0) + .then(async (res) => { + try { + const array: { [key: string]: string | number }[] = []; + if (Array.isArray(res)) { + res.some((item) => { + const object: { [key: string]: string | number } = {}; + Object.keys(names).some((key) => { + if (item && names[key] !== undefined) { + // if (key === "공장관리번호") { + // item[key] = String(item[key]) + // } else { + object[names[key] as string] = item[key]; + // } + } + return false; + }); + + array.push(object); - try { - let array: { [key: string]: string | number }[] = [] - if (Array.isArray(res)) { - res.some((item, index) => { - let object: { [key: string]: string | number } = {} - Object.keys(names).some((key) => { - if (item && names[key] !== undefined) { - // if (key === "공장관리번호") { - // item[key] = String(item[key]) - // } else { - object[names[key] as string] = item[key]; - // } - } return false; - }) - - array.push(object) - - return false; - }) + }); + } + await ldrmntRegData(array); + isModal(false); + loadingOpen(false); + toast.success(`잠재수요처 등록이 완료되었습니다.`); + } catch (e) { + console.log(e); + loadingOpen(false); + alert(e); + return true; } - await ldrmntRegData(array); - isModal(false); - loadingOpen(false); - toast.success(`잠재수요처 등록이 완료되었습니다.`); - } catch (e) { - console.log(e) - loadingOpen(false); - alert(e) - return true; - } - }).catch((e) => { - console.log("file", e); - }); - }; - } + }) + .catch((e) => { + console.log("file", e); + }); + } + }; return ( <> @@ -85,28 +89,22 @@ export default function CoRegExcel({ isModal }: { isModal: (open: boolean) => vo <h3 className="text-2xl font-bold text-gray-900 mt-1 ml-7"> {"잠재수요처 파일"} </h3> - - <Button className="" type="submit" size={"sm"}> + <Button className="" type="submit" size={"sm"} onClick={onSubmit}> 저장 </Button> </div> <div> - <FormField - control={form.control} - name="file" - render={({ field }) => ( - <FormUi label=""> - <div className="space-y-4 p-4"> - <Input - type="file" - onChange={handleFileChange} - accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" - /> - </div> - </FormUi> - )} - /> + <div className="space-y-4 p-4"> + <Input + type="file" + onChange={(e) => { + const selectedFile = e.target.files?.[0]; + if (selectedFile) setFiles(selectedFile); + }} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" + /> + </div> </div> </form> </Form> diff --git a/apps/wr/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal.tsx index 0b071aa91..09f66ed2a 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal.tsx @@ -1,8 +1,6 @@ import { useWrStore } from "@/app/store"; import { UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { useEffect } from "react"; - import type { @@ -10,7 +8,7 @@ import type { } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; export default function BdstChgModal({ chgBuilding }: { chgBuilding:chgBuilding[] }) { -const {bdst,rain} = useWrStore((state) => { +const {bdst} = useWrStore((state) => { return state; }); const { bdstChgHeadList } = bdst; @@ -26,7 +24,6 @@ const { bdstChgHeadList } = bdst; onPageChange={() => {}} headName={"○건축물 변경 이력"} tableData={chgBuilding} - children={undefined} cellClick={undefined} /> </ListDiv> diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index a049772e8..c087096f3 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -12,7 +12,7 @@ import { } from "@common/business_components"; import { Button, Input, Label } from "@common/components"; import { useEffect, useState } from "react"; -import { getCity, tableData } from "@/components/lib/func/commom"; +import { tableData } from "@/components/lib/func/commom"; import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import RainRegForm from "@/components/ui/form/fcltReg/rainReg/rainRegForm"; @@ -35,17 +35,15 @@ type BdstTypeMap = { interface BdstRegProps<T extends MoType> { moType: T; isModal: boolean; - siSggCode?: string; setIsModal?: (open: boolean) => void; } export function BdstReg<T extends MoType>({ moType, setIsModal, - siSggCode, isModal, }: BdstRegProps<T>) { - const { rain, code, bdst, findBdst } = useWrStore((state) => { + const { code, bdst, findBdst } = useWrStore((state) => { return state; }); @@ -56,14 +54,12 @@ export function BdstReg<T extends MoType>({ {} as BdstTypeMap[T] ); const [searchTxt, setSearchTxt] = useState<string>(); - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(); const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "", }); const [useCityCd, setUserCityCd] = useState<SelectDataType[]>([]); const [useSggCd, setUserSggCd] = useState<SelectDataType[]>([]); - const [dataCode, setDataCode] = useState<string>(); const searchBdst = (searchTxt: string | undefined) => { let data = objSearch.city; @@ -78,7 +74,7 @@ export function BdstReg<T extends MoType>({ useEffect(() => { if (code.sggCd.length > 0) { const bdstData = bdst.bdstBase.map((bdst) => { - let archArea = + const archArea = bdst?.archArea.split(".")[0] !== "-1" ? bdst?.archArea.split(".")[0] : "확인불가"; @@ -117,8 +113,7 @@ export function BdstReg<T extends MoType>({ }, [userSiSggCd, code.cityCd, code.sggCd]); const tableClick: (val: number | undefined, headId: string) => void = ( - val, - headId + val ) => { if (val !== undefined && bdst?.bdstBase.length > 0) { const data: BdstTypeMap[T] = bdst?.bdstBase[val]; @@ -195,6 +190,7 @@ export function BdstReg<T extends MoType>({ cellClick={(idx, headId) => tableClick(idx, headId || "")} onPageChange={function (page: number): void { throw new Error("Function not implemented."); + console.log("page ", page); }} ></UiTable> </div> @@ -212,16 +208,20 @@ export function BdstReg<T extends MoType>({ <RswtrRegForm rswtForm={rainBdstForm as customRswtBdst} isModal={isModal} - setIsModal={(open) => { - setIsModal && setIsModal(open); + setIsModal={(open?: boolean) => { + if (setIsModal && open) { + setIsModal(open); + } }} ></RswtrRegForm> ) : ( <HtdflRegForm htdflForm={rainBdstForm as unknown as customHtdflBdst} isModal={true} - setIsModal={(open) => { - setIsModal && setIsModal(open); + setIsModal={(open?: boolean) => { + if (setIsModal && open) { + setIsModal(open); + } }} ></HtdflRegForm> )} diff --git a/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx index 5b1a6f0f6..1f2ea4a52 100644 --- a/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx @@ -2,13 +2,11 @@ import { useWrStore } from "@/app/store"; import type { pubHasuType, - fcBizType, fcOrgwtType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import type { TableUpperProps } from "@/app/store/common/type/header"; import { tableData } from "@/components/lib/func/commom"; import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable"; -import { Title, UiTable } from "@common/business_components/ui"; +import { Title } from "@common/business_components/ui"; import { Label } from "@common/business_components/ui/form/lib/label"; import { Button } from "@common/business_components/ui/table/lib/button"; import { Input } from "@common/components/ui"; diff --git a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx index f658fa485..69ba1fb68 100644 --- a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx @@ -1,10 +1,8 @@ "use client"; -import { useWrStore } from "@/app/store"; import { pbnstRegZod, type customPbnst, type PbnstRegArrrayType, - type pubHasuType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { ScrollArea } from "@common/business_components"; @@ -18,12 +16,10 @@ import { import { useEffect, useState } from "react"; import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; import { - useFieldArray, type FieldErrors, type UseFormReturn, } from "react-hook-form"; import { writeRgtrAndMdfr } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg"; -import toast from "react-hot-toast"; import type { z } from "zod"; export function PbnstRegModal({ @@ -36,10 +32,13 @@ export function PbnstRegModal({ onInvalid:(errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }>) => void }) { - const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>( - {} as customPbnst - ); - const [currentTab, setCurrentTab] = useState<string>("mng"); + // const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>( + // {} as customPbnst + // ); + + //TODO: 유즈 스테이트에 set만해도 되나? + const [, setCurrentTab] = useState<string>("mng"); + //const setCurrentTab = "mng" const [indexMng, setIndexMng] = useState<number>(0); const [indexBiz, setIndexBiz] = useState<number>(0); @@ -51,70 +50,7 @@ export function PbnstRegModal({ setPbnstInsert(data[0]); } }; - // const onInvalid = ( - // errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }> - // ) => { - // // 재귀 함수를 사용해 중첩된 에러 객체에서 모든 에러 메시지와 경로를 찾습니다. - - - // const findAllErrors = ( - // errorObject: any, - // path: (string | number)[] = [] - // ): { message: string; path: (string | number)[] }[] => { - // if (!errorObject) return []; - - // return Object.keys(errorObject).flatMap((key) => { - // const value = errorObject[key]; - // const currentKey = !isNaN(parseInt(key)) ? parseInt(key) : key; - // const newPath = [...path, currentKey]; - // if (value && typeof value === "object") { - // if (typeof value.message === "string") { - // return [{ message: value.message, path: newPath }]; // 에러 메시지와 경로 반환 - // } - // return findAllErrors(value, newPath); - // } - // return []; - // }); - // }; - - - // const errorList = findAllErrors(errors); - - - // if (errorList.length > 0) { - // errorList.forEach((errorInfo) => { - // const { message, path } = errorInfo; - // let prefix = ""; - // const itemsIndex = path.indexOf("items"); - - - // if (itemsIndex > -1 && path.length > itemsIndex + 1) { - // const itemIdx = path[itemsIndex + 1] as number; - // const facilityName = form.getValues( - // `items.${itemIdx}.ruseUtztnFcltNm` - // ); - // if (facilityName) { - // prefix += `[${facilityName}] `; - // } - - // const fcBizsIndex = path.indexOf("fcBizs"); - // if (fcBizsIndex > -1 && path.length > fcBizsIndex + 1) { - // const bizIdx = path[fcBizsIndex + 1] as number; - // const cycle = form.getValues( - // `items.${itemIdx}.fcBizs.${bizIdx}.cycl` - // ); - // if (cycle) { - // prefix += `[${cycle}차수] `; - // } - // } - // } - - - // toast.error(`${prefix}${message}`); - // }); - // } - // }; - + const handleTabChange = (value: string) => { setCurrentTab(value); }; @@ -158,7 +94,7 @@ export function PbnstRegModal({ <PbnstMngForm form={form} formType={"reg"} - firstFcltData={pbnstBdstForm} + // firstFcltData={pbnstBdstForm} indexMng={indexMng} setIndexMng={setIndexMng} /> @@ -170,7 +106,7 @@ export function PbnstRegModal({ indexBiz={indexBiz} setIndexBiz={setIndexBiz} formType={"reg"} - firstBizData={pbnstBdstForm.fcBizs} + // firstBizData={pbnstBdstForm.fcBizs} /> </TabsContent> </Tabs> From ba25659db954d2579db4e776643b88aaaa5d07b9 Mon Sep 17 00:00:00 2001 From: swcho <swcho@mind-one.co.kr> Date: Mon, 14 Jul 2025 14:02:22 +0900 Subject: [PATCH 107/159] =?UTF-8?q?feat:=20map=20-=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EB=82=B4=EB=B6=80=20=EB=B9=8C=EB=93=9C=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20SearchBar=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/featureClickEventPopup.tsx | 200 ------- apps/wr/app/map/htdflPrfmncSttnPopup.tsx | 621 -------------------- apps/wr/app/map/htdflSttn/page.tsx | 10 +- apps/wr/app/map/mapSearchForm.tsx | 628 ++++++++++----------- apps/wr/app/map/newWindowPopup.tsx | 99 ++-- apps/wr/app/map/newWindowPortal.tsx | 2 +- apps/wr/app/map/pbnstPrfmncSttnPopup.tsx | 582 ------------------- apps/wr/app/map/rainPrfmncSttnPopup.tsx | 410 -------------- apps/wr/app/map/rswtrPrfmncSttnPopup.tsx | 403 ------------- 9 files changed, 352 insertions(+), 2603 deletions(-) delete mode 100644 apps/wr/app/map/featureClickEventPopup.tsx delete mode 100644 apps/wr/app/map/htdflPrfmncSttnPopup.tsx delete mode 100644 apps/wr/app/map/pbnstPrfmncSttnPopup.tsx delete mode 100644 apps/wr/app/map/rainPrfmncSttnPopup.tsx delete mode 100644 apps/wr/app/map/rswtrPrfmncSttnPopup.tsx diff --git a/apps/wr/app/map/featureClickEventPopup.tsx b/apps/wr/app/map/featureClickEventPopup.tsx deleted file mode 100644 index 41a2c8924..000000000 --- a/apps/wr/app/map/featureClickEventPopup.tsx +++ /dev/null @@ -1,200 +0,0 @@ -'use client' -import { getData, putData } from "../../../sn/app/components/lib/api"; -import Modal from "../../../sn/app/components/ui/modal"; -import { VerticalTable } from "../../../sn/app/components/ui/verticalTable"; -import { useGisContext } from "@common/business_components/ui/map/Gis"; -import { Button } from "@common/components/ui"; -import { useEffect, useRef, useState } from "react"; -import { getLayerContentComponent } from "../../../sn/app/map/components/common"; -// TODO: -const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => { - const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; - // const featureId = featureData.getId(); // 피처의 id 가져오기 - const featureId = typeof featureData.getId === 'function' - ? featureData.getId() - : featureData.fid; - const [layerNm, setLayerNm] = useState<string>(""); // 레이어 이름 상태 - const [tableData, setTableData] = useState<any>(null); // 피처 데이터 - const [mntrngsData, setMntrngsData] = useState(false); // 수량/수질 측정 정보 - const [headlist, setHeadlist] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태 - const [buttonChk, setButtonChk] = useState(true) - const [fetchData, setfetchData] = useState<any>(); // api 호출여부 - const contentRef = useRef<HTMLDivElement>(null); - const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열기 상태 - const [chkMainSsc, setChkMainSsc] = useState(false); // 중점우수토실 여부 - - // 피쳐데이터의 현재 레이어 이름 가져오는 함수 - const getSelectedLayers = () => { - let result = null; - const layers = gisMap.getLayers().getArray(); // gisMap에서 모든 레이어 가져오기 - let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 - layers.forEach((layer: any) => { - const source = layer.getSource(); - if (source && source.hasFeature && featureData - && typeof featureData.getId === 'function' && source.hasFeature(featureData)) { - featureLayer = layer; // 피처가 속한 레이어 찾기 - } - }); - // SearchModal 클릭 이벤트와 Gis 클릭 이벤트 구분하기 - if (featureLayer.get('lyrNm') === null) { - if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설'; - else if (featureData.lyrTypeNm === 'tb_ms_swage_prcs_zone') result = '하수처리구역'; - else if (featureData.lyrTypeNm === 'om_dt_untrt_swg_rain') result = '중점우수토실'; - } - else result = featureLayer.get('lyrNm'); - - return result; - // return featureLayer.get('lyrNm'); // 레이어 이름 출력 - }; - - useEffect(() => { - const fetchData = async () => { - if (featureId) { - const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기 - setLayerNm(selectedLayerName); // 상태 업데이트 - const layerId = featureId.split('.')[0] - let data = await getData(`v1/fclts/${featureId}?lyrTypeNm=${layerId}`); - setfetchData(data) - switch (selectedLayerName) { - case '하수처리시설': - setButtonChk(false) - break; - case '하수처리구역': - setButtonChk(false) - break; - case '중점우수토실': - setButtonChk(false) - setChkMainSsc(true) - - // 데이터 전처리: 합쳐진 필드 추가 - data = data ? { - ...data, - discharge_pipe_spec: `직경: ${data.pipe_diameter || '-'} / 높이: ${data.pipe_hg || '-'} / 길이: ${data.pipe_lt || '-'}` - } : {}; - - // 수량/수질측정 정보 데이터 호출 - const additionalResponse = await getData(`v1/onsemiro/swgRain/${data.adst_dstr_cd}/${data.manage_no}/mntrngs`); - setMntrngsData(additionalResponse.content); - break; - case '우수토실': - setButtonChk(true) - break; - case '하수관로': - setButtonChk(true) - break; - case '오수펌프': - setButtonChk(true) - break; - case '빗물펌프': - setButtonChk(true) - break; - case '하수맨홀': - setButtonChk(true) - break; - default: - break; - } - setTableData(data); - }; - } - fetchData(); - }, [featureId]); - - // 저장 시 모달 띄우기 - const handleSaveClick = () => { - setIsModalOpen(true); // 모달 열기 - }; - - const handleModalSave = () => { - setIsModalOpen(false); // 모달 닫기 - btnClickEvent(); // 저장 이벤트 실행 - }; - - const handleModalClose = () => { - setIsModalOpen(false); // 모달 닫기 - }; - - const btnClickEvent = async () => { - const bodyData: Record<string, any> = {} - if (buttonChk && contentRef.current) { - const inputElements = contentRef.current.querySelectorAll('input'); - const selectElements = contentRef.current.querySelectorAll('select'); - // 카멜케이스 변환 함수 - const toCamelCase = (str: string) => - str.replace(/_([a-z])/g, (_, char) => char.toUpperCase()); - // select 태그의 값 가져오기 - selectElements.forEach((select) => { - const camelCaseId = toCamelCase(select.id); - bodyData[camelCaseId] = select.value; - }); - // input 태그의 값 가져오기 - inputElements.forEach((input) => { - const camelCaseId = toCamelCase(input.id); - bodyData[camelCaseId] = input.value; - }); - if (layerNm === '하수관로') bodyData['lyrTypeNm'] = 'tb_ms_swage_ppl' - else if (layerNm === '우수토실') bodyData['lyrTypeNm'] = 'tb_ms_stofcbr' - else if (layerNm === '오수펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' - else if (layerNm === '빗물펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' - else if (layerNm === '하수맨홀') bodyData['lyrTypeNm'] = 'tb_ms_swage_mnhl' - bodyData['fid'] = featureId - const data = await putData(`v1/fclts/${featureId}`, bodyData); - if (data.status == 200) { - alert('저장되었습니다') - setTableData(data) - setfetchData(data) - } - } - } - type ContentComponentProps = { - featureData: any; - chkMainSsc: boolean; - additionalData: any; - }; - const ContentComponent = layerNm ? getLayerContentComponent(layerNm) as React.ComponentType<ContentComponentProps> : null; - return ( - <div id="popup" className="absolute top-0 right-0 w-[350px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-[102]"> - <div className="card-header bg-primary flex items-center justify-between p-4"> - <div className="flex mx-3 flex-col"> - <h3 className="text-2xl font-medium text-white text-label">{layerNm} 정보</h3> - <div className="font-medium text-white text-label">(00구 00리 하수관로)</div> - </div> - <button - onClick={onClose} - className="text-white hover:text-gray-700 focus:outline-none" - aria-label="닫기" - > - ✕ - </button> - </div> - <div className="overflow-y-auto overflow-x-hidden flex-1" ref={contentRef}> - <VerticalTable - headName='LX 연계정보' - tableData={[tableData]} - headlist={headlist} - pageSize={20} - total={0} - children={undefined} - cellClick={undefined} - onPageChange={function (page: number): void { - throw new Error("Function not implemented."); - }} - /> - <div className="w-full mx-5 flex items-center justify-end space-x-2"> - {buttonChk ? <Button onClick={handleSaveClick} className="px-4 mr-5 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"> - 저장 - </Button> : null} - </div> - <Modal isModalOpen={isModalOpen} title="자체입력정보 저장" setIsModalOpen={setIsModalOpen} closeModal={handleModalClose} saveModal={handleModalSave}><div className="text-lg">정보를 저장하시겠습니까?</div></Modal> - {ContentComponent && - <ContentComponent - featureData={fetchData} - chkMainSsc={chkMainSsc} - additionalData={mntrngsData} - /> - } - </div> - </div> - ) -} -export default FeatureClickEventPopup; \ No newline at end of file diff --git a/apps/wr/app/map/htdflPrfmncSttnPopup.tsx b/apps/wr/app/map/htdflPrfmncSttnPopup.tsx deleted file mode 100644 index 8d1bec486..000000000 --- a/apps/wr/app/map/htdflPrfmncSttnPopup.tsx +++ /dev/null @@ -1,621 +0,0 @@ -"use client"; - -import { - Form, - FormField, - FormUi, - SelectBox, -} from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useForm } from "react-hook-form"; -import { z } from "zod"; -import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { - hdtflZod, - type customHtdflBdst, -} from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { useEffect } from "react"; -import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; -import { - formatCommaNumber, - handleCommaNumberChange, -} from "@/components/lib/func/commom"; -import { formH1Class } from "@/components/lib/class/comClass"; - -export default function HtdflPrfmncSttnPopup({ - htdflForm, - isModal, -}: { - htdflForm: customHtdflBdst; - isModal: boolean; -}) { - const { code, htdflBdstUpdate, htdflBdstReg } = useWrStore((state) => state); - - const defaultValues: z.infer<typeof hdtflZod> = hdtflZod.parse({}); - - const form = useForm<z.infer<typeof hdtflZod>>({ - resolver: zodResolver(hdtflZod), - defaultValues: defaultValues, - }); - - const onSubmit = (values: z.infer<typeof hdtflZod>) => { - if (isModal) { - htdflBdstReg(values, '41'); - } else { - htdflBdstUpdate(values, '41'); - } - }; - - - const cleanHtdflData = (raw: any): z.infer<typeof hdtflZod> => { - return { - ...raw, - frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null), - archChgPrmsnDt: raw?.archChgPrmsnDt - ? new Date(raw?.archChgPrmsnDt) - : null, - chgBuilding: (raw?.chgBuilding || []).map((item: any) => ({ - ...item, - archChgPrmsnDt: - item?.archChgPrmsnDt === null - ? new Date() - : new Date(item?.archChgPrmsnDt), - bdstChgNm: item?.bdstChgNm ?? "", // null → "" - })), - reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({ - ...item, - instlCmptnDt: new Date(item?.instlCmptnDt), - htdflObj: { - ...item?.htdflObj, - }, - })), - }; - }; - - useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); - - useEffect(() => { - if (hdtflZod) form.reset(cleanHtdflData(htdflForm)); - }, [htdflForm]); - - return ( - <div className="!mx-[1.6rem] !p-0r"> - <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> - {/* <div className="flex justify-between items-center mx-3"> */} - <div> - <div className="grid grid-cols-12 flex items-center card-header"> - <h1 className="text-2xl font-medium text-label col-span-10">온배수 시설 정보</h1> - </div> - </div> - - {isModal && htdflForm != undefined ? <BdstReg form={form} /> : <></>} - {isModal ? ( - <h1 className="text-xl col-span-10 mt-4"> - 온배수 시설 정보{" "} - </h1> - ) : ( - <></> - )} - - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.etgtType" - render={({ field }) => ( - <FormUi label="발전유형(코드정비후 수정)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.fclCpct" // 이름 이상함. - render={({ field }) => ( - <FormUi label="설비용량"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.plwtYn" - render={({ field }) => ( - <FormUi label="담수화 여부"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - <div className=" my-4"> - <h1 className={formH1Class}> - 온배수 시설 운영현황 - </h1> - </div> - - <div className="grid grid-cols-10 gap-1 mt-4"> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.orgwtWtritSpt" - render={({ field }) => ( - <FormUi label="원수취수 지점(코드정비후 수정)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - value={field.value ?? 0} - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.orgwtOcrnProcs" - render={({ field }) => ( - <FormUi label="원수발생 공정"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.wtritEntrcTp" - render={({ field }) => ( - <FormUi label="취수구 온도"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.amtgnr" - render={({ field }) => ( - <FormUi label="발생량(m³/년)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.prcsProcsYn" - render={({ field }) => ( - <FormUi label="처리공정"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.prcsFcltCpct" - render={({ field }) => ( - <FormUi label="처리시설 용량(m³/년)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.fmYn" - render={({ field }) => ( - <FormUi label="유량계유무"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.utztnCpct" - render={({ field }) => ( - <FormUi label="이용량(m³/년)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.utztnUsg" - render={({ field }) => ( - <FormUi label="이용용도"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className=" my-2"> - <h1 className={formH1Class}> - 요구수질 - </h1> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.grssClfg" - render={({ field }) => ( - <FormUi label="총대장균군"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.tn" - render={({ field }) => ( - <FormUi label="총질소"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.combResdch" - render={({ field }) => ( - <FormUi label="결합잔류염소"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6 "> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.tph" - render={({ field }) => ( - <FormUi label="총인"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.trbt" - render={({ field }) => ( - <FormUi label="탁도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.ph" - render={({ field }) => ( - <FormUi label="수소이온농도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.bod" - render={({ field }) => ( - <FormUi label="생물학적 산소요구량"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.clIonQnt" - render={({ field }) => ( - <FormUi label="염화물"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.smll" - render={({ field }) => ( - <FormUi label="냄새"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.cdtnv" - render={({ field }) => ( - <FormUi label="전기전도도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.crmty" - render={({ field }) => ( - <FormUi label="색도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="reuseBuilding.0.htdflObj.emsnExitTp" - render={({ field }) => ( - <FormUi label="배출구온도"> - <Input - className={'w-full !text-xl'} - placeholder="10" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - </form> - </Form> - </div> - ); -} diff --git a/apps/wr/app/map/htdflSttn/page.tsx b/apps/wr/app/map/htdflSttn/page.tsx index b7935ee99..035713b35 100644 --- a/apps/wr/app/map/htdflSttn/page.tsx +++ b/apps/wr/app/map/htdflSttn/page.tsx @@ -2,7 +2,6 @@ import Gis from "@common/business_components/ui/map/Gis"; import { useEffect, useRef, useState, useCallback } from "react"; -import FeatureClickEventPopup from "../featureClickEventPopup"; import { mapService } from "../service"; // import { MapSearchBar } from "../mapSearchBar"; import NewWindowPopup from "../newWindowPopup"; @@ -10,7 +9,6 @@ import GisApp from "@common/business_components/ui/map/lib/gis.core"; const Map = () => { const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정 - const [selectedFeature, setSelectedFeature] = useState(null); // 선택된 피처 상태 const gisMaps = useRef<any | null>(null); const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태 @@ -46,7 +44,7 @@ const Map = () => { // SearchModal, GisContent 등에서 호출 const onFeatureSelect = (data: any) => { - let map = gisMaps.current; + const map = gisMaps.current; if (!map) { console.warn("지도가 초기화되지 않았습니다."); return; @@ -60,7 +58,7 @@ const Map = () => { select.resetSelectedFeature(); // 2. data가 OpenLayers Feature 인스턴스인지 확인 - let foundFeature = null; + let foundFeature: any = null; if ( data && typeof data.getGeometry === "function" && @@ -85,9 +83,9 @@ const Map = () => { // 3. 피처 선택 if (foundFeature) { - let geometry = foundFeature.getGeometry(); + const geometry = foundFeature.getGeometry(); if (geometry) { - let extent = geometry.getExtent(); + const extent = geometry.getExtent(); map.getView().fit(extent, { duration: 300, diff --git a/apps/wr/app/map/mapSearchForm.tsx b/apps/wr/app/map/mapSearchForm.tsx index 70927996b..e01c60faf 100644 --- a/apps/wr/app/map/mapSearchForm.tsx +++ b/apps/wr/app/map/mapSearchForm.tsx @@ -1,340 +1,340 @@ -"use client" +// "use client" -import React, { useEffect, useState } from 'react'; -import type { SelectDataType } from '@common/business_components/ui/search_input_select'; -import { SelectBox } from '@common/business_components/ui/select'; +// import React, { useEffect, useState } from 'react'; +// import type { SelectDataType } from '@common/business_components/ui/search_input_select'; +// import { SelectBox } from '@common/business_components/ui/select'; -/** - * 검색 폼 왼쪽 컴포넌트 타입 - * - * @param isShowPart 구분 조회 여부 - * @param children 자식 컴포넌트 - * @param selectSidoData 시도 데이터 - * @param selectSigunData 시군구 데이터 - * @param selectRegionData 유역 데이터 - * @param selectUnitWaterShedData 단위유역 데이터 - * @param selectMiddleRegionData 중권역 데이터 - * @param selectEnvPartData 환경청 데이터 - * @param selectEnvPartSidoData 환경청 시도 데이터 - * @param selectEnvPartSigunData 환경청 시군구 데이터 - * @param setRtnPartValue 부분 값 변경 핸들러 - */ -type SearchFormLeftProps = { - isShowPart?: boolean | undefined; - children: React.ReactNode; - selectSidoData?: SelectDataType[] | []; - selectSigunData?: SelectDataType[] | []; - selectRegionData?: SelectDataType[] | []; - selectUnitWaterShedData?: SelectDataType[] | []; - selectMiddleRegionData?: SelectDataType[] | []; - selectEnvPartData?: EnvPartSelectDataType[] | []; - selectEnvPartSidoData?: SelectDataType[] | []; - selectEnvPartSigunData?: SelectDataType[] | []; +// /** +// * 검색 폼 왼쪽 컴포넌트 타입 +// * +// * @param isShowPart 구분 조회 여부 +// * @param children 자식 컴포넌트 +// * @param selectSidoData 시도 데이터 +// * @param selectSigunData 시군구 데이터 +// * @param selectRegionData 유역 데이터 +// * @param selectUnitWaterShedData 단위유역 데이터 +// * @param selectMiddleRegionData 중권역 데이터 +// * @param selectEnvPartData 환경청 데이터 +// * @param selectEnvPartSidoData 환경청 시도 데이터 +// * @param selectEnvPartSigunData 환경청 시군구 데이터 +// * @param setRtnPartValue 부분 값 변경 핸들러 +// */ +// type SearchFormLeftProps = { +// isShowPart?: boolean | undefined; +// children: React.ReactNode; +// selectSidoData?: SelectDataType[] | []; +// selectSigunData?: SelectDataType[] | []; +// selectRegionData?: SelectDataType[] | []; +// selectUnitWaterShedData?: SelectDataType[] | []; +// selectMiddleRegionData?: SelectDataType[] | []; +// selectEnvPartData?: EnvPartSelectDataType[] | []; +// selectEnvPartSidoData?: SelectDataType[] | []; +// selectEnvPartSigunData?: SelectDataType[] | []; - setRtnPartValue?: (value: string) => void; - setRtnSidoValue?: (value: string) => void; - setRtnSigunValue?: (value: string) => void; - setRtnRegionValue?: (value: string) => void; - setRtnUnitWaterShedValue?: (value: string) => void; - setRtnMiddleRegionValue?: (value: string) => void; - setRtnEnvPartValue?: (value: string) => void; - setRtnEnvPartSidoValue?: (value: string) => void; - setRtnEnvPartSigunValue?: (value: string) => void; - setRtnSidoText?: (value: string) => void; - setRtnSigunText?: (value: string) => void; - resetTrigger?: boolean; - isAdmin?: boolean; -} +// setRtnPartValue?: (value: string) => void; +// setRtnSidoValue?: (value: string) => void; +// setRtnSigunValue?: (value: string) => void; +// setRtnRegionValue?: (value: string) => void; +// setRtnUnitWaterShedValue?: (value: string) => void; +// setRtnMiddleRegionValue?: (value: string) => void; +// setRtnEnvPartValue?: (value: string) => void; +// setRtnEnvPartSidoValue?: (value: string) => void; +// setRtnEnvPartSigunValue?: (value: string) => void; +// setRtnSidoText?: (value: string) => void; +// setRtnSigunText?: (value: string) => void; +// resetTrigger?: boolean; +// isAdmin?: boolean; +// } -export type EnvPartSelectDataType = SelectDataType & { - adstDliStrCd: string, -} +// export type EnvPartSelectDataType = SelectDataType & { +// adstDliStrCd: string, +// } -const selectPartData: SelectDataType[] = [ - { text: "행정별", val: 'A' }, - { text: "유역별", val: 'R' }, - { text: "환경청별", val: 'G' }, -]; +// const selectPartData: SelectDataType[] = [ +// { text: "행정별", val: 'A' }, +// { text: "유역별", val: 'R' }, +// { text: "환경청별", val: 'G' }, +// ]; -function MapSearchFormLeft({ isShowPart = false, children, selectSidoData = [], selectSigunData = [], selectRegionData = [], selectUnitWaterShedData = [], selectMiddleRegionData = [], selectEnvPartData = [], setRtnPartValue, setRtnSidoValue, setRtnSidoText, setRtnSigunValue, setRtnSigunText, setRtnRegionValue, setRtnUnitWaterShedValue, setRtnMiddleRegionValue, setRtnEnvPartValue, setRtnEnvPartSidoValue, setRtnEnvPartSigunValue, resetTrigger = false, isAdmin = false }: SearchFormLeftProps) { - /******************선택된 데이터******************/ - const [partValue, setPartValue] = useState<string>('A'); - //행정별 시도 시군구 - const [sidoValue, setSidoValue] = useState<string>('0'); - const [sigunValue, setSigunValue] = useState<string>('0'); - const [sidoText, setSidoText] = useState<string>(''); - const [sigunText, setSigunText] = useState<string>(''); - //유역별 - const [regionValue, setRegionValue] = useState<string>('0'); - const [unitWaterShedValue, setUnitWaterShedValue] = useState<string>('0'); - const [middleRegionValue, setMiddleRegionValue] = useState<string>('0'); - //환경청별 시도 시군구 - const [envPartValue, setEnvPartValue] = useState<string>('0'); - // 환경청 - const [filteredEnvPartSigunDataSelected, setFilteredEnvPartSigunDataSelected] = useState<SelectDataType[]>([]); +// function MapSearchFormLeft({ isShowPart = false, children, selectSidoData = [], selectSigunData = [], selectRegionData = [], selectUnitWaterShedData = [], selectMiddleRegionData = [], selectEnvPartData = [], setRtnPartValue, setRtnSidoValue, setRtnSidoText, setRtnSigunValue, setRtnSigunText, setRtnRegionValue, setRtnUnitWaterShedValue, setRtnMiddleRegionValue, setRtnEnvPartValue, setRtnEnvPartSidoValue, setRtnEnvPartSigunValue, resetTrigger = false, isAdmin = false }: SearchFormLeftProps) { +// /******************선택된 데이터******************/ +// const [partValue, setPartValue] = useState<string>('A'); +// //행정별 시도 시군구 +// const [sidoValue, setSidoValue] = useState<string>('0'); +// const [sigunValue, setSigunValue] = useState<string>('0'); +// const [sidoText, setSidoText] = useState<string>(''); +// const [sigunText, setSigunText] = useState<string>(''); +// //유역별 +// const [regionValue, setRegionValue] = useState<string>('0'); +// const [unitWaterShedValue, setUnitWaterShedValue] = useState<string>('0'); +// const [middleRegionValue, setMiddleRegionValue] = useState<string>('0'); +// //환경청별 시도 시군구 +// const [envPartValue, setEnvPartValue] = useState<string>('0'); +// // 환경청 +// const [filteredEnvPartSigunDataSelected, setFilteredEnvPartSigunDataSelected] = useState<SelectDataType[]>([]); - /****************** 셀렉트 리스트 데이터. ******************/ - // 조회된 조건에 맞는 시도 시군 유역 - const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - const [filteredUnitWaterShedData, setFilteredUnitWaterShedData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - const [filteredMiddleRegionData, setFilteredMiddleRegionData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - // 조회된 조건에 맞는 환경청 시도 시군 - const [filteredEnvPartData, setFilteredEnvPartData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]); - const [filteredEnvPartSidoData, setFilteredEnvPartSidoData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]); - const [filteredEnvPartSigunData, setFilteredEnvPartSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); +// /****************** 셀렉트 리스트 데이터. ******************/ +// // 조회된 조건에 맞는 시도 시군 유역 +// const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); +// const [filteredUnitWaterShedData, setFilteredUnitWaterShedData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); +// const [filteredMiddleRegionData, setFilteredMiddleRegionData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); +// // 조회된 조건에 맞는 환경청 시도 시군 +// const [filteredEnvPartData, setFilteredEnvPartData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]); +// const [filteredEnvPartSidoData, setFilteredEnvPartSidoData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]); +// const [filteredEnvPartSigunData, setFilteredEnvPartSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); - // 시군구 세팅 - const initializeSigunData = (sidoCd: string) => { - if (sidoCd === '0') { - setSigunValue('0'); - setFilteredSigunData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectSigunData.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd) - ]; - setSigunValue('0'); - setFilteredSigunData(newFilteredData); - } - } +// // 시군구 세팅 +// const initializeSigunData = (sidoCd: string) => { +// if (sidoCd === '0') { +// setSigunValue('0'); +// setFilteredSigunData([{ text: "전체", val: '0' }]); +// } else { +// const newFilteredData = [ +// { text: "전체", val: '0' }, +// ...selectSigunData.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd) +// ]; +// setSigunValue('0'); +// setFilteredSigunData(newFilteredData); +// } +// } - // 단위유역 세팅 - const initializeUnitWaterShedData = (regionCd: string) => { - if (regionCd === '0') { - setUnitWaterShedValue('0'); - setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectUnitWaterShedData.filter((item: SelectDataType) => item.val.substring(0, 1) === regionCd) - ]; - setUnitWaterShedValue('0'); - setFilteredUnitWaterShedData(newFilteredData); - } - } +// // 단위유역 세팅 +// const initializeUnitWaterShedData = (regionCd: string) => { +// if (regionCd === '0') { +// setUnitWaterShedValue('0'); +// setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]); +// } else { +// const newFilteredData = [ +// { text: "전체", val: '0' }, +// ...selectUnitWaterShedData.filter((item: SelectDataType) => item.val.substring(0, 1) === regionCd) +// ]; +// setUnitWaterShedValue('0'); +// setFilteredUnitWaterShedData(newFilteredData); +// } +// } - // 중권역 세팅 - const initializeMiddleRegionData = (unitWaterShedCd: string) => { - if (unitWaterShedCd === '0') { - setMiddleRegionValue('0'); - setFilteredMiddleRegionData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectMiddleRegionData.filter((item: SelectDataType) => item.val.substring(0, 2) === unitWaterShedCd) - ]; - setMiddleRegionValue('0'); - setFilteredMiddleRegionData(newFilteredData); - } - } +// // 중권역 세팅 +// const initializeMiddleRegionData = (unitWaterShedCd: string) => { +// if (unitWaterShedCd === '0') { +// setMiddleRegionValue('0'); +// setFilteredMiddleRegionData([{ text: "전체", val: '0' }]); +// } else { +// const newFilteredData = [ +// { text: "전체", val: '0' }, +// ...selectMiddleRegionData.filter((item: SelectDataType) => item.val.substring(0, 2) === unitWaterShedCd) +// ]; +// setMiddleRegionValue('0'); +// setFilteredMiddleRegionData(newFilteredData); +// } +// } - // 환경청 세팅 - 시도 - const initializeCityDataByEnvPartSido = (envPartCd: string) => { - const foundEnvPart = selectEnvPartData.find((item: EnvPartSelectDataType) => item.val === envPartCd); - const cityArray = foundEnvPart?.adstDliStrCd.toString().split('|').join('').split(','); +// // 환경청 세팅 - 시도 +// const initializeCityDataByEnvPartSido = (envPartCd: string) => { +// const foundEnvPart = selectEnvPartData.find((item: EnvPartSelectDataType) => item.val === envPartCd); +// const cityArray = foundEnvPart?.adstDliStrCd.toString().split('|').join('').split(','); - // 시군구 데이터 - const envSigunData = selectSigunData.filter((item: SelectDataType) => cityArray?.includes(item.val)); +// // 시군구 데이터 +// const envSigunData = selectSigunData.filter((item: SelectDataType) => cityArray?.includes(item.val)); - // 환경청 시도 데이터 - const sidoArray = [...new Set(envSigunData.map((item: SelectDataType) => item.val.substring(0, 2)))]; - const envSidoData = selectSidoData.filter((item: SelectDataType) => sidoArray?.includes(item.val)); - setFilteredEnvPartSigunDataSelected(envSigunData); +// // 환경청 시도 데이터 +// const sidoArray = [...new Set(envSigunData.map((item: SelectDataType) => item.val.substring(0, 2)))]; +// const envSidoData = selectSidoData.filter((item: SelectDataType) => sidoArray?.includes(item.val)); +// setFilteredEnvPartSigunDataSelected(envSigunData); - setFilteredEnvPartSidoData([ - { text: "전체", val: '0', adstDliStrCd: '' }, - ...envSidoData.map((item: SelectDataType) => ({ text: item.text, val: item.val, adstDliStrCd: '' })) - ]); - } +// setFilteredEnvPartSidoData([ +// { text: "전체", val: '0', adstDliStrCd: '' }, +// ...envSidoData.map((item: SelectDataType) => ({ text: item.text, val: item.val, adstDliStrCd: '' })) +// ]); +// } - // 환경청 세팅 - 시군구 - const initializeCityDataByEnvPartSigun = (sidoCd: string) => { - const envSigunData = filteredEnvPartSigunDataSelected.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd); - setFilteredEnvPartSigunData([ - { text: "전체", val: '0' }, - ...envSigunData.map((item: SelectDataType) => ({ text: item.text, val: item.val })) - ]); - } +// // 환경청 세팅 - 시군구 +// const initializeCityDataByEnvPartSigun = (sidoCd: string) => { +// const envSigunData = filteredEnvPartSigunDataSelected.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd); +// setFilteredEnvPartSigunData([ +// { text: "전체", val: '0' }, +// ...envSigunData.map((item: SelectDataType) => ({ text: item.text, val: item.val })) +// ]); +// } - const onSelectValue = (val: string, type: string) => { - let selectedSido; - let selectedSigun; - let selectedEnvPartSido; - let selectedEnvPartSigun; +// const onSelectValue = (val: string, type: string) => { +// let selectedSido; +// let selectedSigun; +// let selectedEnvPartSido; +// let selectedEnvPartSigun; - switch (type) { - case 'part': - setPartValue(val); - if (setRtnPartValue) { - setRtnPartValue(val); - } - // 구분 - if (val == 'R') { - initializeMiddleRegionData('0'); - initializeUnitWaterShedData('0'); - } else if (val == 'G') { - setFilteredEnvPartData([ - { text: "전체", val: '0', adstDliStrCd: '' }, - ...selectEnvPartData.filter((item: EnvPartSelectDataType) => item.val !== null && item.adstDliStrCd !== '') - ]); - setEnvPartValue('0'); - initializeCityDataByEnvPartSido('0'); - } else { - initializeSigunData('0'); - onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); - } +// switch (type) { +// case 'part': +// setPartValue(val); +// if (setRtnPartValue) { +// setRtnPartValue(val); +// } +// // 구분 +// if (val == 'R') { +// initializeMiddleRegionData('0'); +// initializeUnitWaterShedData('0'); +// } else if (val == 'G') { +// setFilteredEnvPartData([ +// { text: "전체", val: '0', adstDliStrCd: '' }, +// ...selectEnvPartData.filter((item: EnvPartSelectDataType) => item.val !== null && item.adstDliStrCd !== '') +// ]); +// setEnvPartValue('0'); +// initializeCityDataByEnvPartSido('0'); +// } else { +// initializeSigunData('0'); +// onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); +// } - // 다른 selectbox 전체로 초기화 - onSelectValue(selectSidoData[0]?.val || '0', 'sido'); - onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); - break; - case 'sido': - setSidoValue(val); - selectedSido = selectSidoData.find(item => item.val === val); - setSidoText(selectedSido?.text || ''); - if (setRtnSidoValue) { - setRtnSidoValue(val); - } - if (setRtnSidoText) { - setRtnSidoText(selectedSido?.text || ''); - } - initializeSigunData(val); - onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); - break; - case 'sigun': - if (setRtnSigunValue) { - setRtnSigunValue(val); - } - setSigunValue(val); - selectedSigun = filteredSigunData.find(item => item.val === val); - if (setRtnSigunText) { - setRtnSigunText(selectedSigun?.text || ''); - } - setSigunText(selectedSigun?.text || ''); - break; +// // 다른 selectbox 전체로 초기화 +// onSelectValue(selectSidoData[0]?.val || '0', 'sido'); +// onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); +// break; +// case 'sido': +// setSidoValue(val); +// selectedSido = selectSidoData.find(item => item.val === val); +// setSidoText(selectedSido?.text || ''); +// if (setRtnSidoValue) { +// setRtnSidoValue(val); +// } +// if (setRtnSidoText) { +// setRtnSidoText(selectedSido?.text || ''); +// } +// initializeSigunData(val); +// onSelectValue(selectSigunData[0]?.val || '0', 'sigun'); +// break; +// case 'sigun': +// if (setRtnSigunValue) { +// setRtnSigunValue(val); +// } +// setSigunValue(val); +// selectedSigun = filteredSigunData.find(item => item.val === val); +// if (setRtnSigunText) { +// setRtnSigunText(selectedSigun?.text || ''); +// } +// setSigunText(selectedSigun?.text || ''); +// break; - // 유역 세팅 - case 'region': - setRegionValue(val); - if (setRtnRegionValue) { - setRtnRegionValue(val); - } - initializeUnitWaterShedData(val); - onSelectValue(selectUnitWaterShedData[0]?.val || '0', 'unitWaterShed'); - break; - case 'unitWaterShed': - setUnitWaterShedValue(val); - if (setRtnUnitWaterShedValue) { - setRtnUnitWaterShedValue(val); - } - initializeMiddleRegionData(val); - onSelectValue(selectMiddleRegionData[0]?.val || '0', 'middleRegion'); - break; - case 'middleRegion': - setMiddleRegionValue(val); - if (setRtnMiddleRegionValue) { - setRtnMiddleRegionValue(val); - } - break; +// // 유역 세팅 +// case 'region': +// setRegionValue(val); +// if (setRtnRegionValue) { +// setRtnRegionValue(val); +// } +// initializeUnitWaterShedData(val); +// onSelectValue(selectUnitWaterShedData[0]?.val || '0', 'unitWaterShed'); +// break; +// case 'unitWaterShed': +// setUnitWaterShedValue(val); +// if (setRtnUnitWaterShedValue) { +// setRtnUnitWaterShedValue(val); +// } +// initializeMiddleRegionData(val); +// onSelectValue(selectMiddleRegionData[0]?.val || '0', 'middleRegion'); +// break; +// case 'middleRegion': +// setMiddleRegionValue(val); +// if (setRtnMiddleRegionValue) { +// setRtnMiddleRegionValue(val); +// } +// break; - // 환경청 세팅 - case 'envPart': - setEnvPartValue(val); - if (setRtnEnvPartValue) { - setRtnEnvPartValue(val); - } - initializeCityDataByEnvPartSido(val); - onSelectValue(filteredEnvPartSidoData[0]?.val || '0', 'envPartSido'); - break; - case 'envPartSido': - setSidoValue(val); - selectedEnvPartSido = filteredEnvPartSidoData.find(item => item.val === val); - setSidoText(selectedEnvPartSido?.text || ''); - if (setRtnEnvPartSidoValue) { - setRtnEnvPartSidoValue(val); - } - initializeCityDataByEnvPartSigun(val); - onSelectValue(filteredEnvPartSigunData[0]?.val || '0', 'envPartSigun'); - break; - case 'envPartSigun': - setSigunValue(val); - selectedEnvPartSigun = filteredEnvPartSigunData.find(item => item.val === val); - setSigunText(selectedEnvPartSigun?.text || ''); - if (setRtnEnvPartSigunValue) { - setRtnEnvPartSigunValue(val); - } - break; - } - } +// // 환경청 세팅 +// case 'envPart': +// setEnvPartValue(val); +// if (setRtnEnvPartValue) { +// setRtnEnvPartValue(val); +// } +// initializeCityDataByEnvPartSido(val); +// onSelectValue(filteredEnvPartSidoData[0]?.val || '0', 'envPartSido'); +// break; +// case 'envPartSido': +// setSidoValue(val); +// selectedEnvPartSido = filteredEnvPartSidoData.find(item => item.val === val); +// setSidoText(selectedEnvPartSido?.text || ''); +// if (setRtnEnvPartSidoValue) { +// setRtnEnvPartSidoValue(val); +// } +// initializeCityDataByEnvPartSigun(val); +// onSelectValue(filteredEnvPartSigunData[0]?.val || '0', 'envPartSigun'); +// break; +// case 'envPartSigun': +// setSigunValue(val); +// selectedEnvPartSigun = filteredEnvPartSigunData.find(item => item.val === val); +// setSigunText(selectedEnvPartSigun?.text || ''); +// if (setRtnEnvPartSigunValue) { +// setRtnEnvPartSigunValue(val); +// } +// break; +// } +// } - // 리셋 함수 - const resetAllValues = () => { - setPartValue('A'); - setSidoValue('0'); - setSigunValue('0'); - setRegionValue('0'); - setUnitWaterShedValue('0'); - setMiddleRegionValue('0'); - setEnvPartValue('0'); +// // 리셋 함수 +// const resetAllValues = () => { +// setPartValue('A'); +// setSidoValue('0'); +// setSigunValue('0'); +// setRegionValue('0'); +// setUnitWaterShedValue('0'); +// setMiddleRegionValue('0'); +// setEnvPartValue('0'); - setFilteredSigunData([{ text: "전체", val: '0' }]); - setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]); - setFilteredMiddleRegionData([{ text: "전체", val: '0' }]); - setFilteredEnvPartData([{ text: "전체", val: '0', adstDliStrCd: '' }]); - setFilteredEnvPartSidoData([{ text: "전체", val: '0', adstDliStrCd: '' }]); - setFilteredEnvPartSigunData([{ text: "전체", val: '0' }]); +// setFilteredSigunData([{ text: "전체", val: '0' }]); +// setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]); +// setFilteredMiddleRegionData([{ text: "전체", val: '0' }]); +// setFilteredEnvPartData([{ text: "전체", val: '0', adstDliStrCd: '' }]); +// setFilteredEnvPartSidoData([{ text: "전체", val: '0', adstDliStrCd: '' }]); +// setFilteredEnvPartSigunData([{ text: "전체", val: '0' }]); - if (setRtnPartValue) setRtnPartValue('A'); - if (setRtnSidoValue) setRtnSidoValue('0'); - if (setRtnSigunValue) setRtnSigunValue('0'); - if (setRtnRegionValue) setRtnRegionValue('0'); - if (setRtnUnitWaterShedValue) setRtnUnitWaterShedValue('0'); - if (setRtnMiddleRegionValue) setRtnMiddleRegionValue('0'); - if (setRtnEnvPartValue) setRtnEnvPartValue('0'); - if (setRtnEnvPartSidoValue) setRtnEnvPartSidoValue('0'); - if (setRtnEnvPartSigunValue) setRtnEnvPartSigunValue('0'); - }; +// if (setRtnPartValue) setRtnPartValue('A'); +// if (setRtnSidoValue) setRtnSidoValue('0'); +// if (setRtnSigunValue) setRtnSigunValue('0'); +// if (setRtnRegionValue) setRtnRegionValue('0'); +// if (setRtnUnitWaterShedValue) setRtnUnitWaterShedValue('0'); +// if (setRtnMiddleRegionValue) setRtnMiddleRegionValue('0'); +// if (setRtnEnvPartValue) setRtnEnvPartValue('0'); +// if (setRtnEnvPartSidoValue) setRtnEnvPartSidoValue('0'); +// if (setRtnEnvPartSigunValue) setRtnEnvPartSigunValue('0'); +// }; - // 리셋 트리거 변경 감지 - useEffect(() => { - if (resetTrigger) { - resetAllValues(); - // 리셋 후 트리거를 false로 설정 - if (setRtnPartValue) { - setRtnPartValue('0'); - } - } - }, [resetTrigger]); +// // 리셋 트리거 변경 감지 +// useEffect(() => { +// if (resetTrigger) { +// resetAllValues(); +// // 리셋 후 트리거를 false로 설정 +// if (setRtnPartValue) { +// setRtnPartValue('0'); +// } +// } +// }, [resetTrigger]); - return ( - isShowPart ? ( - <div className="flex gap-5"> - <SelectBox className="w-auto whitespace-nowrap" label={'구분'} selectArray={isAdmin ? selectPartData.slice(0, 1) : selectPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'part')} value={partValue} selectClass={'w-32'} /> - {partValue === 'R' ? ( - <> - <SelectBox className="w-auto whitespace-nowrap" label={'유역'} selectArray={selectRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'region')} value={regionValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'단위유역'} selectArray={filteredUnitWaterShedData} onSelectValue={(val) => onSelectValue(val.toString(), 'unitWaterShed')} value={unitWaterShedValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'중권역'} selectArray={filteredMiddleRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'middleRegion')} value={middleRegionValue} selectClass={'w-44'} /> - </> - ) : partValue === 'G' ? ( - <> - <SelectBox className="w-auto whitespace-nowrap" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={sidoValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={sigunValue} selectClass={'w-44'} /> - </> - ) : ( - <> - <SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={selectSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={'w-44'} /> - <SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={'w-44'} /> - </> - )} - </div> - ) : ( - <div className="grid grid-cols-12 gap-5 w-11/12 m-4"> - {children} - </div> - ) - ) -} +// return ( +// isShowPart ? ( +// <div className="flex gap-5"> +// <SelectBox className="w-auto whitespace-nowrap" label={'구분'} selectArray={isAdmin ? selectPartData.slice(0, 1) : selectPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'part')} value={partValue} selectClass={'w-32'} /> +// {partValue === 'R' ? ( +// <> +// <SelectBox className="w-auto whitespace-nowrap" label={'유역'} selectArray={selectRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'region')} value={regionValue} selectClass={'w-44'} /> +// <SelectBox className="w-auto whitespace-nowrap" label={'단위유역'} selectArray={filteredUnitWaterShedData} onSelectValue={(val) => onSelectValue(val.toString(), 'unitWaterShed')} value={unitWaterShedValue} selectClass={'w-44'} /> +// <SelectBox className="w-auto whitespace-nowrap" label={'중권역'} selectArray={filteredMiddleRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'middleRegion')} value={middleRegionValue} selectClass={'w-44'} /> +// </> +// ) : partValue === 'G' ? ( +// <> +// <SelectBox className="w-auto whitespace-nowrap" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'w-44'} /> +// <SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={sidoValue} selectClass={'w-44'} /> +// <SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={sigunValue} selectClass={'w-44'} /> +// </> +// ) : ( +// <> +// <SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={selectSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={'w-44'} /> +// <SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={'w-44'} /> +// </> +// )} +// </div> +// ) : ( +// <div className="grid grid-cols-12 gap-5 w-11/12 m-4"> +// {children} +// </div> +// ) +// ) +// } -export { MapSearchFormLeft }; +// export { MapSearchFormLeft }; diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index e8641ca6c..3bb7cd9be 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -1,51 +1,29 @@ -import { useWrStore } from "@/app/store"; -import type { customPbnst, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload, tableData } from "@/components/lib/func/commom"; -import { Title, UiTable, UITab, ContentsDiv, ScrollArea } from '@common/business_components'; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import React, { useCallback, useState, useEffect } from 'react'; import NewWindowPortal from '@/app/map/newWindowPortal'; -import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; -import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; -import type { chgBuilding, customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; +import { useWrStore } from "@/app/store"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; +import type { customPbnst, 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 type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; import { fetchType, getFetch, postFectch } from "@/components/lib/api"; -import { useGisContext } from "@common/business_components/ui/map/Gis"; +import { excelDownload, tableData } from "@/components/lib/func/commom"; +import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; -import { set } from "react-hook-form"; +import { Title, UITab, UiTable } from '@common/business_components'; +import { useGisContext } from "@common/business_components/ui/map/Gis"; +import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; +import React, { useCallback, useEffect, useState } from 'react'; interface NewWindowPopupProps { featureData: any; - checkedLayers?: string[]; - checkedLayersData?: any[]; seletectedLayerNm?: string viewMode?: 'list' | 'detail' | 'nothing' onFeatureSelect: (data: any) => void; onClose: () => void; } -// 탭 -const TABS = [ - { val: "0", text: "재이용시설1" }, - { val: "1", text: "재이용시설2" }, - { val: "2", text: "재이용시설n" }, -]; - -// 데이터의 속성(key)을 사용자에게 보여줄 한글 이름으로 변환하기 위한 맵 -// 실제 데이터에 맞게 이 부분을 확장해야 합니다. -const propertyNameMap: { [key: string]: string } = { - fid: '고유 ID', - fcltNm: '시설명', - opertDe: '운영일자', - addr: '주소', - // ... 필요한 만큼 속성 매핑 추가 -}; - const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ featureData, - checkedLayers = [], - checkedLayersData = [], seletectedLayerNm, onFeatureSelect, onClose @@ -70,7 +48,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ pbnSttnInit, getFlcts } = useWrStore((state) => state); - const { fclts, pbnstSttnResCount} = pbnstSttn + const { fclts, pbnstSttnResCount } = pbnstSttn const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>() // 빗물재이용시설 변수 @@ -79,10 +57,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ ); let { rainSttnRes, rainSttnResCount } = rainSttn; const [rainTable, setRainTable] = useState<customRainBdst[]>(); - const [rainBdstChgProps, setRainBdstChgProps] = useState<{ - isOpen: boolean; - chBuilding: chgBuilding[]; - }>({ isOpen: false, chBuilding: [] }); const [rainPage, setRainPage] = useState(1) const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }); @@ -93,15 +67,12 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ let { rswtSttnRes, rswtSttnResCount } = rswtSttn; const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>(); const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false }); - const [rswtrBdstChgProps, setRswtrBdstChgProps] = useState<{ - isOpen: boolean; - chBuilding: chgBuilding[]; - }>({ isOpen: false, chBuilding: [] }); + const [rswtrPage, setRswtrPage] = useState(1); // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); - let { htdflSttnRes,htdflSttnResCount } = htdflSttn; + let { htdflSttnRes, htdflSttnResCount } = htdflSttn; const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [htdflPage, setHtdflPage] = useState(1) @@ -117,13 +88,12 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }>({ data: undefined }); const [hasuTable, setHasuTable] = useState<pubHasuType[]>(); const [hasuPage, setHasuPage] = useState<number>(1); - const [hasuRes,setHasuRes] = useState<number>() if (!featureData) return; ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// const getSelectedLayers = () => { let result = null; const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기 - let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수 + let featureLayer: { get: (key: string) => any }; // 피처가 속한 레이어를 찾기 위한 변수 layers.forEach((layer: any) => { const source = layer.getSource(); if (source && source.hasFeature && featureData @@ -152,10 +122,10 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ setFcltPk(featureCd); // 현재 호출된 featureCd 저장 fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd); } - else{ + else { featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) - detainSttn(featureCd,layerId) + detainSttn(featureCd, layerId) } setViewMode("detail") } @@ -176,14 +146,14 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ onClose() } }; - + // 재이용 현황 초기값 useEffect(() => { if (!pbnstSttn.isInit) { getFlcts() } }, [seletectedLayerNm, pbnstSttn.isInit]); - useEffect(()=>{ + useEffect(() => { pbnSttnInit("1", "15", { partValue: "A", sidoValue: '0', @@ -195,7 +165,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ sidoText: "", sigunText: "" }, String(new Date().getFullYear()), pbnstSttn.fclts); - },[fclts]) + }, [fclts]) useEffect(() => { setBdstTable(pbnstSttn.pbnstSttnRes); }, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]); @@ -237,7 +207,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ sigunText: "", }, "", - String(new Date().getFullYear()),fclts + String(new Date().getFullYear()), fclts ); }, []); const excelClick = useCallback(() => { @@ -263,9 +233,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ // setViewMode('detail') onFeatureSelect(rainTable[index]); onClose(); - } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { - if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) - setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); } } const detainSttn = async (featureCd: string, layerNm: string) => { @@ -274,13 +241,13 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ rainSttnRes = res setRainDetailModal({ isOpen: true, data: rainSttnRes[0] }); } - else if(layerNm == '중수도시설'){ - const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`) + else if (layerNm == '중수도시설') { + const res = await getFetch(fetchType.WR, `/reuseFc/waterreuseFc/1/20/0/${featureCd}`) rswtSttnRes = res console.log('중수도', res, featureCd) - setRswtrDetailModal({isOpen:true,data:rswtSttnRes[0]}) + setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }) } - else{ + else { const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`) htdflSttnRes = res setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); @@ -289,7 +256,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ useEffect(() => { if (!rainSttn.isInit) { - rainSttnInit(false,1, "20", "0", '', code.cityCd, code.sggCd); + rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd); } }, [rainSttn.isInit, rainSttnInit]); @@ -325,7 +292,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }, [code, rainSttnRes, rainSttn.rainSttHeadList]); useEffect(() => { - rainSttnSearch(false,rainPage, "20", '', '', code.cityCd, code.sggCd); + rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd); }, [rainPage]); ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// @@ -397,7 +364,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ }; useEffect(() => { if (!htdflSttn.isInit) { - initHtdfl(false,1, "20", "0", '', code.cityCd, code.sggCd); + initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd); } }, [htdflSttn.isInit, initHtdfl]); @@ -466,15 +433,15 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ layerId = seletectedLayerNm || ''; } //하수처리시설 - let isPrcsFclt = layerId == '하수처리시설' + const isPrcsFclt = layerId == '하수처리시설' // 재이용시설 - let isPbnst = layerId == '하수재이용시설'; + const isPbnst = layerId == '하수재이용시설'; // 빗물이용시설 - let isRain = layerId == '빗물이용시설'; + const isRain = layerId == '빗물이용시설'; // 중수도시설 - let isRswt = layerId == '중수도시설'; + const isRswt = layerId == '중수도시설'; // 온배수시설 - let isHtdfl = layerId == '온배수시설'; + const isHtdfl = layerId == '온배수시설'; if (isPrcsFclt) { if (viewMode == 'list') { return ( diff --git a/apps/wr/app/map/newWindowPortal.tsx b/apps/wr/app/map/newWindowPortal.tsx index 6bc1cd047..fc28495ad 100644 --- a/apps/wr/app/map/newWindowPortal.tsx +++ b/apps/wr/app/map/newWindowPortal.tsx @@ -81,7 +81,7 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti onCloseRef.current(); // onClose(); } - }, [onClose, title]); + }, [handleUnload, onClose, title]); // `createPortal`을 사용해 children을 새 창의 container div에 렌더링합니다. return container ? createPortal(children, container) : null; diff --git a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx b/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx deleted file mode 100644 index 79e1bf009..000000000 --- a/apps/wr/app/map/pbnstPrfmncSttnPopup.tsx +++ /dev/null @@ -1,582 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; -import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SelectBox, UiTable, type ChartConfig } from "@common/business_components"; -import ListDiv from "@common/business_components/ui/list_div"; -import { useEffect, useState } from "react"; -import { Toaster } from "react-hot-toast"; - -interface PbnstPrfmncSttnPopupProps { - isVisible?: boolean; -} - -export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSttnPopupProps) { - const { pbnstPrfmncSttn, pbnstPrfmncInit, prfmnc } = useWrStore((state) => state); - const { monthHeadList } = prfmnc - const { prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn; - const [year, setYear] = useState<string>(String(new Date().getFullYear())); - const [chartConfig, setChartConfig] = useState<ChartConfig>({}); - const [chartData, setChartData] = useState<dnChartForm[]>([]); - const [dnInUsage, setDnInUsage] = useState<dnChartForm[]>([]); - const [dnInChartConfig, setDnInChartConfig] = useState<ChartConfig>({}); - const [dnOutUsage, setDnOutUsage] = useState<dnChartForm[]>([]); - const [dnOutChartConfig, setDnOutChartConfig] = useState<ChartConfig>({}); - const [barData, setBarData] = useState<barChartForm[]>([]); - const [barChartConfig, setBarChartConfig] = useState<ChartConfig>({}); - const [prfData, setPrfData] = useState<any[]>(); - const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({}); - const [lnOutChartConfig, setLnOutChartConfig] = useState<ChartConfig>({}); - const [inLineData, setInLineData] = useState<{ - chartData1: lineChartDataProps[]; - chartData2: lineChartDataProps[]; - chartData3: lineChartDataProps[]; - chartData4: lineChartDataProps[]; - chartData5: lineChartDataProps[]; - chartData6: lineChartDataProps[]; - chartData7: lineChartDataProps[]; - chartData8: lineChartDataProps[]; - chartData9: lineChartDataProps[]; - }>(); - // const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({}); - const [outLineData, setOutLineData] = useState<{ - chartData1: lineChartDataProps[]; - chartData2: lineChartDataProps[]; - chartData3: lineChartDataProps[]; - chartData4: lineChartDataProps[]; - chartData5: lineChartDataProps[]; - chartData6: lineChartDataProps[]; - }>(); - - - - type dnChartForm = { label: string, val: number, fill?: string }; - type barChartForm = { label: string, "장내용수": number, "장외용수": number }; - type lineChartDataProps = { label: string, val: number, color: string }; - - const prfTableData = (prfList: PrfType[], year: string) => { - const inUsageData = initValInUsage; - const outUsageData = initValOutUsage; - - const inSubtotal = subTotalObj; - const outSubtotal = subTotalObj; - - console.log(' prfList ', prfList) - const prfFilter = prfList?.filter((e) => e.ym.slice(0, 4) === year) - if (prfList && prfFilter.length > 0) { - prfList?.forEach((prfItem) => { - const month = Number(prfItem?.ym?.slice(4)); // "MM" - const monthKey = `${month}월`; - - inUsageData.forEach((inData: any) => { - const usageKey = inData.usage; - const value = (prfItem as any)[usageKey] ?? 0; - - inData[monthKey] = value; - inData.total += value; - - if (inSubtotal && usageKey !== "subtotal") { - (inSubtotal as any)[monthKey] = - ((inSubtotal as any)[monthKey] ?? 0) + value; - inSubtotal.total += value; - } - }); - - outUsageData.forEach((outData: any) => { - const usageKey = outData.usage; - const value = (prfItem as any)[usageKey] ?? 0; - - outData[monthKey] = value; - outData.total += value; - - if (usageKey !== "subtotal") { - (outSubtotal as any)[monthKey] = - ((outSubtotal as any)[monthKey] ?? 0) + value; - outSubtotal.total += value; - } - }); - }); - inUsageData.push(inSubtotal); - outUsageData.push(outSubtotal); - const usageTotalObj: { [key: string]: any } = totalObj; - for (const key in usageTotalObj) { - if (["usage", "gubun", "edit"].includes(key)) continue; - const val = - (Number((inSubtotal as any)[key]) || 0) + - (Number((outSubtotal as any)[key]) || 0); - - (usageTotalObj as any)[key] = val; - } - const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; - setPrfData(tableData); - - } else { - setPrfData([]); - } - } - useEffect(() => { - let wshwtr = 0; - let coolUswtr = 0; - let cleanUswtr = 0; - let drwtUswtr = 0; - let dltnUswtr = 0; - let ithlRswtr = 0; - let ithlEtcUswtr = 0; - let cleanToilUswtr = 0; - let resn = 0; - let lndwtr = 0; - let hydUswtr = 0; - let ugwtChr = 0; - let farmUswtr = 0; - let rvrKeepUswtr = 0; - let indstUswtr = 0; - if (rawData) { - rawData.forEach((item) => { - prfTableData(item.prfList, year); - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - - wshwtr += element.wshwtr; //세척수 - coolUswtr += element.coolUswtr; //냉각수 - cleanUswtr += element.cleanUswtr; //청소수 - drwtUswtr += element.drwtUswtr; //식수대 - dltnUswtr += element.dltnUswtr //희석용수 - ithlRswtr += element.ithlRswtr //중수도 - ithlEtcUswtr += element.ithlEtcUswtr //기타 - cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 - resn += element.resn //세척살수용수 - - lndwtr += element.lndwtr; //조경용수 - hydUswtr += element.hydUswtr; //친수용수 - ugwtChr += element.ugwtChr; //지하수충전 - farmUswtr += element.farmUswtr //농업용수 - rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 - indstUswtr += element.indstUswtr //공업용수 - - }); - }) - const data: dnChartForm[] = [] - data?.push({ label: "세척수", val: wshwtr, fill: "red" }) - data?.push({ label: "냉각수", val: coolUswtr, fill: "orange" }) - data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) - data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) - data?.push({ label: "희석용수", val: dltnUswtr, fill: "skyblue" }) - data?.push({ label: "중수도", val: ithlRswtr, fill: "blue" }) - data?.push({ label: "기타", val: ithlEtcUswtr, fill: "purple" }) - data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "red" }) - data?.push({ label: "세척살수용수", val: resn, fill: "orange" }) - data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) - data?.push({ label: "친수용수", val: hydUswtr, fill: "green" }) - data?.push({ label: "지하수충전", val: ugwtChr, fill: "skyblue" }) - data?.push({ label: "농업용수", val: farmUswtr, fill: "blue" }) - data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "purple" }) - data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) - setChartData(data); - } - }, [rawData, year]) - - - useEffect(() => { - const newChartConfig = chartData.reduce((config, element) => { - config[element.label] = { - label: element.label, - fill: element.fill - }; - return config; - }, {} as Record<string, { label: string; fill?: string }>) satisfies ChartConfig; - setChartConfig(newChartConfig); - }, [chartData]); - - // 장내용수 도넛차트 - useEffect(() => { - let wshwtr = 0; - let coolUswtr = 0; - let cleanUswtr = 0; - let drwtUswtr = 0; - let dltnUswtr = 0; - let ithlRswtr = 0; - let ithlEtcUswtr = 0; - let cleanToilUswtr = 0; - let resn = 0; - if (rawData) { - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - - wshwtr += element.wshwtr; //세척수 - coolUswtr += element.coolUswtr; //냉각수 - cleanUswtr += element.cleanUswtr; //청소수 - drwtUswtr += element.drwtUswtr; //식수대 - dltnUswtr += element.dltnUswtr //희석용수 - ithlRswtr += element.ithlRswtr //중수도 - ithlEtcUswtr += element.ithlEtcUswtr //기타 - cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 - resn += element.resn //세척살수용수 - }); - }) - const data: dnChartForm[] = [] - data?.push({ label: "세척수", val: wshwtr, fill: "yellow" }) - data?.push({ label: "냉각수", val: coolUswtr, fill: "green" }) - data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) - data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) - data?.push({ label: "희석용수", val: dltnUswtr, fill: "yellow" }) - data?.push({ label: "중수도", val: ithlRswtr, fill: "green" }) - data?.push({ label: "기타", val: ithlEtcUswtr, fill: "yellow" }) - data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "green" }) - data?.push({ label: "세척살수용수", val: resn, fill: "yellow" }) - setDnInUsage(data); - } - }, [rawData, year]) - - useEffect(() => { - const newChartConfig = dnInUsage.reduce((config, element) => { - config[element.label] = { - label: element.label, - fill: element.fill - }; - return config; - }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; - setDnInChartConfig(newChartConfig); - }, [dnInUsage]); - - // 장외용수 도넛차트 - useEffect(() => { - let lndwtr = 0; - let hydUswtr = 0; - let ugwtChr = 0; - let farmUswtr = 0; - let rvrKeepUswtr = 0; - let indstUswtr = 0; - if (rawData) { - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - lndwtr += element.lndwtr; //조경용수 - hydUswtr += element.hydUswtr; //친수용수 - ugwtChr += element.ugwtChr; //지하수충전 - farmUswtr += element.farmUswtr //농업용수 - rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 - indstUswtr += element.indstUswtr //공업용수 - - }); - }) - const data: dnChartForm[] = [] - data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) - data?.push({ label: "친수용수", val: hydUswtr, fill: "black" }) - data?.push({ label: "지하수충전", val: ugwtChr, fill: "yellow" }) - data?.push({ label: "농업용수", val: farmUswtr, fill: "black" }) - data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "yellow" }) - data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) - setDnOutUsage(data); - } - }, [rawData, year]) - - useEffect(() => { - const newChartConfig = dnOutUsage.reduce((config, element) => { - config[element.label] = { - label: element.label, - fill: element.fill - }; - return config; - }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; - setDnOutChartConfig(newChartConfig); - }, [dnOutUsage]); - - //월별 장내외 용수 총 실적 막대차트 - useEffect(() => { - let wshwtr = 0; - let coolUswtr = 0; - let cleanUswtr = 0; - let drwtUswtr = 0; - let dltnUswtr = 0; - let ithlRswtr = 0; - let ithlEtcUswtr = 0; - let cleanToilUswtr = 0; - let resn = 0; - let lndwtr = 0; - let hydUswtr = 0; - let ugwtChr = 0; - let farmUswtr = 0; - let rvrKeepUswtr = 0; - let indstUswtr = 0; - let inUsageSum = 0; - let outUsageSum = 0; - - - if (rawData) { - const data: barChartForm[] = [] - rawData.forEach((item) => { - item.prfList - .filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - - wshwtr = element.wshwtr; //세척수 - coolUswtr = element.coolUswtr; //냉각수 - cleanUswtr = element.cleanUswtr; //청소수 - drwtUswtr = element.drwtUswtr; //식수대 - dltnUswtr = element.dltnUswtr //희석용수 - ithlRswtr = element.ithlRswtr //중수도 - ithlEtcUswtr = element.ithlEtcUswtr //기타 - cleanToilUswtr = element.cleanToilUswtr //청소화장실용수 - resn = element.resn //세척살수용수 - - lndwtr = element.lndwtr; //조경용수 - hydUswtr = element.hydUswtr; //친수용수 - ugwtChr = element.ugwtChr; //지하수충전 - farmUswtr = element.farmUswtr //농업용수 - rvrKeepUswtr = element.rvrKeepUswtr //하천등유지용수 - indstUswtr = element.indstUswtr //공업용수 - - inUsageSum = wshwtr + coolUswtr + cleanUswtr + drwtUswtr + dltnUswtr + ithlRswtr + ithlEtcUswtr + cleanToilUswtr + resn; - outUsageSum = lndwtr + hydUswtr + ugwtChr + farmUswtr + rvrKeepUswtr + indstUswtr; - - const month = Number(element.ym.slice(4, 6)) - data.push({ label: `${month}월`, "장내용수": inUsageSum, "장외용수": outUsageSum }) - - }, - ); - - }) - - setBarData(data); - } - }, [rawData, year]) - - useEffect(() => { - const newChartConfig = barData.reduce((config, element) => { - config[element.label] = { - label: element.label, - }; - return config; - - }, {} as Record<string, { label: string }>) satisfies ChartConfig; - setBarChartConfig(newChartConfig); - }, [barData]); - - //월별 장내 용수 실적 라인차트 - useEffect(() => { - - if (rawData) { - const wshwtrData: lineChartDataProps[] = [] - const coolUswtrData: lineChartDataProps[] = [] - const cleanUswtrData: lineChartDataProps[] = [] - const drwtUswtrData: lineChartDataProps[] = [] - const dltnUswtrData: lineChartDataProps[] = [] - const ithlRswtrData: lineChartDataProps[] = [] - const ithlEtcUswtrData: lineChartDataProps[] = [] - const cleanToilUswtrData: lineChartDataProps[] = [] - const resnData: lineChartDataProps[] = [] - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - const month = Number(element.ym.slice(4, 6)) - wshwtrData.push({ label: `${month}월`, val: element.wshwtr, color: "red" }) - coolUswtrData.push({ label: `${month}월`, val: element.coolUswtr, color: "red" }) - cleanUswtrData.push({ label: `${month}월`, val: element.cleanUswtr, color: "red" }) - drwtUswtrData.push({ label: `${month}월`, val: element.drwtUswtr, color: "red" }) - dltnUswtrData.push({ label: `${month}월`, val: element.dltnUswtr, color: "red" }) - ithlRswtrData.push({ label: `${month}월`, val: element.ithlRswtr, color: "red" }) - ithlEtcUswtrData.push({ label: `${month}월`, val: element.ithlEtcUswtr, color: "red" }) - cleanToilUswtrData.push({ label: `${month}월`, val: element.cleanToilUswtr, color: "red" }) - resnData.push({ label: `${month}월`, val: element.resn, color: "red" }) - - }, - ); - }) - const rtndata = { - chartData1: wshwtrData, - chartData2: coolUswtrData, - chartData3: cleanUswtrData, - chartData4: drwtUswtrData, - chartData5: dltnUswtrData, - chartData6: ithlRswtrData, - chartData7: ithlEtcUswtrData, - chartData8: cleanToilUswtrData, - chartData9: resnData - } - - setInLineData(rtndata) - } - }, [rawData, year]) - - useEffect(() => { - if (inLineData?.chartData1) { - const newChartConfig = { - chartData1: { - label: '세척수', - color: "red", - }, - chartData2: { - label: '냉각수', - color: "orange", - }, - chartData3: { - label: '청소수', - color: "yellow", - }, - chartData4: { - label: '식수대', - color: "pink", - }, - chartData5: { - label: '희석용수', - color: "purple", - }, - chartData6: { - label: '중수도', - color: "green", - }, - chartData7: { - label: '기타', - color: "blue", - }, - chartData8: { - label: '청소화장실용수', - color: "magenta", - }, - chartData9: { - label: '세척살수용수', - color: "skyblue", - }, - } satisfies ChartConfig; - setLnInChartConfig(newChartConfig); - } - }, [inLineData]); - - //월별 장외 용수 실적 라인차트 - useEffect(() => { - if (rawData) { - const lndwtrData: lineChartDataProps[] = [] - const hydUswtrData: lineChartDataProps[] = [] - const ugwtChrData: lineChartDataProps[] = [] - const farmUswtrData: lineChartDataProps[] = [] - const rvrKeepUswtrData: lineChartDataProps[] = [] - const indstUswtrData: lineChartDataProps[] = [] - rawData.forEach((item) => { - item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => { - const month = Number(element.ym.slice(4, 6)) - lndwtrData.push({ label: `${month}월`, val: element.lndwtr, color: "red" }) - hydUswtrData.push({ label: `${month}월`, val: element.hydUswtr, color: "red" }) - ugwtChrData.push({ label: `${month}월`, val: element.ugwtChr, color: "red" }) - farmUswtrData.push({ label: `${month}월`, val: element.farmUswtr, color: "red" }) - rvrKeepUswtrData.push({ label: `${month}월`, val: element.rvrKeepUswtr, color: "red" }) - indstUswtrData.push({ label: `${month}월`, val: element.indstUswtr, color: "red" }) - }, - ); - }) - setOutLineData({ - chartData1: lndwtrData, - chartData2: hydUswtrData, - chartData3: ugwtChrData, - chartData4: farmUswtrData, - chartData5: rvrKeepUswtrData, - chartData6: indstUswtrData, - }) - } - }, [rawData, year]) - - useEffect(() => { - if (outLineData?.chartData1) { - const newChartConfig = { - chartData1: { - label: '조경용수', - color: "red", - }, - chartData2: { - label: '친수용수', - color: "orange", - }, - chartData3: { - label: '지하수충전', - color: "yellow", - }, - chartData4: { - label: '농업용수', - color: "green", - }, - chartData5: { - label: '하천등유지용수', - color: "blue", - }, - chartData6: { - label: '공업용수', - color: "purple", - }, - } satisfies ChartConfig; - setLnOutChartConfig(newChartConfig); - } - }, [outLineData]); - - useEffect(() => { - if (!pbnstPrfmncSttn.isInit) { - pbnstPrfmncInit("1", "11"); - } - }, [pbnstPrfmncSttn.isInit, pbnstPrfmncInit]); - - return ( - <> - <ContentsDiv> - <ListDiv> - <hr /> - <h3 className="mt-4 ml-2 text-2xl font-medium text-label">하수재이용실적 상세현황</h3> - - <SelectBox - className="w-1/12 text-2xl mt-4 ml-2" - label="연도" - selectClass={""} - selectArray={selectYearList} - value={year} - onSelectValue={(val: string | number) => setYear(String(val))} /> - <h1 className="mt-4 ml-2">장내·외 용도별 하수재이용실적 현황(계)</h1> - - <div className="flex"> - <div className="w-1/3"> - <MainChart chartConfig={chartConfig} chartData={chartData} chartTitle={"장내·외 용수 총 실적"} chartForm={CHART_FORM.DN} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={dnInChartConfig} chartData={dnInUsage} chartTitle={"장내용수 실적"} chartForm={CHART_FORM.DN} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={dnOutChartConfig} chartData={dnOutUsage} chartTitle={"장외용수 실적"} chartForm={CHART_FORM.DN} /> - </div> - </div> - <h1 className="">장내·외 월별 하수재이용실적 현황</h1> - <div className="flex"> - <div className="w-1/3"> - <MainChart chartConfig={barChartConfig} chartData={barData} chartTitle={"월별 장내·외 용수 총 실적"} chartForm={CHART_FORM.DOUBLEBAR} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={lnInChartConfig} chartData={inLineData} chartTitle={"월별 장내 용수 실적"} chartForm={CHART_FORM.LINE} /> - </div> - <div className="w-1/3"> - <MainChart chartConfig={lnOutChartConfig} chartData={outLineData} chartTitle={"월별 장외 용수 총 실적"} chartForm={CHART_FORM.LINE} /> - </div> - </div> - {/* 하수재이용실적 현황 - 조건부 렌더링 */} - {isVisible && ( - <> - <h1 className="">하수재이용실적 현황</h1> - <ListDiv className="col-span-8 pr-6 "> - <ScrollArea className="h-[60vh]"> - <div className="card-header"> - <h3 className="text-2xl font-medium text-label"> - {"하수처리수재이용 실적(m3) 등록결과"} - </h3> - </div> - - <UiTable - headName={undefined} - tableData={prfData || []} - headlist={monthHeadList} - pageSize={0} - total={0} - cellClick={undefined} - onPageChange={function (): void { - throw new Error("Function not implemented."); - }}> - </UiTable> - </ScrollArea> - </ListDiv> - </> - )} - </ListDiv> - </ContentsDiv> - <Toaster position="top-center" /> - </> - ) -} diff --git a/apps/wr/app/map/rainPrfmncSttnPopup.tsx b/apps/wr/app/map/rainPrfmncSttnPopup.tsx deleted file mode 100644 index 7449772e8..000000000 --- a/apps/wr/app/map/rainPrfmncSttnPopup.tsx +++ /dev/null @@ -1,410 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { - rainZod, - selectClass, - type customRainBdst, -} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; -import { - formatCommaNumber, - handleCommaNumberChange, -} from "@/components/lib/func/commom"; -import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; -import { DatePicker, FormUi } from "@common/business_components"; -import { Form, FormField, SelectBox } from "@common/business_components/ui"; -import { Input } from "@common/components/ui"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { z } from "zod"; - -export default function RainPrfmncSttnPopup({ - rainForm, - isModal, -}: { - rainForm: customRainBdst; - isModal: boolean; -}) { - const { code, rainBdstReg, rainBdstUpdate } = useWrStore( - (state) => state - ); - const { rainFcltCd } = code; - const defaultValues: z.infer<typeof rainZod> = rainZod.parse({}); - - const form = useForm<z.infer<typeof rainZod>>({ - resolver: zodResolver(rainZod), - defaultValues: defaultValues, - }); - - const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn] = form.watch([ - "reuseBuilding.0.grntchBdstCertYn", - "reuseBuilding.0.instlCstSprtYn", - "reuseBuilding.0.rainyObj.filtrTrtmfctYn", - ]); - - const cleanRainData = (raw: any): z.infer<typeof rainZod> => { - return { - ...raw, - frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null), - archChgPrmsnDt: raw?.archChgPrmsnDt - ? new Date(raw?.archChgPrmsnDt) - : null, - reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({ - ...item, - instlCmptnDt: new Date(item?.instlCmptnDt), - operMngCd: item?.operMngCd ?? "", // null → "" - grntchBdstCertYr: - typeof item?.grntchBdstCertYr === "string" - ? item?.grntchBdstCertYr - : "", // null → "" - rainObj: { - ...item?.rainObj, - }, - })), - }; - }; - - useEffect(() => { - if (grntchBdstCertYn === "N") { - form.setValue("reuseBuilding.0.grntchBdstCertYr", ""); - form.setValue("reuseBuilding.0.grntchBdstCertNo", ""); - form.setValue("reuseBuilding.0.grntchBdstCertGrd", ""); - } else if (instlCstSprtYn === "N") { - form.setValue("reuseBuilding.0.instlCstSprtAmt", 0); - } else if (filtrTrtmfctYn === "N") { - form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctCpct", 0); - form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctPrs", ""); - } - }, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn]); - - useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); - - const onSubmit = (values: z.infer<typeof rainZod>) => { - if (isModal) { - rainBdstReg(values, "41"); - } else { - rainBdstUpdate(values, "41"); - } - }; - - useEffect(() => { - if (rainZod) form.reset(cleanRainData(rainForm)); - }, [rainForm]); - - - return ( - <div className="!mx-[1.6rem] !p-0r"> - <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> - <div> - <div className="grid grid-cols-12 flex items-center card-header"> - <h1 className="text-2xl font-medium text-label col-span-10"> - {isModal ? "건축물 운영정보" : "빗물이용시설 정보"} - </h1> - </div> - </div> - {isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>} - {isModal ? ( - <h1 className="pl-3 text-xl col-span-10 mt-4"> - 빗물이용시설 정보{" "} - </h1> - ) : ( - <></> - )} - <h1 className={formH1Class}> - 기본정보 - </h1> - - <div className="grid grid-cols-4 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCmptnDt" - render={({ field }) => ( - <FormUi label="설치완료일"> - <DatePicker - mode="single" - field={{ - value: - field.value && !isNaN(new Date(field.value).getTime()) - ? new Date(field.value) - : new Date(), // Provide a default Date value - onChange: (date) => field.onChange(date), - }} - selectClass={"w-full"} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCst" - render={({ field }) => ( - <FormUi label="설치비"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - <div className=""> - <h1 className={formH1Class}> - 빗물이용시설 정보 - </h1> - </div> - <div> - <h2 className={formH2Class}>집수면</h2> - </div> - <div className="grid grid-cols-10 gap-4 mt-4 "> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.pntfColKnd" - render={({ field }) => ( - <FormUi label="종류"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={rainFcltCd} - onSelectValue={field.onChange} - value={field.value ?? rainFcltCd[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.pntfColArea" - render={({ field }) => ( - <FormUi label="면적(m³)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - /> - </FormUi> - )} - /> - </div> - </div> - - <div> - <h2 className={formH2Class}>여과 등 처리시설</h2> - </div> - <div className="grid grid-cols-12 gap-2 mt-4"> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.filtrTrtmfctYn" - render={({ field }) => ( - <FormUi label="유무"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.filtrTrtmfctCpct" - render={({ field }) => ( - <FormUi label="용량(m³/일)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rainyObj.filtrTrtmfctPrs" - render={({ field }) => ( - <FormUi label="처리공정"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - <div className=" my-2"> - <h1 className={formH1Class}> - 인센티브 정보 - </h1> - </div> - <div> - <h2 className={formH2Class}>설치비 지원</h2> - </div> - <div className="grid grid-cols-10 gap-2 mt-4"> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtYn" - render={({ field }) => ( - <FormUi label="지원 여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-5"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtAmt" - render={({ field }) => ( - <FormUi label="지원금액(원)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div> - <h2 className={formH2Class}>녹색건축물 인증</h2> - </div> - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYn" - render={({ field }) => ( - <FormUi label="인증여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYr" - render={({ field }) => ( - <FormUi label="인증년도"> - <Input - className={'w-full !text-xl'} - placeholder="2024" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 "> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertNo" - render={({ field }) => ( - <FormUi label="인증번호"> - <Input - className={'w-full !text-xl'} - placeholder="ab1234678" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertGrd" - render={({ field }) => ( - <FormUi label="인증등급"> - <Input - className={'w-full !text-xl'} - placeholder="A" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - </form> - </Form> - </div> - ); -} diff --git a/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx b/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx deleted file mode 100644 index 161860c10..000000000 --- a/apps/wr/app/map/rswtrPrfmncSttnPopup.tsx +++ /dev/null @@ -1,403 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { - rswtZod, - type customRswtBdst, -} from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; -import { formH1Class, formH2Class } from "@/components/lib/class/comClass"; -import { - formatCommaNumber, - handleCommaNumberChange, -} from "@/components/lib/func/commom"; -import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg"; -import { - DatePicker, - Form, - FormField, - FormUi, - SelectBox, -} from "@common/business_components/ui"; -import { Input } from "@common/components/ui"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { z } from "zod"; - -export default function RswtrPrfmncsSttnPopup({ - rswtForm, - isModal, -}: { - rswtForm: customRswtBdst; - isModal: boolean; -}) { - const { code, rswtBdstUpdate, rswtBdstReg } = useWrStore( - (state) => state - ); - - const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({}); - - const form = useForm<z.infer<typeof rswtZod>>({ - resolver: zodResolver(rswtZod), - defaultValues: defaultValues, - }); - - const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs] = form.watch([ - "reuseBuilding.0.grntchBdstCertYn", - "reuseBuilding.0.instlCstSprtYn", - "reuseBuilding.0.rswtrObj.filtrTrtmfctProcs", - ]); - - const onSubmit = (values: z.infer<typeof rswtZod>) => { - if (isModal) { - rswtBdstReg(values, "41"); - } else { - rswtBdstUpdate(values, "41"); - } - }; - const cleanRswtData = (raw: any): z.infer<typeof rswtZod> => { - return { - ...raw, - frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null), - archChgPrmsnDt: raw?.archChgPrmsnDt - ? new Date(raw?.archChgPrmsnDt) - : null, - reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({ - ...item, - instlCmptnDt: new Date(item?.instlCmptnDt), - operMngCd: item?.operMngCd ?? "", // null → "" - grntchBdstCertYr: - typeof item?.grntchBdstCertYr === "string" - ? item?.grntchBdstCertYr - : "", // null → "" - rswtrObj: { - ...item?.rswtrObj, - }, - })), - }; - }; - - useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); - - useEffect(() => { - console.log("filtrTrtmfctProcs ", filtrTrtmfctProcs); - if (grntchBdstCertYn === "N") { - form.setValue("reuseBuilding.0.grntchBdstCertYr", ""); - form.setValue("reuseBuilding.0.grntchBdstCertNo", ""); - form.setValue("reuseBuilding.0.grntchBdstCertGrd", ""); - } else if (instlCstSprtYn === "N") { - form.setValue("reuseBuilding.0.instlCstSprtAmt", 0); - } - }, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs]); - - useEffect(() => { - if (rswtZod) form.reset(cleanRswtData(rswtForm)); - }, [rswtForm]); - - return ( - <div className="!mx-[1.6rem] !p-0r"> - <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> - {/* <div className="flex justify-between items-center mx-3"> */} - <div> - <div className="grid grid-cols-12 flex items-center card-header"> - <h1 className="text-2xl font-medium text-label col-span-10"> - 건축물 운영정보 - </h1> - </div> - </div> - - {isModal && rswtForm != undefined ? <BdstReg form={form} /> : <></>} - {isModal ? ( - <h1 className="pl-3 text-xl col-span-10 mt-4 "> - 중수도 시설 정보{" "} - </h1> - ) : ( - <></> - )} - <h1 className={formH1Class}>기본정보</h1> - <div className="grid grid-cols-4 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCmptnDt" - render={({ field }) => ( - <FormUi label="설치완료일"> - <DatePicker - mode="single" - field={{ - value: - field.value && !isNaN(new Date(field.value).getTime()) - ? new Date(field.value) - : new Date(), // Provide a default Date value - onChange: (date) => field.onChange(date), - }} - selectClass={"w-full"} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCst" - render={({ field }) => ( - <FormUi label="설치비"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - <div className="grid grid-cols-4 gap-2 mt-4"> - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.wtrUsqty" - render={({ field }) => ( - <FormUi label="물사용량(m³)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-2"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.oblgTrgtWtrUsqty" - render={({ field }) => ( - <FormUi label="의무대상 물사용량(m³)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - <div className=" my-4"> - <h1 className={formH1Class}>중수도 시설 정보</h1> - </div> - - <div className="grid grid-cols-12 gap-1 mt-4"> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.filtrTrtmfctCpct" - render={({ field }) => ( - <FormUi label="처리시설 용량"> - <Input - className={'w-full !text-xl'} - placeholder="0" - type="number" - value={field.value ?? ""} - onChange={(e)=>{field.onChange(Number(e.target.value))} } - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.orgwtKndCd" - render={({ field }) => ( - <FormUi label="원수 종류"> - <SelectBox - className={""} - label={""} - selectClass={selectClass} - selectArray={code.orgwtKndCd} - onSelectValue={field.onChange} - value={field.value ?? code.orgwtKndCd[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="reuseBuilding.0.rswtrObj.filtrTrtmfctProcs" - render={({ field }) => ( - <FormUi label="주요처리공정"> - <Input - className={'w-full !text-xl'} - placeholder="주요처리공정" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - - <div className=" my-2"> - <h1 className={formH1Class}>인센티브 정보</h1> - </div> - <div> - <h2 className={formH2Class}>설치비 지원</h2> - </div> - <div className="grid grid-cols-2 gap-2 mt-4"> - <div className="col-span-1"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtYn" - render={({ field }) => ( - <FormUi label="설치비 지원여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-1"> - <FormField - control={form.control} - name="reuseBuilding.0.instlCstSprtAmt" - render={({ field }) => ( - <FormUi label="지원금액(원)"> - <Input - className={'w-full !text-xl'} - placeholder="1,000,000" - type="text" - onChange={(e) => { - handleCommaNumberChange(e, field.onChange); - }} - value={formatCommaNumber(field.value)} - readOnly={instlCstSprtYn !== "Y"} - /> - </FormUi> - )} - /> - </div> - </div> - - <div> - <h2 className={formH2Class}>녹색건축물 인증</h2> - </div> - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYn" - render={({ field }) => ( - <FormUi label="인증여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={field.onChange} - value={field.value ?? code.yn[0]?.val} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertYr" - render={({ field }) => ( - <FormUi label="인증년도"> - <Input - className={'w-full !text-xl'} - placeholder="2024" - type="text" - {...field} - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertNo" - render={({ field }) => ( - <FormUi label="인증번호"> - <Input - className={'w-full !text-xl'} - placeholder="ab1234678" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="reuseBuilding.0.grntchBdstCertGrd" - render={({ field }) => ( - <FormUi label="인증등급"> - <Input - className={'w-full !text-xl'} - placeholder="A" - type="" - value={field.value ?? ""} - onChange={field.onChange} - readOnly={true} - /> - </FormUi> - )} - /> - </div> - </div> - </form> - </Form> - </div> - ); -} From 802204fa67fa5a17729fd16b982c26cddc05748d Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 14 Jul 2025 14:11:59 +0900 Subject: [PATCH 108/159] =?UTF-8?q?=EB=B9=8C=EB=93=9C=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=A4=91=20/=EC=8B=9C=EC=84=A4=ED=98=84?= =?UTF-8?q?=ED=99=A9=20=EC=9E=A1=EC=95=84=EC=95=BC=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 19 ++--- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 2 - .../fcltReg/pbnstReg/buseReg/bugRegForm.tsx | 1 - .../ui/modal/coMat/rateFeeModal.tsx | 76 +++++++++---------- .../guideDetailTable/guideDetailTable.tsx | 8 +- .../chkgdTable/rswtChkgd/rswtChkgdTable.tsx | 2 +- 6 files changed, 47 insertions(+), 61 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 1b6b7e76f..fa37a7704 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -33,9 +33,7 @@ import { writeRgtrAndMdfr } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg"; import { useFieldArray, useForm, type FieldErrors } from "react-hook-form"; // FieldErrors 타입 추가 import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; - import { createDefaultPbnstItem } from "./utilsZod"; -import { flushSync } from "react-dom"; export default function PublicReuseFaciltyInsert() { const { @@ -49,7 +47,7 @@ export default function PublicReuseFaciltyInsert() { pbnstRuseBizUpdate, } = useWrStore((state) => state); const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; - const [currentTab, setCurrentTab] = useState<string>("mng"); + const [, setCurrentTab] = useState<string>("mng"); const [isRuseReg, setIsRuseReg] = useState<{ isModal: boolean; }>({ isModal: false }); @@ -278,11 +276,15 @@ export default function PublicReuseFaciltyInsert() { <Button className="" size={"sm"} - onClick={(e) => { - searchTxt && searchTxt?.length > 0 - ? pubHasuSearch(String(pageNation), "41", searchTxt) - : pubHasuInit(String(pageNation), "41"); - isResetPage(true); + onClick={() => { + if(searchTxt && searchTxt?.length > 0) { + pubHasuSearch(String(pageNation), "41", searchTxt) + + }else{ + pubHasuInit(String(pageNation), "41"); + } + isResetPage(true); + }} > 조회 @@ -324,7 +326,6 @@ export default function PublicReuseFaciltyInsert() { headName={"공공 하수처리시설 목록"} cellClick={cellClick} onPageChange={setPageNation} - children={undefined} resetPageNo={resetPage} /> </ScrollArea> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 50f0afeea..336b581e2 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -18,7 +18,6 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { excelDownload, yearOptions } from "@/components/lib/func/commom"; -import SearchInputText from "@/components/ui/searchInput/searchInput"; import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; @@ -29,7 +28,6 @@ export default function PbnstSttn() { pbnstSttnSearch, pbnSttnInit, getPbnStnDetail, - pbnNmSearch, getFlcts } = useWrStore((state) => state); diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 4a00f525d..bf7586b26 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -13,7 +13,6 @@ import { fcBizSchema, type fcBizType, type PbnstRegArrrayType, - type ppInstlType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { diff --git a/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx b/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx index c7403b2b3..cc7de726a 100644 --- a/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx +++ b/apps/wr/components/ui/modal/coMat/rateFeeModal.tsx @@ -2,13 +2,13 @@ import { useWrStore } from "@/app/store"; import type { rateFeeType } from "@/app/store/common/searchCode/type"; -import { UiTable } from "@common/business_components/ui"; +import { UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Input, Label } from "@common/components/ui"; +import { Label } from "@common/components/ui"; import { useEffect, useState } from "react"; export function RateFeeTableModal() { - const { coRvw, rateFeeRes } = useWrStore((state) => state); + const { coRvw, rateFeeRes } = useWrStore((state) => state); const [reateFeeTable, setRateFeeTable] = useState<rateFeeType[]>([]); const gubunLabelMap: Record<number, string> = { @@ -32,32 +32,32 @@ export function RateFeeTableModal() { }; const fetchData = async (rateFeeRes: rateFeeType[]) => { - const data = await rateFeeRes?.filter((item: rateFeeType) => { - return item.incExpCd !== "SS"; - }) - .reduce((acc: any, cur: rateFeeType) => { - const key = cur.stdCost; - let target = acc.find((item: any) => item.stdCost === key); - if (!target) { - target = { - stdCost: cur.stdCost, - BD: 0, - SE: 0, - CE: 0, - }; - acc.push(target); - } - target[cur.incExpCd] = cur.rt; - return acc; - }, []); - + const data = await rateFeeRes + ?.filter((item: rateFeeType) => { + return item.incExpCd !== "SS"; + }) + .reduce((acc: any, cur: rateFeeType) => { + const key = cur.stdCost; + let target = acc.find((item: any) => item.stdCost === key); + if (!target) { + target = { + stdCost: cur.stdCost, + BD: 0, + SE: 0, + CE: 0, + }; + acc.push(target); + } + target[cur.incExpCd] = cur.rt; + return acc; + }, []); const dataGubun = data?.map((item: any) => { return { ...item, gubun: gubunLabelMap[item.stdCost] || item.stdCost, }; - }) + }); return dataGubun?.sort((a: any, b: any) => a.stdCost - b.stdCost); }; @@ -81,26 +81,20 @@ export function RateFeeTableModal() { <div className="col-span-5 flex items-center"> <Label className=" text-xl text-gray-600">기준년도</Label> - <Input - className="col-span-1 text-2xl text-right ml-2 w-32" - placeholder="" - type="text" - onChange={(e) => {}} - value={new Date().getFullYear() || ""} - /> + <span>{new Date().getFullYear() || ""}</span> </div> <div className="col-span-6 pr-6"> - <UiTable - className="min-w-full pr-12" - key={"rateTable" + reateFeeTable?.length} - headName={""} - tableData={reateFeeTable || []} - headlist={coRvw.rateFeeHeadList} - onPageChange={() => {}} - pageSize={0} - total={0} - cellClick={undefined} - /> + <UiTable + className="min-w-full pr-12" + key={"rateTable" + reateFeeTable?.length} + headName={""} + tableData={reateFeeTable || []} + headlist={coRvw.rateFeeHeadList} + onPageChange={() => {}} + pageSize={0} + total={0} + cellClick={undefined} + /> </div> </div> </ListDiv> diff --git a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx index 627537dcb..7676f7e71 100644 --- a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx @@ -1,26 +1,21 @@ "use client"; import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead"; -import { useWrStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common/type/header"; import type { } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; import { InputTableBody } from "@/components/lib/func/TableData"; import { - Input, Table, TableBody, - TableCell, TableHeader, - TableRow, } from "@common/components/ui"; -import { useEffect, useState, type Dispatch, type SetStateAction } from "react"; +import { useEffect, useState } from "react"; export function GuideDetailsTable({ chgRes, headList, upheadList, - type, setChGuidData, }: { chgRes: any[]; @@ -29,7 +24,6 @@ export function GuideDetailsTable({ type: string; setChGuidData: (chgRes: any[]) => void; }) { - const { code, rainChkgdn } = useWrStore((state) => state); const [inputData, setInputData] = useState<any[]>(); useEffect(() => { diff --git a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx index 7a43df3d8..b00b49988 100644 --- a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx @@ -35,7 +35,7 @@ export default function RswtChkgdTable({ onPageChange: (page: number) => void; pageCount: number; }) { - const { code, rswtChkgdn, rswtChkSttn, rswtChkgdnInit, rswtChkPolAndGuide, getRswtSttnExcel } = useWrStore( + const { code, rswtChkgdn, rswtChkSttn, rswtChkPolAndGuide, getRswtSttnExcel } = useWrStore( (state) => state ); const [headList, setHeadList] = useState<{ headList: TableUpperProps[], upHeadList: chHeadType[] }>({ headList: [], upHeadList: [] }); From 34bc8b6a5caa21594c57e7d5df720e72dbdbb14c Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 14 Jul 2025 14:12:41 +0900 Subject: [PATCH 109/159] =?UTF-8?q?=EB=B9=97=EB=AC=BC/=EC=A4=91=EC=88=98?= =?UTF-8?q?=EB=8F=84/=EC=98=A8=EB=B0=B0=EC=88=98=20=EB=93=B1=EB=A1=9D,=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20build=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ruseFcltMng/fcltReg/htdflReg/page.tsx | 25 ++++---- .../app/ruseFcltMng/fcltReg/rainReg/page.tsx | 4 +- .../app/ruseFcltMng/fcltReg/rswtReg/page.tsx | 4 +- .../ruseFcltMng/fcltSttn/htdflSttn/page.tsx | 31 ++++------ .../ruseFcltMng/fcltSttn/rainSttn/page.tsx | 31 ++++------ .../ruseFcltMng/fcltSttn/rswtSttn/page.tsx | 15 ++--- .../ruseFcltMng/fcltSttn/htdflSttn/excel.tsx | 2 +- .../ruseFcltMng/fcltSttn/htdflSttn/index.tsx | 18 +++--- .../ruseFcltMng/fcltSttn/rainSttn/excel.tsx | 6 +- .../ruseFcltMng/fcltSttn/rswtSttn/excel.tsx | 10 ++-- .../fcltSttn/rswtSttn/headList.tsx | 59 +++++++++---------- .../ruseFcltMng/fcltSttn/rswtSttn/index.tsx | 20 +++---- 12 files changed, 98 insertions(+), 127 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx index c80d5b4b4..c6056a3cc 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -1,6 +1,10 @@ "use client"; import { useWrStore } from "@/app/store"; +import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; +import { tableData } from "@/components/lib/func/commom"; +import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm"; +import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, ScrollArea, @@ -12,15 +16,9 @@ import { UiModal, UiTable, } from "@common/business_components"; -import { Button } from "@common/components"; import ListDiv from "@common/business_components/ui/list_div"; +import { Button } from "@common/components"; import { useEffect, useState } from "react"; -import { tableData } from "@/components/lib/func/commom"; -import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm"; -import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; -import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { Toaster } from "react-hot-toast"; export default function Home() { @@ -33,10 +31,10 @@ export default function Home() { const [bdstTable, setbdstTable] = useState<customHtdflBdst[]>(); const [issNewReg, setIsNewReg] = useState<boolean>(false); - const [bdstChgProps, setBdstChgProps] = useState<{ - isOpen: boolean; - chgBuilding: chgBuilding[]; - }>({ isOpen: false, chgBuilding: [] }); + // const [bdstChgProps, setBdstChgProps] = useState<{ + // isOpen: boolean; + // chgBuilding: chgBuilding[]; + // }>({ isOpen: false, chgBuilding: [] }); const { htdflRes ,htdflResCount} = htdfl; @@ -49,7 +47,7 @@ export default function Home() { if (htdflRes && htdflRes.length > 0) { const htdflData = tableData(htdflRes, { code }).map( (item: customHtdflBdst) => { - let archArea = + const archArea = item?.archArea.split(".")[0] !== "-1" ? item?.archArea.split(".")[0] : "확인불가"; @@ -67,8 +65,7 @@ export default function Home() { }, [code, htdflRes]); const cellClick: (val: number | undefined, headId: string) => void = ( - val, - headId + val ) => { if ((bdstTable ?? []).length > 0 && val !== undefined) { { diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index 426ca7f61..83679a274 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -52,7 +52,7 @@ export default function Home() { if (rainRes && rainRes.length > 0) { const rainData = tableData(rainRes, { code }).map( (item: customRainBdst) => { - let archArea = + const archArea = item?.archArea.split(".")[0] !== "-1" ? item?.archArea.split(".")[0] : "확인불가"; @@ -117,7 +117,7 @@ export default function Home() { <Button className="" size={"sm"} - onClick={(e) => { + onClick={() => { rainSearch(searchTxt || "", 1, "41"); //rainSearch(searchTxt || "", pageNation, "41"); }} diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx index 568145707..686154bc9 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx @@ -48,7 +48,7 @@ export default function Home() { if (rswtRes?.length > 0) { const rswtData = tableData(rswtRes, { code })?.map( (item: customRswtBdst) => { - let archArea = + const archArea = item?.archArea.split(".")[0] !== "-1" ? item?.archArea.split(".")[0] : "확인불가"; @@ -125,7 +125,7 @@ export default function Home() { <Button size={"sm"} className="mr-4 " - onClick={(e) => { + onClick={() => { rswtBdstSearch(searchTxt || "", pageNation, "41"); }} > diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index d8a1cef52..147b9a674 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -3,20 +3,18 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { - chgBuilding, - customRainBdst, + customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { excelDownload, getCity, - getCityOrSgg, - tableData, + tableData } from "@/components/lib/func/commom"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; import { ContentsDiv, - SearchBaseForm, SearchDiv, SearchFormLeft, SearchFormRight, @@ -25,15 +23,12 @@ import { Title, UiModal, UiTable, - type ReturnType, - type SelectDataType, + type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; +import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; -import { excelHtdflSttnParsing } from "@/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel"; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; @@ -43,7 +38,6 @@ export default function HtdflSttn() { ); const { htdflSttnRes, htdflSttnResCount } = htdflSttn; - const ref = useRef<ReturnType>({} as ReturnType); const isDownloadTriggered = useRef(false); const { t } = useTranslation('base'); const [pageNation, setPageNation] = useState(1); @@ -56,10 +50,10 @@ export default function HtdflSttn() { isOpen: boolean; data: customRainBdst | undefined; }>({ data: undefined, isOpen: false }); - const [bdstChgProps, setBdstChgProps] = useState<{ - isOpen: boolean; - chBuilding: chgBuilding[]; - }>({ isOpen: false, chBuilding: [] }); + // const [bdstChgProps, setBdstChgProps] = useState<{ + // isOpen: boolean; + // chBuilding: chgBuilding[]; + // }>({ isOpen: false, chBuilding: [] }); const [fcltNm, setFcltNm] = useState<string>(""); useEffect(() => { @@ -224,9 +218,6 @@ export default function HtdflSttn() { <UiTable headName={undefined} tableData={bdstTable || []} - children={ - <HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} /> - } headlist={htdflSttn.htdflSttHeadList} pageSize={20} total={htdflSttnResCount || 0} @@ -235,7 +226,9 @@ export default function HtdflSttn() { }} onPageChange={setPageNation} resetPageNo={resetPage} - ></UiTable> + > + <HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} /> + </UiTable> </ListDiv> </div> </div> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx index 74ea41ce0..13d0cc974 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -2,16 +2,21 @@ "use client"; import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; +import type { + chgBuilding, + customRainBdst, +} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { excelDownload, getCity, - getCityOrSgg, - tableData, + tableData } from "@/components/lib/func/commom"; +import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; +import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; import { ContentsDiv, - SearchBaseForm, SearchDiv, SearchFormLeft, SearchFormRight, @@ -20,20 +25,12 @@ import { Title, UiModal, UiTable, - type ReturnType, - type SelectDataType, + type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; +import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; -import type { - chgBuilding, - customRainBdst, -} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; -import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; -import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; @@ -42,7 +39,6 @@ export default function RainSttn() { (state) => state ); const { rainSttnRes, rainSttnResCount } = rainSttn; - const ref = useRef<ReturnType>({} as ReturnType); const [pageNation, setPageNation] = useState(1); const [isChHead, setIsChHead] = useState(false); @@ -235,16 +231,15 @@ export default function RainSttn() { <UiTable headName={undefined} tableData={bdstTable || []} - children={ - <HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} /> - } headlist={rainSttn.rainSttHeadList} pageSize={20} total={rainSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} resetPageNo={resetPage} - ></UiTable> + > + <HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} /> + </UiTable> </ListDiv> </div> </div> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index e28286add..0bde2417d 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -6,8 +6,7 @@ import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import { excelDownload, getCity, - getCityOrSgg, - tableData, + tableData } from "@/components/lib/func/commom"; import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; @@ -15,7 +14,6 @@ import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; import { ContentsDiv, - SearchBaseForm, SearchDiv, SearchFormLeft, SearchFormRight, @@ -24,8 +22,7 @@ import { Title, UiModal, UiTable, - type ReturnType, - type SelectDataType, + type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; @@ -43,7 +40,6 @@ export default function RswtSttn() { const { rswtSttnRes, rswtSttnResCount } = rswtSttn; const [isChHead, setIsChHead] = useState(false); const [resetPage, isResetPage] = useState(false); - const ref = useRef<ReturnType>({} as ReturnType); const [bdstTable, setBdstTable] = useState<customRswtBdst[]>(); const isDownloadTriggered = useRef(false); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() @@ -233,16 +229,15 @@ export default function RswtSttn() { <UiTable headName={undefined} tableData={bdstTable || []} - children={ - <HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} /> - } headlist={rswtSttn.rswtSttHeadList} pageSize={20} total={rswtSttnResCount || 0} cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} onPageChange={setPageNation} resetPageNo={resetPage} - ></UiTable> + > + <HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} /> + </UiTable> </ListDiv> </div> </div> diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx index 1ae5f56cc..18e045025 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel.tsx @@ -2,7 +2,7 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customHtdflBdst } from "../../fcltReg/htdflReg"; export const excelHtdflSttnParsing = ( - excel: customHtdflBdst[], + excel: { data: customHtdflBdst[] }, sidoCode: SelectDataType[], sggCode: SelectDataType[] ): string[][] => { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx index fb264f669..d62ee3340 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx @@ -1,12 +1,12 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; -import { htdflSttHeadListExport, htdflSttNodeListExport } from "./headList"; -import type { sttnHeadListType } from "../rainSttn/headList"; -import type { z } from "zod"; -import { controlHeadView } from "../rainSttn"; -import type { customHtdflBdst } from "../../fcltReg/htdflReg"; -import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api"; +import { fetchType, getFetchWithCount } from "@/components/lib/api"; import type { SelectDataType } from "@common/business_components/ui"; +import type { z } from "zod"; +import type { customHtdflBdst } from "../../fcltReg/htdflReg"; +import { controlHeadView } from "../rainSttn"; +import type { sttnHeadListType } from "../rainSttn/headList"; import { excelHtdflSttnParsing } from "./excel"; +import { htdflSttHeadListExport, htdflSttNodeListExport } from "./headList"; const htdflSttHeadList = htdflSttHeadListExport; const htdflSttNodeList = htdflSttNodeListExport; @@ -45,9 +45,7 @@ export const htdflSttnStateExport: htdflSttnState = { htdflSttnResCount: 1, }, }; -const initFetch = async (page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { +const initFetch = async (page: number, total: string, con: string, txt: string) => { const htdflRes = await getFetchWithCount( "wr", `/drain/facilityList` + @@ -68,7 +66,7 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = ( sidoCode: SelectDataType[], sggCode: SelectDataType[]) => { try { - const htdflSttnRes = await initFetch(page, total, con, txt, sidoCode, sggCode); + const htdflSttnRes = await initFetch(page, total, con, txt); if (isExcel) { const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode); set((state: htdflSttnState) => { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx index d2e39aa28..367106e58 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx @@ -2,7 +2,7 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customRainBdst } from "../../fcltReg/rainReg"; export const excelRainSttnParsing = ( - excel: customRainBdst[], + excel: { data: customRainBdst[] }, sidoCode: SelectDataType[], sggCode: SelectDataType[] ): string[][] => { @@ -10,8 +10,8 @@ export const excelRainSttnParsing = ( excel.data.forEach((item) => { excelExportData.push([ - sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", - sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", + sidoCode.find((sido) => sido.val === item.ctpvCd?.toString())?.text ?? "", + sggCode.find((sgg) => sgg.val === item.sggCd?.toString())?.text ?? "", item.bdstNm ?? "", item.daddr ?? "", String(item.bdstInfoPk ?? ""), diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx index 442b027e3..803dc2d83 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx @@ -1,15 +1,15 @@ +import { bdstUsgCd } from "@/app/store/common/code/basicCode"; import type { SelectDataType } from "@common/business_components/ui"; import type { customRswtBdst } from "../../fcltReg/rswtReg"; -import { useWrStore } from "@/app/store"; -import { bdstUsgCd } from "@/app/store/common/code/basicCode"; export const excelRSwtSttnParsing = ( - excel: customRswtBdst[], + excel: { data: customRswtBdst[] }, sidoCode: SelectDataType[], sggCode: SelectDataType[] ): string[][] => { const excelExportData: string[][] = []; excel.data.forEach((item) => { + console.log("item", item) excelExportData.push([ sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", @@ -18,10 +18,10 @@ export const excelRSwtSttnParsing = ( bdstUsgCd.find((cd)=> cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 String(item.frstArchPrmsnDt ?? ""), String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]), - String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량 + // String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량 String(item.chgBuilding.length > 0 ? "Y" : "N"), //중축・개축・재축여부 String(item.reuseBuilding?.[0]?.lawTrgtYn ?? ""), //법적의무대상여부 - String(item.reuseBuilding?.[0]?.rswtrObj.oblgTrgtWtrUsqty ?? ""), //의무대상물사용량 + // String(item.reuseBuilding?.[0]?.rswtrObj.oblgTrgtWtrUsqty ?? ""), //의무대상물사용량 String(item.reuseBuilding?.[0]?.instlCmptnDt ?? ""), //설치완료일시 String(item.reuseBuilding?.[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding?.[0]?.instlCst ?? ""), //설치비용 item.reuseBuilding?.[0]?.rswtrObj?.orgwtKndCd ?? "", //원수종류 diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx index 9989290e7..2f44b2c33 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx @@ -38,11 +38,11 @@ export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [ title: "건축면적", visible: true, }, - { - id: "wtrUsqty", - title: "물사용량", - visible: true, - }, + // { + // id: "wtrUsqty", + // title: "물사용량", + // visible: true, + // }, { id: "chBuildingYn", title: "중축・개축・재축여부", @@ -54,12 +54,11 @@ export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [ title: "법적의무대상여부", visible: true, }, - - { - id: "oblgTrgtWtrUsqty", - title: "의무대상물사용량 ", - visible: true, - }, + // { + // id: "oblgTrgtWtrUsqty", + // title: "의무대상물사용량 ", + // visible: true, + // }, { id: "instlCmptnDt", title: "설치완료일시", @@ -134,7 +133,7 @@ export const rswtSttNodeListExport: CommonTableProps[] = [ visible: true, row: 1, rowSpan: 1, - colSpan: 12, + colSpan: 10, }, { id: "rswtFcltInfo", @@ -229,15 +228,15 @@ export const rswtSttNodeListExport: CommonTableProps[] = [ rowSpan: 2, colSpan: 1, }, - { - id: "wtrUsqty", - title: "물사용량", - upName: "bdnstInfo", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, + // { + // id: "wtrUsqty", + // title: "물사용량", + // upName: "bdnstInfo", + // visible: true, + // row: 2, + // rowSpan: 2, + // colSpan: 1, + // }, { id: "chBuildingYn", title: "중축・개축・재축여부", @@ -257,15 +256,15 @@ export const rswtSttNodeListExport: CommonTableProps[] = [ rowSpan: 2, colSpan: 1, }, - { - id: "oblgTrgtWtrUsqty", - title: "의무대상물사용량", - upName: "bdnstInfo", - visible: true, - row: 2, - rowSpan: 2, - colSpan: 1, - }, + // { + // id: "oblgTrgtWtrUsqty", + // title: "의무대상물사용량", + // upName: "bdnstInfo", + // visible: true, + // row: 2, + // rowSpan: 2, + // colSpan: 1, + // }, { id: "instlCmptnDt", title: "설치완료일시", diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index e76095bd5..97c9dfe5b 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -1,12 +1,12 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; -import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api"; +import { fetchType, getFetchWithCount } from "@/components/lib/api"; +import type { SelectDataType } from "@common/business_components/ui"; import type { z } from "zod"; import type { customRswtBdst } from "../../fcltReg/rswtReg"; import { controlHeadView } from "../rainSttn"; import type { sttnHeadListType } from "../rainSttn/headList"; import { excelRSwtSttnParsing } from "./excel"; import { rswtSttHeadListExport, rswtSttNodeListExport } from "./headList"; -import type { SelectDataType } from "@common/business_components/ui"; @@ -30,11 +30,11 @@ export type rswtSttnState = { type rswtSttnActions = { rswtSttnInit: (isExcel: boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => void; rswtSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + sidoCode: SelectDataType[], + sggCode: SelectDataType[]) => void; rswtChSttnHead: ( headList: z.infer<typeof sttnHeadListType>, ) => void; @@ -72,7 +72,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); + const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); set((state: rswtSttnState) => { return { ...state, @@ -111,12 +111,6 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (con ? `/${con}` : "/0") + (txt ? `/${txt}` : "") ); - console.log("주소",`/reuseFc/waterreuseFc` + - (page ? `/${page}` : "/1") + - (total ? `/${total}` : "/20") + - (con ? `/${con}` : "/0") + - (txt ? `/${txt}` : "")) - console.log("rswtSttnRes", rswtSttnRes) if (isExcel) { const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); set((state: rswtSttnState) => { From e4ea9369cefc0902c66af894094e0d4546f984ee Mon Sep 17 00:00:00 2001 From: truthwing <truthplumage@gmail.com> Date: Mon, 14 Jul 2025 14:13:58 +0900 Subject: [PATCH 110/159] =?UTF-8?q?headChModal=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wr/components/ui/modal/sttn/headChModal/headChModal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx b/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx index 2cf90416c..0673f3ca5 100644 --- a/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx +++ b/apps/wr/components/ui/modal/sttn/headChModal/headChModal.tsx @@ -1,9 +1,9 @@ import { useWrStore } from "@/app/store"; import { sttnHeadListType } from "@/app/store/ruseFcltMng/fcltSttn/rainSttn/headList"; -import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@common/business_components/ui"; +import { Form, FormControl, FormField, FormItem, FormLabel, } from "@common/business_components/ui"; import { Button, Checkbox } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; @@ -11,7 +11,7 @@ export default function HeadChModal({ headList, type }: { headList: z.infer<type const { rainChSttnHead, rswtChSttnHead, htdflChSttnHead, pbnstChSttnHead } = useWrStore((state) => state); - let items = headList.map(item => ({ id: item.id, title: item.title, val: item.visible })); + const items = headList.map(item => ({ id: item.id, title: item.title, val: item.visible })); const form = useForm<z.infer<typeof sttnHeadListType>>({ resolver: zodResolver(sttnHeadListType), From b930722f5f5b9b2712fcf6635d5d087b3d0f1c9d Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 14 Jul 2025 14:15:56 +0900 Subject: [PATCH 111/159] =?UTF-8?q?=EC=9E=AC=EC=9D=B4=EC=9A=A9=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=20=EC=9A=B4=EC=98=81=20=ED=98=84=ED=99=A9=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 24f94dc58..725f95ea5 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -129,7 +129,6 @@ const hasuListFetch = async ( fetchType.WR ); const checkWrRegListRes = getRuseList.data; - const count = getRuseList.count; @@ -140,7 +139,6 @@ const hasuListFetch = async ( fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11) ); - console.log(' pbnList ', pbnList) if(findData){ const usage = item.prfList.reduce( From e352a63db4faee1a1535cd41e53c838ffd6c2e3b Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Mon, 14 Jul 2025 14:16:08 +0900 Subject: [PATCH 112/159] =?UTF-8?q?=EC=8B=9C=EC=84=A4=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 336b581e2..f8d31f0da 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -28,36 +28,38 @@ export default function PbnstSttn() { pbnstSttnSearch, pbnSttnInit, getPbnStnDetail, - getFlcts + getFlcts, } = useWrStore((state) => state); - const { pbnstSttnRes, fclts,pbnstSttnResCount} =pbnstSttn + const { pbnstSttnRes, fclts, pbnstSttnResCount } = pbnstSttn; const ref = useRef<ReturnType>({} as ReturnType); const [searchYear, setSearchYear] = useState<string>( String(new Date().getFullYear()) ); const [isChHead, setIsChHead] = useState(false); const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>(); - const [pageNation, setPageNation] = useState(1); const [pbnDetaileData, setPbnDetaileData] = useState<{ isModal: boolean; data: customPbnst; }>({ isModal: false, data: {} as customPbnst }); - const [returnType, setReturnType] = useState<ReturnType>({} as ReturnType); const [pbnRuseNm, setPbnRuseNm] = useState<string>(""); const excelClick = useCallback(() => { - pbnstSttnSearch(true, String(pageNation), "100000", ref.current, pbnRuseNm, searchYear,fclts ); - }, [pbnstSttnSearch,fclts,pbnRuseNm]); + pbnstSttnSearch( + true, + String(1), + "100000", + ref.current, + pbnRuseNm, + searchYear, + fclts + ); + }, [pbnstSttnSearch, fclts, pbnRuseNm]); const cellCLick = useCallback( (index: number | undefined) => { - if ( - index !== undefined && - pbnstSttnRes && - pbnstSttnRes[index] - ) { + if (index !== undefined && pbnstSttnRes && pbnstSttnRes[index]) { const pbnstRuseFcltPk = pbnstSttnRes[index].pbnstRuseFcltPk; getPbnStnDetail(pbnstRuseFcltPk); } @@ -78,21 +80,20 @@ export default function PbnstSttn() { }, [pbnstSttn.excelList]); useEffect(() => { if (!pbnstSttn.isInit) { - getFlcts() - + getFlcts(); } }, [pbnstSttn.isInit, pbnSttnInit, ref.current]); useEffect(() => { - if(pbnstSttnRes && pbnstSttnRes.length>0) { + if (pbnstSttnRes && pbnstSttnRes.length > 0) { setBdstTable(pbnstSttnRes); - }else{ + } else { setBdstTable([]); } }, [pbnstSttnRes]); - useEffect(() =>{ + useEffect(() => { pbnSttnInit("1", "15", ref.current, searchYear, pbnstSttn.fclts); - },[fclts]) + }, [fclts]); useEffect(() => { if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk) @@ -154,13 +155,19 @@ export default function PbnstSttn() { </div> } queryClick={function (returnType: ReturnType): void { - setReturnType(returnType); - pbnstSttnSearch(false, "1", "15", returnType, pbnRuseNm, searchYear, fclts); + pbnstSttnSearch( + false, + "1", + "15", + returnType, + pbnRuseNm, + searchYear, + fclts + ); }} excelClick={excelClick} - initClick={function (): void { - setPbnRuseNm('') - + initClick={function (): void { + setPbnRuseNm(""); }} btnClass={btnClass} ref={ref} @@ -174,13 +181,10 @@ export default function PbnstSttn() { <UiTable headName={undefined} tableData={bdstTable || []} - children={ - <HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} /> - } headlist={pbnstSttn.pbnstSttHeadList} pageSize={15} total={pbnstSttnResCount} - cellClick={(index: number | undefined, headId: string) => { + cellClick={(index: number | undefined) => { cellCLick(index); }} onPageChange={(page: number) => { @@ -194,7 +198,9 @@ export default function PbnstSttn() { fclts ); }} - ></UiTable> + > + <HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} /> + </UiTable> </ListDiv> </div> </div> @@ -223,7 +229,9 @@ export default function PbnstSttn() { bodyClass="w-[68vw] max-w-none h-[90vh]" open={pbnDetaileData.isModal} onOpenChange={(open) => { - setPbnDetaileData({ data: {} as customPbnst, isModal: false }); + //TODO:OPEN 상태 확인필요 + if(!open) + setPbnDetaileData({ data: {} as customPbnst, isModal: open }); }} /> </ContentsDiv> From 2c5a80105b6d072bdd5d5bfeeb70891d50b983e8 Mon Sep 17 00:00:00 2001 From: truthwing <truthplumage@gmail.com> Date: Mon, 14 Jul 2025 14:16:34 +0900 Subject: [PATCH 113/159] =?UTF-8?q?pbnstSttnModal=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sttn/pbnstSttnModal/pbnstSttnModal.tsx | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx index 498019cd7..99fdb48a3 100644 --- a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx +++ b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx @@ -21,28 +21,23 @@ import { ScrollArea, Title, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { + Table, + TableBody, + TableHeader, Tabs, + TabsContent, TabsList, TabsTrigger, - Button, - TabsContent, - TableHeader, - TableBody, - Table, } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; -import { set, useForm } from "react-hook-form"; +import { useForm } from "react-hook-form"; import { z } from "zod"; export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titleVisible?: boolean }) { - const { code, pbnstSttn, prfmnc , pbnstPrfmncSttn} = useWrStore((state) => state); + const { pbnstSttn, prfmnc , pbnstPrfmncSttn} = useWrStore((state) => state); const [fcltTab, setFcltTab] = useState<string>("fclt"); const [ruseTab, setRuseTab] = useState<string>("totalPrf"); - const [ruseBizData, setRuseBizData] = useState<{ - data: any[]; - head: TableUpperProps[]; - }>(); const [ruseHeadList, setRuseHeadList] = useState<TableUpperProps[]>([]); const [ruseTableData, setRuseTableData] = useState<TableUpperProps[]>([]); const [prfData, setPrfData] = useState<{ @@ -51,7 +46,6 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl totalPrf: any[]; }>(); const [indexMng, setIndexMng] = useState<number>(0); - const [indexBiz, setIndexBiz] = useState<number>(0); const form = useForm<{ items: z.infer<typeof pbnstRegZod>[]; }>({ @@ -61,7 +55,6 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl }); - const { monthHeadList } = prfmnc; useEffect(() => { let tableData; if (fcltTab === "fclt") { @@ -302,15 +295,14 @@ export function PbnstSttnModal({ data, titleVisible }: { data: customPbnst; titl pageSize={0} total={0} cellClick={undefined} - onPageChange={function (page: number): void { + onPageChange={function (): void { throw new Error("Function not implemented."); }} - children={ - fcltTab === "fclt" ? ( + > + {fcltTab === "fclt" ? ( <HeadMakeColSpan upHeadList={pbnstSttn.ruseFcltNodeList} /> - ) : undefined - } - ></UiTable> + ) : undefined} + </UiTable> </TabsContent> </Tabs> <div className=""> From ea9a2b0cee6d149044ee6f21d0139434effb960b Mon Sep 17 00:00:00 2001 From: truthwing <truthplumage@gmail.com> Date: Mon, 14 Jul 2025 14:22:20 +0900 Subject: [PATCH 114/159] =?UTF-8?q?CoDetailModal=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sttn/sttnDetailModal/coDatailModal.tsx | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx index 4bb0803e8..0e48f1211 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx @@ -1,13 +1,12 @@ "use client"; -import { useWrStore } from "@/app/store"; import type { customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn"; import { ldrmntZod } from "@/app/store/matDmd/ldrmntCoSttn/headList"; import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { handleCommaNumberChange } from "@/components/lib/func/commom"; -import { DatePicker, Form, FormField, FormUi, ScrollArea } from "@common/business_components/ui"; +import { Form, FormField, FormUi, ScrollArea } from "@common/business_components/ui"; import { Button, Input } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { useForm } from "react-hook-form"; import type { z } from "zod"; @@ -66,8 +65,6 @@ export default function CoDetailModal({ className={selectClass} placeholder="" type="hidden" - onChange={(e) => { - }} value={field.value ?? ""} /> </FormUi> @@ -88,7 +85,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -107,7 +104,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -129,7 +126,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -148,7 +145,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -169,7 +166,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -188,7 +185,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -207,7 +204,7 @@ export default function CoDetailModal({ onChange={(e) => { field.onChange(e.target.value); }} - value={field.value ?? "" ?? ""} + value={field.value ?? ""} /> </FormUi> )} @@ -746,7 +743,7 @@ export default function CoDetailModal({ <FormField control={form.control} name="fctryMngNo" - render={({ field, fieldState }) => ( + render={({ field }) => ( <FormUi label="공장관리번호"> <Input className={selectClass} From b8ef43e0bd76a89895998ece01be36e2926cd23d Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Mon, 14 Jul 2025 14:22:31 +0900 Subject: [PATCH 115/159] =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/modal/ldrmntSttn/ldrmntExcelModal.tsx | 67 ------------------- 1 file changed, 67 deletions(-) delete mode 100644 apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx diff --git a/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx b/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx deleted file mode 100644 index 5427c5dd2..000000000 --- a/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useWrStore } from "@/app/store"; -import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList"; -import type { FcPrfType, PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; -import { yearOptions } from "@/components/lib/func/commom"; -import { FileUpload, Form, FormField, FormUi, SelectBox, Title } from "@common/business_components/ui"; -import { Button, Input } from "@common/components/ui"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useState } from "react"; -import { useForm } from "react-hook-form"; -import type { z } from "zod"; - -export default function LdrmntExcelModal({ data }: { data: FcPrfType }) { - const { prfmnRegData } = useWrStore((state) => state); - const [excelData, setExcelData] = useState<PrfType[]>(); - const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({ - resolver: zodResolver(pbnPrfRegExcelZod), - defaultValues: { - ym: String(new Date().getFullYear()), - }, - }); - const onSubmit = (values: z.infer<typeof pbnPrfRegExcelZod>) => { - if (excelData) { - prfmnRegData(excelData as unknown as PrfType); - } - }; - const [files, setFiles] = useState<File[] | null>(null); - return ( - <> - <div> - <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> - <div> - <Title title={"잠재수요처 등록"}> -
-
-

- {"잠재수요처 파일"} -

- - -
-
- ( - - { - if (files) setFiles(files); - }} - fileTypes="xlsx" - > - - )} - /> -
- - -
- - ) - -} \ No newline at end of file From 96499a8cd0a9fcd83f0580347bbd469fadba8c71 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Mon, 14 Jul 2025 14:23:34 +0900 Subject: [PATCH 116/159] =?UTF-8?q?=EC=A7=80=EB=8F=84=EC=A0=90=EA=B2=80?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B9=8C?= =?UTF-8?q?=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index cb3f2f9ef..03397255c 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -290,7 +290,7 @@ export default function Page() {
-
From 1926d53da62813978309b70ac7694334b561a78f Mon Sep 17 00:00:00 2001 From: truthwing Date: Mon, 14 Jul 2025 14:31:32 +0900 Subject: [PATCH 119/159] =?UTF-8?q?lib=20=ED=8F=B4=EB=8D=94=20=EB=B9=8C?= =?UTF-8?q?=EB=93=9C=20=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/components/lib/api/index.ts | 2 +- apps/wr/components/lib/func/TableData.tsx | 1 - apps/wr/components/lib/func/commom.tsx | 4 ++-- apps/wr/components/lib/useTus_wr/useTusWr.tsx | 21 ++++++++----------- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/wr/components/lib/api/index.ts b/apps/wr/components/lib/api/index.ts index bf2c01683..8772959e1 100644 --- a/apps/wr/components/lib/api/index.ts +++ b/apps/wr/components/lib/api/index.ts @@ -1,6 +1,6 @@ //8880 -import { CS_URL, DEV_URL_FO, DEV_URL_WR, LOCAL_URL } from "../config/"; +import { DEV_URL_FO, DEV_URL_WR, LOCAL_URL } from "../config/"; export const fetchType = { COMMON: "common", WR: "wr", LOCAL: "LOCAL" , CS: "CS" }; diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index 2046bd15e..ab6aa98d6 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -2,7 +2,6 @@ import type { TableUpperProps } from "@/app/store/common/type/header"; import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; import { Checkbox, Input, TableCell, TableRow } from "@common/components/ui"; -import { useEffect } from "react"; export const rainChkTableData = (chkData: rainChkZodType[]) => { // 1. chkgdnFk + utztnUsgCd 기준 누계 정보 만들기 diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index 6d96b3540..5c2ce97ff 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -1,9 +1,9 @@ import type { comCodeState } from "@/app/store/common/code"; import { filePickedBlob, - type SelectDataType, - type ReturnType, filePickedBlobArray, + type ReturnType, + type SelectDataType, type SheetParameter, } from "@common/business_components/ui"; import { Button } from "@common/components/ui"; diff --git a/apps/wr/components/lib/useTus_wr/useTusWr.tsx b/apps/wr/components/lib/useTus_wr/useTusWr.tsx index aca2b1fb6..c7580f84f 100644 --- a/apps/wr/components/lib/useTus_wr/useTusWr.tsx +++ b/apps/wr/components/lib/useTus_wr/useTusWr.tsx @@ -1,15 +1,14 @@ +import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; +import toast from "react-hot-toast"; import { Upload, + type DetailedError, type HttpRequest, type HttpResponse, type OnSuccessPayload, - type DetailedError, } from "tus-js-client"; -import { CS_TUS_UPLOAD, CS_URL } from "../config"; -import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { fetchType, putFectch } from "../api"; -import { error } from "console"; -import toast from "react-hot-toast"; +import { CS_TUS_UPLOAD } from "../config"; type UploadOptions = { handleUploadStart?: (upload: Upload) => void; @@ -26,16 +25,14 @@ export type ReturnFileType = { lnkgDmnId: string | null; lnkgDmnNm: string | null; regDt: Date | null; - atflCd: String; + atflCd: string; atflSn: number; - atflId: String; - physFileNm: String; + atflId: string; + physFileNm: string; }; export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) => new Promise((resolve, reject) => { try { - const Authorization = "Authorization"; - const AUTH_USER_ID = "token-id"; let fileInfo: string | undefined; //CS_URL const uploader = new Upload(oFile.file, { @@ -77,10 +74,10 @@ export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) => WrTableInfo, fetchType.CS ) - .then((res) => { + .then(() => { resolve(fileParse); }) - .catch((error) => { + .catch(() => { reject({ causingError: { cause: "파일 업로드 업데이트 실패", From 9fbf6d1a6aa69da984110e04fee0228952e22cbb Mon Sep 17 00:00:00 2001 From: leedj312 Date: Mon, 14 Jul 2025 14:36:45 +0900 Subject: [PATCH 120/159] =?UTF-8?q?sttnDetailModal=20=EB=B9=8C=EB=93=9C=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx index 4f6deee51..a45f69cc2 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx @@ -9,9 +9,8 @@ import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import { useWrStore } from "@/app/store"; import { useEffect, useState } from "react"; import type { CommonTableProps } from "@/app/store/common/type/header"; -import { rainChkTableData, rswtChkTableData } from "@/components/lib/func/TableData"; +import { rainChkTableData } from "@/components/lib/func/TableData"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; export default function SttnDetailModal({ type, @@ -20,7 +19,7 @@ export default function SttnDetailModal({ type: string; formObj: any; }) { - const { code, rainSttn, rswtSttn, rainSttnChkSearch,rswtChkPolAndGuide } = useWrStore( + const { rainSttn, rswtSttn, rainSttnChkSearch } = useWrStore( (state) => state ); const [detailData, setDetailData] = useState({ @@ -103,15 +102,17 @@ export default function SttnDetailModal({ } tableData={detailData.data || []} headlist={detailData.head || []} - children={ } pageSize={0} total={0} cellClick={undefined} onPageChange={function (page: number): void { throw new Error("Function not implemented."); + console.log('page ', page) }} - >:<>} + > + + :<>} From 9e3478252e970a3055ce96bab4732ea39ba3f699 Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Mon, 14 Jul 2025 14:36:55 +0900 Subject: [PATCH 121/159] =?UTF-8?q?=EC=83=81=EC=84=B8=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20state=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 39 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 6da584f8e..ccabfc443 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -61,6 +61,7 @@ const NewWindowPopup: React.FC = ({ const [rainTable, setRainTable] = useState(); const [rainPage, setRainPage] = useState(1) const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }); + const [rainList, setRainList] = useState(rainSttnRes || []); // 중수도시설 변수 const { rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore( @@ -70,6 +71,7 @@ const NewWindowPopup: React.FC = ({ const [rswtrTable, setRswtrTable] = useState(); const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false }); const [rswtrPage, setRswtrPage] = useState(1); + const [rswtrList, setRswtrList] = useState(rswtSttnRes || []); // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); @@ -77,6 +79,7 @@ const NewWindowPopup: React.FC = ({ const [htdflTable, setHtdflTable] = useState(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [htdflPage, setHtdflPage] = useState(1) + const [htdflList, setHtdflList] = useState(htdflSttnRes || []); //하수처리시설 변수 const { @@ -118,8 +121,7 @@ const NewWindowPopup: React.FC = ({ }; const fetchHasuDetail = async (featureCd: string, data: string) => { try { - const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON); - //TODO : state 처리. + const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON) setHasuList( rainRes.data.map((item: any) => { return { @@ -127,34 +129,41 @@ const NewWindowPopup: React.FC = ({ fctCpc: Number(item.fctCpc) || 0, ruse: item.ruse === false ? "N" : "Y", }; - }); + }) ) - pbnstHasuRes = hasuList - if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] }); - } catch (error) { console.error("Error fetching data:", error); } }; - const detainSttn = async (featureCd: string, layerNm: string) => { if (layerNm == '빗물이용시설') { const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`) - rainSttnRes = res - setRainDetailModal({ isOpen: true, data: rainSttnRes[0] }); + setRainList(res) } else if(layerNm == '중수도시설'){ const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`) - rswtSttnRes = res - console.log('중수도', res, featureCd) - setRswtrDetailModal({isOpen:true,data:rswtSttnRes[0]}) + setRswtrList(res) } else{ const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`) - htdflSttnRes = res + setHtdflList(res) setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] }); } } + // 상세 목록 데이터 상태 처리 + 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]) + const layerId = getSelectedLayers(); if (featureData && typeof featureData.getProperties === "function") { const selectedVal = featureData.getProperties(); @@ -174,7 +183,9 @@ const NewWindowPopup: React.FC = ({ else{ featureCd = selectedVal?.bdst_nm; setFcltPk(featureCd) - detainSttn(featureCd,layerId) + if (layerId) { + detainSttn(featureCd, layerId); + } } setViewMode("detail") } From 92561ab1d3fd97827c79e9e72c768d903dd3d68b Mon Sep 17 00:00:00 2001 From: leedj312 Date: Mon, 14 Jul 2025 14:43:14 +0900 Subject: [PATCH 122/159] =?UTF-8?q?=EC=9E=AC=EA=B2=80=ED=86=A0=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=20=EB=B9=8C=EB=93=9C=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx | 6 +++--- apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx | 7 ++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx index 623335c6b..75fd6825f 100644 --- a/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx @@ -137,7 +137,7 @@ export default function RuseRvwHstry() { const confrirmToast = () => { const completeData = rvwHistData ?.map((item) => { - form.clearErrors; + form.clearErrors(); if (item?.completeYn) { return Number(item.dmdInfoSn); } @@ -153,7 +153,7 @@ export default function RuseRvwHstry() {