결함대장 시설등록 수정중

This commit is contained in:
leedj312
2025-07-02 16:21:54 +09:00
parent 83b3fad3af
commit a4089a6589
16 changed files with 1126 additions and 915 deletions
@@ -16,71 +16,68 @@ import { Button } from "@common/components";
import ListDiv from "@common/business_components/ui/list_div";
import { useEffect, useState } from "react";
import { tableData } from "@/components/lib/func/commom";
import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm";
import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm";
import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
export default function Home() {
const { code, htdfl, initHtdfl,getHtdflBdstData } = useWrStore((state) => state);
const { code, htdfl, initHtdfl, getHtdflBdstData } = useWrStore(
(state) => state
);
const [searchTxt, setSearchTxt] = useState("");
const [pageNation, setPageNation] = useState(1);
const [htdflForm, setHtdflForm] = useState<customHtdflBdst>();
const [bdstTable, setbdstTable] = useState<customHtdflBdst[]>();
const [issNewReg,setIsNewReg] = useState<boolean>( false);
const [issNewReg, setIsNewReg] = useState<boolean>(false);
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chgBuilding: chgBuilding[];
}>({ isOpen: false, chgBuilding: [] });
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chgBuilding: chgBuilding[];
}>({ isOpen: false, chgBuilding: [] });
const { htdflRes } = htdfl;
useEffect(() => {
if (!htdfl.isInit) {
initHtdfl('0');
}
}, [htdfl.isInit, initHtdfl]);
useEffect(() => {
if (code.sggCd.length > 0) {
const htdflData = tableData(htdflRes, { code }).map(
(item: customHtdflBdst) => {
return {
...item,
bdstChgYn: item?.chgBuilding && item.chgBuilding.length > 0 && item.chgBuilding[0]?.bdstChgNm !== null ? 'Y' : 'N',
bdstUsgCd: item.reuseBuilding[0]?.bdstUsgCd
};
}
);
setbdstTable(htdflData);
const htdflData = tableData(htdflRes, { code }).map(
(item: customHtdflBdst) => {
return {
...item,
};
}
);
setbdstTable(htdflData);
}
}, [code, htdflRes]);
const cellClick: (val: number|undefined ,headId: string) => void = (
val
,headId) => {
const cellClick: (val: number | undefined, headId: string) => void = (
val,
headId
) => {
if ((bdstTable ?? []).length > 0 && val !== undefined) {
{
setHtdflForm(htdflRes[val]);
}
}
if (headId === "bdstChgYn" && val !== undefined) {
if (
htdflRes[val]?.bdstInfoPk != null &&
htdflRes[val]?.chgBuilding?.length > 0
) {
bdstChgModal(htdflRes[val]?.chgBuilding as chgBuilding[]);
}
}
};
const bdstChgModal = (chgBuilding: chgBuilding[]) => {
setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding });
// if (headId === "bdstChgYn" && val !== undefined) {
// if (
// htdflRes[val]?.bdstInfoPk != null &&
// htdflRes[val]?.chgBuilding?.length > 0
// ) {
// bdstChgModal(htdflRes[val]?.chgBuilding as chgBuilding[]);
// }
// }
};
// const bdstChgModal = (chgBuilding: chgBuilding[]) => {
// setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding });
// };
useEffect(() => {
getHtdflBdstData(pageNation, "0");
}, [pageNation]);
@@ -103,14 +100,18 @@ export default function Home() {
/>
</SearchFormLeft>
<SearchFormRight>
<div className="flex flex-row space-x-2 items-center">
<Button size={"sm"} onClick={()=>{initHtdfl(searchTxt||"")}}>조회</Button>
<Button
<div className="flex flex-row space-x-2 items-center">
<Button
size={"sm"}
onClick={() => setIsNewReg(!issNewReg)}
>
신규등록
</Button>
onClick={() => {
initHtdfl(searchTxt || "");
}}
>
조회
</Button>
<Button size={"sm"} onClick={() => setIsNewReg(!issNewReg)}>
신규등록
</Button>
</div>
</SearchFormRight>
</SearchDiv>
@@ -126,41 +127,49 @@ export default function Home() {
pageSize={100}
total={10}
headName={"건축물 목록"}
cellClick={(val, headId) => { cellClick(val || undefined, headId); } }
cellClick={(val, headId) => {
cellClick(val || undefined, headId);
}}
onPageChange={setPageNation}
>
</UiTable>
></UiTable>
</ListDiv>
</div>
<div className="col-span-2 max-h-full">
<ListDiv>
<ScrollArea className="h-[60vh]">
<HtdflRegForm
htdflForm={htdflForm ?? ({} as customHtdflBdst)}
isModal={false}
/>
</ScrollArea>
<ListDiv>
<ScrollArea className="h-[60vh]">
<HtdflRegForm
htdflForm={htdflForm ?? ({} as customHtdflBdst)}
isModal={false}
/>
</ScrollArea>
</ListDiv>
</div>
</div>
<UiModal
body={<BdstReg moType="HTB"></BdstReg>}
bodyClass="w-[68vw] max-w-none h-[90vh]"
open={issNewReg}
onOpenChange={(open) => {
setIsNewReg(open);
}}
/>
<UiModal
<UiModal
body={
<BdstReg
moType="HTB"
isModal={false}
setIsModal={setIsNewReg}
></BdstReg>
}
bodyClass="w-[68vw] max-w-none h-[90vh]"
open={issNewReg}
onOpenChange={(open) => {
setIsNewReg(open);
}}
/>
{/* <UiModal
bodyClass={""}
open={bdstChgProps.isOpen}
body={<BdstChgModal chgBuilding={bdstChgProps.chgBuilding}></BdstChgModal>}
body={
<BdstChgModal chgBuilding={bdstChgProps.chgBuilding}></BdstChgModal>
}
onOpenChange={(open) => {
setBdstChgProps({ ...bdstChgProps, isOpen: open });
}
}
/>
}}
/> */}
</ContentsDiv>
</>
);
@@ -151,7 +151,7 @@ export default function Home() {
</div>
<UiModal
body={<BdstReg moType="RST" setIsModal={setIsNewReg}></BdstReg>}
body={<BdstReg moType="RST" setIsModal={setIsNewReg} isModal={issNewReg}></BdstReg>}
bodyClass="w-[68vw] max-w-none h-[90vh]"
open={issNewReg}
onOpenChange={(open) => {
+204
View File
@@ -0,0 +1,204 @@
import type { SelectDataType } from "@common/business_components";
export const yn: SelectDataType[] = [
{ val: "Y", text: "Y" },
{ val: "N", text: "N" },
];
export const bdstFilterYn: SelectDataType[] = [
{ val: "Y", text: "Y" },
{ val: "N", text: "N" },
{ val: "D", text: "확인불가" },
{ val: "F", text: "미가동" },
];
// 최우수(그린1)/우수(그린2), 우량(그린3), 일반(그린4), 확인불가 체크
export const bdstGrntchClass: SelectDataType[] = [
{ val: "최우수(그린1)", text: "최우수(그린1)" },
{ val: "우수(그린2)", text: "우수(그린2)" },
{ val: "우량(그린3)", text: "우량(그린3)" },
{ val: "일반(그린4)", text: "일반(그린4)" },
{ val: "확인불가", text: "확인불가" },
];
export const bdstIncenYn: SelectDataType[] = [
{ val: "Y", text: "Y" },
{ val: "N", text: "N" },
{ val: "D", text: "확인불가" },
];
//처리장연계/자체+연계/자체처리
export const erctUswtrPrcsMeth: SelectDataType[] = [
{ val: "처리장연계", text: "처리장연계" },
{ val: "자체+연계", text: "자체+연계" },
{ val: "자체처리", text: "자체처리" },
];
export const rusePrcsMthdCd: SelectDataType[] = [
{ val: "물리학적처리", text: "물리학적처리" },
{ val: "생물학적처리", text: "생물학적처리" },
];
export const ruseSeCd: SelectDataType[] = [
{ val: "신규", text: "신규" },
{ val: "증설", text: "증설" },
{ val: "관로", text: "관로" },
{ val: "감량", text: "감량" },
{ val: "개량", text: "개량" },
];
export const ruseBizMthdCd: SelectDataType[] = [
{ val: "재정", text: "재정" },
{ val: "민간투자", text: "민간투자" },
{ val: "자체", text: "자체" },
];
//공통 건축물 용도
export const bdstUsgCd: SelectDataType[] = [
{ val: "-1", text: "확인불가" },
{ val: "1", text: "운동장" },
{ val: "2", text: "체육관" },
{ val: "3", text: "공공업무시설" },
{ val: "4", text: "공공기관의청사" },
{ val: "5", text: "아파트" },
{ val: "6", text: "연립주택" },
{ val: "7", text: "다세대주택" },
{ val: "8", text: "기숙사" },
{ val: "9", text: "초등학교" },
{ val: "10", text: "중학교" },
{ val: "11", text: "고등학교" },
{ val: "12", text: "전문대학" },
{ val: "13", text: "대학및대학교" },
{ val: "14", text: "골프장" },
{ val: "15", text: "대규모점포" },
{ val: "16", text: "기타" },
];
export const rswtBdstType: SelectDataType[] = [
{ text: "숙박업", val: "17" },
{ text: "목욕장업", val: "18" },
{ text: "공장", val: "19" },
{ text: "발전시설", val: "20" },
{ text: "관광단지개발사업", val: "21" },
{ text: "도시개발사업", val: "22" },
{ text: "산업단지개발사업", val: "23" },
{ text: "택지개발사업", val: "24" },
{ text: "대규모점포(대형마트)", val: "25" },
{ text: "대규모점포(전문점)", val: "26" },
{ text: "대규모점포(백화점)", val: "27" },
{ text: "대규모점포(쇼핑센터)", val: "28" },
{ text: "대규모점포(복합쇼핑몰)", val: "29" },
{ text: "물류시설", val: "30" },
{ text: "운수시설(여객자동차터미널)", val: "31" },
{ text: "운수시설(철도시설)", val: "32" },
{ text: "운수시설(공항시설)", val: "33" },
{ text: "운수시설(항만시설)", val: "34" },
{ text: "업무시설(공공업무시설)", val: "35" },
{ text: "업무시설(금융업소)", val: "36" },
{ text: "업무시설(사무소)", val: "37" },
{ text: "업무시설(결혼상담소 등 소개업소)", val: "38" },
{ text: "업무시설(출판사)", val: "39" },
{ text: "업무시설(신문사)", val: "40" },
{ text: "업무시설(오피스텔)", val: "41" },
{ text: "교정시설", val: "42" },
{ text: "방송국", val: "43" },
{ text: "전신전화국", val: "44" },
{ text: "기타", val: "45" },
];
export const orgwtKndCd = [
{ text: "오수(변기 오수 제외)", val: "1" },
{ text: "오수", val: "2" },
{ text: "폐수", val: "3" },
{ text: "오수 및 폐수", val: "4" },
{ text: "기타", val: "5" },
];
export const chBuCd = [
{ val: "증축", text: "증축" },
{ val: "개축", text: "개축" },
{ val: "재축", text: "재축" },
];
export const dmdUszCd = [
{ val: "조경용수", text: "조경용수" },
{ val: "청소화장실용수", text: "청소화장실용수" },
{ val: "농업용수", text: "농업용수" },
{ val: "공업용수", text: "공업용수" },
{ val: "친수용수", text: "친수용수" },
{ val: "기타", text: "기타" },
];
export const ruseMngMtd = [
{ val: "자체운영", text: "자체운영" },
{ val: "공기업", text: "공기업" },
{ val: "민간(대행)", text: "민간(대행)" },
];
export const pplQulity = [
{ val: "도복장강관", text: "도복장강관" },
{ val: "PE관", text: "PE관" },
{ val: "스테인레스관", text: "스테인레스관" },
{ val: "덕타일주철관", text: "덕타일주철관" },
{ val: "유리섬유복합관", text: "유리섬유복합관" },
{ val: "기타", text: "기타" },
];
export const pplLenght = [
{ val: "D100", text: "D100" },
{ val: "D200", text: "D200" },
{ val: "D250", text: "D250" },
{ val: "D300", text: "D300" },
{ val: "D350", text: "D350" },
{ val: "D400", text: "D400" },
{ val: "D450", text: "D450" },
{ val: "D500", text: "D500" },
{ val: "D700", text: "D700" },
{ val: "D900", text: "D900" },
{ val: "D1000​", text: "D1000​" },
];
export const rainFcltCd = [
{ val: "지붕", text: "지붕" },
{ val: "건물옥상", text: "건물옥상" },
{ val: "골프장 연못", text: "골프장 연못" },
{ val: "운동장 바닥", text: "운동장 바닥" },
{ val: "운동장 지붕", text: "운동장 지붕" },
{ val: "주차장", text: "주차장" },
{ val: "태양광패널", text: "태양광패널" },
{ val: "연못", text: "연못" },
{ val: "기타", text: "기타" },
{ val: "확인불가", text: "확인불가" },
];
//물리화학적처리(스크린, 응집, 침전)/생물학적처리(활성슬러지법 등)/소독(염소, UV 등)/기타
export const rswtPrscCdMthdCd = [
{
val: "물리화학적처리(스크린,응집,침전)",
text: "물리화학적처리(스크린,응집,침전)",
},
{
val: "생물학적처리(활성슬러지법 등)",
text: "생물학적처리(활성슬러지법 등)",
},
{ val: "소독(염소, UV 등)", text: "소독(염소, UV 등)" },
{ val: "기타", text: "기타" },
];
export const htdPowerMthdCd= [
{
val: "석탄화력발전",
text: "석탄화력발전",
},
];
//(공업용수/양식장/농업용수)
export const htdUtztnUsgCd= [
{
val: "공업용수",
text: "공업용수",
},
{
val: "양식장",
text: "양식장",
},
{
val: "농업용수",
text: "농업용수",
},
];
+46 -228
View File
@@ -1,236 +1,13 @@
import { getFetch } from "@/components/lib/api";
import type { EnvPartSelectDataType, SelectDataType } from "@common/business_components/ui";
import { bdstFilterYn, bdstGrntchClass, bdstIncenYn, bdstUsgCd, chBuCd, dmdUszCd, erctUswtrPrcsMeth, htdPowerMthdCd, htdUtztnUsgCd, orgwtKndCd, pplLenght, pplQulity, rainFcltCd, rswtPrscCdMthdCd, ruseBizMthdCd, ruseMngMtd, rusePrcsMthdCd, ruseSeCd, yn } from "./basicCode";
export const btnClass = "p-4 m-2 text-white rounded-sm text-lg font-medium "
const yn: SelectDataType[] = [
{ val: 'Y', text: 'Y' },
{ val: 'N', text: 'N' },
]
const bdstFilterYn: SelectDataType[] = [
{ val: 'Y', text: 'Y' },
{ val: 'N', text: 'N' },
{ val: 'D', text: '확인불가' },
{ val: 'F', text: '미가동' },
]
// 최우수(그린1)/우수(그린2), 우량(그린3), 일반(그린4), 확인불가 체크
const bdstGrntchClass: SelectDataType[] = [
{ val: '최우수(그린1)', text: '최우수(그린1)' },
{ val: '우수(그린2)', text: '우수(그린2)' },
{ val: '우량(그린3)', text: '우량(그린3)' },
{ val: '일반(그린4)', text: '일반(그린4)' },
{ val: '확인불가', text: '확인불가' },
]
const bdstIncenYn: SelectDataType[] = [
{ val: 'Y', text: 'Y' },
{ val: 'N', text: 'N' },
{ val: 'D', text: '확인불가' },
]
//처리장연계/자체+연계/자체처리
const erctUswtrPrcsMeth : SelectDataType[]= [
{ val: '처리장연계', text: '처리장연계' },
{ val: '자체+연계', text: '자체+연계' },
{ val: '자체처리', text: '자체처리' },
]
const rusePrcsMthdCd : SelectDataType[] = [
{ val: '물리학적처리', text: '물리학적처리' },
{ val: '생물학적처리', text: '생물학적처리' },
]
const ruseSeCd : SelectDataType[] = [
{ val: '신규', text: '신규' },
{ val: '증설', text: '증설' },
{ val: '관로', text: '관로' },
{ val: '감량', text: '감량' },
{ val: '개량', text: '개량' },
]
const ruseBizMthdCd: SelectDataType[] = [
{ val: '재정', text: '재정' },
{ val: '민간투자', text: '민간투자' },
{ val: '자체', text: '자체' },
]
//공통 건축물 용도
const bdstUsgCd: SelectDataType[] = [
{ val: '-1', text: "확인불가" },
{ val: '1', text: "운동장" },
{ val: '2', text: "체육관" },
{ val: '3', text: "공공업무시설" },
{ val: '4', text: "공공기관의청사" },
{ val: '5', text: "아파트" },
{ val: '6', text: "연립주택" },
{ val: '7', text: "다세대주택" },
{ val: '8', text: "기숙사" },
{ val: '9', text: "초등학교" },
{ val: '10', text: "중학교" },
{ val: '11', text: "고등학교" },
{ val: '12', text: "전문대학" },
{ val: '13', text: "대학및대학교" },
{ val: '14', text: "골프장" },
{ val: '15', text: "대규모점포" },
{ val: '16', text: "기타" },
];
//빗물 집수면 종류 용도
// const rainFcltCd = [
// { val: "1", text: "지붕" },
// { val: "2", text: "건물옥상" },
// { val: "3", text: "골프장 연못" },
// { val: "4", text: "운동장 바닥" },
// { val: "5", text: "운동장 지붕" },
// { val: "6", text: "주차장" },
// { val: "7", text: "태양광패널" },
// { val: "8", text: "연못" },
// { val: "9", text: "기타" },
// { val: "10", text: "확인불가" },
// ];
// 중수도 필수 원수종류
const rswtBdstType: SelectDataType[] = [
{ text: "숙박업", val: "17" },
{ text: "목욕장업", val: "18" },
{ text: "공장", val: "19" },
{ text: "발전시설", val: "20" },
{ text: "관광단지개발사업", val: "21" },
{ text: "도시개발사업", val: "22" },
{ text: "산업단지개발사업", val: "23" },
{ text: "택지개발사업", val: "24" },
{ text: "대규모점포(대형마트)", val: "25" },
{ text: "대규모점포(전문점)", val: "26" },
{ text: "대규모점포(백화점)", val: "27" },
{ text: "대규모점포(쇼핑센터)", val: "28" },
{ text: "대규모점포(복합쇼핑몰)", val: "29" },
{ text: "물류시설", val: "30" },
{ text: "운수시설(여객자동차터미널)", val: "31" },
{ text: "운수시설(철도시설)", val: "32" },
{ text: "운수시설(공항시설)", val: "33" },
{ text: "운수시설(항만시설)", val: "34" },
{ text: "업무시설(공공업무시설)", val: "35" },
{ text: "업무시설(금융업소)", val: "36" },
{ text: "업무시설(사무소)", val: "37" },
{ text: "업무시설(결혼상담소 등 소개업소)", val: "38" },
{ text: "업무시설(출판사)", val: "39" },
{ text: "업무시설(신문사)", val: "40" },
{ text: "업무시설(오피스텔)", val: "41" },
{ text: "교정시설", val: "42" },
{ text: "방송국", val: "43" },
{ text: "전신전화국", val: "44" },
{ text: "기타", val: "45" }
];
const orgwtKndCd = [
{ text: "오수(변기 오수 제외)", val: "1" },
{ text: "오수", val: "2" },
{ text: "폐수", val: "3" },
{ text: "오수 및 폐수", val: "4" },
{ text: "기타", val: "5" },
];
const chBuCd = [
{ val: "증축", text: "증축" },
{ val: "개축", text: "개축" },
{ val: "재축", text: "재축" },
]
const dmdUszCd = [
{ val: "조경용수", text: "조경용수" },
{ val: "청소화장실용수", text: "청소화장실용수" },
{ val: "농업용수", text: "농업용수" },
{ val: "공업용수", text: "공업용수" },
{ val: "친수용수", text: "친수용수" },
{ val: "기타", text: "기타" },
]
const ruseMngMtd = [
{ val: "자체운영", text: "자체운영" },
{ val: "공기업", text: "공기업" },
{ val: "민간(대행)", text: "민간(대행)" },
]
const pplQulity = [
{ val: "도복장강관", text: "도복장강관" },
{ val: "PE관", text: "PE관" },
{ val: "스테인레스관", text: "스테인레스관" },
{ val: "덕타일주철관", text: "덕타일주철관" },
{ val: "유리섬유복합관", text: "유리섬유복합관" },
{ val: "기타", text: "기타" },
]
const pplLenght = [
{ val: "D100", text: "D100" },
{ val: "D200", text: "D200" },
{ val: "D250", text: "D250" },
{ val: "D300", text: "D300" },
{ val: "D350", text: "D350" },
{ val: "D400", text: "D400" },
{ val: "D450", text: "D450" },
{ val: "D500", text: "D500" },
{ val: "D700", text: "D700" },
{ val: "D900", text: "D900" },
{ val: "D1000​", text: "D1000​" },
]
export const buildingType = {
RST:"RST",
RNB:"RNB",
HTB:"HTB"
}
const rainFcltCd = [
{ val: "지붕", text: "지붕" },
{ val: "건물옥상", text: "건물옥상" },
{ val: "골프장 연못", text: "골프장 연못" },
{ val: "운동장 바닥", text: "운동장 바닥" },
{ val: "운동장 지붕", text: "운동장 지붕" },
{ val: "주차장", text: "주차장" },
{ val: "태양광패널", text: "태양광패널" },
{ val: "연못", text: "연못" },
{ val: "기타", text: "기타" },
{ val: "확인불가", text: "확인불가" },
];
export type comCodeState = {
code: {
isInit: boolean;
chBuCd: SelectDataType[]
rainFcltCd: SelectDataType[];
bdstUsgCd: SelectDataType[];
cityCd: SelectDataType[];
sggCd: SelectDataType[];
rvbsnCd: SelectDataType[];
mdmbsnCd: SelectDataType[];
lgbsnCd: SelectDataType[];
lclgvrnmntCd: EnvPartSelectDataType[];
orgwtKndCd: SelectDataType[];
yn: SelectDataType[];
pplQulity: SelectDataType[];
pplLenght: SelectDataType[];
dmdUszCd:SelectDataType[]
buildingType: {
RST:string,
RNB:string,
HTB:string
}
ruseMngMtd:SelectDataType[]
ruseSeCd: SelectDataType[];
ruseBizMthdCd: SelectDataType[];
rusePrcsMthdCd: SelectDataType[];
erctUswtrPrcsMeth: SelectDataType[];
bdstFilterYn: SelectDataType[];
bdstIncenYn: SelectDataType[];
bdstGrntchClass:SelectDataType[];
};
};
export type comCodeType = comCodeState & comCodeActions;
export const getSggCd = async (set: any) => {
const sgg = await getFetch("common", "/addr/sgg");
/* const sggCd = sgg.map((item: any) => ({
@@ -356,6 +133,47 @@ export const getEnvPartCd = async (set: any) => {
export type comCodeState = {
code: {
isInit: boolean;
chBuCd: SelectDataType[]
rainFcltCd: SelectDataType[];
bdstUsgCd: SelectDataType[];
cityCd: SelectDataType[];
sggCd: SelectDataType[];
rvbsnCd: SelectDataType[];
mdmbsnCd: SelectDataType[];
lgbsnCd: SelectDataType[];
lclgvrnmntCd: EnvPartSelectDataType[];
orgwtKndCd: SelectDataType[];
yn: SelectDataType[];
pplQulity: SelectDataType[];
pplLenght: SelectDataType[];
dmdUszCd:SelectDataType[]
buildingType: {
RST:string,
RNB:string,
HTB:string
}
ruseMngMtd:SelectDataType[]
ruseSeCd: SelectDataType[];
ruseBizMthdCd: SelectDataType[];
rusePrcsMthdCd: SelectDataType[];
erctUswtrPrcsMeth: SelectDataType[];
bdstFilterYn: SelectDataType[];
bdstIncenYn: SelectDataType[];
bdstGrntchClass:SelectDataType[];
rswtPrscCdMthdCd:SelectDataType[];
htdPowerMthdCd:SelectDataType[]
htdUtztnUsgCd:SelectDataType[]
};
};
export type comCodeType = comCodeState & comCodeActions;
export const comCodeStateExport: comCodeState = {
code: {
isInit: false,
@@ -381,7 +199,10 @@ export const comCodeStateExport: comCodeState = {
erctUswtrPrcsMeth:erctUswtrPrcsMeth,
bdstFilterYn:bdstFilterYn,
bdstIncenYn:bdstIncenYn,
bdstGrntchClass:bdstGrntchClass
bdstGrntchClass:bdstGrntchClass,
rswtPrscCdMthdCd:rswtPrscCdMthdCd,
htdPowerMthdCd:htdPowerMthdCd,
htdUtztnUsgCd:htdUtztnUsgCd,
},
};
@@ -389,9 +210,6 @@ export type comCodeActions = {
codeInit: () => void;
};
export const codeActionExport: (set: any) => comCodeActions = (set: any) => {
return {
codeInit: async () => {
@@ -79,8 +79,9 @@ const isRswtBdst = (data: any): data is customRswtBdst =>{
data.reuseBuilding=chData;
}
if(data?.chgBuilding.length>0){
const chRgtr = data.chgBuilding.map((item) =>({...item, rgtr:TEST_UUID, mdfr: item.mdfr ?? null }))
if('chgBuilding' in data && Array.isArray(data.chgBuilding) && data.chgBuilding.length > 0){
const chRgtr = data.chgBuilding.map((item) =>({...item, rgtr:TEST_UUID, mdfr: item.mdfr ?? null }))
data.chgBuilding =chRgtr;
}
return data;
@@ -127,7 +128,7 @@ const isRswtBdst = (data: any): data is customRswtBdst =>{
data.reuseBuilding=chData;
}
if(data?.chgBuilding.length>0){
if('chgBuilding' in data && Array.isArray(data.chgBuilding) && data.chgBuilding.length > 0){
const chMdfr = data.chgBuilding.map((item) =>({...item, mdfr:TEST_UUID, archChgArea: item.archChgArea ?? '' }))
data.chgBuilding =chMdfr;
}
@@ -0,0 +1,10 @@
import type { TableUpperProps } from "@/app/store/common/type/header";
export const htdTableHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도" },
{ id: "sggText", title: "시군구" },
{ id: "bdstNm", title: "발전소명" },
{ id: "daddr", title: "위치" },
{ id: "frstArchPrmsnDt", title: "준공년도" },
{ id: "archArea", title: "건축면적" },
];
@@ -6,9 +6,12 @@ import { makeMdfr, makeRstr } from "../bdstReg";
import {
baseReuseBuildingSchema,
chgBuildingSchema,
htdflReuseBuildingSchema,
validationMessages,
} from "../rainReg/type"; // Import baseReuseBuildingSchema, chgBuildingSchema, validationMessages
import type { TableUpperProps } from "@/app/store/common/type/header";
import { htdTableHeadList } from "./headList";
import toast from "react-hot-toast";
const hdtflObjSchema = z.object({
htdflFcltPk: z.number().nullish(),
@@ -21,8 +24,8 @@ const hdtflObjSchema = z.object({
.positive({ message: validationMessages.required("시설 용량") }),
plwtYn: z.enum(["Y", "N"]).default("Y"),
orgwtWtritSpt: z
.number()
.positive({ message: validationMessages.required("원수 취수량") }),
.string()
.min(1, { message: validationMessages.required("원수 취수 지점") }),
orgwtOcrnProcs: z
.string()
.min(1, { message: validationMessages.required("원수 발생 공정") }),
@@ -53,7 +56,9 @@ const hdtflObjSchema = z.object({
ph: z.number().default(0), // Measurements, 0 is fine as default
clIonQnt: z.number().default(0), // Measurements, 0 is fine as default
cdtnv: z.number().default(0), // Measurements, 0 is fine as default
emsnExitTp: z.number().default(0), // Measurements, 0 is fine as default
emsnExitTp: z.number()
.max(100, { message: "온도는 100이상이 될 수 없습니다." })
.default(0), // Changed max to 100 based on message, // Measurements, 0 is fine as default
rgtr: z.string().nullish().default(null),
mdfr: z.string().nullish().default(null),
});
@@ -77,16 +82,15 @@ export const hdtflZod = z.object({
mdfr: z.string().nullish().default(null),
reuseBuilding: z
.array(
baseReuseBuildingSchema.extend({
htdflReuseBuildingSchema.extend({
htdflObj: hdtflObjSchema,
})
)
.default([]),
chgBuilding: z.array(chgBuildingSchema).default([]), // Use imported chgBuildingSchema
//온배수는 건축물은 등록 하는것이 다름
// chgBuilding: z.array(chgBuildingSchema).nullish(), // Use imported chgBuildingSchema
});
export type customHtdflBdst = z.infer<typeof hdtflZod>;
export type htdflFacState = {
htdfl: {
isInit: boolean;
@@ -104,18 +108,16 @@ type htdflFacSActions = {
const htdflRes: customHtdflBdst[] = [];
export type htdflFacType = htdflFacState & htdflFacSActions;
export const htdflFacStateExport: htdflFacState = {
htdfl: {
isInit: false,
upHeadList: upHeadList,
upHeadList: htdTableHeadList,
htdflRes: htdflRes,
},
};
const initFetch = async (code: string | number) => {
const rswtRes = await getFetch("wr", `/facilityList/1/20/${code}`);
const rswtRes = await getFetch("wr", `/drain/facilityList/1/20/${code}`);
return rswtRes;
};
export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
@@ -128,8 +130,6 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
"wr",
`/drain/facilityList/${pageNation}/20/${code}`
);
console.log(pageNation);
// 여기서 상태 업데이트
return set((state: htdflFacState) => ({
...state,
htdfl: {
@@ -142,7 +142,6 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
console.log(e);
}
},
initHtdfl: async (code: string) => {
try {
const htdflRes = await initFetch(code);
@@ -162,10 +161,15 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
},
htdflBdstUpdate: async (data: customHtdflBdst, code: string | number) => {
try {
console.log('data ', data)
const chData = await makeMdfr(data);
const res = await putFectch("/drain/facility", data);
console.log('chData ', chData)
const res = await putFectch("/drain/facility", chData);
if (res.ok) {
alert(" 수정이 완료되었습니다.");
toast.success("온배수 건축물 수정이 완료되었습니다.");
}
const htdflRes = await initFetch(code);
@@ -178,40 +182,18 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
},
}));
} catch (errorUpdate) {
alert(
"업데이트 오류입니다. " +
(errorUpdate instanceof Error ? errorUpdate.message : "")
);
toast.error("온배수 건축물 수정 오류입니다..");
}
},
htdflBdstReg: async (data: customHtdflBdst, code: string | number) => {
try {
const chData = await makeRstr(data);
const res = await postFectch("/drain/facility", data);
if (res.ok) {
if (data.chgBuilding.length > 0) {
await res
.json()
.then((resData: any) => {
const chPK = resData?.data?.bdstInfoPk;
const makeCh = resData.data.chgBuilding.map(
(item: chgBuilding) => ({
...item,
bdstInfoFk: chPK,
})
);
const chch = postFectch("/reuseFc/chgBuilding", makeCh);
return chch;
})
.then((chch: any) => {
if (chch.ok) {
alert("등록이 완료되었습니다.");
}
});
} else {
alert("등록이 완료되었습니다.");
}
// data는 단일 객체이므로 .map을 사용할 수 없습니다.
// 등록 시에는 건축물 변경 이력이 없으므로 chgBuilding을 빈 배열로 설정하고,
// API가 배열을 기대하므로 단일 객체를 배열로 감싸줍니다.
const chData = makeRstr(data);
const res = await postFectch("/drain/facility", chData);
if (res.status ===200) {
toast.success("온배수 건축물 등록이 완료되었습니다.");
}
const htdflRes = await initFetch(code);
set((state: htdflFacState) => ({
@@ -223,8 +205,9 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
},
}));
} catch (errorReg) {
alert("등록 오류입니다.");
toast.error("온배수 건축물 등록 오류입니다..");
}
},
}
};
};
@@ -25,8 +25,7 @@ export const baseReuseBuildingSchema = z.object({
{
message: validationMessages.yearFormat,
}
)
.nullish(),
),
grntchBdstCertNo: z.string().default(""),
grntchBdstCertGrd: z.string().default(""),
crgRdctYn: z.string().default("N").nullish(), /// 안쓰는 값
@@ -52,3 +51,40 @@ export const chgBuildingSchema = z.object({
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
});
export const htdflReuseBuildingSchema = z.object({
bdstRuseFcltPk: z.number().nullish(),
bdstInfoFk: z.number().nullish(),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish(),
operMngCd: z.string().optional().nullish(),
anlOperCst: z.number().default(0),
instlCstSprtYn: z.string().default("Y"),
instlCstSprtAmt: z.number().nullish(),
grntchBdstCertYn: z.string().default("Y"),
grntchBdstCertYr: z
.string()
.max(4, { message: validationMessages.yearFormat })
.refine(
(year) => year.length === 0 || /^\d{4}$/.test(year),
{
message: validationMessages.yearFormat,
}
)
.nullish(),
grntchBdstCertNo: z.string().default(""),
grntchBdstCertGrd: z.string().default(""),
crgRdctYn: z.string().default("N").nullish(), /// 안쓰는 값
crgRdctBss: z.string().default("").nullish(), /// 안쓰는 값
crgRdctAmt: z.number().default(0), // 안쓰는 값
ruseFcltFlg: z.string().default(""),
bdstUsgCd: z.number().default(0).nullish(),
lawTrgtYn: z.string().default("Y").nullish(),
rgtr: z.string().nullish(),
mdfr: z.string().nullish(),
});
@@ -16,10 +16,10 @@ import {
type SelectDataType,
} from "@common/business_components";
import { Button, Checkbox, Input } from "@common/components";
import { useEffect, useState } from "react";
import { useEffect, useState } from "react";
import { useFieldArray } from "react-hook-form";
export default function BdstReg({ form }: { form: any }) {
export default function BdstReg({ form, type }: { form: any; type?: string }) {
const { code } = useWrStore((state) => {
return state;
});
@@ -37,16 +37,15 @@ export default function BdstReg({ form }: { form: any }) {
});
};
const removeSelected = () => {
const idxsToRemove = fields
.map((item, idx) => selectedIds.includes(item.id) ? idx : -1)
.filter(index => index > -1)
.sort((prevIndex, nextIndex) => nextIndex - prevIndex);
const idxsToRemove = fields
.map((item, idx) => (selectedIds.includes(item.id) ? idx : -1))
.filter((index) => index > -1)
.sort((prevIndex, nextIndex) => nextIndex - prevIndex);
remove(idxsToRemove);
setSelectedIds([]);
};
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | undefined>();
const [objSearch, setObjSearch] = useState<objSearchType>({
sgg: "",
@@ -83,18 +82,14 @@ export default function BdstReg({ form }: { form: any }) {
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const toggleSelect = (id: string) => {
setSelectedIds(prev =>
prev.includes(id)
? prev.filter(x => x !== id)
: [...prev, id]
setSelectedIds((prev) =>
prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
);
};
return (
<>
<h1 className={formH1Class}>
건축물 기본 정보
</h1>
<h1 className={formH1Class}>건축물 기본 정보</h1>
<div className="grid grid-cols-6 gap-2 mt-4">
<div className="col-span-3">
<FormField
@@ -172,26 +167,7 @@ export default function BdstReg({ form }: { form: any }) {
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.bdstUsgCd"
render={({ field }) => (
<FormUi label="건축물용도">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.bdstUsgCd}
onSelectValue={(val) => {
field.onChange(Number(val));
}}
value={field.value??code.bdstUsgCd[0]?.val}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
@@ -201,133 +177,166 @@ export default function BdstReg({ form }: { form: any }) {
<DatePicker
mode={"single"}
field={{
value: field.value?? new Date(),
value: field.value ?? new Date(),
onChange: (date: Date | undefined) => field.onChange(date),
}}
selectClass={'w-full'}
selectClass={"w-full"}
></DatePicker>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="archArea"
render={({ field }) => (
<FormUi label="건축면적(m³)">
<Input
className={selectClass}
placeholder="면적을 입력하세요"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.lawTrgtYn"
render={({ field }) => (
<FormUi label="법정의무대상여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={(val) => {
field.onChange(val);
}}
value={field.value??code.yn[0]?.val }
/>
</FormUi>
)}
/>
</div>
</div>
<h1 className={formH1Class}>
중축, 개축, 재축
</h1>
<div className="flex justify-end gap-2 mt-4">
<Button type="button" className="" size={"sm"} onClick={plusHist}>
이력추가
</Button>
<Button
type="button"
className="!bg-red-500 text-white"
size={"sm"}
onClick={removeSelected}
>
삭제
</Button>
</div>
{fields.map((field, index) => (
<div key={field.id} className="grid grid-cols-[auto,1fr,1fr,1fr] gap-2 mt-4 items-center">
<div className="col-span-1 flex justify-center mr-4">
<Checkbox
checked={selectedIds.includes(field.id)}
onCheckedChange={() => toggleSelect(field.id)}
/>
</div>
<div className="">
<FormField
control={form.control}
name={`chgBuilding.${index}.bdstChgNm`}
render={({ field: f }) => (
<FormUi label="구분">
<SelectBox
selectClass={selectClass}
selectArray={code.chBuCd}
onSelectValue={val => f.onChange(val)}
value={f.value ?? code.chBuCd[0]?.val} className={""} label={""} />
</FormUi>
)}
/>
</div>
<div className="">
<FormField
control={form.control}
name={`chgBuilding.${index}.archChgPrmsnDt`}
render={({ field: f }) => (
<FormUi label="허가일">
<DatePicker
mode="single"
field={{
value: safeDate(f.value) || new Date(),
onChange: (date) => f.onChange(date),
}}
selectClass="w-full"
{type !== "HTB" ? (
<>
<div className="grid grid-cols-6 gap-2 mt-4 ">
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.bdstUsgCd"
render={({ field }) => (
<FormUi label="건축물용도">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.bdstUsgCd}
onSelectValue={(val) => {
field.onChange(Number(val));
}}
value={field.value ?? code.bdstUsgCd[0]?.val}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="archArea"
render={({ field }) => (
<FormUi label="건축면적(m³)">
<Input
className={selectClass}
placeholder="면적을 입력하세요"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.lawTrgtYn"
render={({ field }) => (
<FormUi label="법정의무대상여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={(val) => {
field.onChange(val);
}}
value={field.value ?? code.yn[0]?.val}
/>
</FormUi>
)}
/>
</div>
</div>
<h1 className={formH1Class}>중축, 개축, 재축</h1>
<div className="flex justify-end gap-2 mt-4">
<Button type="button" className="" size={"sm"} onClick={plusHist}>
이력추가
</Button>
<Button
type="button"
className="!bg-red-500 text-white"
size={"sm"}
onClick={removeSelected}
>
삭제
</Button>
</div>
{fields.map((field, index) => (
<div
key={field.id}
className="grid grid-cols-[auto,1fr,1fr,1fr] gap-2 mt-4 items-center"
>
<div className="col-span-1 flex justify-center mr-4">
<Checkbox
checked={selectedIds.includes(field.id)}
onCheckedChange={() => toggleSelect(field.id)}
/>
</FormUi>
)}
/>
</div>
<div className="">
<FormField
control={form.control}
name={`chgBuilding.${index}.archChgArea`}
render={({ field: f }) => (
<FormUi label="면적">
<Input
placeholder="-"
type="text"
onChange={e => f.onChange}
value={f.value}
className={selectClass}
</div>
<div className="">
<FormField
control={form.control}
name={`chgBuilding.${index}.bdstChgNm`}
render={({ field: f }) => (
<FormUi label="구분">
<SelectBox
selectClass={selectClass}
selectArray={code.chBuCd}
onSelectValue={(val) => f.onChange(val)}
value={f.value ?? code.chBuCd[0]?.val}
className={""}
label={""}
/>
</FormUi>
)}
/>
</FormUi>
)}
/>
</div>
</div>
))}
<div className="border-b border-gray-300 my-4"> </div>
</div>
<div className="">
<FormField
control={form.control}
name={`chgBuilding.${index}.archChgPrmsnDt`}
render={({ field: f }) => (
<FormUi label="허가일">
<DatePicker
mode="single"
field={{
value: safeDate(f.value) || new Date(),
onChange: (date) => f.onChange(date),
}}
selectClass="w-full"
/>
</FormUi>
)}
/>
</div>
<div className="">
<FormField
control={form.control}
name={`chgBuilding.${index}.archChgArea`}
render={({ field: f }) => (
<FormUi label="면적">
<Input
placeholder="-"
type="text"
onChange={(e) => f.onChange}
value={f.value}
className={selectClass}
/>
</FormUi>
)}
/>
</div>
</div>
))}
<div className="border-b border-gray-300 my-4"> </div>
</>
) : (
<></>
)}
</>
);
}
@@ -23,15 +23,18 @@ import {
handleCommaNumberChange,
} from "@/components/lib/func/commom";
import { formH1Class } from "@/components/lib/class/comClass";
import toast from "react-hot-toast";
export default function HtdflRegForm({
htdflForm,
isModal,
readonly = false
readonly = false,
setIsModal,
}: {
htdflForm: customHtdflBdst;
isModal: boolean;
readonly?: boolean;
setIsModal?: (modal: boolean) => void;
}) {
const { code, htdflBdstUpdate, htdflBdstReg } = useWrStore((state) => state);
@@ -41,16 +44,26 @@ export default function HtdflRegForm({
resolver: zodResolver(hdtflZod),
defaultValues: defaultValues,
});
const [regCtpvCd, regSggcd] = form.watch(["ctpvCd", "sggCd"]);
const onSubmit = (values: z.infer<typeof hdtflZod>) => {
if (isModal) {
htdflBdstReg(values, '41');
const data = regCtpvCd ? regCtpvCd : regSggcd ? regSggcd : "noCd";
if (data === "noCd") {
toast.error("시도/시군구 코드를 선택해야합니다.");
return;
}
htdflBdstReg(values,data);
if (setIsModal) setIsModal(false);
} else {
htdflBdstUpdate(values, '41');
console.log(' isModal ' ,isModal)
console.log(' values ' ,values)
htdflBdstUpdate(values, "41");
}
};
const cleanHtdflData = (raw: any): z.infer<typeof hdtflZod> => {
return {
...raw,
@@ -80,9 +93,31 @@ export default function HtdflRegForm({
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
// form.reset은 비동기로 동작할 수 있어, useEffect 하나로 관리하여 의도치 않은 초기화를 방지합니다.
useEffect(() => {
if (hdtflZod) form.reset(cleanHtdflData(htdflForm));
}, [htdflForm]);
// Case 1: 수정 또는 '복사하여 등록' 등 데이터가 주입되는 경우
if (htdflForm && Object.keys(htdflForm).length > 0) {
form.reset(cleanHtdflData(htdflForm));
}
// Case 2: 데이터가 없는 순수 신규 등록 모드인 경우
if(isModal) {
const firstYnValue = code.yn?.[0]?.val;
const firstHtdPowerMthdCd = code.htdPowerMthdCd?.[0]?.val;
const firstHtdUtztnUsgCd = code.htdUtztnUsgCd?.[0]?.val;
if (firstHtdPowerMthdCd) {
form.setValue('reuseBuilding.0.htdflObj.etgtType', firstHtdPowerMthdCd, { shouldDirty: true });
}
if (firstYnValue) {
form.setValue('reuseBuilding.0.htdflObj.plwtYn', firstYnValue as "Y" | "N", { shouldDirty: true });
form.setValue('reuseBuilding.0.htdflObj.prcsProcsYn', firstYnValue as "Y" | "N", { shouldDirty: true });
form.setValue('reuseBuilding.0.htdflObj.fmYn', firstYnValue as "Y" | "N", { shouldDirty: true });
}
if (firstHtdUtztnUsgCd) {
form.setValue('reuseBuilding.0.htdflObj.utztnUsg', firstHtdUtztnUsgCd, { shouldDirty: true });
}
}
}, [htdflForm, code, form]);
return (
<div className="!mx-[1.6rem] !p-0r">
@@ -91,20 +126,30 @@ export default function HtdflRegForm({
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<div className="grid grid-cols-12 flex items-center card-header">
<h1 className="text-2xl font-medium text-label col-span-10">온배수 시설 정보</h1>
<h1 className="text-2xl font-medium text-label col-span-10">
온배수 시설 등록
</h1>
{!readonly && (
<Button type="submit" className="col-start-12 col-span-1" size={"sm"}>
<Button
type="submit"
className="col-start-12 col-span-1"
size={"sm"}
>
저장
</Button>
)}
</div>
</div>
{isModal && htdflForm != undefined ? <BdstReg form={form} /> : <></>}
{isModal && htdflForm != undefined ? (
<BdstReg form={form} type="HTB" />
) : (
<></>
)}
{isModal ? (
<h1 className="text-xl col-span-10 mt-4">
온배수 시설 정보{" "}
</h1>
<div className=" my-4">
<h1 className={formH1Class}>온배수 시설 정보 </h1>
</div>
) : (
<></>
)}
@@ -115,15 +160,14 @@ export default function HtdflRegForm({
control={form.control}
name="reuseBuilding.0.htdflObj.etgtType"
render={({ field }) => (
<FormUi label="발전유형(코드정비후 수정)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
<FormUi label="발전유형">
<SelectBox
className={""}
label={""}
selectClass={selectClass}
selectArray={code.htdPowerMthdCd}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange(e)
}}
readOnly={readonly}
/>
</FormUi>
@@ -136,13 +180,14 @@ export default function HtdflRegForm({
control={form.control}
name="reuseBuilding.0.htdflObj.fclCpct" // 이름 이상함.
render={({ field }) => (
<FormUi label="설비용량">
<FormUi label="설비용량(KW)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -162,8 +207,8 @@ export default function HtdflRegForm({
label={""}
selectClass={selectClass}
selectArray={code.yn}
onSelectValue={readonly ? () => { } : field.onChange}
value={field.value ?? code.yn[0]?.val}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? ""}
readOnly={readonly}
/>
</FormUi>
@@ -172,9 +217,7 @@ export default function HtdflRegForm({
</div>
</div>
<div className=" my-4">
<h1 className={formH1Class}>
온배수 시설 운영현황
</h1>
<h1 className={formH1Class}>온배수 시설 운영현황</h1>
</div>
<div className="grid grid-cols-10 gap-1 mt-4">
@@ -183,14 +226,14 @@ export default function HtdflRegForm({
control={form.control}
name="reuseBuilding.0.htdflObj.orgwtWtritSpt"
render={({ field }) => (
<FormUi label="원수취수 지점(코드정비후 수정)">
<FormUi label="원수취수 지점">
<Input
className={selectClass}
placeholder="1,000,000"
placeholder=""
type="text"
value={field.value ?? 0}
value={field.value ?? ''}
onChange={(e) => {
if (!readonly) field.onChange(Number(e.target.value));
if (!readonly) field.onChange((e.target.value));
}}
readOnly={readonly}
/>
@@ -206,11 +249,11 @@ export default function HtdflRegForm({
<FormUi label="원수발생 공정">
<Input
className={selectClass}
placeholder="1,000,000"
type=""
placeholder=""
type="text"
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange
if (!readonly) field.onChange(e.target.value);
}}
readOnly={readonly}
/>
@@ -223,13 +266,35 @@ export default function HtdflRegForm({
control={form.control}
name="reuseBuilding.0.htdflObj.wtritEntrcTp"
render={({ field }) => (
<FormUi label="취수구 온도">
<FormUi label="취수구 온도(℃)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.emsnExitTp"
render={({ field }) => (
<FormUi label="배출구 온도(℃)">
<Input
className={selectClass}
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -249,7 +314,8 @@ export default function HtdflRegForm({
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -263,14 +329,14 @@ export default function HtdflRegForm({
control={form.control}
name="reuseBuilding.0.htdflObj.prcsProcsYn"
render={({ field }) => (
<FormUi label="처리공정">
<FormUi label="처리공정 유무">
<SelectBox
className={""}
label={""}
selectClass={selectClass}
selectArray={code.yn}
onSelectValue={readonly ? () => { } : field.onChange}
value={field.value ?? code.yn[0]?.val}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? ""}
readOnly={readonly}
/>
</FormUi>
@@ -288,7 +354,8 @@ export default function HtdflRegForm({
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -308,8 +375,8 @@ export default function HtdflRegForm({
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={readonly ? () => { } : field.onChange}
value={field.value ?? code.yn[0]?.val}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? ""}
readOnly={readonly}
/>
</FormUi>
@@ -327,7 +394,8 @@ export default function HtdflRegForm({
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -342,14 +410,13 @@ export default function HtdflRegForm({
name="reuseBuilding.0.htdflObj.utztnUsg"
render={({ field }) => (
<FormUi label="이용용도">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.htdUtztnUsgCd}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? ""}
onChange={() => {
if (!readonly) field.onChange
}}
readOnly={readonly}
/>
</FormUi>
@@ -359,9 +426,7 @@ export default function HtdflRegForm({
</div>
<div className=" my-2">
<h1 className={formH1Class}>
요구수질
</h1>
<h1 className={formH1Class}>수질</h1>
</div>
<div className="grid grid-cols-12 gap-4">
@@ -376,7 +441,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -397,7 +463,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -420,7 +487,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -441,7 +509,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -464,7 +533,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -485,7 +555,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -508,7 +579,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -529,7 +601,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -552,7 +625,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -573,7 +647,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -596,7 +671,8 @@ export default function HtdflRegForm({
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
if (!readonly)
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
@@ -606,26 +682,6 @@ export default function HtdflRegForm({
/>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.emsnExitTp"
render={({ field }) => (
<FormUi label="배출구온도">
<Input
className={selectClass}
placeholder="10"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
/>
</FormUi>
)}
/>
</div>
</div>
</form>
</Form>
@@ -194,6 +194,23 @@ export function PbnstBuseForm({
name: `items.${indexMng}.fcBizs.${indexBiz}.fcDemands`,
});
const demandsContainerRef = useRef<HTMLDivElement>(null);
const prevDemandsLengthRef = useRef(fcDemands.length);
// 수요처 추가 시 새로 추가된 항목으로 스크롤하는 효과
useEffect(() => {
// 수요처 항목이 추가되었는지 확인 (길이가 이전보다 길어졌는지)
if (fcDemands.length > prevDemandsLengthRef.current) {
// 컨테이너의 마지막 자식 요소(새로 추가된 수요처 폼)로 부드럽게 스크롤
demandsContainerRef.current?.lastElementChild?.scrollIntoView({
behavior: "smooth",
block: "end",
});
}
// 다음 렌더링을 위해 현재 길이를 ref에 저장
prevDemandsLengthRef.current = fcDemands.length;
}, [fcDemands.length]);
const { fields: fcOrgwtFiled } = useFieldArray({
control: form.control,
name: `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`,
@@ -351,7 +368,7 @@ export function PbnstBuseForm({
<MngRegFormDetail
key={`buziMoney-${indexMng}-${indexBiz}`}
formList={businessMoneyInfo}
h1Title={"사업비"}
h1Title={"사업비(원)"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
@@ -429,7 +446,7 @@ export function PbnstBuseForm({
<Label className="text-right">합계</Label>
<Input
type="text"
value={sumCpct}
value={ formatCommaNumber(sumCpct)}
readOnly={true}
className="w-32 border-gray-300 rounded pr-8 "
/>
@@ -488,7 +505,8 @@ export function PbnstBuseForm({
<MngRegFormDetail
formList={ruseWaterQulityList}
h1Title={"하수처리수 재이용시설 보증수질"}
h1Title={`하수처리수 재이용시설 보증수질 `}
subTitle="※재처리시설이 있는 경우만 작성"
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
@@ -524,16 +542,11 @@ export function PbnstBuseForm({
수요처 신규등록
</Button>
</div>
{(
form.getValues(
`items.${indexMng}.fcBizs.${indexBiz}.fcDemands`
) || []
).map((field, index) => (
<div ref={demandsContainerRef}>
{fcDemands.map((field, index) => (
<div
key={`fcDemands-${indexMng}-${indexBiz}=${index}`} // 이게 핵심!
className="grid grid-cols-12 gap-4 mt-3
border-b border-gray-400 pb-3
"
key={field.id} // useFieldArray의 고유 id를 key로 사용
className="grid grid-cols-12 gap-4 mt-3 border-b border-gray-400 pb-3"
>
<div key={index + "keySon1"} className="col-span-4">
<FormField
@@ -664,7 +677,7 @@ export function PbnstBuseForm({
control={form.control}
name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`}
render={({ field: f }) => (
<FormUi label="(계약)공급량(m3/일)">
<FormUi label="(계약)공급량(m³/일)">
<Input
placeholder=""
type="text"
@@ -698,7 +711,8 @@ export function PbnstBuseForm({
/>
</div>
</div>
))}
))}
</div>
</div>
</form>
</Form>
@@ -14,6 +14,7 @@ import { Input } from "@common/components/ui";
export default function MngRegFormDetail({
formList,
h1Title,
subTitle,
form,
moClass,
sonClass,
@@ -22,6 +23,7 @@ export default function MngRegFormDetail({
}: {
formList: formDetailType[];
h1Title?: string;
subTitle?:string
form: any;
moClass?: string;
indexBiz?: number;
@@ -33,6 +35,8 @@ export default function MngRegFormDetail({
return (
<>
{h1Title ? <h1 className={formH1Class}>{h1Title}</h1> : <></>}
{subTitle ? <h3 className={'items-center'}>{subTitle}</h3> : <></>}
<div className={moClass}>
{formList?.map((formHead, index) => {
const fieldId =
@@ -9,16 +9,10 @@ import {
import { formH1Class, formH2Class } from "@/components/lib/class/comClass";
import {
formatCommaNumber,
handleCommaNumberChange,
handleMinusNumberChange,
} from "@/components/lib/func/commom";
import { DatePicker, FormUi } from "@common/business_components";
import {
Form,
FormField,
FormLabel,
SelectBox,
} from "@common/business_components/ui";
import { Form, FormField, SelectBox } from "@common/business_components/ui";
import { Button, Checkbox, Input, Label } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
@@ -31,11 +25,11 @@ export default function RainRegForm({
rainForm,
isModal,
readonly = false,
setIsModal
setIsModal,
}: {
rainForm: customRainBdst;
isModal: boolean;
setIsModal?:(modal:boolean) => void
setIsModal?: (modal: boolean) => void;
readonly?: boolean;
}) {
const { code, rainBdstReg, rainBdstUpdate, rain } = useWrStore(
@@ -100,20 +94,19 @@ export default function RainRegForm({
form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctPrs", "");
}
if(grntchBdstCertYn === "D") {
if (grntchBdstCertYn === "D") {
form.setValue("reuseBuilding.0.grntchBdstCertYr", "0000");
form.setValue("reuseBuilding.0.grntchBdstCertNo", "확인불가");
form.setValue("reuseBuilding.0.grntchBdstCertGrd", "확인불가");
}else if (instlCstSprtYn === "D") {
} else if (instlCstSprtYn === "D") {
form.setValue("reuseBuilding.0.instlCstSprtAmt", -1);
} else if (filtrTrtmfctYn === "D") {
form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctCpct", -1);
form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctPrs", "확인불가");
}
}, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn]);
const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
const [regCtpvCd, regSggcd] = form.watch(["ctpvCd", "sggCd"]);
// form 값이 변경될 때마다 로그 출력
useEffect(() => {
@@ -127,15 +120,15 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
const onSubmit = (values: z.infer<typeof rainZod>) => {
if (isModal) {
const data = regCtpvCd?regCtpvCd:regSggcd?regSggcd:'noCd'
if(data ==='noCd'){
const data = regCtpvCd ? regCtpvCd : regSggcd ? regSggcd : "noCd";
if (data === "noCd") {
toast.error("시도/시군구 코드를 선택해야합니다.");
return
return;
}
rainBdstReg(values, data);
setIsModal(false)
if (setIsModal) setIsModal(false);
} else {
rainBdstUpdate(values, "41");
}
@@ -207,29 +200,27 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
const value = field.value;
const isUnknown = value === null || value === -1; // 또는 Number(value) === -1
return (
<div className="flex items-center gap-2">
<FormUi label="설치비(원)">
<Input
placeholder="1,000,000"
type="text"
className={selectClass}
readOnly={readonly }
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
<FormUi label="설치비(원)">
<Input
placeholder="1,000,000"
type="text"
className={selectClass}
readOnly={readonly}
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly ) return;
handleMinusNumberChange(e, field.onChange);
}}
/>
</FormUi>
</div>
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
/>
</FormUi>
);
}}
/>
@@ -246,34 +237,34 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.dtfcltCpct"
render={({ field }) =>
{
const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1
render={({ field }) => {
const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1
return (
<FormUi label="저류조 용량(m³)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
value={
isUnknown ? "확인불가" : formatCommaNumber(field.value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
<FormUi label="저류조 용량(m³)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
value={
isUnknown
? "확인불가"
: formatCommaNumber(field.value)
}
}}
onChange={(e) => {
if (readonly ) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
/>
</FormUi>
)
}}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
/>
</FormUi>
);
}}
/>
</div>
<div className="col-span-4">
@@ -319,13 +310,12 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
}
}}
onChange={(e) => {
if (readonly ) return;
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
/>
</FormUi>
</div>
);
}}
@@ -360,36 +350,35 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.filtrTrtmfctCpct"
render={({ field }) =>
{
render={({ field }) => {
const isUnknown = field.value === null || field.value === -1; // 또는 Number(value) === -1
return(
<FormUi label="용량(m³/일)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
value={
isUnknown ? "확인불가" : formatCommaNumber(field.value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
return (
<FormUi label="용량(m³/일)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
value={
isUnknown
? "확인불가"
: formatCommaNumber(field.value)
}
}}
onChange={(e) => {
if (readonly ) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
disabled={filtrTrtmfctYn !== "Y"}
/>
</FormUi>
)
}}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
disabled={filtrTrtmfctYn !== "Y"}
/>
</FormUi>
);
}}
/>
</div>
<div className="col-span-4">
@@ -404,7 +393,7 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
<div className="flex items-center gap-2">
<FormUi label="처리공정">
<Input
className={' h-full !text-xl col-span-4' }
className={" h-full !text-xl col-span-4"}
placeholder="처리공정 입력"
type="text"
value={field.value ?? ""}
@@ -413,7 +402,6 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
disabled={filtrTrtmfctYn !== "Y"}
/>
</FormUi>
</div>
);
}}
@@ -450,35 +438,34 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
<FormField
control={form.control}
name="reuseBuilding.0.instlCstSprtAmt"
render={({ field }) =>
{
render={({ field }) => {
const value = field.value;
const isUnknown = value === null || value === -1; // 또는 Number(value) === -1
return (
<FormUi label="지원금액(원)">
<Input
className={selectClass}
placeholder=""
type="text"
readOnly={readonly || isUnknown}
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
return (
<FormUi label="지원금액(원)">
<Input
className={selectClass}
placeholder=""
type="text"
readOnly={readonly || isUnknown}
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
}
}}
onChange={(e) => {
if (readonly ) return;
handleMinusNumberChange(e, field.onChange);
}}
disabled={instlCstSprtYn !== "Y"}
/>
</FormUi>
)}
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
disabled={instlCstSprtYn !== "Y"}
/>
</FormUi>
);
}}
/>
</div>
</div>
@@ -508,10 +495,10 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertYr"
render={({ field }) =>
{
const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1
return (
render={({ field }) => {
const isUnknown =
field.value === null || field.value === "0000"; // 또는 Number(value) === -1
return (
<FormUi label="인증년도">
<Input
className={selectClass}
@@ -523,43 +510,57 @@ const [regCtpvCd , regSggcd] = form.watch(['ctpvCd','sggCd'])
field.onChange(""); // 초기화
}
}}
value={
isUnknown?'확인불가':field.value ?? ""}
value={isUnknown ? "확인불가" : (field.value ?? "")}
onChange={(e) => {
if (readonly) return
if (e.target.value === '확인불가') {
field.onChange('0000');
}else{
if (readonly) return;
if (e.target.value === "확인불가") {
field.onChange("0000");
} else {
field.onChange(e.target.value);
}
}}
disabled={grntchBdstCertYn !== "Y"}
max={4}
/>
</FormUi>
)}
}
);
}}
/>
</div>
<div className="col-span-3 ">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertNo"
render={({ field }) => (
<FormUi label="인증번호">
<Input
className={selectClass}
placeholder="ab1234678"
type=""
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange(e);
}}
disabled={grntchBdstCertYn !== "Y"}
/>
</FormUi>
)}
render={({ field }) => {
const isUnknown =
field.value === null || field.value === "0000"; // 또는 Number(value) === -1
return (
<FormUi label="인증번호">
<Input
className={selectClass}
placeholder="ab1234678"
type=""
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
value={isUnknown ? "확인불가" : (field.value ?? "")}
onChange={(e) => {
if (readonly) return;
if (e.target.value === "확인불가") {
field.onChange("");
} else {
field.onChange(e.target.value);
}
}}
disabled={grntchBdstCertYn !== "Y"}
/>
</FormUi>
);
}}
/>
</div>
<div className="col-span-3">
@@ -10,6 +10,7 @@ import { formH1Class, formH2Class } from "@/components/lib/class/comClass";
import {
formatCommaNumber,
handleCommaNumberChange,
handleMinusNumberChange,
} from "@/components/lib/func/commom";
import {
DatePicker,
@@ -21,7 +22,7 @@ import {
import { Button, Input } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { useForm, type UseFormReturn } from "react-hook-form";
import { z } from "zod";
import BdstReg from "../bdstReg/bdstReg";
@@ -29,7 +30,7 @@ export default function RswtrRegForm({
rswtForm,
isModal,
setIsModal,
readonly = false
readonly = false,
}: {
rswtForm: customRswtBdst;
isModal: boolean;
@@ -56,7 +57,7 @@ export default function RswtrRegForm({
const onSubmit = (values: z.infer<typeof rswtZod>) => {
if (isModal) {
rswtBdstReg(values, "41");
if(setIsModal) setIsModal(false)
if (setIsModal) setIsModal(false);
} else {
rswtBdstUpdate(values, "41");
}
@@ -73,21 +74,19 @@ export default function RswtrRegForm({
reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
...item,
instlCmptnDt: item?.instlCmptnDt
? new Date(item.instlCmptnDt)
: new Date(), // item?.instlCmptnDt가 유효하지 않으면 현재 날짜로 초기화
operMngCd: item?.operMngCd ?? "", // null → ""
instlCstSprtYn: item?.instlCstSprtYn ?? "Y", // null → "Y"
grntchBdstCertYn:item?.grntchBdstCertYn??"Y",
rswtrObj: {
? new Date(item.instlCmptnDt)
: new Date(), // item?.instlCmptnDt가 유효하지 않으면 현재 날짜로 초기화
operMngCd: item?.operMngCd ?? "", // null → ""
instlCstSprtYn: item?.instlCstSprtYn ?? "Y", // null → "Y"
grntchBdstCertYn: item?.grntchBdstCertYn ?? "Y",
rswtrObj: {
...item?.rswtrObj,
filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn ?? "Y",
},
})),
};
};
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
@@ -99,6 +98,16 @@ export default function RswtrRegForm({
} else if (instlCstSprtYn === "N") {
form.setValue("reuseBuilding.0.instlCstSprtAmt", 0);
}
if (grntchBdstCertYn === "D") {
form.setValue("reuseBuilding.0.grntchBdstCertYr", "0000");
form.setValue("reuseBuilding.0.grntchBdstCertNo", "확인불가");
form.setValue("reuseBuilding.0.grntchBdstCertGrd", "확인불가");
} else if (instlCstSprtYn === "D") {
form.setValue("reuseBuilding.0.instlCstSprtAmt", -1);
}
}, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs, form]);
useEffect(() => {
@@ -116,7 +125,11 @@ export default function RswtrRegForm({
건축물 운영정보
</h1>
{!readonly && (
<Button type="submit" className="col-start-12 col-span-1" size={"sm"}>
<Button
type="submit"
className="col-start-12 col-span-1"
size={"sm"}
>
저장
</Button>
)}
@@ -155,68 +168,37 @@ export default function RswtrRegForm({
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.instlCst"
render={({ field }) => (
<FormUi label="설치비">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-4 gap-2 mt-4">
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.wtrUsqty"
render={({ field }) => (
<FormUi label="물사용량(m³)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.oblgTrgtWtrUsqty"
render={({ field }) => (
<FormUi label="의무대상 물사용량(m³)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={readonly}
/>
</FormUi>
)}
render={({ field }) => {
const value = field.value;
const isUnknown = value === null || value === -1; // 또는 Number(value) === -1
return (
<FormUi label="설치비">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
/>
</FormUi>
);
}}
/>
</div>
</div>
@@ -229,20 +211,34 @@ export default function RswtrRegForm({
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.filtrTrtmfctCpct"
render={({ field }) => (
<FormUi label="처리시설 용량">
<Input
className={selectClass}
placeholder=""
type="number"
value={field.value ?? 0}
onChange={(e) => {
if (!readonly) field.onChange(Number(e.target.value));
}}
readOnly={readonly}
/>
</FormUi>
)}
render={({ field }) => {
const value = field.value;
const isUnknown = value === null || value === -1; // 또는 Number(value) === -1
return (
<FormUi label="처리시설 용량">
<Input
className={selectClass}
placeholder=""
type="text"
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
readOnly={readonly}
/>
</FormUi>
);
}}
/>
</div>
<div className="col-span-4">
@@ -256,7 +252,7 @@ export default function RswtrRegForm({
label={""}
selectClass={selectClass}
selectArray={code.orgwtKndCd}
onSelectValue={readonly ? () => { } : field.onChange}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? code.orgwtKndCd[0]?.val}
readOnly={readonly}
/>
@@ -270,14 +266,13 @@ export default function RswtrRegForm({
name="reuseBuilding.0.rswtrObj.filtrTrtmfctProcs"
render={({ field }) => (
<FormUi label="주요처리공정">
<Input
className={selectClass}
placeholder=""
type=""
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange
}}
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.rswtPrscCdMthdCd}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? code.rswtPrscCdMthdCd[0]?.val}
readOnly={readonly}
/>
</FormUi>
@@ -303,9 +298,9 @@ export default function RswtrRegForm({
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={readonly ? () => { } : field.onChange}
value={field.value ?? code.yn[0]?.val}
selectArray={code.bdstIncenYn}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? code.bdstIncenYn[0]?.val}
readOnly={readonly}
/>
</FormUi>
@@ -313,23 +308,37 @@ export default function RswtrRegForm({
/>
</div>
<div className="col-span-1">
<FormField
<FormField
control={form.control}
name="reuseBuilding.0.instlCstSprtAmt"
render={({ field }) => (
<FormUi label="지원금액(원)">
<Input
className={selectClass}
placeholder="1,000,000"
type="text"
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={instlCstSprtYn !== "Y"}
/>
</FormUi>
)}
render={({ field }) => {
const value = field.value;
const isUnknown = value === null || value === -1; // 또는 Number(value) === -1
return (
<FormUi label="지원금액(원)">
<Input
className={selectClass}
placeholder=""
type="text"
readOnly={readonly || isUnknown}
value={
isUnknown ? "확인불가" : formatCommaNumber(value)
}
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
onChange={(e) => {
if (readonly) return;
handleMinusNumberChange(e, field.onChange);
}}
disabled={instlCstSprtYn !== "Y"}
/>
</FormUi>
);
}}
/>
</div>
</div>
@@ -348,8 +357,8 @@ export default function RswtrRegForm({
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={readonly ? () => { } : field.onChange}
selectArray={code.bdstIncenYn}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={readonly}
/>
@@ -361,41 +370,75 @@ export default function RswtrRegForm({
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertYr"
render={({ field }) => (
render={({ field }) =>
{
const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1
return (
<FormUi label="인증년도">
<Input
className={selectClass}
placeholder="2024"
type="text"
{...field}
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange(e)
type=""
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
readOnly={grntchBdstCertYn !== "Y"}
value={
isUnknown?'확인불가':field.value ?? ""}
onChange={(e) => {
if (readonly) return
if (e.target.value === '확인불가') {
field.onChange('0000');
}else{
field.onChange(e.target.value);
}
}}
disabled={grntchBdstCertYn !== "Y"}
max={4}
/>
</FormUi>
)}
)}}
/>
</div>
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertNo"
render={({ field }) => (
render={({ field }) =>
{
const isUnknown = field.value === null || field.value === "0000"; // 또는 Number(value) === -1
return (
<FormUi label="인증번호">
<Input
className={selectClass}
placeholder="ab1234678"
type=""
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange(e)
onFocus={() => {
// 입력 시 자동으로 확인불가 해제
if (isUnknown && !readonly) {
field.onChange(""); // 초기화
}
}}
readOnly={grntchBdstCertYn !== "Y"}
value={
isUnknown?'확인불가':field.value ?? ""}
onChange={(e) => {
if (readonly) return
if (e.target.value === '확인불가') {
field.onChange('');
}else{
field.onChange(e.target.value);
}
}}
disabled={grntchBdstCertYn !== "Y"}
/>
</FormUi>
)}
)}}
/>
</div>
<div className="col-span-3">
@@ -404,15 +447,14 @@ export default function RswtrRegForm({
name="reuseBuilding.0.grntchBdstCertGrd"
render={({ field }) => (
<FormUi label="인증등급">
<Input
className={selectClass}
placeholder="A"
type=""
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) field.onChange(e)
}}
readOnly={grntchBdstCertYn !== "Y"}
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.bdstGrntchClass}
onSelectValue={readonly ? () => {} : field.onChange}
value={field.value ?? code.bdstGrntchClass[0]?.val}
readOnly={readonly}
/>
</FormUi>
)}
@@ -120,7 +120,12 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg
</div>
<div className="border-t border-gray-300 my-4"></div>
<div className="h-auto">
<h1 className="text-2xl font-medium text-label pl-8">건축물 목록 (유의 사항: 신규등록하려는 건축물이 목록에 없을 경우 하단 건축물 정보에 추가하여 주시기 바랍니다.)</h1>
<h1 className="text-2xl font-medium text-label pl-8">
건축물 목록
<span className="!text-2xl text-base text-blue-500">
(유의 사항: 신규등록하려는 건축물이 목록에 없을 경우 하단 건축물 정보에 추가하여 주시기 바랍니다.)
</span>
</h1>
<ScrollArea className="h-[30vh]">
<div>
<UiTable
@@ -143,7 +148,7 @@ export function BdstReg<T extends MoType>({ moType,setIsModal,isModal }: BdstReg
<RainRegForm rainForm={rainBdstForm as customRainBdst} isModal={isModal} setIsModal={setIsModal} />
:moType==='RST'
? <RswtrRegForm rswtForm={rainBdstForm as customRswtBdst} isModal={isModal} setIsModal={(open) =>{setIsModal}}></RswtrRegForm>
:<HtdflRegForm htdflForm={rainBdstForm as unknown as customHtdflBdst} isModal={true}></HtdflRegForm>
:<HtdflRegForm htdflForm={rainBdstForm as unknown as customHtdflBdst} isModal={true} setIsModal={(open) =>{setIsModal}}></HtdflRegForm>
}
</div>
@@ -3,6 +3,10 @@ import type { TableUpperProps } from "@/app/store/common/type/header";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
import type { customPbnst as OriginalCustomPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
formatCommaNumber,
handleCommaNumberChange,
} from "@/components/lib/func/commom";
import {
DatePicker,
@@ -32,12 +36,24 @@ type RuseMngTableProps = {
indexMng?: number;
indexBiz?: number;
form?: any;
formNm?:string
formNm?: string;
};
const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>(
({ tableData, headList, upHeadList, code, onTableSet, indexMng, form,formNm,indexBiz }, ref) => {
(
{
tableData,
headList,
upHeadList,
code,
onTableSet,
indexMng,
form,
formNm,
indexBiz,
},
ref
) => {
return (
<>
<Table key={`table-${indexMng}-${indexBiz}`} variant="secondary">
@@ -73,26 +89,31 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>(
typeof indexMng === "number" &&
indexMng >= 0 &&
typeof indexBiz === "number" &&
indexBiz >= 0?
`items.${indexMng}.fcBizs.${indexBiz}.${formNm}.${i}.${head.id}`:
typeof indexMng === "number" && indexMng >= 0?
`items.${indexMng}.${formNm}.${i}.${head.id}`:
`items.${indexMng}.${formNm}.${i}.${head.id}`}
indexBiz >= 0
? `items.${indexMng}.fcBizs.${indexBiz}.${formNm}.${i}.${head.id}`
: typeof indexMng === "number" && indexMng >= 0
? `items.${indexMng}.${formNm}.${i}.${head.id}`
: `items.${indexMng}.${formNm}.${i}.${head.id}`
}
render={({ field }) => (
<FormUi label="">
{head.edit === true ? (
<Input
className={`${head.type === "number" ? "text-right" : "text-center"} !text-xl`}
type={head.type}
type="text"
onChange={(txt) => {
field.onChange(txt.target.value);
if (head.type === "number") {
handleCommaNumberChange(txt, field.onChange);
} else {
field.onChange(txt.target.value);
}
}}
value={
head.type === "number"
? (Number(field.value) ?? 0)
? formatCommaNumber(field.value)
: field.value || ""
}
readOnly ={head.readonly ? true : false}
readOnly={head.readonly ? true : false}
/>
) : head.type === "select" ? (
<SelectBox
@@ -102,43 +123,41 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>(
(item) => item.name === head.selectData
)?.val ?? []
}
value={
field.value || ""
}
value={field.value || ""}
className={""}
selectClass={selectClass}
onSelectValue={(val) => {
if(head.readonly === true){
return
}else{
if (head.readonly === true) {
return;
} else {
field.onChange(val);
}
}}
readOnly ={head.readonly ? true : false}
readOnly={head.readonly ? true : false}
// Disabled prop removed as SelectBox does not support it
></SelectBox>
) : head.type === "date" ? (
<DatePicker
mode="single"
field={{
value:typeof field.value === "string" ? new Date(field.value) : field.value,
value:
typeof field.value === "string"
? new Date(field.value)
: field.value,
onChange: (date: Date | undefined) => {
console.log("date", date);
field.onChange(date); // readonly 상태가 아닐 때만 값 변경
field.onChange(date); // readonly 상태가 아닐 때만 값 변경
},
}}
selectClass={"w-full"}
readOnly ={head.readonly ? true : false}
readOnly={head.readonly ? true : false}
/>
) : head.type === "checkbox" ? (
<Checkbox
className=""
checked={ field.value || false}
checked={field.value || false}
onCheckedChange={(checked) => {
field.onChange(checked);
field.onChange(checked);
}}
></Checkbox>
) : (