140 lines
3.8 KiB
TypeScript
140 lines
3.8 KiB
TypeScript
/** 지반침하 화면에 필요한 공통코드를 조회하고 선택 항목으로 제공한다. */
|
|
"use client";
|
|
|
|
import { useEffect, useMemo, useState } from "react";
|
|
|
|
import { getCommonCodes } from "@/components/lib/common/apiHelpers";
|
|
|
|
import {
|
|
SINKHOLE_COORD_STATUS_OPTIONS,
|
|
SINKHOLE_RESTORE_STATUS_OPTIONS,
|
|
} from "./sinkholeTypes";
|
|
|
|
type CodeLabelMap = Record<string, string>;
|
|
type StatusOption = { value: string; label: string };
|
|
|
|
const COMMON_CODE_GROUPS = {
|
|
restoreStatus: "SNKHLRSTRSTTS",
|
|
coordStatus: "SNKHLCRDSTTS",
|
|
} as const;
|
|
|
|
const cachedCodeLists = new Map<
|
|
string,
|
|
Array<{ lwpoCd: string; lwpoCdNm: string }>
|
|
>();
|
|
const pendingCodeLists = new Map<
|
|
string,
|
|
Promise<Array<{ lwpoCd: string; lwpoCdNm: string }>>
|
|
>();
|
|
|
|
/** 같은 브라우저 세션에서는 지반침하 상태 코드그룹별 CMS 요청을 한 번만 수행한다. */
|
|
const loadCodeList = async (upCd: string) => {
|
|
const cached = cachedCodeLists.get(upCd);
|
|
if (cached) return cached;
|
|
|
|
const pending = pendingCodeLists.get(upCd);
|
|
if (pending) return pending;
|
|
|
|
const request = getCommonCodes(upCd)
|
|
.then((codes) => {
|
|
const codeList = codes.map(({ lwpoCd, lwpoCdNm }) => ({
|
|
lwpoCd,
|
|
lwpoCdNm,
|
|
}));
|
|
cachedCodeLists.set(upCd, codeList);
|
|
return codeList;
|
|
})
|
|
.finally(() => {
|
|
pendingCodeLists.delete(upCd);
|
|
});
|
|
|
|
pendingCodeLists.set(upCd, request);
|
|
return request;
|
|
};
|
|
|
|
/** 지반침하 상태의 검색값 계약은 유지하고 선택지와 표시명만 CMS 기준으로 제공한다. */
|
|
export const useSinkholeCommonCodes = () => {
|
|
const [restoreCodes, setRestoreCodes] = useState(
|
|
cachedCodeLists.get(COMMON_CODE_GROUPS.restoreStatus) ?? [],
|
|
);
|
|
const [coordCodes, setCoordCodes] = useState(
|
|
cachedCodeLists.get(COMMON_CODE_GROUPS.coordStatus) ?? [],
|
|
);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
|
|
loadCodeList(COMMON_CODE_GROUPS.restoreStatus)
|
|
.then((codes) => {
|
|
if (!cancelled) setRestoreCodes(codes);
|
|
})
|
|
.catch((error) => {
|
|
console.error("SNKHLRSTRSTTS 공통코드 조회에 실패했습니다.", error);
|
|
});
|
|
loadCodeList(COMMON_CODE_GROUPS.coordStatus)
|
|
.then((codes) => {
|
|
if (!cancelled) setCoordCodes(codes);
|
|
})
|
|
.catch((error) => {
|
|
console.error("SNKHLCRDSTTS 공통코드 조회에 실패했습니다.", error);
|
|
});
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
const restoreStatusOptions = useMemo<StatusOption[]>(
|
|
() =>
|
|
restoreCodes.length > 0
|
|
? [
|
|
{ value: "0", label: "전체" },
|
|
...restoreCodes.map((code) => ({
|
|
// 백엔드는 복구상태 한글 설명값을 검색조건으로 사용하므로 코드명을 전송한다.
|
|
value: code.lwpoCdNm,
|
|
label: code.lwpoCdNm,
|
|
})),
|
|
]
|
|
: [...SINKHOLE_RESTORE_STATUS_OPTIONS],
|
|
[restoreCodes],
|
|
);
|
|
|
|
const coordStatusOptions = useMemo<StatusOption[]>(
|
|
() =>
|
|
coordCodes.length > 0
|
|
? [
|
|
{ value: "0", label: "전체" },
|
|
...coordCodes.map((code) => ({
|
|
value: code.lwpoCd,
|
|
label: code.lwpoCdNm,
|
|
})),
|
|
]
|
|
: [...SINKHOLE_COORD_STATUS_OPTIONS],
|
|
[coordCodes],
|
|
);
|
|
|
|
const restoreStatusLabels = useMemo<CodeLabelMap>(() => {
|
|
const labels: CodeLabelMap = {};
|
|
restoreCodes.forEach((code) => {
|
|
labels[code.lwpoCd] = code.lwpoCdNm;
|
|
labels[code.lwpoCdNm] = code.lwpoCdNm;
|
|
});
|
|
return labels;
|
|
}, [restoreCodes]);
|
|
|
|
const coordStatusLabels = useMemo<CodeLabelMap>(() => {
|
|
const labels: CodeLabelMap = {};
|
|
coordCodes.forEach((code) => {
|
|
labels[code.lwpoCd] = code.lwpoCdNm;
|
|
});
|
|
return labels;
|
|
}, [coordCodes]);
|
|
|
|
return {
|
|
restoreStatusOptions,
|
|
coordStatusOptions,
|
|
restoreStatusLabels,
|
|
coordStatusLabels,
|
|
};
|
|
};
|