/** * ➡️ 경로 : I/I 분석 모든 페이지 * * 📄 Base Layout * 분석 페이지 기본 레이아웃 컴포넌트 * * - 검색 및 필터링 UI 제공 (시도/시군구/하수처리시설 선택) * - 날짜 범위 선택 기능 * - 파일 다운로드 및 삭제 버튼 지원 * - 분석 실행 버튼 및 확인 토스트 처리 * - 양식 파일 다운로드 링크 제공 * - 폼 제출 및 이벤트 핸들링 */ "use client"; import { DateMonthPicker, Form } from "@common/business_components/ui"; import { Button, Label } from "@common/components/ui"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import type { ReactNode } from "react"; import { CtpvSggPrcsFcltSelectBox } from "@/components/ui/ctpvSggPrcsFcltSelectBox"; type TitleName = { mainTitle: string; firstCardTitle: string; secondCardTitle?: string; }; type SelectBox = { labelNm?: Label; searchChk?: boolean; title?: string; onSearchClick?: () => Promise; onResetClick?: () => void | Promise; }; type Label = { first: string; second: string; third: string; fourth: string; }; // API로부터 받아올 데이터 타입을 정의 (SelectBox에 사용될 형태) interface ApiSelectOption { text: string; val: string; } type BaseLayout = { children?: ReactNode[]; titleName: TitleName; form: any; onSubmitEvent: Function; graphBtn?: boolean; analysisBtn?: string; resultViewBtn?: string; firstDivBtn?: boolean; selectBox?: SelectBox; selectionComponent?: ReactNode; showDatePicker?: boolean; ctpvCd: string; sggCd: string; sggName?: string; sigungu?: ApiSelectOption; selectedSwagePrcsFclt?: string; onSwagePrcsFcltChange?: (value: string) => void; aplcnYmFrom?: string; setAplcnYmFrom?: (aplcnYmFrom: string) => void; aplcnYmTo?: string; setAplcnYmTo?: (aplcnYmTo: string) => void; setCtpvCd: (ctpv: string) => void; setSggCd: (sgg: string) => void; setSggName?: (sggName: string) => void; setSwtrmtFcltNm?: (swtrmtFcltNm: string) => void; defaultSwtrmtFcltNm?: string; setIsLoading?: (isLoading: boolean) => void; onExcelDownload?: () => void; onDeleteFile?: () => void; onAnalysis?: () => void | Promise; onResultView?: () => void; selectedRowData?: any; isIr?: boolean; isRdii?: boolean; }; const BaseLayout = ({ children, titleName, form, onSubmitEvent, graphBtn = false, analysisBtn, resultViewBtn, selectBox, selectionComponent, showDatePicker = false, ctpvCd, sggCd, sggName, sigungu, selectedSwagePrcsFclt, onSwagePrcsFcltChange, aplcnYmFrom, setAplcnYmFrom, aplcnYmTo, setAplcnYmTo, setCtpvCd, setSggCd, setSggName, setSwtrmtFcltNm, defaultSwtrmtFcltNm, setIsLoading, onExcelDownload, onDeleteFile, onAnalysis, onResultView, isIr = false, isRdii = false, }: BaseLayout) => { // 분석 실행 전 CS와 동일한 전역 확인 대화상자를 호출한다. const { confirm } = useConfirm(); // 파일 다운로드 const isChckFile = () => { // Excel 다운로드 함수가 있으면 Excel 다운로드 실행 if (onExcelDownload) { onExcelDownload(); return; } return true; }; // 파일 삭제 const isDeleteFile = async () => { // Excel 다운로드 함수가 있으면 Excel 다운로드 실행 if (onDeleteFile) { onDeleteFile(); return; } }; const handleConfirm = async () => { const shouldRunAnalysis = await confirm( "분석에는 2분 내외의 시간이 소요될 수 있습니다.\n분석을 진행하시겠습니까?", ); if (!shouldRunAnalysis) return; await onAnalysis?.(); }; return ( <>
{/* searchBox.title이 있으면 h3 태그로 제목을 표시합니다. */} {selectBox?.title && (

{selectBox.title}

)}
{showDatePicker && ( // showDatePicker 값에 따라 DatePicker 렌더링 <> { // aplcnYm이 없으면 현재 연월을 기본값으로 설정 const now = new Date(); const year = now.getFullYear(); // const month = String(now.getMonth() + 1).padStart(2, '0'); // return `${year}${month}`; return `${year}01`; })(), // yyyyMM 형식 onChange: (value: string) => { setAplcnYmFrom?.(value); // string 값을 직접 전달 }, }} selectClass="w-[10rem]" startYear={1900} // 시작 연도 설정 /> ~ { // aplcnYm이 없으면 현재 연월을 기본값으로 설정 const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart( 2, "0", ); return `${year}${month}`; })(), // yyyyMM 형식 onChange: (value: string) => { setAplcnYmTo?.(value); // string 값을 직접 전달 }, }} selectClass="w-[10rem]" startYear={1900} // 시작 연도 설정 /> )} {/* 침입수 분석 실행처럼 선택 구조가 다른 화면은 커스텀 selector를 주입하고, 나머지는 기존 시설 selector를 유지한다. */} {selectionComponent ?? ( { setCtpvCd(sidoId); setSggCd("0"); }} onSigunguChange={setSggCd} setSggName={setSggName} selectedSwagePrcsFclt={selectedSwagePrcsFclt} onSwagePrcsFcltChange={onSwagePrcsFcltChange} setSwtrmtFcltNm={setSwtrmtFcltNm} defaultSwtrmtFcltNm={defaultSwtrmtFcltNm} setIsLoading={setIsLoading} /> )} {selectBox?.searchChk && (
{selectBox.onResetClick ? ( ) : null}
)}

{titleName.firstCardTitle}

{graphBtn && ( )} {/* 침입수 분석 */} {isIr && ( )} {/* RDII 분석 */} {isRdii && ( )} {/* 분석 버튼 */} {analysisBtn && ( )} {resultViewBtn && ( )} {graphBtn && ( )}
{/* 폼 정보 입력 칸 */} {children?.[0]}
{children?.[1] != null && (

{titleName?.secondCardTitle}

{graphBtn && ( )} {/* 그래프 있을 시 */} {graphBtn && ( )}
{children?.[1]}
)} ); }; export default BaseLayout;