243 lines
9.2 KiB
TypeScript
243 lines
9.2 KiB
TypeScript
'use client';
|
|
import React, { useEffect, useState } from 'react';
|
|
import { Button, Label } from '@common/components';
|
|
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
|
|
import { SelectBox, UiTable } from '@common/business_components/ui';
|
|
import LoadingOverlay from '@/components/ui/LoadingBar';
|
|
import { addFileName, flattenFolders, getFileDownload, getDcTree, useDcTree, reportGubuns } from './searchModalReportApi';
|
|
import useStore from '../../../store/useStore';
|
|
import { CtpvSggPrcsFcltSelectBox } from '@/components/ui/ctpvSggPrcsFcltSelectBox';
|
|
|
|
|
|
// 하수도정비 기본계획 보고서
|
|
export const reportTableHeadlist = [
|
|
{ id: "no", title: "NO" },
|
|
{ id: "sido", title: "시도" },
|
|
{ id: "sigungu", title: "시군구" },
|
|
{ id: "approvalYear", title: "승인년도" },
|
|
{ id: "plantZoneGubun", title: "구분" },
|
|
{ id: "reportGubun", title: "보고서구분" },
|
|
{ id: "fileName", title: "파일명" },
|
|
{ id: "regDate", title: "등록일자" },
|
|
];
|
|
interface ReportTabProps {
|
|
open?: boolean;
|
|
isSearch?: boolean;
|
|
ctpvNm?: string;
|
|
sggNm?: string;
|
|
}
|
|
|
|
const ReportTab: React.FC<ReportTabProps> = ({ open, isSearch = true, ctpvNm, sggNm }) => {
|
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [isResetPage, setIsResetPage] = useState<boolean>(false);
|
|
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
|
|
const [showTable, setShowTable] = useState(false);
|
|
const [tableData, setTableData] = useState<any[]>([]);
|
|
const [tableCount, setTableCount] = useState(0);
|
|
const [curPage, setCurPage] = useState(1);
|
|
const [yearFilter, setYearFilter] = useState({ start: "", end: "" });
|
|
const [ctpvCd, setCtpvCd] = useState(0);
|
|
const [sggCd, setSggCd] = useState(0);
|
|
const [reportGubun, setReportGubun] = useState("0");
|
|
// const [gubun, setGubun] = useState("");
|
|
|
|
const { ctpv, sgg } = useStore();
|
|
|
|
// 하수정비기본계획 report
|
|
const reportOriginData = useDcTree(""); //:Folder[]
|
|
|
|
useEffect(() => {
|
|
// filterParams 초기화
|
|
setCtpvCd(0);
|
|
setSggCd(0);
|
|
setReportGubun('0');
|
|
setYearFilter({ start: "", end: "" });
|
|
setShowTable(false);
|
|
setTableData([]);
|
|
setTableCount(0);
|
|
setCurPage(1); // 페이지를 1로 초기화
|
|
setIsResetPage(true); // 페이지를 초기화
|
|
setIsResetSelection(true); // 선택 초기화
|
|
}, [open]);
|
|
|
|
useEffect(() => {
|
|
let newCtpvCd = ctpv.find((n) => n.name === ctpvNm)?.id || 0;
|
|
let newSggCd = sgg.find((n) => n.name === sggNm)?.id || 0;
|
|
|
|
setCtpvCd(newCtpvCd);
|
|
setSggCd(newSggCd);
|
|
}, [ctpvNm, sggNm]);
|
|
|
|
// ctpvCd, sggCd가 업데이트된 후에 fetchFilteredData 실행
|
|
useEffect(() => {
|
|
if (!isSearch && ctpvCd && sggCd) {
|
|
fetchFilteredData();
|
|
}
|
|
}, [reportOriginData, ctpvCd, sggCd, isSearch]);
|
|
|
|
// 페이지 변경 시마다 데이터 fetch
|
|
useEffect(() => {
|
|
// showTable이 true일 때만 fetch (최초 렌더 방지)
|
|
setIsResetPage(false);
|
|
|
|
if (showTable) fetchFilteredData();
|
|
}, [curPage]);
|
|
|
|
const handleCtpvCdChange = (sidoId: number) => {
|
|
setCtpvCd(sidoId);
|
|
setSggCd(0);
|
|
}
|
|
|
|
// 조회 버튼 클릭 시 1페이지로 이동 및 데이터 초기화
|
|
const handleSearch = () => {
|
|
setCurPage(1); // 페이지를 1로 초기화
|
|
fetchFilteredData();
|
|
setIsResetPage(true); // 페이지를 초기화
|
|
setIsResetSelection(false); // 선택 초기화
|
|
setShowTable(true);
|
|
};
|
|
|
|
// 하수도정비기본계획 테이블 cellClick 핸들러
|
|
const handleReportCellClick = (index: number | undefined) => {
|
|
console.log(index);
|
|
if (typeof index === "number" && tableData[index]) {
|
|
const reportData = tableData[index];
|
|
const fileName = reportData.fileName;
|
|
const filePath = reportData.filePath;
|
|
if (reportData.fileSn !== "") {
|
|
getFileDownload(reportData.fileSn, fileName, filePath);
|
|
}
|
|
}
|
|
};
|
|
|
|
// 검색 API 호출 함수
|
|
const fetchFilteredData = async () => {
|
|
setIsLoading(true); // 로딩 시작
|
|
setIsResetSelection(true); // 선택 초기화
|
|
|
|
try {
|
|
const reportData = flattenFolders(reportOriginData);
|
|
let filterReportData = reportData;
|
|
console.log("필터링 전 보고서 데이터:", filterReportData);
|
|
console.log('ctpv, sgg, ctpvCd, sggCd', ctpv, sgg, ctpvCd, sggCd);
|
|
|
|
if (ctpvCd) { // 시도검색
|
|
console.log('시도 실행되나');
|
|
const sidoOption = ctpv.find((n) => String(n.id) === String(ctpvCd));
|
|
console.log('sidoOption', sidoOption)
|
|
filterReportData = filterReportData.filter(item => item.sido === sidoOption?.name);
|
|
console.log('시도 필터링 후:', filterReportData);
|
|
}
|
|
if (sggCd) { // 시군구검색
|
|
console.log('시군구 실행되나');
|
|
const sigunguOption = sgg.find((n) => String(n.id) === String(sggCd));
|
|
filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.name);
|
|
console.log('시군구 필터링 후:', filterReportData);
|
|
}
|
|
if (reportGubun !== "0") { // 보고서구분검색
|
|
const reportGubunOption = reportGubuns.find((n) => n.val === reportGubun);
|
|
filterReportData = filterReportData.filter(item => item.reportGubun === reportGubunOption?.text);
|
|
}
|
|
|
|
if (yearFilter.start != "" && yearFilter.end == "") //승인년도검색
|
|
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear >= yearFilter.start + "년" : null);
|
|
if (yearFilter.start == "" && yearFilter.end != "")
|
|
filterReportData = filterReportData.filter(item => (item.approvalYear) ? item.approvalYear <= yearFilter.end + "년" : null);
|
|
if (yearFilter.start != "" && yearFilter.end != "") {
|
|
filterReportData = filterReportData.filter(item => {
|
|
return (item.approvalYear) ? item.approvalYear >= yearFilter.start + "년" && item.approvalYear <= yearFilter.end + "년" : null;
|
|
});
|
|
}
|
|
// if (gubun !== "") { // 구분검색 (추후 사용할 수도 있을 것 같아 남겨둠)
|
|
// filterReportData = filterReportData.filter(item => (item.plantZoneGubun) ? String(item.plantZoneGubun).includes(String(gubun)) : null);
|
|
// }
|
|
console.log('report count:', filterReportData.length);
|
|
|
|
setTableCount(filterReportData.length || 0);
|
|
|
|
filterReportData = filterReportData.slice((curPage - 1) * 10, curPage * 10); // paging
|
|
filterReportData = filterReportData?.map((item, index) => ({ ...item, no: (curPage - 1) * 10 + index + 1 }));
|
|
|
|
addFileName(filterReportData).then(data => {
|
|
filterReportData = data;
|
|
setTableData(filterReportData || []);
|
|
setIsResetSelection(false); // 데이터 설정 후 선택 초기화 해제
|
|
});
|
|
|
|
setTableData(filterReportData || []);
|
|
setShowTable(true);
|
|
} catch (err) {
|
|
console.error('API ERROR:', err);
|
|
setTableData([]);
|
|
setIsResetSelection(false); // 에러 시에도 선택 초기화 해제
|
|
} finally {
|
|
setIsLoading(false); // 로딩 종료
|
|
}
|
|
};
|
|
|
|
|
|
return (
|
|
<>
|
|
<div className={`relative flex flex-col border rounded-lg p-5 w-full ${isSearch ? "h-[10vh]" : "h-[6vh]"}`}>
|
|
{isSearch && (
|
|
<>
|
|
<div className="flex items-center mb-3">
|
|
<CtpvSggPrcsFcltSelectBox
|
|
sido={ctpvCd}
|
|
sigungu={sggCd}
|
|
onSidoChange={(sidoId: number) => { handleCtpvCdChange(sidoId) }}
|
|
onSigunguChange={setSggCd}
|
|
setIsLoading={setIsLoading}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
<div className="flex items-center mb-6">
|
|
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">보고서 구분</Label>
|
|
<SelectBox className="w-44 mr-8"
|
|
selectClass="rounded-lg bg-white"
|
|
label=""
|
|
selectArray={[...reportGubuns]}
|
|
value={reportGubun} onSelectValue={val => setReportGubun(String(val))}
|
|
selectContentClass="z-[101]" labelClass='whitespace-nowrap text-xl text-gray-600 pr-2'
|
|
/>
|
|
{/* 승인년도 필터 */}
|
|
<YearRangeSelectBox
|
|
start={yearFilter.start}
|
|
end={yearFilter.end}
|
|
onChange={range => setYearFilter({ ...yearFilter, start: range.start, end: range.end })}
|
|
startLabel="승인년도" endLabel=""
|
|
/>
|
|
{/* 조회 버튼 */}
|
|
<div className="flex-1 flex justify-end">
|
|
<Button className="text-base py-2" onClick={handleSearch}>조회</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="h-[79vh] w-full overflow-hidden rounded-lg border">
|
|
{/* 테이블2 영역 (가로/세로 스크롤 가능) */}
|
|
<div className="flex-1 px-2 pb-2">
|
|
<LoadingOverlay isLoading={isLoading} />
|
|
<UiTable
|
|
headName={(() => {
|
|
return (<>조회 결과 ({tableCount.toLocaleString('ko-KR')})건</>);
|
|
})()
|
|
}
|
|
tableData={tableData}
|
|
headlist={reportTableHeadlist}
|
|
pageSize={10}
|
|
total={tableCount}
|
|
cellClick={handleReportCellClick}
|
|
onPageChange={setCurPage}
|
|
resetPageNo={isResetPage}
|
|
resetSelection={isResetSelection}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default React.memo(ReportTab); |