147 lines
4.9 KiB
TypeScript
147 lines
4.9 KiB
TypeScript
"use client";
|
|
|
|
import { useWrStore } from "@/app/store";
|
|
import type { rateFeeType } from "@/app/store/common/searchCode/type";
|
|
import { SelectBox, UiTable } from "@common/business_components/ui";
|
|
import ListDiv from "@common/business_components/ui/list_div";
|
|
import { Label } from "@common/components/ui";
|
|
import { useEffect, useState } from "react";
|
|
|
|
export function RateFeeTableModal() {
|
|
const { coRvw, rateFeeRes, getRateFeeRtn } = useWrStore((state) => state);
|
|
const [rateFeeTable, setRateFeeTable] = useState<rateFeeType[]>([]);
|
|
const [selectedYear, setSelectedYear] = useState<string>(String(new Date().getFullYear()));
|
|
|
|
// 연도 선택을 위한 옵션 생성 (예: 현재 연도부터 10년 전까지)
|
|
const yearOptions = Array.from({ length: 10 }, (_, i) => {
|
|
const year = new Date().getFullYear() - i;
|
|
return { val: String(year), text: String(year) };
|
|
});
|
|
|
|
// const 기준년도 = rateFeeRes?.[0]?.yr ?? selectedYear; // 실제 데이터의 기준년도 또는 선택된 연도
|
|
// setSelectedYear(rateFeeRes?.[0]?.yr ?? selectedYear);
|
|
|
|
const gubunLabelMap: Record<number, string> = {
|
|
50: "5천만원까지",
|
|
100: "1억원까지",
|
|
200: "2억원까지",
|
|
300: "3억원까지",
|
|
500: "5억원까지",
|
|
1000: "10억원까지",
|
|
2000: "20억원까지",
|
|
3000: "30억원까지",
|
|
5000: "50억원까지",
|
|
10000: "100억원까지",
|
|
20000: "200억원까지",
|
|
30000: "300억원까지",
|
|
50000: "500억원까지",
|
|
100000: "1000억원까지",
|
|
200000: "2000억원까지",
|
|
300000: "3000억원까지",
|
|
500000: "5000억원까지",
|
|
};
|
|
|
|
/**
|
|
* rateFeeRes 데이터를 가공하여 테이블에 표시하기 적합한 형태로 변환합니다.
|
|
* - 'SS' 코드를 제외하고, stdCost 기준으로 그룹화하여 BD, SE, CE 요율을 컬럼으로 피벗합니다.
|
|
* - gubunLabelMap을 사용하여 stdCost에 해당하는 한글 라벨을 추가합니다.
|
|
*/
|
|
const fetchData = async (rateFeeRes: rateFeeType[]) => {
|
|
const data = await rateFeeRes
|
|
?.filter((item: rateFeeType) => {
|
|
return item.incExpCd !== "SS";
|
|
})
|
|
.reduce((acc: any, cur: rateFeeType) => {
|
|
const key = cur.stdCost;
|
|
let target = acc.find((item: any) => item.stdCost === key);
|
|
if (!target) {
|
|
target = {
|
|
stdCost: cur.stdCost,
|
|
BD: 0,
|
|
SE: 0,
|
|
CE: 0,
|
|
};
|
|
acc.push(target);
|
|
}
|
|
target[cur.incExpCd] = cur.rt;
|
|
return acc;
|
|
}, []);
|
|
|
|
const dataGubun = data?.map((item: any) => {
|
|
return {
|
|
...item,
|
|
gubun: gubunLabelMap[item.stdCost] || item.stdCost,
|
|
};
|
|
});
|
|
|
|
return dataGubun?.sort((a: any, b: any) => a.stdCost - b.stdCost);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (rateFeeRes?.length >= 0) {
|
|
setSelectedYear(rateFeeRes?.[0]?.yr ?? selectedYear);
|
|
fetchData(rateFeeRes).then((data) => {
|
|
setRateFeeTable(data);
|
|
});
|
|
}
|
|
}, [rateFeeRes]);
|
|
|
|
// 컴포넌트 마운트 시 또는 선택된 연도가 변경될 때 데이터 조회
|
|
useEffect(() => {
|
|
const fetchRateFee = async () => {
|
|
if (selectedYear) {
|
|
const result = await getRateFeeRtn(selectedYear);
|
|
if (result && result.length > 0) {
|
|
const data = await fetchData(result);
|
|
setRateFeeTable(data);
|
|
} else {
|
|
alert(selectedYear+'년 데이터가 없습니다.');
|
|
}
|
|
}
|
|
}
|
|
fetchRateFee();
|
|
}, [selectedYear]);
|
|
|
|
return (
|
|
<ListDiv className="min-w-[460px] h-[50vh] overflow-auto">
|
|
<div className="sticky top-0 z-10 grid grid-cols-6 gap-4 bg-background p-4">
|
|
<h3 className="col-span-6 text-2xl font-medium text-label">
|
|
시설부대경비 요율(%)
|
|
</h3>
|
|
<hr className="col-span-6 border-border" />
|
|
|
|
<div className="col-span-5 flex items-center">
|
|
<Label className="mr-1 text-xl text-label">기준년도</Label>
|
|
<SelectBox
|
|
className="h-full w-32 text-2xl"
|
|
label=""
|
|
selectClass={""}
|
|
selectArray={yearOptions}
|
|
value={selectedYear}
|
|
onSelectValue={(val) => setSelectedYear(String(val))
|
|
}
|
|
/>
|
|
</div>
|
|
<div className="col-span-6 pr-6">
|
|
<UiTable
|
|
className="min-w-full pr-12"
|
|
key={"rateTable" + rateFeeTable?.length}
|
|
headName={""}
|
|
tableData={rateFeeTable || []}
|
|
headlist={coRvw.rateFeeHeadList}
|
|
onPageChange={() => {}}
|
|
pageSize={0}
|
|
total={0}
|
|
cellClick={undefined}
|
|
/>
|
|
</div>
|
|
<div className="col-span-6 px-3 text-lg leading-relaxed text-foreground">
|
|
출처 : 하수도분야 보조금 편성 및 실무요령
|
|
<br />
|
|
시설부대경비 및 감리비 요율적용시 공사비가 요율표의 중간에 있을 때는 직선보간법에 의하여 산출
|
|
</div>
|
|
</div>
|
|
</ListDiv>
|
|
);
|
|
}
|