하수관로 차트 / 사용자 입력 정보 api 요청 작업 중

This commit is contained in:
JIeunhuh
2025-05-16 16:32:02 +09:00
parent 6315c5406b
commit 9cf8a5355c
6 changed files with 79 additions and 44 deletions
+3 -1
View File
@@ -45,7 +45,7 @@ export function VerticalTable({
onPageChange(1);
}
}, [onPageChange, resetPageNo]);
useEffect(() => {
if (tableData.length > 0 && tableData[0]) {
setFormData(tableData[0] as { [key: string]: string | number | boolean });
@@ -85,6 +85,7 @@ export function VerticalTable({
{children && children[head.id] ? children[head.id] : isEditable ? (
head.type === "select" ? (
<select
id={head.id}
value={formData[head.id] ?? "-"}
onChange={(e) => handleInputChange(head.id, e.target.value)}
className="w-full border border-gray-300 rounded-sm px-2 py-1 text-xl border-radius-0"
@@ -97,6 +98,7 @@ export function VerticalTable({
</select>
) : head.type === "input" ? (
<input
id={head.id}
type="text"
value={formData[head.id] ?? ""}
onChange={(e) => handleInputChange(head.id, e.target.value)}
+1 -1
View File
@@ -17,7 +17,7 @@ type LayerContentMap = {
const layerContentMap: LayerContentMap = {
// TODO: gis데이터 추가되면 추가 작업 필요
"하수처리시설": {
component: SwtrmtFclt,
component: StormWaterPump,
},
"하수처리구역": { },
"중점우수토실":{component: Ssc,},
@@ -18,7 +18,9 @@ const inputColumn = [
const SwtrmtFclt = ({ featureData }: { featureData: any }) => {
console.log("featureData", featureData);
const [isModalOpen, setIsModalOpen] = React.useState(false);
const openModal = () => {
const [btnTxt, setBtnTxt] = useState<string>("");
const openModal = (e: React.MouseEvent<HTMLButtonElement>) => {
e.currentTarget.textContent && setBtnTxt(e.currentTarget.textContent)
setIsModalOpen(true);
};
const closeModal = () => {
@@ -72,12 +74,12 @@ const SwtrmtFclt = ({ featureData }: { featureData: any }) => {
</Button>
<Button
className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
onClick={() => console.log("버튼 2 클릭")}
onClick={openModal}
>
RDII
</Button>
</div>
<InfilChart isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} closeModal={closeModal} />
<InfilChart btnTxt={btnTxt} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} closeModal={closeModal} />
</div>
)
}
@@ -6,8 +6,9 @@ type ModalOpenProp = {
isModalOpen: boolean,
setIsModalOpen: (open: boolean) => void,
closeModal: () => void,
btnTxt?: string,
}
const InfilChart = ({ isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => {
const InfilChart = ({ btnTxt, isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp) => {
const [popupOpen, setPopupOpen] = React.useState(false);
const buttonRef = React.useRef<HTMLButtonElement>(null); // 버튼 참조
const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치
@@ -21,29 +22,34 @@ const InfilChart = ({ isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp)
}
setPopupOpen(true); // 팝업 열기
};
console.log("btnTxt", btnTxt);
const closePopup = () => {setPopupOpen(false);}; // 팝업 닫기
const chartForm = CHART_FORM.LINE;
const chartData = [
{ label: "1", val: 20 },
{ label: "3", val: 40 },
{ label: "5", val: 60 },
{ label: "7", val: 80 },
{ label: "9", val: 100 },
{ label: "11", val: 120 },
{ label: "13", val: 140 },
{ label: "15", val: 120 },
{ label: "17", val: 100 },
{ label: "19", val: 80 },
{ label: "21", val: 60 },
{ label: "23", val: 40 },
];
const chartConfig = chartData.reduce((config, element) => {
config[element.label] = {
label: element.label,
color: "hsl(var(--chart-1))",
};
return config;
}, {} as Record<string, { label: string; color: string }>) satisfies ChartConfig;
const chartData = {
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 },
],
}
const chartConfig = Object.values(chartData).flat().reduce((config, element) => {
config[element.label] = {
label: element.label,
color: "hsl(var(--chart-1))",
};
return config;
}, {} as Record<string, { label: string; color: string }>) satisfies ChartConfig;
const getCurrentDate = () => {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, "0"); // 월은 0부터 시작하므로 +1
return `${year}-${month}`;
};
return (
<Modal isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} closeModal={closeModal}>
{/* 분석 입력현황 조회 */}
@@ -64,12 +70,12 @@ const InfilChart = ({ isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp)
</div>
{/* 차트 */}
<div className="w-[500px] h-[300px] bg-white p-4">
<MainChart chartConfig={chartConfig} chartForm={chartForm} chartData={[]} chartTitle={'관로유량'} />
<MainChart chartConfig={chartConfig} chartForm={chartForm} chartData={chartData} chartTitle={'관로유량'} />
</div>
</div>
{popupOpen && (
<div
className="absolute bg-gray-100 border border-gray-300 w-[300px] shadow-lg p-4 rounded"
className="absolute bg-gray-100 border border-gray-300 w-[320px] shadow-lg p-4 rounded"
style={{
top: popupPosition.top,
left: popupPosition.left,
@@ -80,10 +86,7 @@ const InfilChart = ({ isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp)
<div className="grid grid-cols-2 gap-2">
<div>상수사용량 정보:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>2024-12</option>
<option>2025-01</option>
</select>
<input type='month' defaultValue={getCurrentDate()} className="border border-gray-300 rounded px-2 py-1"/>
</div>
<div>오수 전환율:</div>
<div>
@@ -106,6 +109,19 @@ const InfilChart = ({ isModalOpen, setIsModalOpen, closeModal }: ModalOpenProp)
<option>서울.inp</option>
</select>
</div>
{btnTxt === 'RDII' ? <><div>강우 자료:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>R20240815.xlsx</option>
</select>
</div>
<div>RTX 계수 출처:</div>
<div>
<select className="border border-gray-300 rounded px-2 py-1">
<option>2015년 하수도정비기본계획</option>
</select>
</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}>
@@ -1,13 +1,15 @@
import { VerticalTable } from '@/components/ui/verticalTable';
import React from 'react'
const inputColumn = [
{ id: "guyeok", title: "처리구역", type: "select", options: ["구역1", "구역2"] },
{ id: "bungu", title: "배수분구", type: "input" },
{ id: "swtrmt_zone_cd", title: "처리구역", type: "input" },
{ id: "mltv_dtdv_nm", title: "배수분구", type: "input" },
]
// 빗물펌프
const StormWaterPump = ({ featureData }: { featureData: any }) => {
const StormWaterPump = ({ featureData }: { featureData: Record<string, any> }) => {
const validKey = inputColumn.map((item) => item.id);
const filteredData = featureData && Object.entries(featureData).filter(([key]) => validKey.includes(key)).reduce((obj: Record<string, any>, [key, value]) => {obj[key] = value; return obj;}, {});
return (
<div><VerticalTable headName='자체 입력정보' tableData={[]} headlist={inputColumn} pageSize={0} total={0} children={undefined} cellClick={undefined} isEditable={true} onPageChange={function (page: number): void {
<div><VerticalTable headName='자체 입력정보' tableData={[filteredData]} headlist={inputColumn} pageSize={0} total={0} children={undefined} cellClick={undefined} isEditable={true} onPageChange={function (page: number): void {
throw new Error('Function not implemented.');
}} />
</div>
+20 -7
View File
@@ -4,7 +4,7 @@ import { Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow }
import { useEffect, useRef, useState } from "react";
import { SwtrmtFcltCol, SwtrmtPrcsZoneCol } from "./components/common/table";
import { useGisContext } from "@common/business_components/ui/map/Gis";
import { getData } from "@/components/lib/api";
import { getData, putData } from "@/components/lib/api";
import { getLayerContentComponent } from "./components/common";
// TODO:
const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => {
@@ -69,21 +69,34 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
fetchData();
}, [featureId]);
// TODO: api 호출작업 필요(사용자 입력부분)
const btnClickEvent = () => {
const btnClickEvent = async() => {
const bodyData: Record<string, any> = {}
if (buttonChk && contentRef.current) {
const inputElements = contentRef.current.querySelectorAll('input');
const selectElements = contentRef.current.querySelectorAll('select');
// select 태그의 값 가져오기
console.log("Select Elements:", selectElements);
console.log("Input Elements:", inputElements);
selectElements.forEach((select) => {
console.log("Select Value:", select.value);
bodyData[select.id] = select.value;
});
// input 태그의 값 가져오기
inputElements.forEach((input) => {
console.log("Input Value:", input.value);
bodyData[input.id] = input.value;
});
if (layerNm === '하수관로' || layerNm === '하수처리시설') {
bodyData['lyrTypeNm'] = 'tb_ms_swage_ppl'
} else if (layerNm === '우수토실') {
bodyData['lyrTypeNm'] = 'tb_ms_stofcbr'
} else if (layerNm === '오수펌프') {
bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn'
}
else if (layerNm === '빗물펌프') {
bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn'
}
bodyData['fid'] = featureId
const data = await putData(`v1/fclts/${featureId}`, bodyData);
if(data){
console.log('저장완료', data);
}
}
}
const ContentComponent = layerNm ? getLayerContentComponent(layerNm) : null;