refactor: infilChart.tsx 공통 컴포넌트 적용

This commit is contained in:
swcho
2025-06-30 16:33:54 +09:00
parent 842e63cef1
commit 2c3b2785bc
@@ -1,15 +1,11 @@
'use client'
import React, { useState, useMemo, useEffect } from 'react'
import { SelectBox } from '@common/business_components/ui'
import { type ChartConfig, MainChart, CHART_FORM, UiModal } from "@common/business_components";
import { CHART_FORM, type ChartConfig, MainChart, UiModal } from "@common/business_components";
import { SelectBox } from '@common/business_components/ui';
import { Button, Input, Label } from '@common/components';
import { getData } from "@/components/lib/api";
import React, { useEffect, useState } from 'react';
import type { TInftwtAnls, TInftwtAnlsRslt } from './aplcnYms';
import { useAplcnYms, selectInftwtAnls, getOptionsInftwtAnlsInfo} from './aplcnYms';
import { selectInftwtAnlsRslt, getChartDataInftwtAnlsRslt} from './aplcnYms';
import { selectOilq, getChartDataOilq} from './aplcnYms';
import { set } from 'react-hook-form';
import type { TInftwtAnls } from './aplcnYms';
import { getChartDataInftwtAnlsRslt, getOptionsInftwtAnlsInfo, selectInftwtAnls, selectInftwtAnlsRslt, useAplcnYms } from './aplcnYms';
type ModalOpenProp = {
isModalOpen: boolean,
setIsModalOpen: (open: boolean) => void,
@@ -17,51 +13,7 @@ type ModalOpenProp = {
btnTxt?: string,
}
// 더미 데이터 리스트
const rainDataList = [
{ val: "R20240815.xlsx", text: "R20240815.xlsx" },
{ val: "R20240701.xlsx", text: "R20240701.xlsx" },
{ val: "R20240615.xlsx", text: "R20240615.xlsx" },
{ val: "R20240531.xlsx", text: "R20240531.xlsx" },
{ val: "R20240420.xlsx", text: "R20240420.xlsx" },
];
const rtxSourceList = [
{ val: "2015년 하수도정비기본계획", text: "2015년 하수도정비기본계획" },
{ val: "2018년 하수도정비기본계획", text: "2018년 하수도정비기본계획" },
{ val: "2020년 하수도정비기본계획", text: "2020년 하수도정비기본계획" },
{ val: "2022년 하수도정비기본계획", text: "2022년 하수도정비기본계획" },
{ val: "2024년 하수도정비기본계획", text: "2024년 하수도정비기본계획" },
];
// 상수사용월 더미 데이터
const dummyAplcnYms = [
{ val: '0', text: '선택' },
{ val: '202401', text: '2024-01' },
{ val: '202402', text: '2024-02' },
{ val: '202403', text: '2024-03' },
{ val: '202404', text: '2024-04' },
{ val: '202405', text: '2024-05' },
{ val: '202406', text: '2024-06' },
{ val: '202407', text: '2024-07' },
{ val: '202408', text: '2024-08' },
{ val: '202409', text: '2024-09' },
{ val: '202410', text: '2024-10' },
{ val: '202411', text: '2024-11' },
{ val: '202412', text: '2024-12' },
];
// 침입수분석정보 더미 데이터
const dummyInftwtAnlsInfos = [
{ val: 0, text: '선택' },
{ val: 1001, text: '서울시 강남구 침입수분석 1차' },
{ val: 1002, text: '서울시 강남구 침입수분석 2차' },
{ val: 1003, text: '서울시 서초구 침입수분석 1차' },
{ val: 1004, text: '부산시 해운대구 침입수분석 1차' },
{ val: 1005, text: '대구시 수성구 침입수분석 1차' },
{ val: 1006, text: '인천시 연수구 침입수분석 1차' },
{ val: 1007, text: '광주시 북구 침입수분석 1차' },
{ val: 1008, text: '대전시 유성구 침입수분석 1차' },
{ val: 1009, text: '울산시 남구 침입수분석 1차' },
{ val: 1010, text: '경기도 성남시 침입수분석 1차' },
];
const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => {
const [popupOpen, setPopupOpen] = React.useState(true);
@@ -72,11 +24,6 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState<any[]>([]); // 침입수분석정보 options
const [inftwtAnls, setInftwtAnls] = useState<TInftwtAnls | null>(null); // 침입수분석정보
const [inftwtAnlsSn, setInftwtAnlsSn] = useState<number>(0); // 침입수분석 정보 선택시 사용
const [drtwSwtcRt, setDrtwSwtcRt] = useState<number>(0); // 오수전환율
const [atflHrPttnNm, setAtflHrPttnNm] = useState<number>(0); // 시간패턴 파일명
const [atflMpng, setAtflMpng] = useState<number>(0); // 수용가-맨홀 매칭
const [atflInpNm, setAtflInpNm] = useState<number>(0); // 관망도 파일명
const [tbSnOilqData, setTbSnOilqData] = useState<number>(0); // 유량 파일명
const [chartData, setChartData] = useState<{ chartData1: { label: string; val: number }[]; chartData2: { label: string; val: number }[] }>({
chartData1: [{ label: "1", val: 20 },
{ label: "3", val: 40 },
@@ -86,36 +33,12 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
{ label: "5", val: 55 },],
});
// chartData1: [],chartData2: [],});
useEffect(() => {
if(isModalOpen === false){
setPopupOpen(true); // 모달이 닫힐 때 팝업은
setAplcnYm(""); // 상수사용월 초기화
setInftwtAnlss([]); // 침입수분석 초기화
setInftwtAnlsInfos([]); // 침입수분석정보 초기화
setInftwtAnls(null); // 침입수분석정보 초기화
setInftwtAnlsSn(0); // 침입수분석 일련번호 초기화
setChartData({
chartData1: [{ label: "1", val: 20 },
{ label: "3", val: 40 },
{ label: "5", val: 60 },],
chartData2: [{ label: "1", val: 15 },
{ label: "3", val: 35 },
{ label: "5", val: 55 },],
}); // 차트 데이터 초기화
}
}, [isModalOpen]);
// 상수사용월, 분석정보 더미 데이터로 초기화 (API 호출 실패 시 대비)
const [selectedAplcnYms, setSelectedAplcnYms] = useState<string>(dummyAplcnYms[0]?.val || "0");
const [selectedInftwtAnlsInfos, setSelectedInftwtAnlsInfos] = useState<number>(dummyInftwtAnlsInfos[0]?.val || 0);
// 선택된 값들을 위한 상태 추가
const [selectedRainData, setSelectedRainData] = useState<string>(rainDataList[0]?.val || "선택"); // 초기값으로 첫 번째 항목 선택
const [selectedRtxSource, setSelectedRtxSource] = useState<string>(rtxSourceList[0]?.val || "선택");
// API에서 데이터를 가져오지 못할 경우 더미 데이터 사용
// const aplcnYms = useAplcnYms().length > 0 ? useAplcnYms() : dummyAplcnYms;
//const [aplcnYms, setAplcnYms] = useState<{ text: string; val: string }[]>([]);
// const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기
const aplcnYms = useAplcnYms(); // 상수사용월 데이터 가져오기
const openPopup = () => {
if (buttonRef.current) {
const rect = buttonRef.current.getBoundingClientRect(); // 버튼 위치 계산
@@ -130,10 +53,60 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
const chartForm = CHART_FORM.LINE;
const chartConfig = {
chartData1: {label: '침입수예측유량',color: "red",},
chartData2: {label: '실측유량',color: "orange",}
} as ChartConfig;
chartData1: { label: '침입수예측유량', color: "red", },
chartData2: { label: '실측유량', color: "orange", }
} as ChartConfig;
useEffect(() => {
if (isModalOpen === false) {
setPopupOpen(true); // 모달이 닫힐 때 팝업은
setAplcnYm(""); // 상수사용월 초기화
setInftwtAnlss([]); // 침입수분석 초기화
setInftwtAnlsInfos([]); // 침입수분석정보 초기화
setInftwtAnls(null); // 침입수분석정보 초기화
setInftwtAnlsSn(0); // 침입수분석 일련번호 초기화
setChartData({
chartData1: [{ label: "1", val: 20 },
{ label: "3", val: 40 },
{ label: "5", val: 60 },],
chartData2: [{ label: "1", val: 15 },
{ label: "3", val: 35 },
{ label: "5", val: 55 },],
}); // 차트 데이터 초기화
}
}, [isModalOpen]);
// 상수사용월 변경시 분석 정보 리스트 가져오기
useEffect(() => {
// aplcnYm이 비어있거나 "0"이면 API 호출하지 않음
if (!aplcnYm || aplcnYm === "0" || aplcnYm === "") {
setInftwtAnlsSn(0); // 초기화
setInftwtAnlsInfos([{ val: 0, text: '선택' }]);
return;
}
selectInftwtAnls(aplcnYm)
.then((data) => {
setInftwtAnlss(data ?? []);
setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data));
})
.catch((error) => {
console.error("selectInftwtAnls 에러:", error);
setInftwtAnlss([]);
setInftwtAnlsInfos([{ val: 0, text: '선택' }]);
});
setInftwtAnlsSn(0); // 초기화
}, [aplcnYm]);
// 값 표시
useEffect(() => {
// 선택된 침입수분석 정보에 대한 처리 로직
const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === inftwtAnlsSn);
if (selectedAnls) {
setInftwtAnls(selectedAnls);
}
}, [inftwtAnlsSn, inftwtAnlss]);
const closePopup = () => { // 팝업 닫기
selectInftwtAnlsRslt(inftwtAnlsSn, "L13101003").then((data) => {// 침입수분석 결과 조회
const rsltData = getChartDataInftwtAnlsRslt(data ?? []);
@@ -149,27 +122,9 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
// chartData2: rsltData // 유량
// }));
// });
setPopupOpen(false);
setPopupOpen(false);
};
const onChangeAplcnYm = (e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedValue = e.target.value;
selectInftwtAnls(selectedValue).then((data) => {
setInftwtAnlss(data ?? []);
console.log("onChangeAplcnYm", selectedValue, inftwtAnlss);
setInftwtAnlsInfos(getOptionsInftwtAnlsInfo(data ?? []));
});
setAplcnYm(selectedValue);
};
const onChangeInftwtAnlsInfo = (e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedInfo = e.target.value;
setInftwtAnlsSn(Number(selectedInfo)); // 선택값 상태로 저장
// 선택된 침입수분석 정보에 대한 처리 로직 추가
const selectedAnls = inftwtAnlss.find(anls => anls.inftwtAnlsSn === Number(selectedInfo));
if (selectedAnls) {
setInftwtAnls(selectedAnls);
}
};
const renderBody = () => (
@@ -213,10 +168,10 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
className="w-[200px] mr-8 z-[51]"
selectClass="rounded-lg bg-white"
label=''
selectArray={dummyAplcnYms}
value={selectedAplcnYms}
selectArray={aplcnYms}
value={aplcnYm}
onSelectValue={(val) => {
setSelectedAplcnYms(String(val));
setAplcnYm(String(val));
}}
/>
</div>
@@ -226,10 +181,10 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
className="w-[200px] mr-8 z-[51]"
selectClass="rounded-lg bg-white"
label=''
selectArray={dummyInftwtAnlsInfos}
value={selectedInftwtAnlsInfos}
selectArray={inftwtAnlsInfos}
value={inftwtAnlsSn}
onSelectValue={(val) => {
setSelectedInftwtAnlsInfos(Number(val));
setInftwtAnlsSn(Number(val));
}}
/>
</div>
@@ -238,10 +193,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder="입력"
value={drtwSwtcRt}
onChange={(e) => {
setDrtwSwtcRt(Number(e.target.value));
}}
value={inftwtAnls?.drtwSwtcRt ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
@@ -249,10 +202,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder="입력"
value={atflHrPttnNm}
onChange={(e) => {
setAtflHrPttnNm(Number(e.target.value));
}}
value={inftwtAnls?.atflHrPttnNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
@@ -260,10 +211,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder="입력"
value={atflMpng}
onChange={(e) => {
setAtflMpng(Number(e.target.value));
}}
value={inftwtAnls?.atflMpngNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
@@ -271,10 +220,8 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder="입력"
value={atflInpNm}
onChange={(e) => {
setAtflInpNm(Number(e.target.value));
}}
value={inftwtAnls?.atflInpNm ?? ""}
readOnly={true}
/>
</div>
<div className='flex items-center justify-between'>
@@ -282,41 +229,10 @@ const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOp
<Input
className="mr-8 w-[200px] !text-xl placeholder:text-center"
placeholder="입력"
value={tbSnOilqData}
onChange={(e) => {
setTbSnOilqData(Number(e.target.value));
}}
value={inftwtAnls?.atflOilqNm ?? "없음"}
readOnly={true}
/>
</div>
{btnTxt === 'RDII' ?
<>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">강우 자료:</Label>
<SelectBox
className="w-[150px] mr-8 z-[51]"
selectClass="rounded-lg bg-white"
label=''
selectArray={rainDataList}
value={selectedRainData}
onSelectValue={(val) => {
setSelectedRainData(String(val));
}}
/>
</div>
<div className='flex items-center justify-between'>
<Label className="mr-2 w-auto text-2xl text-gray-600 whitespace-nowrap">RTX 계수 출처:</Label>
<SelectBox
className="w-[150px] mr-8 z-[51]"
selectClass="rounded-lg bg-white"
label=''
selectArray={rtxSourceList}
value={selectedRtxSource}
onSelectValue={(val) => {
setSelectedRtxSource(String(val));
}}
/>
</div>
</> : null}
</div>
<div className="flex justify-end mt-4 space-x-2">
<button className="px-4 py-2 bg-gray-600 text-white rounded" onClick={closePopup}>