From 54d3a35b38015bd4ff3c09bbaf884d57d92292f8 Mon Sep 17 00:00:00 2001 From: ljpark Date: Thu, 4 Jun 2026 15:56:28 +0900 Subject: [PATCH 01/52] =?UTF-8?q?wr:=20store=20code=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20=EC=9C=84=EC=B9=98=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-layout)/map/mainMap/page.tsx | 7 ++++- apps/wr/app/store/common/auth/index.tsx | 2 +- apps/wr/app/store/common/code/index.ts | 31 +++++++++++++++---- apps/wr/app/store/store.tsx | 14 ++++----- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/apps/wr/app/(map-layout)/map/mainMap/page.tsx b/apps/wr/app/(map-layout)/map/mainMap/page.tsx index 13798ff4f..10421b48b 100644 --- a/apps/wr/app/(map-layout)/map/mainMap/page.tsx +++ b/apps/wr/app/(map-layout)/map/mainMap/page.tsx @@ -22,7 +22,7 @@ import WrOverLay from "@/components/ui/map/wrOverLay/wrOverLay"; const Map = () => { const { code, comMap, rainMapDetile, rswtMapDetile, getRuseMaplListReturn - , pbnMapDetaile, ldrmntMapDetile, htdfMapDetile, coSttnMapDetail } = useWrStore((state) => state); + , pbnMapDetaile, ldrmntMapDetile, htdfMapDetile, coSttnMapDetail, initCommonCodes } = useWrStore((state) => state); const { isFeatured } = comMap; const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정 const gisMaps = useRef(null); @@ -73,6 +73,11 @@ const Map = () => { }; }, []); + useEffect(() => { + if (code.isInit) return; + initCommonCodes(); + }, [code.isInit, initCommonCodes]); + // 체크된 레이어 정보를 받는 핸들러 const handleCheckedLayersChange = ( checkedIds: string[], diff --git a/apps/wr/app/store/common/auth/index.tsx b/apps/wr/app/store/common/auth/index.tsx index feca57c80..6e9396e6e 100644 --- a/apps/wr/app/store/common/auth/index.tsx +++ b/apps/wr/app/store/common/auth/index.tsx @@ -32,7 +32,7 @@ export const authStateExport: authState = { export type authActions = { getMenuAuthrts: (menuCd: number) => void; - getLaeSeCdCheck: () => Promise; + getLaeSeCdCheck: () => Promise; // 로그인 사용자 지역코드 laeSeCd를 조회 후 상태 update getMyUUID: () => Promise; }; export const authActionsExport: (set: any, get: any) => authActions = ( diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index adcff57f2..4f7896de0 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -21,12 +21,12 @@ const codeMApping = { WR002: "rswtBdstType", WR003: "rainFcltCd", WR004: "bdstGrntchClass", - WR005: "rswtPrscCdMthdCd", // 아직 디 못바꿈 - WR006: "orgwtKndCd", //작업 완ㅛ - WR007: "ruseMngMtd", // 작업완료 - WR008: "rusePrcsMthdCd", //w작업완료 - WR009: "erctUswtrPrcsMeth", //w작업완료 - WR010: "ruseFcltSpot", // inout은 yn 만 사용해야 함으로 해당 코드는 사용안함. + WR005: "rswtPrscCdMthdCd", + WR006: "orgwtKndCd", + WR007: "ruseMngMtd", + WR008: "rusePrcsMthdCd", + WR009: "erctUswtrPrcsMeth", + WR010: "ruseFcltSpot", WR011: "pplQulity", WR012: "pplLenght", WR013: "bdstFilterYn", // 사용 불가 yn만 사용해야함으로 해당코드 사용 안함 @@ -312,6 +312,7 @@ export type comCodeActions = { returnCodeText: (val: string, codeName: string) => string; returnTextCode: (text: string, codeName: string) => string; getCommonCodesByKeys: (keys: string[]) => Promise; + initCommonCodes: () => Promise; }; export const codeActionExport: (set: any, get:any) => comCodeActions = (set: any, get:any) => { @@ -368,5 +369,23 @@ export const codeActionExport: (set: any, get:any) => comCodeActions = (set: any const found = codeList.find((item) => item.text === text); return found ? found.val : text; }, + initCommonCodes: async () => { + if (get().code.isInit) return; + + await getSggCd(set); + await getCityCd(set); + await getRegionCd(set); + await getMiddleRegionCd(set); + await getUnitWaterShedCd(set); + await getEnvPartCd(set); + await getCommonUpCd(set); + + set((state) => ({ + code: { + ...state.code, + isInit: true, + }, + })); + }, }; }; diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index fbb3434d9..3024d1cb1 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -336,13 +336,13 @@ export const StoreZus = ( } ) => { return createStore()((set ,get) => { - getSggCd(set); - getCityCd(set); - getRegionCd(set); - getMiddleRegionCd(set); - getUnitWaterShedCd(set); - getEnvPartCd(set); - getCommonUpCd(set) + // getSggCd(set); + // getCityCd(set); + // getRegionCd(set); + // getMiddleRegionCd(set); + // getUnitWaterShedCd(set); + // getEnvPartCd(set); + // getCommonUpCd(set); return { ...initState, ...comFcltSearchAction(set), From 3fee2a781fdbc5aa072d83ec533754858c767692 Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 5 Jun 2026 16:15:46 +0900 Subject: [PATCH 02/52] =?UTF-8?q?wr:=20=ED=95=98=EC=88=98=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=EC=8B=9C=EC=84=A4=EB=93=B1=EB=A1=9D=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 --- .../ruseFcltMng/fcltReg/pbnstReg/page.tsx | 29 ++++----- apps/wr/app/api/proxy/[...url]/route.ts | 2 +- .../ruseFcltMng/fcltReg/pbnstReg/index.tsx | 63 +++++++++++++------ .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 3 +- apps/wr/app/store/store.tsx | 2 +- apps/wr/components/lib/func/common.tsx | 6 +- 6 files changed, 65 insertions(+), 40 deletions(-) diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 75d718411..51b5c255a 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -31,7 +31,6 @@ import { btnClass } from "@/app/store/common/code"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; import { useCallback, useEffect, useRef, useState } from "react"; import ListDiv from "@common/business_components/ui/list_div"; -import { tableData } from "@/components/lib/func/common"; import type { customPbnst, fcBizType, @@ -56,7 +55,6 @@ import { useAlertStore } from "@/src/shared/lib"; export default function PublicReuseFaciltyInsert() { const { auth, - code, pbnst, pubHasuInit, pbnstInsert, @@ -112,11 +110,11 @@ export default function PublicReuseFaciltyInsert() { useInitRef.current = true; }, []); - useEffect(() => { - if (useInitRef.current == true && laeSeCd !== undefined) { - pubHasuInit("1", laeSeCd); //page: string, sggOrCity: string - } - }, [useInitRef.current, laeSeCd]); + // useEffect(() => { + // if (useInitRef.current == true && laeSeCd !== undefined) { + // pubHasuInit(1, laeSeCd); + // } + // }, [useInitRef.current, laeSeCd]); const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => { const data = writeRgtrAndMdfr(valuse.items); @@ -156,7 +154,7 @@ export default function PublicReuseFaciltyInsert() { message += "하수재이용 시설 사업 "; } alert(message + "오류 입니다 "); - pubHasuInit("1", laeSeCd); + pubHasuInit(1, laeSeCd); } }; if (await confirm(t("isUpdatetMsg"))) { @@ -233,10 +231,12 @@ export default function PublicReuseFaciltyInsert() { }, [items]); useEffect(() => { - if (code.sggCd.length && pbnstHasuRes.length > 0) { - setbdstTable(tableData(pbnstHasuRes, { code })); + if (pbnstHasuRes.length > 0) { + setbdstTable(pbnstHasuRes); + } else { + setbdstTable([]); } - }, [code, pbnstHasuRes]); + }, [pbnstHasuRes]); const cellClick = (val: number | undefined) => { if (val === undefined) return; @@ -288,7 +288,8 @@ export default function PublicReuseFaciltyInsert() { }, [pbnstRes, append, selectRow]); useEffect(() => { - pubHasuInit(String(pageNation), laeSeCd); // 해당 지자체의 하수처리시설 조회 + if (laeSeCd === undefined) return; + pubHasuInit(pageNation, laeSeCd); // 해당 지자체의 하수처리시설 조회 isResetPage(false); setSelectRow(undefined); setSelectedRowIndex(-1); @@ -316,9 +317,9 @@ export default function PublicReuseFaciltyInsert() { // size={"sm"} onClick={() => { if (searchTxt && searchTxt?.length > 0) { - pubHasuSearch(String(pageNation), laeSeCd, searchTxt); + pubHasuSearch(pageNation, laeSeCd, searchTxt); } else { - pubHasuInit(String(pageNation), laeSeCd); + pubHasuInit(pageNation, laeSeCd); } isResetPage(true); }} diff --git a/apps/wr/app/api/proxy/[...url]/route.ts b/apps/wr/app/api/proxy/[...url]/route.ts index e847e8ad2..d779aec83 100644 --- a/apps/wr/app/api/proxy/[...url]/route.ts +++ b/apps/wr/app/api/proxy/[...url]/route.ts @@ -75,7 +75,7 @@ async function handler( if (refreshToken) { response.cookies.set(REFRESH_TOKEN, refreshToken, { httpOnly: true, - sameSite: "strict", // 다른 사이트에서 들어오는 모든 요청에 대해 쿠키를 보내지 않는 가장 강력한 설정 + sameSite: "lax", // 다른 사이트에서 들어오는 모든 요청에 대해 쿠키를 보내지 않는 가장 강력한 설정 domain: getCookieDomain(), path: "/", }); diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 6340f1082..887f437a7 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -5,6 +5,7 @@ import { getFetch, postFectch, putFectch, + getFetchWithCount } from "@/components/lib/api"; import { DEFAULT_LIST_SIZE, SITE_ID } from "@/src/shared/config"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; @@ -61,10 +62,11 @@ export type pubFacState = { dmdComList: any[]; apiMessage: string; pbnstHasuResCount: number; + fclts: any[] | null; }; }; type pubFacActions = { - pubHasuInit: (page: string, sggOrCity: string) => void; + pubHasuInit: (page: number, sggOrCity: string) => void; pbnstRegClick: (pubHasuRes: pubHasuType) => void; //pbnstReg: (txt: string | undefined) => void; pbnstInsert(pbnstRes: customPbnst): Promise; @@ -73,7 +75,7 @@ type pubFacActions = { fileDownLoadName: (atflCd: string, fileName: string) => void; pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; - pubHasuSearch: (page: string, sggOrCity: string, searchTxt: string) => void; + pubHasuSearch: (page: number, sggOrCity: string, searchTxt: string) => void; getFcOrgwts: (fcltPkList: string[], size: number) => void; }; export type pubFacType = pubFacState & pubFacActions; @@ -98,38 +100,59 @@ export const pubFacStateExport: pubFacState = { dmdComList: [], apiMessage: "", pbnstHasuResCount: 1, + fclts: null, }, }; // 재사용시설에 대한 정보 조회 -export const checkWrRegList = async () => { +export const checkWrRegList = async (get: any, set: any) => { + const { pbnst } = get(); + + if (Array.isArray(pbnst.fclts)) { + return pbnst.fclts; + } + const wrRegList = await getFetch("wr", `/reuseFc/pubFc`); - return wrRegList; + const fclts = Array.isArray(wrRegList) ? wrRegList : []; + + set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + fclts, + }, + })); + + return fclts; }; // 하수처리시설 정보 조회 const hasuListFetch = async ( - page: string, + get: any, + set: any, + page: number = 1, sggOrCity: string, // 해당 지자체의 하수처리시설 조회 searchTxt?: string ) => { - const checkWrRegListRes = await checkWrRegList(); // 재사용시설에 대한 정보 조회 + const wrData = await checkWrRegList(get, set); // 재사용시설에 대한 정보 조회 + const wrBscFctCdSet = new Set( + wrData + .map((wrItem: any) => (typeof wrItem === "string" ? wrItem.trim() : "")) + ); - let url = `/prcsFclt/ruseInfo/${page ? page : 1}/${DEFAULT_LIST_SIZE}/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`; - - const data = checkWrRegListRes.filter((item: string) => item !== ""); - if (searchTxt) { - url = url + `/${searchTxt}`; + let url = `/prcsFclt/ruseInfo/reg/${page}/${DEFAULT_LIST_SIZE}/A/${sggOrCity ? sggOrCity : "0"}/0/1/SW`; + if (searchTxt?.trim()) { + url += `?swtrmtFcltNm=${encodeURIComponent(searchTxt.trim())}`; } - const rainRes = await postFectch(url, data, fetchType.COMMON); // fo + const fcltRes = await getFetchWithCount(fetchType.COMMON, url); // fo - const hasuList = rainRes.data.map((item: any) => { + const hasuList = fcltRes.data.map((item: any) => { return { ...item, fctCpc: Number(item.fctCpc) || 0, - ruse: item.ruse === false ? "N" : "Y", + ruse: item?.bscFctCd && wrBscFctCdSet.has(item.bscFctCd) ? "Y" : "N", }; }); - return { data: hasuList, count: rainRes.count }; + return { data: hasuList, count: fcltRes.count }; }; const initFetch = async (ruseFcltPk: string | undefined) => { @@ -172,12 +195,12 @@ export const writeRgtrAndMdfr = (data: customPbnst[]) => { return data; }; -export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { +export const pubFacActionsExport: (set: any, get: any) => pubFacActions = (set: any, get: any) => { return { // 하수처리시설을 조회한다(운영실태) - pubHasuInit: async (page: string, sggOrCity: string) => { + pubHasuInit: async (page: number, sggOrCity: string) => { try { - const pbnstHasuRes = await hasuListFetch(page, sggOrCity); // /prcsFclt/ruseInfo + const pbnstHasuRes = await hasuListFetch(get, set, page, sggOrCity); // /prcsFclt/ruseInfo return set((state: pubFacState) => ({ ...state, pbnst: { @@ -192,12 +215,12 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { }, // 하수처리시설을 조회한다(운영실태) (처리시설명 포함) pubHasuSearch: async ( - page: string, + page: number, sggOrCity: string, searchTxt: string ) => { try { - const pbnstHasuRes = await hasuListFetch(page, sggOrCity, searchTxt); + const pbnstHasuRes = await hasuListFetch(get, set, page, sggOrCity, searchTxt); return set((state: pubFacState) => ({ ...state, pbnst: { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 35a3fb3d7..f89320c45 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -47,7 +47,7 @@ export type pbnstSttnState = { pbnstSttnResCount: number; excelList: []; fclts: string[]; - isInit: boolean; + isInit: boolean; // wr 하수재이용시설 조회했는지 점검 }; }; @@ -254,6 +254,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( return set((state: pbnstSttnState) => ({ pbnstSttn: { ...state.pbnstSttn, + isInit: true, // wr 하수재이용시설을 조회 여부?? fclts: fclts, }, })); diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index 3024d1cb1..c90fc18bf 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -346,7 +346,7 @@ export const StoreZus = ( return { ...initState, ...comFcltSearchAction(set), - ...pubFacActionsExport(set), + ...pubFacActionsExport(set, get), ...rainFacActionsExport(set), ...rswtFacActionsExport(set), ...matDmdActionsExport(set), diff --git a/apps/wr/components/lib/func/common.tsx b/apps/wr/components/lib/func/common.tsx index 1d9d4a43e..7afeda993 100644 --- a/apps/wr/components/lib/func/common.tsx +++ b/apps/wr/components/lib/func/common.tsx @@ -66,9 +66,9 @@ export const tableData = (data: any, code: comCodeState) => { ...item, sggText: sggText ?? "없음", cityText: cityText ?? "없음", - bdsgUsgText: bdsgUsgText, - lawTrgtYn: lawTrgtYn, - grntchBdstCertGrdText: grntchBdstCertGrdText, + bdsgUsgText: bdsgUsgText, // 건물용도명 + lawTrgtYn: lawTrgtYn, // 법정대상 여부 + grntchBdstCertGrdText: grntchBdstCertGrdText, // 녹색건축인증등급명 }; } else { returnData = { From 6df6e612bcc80f86efa5e61348e09762dfc41c04 Mon Sep 17 00:00:00 2001 From: ljpark Date: Fri, 5 Jun 2026 17:44:51 +0900 Subject: [PATCH 03/52] =?UTF-8?q?wr:=20=EA=B3=B5=ED=86=B5=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A1=B0=ED=9A=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/api/common-codes/route.ts | 207 +++++++++++++++++++++ apps/wr/app/store/common/code/index.ts | 76 +++++++- apps/wr/src/app/providers/app-provider.tsx | 19 +- 3 files changed, 294 insertions(+), 8 deletions(-) create mode 100644 apps/wr/app/api/common-codes/route.ts diff --git a/apps/wr/app/api/common-codes/route.ts b/apps/wr/app/api/common-codes/route.ts new file mode 100644 index 000000000..ded38eadf --- /dev/null +++ b/apps/wr/app/api/common-codes/route.ts @@ -0,0 +1,207 @@ +import { SITE_ID } from "@/src/shared/config"; +import { NextResponse } from "next/server"; + +export const revalidate = 60 * 60 * 24; + +type SelectDataType = { + text: string; + val: string; +}; + +type EnvPartSelectDataType = SelectDataType & { + adstDliStrCd: string; +}; + +const codeMapping = { + WR001: "bdstUsgCd", + WR002: "rswtBdstType", + WR003: "rainFcltCd", + WR004: "bdstGrntchClass", + WR005: "rswtPrscCdMthdCd", + WR006: "orgwtKndCd", + WR007: "ruseMngMtd", + WR008: "rusePrcsMthdCd", + WR009: "erctUswtrPrcsMeth", + WR010: "ruseFcltSpot", + WR011: "pplQulity", + WR012: "pplLenght", + WR013: "bdstFilterYn", + WR014: "rainRswtMng", + WR015: "rainFcltFlowRate", + WR016: "dmdUszCd", + WR017: "sewageInFcltUse", + WR018: "sewageOutFclttUse", + WR019: "htdPowerMthdCd", + WR020: "htdUtztnUsgCd", +} as const; + +const defaultHeaders = { + accept: "application/json", + "X-Site-Id": SITE_ID, +}; + +function getServerBaseUrl() { + const port = process.env.PORT ?? process.env.NEXT_PUBLIC_PORT ?? "3000"; + const proxyHost = process.env.NEXT_PUBLIC_PROXY_HOST; + + if (process.env.NODE_ENV === "production" && process.env.HOSTNAME) { + return `http://${process.env.HOSTNAME}:${port}`; + } + + return proxyHost || `http://localhost:${port}`; +} + +async function fetchJson(url: string, cookieHeader?: string) { + const response = await fetch(url, { + method: "GET", + headers: { + ...defaultHeaders, + ...(cookieHeader ? { cookie: cookieHeader } : {}), + }, + next: { revalidate }, + }); + + if (!response.ok) { + throw new Error(`Failed to fetch ${url}: ${response.status}`); + } + + return response.json(); +} + +async function fetchOperationData(path: string, cookieHeader?: string) { + const json = await fetchJson( + `${getServerBaseUrl()}/operation-service${path}`, + cookieHeader + ); + return json.data; +} + +async function fetchCmsData(path: string, cookieHeader?: string) { + return fetchJson(`${getServerBaseUrl()}${path}`, cookieHeader); +} + +async function fetchCommonCodesByKeys(keys: string[], cookieHeader?: string) { + const targets = [...new Set(keys)].filter( + (cd) => Boolean(codeMapping[cd as keyof typeof codeMapping]) + ); + + const entries = await Promise.all( + targets.map(async (cd) => { + const mapping = codeMapping[cd as keyof typeof codeMapping]; + const lwCd = await fetchCmsData( + `/cms-service/api/v1/lwpo-cds/up-cd/${cd}`, + cookieHeader + ); + const list = Array.isArray(lwCd) ? lwCd : (lwCd.content ?? []); + + return [ + mapping, + list.map((it: any) => ({ + text: it.lwpoCdNm, + val: it.lwpoCd, + })), + ] as const; + }) + ); + + return Object.fromEntries(entries) as Record; +} + +export async function GET(request: Request) { + try { + const cookieHeader = request.headers.get("cookie") ?? ""; + const [sgg, city, rvbsn, mdmbsn, lgbsn, lclgvrnmnt, upCd] = + await Promise.all([ + fetchOperationData("/addr/sgg", cookieHeader), + fetchOperationData("/addr/city", cookieHeader), + fetchOperationData("/addr/sarea", cookieHeader), + fetchOperationData("/addr/midArea", cookieHeader), + fetchOperationData("/addr/largeArea", cookieHeader), + fetchOperationData("/addr/govArea", cookieHeader), + fetchCmsData( + "/cms-service/api/v1/up-codes?keyword=&upCd=&cdSe=&useYn=Y&siteId=WR&page=0&size=100&sort=string", + cookieHeader + ), + ]); + + const upWrCode: string[] = (upCd.content ?? []) + .filter((item: any) => item.upCd.slice(0, 2) === "WR") + .map((cd: any) => cd.upCd); + + const lwCds = await fetchCommonCodesByKeys(upWrCode, cookieHeader); + + const payload = { + sggCd: [ + ...((sgg ?? []).map((item: any) => ({ + text: item.gugun || "", + val: String(item.adstDstrCd) || "", + })) as SelectDataType[]), + ], + cityCd: [ + { val: "0", text: "전체" }, + ...((city ?? []).map((item: any) => ({ + val: item.adstDstrCd, + text: item.sido, + })) as SelectDataType[]), + ], + rvbsnCd: [ + { val: "0", text: "전체" }, + ...((rvbsn ?? []).map((item: any) => ({ + val: item.rvbsnCd, + text: item.rvbsn, + })) as SelectDataType[]), + ], + mdmbsnCd: [ + { val: "0", text: "전체" }, + ...((mdmbsn ?? []).map((item: any) => ({ + val: item.rvbsnCd, + text: item.mdmbsn, + })) as SelectDataType[]), + ], + lgbsnCd: [ + { val: "0", text: "전체" }, + ...((lgbsn ?? []).map((item: any) => ({ + val: item.rvbsnCd, + text: item.lgbsn, + })) as SelectDataType[]), + ], + lclgvrnmntCd: [ + { val: "0", text: "전체", adstDliStrCd: "" }, + ...((lclgvrnmnt ?? []).map((item: any) => ({ + val: item.lclgvrnmntCd, + text: item.lclgvrnmntNm, + adstDliStrCd: item.adstDliStrCd || "", + })) as EnvPartSelectDataType[]), + ], + rainFcltCd: lwCds["rainFcltCd"] ?? [], + bdstUsgCd: lwCds["bdstUsgCd"] ?? [], + orgwtKndCd: lwCds["orgwtKndCd"] ?? [], + pplQulity: lwCds["pplQulity"] ?? [], + pplLenght: lwCds["pplLenght"] ?? [], + dmdUszCd: lwCds["dmdUszCd"] ?? [], + sewageOutFclttUse: lwCds["sewageOutFclttUse"] ?? [], + rainRswtMng: lwCds["rainRswtMng"] ?? [], + rainFcltFlowRate: lwCds["rainFcltFlowRate"] ?? [], + ruseMngMtd: lwCds["ruseMngMtd"] ?? [], + rusePrcsMthdCd: lwCds["rusePrcsMthdCd"] ?? [], + erctUswtrPrcsMeth: lwCds["erctUswtrPrcsMeth"] ?? [], + bdstGrntchClass: lwCds["bdstGrntchClass"] ?? [], + htdPowerMthdCd: lwCds["htdPowerMthdCd"] ?? [], + htdUtztnUsgCd: lwCds["htdUtztnUsgCd"] ?? [], + rswtBdstType: lwCds["rswtBdstType"] ?? [], + bdstTotalUsgType: (lwCds["bdstUsgCd"] ?? []).concat(lwCds["rswtBdstType"] ?? []), + }; + + return NextResponse.json(payload, { + headers: { + "Cache-Control": "s-maxage=86400, stale-while-revalidate=3600", + }, + }); + } catch (error) { + console.error("Failed to load common codes:", error); + return NextResponse.json( + { message: "Failed to load common codes" }, + { status: 500 } + ); + } +} diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index 4f7896de0..0ddb7fc8c 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -371,18 +371,80 @@ export const codeActionExport: (set: any, get:any) => comCodeActions = (set: any }, initCommonCodes: async () => { if (get().code.isInit) return; + const response = await fetch("/api/common-codes", { + method: "GET", + headers: { + accept: "application/json", + }, + }); - await getSggCd(set); - await getCityCd(set); - await getRegionCd(set); - await getMiddleRegionCd(set); - await getUnitWaterShedCd(set); - await getEnvPartCd(set); - await getCommonUpCd(set); + if (!response.ok) { + throw new Error(`공통 코드 조회 실패: ${response.status}`); + } + + const data = await response.json(); + + lwCds["rainFcltCd"] = data.rainFcltCd ?? lwCds["rainFcltCd"] ?? []; + lwCds["bdstUsgCd"] = data.bdstUsgCd ?? lwCds["bdstUsgCd"] ?? []; + lwCds["orgwtKndCd"] = data.orgwtKndCd ?? lwCds["orgwtKndCd"] ?? []; + lwCds["pplQulity"] = data.pplQulity ?? lwCds["pplQulity"] ?? []; + lwCds["pplLenght"] = data.pplLenght ?? lwCds["pplLenght"] ?? []; + lwCds["dmdUszCd"] = data.dmdUszCd ?? lwCds["dmdUszCd"] ?? []; + lwCds["sewageOutFclttUse"] = + data.sewageOutFclttUse ?? lwCds["sewageOutFclttUse"] ?? []; + lwCds["rainRswtMng"] = data.rainRswtMng ?? lwCds["rainRswtMng"] ?? []; + lwCds["rainFcltFlowRate"] = + data.rainFcltFlowRate ?? lwCds["rainFcltFlowRate"] ?? []; + lwCds["ruseMngMtd"] = data.ruseMngMtd ?? lwCds["ruseMngMtd"] ?? []; + lwCds["rusePrcsMthdCd"] = + data.rusePrcsMthdCd ?? lwCds["rusePrcsMthdCd"] ?? []; + lwCds["erctUswtrPrcsMeth"] = + data.erctUswtrPrcsMeth ?? lwCds["erctUswtrPrcsMeth"] ?? []; + lwCds["bdstGrntchClass"] = + data.bdstGrntchClass ?? lwCds["bdstGrntchClass"] ?? []; + lwCds["htdPowerMthdCd"] = + data.htdPowerMthdCd ?? lwCds["htdPowerMthdCd"] ?? []; + lwCds["htdUtztnUsgCd"] = + data.htdUtztnUsgCd ?? lwCds["htdUtztnUsgCd"] ?? []; + lwCds["rswtBdstType"] = + data.rswtBdstType ?? lwCds["rswtBdstType"] ?? []; + lwCds["bdstTotalUsgType"] = + data.bdstTotalUsgType ?? lwCds["bdstTotalUsgType"] ?? []; set((state) => ({ code: { ...state.code, + sggCd: data.sggCd ?? state.code.sggCd, + cityCd: data.cityCd ?? state.code.cityCd, + rvbsnCd: data.rvbsnCd ?? state.code.rvbsnCd, + mdmbsnCd: data.mdmbsnCd ?? state.code.mdmbsnCd, + lgbsnCd: data.lgbsnCd ?? state.code.lgbsnCd, + lclgvrnmntCd: data.lclgvrnmntCd ?? state.code.lclgvrnmntCd, + rainFcltCd: data.rainFcltCd ?? state.code.rainFcltCd, + bdstUsgCd: data.bdstUsgCd ?? state.code.bdstUsgCd, + orgwtKndCd: data.orgwtKndCd ?? state.code.orgwtKndCd, + pplQulity: data.pplQulity ?? state.code.pplQulity, + pplLenght: data.pplLenght ?? state.code.pplLenght, + dmdUszCd: data.dmdUszCd ?? state.code.dmdUszCd, + sewageOutFclttUse: + data.sewageOutFclttUse ?? state.code.sewageOutFclttUse, + rainRswtMng: data.rainRswtMng ?? state.code.rainRswtMng, + rainFcltFlowRate: + data.rainFcltFlowRate ?? state.code.rainFcltFlowRate, + ruseMngMtd: data.ruseMngMtd ?? state.code.ruseMngMtd, + rusePrcsMthdCd: + data.rusePrcsMthdCd ?? state.code.rusePrcsMthdCd, + erctUswtrPrcsMeth: + data.erctUswtrPrcsMeth ?? state.code.erctUswtrPrcsMeth, + bdstGrntchClass: + data.bdstGrntchClass ?? state.code.bdstGrntchClass, + htdPowerMthdCd: + data.htdPowerMthdCd ?? state.code.htdPowerMthdCd, + htdUtztnUsgCd: + data.htdUtztnUsgCd ?? state.code.htdUtztnUsgCd, + rswtBdstType: data.rswtBdstType ?? state.code.rswtBdstType, + bdstTotalUsgType: + data.bdstTotalUsgType ?? state.code.bdstTotalUsgType, isInit: true, }, })); diff --git a/apps/wr/src/app/providers/app-provider.tsx b/apps/wr/src/app/providers/app-provider.tsx index 63df8349d..33f2e728a 100644 --- a/apps/wr/src/app/providers/app-provider.tsx +++ b/apps/wr/src/app/providers/app-provider.tsx @@ -1,5 +1,6 @@ "use client"; +import { useEffect } from "react"; import { DndProvider } from "react-dnd"; import { MultiBackend, getBackendOptions } from "@minoru/react-dnd-treeview"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; @@ -16,7 +17,10 @@ import i18next from "i18next"; import { I18nextProvider } from "react-i18next"; import { Toaster } from "react-hot-toast"; import koBase from "@/public/locales/ko/message.json"; -import { StoreProvider as WrStoreProvider } from "@/app/store"; +import { + StoreProvider as WrStoreProvider, + useWrStore, +} from "@/app/store"; //import { LoginApi } from "@/src/entities/auth"; //import { useEffect } from "react"; import { setCookie } from "@/src/shared/lib/cookie"; @@ -34,6 +38,18 @@ i18n.init({ }, }); +function CommonCodeInitializer() { + const isInit = useWrStore((state) => state.code.isInit); + const initCommonCodes = useWrStore((state) => state.initCommonCodes); + + useEffect(() => { + if (isInit) return; + initCommonCodes(); + }, [isInit, initCommonCodes]); + + return null; +} + const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { const queryClient = new QueryClient(); return ( @@ -49,6 +65,7 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { > + {children} From 66db81071e0b5bd158952941a8ffd34200935e3e Mon Sep 17 00:00:00 2001 From: ljpark Date: Mon, 8 Jun 2026 09:06:58 +0900 Subject: [PATCH 04/52] =?UTF-8?q?wr:=20=EB=B9=8C=EB=93=9C=EC=98=A4?= =?UTF-8?q?=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/app/api/common-codes/route.ts | 3 ++- apps/wr/app/store/map/pbnstMap/index.tsx | 10 ++++++---- apps/wr/app/store/store.tsx | 9 +-------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/apps/wr/app/api/common-codes/route.ts b/apps/wr/app/api/common-codes/route.ts index ded38eadf..aa62b261b 100644 --- a/apps/wr/app/api/common-codes/route.ts +++ b/apps/wr/app/api/common-codes/route.ts @@ -1,7 +1,8 @@ +export const dynamic = "force-dynamic"; import { SITE_ID } from "@/src/shared/config"; import { NextResponse } from "next/server"; -export const revalidate = 60 * 60 * 24; +export const revalidate = 86400; //60 * 60 * 24; type SelectDataType = { text: string; diff --git a/apps/wr/app/store/map/pbnstMap/index.tsx b/apps/wr/app/store/map/pbnstMap/index.tsx index 18f9abfe2..80eb2697a 100644 --- a/apps/wr/app/store/map/pbnstMap/index.tsx +++ b/apps/wr/app/store/map/pbnstMap/index.tsx @@ -9,13 +9,15 @@ import { excelHasuMapParsing } from "./excel"; export const pbnMapTableSize = 20; const hasuListFetch = async ( + get: any, + set: any, page: number, pageTotal: number, reurnValue: ReturnType, searchNm?: string ) => { let url = `/prcsFclt/ruseInfo/${page}/${pageTotal}/`; - const checkWrRegListRes = await checkWrRegList(); + const checkWrRegListRes = await checkWrRegList(get, set); if (reurnValue.partValue === "A") { url += `${reurnValue.partValue}/${ @@ -92,7 +94,7 @@ export const pbnMapStateExport: pbnMapState = { }, }; -export const pbnMapActionsExport: (set: any) => pbnMapActions = (set: any) => { +export const pbnMapActionsExport: (set: any, get: any) => pbnMapActions = (set: any, get: any) => { return { pbnMapInit: async ( page: number, @@ -100,7 +102,7 @@ export const pbnMapActionsExport: (set: any) => pbnMapActions = (set: any) => { reurnValue: ReturnType ) => { try { - const pubMapRes = await hasuListFetch(page, pageTotal, reurnValue); + const pubMapRes = await hasuListFetch(get, set, page, pageTotal, reurnValue); set((state: pbnMapState) => { return { ...state, @@ -144,7 +146,7 @@ export const pbnMapActionsExport: (set: any) => pbnMapActions = (set: any) => { txt: string, ) => { try { - const hasuMapRes = await hasuListFetch(page, pageTotal, reurnValue, txt); + const hasuMapRes = await hasuListFetch(get, set, page, pageTotal, reurnValue, txt); if (isExcel) { const hasuMapExcelList = excelHasuMapParsing( hasuMapRes diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index c90fc18bf..268be198b 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -2,13 +2,6 @@ import { createStore } from "zustand/vanilla"; import { codeActionExport, comCodeStateExport, - getCityCd, - getCommonUpCd, - getEnvPartCd, - getMiddleRegionCd, - getRegionCd, - getSggCd, - getUnitWaterShedCd, type comCodeState, type comCodeType, } from "./common/code"; @@ -373,7 +366,7 @@ export const StoreZus = ( ...rswtStatActionsExport(set), ...authActionsExport(set,get), ...commonMapActionsExport(set), - ...pbnMapActionsExport(set), + ...pbnMapActionsExport(set, get), ...rainMapActionsExport(set), ...rswtMapActionsExport(set), ...htdfMapActionsExport(set), From 8c1a976b5bc23b9dbcb5e14e43a86a9deb8a0701 Mon Sep 17 00:00:00 2001 From: ljpark Date: Mon, 8 Jun 2026 11:02:11 +0900 Subject: [PATCH 05/52] wr: isInit --- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 27 +++++++++++++------ .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 24 +++++++++-------- apps/wr/src/app/providers/app-provider.tsx | 7 ++++- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index a481f66a1..0e49c4c6f 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -134,19 +134,30 @@ export default function PbnstSttn() { useEffect(() => { getLaeSeCdCheck(); useInitRef.current = true; + if (!pbnstSttn.isFcltsLoaded) { + getFlcts(); // 하수재이용시설 조회 + } }, []); useEffect(() => { - if (!pbnstSttn.isInit) { - getFlcts(); // 하수재이용시설 조회 - } - }, [pbnstSttn.isInit]); - - useEffect(() => { - if (useInitRef.current === true && laeSeCd !== undefined && fclts.length > 0) { + if ( + useInitRef.current === true && + laeSeCd !== undefined && + pbnstSttn.isFcltsLoaded && + !pbnstSttn.isTableLoaded && + fclts.length > 0 + ) { pbnSttnInit("1", String(DEFAULT_LIST_SIZE), getFixedSearchValue(ref.current), searchYear, fclts); } - }, [fclts, laeSeCd, searchYear, pbnSttnInit, getFixedSearchValue]); + }, [ + fclts, + laeSeCd, + pbnstSttn.isFcltsLoaded, + pbnstSttn.isTableLoaded, + searchYear, + pbnSttnInit, + getFixedSearchValue, + ]); useEffect(() => { if (pbnstSttnRes && pbnstSttnRes.length > 0) { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index f89320c45..b1cf957e6 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -47,7 +47,8 @@ export type pbnstSttnState = { pbnstSttnResCount: number; excelList: []; fclts: string[]; - isInit: boolean; // wr 하수재이용시설 조회했는지 점검 + isFcltsLoaded: boolean; // wr 하수재이용시설 목록 조회 여부 + isTableLoaded: boolean; // 현황 테이블 초기 조회 여부 }; }; @@ -100,7 +101,8 @@ export const pbnstSttnStateExport: pbnstSttnState = { pbnstSearchData: [], excelList: [], fclts: [], - isInit: false, + isFcltsLoaded: false, + isTableLoaded: false, }, }; @@ -251,13 +253,13 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( //등록된 하수재이용시설을 조회한다. getFlcts: async () => { const fclts = await getFetch(fetchType.WR, "/reuseFc/pubFc"); - return set((state: pbnstSttnState) => ({ - pbnstSttn: { - ...state.pbnstSttn, - isInit: true, // wr 하수재이용시설을 조회 여부?? - fclts: fclts, - }, - })); + return set((state: pbnstSttnState) => ({ + pbnstSttn: { + ...state.pbnstSttn, + isFcltsLoaded: true, + fclts: fclts, + }, + })); }, //테이블 헤드를 조정한다. pbnstChSttnHead: async ( @@ -314,7 +316,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes.data, pbnstSttnResCount: pbnstSttnRes.count, - // isInit: false, + isTableLoaded: true, }, }; }); @@ -348,8 +350,8 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes.data, pbnstSttnResCount: pbnstSttnRes.count, - isInit: false, pbnstDetail: {} as customPbnst, + isTableLoaded: true, }, }; }); diff --git a/apps/wr/src/app/providers/app-provider.tsx b/apps/wr/src/app/providers/app-provider.tsx index 33f2e728a..f54dfea52 100644 --- a/apps/wr/src/app/providers/app-provider.tsx +++ b/apps/wr/src/app/providers/app-provider.tsx @@ -21,6 +21,7 @@ import { StoreProvider as WrStoreProvider, useWrStore, } from "@/app/store"; +import { usePathname } from "next/navigation"; //import { LoginApi } from "@/src/entities/auth"; //import { useEffect } from "react"; import { setCookie } from "@/src/shared/lib/cookie"; @@ -41,11 +42,15 @@ i18n.init({ function CommonCodeInitializer() { const isInit = useWrStore((state) => state.code.isInit); const initCommonCodes = useWrStore((state) => state.initCommonCodes); + const pathname = usePathname(); + const isLoginPage = + pathname === "/auth/login" || pathname?.startsWith("/auth/login/"); useEffect(() => { + if (isLoginPage) return; if (isInit) return; initCommonCodes(); - }, [isInit, initCommonCodes]); + }, [isInit, initCommonCodes, isLoginPage]); return null; } From 814365d7debc123c9c862f9867aa6299d655d670 Mon Sep 17 00:00:00 2001 From: ljpark Date: Mon, 8 Jun 2026 11:44:12 +0900 Subject: [PATCH 06/52] =?UTF-8?q?wr:=20common-codes=20error=20=EB=A9=94?= =?UTF-8?q?=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 --- apps/wr/app/api/common-codes/route.ts | 15 +++++++++++++-- apps/wr/app/store/common/code/index.ts | 19 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/apps/wr/app/api/common-codes/route.ts b/apps/wr/app/api/common-codes/route.ts index aa62b261b..ae0c175cd 100644 --- a/apps/wr/app/api/common-codes/route.ts +++ b/apps/wr/app/api/common-codes/route.ts @@ -63,7 +63,12 @@ async function fetchJson(url: string, cookieHeader?: string) { }); if (!response.ok) { - throw new Error(`Failed to fetch ${url}: ${response.status}`); + const responseText = await response.text(); + throw new Error( + `Failed to fetch ${url}: ${response.status} ${response.statusText}${ + responseText ? ` - ${responseText}` : "" + }` + ); } return response.json(); @@ -200,8 +205,14 @@ export async function GET(request: Request) { }); } catch (error) { console.error("Failed to load common codes:", error); + const message = + error instanceof Error ? error.message : "Failed to load common codes"; + return NextResponse.json( - { message: "Failed to load common codes" }, + { + message: "Failed to load common codes", + detail:message , + }, { status: 500 } ); } diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index 0ddb7fc8c..5e6600960 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -379,7 +379,24 @@ export const codeActionExport: (set: any, get:any) => comCodeActions = (set: any }); if (!response.ok) { - throw new Error(`공통 코드 조회 실패: ${response.status}`); + let errorMessage = `공통 코드 조회 실패: ${response.status}`; + + try { + const errorBody = await response.json(); + if (errorBody?.detail) { + errorMessage += ` - ${errorBody.detail}`; + } else if (errorBody?.message) { + errorMessage += ` - ${errorBody.message}`; + } + } catch { + const errorText = await response.text(); + if (errorText) { + errorMessage += ` - ${errorText}`; + } + } + + console.error("initCommonCodes failed:", errorMessage); + throw new Error(errorMessage); } const data = await response.json(); From 7c6c43b33427268705570808caf15972bf4595f8 Mon Sep 17 00:00:00 2001 From: jangwoong Date: Mon, 8 Jun 2026 18:06:01 +0900 Subject: [PATCH 07/52] =?UTF-8?q?[as=20frontend]=20=EC=8B=9C=EB=8F=84,=20?= =?UTF-8?q?=EA=B5=B0=EA=B5=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entities/instl-sncn/model/instl-sncn-interface.ts | 2 ++ apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx | 4 ++-- apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx | 9 ++++----- apps/as/src/pages/instl-sncn/ui/cnfm-view-page.tsx | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts b/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts index e9a4060ab..b3e363aef 100644 --- a/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts +++ b/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts @@ -22,6 +22,8 @@ export interface InstlSncnMngSearchParams { } export interface InstlSncnMng { + gugun: string; + sido: string; instlSncnDocNo: string; admdstCd: string; sidoNm?: string; diff --git a/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx b/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx index 0f5d24a62..f1635cff3 100644 --- a/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx @@ -253,8 +253,8 @@ function CnfmListPage() { className="cnfm-row-clickable" onClick={() => router.push(`/instl-sncn/${row.instlSncnDocNo}`)} > - {row.sidoNm || "-"} - {row.sggNm || "-"} + {row.sido || "-"} + {row.gugun|| "-"} {row.bizNm || "-"} {row.taskSeCdNm || row.taskSeComCd || "-"} {row.chrgrNm || row.aplcntNm || "-"} diff --git a/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx b/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx index 5bcd8925c..95a85a40f 100644 --- a/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx @@ -204,7 +204,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { const [docSeComCd] = useState("INSTL"); const [taskSeComCdNm, setTaskSeComCdNm] = useState( - () => (currentDet?.taskSeComCdNm as string) ?? "재이용수", + () => (currentDet?.taskSeComCdNm as string) ?? "", ); const [taskSeComCd, setTaskSeComCd] = useState(() => (currentDet?.taskSeComCd as string) ?? "RE"); @@ -212,7 +212,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { // do not override server-provided initialData (modify mode) if (currentDet) return; - const raw = sessionStorage.getItem(INSTL_SNCN_REGISTER_SELECTION_KEY); + const raw = sessionStorage.getItem(INSTL_SNCN_REGISTER_SELECTION_KEY); if (!raw) return; try { @@ -220,7 +220,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { taskSeComCdList?: string[]; taskSeComCdNmList?: string[]; }; - + setTaskSeComCd(parsed.taskSeComCdList?.join(",") || "RE"); setTaskSeComCdNm(parsed.taskSeComCdNmList?.join(",") || "재이용수"); } catch { @@ -436,7 +436,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { // 수정모드인 경우 서버가 전달한 업무구분(단일 혹은 콤마로 결합된 복수)을 상태로 복원 setTaskSeComCd(det.taskSeComCd); - setTaskSeComCdNm(det.taskSeComCdNm ); + setTaskSeComCdNm(det.taskSeCdNm ); // 매핑 완료 플래그 설정 — 이후 동일 컴포넌트 인스턴스에서 재매핑 방지 initialMappedRef.current = true; @@ -634,7 +634,6 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { const { data: cklstTree = [] } = useQuery({ queryKey: ["cklstTree", docSeComCd, taskSeComCd], queryFn: async () => { - console.log("Fetching checklist tree with", { docSeComCd, taskSeComCd }); // support comma-separated task codes (e.g. "RE,SP") by splitting const raw = taskSeComCd ?? ""; const codes = raw diff --git a/apps/as/src/pages/instl-sncn/ui/cnfm-view-page.tsx b/apps/as/src/pages/instl-sncn/ui/cnfm-view-page.tsx index 316d466e1..7b35d11c8 100644 --- a/apps/as/src/pages/instl-sncn/ui/cnfm-view-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/cnfm-view-page.tsx @@ -287,13 +287,13 @@ function CnfmViewPage({ id }: { id: string }) { {det.bizCn || "-"} - 업무구분 + 구분 {det.taskSeCdNm || det.taskSeComCd || "-"} 행정동ID {det.admdstCd || "-"} - 사업구분(인가구분) + 사업구분 {det.sncnSeComCd || "-"} From e5dc3472763e4f0b01b784bd377352601d0192ad Mon Sep 17 00:00:00 2001 From: jangwoong Date: Mon, 8 Jun 2026 18:21:35 +0900 Subject: [PATCH 08/52] =?UTF-8?q?[as=20frontend]=20=EC=8B=9C=EB=8F=84,=20?= =?UTF-8?q?=EA=B5=B0=EA=B5=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx b/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx index f1635cff3..555813889 100644 --- a/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/cnfm-list-page.tsx @@ -257,8 +257,8 @@ function CnfmListPage() { {row.gugun|| "-"} {row.bizNm || "-"} {row.taskSeCdNm || row.taskSeComCd || "-"} - {row.chrgrNm || row.aplcntNm || "-"} - {row.instNm || row.aplcntOgdpNm || "-"} + {row.aplcntNm || "-"} + {row.envoSeCdNm || "-"}
From cc21aaede151a1b319f1da2a389a4e458db8f663 Mon Sep 17 00:00:00 2001 From: ljpark Date: Wed, 10 Jun 2026 11:16:10 +0900 Subject: [PATCH 09/52] =?UTF-8?q?wr:=20=ED=95=98=EC=88=98=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=EC=8B=9C=EC=84=A4=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=EC=86=8D=EB=8F=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx | 8 +- .../ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 46 ++--- .../ruseFcltMng/fcltReg/pbnstReg/type.tsx | 17 ++ .../ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 167 +++++++++++++++++- .../ruseFcltMng/fcltSttn/pbnstSttn/type.tsx | 3 +- 5 files changed, 215 insertions(+), 26 deletions(-) diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx index f61697e7e..e36a8433f 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx @@ -6,6 +6,12 @@ export function createDefaultPbnstItem(row: pubHasuType, index: number) { return JSON.parse(JSON.stringify({ pbnstRuseFcltId: pk, swtrmtFcltId: "", + swageTrtmfctId: row.bscFctCd || "", + swageBscFctNm: row.bscFctNm || "", + swageRgnCd: row.rgnCd || "", + swageAdstDstrCd: row.adstDstrCd || "", + swageRvbsnCd: row.rvbsnCd || "", + swageFctCpc: Number(row.fctCpc) || 0, ruseUtztnFcltNm: "", fcltCpct: 0, ruseCpct: 0, @@ -44,4 +50,4 @@ export function createDefaultPbnstItem(row: pubHasuType, index: number) { cycl, // 필요한 값 있으면 여기에 추가 } as fcBizType; - } \ No newline at end of file + } diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 0e49c4c6f..70914ab7b 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -39,15 +39,13 @@ export default function PbnstSttn() { auth, code, pbnstSttn, - pbnstSttnSearch, - pbnSttnInit, + pbnstSttnList, getPbnStnDetail, - getFlcts, // 하수재이용시설(tb_wr_pbnst_ruse_fclt) 조회 resetPbnstDetail, getLaeSeCdCheck, } = useWrStore((state) => state); - const { pbnstSttnRes, fclts, pbnstSttnResCount } = pbnstSttn; + const { pbnstSttnRes, pbnstSttnResCount } = pbnstSttn; const { laeSeCd } = auth; // 지자체구분코드 const [isReset, setIsReset] = useState(false); @@ -110,16 +108,16 @@ export default function PbnstSttn() { const excelClick = useCallback(() => { isDownloadTriggered.current = true; const fixedSearchValue = getFixedSearchValue(ref.current); - pbnstSttnSearch( + pbnstSttnList( true, String(1), "100000", fixedSearchValue, pbnRuseNm, searchYear, - fclts + [] ); - }, [pbnstSttnSearch, fclts, pbnRuseNm, searchYear, getFixedSearchValue]); + }, [pbnstSttnList, pbnRuseNm, searchYear, getFixedSearchValue]); const cellCLick = useCallback( (index: number | undefined) => { @@ -134,28 +132,30 @@ export default function PbnstSttn() { useEffect(() => { getLaeSeCdCheck(); useInitRef.current = true; - if (!pbnstSttn.isFcltsLoaded) { - getFlcts(); // 하수재이용시설 조회 - } }, []); useEffect(() => { if ( useInitRef.current === true && laeSeCd !== undefined && - pbnstSttn.isFcltsLoaded && - !pbnstSttn.isTableLoaded && - fclts.length > 0 + !pbnstSttn.isTableLoaded ) { - pbnSttnInit("1", String(DEFAULT_LIST_SIZE), getFixedSearchValue(ref.current), searchYear, fclts); + pbnstSttnList( + false, + "1", + String(DEFAULT_LIST_SIZE), + getFixedSearchValue(ref.current), + pbnRuseNm, + searchYear, + [] + ); } }, [ - fclts, laeSeCd, - pbnstSttn.isFcltsLoaded, pbnstSttn.isTableLoaded, + pbnRuseNm, searchYear, - pbnSttnInit, + pbnstSttnList, getFixedSearchValue, ]); @@ -262,16 +262,16 @@ export default function PbnstSttn() { } queryClick={() => { const fixedSearchValue = getFixedSearchValue(ref.current); - pbnstSttnSearch( + pbnstSttnList( false, "1", String(DEFAULT_LIST_SIZE), fixedSearchValue, pbnRuseNm, searchYear, - fclts + [] ); - setIsReset(true); + // setIsReset(true); }} excelClick={excelClick} initClick={function (): void { @@ -301,16 +301,16 @@ export default function PbnstSttn() { }} onPageChange={(page: number) => { const fixedSearchValue = getFixedSearchValue(ref.current); - pbnstSttnSearch( + pbnstSttnList( false, String(page), String(DEFAULT_LIST_SIZE), fixedSearchValue, pbnRuseNm, searchYear, - fclts + [] ); - setIsReset(false); + // setIsReset(false); }} resetPageNo={isReset} widthFixed={true} diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx index eafbc4477..c39d3d72b 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -62,10 +62,18 @@ export type PbnstDemandComType = { export const pubHasuZod = z.object({ choose: z.boolean().default(false), bscFctCd: z.string(), + rvbsnCd: z.string().default(""), // 권역코드 + rvbsn: z.string().default(""), + lgbsn: z.string().default(""), + mdmbsn: z.string().default(""), + rgnNm: z.string().default(""), + rgnCd: z.string().default(""), // 지역코드 + adstDstrCd: z.string().default(""), // 행정구역코드 sido: z.string().default(""), // 시도 gugun: z.string().default(""), // 구군 bscFctNm: z.string().default(""), // 시설명 efflWqltStndrdNm: z.string().default(""), // 지역구분 + tel: z.string().default(""), fctCpc: z.number().default(0), // 시설용량 addr: z.string().nullish(), // 위치 }); @@ -258,6 +266,15 @@ const PrfSchema = z.object({ export const pbnstRegZod = z.object({ pbnstRuseFcltId: z.string().default(""), swtrmtFcltId: z.string().default(""), + swageTrtmfctId: z.string().default(""), + swageBscFctNm: z.string().default(""), + swageRgnCd: z.string().default(""), + swageAdstDstrCd: z.string().default(""), + swageRvbsnCd: z.string().default(""), + swageFctCpc: z.preprocess( + (v) => (v !== null && v !== undefined ? Number(v) : v), + z.number().default(0) + ), ruseUtztnFcltNm: //z.string().default(''), z.preprocess( (v) => (v !== null && v !== undefined ? String(v).trim() : ""), // null/undefined → "", 공백 제거 diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index b1cf957e6..57cfd0a1a 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -3,7 +3,7 @@ import type { TableUpperProps, } from "@/app/store/common/type/header"; import type { FcPrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; -import { fetchType, getFetch, postFectch } from "@/components/lib/api"; +import { fetchType, getFetch, getFetchWithCount, postFectch } from "@/components/lib/api"; import type { ReturnType } from "@common/business_components/ui"; import moment from "moment"; import { type z } from "zod"; @@ -54,6 +54,15 @@ export type pbnstSttnState = { type pbnstSttnActions = { pbnstChSttnHead: (headList: z.infer) => void; + pbnstSttnList: ( + isExcel: boolean, + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string, + fclts: string[] + ) => void; pbnstSttnSearch: ( isExcel: boolean, page: string, @@ -246,6 +255,119 @@ export const hasuListFetch = async ( return { data: data, count: getRuseList.count }; }; +export const pbnstListFetch = async ( + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string +) => { + let nameCd = "0"; + let partStr = "A"; + + switch (reurnValue.partValue) { + case "R": + if (reurnValue.regionValue !== "0") { + if (reurnValue.unitWaterShedValue === "0") nameCd = reurnValue.regionValue; + else if (reurnValue.middleRegionValue === "0") nameCd = reurnValue.unitWaterShedValue; + else nameCd = reurnValue.middleRegionValue; + } + partStr = reurnValue.partValue; + break; + default: + if (reurnValue.sidoValue && reurnValue.sidoValue !== "0") nameCd = reurnValue.sidoValue; + if (reurnValue.sigunValue && reurnValue.sigunValue !== "0") nameCd = reurnValue.sigunValue; + partStr = reurnValue.envPartValue !== "0" ? reurnValue.envPartValue : "A"; + break; + } + + let url = `/reuseFc/pbnstList/${year}/${page}/${total}/${partStr}/${nameCd}/0/1/SW`; + if (searchNm && searchNm.length > 0) { + url += `?swtrmtFcltNm=${searchNm}`; + } + + const response = await getFetchWithCount(fetchType.WR, url); + const wrList: WaterReuseFacility[] = Array.isArray(response.data) + ? response.data + : []; + + const swtrmtFcltIds = [ + ...new Set( + wrList + .map((item: WaterReuseFacility) => { + if (item.swtrmtFcltId && item.swtrmtFcltId.length > 0) { + return item.swtrmtFcltId; + } + + if (item.pbnstRuseFcltId && item.pbnstRuseFcltId.length >= 11) { + return item.pbnstRuseFcltId.substring(0, 11); + } + + return ""; + }) + .filter(Boolean) + ), + ]; + + let pbnListData: pubHasuType[] = []; + + if (swtrmtFcltIds.length > 0) { + let foUrl = `/prcsFclt/ruseInfo/1/${swtrmtFcltIds.length + 1}`; + if (searchNm && searchNm.length > 0) { + foUrl += `/${searchNm}`; + } + + const pbnList = await postFectch( + foUrl, + swtrmtFcltIds, + fetchType.COMMON + ); + + pbnListData = Array.isArray(pbnList?.data) ? pbnList.data : []; + } + + const data: WaterReuseFacility[] = wrList.map((item: WaterReuseFacility) => { + const swtrmtFcltId = + item.swtrmtFcltId && item.swtrmtFcltId.length > 0 + ? item.swtrmtFcltId + : item.pbnstRuseFcltId?.substring(0, 11) ?? ""; + + const findData = pbnListData.find( + (fclt: pubHasuType) => fclt.bscFctCd === swtrmtFcltId + ); + + return { + ...item, + swtrmtFcltId, + rvbsn: findData?.rvbsn || item.rvbsn || "-", + lgbsn: findData?.lgbsn || item.lgbsn || "-", + mdmbsn: findData?.mdmbsn || item.mdmbsn || "-", + rgnNm: findData?.rgnNm || item.rgnNm || "-", + sido: findData?.sido || item.sido || "-", + gugun: findData?.gugun || item.gugun || "-", + bscFctNm: findData?.bscFctNm || item.bscFctNm || "-", + efflWqltStndrdNm: + findData?.efflWqltStndrdNm || item.efflWqltStndrdNm || "-", + tel: findData?.tel || item.tel || "-", + fctCpc: Number(findData?.fctCpc ?? item.fctCpc) || 0, + ruseUtztnFcltNm: item.ruseUtztnFcltNm || "-", + fcltCpct: Number(item.fcltCpct) || 0, + splyExtraCpct: Number(item.splyExtraCpct) || 0, + ruseCpct: Number(item.ruseCpct) || 0, + usageTotal: Number(item.usageTotal) || 0, + inUsage: Number(item.inUsage) || 0, + outUsage: Number(item.outUsage) || 0, + operMthd: item.operMthd || "-", + rprtvBzenty: item.rprtvBzenty || "-", + bgngDt: item.bgngDt || "", + endDt: item.endDt || "", + prfList: item.prfList ?? [], + }; + }); + + return { data, count: response.count }; +}; + export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( set: any ) => { @@ -261,6 +383,49 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }, })); }, + pbnstSttnList: async ( + isExcel: boolean, + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string, + _fclts: string[] + ) => { + try { + const pbnstSttnRes = await pbnstListFetch( + page, + total, + reurnValue, + searchNm, + year + ); + + if (isExcel) { + const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes.data); + set((state: pbnstSttnState) => ({ + ...state, + pbnstSttn: { + ...state.pbnstSttn, + excelList: pbnstExcel, + }, + })); + } else { + set((state: pbnstSttnState) => ({ + ...state, + pbnstSttn: { + ...state.pbnstSttn, + pbnstSttnRes: pbnstSttnRes.data, + pbnstSttnResCount: pbnstSttnRes.count, + pbnstDetail: {} as customPbnst, + isTableLoaded: true, + }, + })); + } + } catch (error) { + console.log("error", error); + } + }, //테이블 헤드를 조정한다. pbnstChSttnHead: async ( headList: z.infer diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx index 7d0f8a068..ee202d4f6 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx @@ -1,10 +1,11 @@ import type { PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; export type WaterReuseFacility = { + swtrmtFcltId?: string; bscFctNm: string; // 기본시설명 (예: "난지") efflWqltStndrdNm: string; // 방류수 수질 기준명 (예: "500톤 이상(Ⅲ지역)") fcltCpct: number; // 시설 용량 (숫자형, 예: 1) - fctCpc: string; // 시설 처리 능력 (예: "2360000") + fctCpc: number; // 시설 처리 능력 (예: 2360000) gugun: string; // 구군 정보 (예: " ") inUsage: number; // 유입량 (예: 1387) lgbsn: string; // 대수계 (예: "한강본류") From c0b63a655e755960d86fe14a8c8a22dc89c799d4 Mon Sep 17 00:00:00 2001 From: ljpark Date: Wed, 10 Jun 2026 11:35:09 +0900 Subject: [PATCH 10/52] =?UTF-8?q?wr:=20=20isReset=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx | 4 ---- apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 70914ab7b..4b635016e 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -48,7 +48,6 @@ export default function PbnstSttn() { const { pbnstSttnRes, pbnstSttnResCount } = pbnstSttn; const { laeSeCd } = auth; // 지자체구분코드 - const [isReset, setIsReset] = useState(false); const ref = useRef({} as ReturnType); const [searchYear, setSearchYear] = useState( String(new Date().getFullYear()) @@ -271,7 +270,6 @@ export default function PbnstSttn() { searchYear, [] ); - // setIsReset(true); }} excelClick={excelClick} initClick={function (): void { @@ -310,9 +308,7 @@ export default function PbnstSttn() { searchYear, [] ); - // setIsReset(false); }} - resetPageNo={isReset} widthFixed={true} > diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 57cfd0a1a..5b2a72acf 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -390,7 +390,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( reurnValue: ReturnType, searchNm: string | undefined, year: string, - _fclts: string[] + // _fclts: string[] ) => { try { const pbnstSttnRes = await pbnstListFetch( From 4148a87f3298f1b9c3d1fca4faef5e193999f29e Mon Sep 17 00:00:00 2001 From: jangwoong Date: Wed, 10 Jun 2026 14:16:43 +0900 Subject: [PATCH 11/52] =?UTF-8?q?[as=20frontend]=20=EC=8B=9C=EB=8F=84/?= =?UTF-8?q?=EA=B5=AC=EA=B5=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/instl-sncn/ui/cnfm-regist-page.tsx | 18 ++++++++++++------ .../src/pages/instl-sncn/ui/cnfm-view-page.tsx | 6 +++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx b/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx index 95a85a40f..8b736b028 100644 --- a/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx @@ -155,12 +155,14 @@ const normalizeChecklistResultRows = (payload: any): any[] => { */ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { const router = useRouter(); - const userInfo2 = useUserStore((state) => state.userInfo); + const userInfo = useUserStore((state) => state.userInfo); // userInfo?.dtlInstCd 테스트 코드 ENV.ROLE_USER03 , KECO 권한 테스트용 (실제 권한에 맞게 변경 필요) + /* const userInfo = { ...userInfo2, dtlInstCd: "ROLE_USER03", //ROLE_USER03, ROLE_USER02, ROLE_USER01 KECO 권한 테스트용 (실제 권한에 맞게 변경 필요) }; + */ const alert = useAlertStore((state) => state.setMessage); const qc = useQueryClient(); const currentDet = useMemo(() => initialData?.detDto ?? initialData, [initialData]); @@ -1124,7 +1126,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { } const toInstlSncnMngPayload = (prgrsSttsComCd: "SV" | "ST"| "ER"): InstlSncnMng => ({ - instlSncnDocNo: docId ?? "", // 수정 시 기존 문서번호 유지, 신규 저장 시 빈값 + instlSncnDocNo: docId ?? "", admdstCd: "", sidoNm: "", sggNm: "", @@ -1155,6 +1157,8 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { regDt: "", mdfcnDt: "", rgtrNm: "", + gugun: "", + sido: "" }); async function handleSave() { @@ -1303,7 +1307,9 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { 신청 지자체 - {userInfo?.enoNm ?? "\u00A0"} + {isModifyMode + ? `${currentDet?.sido ?? "-"} ${currentDet?.gugun ?? "-"}` + : userInfo?.laeSeNm ?? "\u00A0"} @@ -1312,9 +1318,9 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
{[ - ["CNFM", "설치인가"], - ["APR", "설치승인"], - ["AFA", "폐지인가"], + ["1", "설치인가"], + ["2", "설치승인"], + ["3", "폐지승인"], ].map(([val, label]) => (
diff --git a/apps/cs/src/pages/role/ui/role-page.tsx b/apps/cs/src/pages/role/ui/role-page.tsx index b370ed338..a6c7ec2d1 100644 --- a/apps/cs/src/pages/role/ui/role-page.tsx +++ b/apps/cs/src/pages/role/ui/role-page.tsx @@ -2,39 +2,68 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; -import { useQuery } from "@tanstack/react-query"; -import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; -import { Button, Input, Label } from "@common/components"; -import { RoleApi, type Role, type RoleParams } from "@/entities/role"; + +import { keepPreviousData, useQuery } from "@tanstack/react-query"; +import { + getCoreRowModel, + type OnChangeFn, + type PaginationState, +} from "@tanstack/react-table"; + import { ENDPOINT } from "@/shared/config"; -import { useAlertStore, useDataTable } from "@/shared/lib"; +import { useDataTable, useSearchParamsState } from "@/shared/lib"; +import { type Role, RoleApi } from "@/entities/role"; +import { Button, Input, Label } from "@common/components"; + import { createColumns } from "../model/table-columns"; +const DEFAULT_PARAMS = { + keywordType: "roleName", + keyword: "", + sort: "regDt,desc", + page: 0, + size: 10, +}; + function RolePage() { const router = useRouter(); - const alert = useAlertStore((state) => state.setMessage); - - const [keyword, setKeyword] = useState(""); - const [searchParams, setSearchParams] = useState({ - keywordType: "roleName", - keyword: "", - sort: "regDt,desc", - }); - const [pagination, setPagination] = useState({ - pageIndex: 0, - pageSize: 10, - }); + const { params, setParams, resetParams } = + useSearchParamsState(DEFAULT_PARAMS); + const [keyword, setKeyword] = useState(params.keyword); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.ROLES, searchParams, pagination], + queryKey: [ENDPOINT.USER_SERVICE.ROLES, params], queryFn: () => RoleApi.getRoles({ - ...searchParams, - page: pagination.pageIndex, - size: pagination.pageSize, + keywordType: params.keywordType, + keyword: params.keyword, + sort: params.sort, + page: params.page, + size: params.size, }), + placeholderData: keepPreviousData, }); + const pagination: PaginationState = { + pageIndex: params.page, + pageSize: params.size, + }; + + const handlePaginationChange: OnChangeFn = (updater) => { + const next = typeof updater === "function" ? updater(pagination) : updater; + setParams({ page: next.pageIndex, size: next.pageSize }); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + setParams({ keyword, page: 0 }); + }; + + const handleReset = () => { + setKeyword(""); + resetParams(); + }; + const handleRowClick = (row: Role) => { router.push(`/role/register/${row.roleId}`); }; @@ -48,7 +77,7 @@ function RolePage() { }, manualPagination: true, getCoreRowModel: getCoreRowModel(), - onPaginationChange: setPagination, + onPaginationChange: handlePaginationChange, }, dataTableOptions: { onRowClick: handleRowClick, @@ -56,26 +85,6 @@ function RolePage() { }, }); - const handleSubmit = (e: React.SubmitEvent) => { - e.preventDefault(); - setPagination({ - ...pagination, - pageIndex: 0, - }); - setSearchParams({ - ...searchParams, - keyword, - }); - }; - - const handleReset = () => { - setKeyword(""); - setSearchParams({ - ...searchParams, - keyword: "", - }); - }; - return (
diff --git a/apps/cs/src/pages/site/ui/site-page.tsx b/apps/cs/src/pages/site/ui/site-page.tsx index fbdd9d36c..20a38e998 100644 --- a/apps/cs/src/pages/site/ui/site-page.tsx +++ b/apps/cs/src/pages/site/ui/site-page.tsx @@ -1,54 +1,65 @@ "use client"; -import "@common/assets/styles/grid.css"; - import { useState } from "react"; import { useRouter } from "next/navigation"; + import { keepPreviousData, useQuery } from "@tanstack/react-query"; -import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; -import { Button, Input, Label } from "@common/components"; -import { SiteApi, type Site, type SiteParams } from "@/entities/site"; +import { + getCoreRowModel, + type OnChangeFn, + type PaginationState, +} from "@tanstack/react-table"; + import { ENDPOINT } from "@/shared/config"; -import { useDataTable } from "@/shared/lib"; +import { useDataTable, useSearchParamsState } from "@/shared/lib"; +import { type Site, SiteApi } from "@/entities/site"; +import { Button, Input, Label } from "@common/components"; + import { columns } from "../model/table-columns"; +const DEFAULT_PARAMS = { + siteNm: "", + sort: "regDt,desc", + page: 0, + size: 10, +}; + function SitePage() { const router = useRouter(); - const [siteNm, setSiteNm] = useState(""); - const [searchParams, setSearchParams] = useState({ - siteNm: "", - sort: "regDt,desc", - }); - const [pagination, setPagination] = useState({ - pageIndex: 0, - pageSize: 10, - }); + const { params, setParams, resetParams } = + useSearchParamsState(DEFAULT_PARAMS); + const [siteNm, setSiteNm] = useState(params.siteNm); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.SITES, searchParams, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.SITES, params], queryFn: () => SiteApi.getSiteList({ - ...searchParams, - page: pagination.pageIndex, - size: pagination.pageSize, + siteNm: params.siteNm, + sort: params.sort, + page: params.page, + size: params.size, }), placeholderData: keepPreviousData, }); - const handleSubmit = (e: React.SubmitEvent) => { + const pagination: PaginationState = { + pageIndex: params.page, + pageSize: params.size, + }; + + const handlePaginationChange: OnChangeFn = (updater) => { + const next = typeof updater === "function" ? updater(pagination) : updater; + setParams({ page: next.pageIndex, size: next.pageSize }); + }; + + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - setSearchParams({ - ...searchParams, - siteNm, - }); + setParams({ siteNm, page: 0 }); }; const handleReset = () => { setSiteNm(""); - setSearchParams({ - ...searchParams, - siteNm: "", - }); + resetParams(); }; const handleRowClick = (row: Site) => { @@ -62,7 +73,7 @@ function SitePage() { state: { pagination, }, - onPaginationChange: setPagination, + onPaginationChange: handlePaginationChange, getCoreRowModel: getCoreRowModel(), manualPagination: true, }, diff --git a/apps/cs/src/pages/survey/ui/survey-page.tsx b/apps/cs/src/pages/survey/ui/survey-page.tsx index 27f080343..f3e0481d5 100644 --- a/apps/cs/src/pages/survey/ui/survey-page.tsx +++ b/apps/cs/src/pages/survey/ui/survey-page.tsx @@ -2,19 +2,23 @@ import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; + import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { getCoreRowModel, + type OnChangeFn, type PaginationState, type RowSelectionState, } from "@tanstack/react-table"; -import { Button, Input, Label } from "@common/components"; -import { POSTING_TYPE, PostingDialog } from "@/entities/posting"; -import { AuthorityButton } from "@/entities/menu-authority"; + import { ENDPOINT } from "@/shared/config"; -import { useDataTable } from "@/shared/lib"; +import { useDataTable, useSearchParamsState } from "@/shared/lib"; +import { AuthorityButton } from "@/entities/menu-authority"; +import { POSTING_TYPE, PostingDialog } from "@/entities/posting"; +import { Button, Input, Label } from "@common/components"; + import { SurveyApi } from "../api/survey-service"; -import type { Survey, SurveyParams } from "../model/survey-interface"; +import type { Survey } from "../model/survey-interface"; import { columns } from "../model/survey-table-columns"; type PostingTarget = { @@ -22,32 +26,53 @@ type PostingTarget = { pstgTrgtNo: number; }; +const DEFAULT_PARAMS = { + srvyTtl: "", + sort: "regDt,desc", + page: 0, + size: 10, +}; + function SurveyPage() { const router = useRouter(); - - const [srvyTtl, setSrvyTtl] = useState(""); - const [searchParams, setSearchParams] = useState({ - srvyTtl: "", - sort: "regDt,desc", - }); - const [pagination, setPagination] = useState({ - pageIndex: 0, - pageSize: 10, - }); + const { params, setParams, resetParams } = + useSearchParamsState(DEFAULT_PARAMS); + const [srvyTtl, setSrvyTtl] = useState(params.srvyTtl); const [rowSelection, setRowSelection] = useState({}); const [postingTargets, setPostingTargets] = useState([]); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.SURVEY, searchParams, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.SURVEY, params], queryFn: () => SurveyApi.getSurveyList({ - ...searchParams, - page: pagination.pageIndex, - size: pagination.pageSize, + srvyTtl: params.srvyTtl, + sort: params.sort, + page: params.page, + size: params.size, }), placeholderData: keepPreviousData, }); + const pagination: PaginationState = { + pageIndex: params.page, + pageSize: params.size, + }; + + const handlePaginationChange: OnChangeFn = (updater) => { + const next = typeof updater === "function" ? updater(pagination) : updater; + setParams({ page: next.pageIndex, size: next.pageSize }); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + setParams({ srvyTtl, page: 0 }); + }; + + const handleReset = () => { + setSrvyTtl(""); + resetParams(); + }; + const handleRowClick = (row: Survey) => { router.push(`/survey/${row.srvySn}`); }; @@ -62,7 +87,7 @@ function SurveyPage() { }, manualPagination: true, getCoreRowModel: getCoreRowModel(), - onPaginationChange: setPagination, + onPaginationChange: handlePaginationChange, onRowSelectionChange: setRowSelection, }, dataTableOptions: { @@ -71,26 +96,6 @@ function SurveyPage() { }, }); - const handleSubmit = (e: React.SubmitEvent) => { - e.preventDefault(); - setPagination({ - ...pagination, - pageIndex: 0, - }); - setSearchParams({ - ...searchParams, - srvyTtl, - }); - }; - - const handleReset = () => { - setSrvyTtl(""); - setSearchParams({ - ...searchParams, - srvyTtl: "", - }); - }; - useEffect(() => { const postingTargets = table .getFilteredSelectedRowModel() diff --git a/apps/cs/src/pages/template/ui/template-page.tsx b/apps/cs/src/pages/template/ui/template-page.tsx index d4ceb3bca..5db3f1572 100644 --- a/apps/cs/src/pages/template/ui/template-page.tsx +++ b/apps/cs/src/pages/template/ui/template-page.tsx @@ -2,58 +2,70 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; + import { keepPreviousData, useQuery } from "@tanstack/react-query"; -import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; -import { Button, Input, Label } from "@common/components"; -import { CodeSelect } from "@/entities/code"; +import { + getCoreRowModel, + type OnChangeFn, + type PaginationState, +} from "@tanstack/react-table"; + import { ENDPOINT } from "@/shared/config"; -import { useDataTable } from "@/shared/lib"; +import { useDataTable, useSearchParamsState } from "@/shared/lib"; +import { CodeSelect } from "@/entities/code"; +import { Button, Input, Label } from "@common/components"; + import { TemplateApi } from "../api/template-service"; +import type { Template } from "../model/template-interface"; import { columns } from "../model/template-table-columns"; -import type { Template, TemplateParams } from "../model/template-interface"; + +const DEFAULT_PARAMS = { + keyword: "", + tmpltSeCd: "", + sort: "regDt,desc", + page: 0, + size: 10, +}; function TemplatePage() { const router = useRouter(); - const [keyword, setKeyword] = useState(""); - const [tmpltSeCd, setTmpltSeCd] = useState(""); - const [searchParams, setSearchParams] = useState({ - keyword: "", - tmpltSeCd: "", - sort: "regDt,desc", - }); - const [pagination, setPagination] = useState({ - pageIndex: 0, - pageSize: 10, - }); + const { params, setParams, resetParams } = + useSearchParamsState(DEFAULT_PARAMS); + const [keyword, setKeyword] = useState(params.keyword); + const [tmpltSeCd, setTmpltSeCd] = useState(params.tmpltSeCd); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.TEMPLATE, searchParams, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.TEMPLATE, params], queryFn: () => TemplateApi.getTemplateList({ - ...searchParams, - page: pagination.pageIndex, - size: pagination.pageSize, + keyword: params.keyword, + tmpltSeCd: params.tmpltSeCd, + sort: params.sort, + page: params.page, + size: params.size, }), placeholderData: keepPreviousData, }); - const handleSubmit = (e: React.SubmitEvent) => { + const pagination: PaginationState = { + pageIndex: params.page, + pageSize: params.size, + }; + + const handlePaginationChange: OnChangeFn = (updater) => { + const next = typeof updater === "function" ? updater(pagination) : updater; + setParams({ page: next.pageIndex, size: next.pageSize }); + }; + + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - setSearchParams({ - ...searchParams, - keyword, - tmpltSeCd, - }); + setParams({ keyword, tmpltSeCd, page: 0 }); }; const handleReset = () => { setKeyword(""); setTmpltSeCd(""); - setSearchParams({ - ...searchParams, - keyword: "", - tmpltSeCd: "", - }); + resetParams(); }; const handleRowClick = (row: Template) => { @@ -67,7 +79,7 @@ function TemplatePage() { state: { pagination, }, - onPaginationChange: setPagination, + onPaginationChange: handlePaginationChange, getCoreRowModel: getCoreRowModel(), manualPagination: true, }, diff --git a/apps/cs/src/pages/terms/ui/terms-page.tsx b/apps/cs/src/pages/terms/ui/terms-page.tsx index ea00276df..73b6b0d16 100644 --- a/apps/cs/src/pages/terms/ui/terms-page.tsx +++ b/apps/cs/src/pages/terms/ui/terms-page.tsx @@ -2,63 +2,70 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; + import { keepPreviousData, useQuery } from "@tanstack/react-query"; -import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; -import { Button, Input, Label } from "@common/components"; -import { CodeSelect } from "@/entities/code"; +import { + getCoreRowModel, + type OnChangeFn, + type PaginationState, +} from "@tanstack/react-table"; + import { ENDPOINT } from "@/shared/config"; -import { useDataTable } from "@/shared/lib"; +import { useDataTable, useSearchParamsState } from "@/shared/lib"; +import { CodeSelect } from "@/entities/code"; +import { Button, Input, Label } from "@common/components"; + import { TermsApi } from "../api/terms-service"; +import type { Terms } from "../model/terms-interface"; import { columns } from "../model/terms-table-columns"; -import type { TermsParams, Terms } from "../model/terms-interface"; + +const DEFAULT_PARAMS = { + keyword: "", + trmsSeCd: "", + sort: "regDt,desc", + page: 0, + size: 10, +}; function TermsPage() { const router = useRouter(); - - const [keyword, setKeyword] = useState(""); - const [trmsSeCd, setTrmsSeCd] = useState(""); - const [searchParams, setSearchParams] = useState({ - keyword: "", - trmsSeCd: "", - sort: "regDt,desc", - }); - const [pagination, setPagination] = useState({ - pageIndex: 0, - pageSize: 10, - }); + const { params, setParams, resetParams } = + useSearchParamsState(DEFAULT_PARAMS); + const [keyword, setKeyword] = useState(params.keyword); + const [trmsSeCd, setTrmsSeCd] = useState(params.trmsSeCd); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.TERMS, searchParams, pagination], + queryKey: [ENDPOINT.CMS_SERVICE.TERMS, params], queryFn: () => TermsApi.getTermsList({ - ...searchParams, - page: pagination.pageIndex, - size: pagination.pageSize, + keyword: params.keyword, + trmsSeCd: params.trmsSeCd, + sort: params.sort, + page: params.page, + size: params.size, }), placeholderData: keepPreviousData, }); - const handleSubmit = (e: React.SubmitEvent) => { + const pagination: PaginationState = { + pageIndex: params.page, + pageSize: params.size, + }; + + const handlePaginationChange: OnChangeFn = (updater) => { + const next = typeof updater === "function" ? updater(pagination) : updater; + setParams({ page: next.pageIndex, size: next.pageSize }); + }; + + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - setPagination({ - ...pagination, - pageIndex: 0, - }); - setSearchParams({ - ...searchParams, - keyword, - trmsSeCd, - }); + setParams({ keyword, trmsSeCd, page: 0 }); }; const handleReset = () => { setKeyword(""); setTrmsSeCd(""); - setSearchParams({ - ...searchParams, - keyword: "", - trmsSeCd: "", - }); + resetParams(); }; const handleRowClick = (row: Terms) => { @@ -72,7 +79,7 @@ function TermsPage() { state: { pagination, }, - onPaginationChange: setPagination, + onPaginationChange: handlePaginationChange, getCoreRowModel: getCoreRowModel(), manualPagination: true, }, diff --git a/apps/cs/src/pages/users/ui/users-page.tsx b/apps/cs/src/pages/users/ui/users-page.tsx index 17b44707c..cabf8eb42 100644 --- a/apps/cs/src/pages/users/ui/users-page.tsx +++ b/apps/cs/src/pages/users/ui/users-page.tsx @@ -3,19 +3,19 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; -import { useQuery } from "@tanstack/react-query"; -import { getCoreRowModel, type PaginationState } from "@tanstack/react-table"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; +import { + getCoreRowModel, + type OnChangeFn, + type PaginationState, +} from "@tanstack/react-table"; import dayjs from "dayjs"; import { ENDPOINT } from "@/shared/config"; -import { useDataTable } from "@/shared/lib"; +import { useDataTable, useSearchParamsState } from "@/shared/lib"; import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; import { CodeApi } from "@/entities/code"; -import { - UserApi, - type UserListResponse, - type UserSearchParams, -} from "@/entities/user"; +import { UserApi, type UserListResponse } from "@/entities/user"; import { Button, Checkbox, @@ -35,34 +35,39 @@ type DateRange = { to?: Date | null; }; +const DEFAULT_PARAMS = { + keywordType: "all", + keyword: "", + userStateCode: "", + aprvYn: "", + grpId: "", + frDateYmd: "", + toDateYmd: "", + sort: "regDt,desc", + page: 0, + size: 10, +}; + +function parseDateRange(frDateYmd: string, toDateYmd: string): DateRange { + return { + from: frDateYmd ? dayjs(frDateYmd, "YYYYMMDD").toDate() : undefined, + to: toDateYmd ? dayjs(toDateYmd, "YYYYMMDD").toDate() : undefined, + }; +} + function UsersPage() { const router = useRouter(); - - const [pagination, setPagination] = useState({ - pageIndex: 0, - pageSize: 10, - }); + const { params, setParams, resetParams } = + useSearchParamsState(DEFAULT_PARAMS); const [presetDateRange, setPresetDateRange] = useState(""); - const [dateRange, setDateRange] = useState({ - 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 [searchParams, setSearchParams] = useState({ - keywordType: "all", - keyword: "", - userStateCode: "", - aprvYn: "", - grpId: "", - frDateYmd: "", - toDateYmd: "", - sort: "regDt,desc", - }); + const [dateRange, setDateRange] = useState(() => + parseDateRange(params.frDateYmd, params.toDateYmd), + ); + const [keywordType, setKeywordType] = useState(params.keywordType); + const [keyword, setKeyword] = useState(params.keyword); + const [userStateCode, setUserStateCode] = useState(params.userStateCode); + const [aprvYn, setAprvYn] = useState(params.aprvYn); + const [grpId, setGrpId] = useState(params.grpId); const { data: userSttsStats } = useQuery({ queryKey: [ENDPOINT.USER_SERVICE.USERS, "userStatusStatistics"], @@ -70,13 +75,21 @@ function UsersPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.USER_SERVICE.USERS, searchParams, pagination], + queryKey: [ENDPOINT.USER_SERVICE.USERS, params], queryFn: () => UserApi.findPageUser({ - ...searchParams, - page: pagination.pageIndex, - size: pagination.pageSize, + keywordType: params.keywordType, + keyword: params.keyword, + userStateCode: params.userStateCode, + aprvYn: params.aprvYn, + grpId: params.grpId, + frDateYmd: params.frDateYmd, + toDateYmd: params.toDateYmd, + sort: params.sort, + page: params.page, + size: params.size, }), + placeholderData: keepPreviousData, }); const { data: userStateCodes } = useQuery({ @@ -84,6 +97,16 @@ function UsersPage() { queryFn: () => CodeApi.getCode("USERSTTS"), }); + const pagination: PaginationState = { + pageIndex: params.page, + pageSize: params.size, + }; + + const handlePaginationChange: OnChangeFn = (updater) => { + const next = typeof updater === "function" ? updater(pagination) : updater; + setParams({ page: next.pageIndex, size: next.pageSize }); + }; + const handleRowClick = (row: UserListResponse) => { router.push(`/users/${row.userUnqId}`); }; @@ -97,7 +120,7 @@ function UsersPage() { }, manualPagination: true, getCoreRowModel: getCoreRowModel(), - onPaginationChange: setPagination, + onPaginationChange: handlePaginationChange, }, dataTableOptions: { onRowClick: handleRowClick, @@ -105,14 +128,9 @@ function UsersPage() { }, }); - const handleSubmit = (e: React.SubmitEvent) => { + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - setPagination({ - ...pagination, - pageIndex: 0, - }); - setSearchParams({ - ...searchParams, + setParams({ keywordType, keyword, userStateCode, @@ -122,6 +140,7 @@ function UsersPage() { ? dayjs(dateRange.from).format("YYYYMMDD") : "", toDateYmd: dateRange?.to ? dayjs(dateRange.to).format("YYYYMMDD") : "", + page: 0, }); }; @@ -131,20 +150,12 @@ function UsersPage() { setUserStateCode(""); setAprvYn(""); setGrpId(""); + setPresetDateRange(""); setDateRange({ from: undefined, to: undefined, }); - setSearchParams({ - ...searchParams, - keywordType: "all", - keyword: "", - userStateCode: "", - aprvYn: "", - grpId: "", - frDateYmd: "", - toDateYmd: "", - }); + resetParams(); }; const handlePresetDateRange = (value: string) => { @@ -351,12 +362,9 @@ function UsersPage() {

회원 목록

setViewCheckResults((prev) => ({ ...prev, [key]: "Y" }))} - /> - - - setViewCheckResults((prev) => ({ ...prev, [key]: "N" }))} - /> - - - )} - {showRadios && selectedReviewStep !== "LOCAL" ? ( - -