Files
frontend/apps/sn/app/(map-layout)/map/searchModal/useSearchModal.ts
T

206 lines
6.2 KiB
TypeScript

/**
* 📄 useSearchModal Hook
* 검색 모달 훅
*
* - 탭 기반 검색 인터페이스 관리 (기본정보, 유지관리 정보, 보고서)
* - 필터링된 데이터 조회 및 포맷팅
* - 조회 버튼을 통한 데이터 검색 트리거
* - 여러 시설 보기 기능
* - Zustand를 통한 상태 관리 및 로딩 처리
* - 데이터 매핑 및 코드 변환 (사업 유형 등)
*
* 🔗 사용 API
* - 유지관리 정보 목록 조회: GET /api/v1/bizInfo (sewerage-service)
*/
import { getData } from '@/components/lib/api';
import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue';
import useStore from '../../../store/useStore';
import GisApp from '@common/business_components/ui/map/lib/gis.core';
import useSearchModalStore from '../../../store/useSearchModalStore';
import useBasicTab from './useBasicTab';
import useOperationTab from './useOperationTab';
import { postPopupMessageAndClose } from '@/features/windowPopup/lib/popupMessage';
import { WINDOW_POPUP_MESSAGE_TYPE } from '@/features/windowPopup/model/types';
const isPopupWindow = () =>
typeof window !== 'undefined' &&
!!window.opener &&
window.location.pathname.startsWith('/popup/');
export default function useSearchModal() {
const {
activeTab,
tableData,
detailTableData,
setIsSearchModalOpen,
setShowTable,
setTableData,
setCurPage,
setIsLoading,
setIsResetPage,
setIsResetDetailPage,
setIsResetSelection,
setIsResetDetailSelection,
getDateString,
} = useSearchModalStore();
const { fetchBasicFilteredData } = useBasicTab();
const { OPERATION_TABLE_SIZE } = useOperationTab();
const { BIZ_TY_CD } = useStore();
const TABS = [
{ val: 'basic', text: '기본 정보' },
{ val: 'operation', text: '유지관리 정보' },
{ val: 'report', text: '하수도 정비 기본계획 보고서' },
];
// 검색 API 호출 함수
const fetchFilteredData = async () => {
const {
activeTab: currentTab,
curPage,
var1,
var2,
yearFilter,
workType,
todayYear,
todayMonth,
todayDate,
setTableData,
setDetailTableData,
setTableCount,
setDetailTableCount,
setShowTable,
setIsLoading,
setIsResetSelection,
setIsResetDetailSelection,
} = useSearchModalStore.getState();
setIsLoading(true);
setIsResetSelection(true);
setIsResetDetailSelection(true);
try {
if (currentTab === 'basic') {
await fetchBasicFilteredData();
} else if (currentTab === 'operation') {
const requestDto: Record<string, string> = {
page: `${curPage - 1}`,
size: `${OPERATION_TABLE_SIZE}`,
};
if (var1) requestDto.bizInfoNm = var1;
if (var2 !== '0' && var2) requestDto.bizTypeCd = var2;
const startDate = getDateString(
yearFilter.start,
'',
'',
'19000101',
);
const endDate = getDateString(
yearFilter.end,
'',
'',
`${todayYear}${todayMonth}${todayDate}`,
);
requestDto.fromflfmtEndYmd = startDate;
requestDto.toflfmtEndYmd = endDate;
requestDto.workTypes = JSON.parse(workType.replace(/'/g, '"'));
const params = new URLSearchParams(requestDto).toString();
const res = await getData(`v1/bizInfo?${params}`);
const mappedContent = (res.content || []).map((item: any, index: number) => {
const formattedItem = formatDisplayData(item);
const matched = BIZ_TY_CD.find((code) => code.lwpoCd === item.bizTypeCd);
return {
...formattedItem,
rowNumber: (curPage - 1) * OPERATION_TABLE_SIZE + index + 1,
bizTypeCd: matched ? matched.lwpoCdNm : item.bizTypeCd,
};
});
setTableData(mappedContent || []);
setTableCount(res.totalElements || 0);
setDetailTableData([]);
setDetailTableCount(0);
}
setShowTable(true);
setIsResetSelection(false);
} catch (err) {
console.error('API ERROR:', err);
setTableData([]);
setIsResetSelection(false);
} finally {
setIsLoading(false);
setIsResetSelection(false);
}
};
// 조회 버튼 클릭 시 1페이지로 이동 및 데이터 초기화
const handleSearch = () => {
setCurPage(1);
void fetchFilteredData();
setIsResetPage(true);
setIsResetDetailPage(true);
setIsResetSelection(false);
setIsResetDetailSelection(false);
setShowTable(true);
};
// 여러 시설 보기
const viewMultipleFeature = async () => {
if (activeTab === 'basic') {
if (!(tableData.length === 0)) {
if (isPopupWindow()) {
const row = tableData[0];
postPopupMessageAndClose(
WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SHOW_MULTIPLE,
{
layerNm: row.lyrTypeNm,
fids: JSON.stringify(tableData.map((item) => item.fid)),
},
);
return;
}
setIsLoading(true);
const row = tableData[0];
const layerNm = row.lyrTypeNm;
const fids = tableData.map((item) => item.fid);
const core = GisApp.Module.layer as any;
await core.showMultipleSearchResultsFromGeoJSON(layerNm, fids);
setIsLoading(false);
setIsSearchModalOpen(false);
}
} else if (activeTab === 'operation') {
if (!(detailTableData.length === 0)) {
if (isPopupWindow()) {
const row = detailTableData[0];
postPopupMessageAndClose(
WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SHOW_MULTIPLE,
{
layerNm: row.lyrTypeNm,
fids: JSON.stringify(detailTableData.map((item) => item.fid)),
},
);
return;
}
setIsLoading(true);
const row = detailTableData[0];
const layerNm = row.lyrTypeNm;
const fids = detailTableData.map((item) => item.fid);
const core = GisApp.Module.layer as any;
await core.showMultipleSearchResultsFromGeoJSON(layerNm, fids);
setIsLoading(false);
setIsSearchModalOpen(false);
}
}
};
return { TABS, getDateString, handleSearch, viewMultipleFeature, fetchFilteredData };
}