/** * ➡️ 경로 : I/I 분석 모든 페이지 * * 📄 Base Layout * 분석 페이지 기본 레이아웃 컴포넌트 * * - 검색 및 필터링 UI 제공 (시도/시군구/하수처리시설 선택) * - 날짜 범위 선택 기능 * - 파일 다운로드 및 삭제 버튼 지원 * - 분석 실행 버튼 및 확인 토스트 처리 * - 양식 파일 다운로드 링크 제공 * - 폼 제출 및 이벤트 핸들링 */ 'use client' import { DateMonthPicker, Form, SelectBox } from '@common/business_components/ui' import ListDiv from '@common/business_components/ui/list_div' import { Button, Label } from '@common/components/ui' import { useEffect, type ReactNode } from 'react' import { CtpvSggPrcsFcltSelectBox } from '@/components/ui/ctpvSggPrcsFcltSelectBox' import { confirmToast } from '@/components/ui/toast' import { toast, Toaster } from "react-hot-toast"; type TitleName = { mainTitle: string firstCardTitle: string secondCardTitle?: string } type SelectBox = { labelNm?: Label searchChk?: boolean title?: string; onSearchClick?: () => 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 firstDivBtn?: boolean selectBox?: SelectBox 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; setIsLoading?: (isLoading: boolean) => void; onExcelDownload?: () => void; onDeleteFile?: () => void; onAnalysis?: () => void; selectedRowData?: any; isIr?: boolean; isRdii?: boolean; } const BaseLayout = ({ children, titleName, form, onSubmitEvent, graphBtn = false, analysisBtn, selectBox, showDatePicker = false, ctpvCd, sggCd, sggName, sigungu, selectedSwagePrcsFclt, onSwagePrcsFcltChange, aplcnYmFrom, setAplcnYmFrom, aplcnYmTo, setAplcnYmTo, setCtpvCd, setSggCd, setSggName, setSwtrmtFcltNm, setIsLoading, onExcelDownload, onDeleteFile, onAnalysis, isIr = false, isRdii = false, }: BaseLayout) => { // 컴포넌트 언마운트 시 confirmToast 정리 useEffect(() => { return () => { // 컴포넌트가 언마운트될 때 global-confirm-toast ID를 가진 Toast 제거 toast.dismiss("global-confirm-toast"); }; }, []); // 파일 다운로드 const isChckFile = () => { // Excel 다운로드 함수가 있으면 Excel 다운로드 실행 if (onExcelDownload) { onExcelDownload(); return; } return true } // 파일 삭제 const isDeleteFile = async () => { // Excel 다운로드 함수가 있으면 Excel 다운로드 실행 if (onDeleteFile) { onDeleteFile(); return; } } const handleConfirm = () => { // 기존 confirmToast가 있다면 먼저 제거 toast.dismiss("global-confirm-toast"); confirmToast( "분석에는 2분 내외의 시간이 소요될 수 있습니다.\n분석을 진행하시겠습니까?", onAnalysis ?? (() => { }), "text-xl font-medium text-gray-800" ); }; 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="ml-8 w-[100px]" 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-[100px] mr-8" startYear={1900} // 시작 연도 설정 /> )} { setCtpvCd(sidoId); setSggCd('0'); }} onSigunguChange={setSggCd} setSggName={setSggName} selectedSwagePrcsFclt={selectedSwagePrcsFclt} onSwagePrcsFcltChange={onSwagePrcsFcltChange} setSwtrmtFcltNm={setSwtrmtFcltNm} setIsLoading={setIsLoading} /> {selectBox?.searchChk && (
)}

{titleName.firstCardTitle}

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

{titleName?.secondCardTitle}

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