/** * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 * * 📄 Search Modal * Next.js App Router (app/) 기반 검색 모달 컴포넌트 * * - 탭 기반 검색 인터페이스 (기본정보, 유지관리 정보, 보고서) * - 테이블 데이터 표시 및 페이지네이션 기능 * - 시설물 조회 결과 및 유지관리 사업 현황 표시 * - 엑셀 다운로드 및 지도에서 보기 기능 * - Zustand를 통한 검색 모달 상태 관리 * - 로딩 오버레이 및 선택 초기화 지원 */ import LoadingOverlay from '@/components/ui/LoadingBar'; import { UiModal, UITab, UiTable } from '@common/business_components/ui'; import { Button } from '@common/components/ui'; import React, { useEffect, useMemo } from 'react'; import { Toaster } from "react-hot-toast"; import useSearchModalStore from '@/store/useSearchModalStore'; import { ExclnSewagePumpCol2, MsSwageMhlCol2, MsSwagePplCol2, stofcbrCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2 } from '../components/common/table'; import BasicTab, { BASIC_TYPES } from './basicTab'; import OperationTab from './operationTab'; import ReportTab from './reportTab'; import useSearchModal from './useSearchModal'; import useBasicTab from './useBasicTab'; import useOperationTab from './useOperationTab'; const SearchModal: React.FC = () => { const { showTable, isSearchModalOpen, setIsSearchModalOpen, activeTab, basicType, workType, tableData, detailTableData, tableCount, detailTableCount, curPage, detailCurPage, detailBizId, isLoading, isDetailLoading, isResetPage, isResetDetailPage, isResetSelection, isResetDetailSelection, setActiveTab, setCurPage, setDetailCurPage, setIsResetPage, setIsResetDetailPage, setDetailBizId, setIsResetDetailSelection, resetFilters } = useSearchModalStore(); const { TABS, viewMultipleFeature, fetchFilteredData } = useSearchModal(); const { handleBasicCellClick, basicExcelDownload } = useBasicTab(); const { WORK_TYPES, OPERATION_TABLE_SIZE, OPERATION_TABLE_HEADLIST, MAINTENANACE_TABLE_HEADLIST, CLEANING_TABLE_HEADLIST, INSPECTION_TABLE_HEADLIST, handleOperationCellClick, handleOperationResultCellClick, operationExcelDownload, operationResultExcelDownload, handleOperationPageNation } = useOperationTab(); const dynamicHeadlist: { id: string, title: string }[] = useMemo(() => { if (activeTab === 'basic') { // 기본정보 if (basicType === 'tb_ms_swage_ppl') return MsSwagePplCol2;// 하수관로 if (basicType === 'tb_il_swage_prcs_fclt') return SwtrmtFcltCol2;// 하수처리시설 if (basicType === 'tb_ms_swage_prcs_zone') return SwtrmtPrcsZoneCol2; // 하수처리구역 if (basicType === 'tb_ms_swage_mhl') return MsSwageMhlCol2; // 하수맨홀 if (basicType === 'tb_ms_swage_pmstn') return ExclnSewagePumpCol2; // 하수펌프장 if (basicType === 'tb_ms_stofcbr') return stofcbrCol2; // 우수토실 return []; } if (activeTab === 'operation') return OPERATION_TABLE_HEADLIST; // 유지관리 정보 return []; }, [activeTab, basicType, workType]); const dynamicHeadlist2: { id: string, title: string }[] = useMemo(() => { if (activeTab === 'operation') { if (workType === WORK_TYPES[0]?.val) return MAINTENANACE_TABLE_HEADLIST; // 보수 및 갱신 if (workType === WORK_TYPES[1]?.val) return CLEANING_TABLE_HEADLIST; // 점검 및 진단 if (workType === WORK_TYPES[2]?.val) return INSPECTION_TABLE_HEADLIST; // 청소 및 준설 } return []; }, [activeTab, workType]); useEffect(() => { resetFilters(); }, [activeTab, basicType, workType]); // 페이지 변경 시마다 데이터 fetch useEffect(() => { setIsResetPage(false); setIsResetDetailPage(true); setDetailBizId(0); if (showTable) fetchFilteredData(); }, [curPage]); // 페이지 변경 시마다 데이터 fetch useEffect(() => { setIsResetDetailSelection(false); if (showTable) handleOperationPageNation(Number(detailBizId)); }, [detailCurPage]); const renderBody = () => ( <> {/* 탭 영역 */} ({ value: tab.val, label: tab.text }))} onValueChange={(value: string) => setActiveTab(value)} /> {activeTab === 'basic' && ()} {/* 기본정보 탭 */} {activeTab === 'operation' && ()} {/* 유지관리 정보 탭 */} {activeTab === 'report' && ()} {/* 하수도정비기본계획보고서 탭 */} {/* 📋 결과 리스트 */} {/* 기본정보 탭 */} {activeTab === 'basic' && (
{ const label = BASIC_TYPES.find((type) => type.val === basicType)?.text return (<>{label} 조회 결과); })() } tableData={tableData} headlist={dynamicHeadlist} pageSize={10} total={tableCount} cellClick={handleBasicCellClick} onPageChange={setCurPage} resetPageNo={isResetPage} resetSelection={isResetSelection} curPage={curPage} headButton={
} />
)} {/* 유지관리 정보 탭 */} {activeTab === 'operation' && ( <>
{/*
*/} { const label = WORK_TYPES.find((type) => type.val === workType)?.text return (<>{label} 사업 현황); })() } tableData={tableData} headlist={dynamicHeadlist} pageSize={OPERATION_TABLE_SIZE} total={tableCount} cellClick={handleOperationCellClick} onPageChange={setCurPage} resetPageNo={isResetPage} resetSelection={isResetSelection} curPage={curPage} headButton={ } /> {/*
*/}
{/* 테이블2 영역 */} {/*
*/} { const label = WORK_TYPES.find((type) => type.val === workType)?.text return (<>{label} 결과표); })() } tableData={detailTableData} headlist={dynamicHeadlist2} pageSize={OPERATION_TABLE_SIZE} total={detailTableCount} cellClick={handleOperationResultCellClick} onPageChange={setDetailCurPage} resetPageNo={isResetDetailPage} resetSelection={isResetDetailSelection} curPage={detailCurPage} headButton={
} /> {/*
*/}
)} ); return (
); }; export default React.memo(SearchModal);