Merge remote-tracking branch 'origin/main' into iipbs/wr/dev

This commit is contained in:
yschoi
2025-07-28 12:41:08 +09:00
9 changed files with 221 additions and 173 deletions
@@ -162,7 +162,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
<span className="text-2xl text-red-600 font-bold">● 침입수량 산정결과</span>
<div className="flex items-center mt-2">
<span className="ml-5 text-black text-xl">침입수량 : </span>
<span className="w-[35px] inline-block text-right text-black text-xl font-bold">{inftwtQty}</span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold">{inftwtQty}</span>
<span className="ml-2 text-black text-xl">m³/d</span>
</div>
</div>
@@ -170,7 +170,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
{/* 차트 */}
<div className="h-[90%] bg-white text-3xl">
<MainChart chartConfig={chartConfig} chartForm={chartForm} chartData={chartData} chartTitle={'침입수량 그래프'}
yFieldText2="시간" yFieldText="유량(m³/h)"/>
yFieldText2="" yFieldText="유량(m³/h)"/>
</div>
</div>
{popupOpen && (
@@ -161,17 +161,17 @@ const RdiiChart = ({ pplMngNo }: ModalOpenProp) => {
<span className="text-2xl text-red-600 font-bold">● 강우유입수량 분석결과</span>
<div className="flex items-center mt-2">
<span className="w-[95px] inline-block text-right text-black text-xl">평균RDII : </span>
<span className="w-[30px] inline-block text-right text-black text-xl font-bold"> {rdiiQty}</span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold"> {rdiiQty}</span>
<span className="ml-2 text-black"> m³/d</span>
</div>
<div className="flex items-center mt-2">
<span className="w-[95px] inline-block text-right text-black text-xl">적용강우량 : </span>
<span className="w-[30px] inline-block text-right text-black text-xl font-bold"> {rainTotal}</span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold"> {rainTotal}</span>
<span className="ml-2 text-black"> mm</span>
</div>
<div className="flex items-center mt-2">
<span className="w-[95px] inline-block text-right text-black text-xl">강우량대비RDII : </span>
<span className="w-[30px] inline-block text-right text-black text-xl font-bold"> {totalVolume}</span>
<span className="w-[45px] inline-block text-right text-black text-xl font-bold"> {totalVolume}</span>
<span className="ml-2 text-black"> m³/mm</span>
</div>
</div>
@@ -1,14 +1,15 @@
'use client';
import React, { useEffect, useState } from 'react';
import { Button } from '@common/components';
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { SelectBox } from '@common/business_components/ui';
import { Button, Input } from '@common/components';
import React from 'react';
//import { useDcTree, flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi';
import { SelectBox, UiTable } from '@common/business_components/ui';
import LoadingOverlay from '@/components/ui/LoadingBar';
import { addFileName, flattenFolders, getFileDownload, useCityCd, useDcTree, useSggCd, reportGubuns } from './searchModalReportApi';
import { type SelectDataType } from '../commonStore';
import { useCityCd, useSggCd } from '../components/searchModalReportApi';
// import { useBizByFcltStore } from "../../../store/StoreProvider";
// // 하수도정비 기본계획 보고서
// 하수도정비 기본계획 보고서
export const reportTableHeadlist = [
{ id: "no", title: "NO" },
{ id: "sido", title: "시도" },
@@ -23,79 +24,180 @@ export const reportTableHeadlist = [
interface BasicTabProps {
open?: boolean;
gubun: string;
sidos: SelectDataType[];
ctpvCd: string | number;
sigungu: string;
filteredSiguns: SelectDataType[];
yearFilter: { start: string; end: string; };
handleSearch: () => void;
handleCtpvCdChange: (val: string | number) => void;
// onOpenChange?: (open: boolean) => void;
// onFeatureSelect?: (row: any) => void;
// setTableData?: (data: any[]) => void;
// setTableCount?: (count: number) => void;
setYearFilter: (filter: { start: string; end: string }) => void;
setGubun: (gubun: string) => void;
setSigungu: (sigungu: string) => void;
}
const ReportTab: React.FC<BasicTabProps> = ({
open,
gubun,
sidos,
ctpvCd,
sigungu,
filteredSiguns = [{ val: '0', text: '전체', sido: '0' }],
yearFilter,
handleSearch,
handleCtpvCdChange,
// onOpenChange,
// onFeatureSelect,
// setTableData,
// setTableCount,
setYearFilter,
setGubun,
setSigungu,
}) => {
const ReportTab: React.FC<BasicTabProps> = ({ open }) => {
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'); // 하수정비기본계획 report
const [sigungu, setSigungu] = useState('0'); // 하수정비기본계획 report
const [filteredSiguns, setFilteredSiguns] = useState<SelectDataType[]>([{ val: '0', text: '전체', sido: '0' }]);
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
const [reportGubun, setReportGubun] = useState("0"); // 하수정비기본계획 report
// 하수정비기본계획 report
const sidos = useCityCd();
const siguns = useSggCd();
const reportOriginData = useDcTree(""); //:Folder[]
const dynamicHeadlist: { id: string, title: string }[] = reportTableHeadlist;
useEffect(() => {
// filterParams 초기화
setCtpvCd('0');
setSigungu('0');
setReportGubun('0');
setYearFilter({ start: "", end: "" });
setShowTable(false);
setTableData([]);
setTableCount(0);
setCurPage(1); // 페이지를 1로 초기화
setIsResetPage(true); // 페이지를 초기화
setIsResetSelection(true); // 선택 초기화
}, [open]);
// 페이지 변경 시마다 데이터 fetch
useEffect(() => {
// showTable이 true일 때만 fetch (최초 렌더 방지)
setIsResetPage(false);
setIsResetSelection(true); // 선택 초기화
if (showTable) fetchFilteredData();
}, [curPage]);
const handleCtpvCdChange = (val: string | number) => { // 하수도정비기본계획.시도
const sidoOption = sidos.find((n) => n.val === val);
setCtpvCd(String(val));
if (val !== '0') {
const filterSiguns = siguns.filter(item => item.sido === sidoOption?.text);
filterSiguns.unshift({ val: '0', text: '전체', sido: '0' });
setFilteredSiguns(filterSiguns);
}
setSigungu("0");
setGubun("");
setYearFilter({ start: "", end: "", });
}
// 조회 버튼 클릭 시 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 reportOriginData = await getDcTree('경기도');
const reportData = flattenFolders(reportOriginData);
let filterReportData = reportData;
if (ctpvCd !== "0") { // 시도검색
const sidoOption = sidos.find((n) => n.val === ctpvCd);
filterReportData = filterReportData.filter(item => item.sido === sidoOption?.text);
}
if (sigungu !== "0") { // 시군구검색
const sigunguOption = filteredSiguns.find((n) => n.val === sigungu);
filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.text);
}
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.plantZoneGugun) ? String(item.plantZoneGugun).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 }));
//const fileList = await getDcFile("CLS20250530000041");
addFileName(filterReportData).then(data => {
filterReportData = data;
setTableData(filterReportData || []);
});
setTableData(filterReportData || []);
setShowTable(true);
} catch (err) {
console.error('API ERROR:', err);
setTableData([]);
} finally {
setIsLoading(false); // 로딩 종료
}
};
return (
<>
<div className="relative flex flex-col border rounded-lg p-6 w-full h-[10vh]">
<div className="flex items-center mb-3">
<SelectBox
className="w-[150px] mr-8"
<SelectBox className="w-[150px] mr-8"
selectClass="rounded-lg bg-white"
label="시도"
selectArray={sidos}
value={ctpvCd}
onSelectValue={handleCtpvCdChange}
label="시도" selectArray={sidos}
value={ctpvCd} onSelectValue={handleCtpvCdChange}
selectContentClass="z-[101]"
/>
<SelectBox
className="w-48"
<SelectBox className="w-48"
selectClass="w-48 rounded-lg bg-white truncate"
label="시군구"
selectArray={filteredSiguns}
value={sigungu}
onSelectValue={val => setSigungu(String(val))}
label="시군구" selectArray={filteredSiguns}
value={sigungu} onSelectValue={val => setSigungu(String(val))}
selectContentClass="z-[101]"
/>
</div>
<div className="flex items-center mb-6">
<label className="inline-block w-auto whitespace-nowrap text-xl text-gray-600 mr-2">구분</label>
{/* <label className="inline-block w-auto whitespace-nowrap text-xl text-gray-600 mr-2">구분</label>
<Input
className='!text-xl w-[100px] placeholder:text-center mr-8'
placeholder="입력"
value={gubun}
onChange={(e) => { setGubun(e.target.value); }}
/> */}
<SelectBox className="w-[150px] 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}
{/* 승인년도 필터 */}
<YearRangeSelectBox start={yearFilter.start} end={yearFilter.end}
onChange={range => setYearFilter({ ...yearFilter, start: range.start, end: range.end })}
startLabel="승인년도"
endLabel=""
startLabel="승인년도" endLabel=""
/>
{/* 조회 버튼 */}
<div className="flex-1 flex justify-end">
@@ -103,6 +205,28 @@ const ReportTab: React.FC<BasicTabProps> = ({
</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={dynamicHeadlist}
pageSize={10}
total={tableCount}
cellClick={handleReportCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
/>
</div>
</div>
</>
);
};
@@ -3,11 +3,8 @@ import { UiModal, UITab, UiTable } from '@common/business_components/ui';
import axios from 'axios';
import React, { useEffect, useMemo, useState } from 'react';
import { ExclnSewagePumpCol2, MsSwageMhlCol2, MsSwagePplCol2, stofcbrCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2 } from '../components/common/table';
//import { useDcTree, flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi';
import { type SelectDataType } from '../commonStore';
import { MS_SWAGE_PPL_CODES, MS_SWAGE_PPL_USE_CODES, MS_SWAGE_MHL_CODES } from '../components/common/table';
import { addFileName, flattenFolders, getFileDownload, useCityCd, useDcTree, useSggCd } from '../components/searchModalReportApi';
// import { useBizByFcltStore } from "../../../store/StoreProvider";
import { getData } from "@/components/lib/api";
import BasicTab, { BASIC_TYPES } from './basicTab';
import OperationTab, { BIZ_TY_CD, operationCleaningTableHeadlist, operationInspectionTableHeadlist, operationMaintenanceTableHeadlist, operationTableHeadlist, WORK_TYPES } from './operationTab';
@@ -68,9 +65,10 @@ const SearchModal: React.FC<SearchModalProps> = ({
const [detailBizId, setDetailBizId] = useState(0);
const [city, setCity] = useState(0);
const [sgg, setSgg] = useState(0);
const [ctpvCd, setCtpvCd] = useState('0');
const [sigungu, setSigungu] = useState('0');
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
const [ctpvCd, setCtpvCd] = useState('0'); // 하수정비기본계획 report
const [sigungu, setSigungu] = useState('0'); // 하수정비기본계획 report
const [gubun, setGubun] = useState(""); // 하수정비기본계획 report
const [reportGubun, setReportGubun] = useState("0"); // 하수정비기본계획 report
const [start1, setStart1] = useState("");
const [start2, setStart2] = useState("");
const [end1, setEnd1] = useState("");
@@ -83,10 +81,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
const [yearFilter, setYearFilter] = useState({ start: "", end: "" });
const [filteredSiguns, setFilteredSiguns] = useState<SelectDataType[]>([{ val: '0', text: '전체', sido: '0' }]);
const sidos = useCityCd();
const siguns = useSggCd();
const reportOriginData = useDcTree(""); //:Folder[]
// 오늘 날짜 구하기
const today = new Date();
const todayYear = today.getFullYear().toString();
@@ -105,7 +100,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
return [];
}
if (activeTab === 'operation') return operationTableHeadlist;
if (activeTab === 'report') return reportTableHeadlist;
return [];
}, [activeTab, basicType, workType]);
@@ -134,8 +128,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
setVar4("");
setCity(0);
setSgg(0);
setCtpvCd('0');
setSigungu('0');
setYearFilter({
start: "",
end: "",
@@ -281,41 +273,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
setDetailTableData([]);
setDetailTableCount(0);
} else if (activeTab === 'report') {
//const reportOriginData = await getDcTree('경기도');
const reportData = flattenFolders(reportOriginData);
let filterReportData = reportData;
if (ctpvCd !== "0") { // 시도검색
const sidoOption = sidos.find((n) => n.val === ctpvCd);
filterReportData = filterReportData.filter(item => item.sido === sidoOption?.text);
}
if (sigungu !== "0") { // 시군구검색
const sigunguOption = filteredSiguns.find((n) => n.val === sigungu);
filterReportData = filterReportData.filter(item => item.sigungu === sigunguOption?.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.plantZoneGugun) ? String(item.plantZoneGugun).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 }));
//const fileList = await getDcFile("CLS20250530000041");
addFileName(filterReportData).then(data => {
filterReportData = data;
setTableData(filterReportData || []);
});
setTableData(filterReportData || []);
}
}
setShowTable(true);
} catch (err) {
@@ -588,31 +546,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
}
}
};
// 하수도정비기본계획 테이블 cellClick 핸들러
const handleReportCellClick = (index: number | undefined, headId?: String) => {
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);
}
}
};
const handleCtpvCdChange = (val: string | number) => { // 하수도정비기본계획.시도
const sidoOption = sidos.find((n) => n.val === val);
setCtpvCd(String(val));
if (val !== '0') {
const filterSiguns = siguns.filter(item => item.sido === sidoOption?.text);
filterSiguns.unshift({ val: '0', text: '전체', sido: '0' });
setFilteredSiguns(filterSiguns);
}
setSigungu("0");
setGubun("");
setYearFilter({ start: "", end: "", });
}
const renderBody = () => (
<>
@@ -673,17 +607,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
{activeTab === 'report' && (
<ReportTab
open={open}
gubun={gubun}
sidos={sidos}
ctpvCd={ctpvCd}
sigungu={sigungu}
filteredSiguns={filteredSiguns}
yearFilter={yearFilter}
handleSearch={handleSearch}
handleCtpvCdChange={handleCtpvCdChange}
setYearFilter={setYearFilter}
setGubun={setGubun}
setSigungu={setSigungu}
/>
)}
{/* </UITab2> */}
@@ -691,7 +614,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
{/* 📋 결과 리스트 */}
{/* 기본정보 탭, 하수도정비기본계획보고서 탭 */}
{(activeTab === 'basic' || activeTab === 'report') && (
{(activeTab === 'basic' ) && (
<div className="h-[79vh] w-full overflow-hidden rounded-lg border">
{/* 테이블2 영역 (가로/세로 스크롤 가능) */}
<div className="flex-1 px-2 pb-2">
@@ -706,7 +629,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
headlist={dynamicHeadlist}
pageSize={10}
total={tableCount}
cellClick={activeTab === 'report' ? handleReportCellClick : handleBasicCellClick}
cellClick={handleBasicCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
@@ -31,6 +31,14 @@ const isYear = (value: string): boolean => {
return /^[0-9]{4}년$/.test(value);
};
export const reportGubuns = [{val: '0', text: '전체'}, {val: '1', text: '보고서'}
, {val: '2', text: '요약보고서'} , {val: '3', text: '부록'}, {val: '4', text: '기타'}];
/**
* Flatten a hierarchical folder structure into a flat array.
* @param data - The hierarchical folder data to flatten.
* @returns An array of flattened folders with their paths and levels.
*/
export function flattenFolders(data: Folder[]): FlattenedFolder[] {
const result: FlattenedFolder[] = [];
const exceptNodeNm = ["부분","통합","전체"];
@@ -72,15 +80,10 @@ export function flattenFolders(data: Folder[]): FlattenedFolder[] {
}
data.forEach((root) => traverse(root, {}, 0));
console.log(result.slice(0, 10));
return result;
}
export const getDcTree = async (clsfSystmNm:string) => {
//const cityName = encodeURIComponent(clsfSystmNm);
const queryString = 'clsfSystmNm='+clsfSystmNm;
console.log("getDcTree queryString:", queryString);
//const result = await getDcData(`/api/v1/dc/clsf${queryString ? `?${queryString}` : ''}`);
const result = await getDcData("/api/v1/dc/clsf?clsfSystmNm=" + clsfSystmNm);
return result;
};
@@ -110,13 +113,8 @@ export const addFileName = async (data:FlattenedFolder[]) => {
data.map(async (item) => {
const filenameArr:ReportDataFile[] = await getDcFile(String(item.clsfSystmSn));
const f = filenameArr[0];
//console.log("clsfSystmSn:", item.clsfSystmSn, "f:", f);
const result = {...item, fileName:f?.fileTitle, regDate:f?.regDt, fileSn:f?.fileSn, filePath:f?.filePath};
// if (f !== undefined && f.fileSn !== "") {
// const fprcs = await getDcFileprcs(f?.fileSn);
// if (fprcs.length>0)
// result.filePath = fprcs[0].filePath;
// }
return result;
})
);
@@ -124,7 +122,6 @@ export const addFileName = async (data:FlattenedFolder[]) => {
}
export const getDcFileprcs = async (fileSn:string) => {
const queryString = 'fileSn='+fileSn;
console.log("getDcTree queryString:", queryString);
const result = await getDcData(`/api/v1/dc/fileprcs${queryString ? `?${queryString}` : ''}`);
return result;
};
@@ -151,9 +148,6 @@ export const fileDownload = (data:Blob, fileName:string) => { // Blob데이터
window.URL.revokeObjectURL(url);
}
export const getFileDownload = async (fileSn:string, fileName:string, filePath:string) => {
//const fileprcsData = await getDcFileprcs(fileSn); // filePath 조회
//if (fileprcsData?.length === 0 ) { alert("filePath 조회 오류"); }
//if (fileprcsData[0].filePath === "") alert("filePath 정보 없으므로 다운로드 불가");
if (filePath === "") alert("filePath 정보 없으므로 다운로드 불가:filesn"+ fileSn);
const blobData = await getDcFileDownload(filePath); // 실제 다운로드 API
fileDownload(blobData, fileName);
@@ -165,12 +159,13 @@ export const getCityCd = async (): Promise<SelectDataType[]> => {
if (!response.ok) throw new Error(`시도 데이터 오류: ${response.status}`);
const res = await response.json();
const city = res.data;
const cityCd = city.map((item: any) => ({
let citys:SelectDataType[] = city.map((item: {adstDstrCd:string, sido:string}) => ({
val: item.adstDstrCd,
text: item.sido,
}));
cityCd.unshift({ val: '0', text: '전체' });
return cityCd;
citys = citys.sort((a:SelectDataType, b:SelectDataType) => a.text.localeCompare(b.text));
citys.unshift({ val: '0', text: '전체' });
return citys;
} catch (error) {
console.error('시도 데이터를 가져오는데 실패했습니다:', error);
return [{ val: '0', text: '전체', sido: '0' }];
@@ -186,9 +181,9 @@ export const useSggCd = () => {
if (result) {
setData(result);
}
console.log("useSggCd호출");
};
fetch();
console.log("useSggCd호출");
}, []);
return data;
};
@@ -200,7 +195,7 @@ export const getSggCd = async (): Promise<SelectDataType[]> => {
if (!response.ok) throw new Error(`시군구 데이터 오류: ${response.status}`);
const res = await response.json();
const sgg = res.data;
const sggCd = sgg.map((item: any) => ({
const sggCd = sgg.map((item: {adstDstrCd:string, sido:string, gugun:string}) => ({
val: item.adstDstrCd,
sido: item.sido,
text: item.gugun,
@@ -222,9 +217,9 @@ export const useCityCd = () => {
if (result) {
setData(result);
}
console.log("useCityCd호출");
};
fetch();
console.log("useCityCd호출");
}, []);
return data;
};
-1
View File
@@ -87,7 +87,6 @@ export const deleteData = async (url: string, data?: object): Promise<any> => {
// RSONE DC API 호출
export const getDcData = async (url: string, data?: object): Promise<any> => {
console.log(url);
const res = await fetch('/dc-service' + url, {
method: "GET",
});
@@ -18,6 +18,7 @@ type MonthPickerProps = {
selectClass?: string;
readOnly?: boolean;
startYear?: number; // 시작 연도 props 추가
yearReadOnly?: boolean;
};
// yyyyMM → Date 객체
@@ -39,6 +40,7 @@ export const DateMonthPicker = ({
selectClass,
readOnly = false,
startYear,
yearReadOnly = false,
}: MonthPickerProps) => {
const [open, setOpen] = useState(false);
@@ -78,6 +80,7 @@ export const DateMonthPicker = ({
currentMonth={parsedDate}
onMonthChange={handleSelect}
startYear={startYear}
yearReadOnly={yearReadOnly}
/>
</PopoverContent>
</Popover>
@@ -29,9 +29,10 @@ export type MonthPickerProps = {
shouldClosePopover?: boolean
) => void;
startYear?: number;
yearReadOnly?: boolean;
};
export function MonthPicker({ currentMonth, onMonthChange, startYear }: MonthPickerProps) {
export function MonthPicker({ currentMonth, onMonthChange, startYear, yearReadOnly }: MonthPickerProps) {
const today = startOfToday();
const currentYear = today.getFullYear();
@@ -73,6 +74,7 @@ const selectedYear = parseInt(yearFromProp);
<div className="flex justify-center pt-1">
<Select
value={yearFromProp}
disabled={yearReadOnly}
onValueChange={(selectedYearStr) => {
const selectedYearNum = parseInt(selectedYearStr);
const newDate = new Date(
@@ -28,6 +28,7 @@ const SelectBox = React.forwardRef<
value?: string | number;
readOnly?: boolean; // readOnly 속성 추가
selectContentClass?: string;
labelClass?: string;
}
>(
(
@@ -40,6 +41,7 @@ const SelectBox = React.forwardRef<
value,
readOnly = false,
selectContentClass,
labelClass = "w-20 whitespace-nowrap text-xl text-gray-600",
},
ref,
) => {
@@ -66,7 +68,7 @@ const SelectBox = React.forwardRef<
return (
<div className={className + " flex items-center"} ref={ref}>
{label && (
<Label className="w-20 whitespace-nowrap text-xl text-gray-600">
<Label className={labelClass}>
{label}
</Label>
)}