diff --git a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx index 4950ab0da..e8146b37a 100644 --- a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx @@ -105,7 +105,7 @@ export default function RuseCaseMng() {
- + { if (!htdfl.isInit) { - initHtdfl('41'); + initHtdfl('0'); } }, [htdfl.isInit, initHtdfl]); @@ -82,7 +82,7 @@ export default function Home() { setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding }); }; useEffect(() => { - getHtdflBdstData(pageNation, "41"); + getHtdflBdstData(pageNation, "0"); }, [pageNation]); return ( diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 3c489837d..441eabf25 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -42,14 +42,12 @@ export default function PublicReuseFaciltyInsert() { searchFclts, pubHasuInit, pbnstRegClick, - pbnstMngData, pbnstRuseFcltUpdate, pubHasuSearch, pbnstRuseBizUpdate, } = useWrStore((state) => state); const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; const [currentTab, setCurrentTab] = useState("mng"); - const [pbnstBiz, setPbnstBiz] = useState(); const [isRuseReg, setIsRuseReg] = useState<{ isModal: boolean; data: pubHasuType; @@ -60,19 +58,15 @@ export default function PublicReuseFaciltyInsert() { const [searchTxt, setSearchTxt] = useState(); const [bdstTable, setbdstTable] = useState(); const [selectRow, setSelectRow] = useState(); + const [pageNation, setPageNation] = useState(1); - // const form = useForm>({ - // resolver: zodResolver(pbnstRegArrayZod), - // defaultValues: pbnstRegArrayZod.parse([]), - // mode: "onChange", - // }); const form = useForm<{ items: z.infer[]; }>({ resolver: zodResolver(z.object({ items: pbnstRegArrayZod })), - defaultValues: { items: pbnstRegArrayZod.parse([]) }, - mode:"onChange" + // defaultValues: { items: pbnstRegArrayZod.parse([]) }, + mode: "onChange", }); const { fields: items, @@ -84,21 +78,31 @@ export default function PublicReuseFaciltyInsert() { }); useEffect(() => { if (!pbnst.isInit) { - pubHasuInit("1", "11"); + pubHasuInit("1", "41"); } }, [pbnst.isInit, pubHasuInit]); const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => { - const data = writeRgtrAndMdfr(valuse.items); let bizs = [] as fcBizType[]; data.forEach((fclt) => { bizs = [...bizs, ...fclt.fcBizs]; }); + const pbnst =data.map((fclt) => { + return({ + pbnstRuseFcltPk: fclt.pbnstRuseFcltPk, + fcltCpct: fclt.fcltCpct, + ruseCpct: fclt.ruseCpct, + splyExtraCpct: fclt.splyExtraCpct, + rgtr: fclt.rgtr, + mdfr: fclt.mdfr, + fcFiles: fclt.fcFiles, + fcOpers: fclt.fcOpers, + }) + }) + await pbnstRuseFcltUpdate(pbnst as customPbnst[]); - await pbnstRuseFcltUpdate(data); - - await pbnstRuseBizUpdate(bizs); + await pbnstRuseBizUpdate(bizs); }; useEffect(() => { @@ -114,9 +118,8 @@ export default function PublicReuseFaciltyInsert() { const cellClick = (val: number | undefined) => { if (val === undefined) return; const selectRow = pbnstHasuRes?.[val]; - setSelectRow(pbnstHasuRes?.[val]) + setSelectRow(pbnstHasuRes?.[val]); if (selectRow) { - //setIsRuseReg({ ...isRuseReg, data: selectRow }); pbnstRegClick(selectRow); } }; @@ -126,8 +129,13 @@ export default function PublicReuseFaciltyInsert() { }; useEffect(() => { - if (pbnst.pbnstRes) { + if (pbnst.pbnstRes&& pbnst.pbnstRes?.length>0) { + console.log("pbnst.pbnstRes", pbnstRes); form.reset({ items: pbnstRegArrayZod.parse(pbnst.pbnstRes) }); + }else{ + + console.log("pbnst.pbnstRes is null", pbnstRes); + form.reset({ items: [] }); } }, [pbnst.pbnstRes]); useEffect(() => { @@ -137,39 +145,57 @@ export default function PublicReuseFaciltyInsert() { }, [indexMng]); useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); + console.log("form errors:", form.formState.errors); + }, [form.formState.errors]); + + const appendPbnstRuseFclt = useCallback(() => { + const selecTableRow = selectRow; - const appendPbnstRuseFclt = useCallback(() => { if (pbnstRes && pbnstRes.length > 0) { const lastPbnst = pbnstRes[pbnstRes.length - 1]; - console.log('lastPbnst.swtrmtFcltFk ', lastPbnst) - if(lastPbnst){ + if (lastPbnst && selecTableRow) { + append( pbnstRegZod.parse({ - pbnstRuseFcltPk: String(lastPbnst.pbnstRuseFcltPk) + String(pbnstRes.length + 1), + pbnstRuseFcltPk: + String(selecTableRow.bscFctCd) + String(pbnstRes.length + 1), ruseUtztnFcltNm: "", - fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(lastPbnst.pbnstRuseFcltPk) + String(pbnstRes.length + 1),cycl:1})] as fcBizType[], + fcBizs: [ + fcBizSchema.parse({ + pbnstRuseFcltFk: + String(lastPbnst.pbnstRuseFcltPk) + + String(pbnstRes.length + 1), + cycl: 1, + }), + ] as fcBizType[], }) ); - setIsRuseReg({ ...isRuseReg, isModal: true }) + setIsRuseReg({ ...isRuseReg, isModal: true }); } } else { - if(selectRow){ + if (selecTableRow) { append( - pbnstRegZod.parse({ - pbnstRuseFcltPk: String(selectRow.bscFctCd)+'1', - ruseUtztnFcltNm: "", - regDt: null, - mdfcnDt: null, - fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(selectRow.bscFctCd)+'1',cycl:1})] as fcBizType[], - }) - ); - setIsRuseReg({ ...isRuseReg, isModal: true }) + pbnstRegZod.parse({ + pbnstRuseFcltPk: String(selecTableRow.bscFctCd)+'1', + ruseUtztnFcltNm: "", + regDt: null, + mdfcnDt: null, + fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(selecTableRow.bscFctCd)+'1',cycl:1})] as fcBizType[], + }) + ) + setIsRuseReg({ ...isRuseReg, isModal: true }); } } - },[pbnstRegZod,pbnstRes,append,selectRow]) + }, [pbnstRegZod, pbnstRes, append, selectRow, form]); + useEffect(() => { + // console.log(" page getgetvaslue ", form.getValues()); + }, [form.getValues()]); + +useEffect(() =>{ + pubHasuInit(String(pageNation), "41"); +},[pageNation,pubHasuInit]) + return ( <> @@ -192,8 +218,8 @@ export default function PublicReuseFaciltyInsert() { size={"sm"} onClick={(e) => { searchTxt && searchTxt?.length > 0 - ? pubHasuSearch("1", "11", searchTxt) - : pubHasuInit("1", "11"); + ? pubHasuSearch(String(pageNation), "41", searchTxt) + : pubHasuInit(String(pageNation), "41"); }} > 조회 @@ -202,13 +228,14 @@ export default function PublicReuseFaciltyInsert() { size={"sm"} className="" onClick={() => { - pbnstMngData([] as customPbnst[]); - if(!selectRow){ - toast.error("하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요") - return - }else{ - appendPbnstRuseFclt() - + // pbnstMngData([] as customPbnst[]); + if (!selectRow) { + toast.error( + "하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요" + ); + return; + } else { + appendPbnstRuseFclt(); } }} > @@ -227,11 +254,11 @@ export default function PublicReuseFaciltyInsert() { {}} + onPageChange={setPageNation} children={undefined} /> @@ -260,6 +287,7 @@ export default function PublicReuseFaciltyInsert() { formType="update" form={form} setIndexMng={(index: number) => { + console.log("setIndexMng", index); setIndexMng(index); }} indexMng={indexMng} @@ -286,10 +314,10 @@ export default function PublicReuseFaciltyInsert() { data={isRuseReg.data || ({} as customPbnst)} > } - bodyClass="w-[68vw] max-w-none h-[90vh]" + bodyClass="w-[68vw] max-w-none h-[90vh]" open={isRuseReg.isModal} onOpenChange={(open) => { - remove(form.getValues("items").length - 1) + remove(form.getValues("items").length - 1); setIsRuseReg({ data: {} as pubHasuType, isModal: open }); }} /> diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 8823abf6d..7a7a125d2 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -16,15 +16,8 @@ import { Button, Label } from "@common/components/ui"; import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal"; import { useCallback, useEffect, useRef, useState } from "react"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import type { - customPbnst, - pubHasuType, -} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { - excelDownload, - getCityOrSgg, - yearOptions, -} from "@/components/lib/func/commom"; +import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { excelDownload, yearOptions } from "@/components/lib/func/commom"; import SearchInputText from "@/components/ui/searchInput/searchInput"; import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type"; import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal"; @@ -43,7 +36,6 @@ export default function PbnstSttn() { const [searchYear, setSearchYear] = useState( String(new Date().getFullYear()) ); - const [pageNation, setPageNation] = useState(1); const [isChHead, setIsChHead] = useState(false); const [bdstTable, setBdstTable] = useState(); const [pbnDetaileData, setPbnDetaileData] = useState<{ @@ -87,14 +79,17 @@ export default function PbnstSttn() { } }, [pbnstSttn.isInit, pbnSttnInit, ref.current]); useEffect(() => { - setBdstTable(pbnstSttn.pbnstSttnRes); }, [pbnstSttn.pbnstSttnRes]); - useEffect(() => { - if (pbnRuseNm.length > 1) - pbnNmSearch("1", "23", ref.current, pbnRuseNm, searchYear); - }, [pbnRuseNm]); + // useEffect(() => { + // pbnstSttnSearch("1", "20", ref.current, pbnRuseNm, searchYear); + // }, [pageNation, ref.current, pbnRuseNm, searchYear, pbnstSttnSearch]); + + // useEffect(() => { + // if (pbnRuseNm.length > 1) + // pbnNmSearch(String(pageNation), "23", ref.current, pbnRuseNm, searchYear); + // }, [pbnRuseNm,pageNation]); useEffect(() => { if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk) @@ -104,15 +99,14 @@ export default function PbnstSttn() { }); }, [pbnstSttn.pbnstDetail]); - - useEffect(() => { - console.log('pbnDetaileData.isModal ', pbnDetaileData.isModal) -},[pbnDetaileData.isModal]) + useEffect(() => { + console.log("pbnDetaileData.isModal ", pbnDetaileData.isModal); + }, [pbnDetaileData.isModal]); return ( <> -
-
+
+
<SearchBaseForm selectSidoData={code.cityCd} @@ -132,41 +126,32 @@ export default function PbnstSttn() { </Button> } leftChildren={ - <> - <div className="flex flex-row space-x-2"> - <SelectBox - className="w-48 h-full text-2xl" - label="연도" - selectClass={""} - selectArray={yearOptions} - value={searchYear} - onSelectValue={(val: string | number) => - setSearchYear(String(val)) - } - /> - </div> - <SearchInputText - label={"하수처리시설"} - initValue={pbnRuseNm ?? ""} - setValue={(searchNm?: string) => { - setPbnRuseNm(searchNm || ""); - }} - setRtnData={function (rtnData: any[]): void { - setBdstTable(rtnData); - }} - searchList={pbnstSttn.pbnstSearchData || []} - ></SearchInputText> - </> + <div className="col-span-3 flex items-center"> + <SelectBox + className="w-48 h-full text-2xl" + label="연도" + selectClass={"w-full "} + selectArray={yearOptions} + value={searchYear} + onSelectValue={(val: string | number) => + setSearchYear(String(val)) + } + /> + <Label className="w-64 mt-2 mx-4 text-xl text-gray-600"> + {"하수처리시설명 "} + </Label> + <SearchInput + className={"text-2xl w-full ㅍ"} + label="" + textValue={pbnRuseNm || ""} + setText={(e) => { + setPbnRuseNm(e || ""); + }} + /> + </div> } queryClick={function (returnType: ReturnType): void { - // '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}' - let con; - if (returnType.sigunValue != "0") { - con = returnType.sigunValue; - } else { - con = returnType.sidoValue; - } - // pbnstSttnSearch(1, "20", con); + pbnstSttnSearch("1", "20", returnType, pbnRuseNm, searchYear); }} excelClick={excelClick} initClick={function (): void {}} @@ -191,7 +176,15 @@ export default function PbnstSttn() { cellClick={(index: number | undefined, headId: string) => { cellCLick(index); }} - onPageChange={setPageNation} + onPageChange={(page: number) => { + pbnstSttnSearch( + String(page), + String(13), + ref.current, + pbnRuseNm, + searchYear + ); + }} ></UiTable> </ListDiv> </div> diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx index 0468cfd3b..18dbc7943 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/page.tsx @@ -2,7 +2,10 @@ import { useWrStore } from "@/app/store"; import { type rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; -import type { rswtChkZodType, rswtrChkDetailsZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; +import type { + rswtChkZodType, + rswtrChkDetailsZodType, +} from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; import { excelArrayDownload, excelDownload, @@ -26,6 +29,7 @@ import ListDiv from "@common/business_components/ui/list_div"; import { Button, Label } from "@common/components/ui"; import { useCallback, useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; +import { shallow } from "zustand/shallow"; //----------------------- export default function Page() { @@ -53,9 +57,9 @@ export default function Page() { const [updateRainDetail, setUpdateRainDetail] = useState<rainChkZodType[]>( [] ); - const [updateRswtDetail, setUpdateRSwtDetail] = useState<rswtrChkDetailsZodType[]>( - [] - ); + const [updateRswtDetail, setUpdateRSwtDetail] = useState< + rswtrChkDetailsZodType[] + >([]); const [deleteIdx, setDeleteIdx] = useState<number[]>([]); const [selFcltDiv, setSelFcltDiv] = useState("RNB"); @@ -67,13 +71,14 @@ export default function Page() { if (searchYear) rainChkInit(searchYear, "0"); }; - const [searchYear, setSearchYear] = useState<string>(String(new Date().getFullYear())); + const [searchYear, setSearchYear] = useState<string>( + String(new Date().getFullYear()) + ); useEffect(() => { if (!rainChkgdn.isInit) { rainChkInit(new Date().getFullYear().toString(), "0"); - isRainSttn(false) - + isRainSttn(false); setIsModal({ data: {}, open: false }); setIsRegExcel(false); } @@ -86,12 +91,14 @@ export default function Page() { }, [rainChkgdn.isInit, rainChkInit]); useEffect(() => { - if (rswtChkgdn.excelList[0]?.data.length > 1) + if (rswtChkgdn.excelList[0]&&rswtChkgdn.excelList[0]?.data.length > 1) { + excelArrayDownload( "중수도시설 지도점검", "sample_rs_chk.xlsx", rswtChkgdn.excelList ); + } }, [rswtChkgdn.excelList]); useEffect(() => { @@ -99,7 +106,8 @@ export default function Page() { rainChkgdn.excelList, "빗물이용시설 지도점검", "sample_rainy.xlsx", - "A1:AN1" + "A1:AN1", + 2 ); }, [rainChkgdn.excelList]); @@ -125,8 +133,8 @@ export default function Page() { ); useEffect(() => { - rainChkgdn.isSttn = false - rswtChkgdn.isSttn = false + rainChkgdn.isSttn = false; + rswtChkgdn.isSttn = false; if (!rainChkgdn.isSttn && !rswtChkgdn.isSttn) { rainChkHeadChange({ rainChkgdn }, true); rswtChkHeadChange({ rswtChkgdn }, true); @@ -138,20 +146,17 @@ export default function Page() { if (selFcltDiv === "RNB") { rainChkDelete(data); } else { - rswtChkDelete(data) + rswtChkDelete(data); } } }; const chkUpdateTable = (selFcltDiv: string) => { if (selFcltDiv === "RNB") { - - rainChkDetilUpdate(updateRainDetail) + rainChkDetilUpdate(updateRainDetail); } else { - - rswtChkDetilsUpdate(updateRswtDetail) + rswtChkDetilsUpdate(updateRswtDetail); } - - } + }; return ( <ContentsDiv> @@ -161,7 +166,9 @@ export default function Page() { <SearchDiv> <SearchFormLeft> <div className="col-span-2 flex flex-row space-x-2"> - <Label className="w-48 mt-2 text-xl text-gray-600">{'지도점검년도'}</Label> + <Label className="w-48 mt-2 text-xl text-gray-600"> + {"지도점검년도"} + </Label> <SelectBox className="w-full h-full text-2xl" label="" @@ -174,7 +181,9 @@ export default function Page() { /> </div> <div className="col-span-2 flex flex-row space-x-2"> - <Label className="w-28 mt-2 text-xl text-gray-600">{'시설구분'}</Label> + <Label className="w-28 mt-2 text-xl text-gray-600"> + {"시설구분"} + </Label> <SelectBox className={"w-full h-full text-2xl"} label={""} @@ -189,8 +198,7 @@ export default function Page() { /> </div> </SearchFormLeft> - <SearchFormRight - className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> + <SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> <div className="space-y"> <div className="flex flex-row space-x-2"> <Button @@ -212,7 +220,7 @@ export default function Page() { <Button size={"sm"} onClick={() => { - chkUpdateTable(selFcltDiv) + chkUpdateTable(selFcltDiv); }} > 저장 diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 0714c9306..6be50a8c5 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -51,6 +51,7 @@ export default function prfmncPrfmncReg() { }>({ isModal: false, data: {} as FcPrfType }); const [inputData, setInputData] = useState<any[]>(); const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState<string>(); + const [pageNation , setPageNation] = useState<number>(1); const [searchYear, setSearchYear] = useState<string>( String(new Date().getFullYear()) @@ -73,9 +74,12 @@ export default function prfmncPrfmncReg() { pbnstRuseFcltPk ) as unknown as PrfType ); - prfmncHasuInit("1", "11"); + prfmncHasuInit(String(pageNation), "41"); } - }, [inputData, searchYear, pbnstRuseFcltPk,prfmncHasuInit]); + }, [inputData, searchYear, pbnstRuseFcltPk,prfmncHasuInit,pageNation]); + + + const cellClick = useCallback( (index: number | undefined, headId: string) => { @@ -146,7 +150,7 @@ export default function prfmncPrfmncReg() { useEffect(() => { if (!prfmnc.isInit) { - prfmncHasuInit("1", "11"); + prfmncHasuInit('1', "41"); } }, [prfmnc.isInit, prfmncHasuInit]); useEffect(() => { @@ -229,13 +233,13 @@ export default function prfmncPrfmncReg() { <UiTable tableData={bdstTable || []} headlist={pbnstPrfmncHeadList} - pageSize={100} - total={10} + pageSize={10} + total={10000} headName={"하수재이용시설 목록"} cellClick={(index: number | undefined, headId: string) => { cellClick(index, headId); }} - onPageChange={(page: number) => {}} + onPageChange={setPageNation} children={undefined} /> </ScrollArea> diff --git a/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx b/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx index 20eded05f..3338bc467 100644 --- a/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx +++ b/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx @@ -78,14 +78,13 @@ const irvwHistInit = async ( pageCnt: number, startYear: string, endYear: string, - sggCd?: string ) => { let url = `/reuseFc/request/infoList/matched/${pageNo}/${pageCnt}/${startYear}/${endYear}`; - console.log("sggCd ", sggCd); - if (sggCd) { - url += `/${sggCd}`; - } + // console.log("sggCd ", sggCd); + // if (sggCd) { + // url += `/${sggCd}`; + // } const rvwHistRes = await getFetch(fetchType.WR, url); @@ -108,7 +107,7 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = ( pageCnt, startYear, endYear, - sggCd + // sggCd ); return set((state: ruseHstryState) => ({ @@ -135,7 +134,6 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = ( 10, new Date().getFullYear().toString(), new Date().getFullYear().toString(), - "0" ); return set((state: ruseHstryState) => ({ ...state, @@ -225,8 +223,6 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = ( 10, new Date().getFullYear().toString(), new Date().getFullYear().toString(), - "0", - '0' ); } } catch (e) { diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx index 8b7c5f91d..eb0010047 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx @@ -1,10 +1,9 @@ import { TEST_UUID, - type TableUpperProps, } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import type { SelectDataType, - sheetParameter, + SheetParameter, } from "@common/business_components"; import { deleteFectch, @@ -25,6 +24,7 @@ import { import { z } from "zod"; import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { type chHeadType } from "../rainChkgdn/headList"; +import type { TableUpperProps } from "@/app/store/common/type/header"; const rswtChkHeadList = rswtChkHeadListExport; const rswtDetailHeadList = rswtDetailHeadListExport; @@ -37,7 +37,7 @@ export type rswtChkgdnState = { rswtDetailHeadList: TableUpperProps[]; rswtHeadNm: chHeadType[]; - excelList: [typeof sheetParameter]; + excelList: SheetParameter[]; rswtChkRes: rswtChkZodType[]; rswtChkPolGuide: rswtChkZodType[]; isInit: boolean; @@ -70,7 +70,7 @@ export const rswtChkgdnStateExport: rswtChkgdnState = { excelList: [{ data: [[]], headerNum: 0, headerRange: "A1:V3", sheetName: "", - startCol: 0 + startCol: '1' }], rswtChkRes: [], rswtChkPolGuide: [], @@ -176,9 +176,6 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( try { const chData = await makeMdfrChk(rswtChk); - console.log("chData ", chData); - - console.log("rswtChk ", rswtChk); const res = await putFectch("/reuseChk/reuseWater", chData); if (res.ok) { diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx index e72d6def6..87e827f60 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx @@ -4,6 +4,7 @@ import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; import type { FcPrfType, PrfType } from "./type"; import type { TableUpperProps } from "../../common/type/header"; import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; +import toast from "react-hot-toast"; const pbnstPrfmncHeadList = pbnstPrfmncHeadListExport; const monthHeadList = monthHeadListExport; @@ -32,7 +33,7 @@ export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions; type pbnstPrfmncActions = { prfmncHasuInit: (page: string, sggOrCity: string) => void; - prfmnRegData: (data:PrfType) =>void + prfmnRegData: (data: PrfType) => void; }; const checkWrRegList = async () => { @@ -46,21 +47,28 @@ const hasuListFetch = async (page: string, sggOrCity: string) => { checkWrRegListRes?.fcltCds, fetchType.COMMON ); - const data = checkWrRegListRes.fcPrfList.map((item: FcPrfType) => { - const findData = rainRes.data.find( - (fclt: pubHasuType) => - fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11) + + + const findData = rainRes.data.map((item: pubHasuType) => { + const data = checkWrRegListRes?.fcPrfList.find( + (fclt: FcPrfType) => + fclt.pbnstRuseFcltPk.substring(0, 11) === item?.bscFctCd ); - return { - sido: findData?.sido, - gugun: findData?.gugun, - bscFctNm: findData?.bscFctNm, - ruseUtztnFcltNm: item.ruseUtztnFcltNm, - pbnstRuseFcltPk: item.pbnstRuseFcltPk, - prfList : item.prfList - }; + if(data !==undefined){ + return( { + + sido: item.sido, + gugun: item.gugun, + bscFctNm: item.bscFctNm, + bscFctCd: item.bscFctCd, + ruseUtztnFcltNm: data.ruseUtztnFcltNm, + pbnstRuseFcltPk: data.pbnstRuseFcltPk, + prfList: data.prfList, + }); + } }); - return data; + + return findData; }; export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = ( set: any @@ -82,31 +90,21 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = ( console.log(errorHasu); } }, - prfmnRegData: async (data:PrfType,) => { - try{ - + prfmnRegData: async (data: PrfType) => { + try { const ressponse = await postFectch( "/reuseFc/pubFcPrf", data, fetchType.WR ); - console.log('ressponse ', ressponse) - - if(ressponse.status === 200){ - ToastFormUi({ - body: "하수재이용 시설 실적 등록이 완료되었습니다. ", - title: "하수재이용 시설 실적 등록", - }); - - } - }catch(e){ - console.log(e) - ToastFormUi({ - body: "하수재이용 시설 실적 등록이 실패하였습니다. ", - title: "하수재이용 시설 실적 등록", - }); + if (ressponse.status === 200) { + toast.success("하수재이용 시설 실적 등록이 완료되었습니다."); + } + } catch (e) { + console.log(e); + toast.error("하수재이용 시설 실적 등록이 실패하였습니다."); } }, }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 9fde9c092..fb799c26c 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -24,6 +24,7 @@ import { fcOrgwtsHeadListExport, } from "./headList"; import type { TableUpperProps } from "@/app/store/common/type/header"; +import toast from "react-hot-toast"; const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }]; const pubFacHeadList = pubFacHeadListExport; @@ -62,9 +63,9 @@ type pubFacActions = { appendRuseFclt(array: customPbnst[]): void; fileDelete: (atflCd: string) => void; fileDownLoad: (atflCd: string) => void; - pbnstMngData: (data: customPbnst[]) => void; - pbnstBizData(data: fcBizType): void; - getBizCycle: (pbnstObj: customPbnst) => void; + //pbnstMngData: (data: customPbnst[]) => void; + //pbnstBizData(data: fcBizType): void; + // getBizCycle: (pbnstObj: customPbnst) => void; getpbnstInsertIndex: (data: pbnstInsertIndex) => void; pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; @@ -100,14 +101,20 @@ const checkWrRegList = async () => { const hasuListFetch = async (page: string, sggOrCity: string, searchTxt?:string) => { const checkWrRegListRes = await checkWrRegList(); -let url = `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`; + + console.log(' checkWrRegListRes ', checkWrRegListRes) +let url = `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity? sggOrCity : "11"}/0/1/SW`; + + +const data = checkWrRegListRes.filter((item:string) => item !== "") + console.log(' checkWrRegListRes ' ) if(searchTxt){ url= url +`/${searchTxt}` } const rainRes = await postFectch( url, - checkWrRegListRes, + data, fetchType.COMMON ); @@ -200,7 +207,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { pbnstRegClick: async (pubHasuRes: pubHasuType) => { try { const pbnstRes = await initFetch(pubHasuRes.bscFctCd); - console.log('pbnstRes ' , pbnstRes) return set((state: pubFacState) => ({ ...state, pbnst: { @@ -234,14 +240,19 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { const response = await postFectch( `/reuseFc/pubFc`, - JSON.stringify( pbnstRes) + pbnstRes ); + if( response.status === 200) { + toast.success(`${pbnstRes.ruseUtztnFcltNm} 하수재이용 시설이 등록되었습니다.`); + } + const pbnstHasuRes = await hasuListFetch('1', '0'); + return set((state: pubFacState) => ({ ...state, pbnst: { ...state.pbnst, - pbnstRes: response.data, + pbnstRes: pbnstHasuRes, isInit: false, }, })); @@ -334,41 +345,41 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } }, - pbnstMngData: (data: customPbnst[]) => { - if (data.length > 0) { - } - return set((state: pubFacState) => { - state.pbnst.pbnstMngRegData = data; - state.pbnst.pbnstBizCycle = - data.length <= 0 - ? [{ text: "없음", val: "1" }] - : state.pbnst.pbnstBizCycle; - return state; - }); - }, + // pbnstMngData: (data: customPbnst[]) => { + // if (data.length > 0) { + // } + // return set((state: pubFacState) => { + // state.pbnst.pbnstMngRegData = data; + // state.pbnst.pbnstBizCycle = + // data.length <= 0 + // ? [{ text: "없음", val: "1" }] + // : state.pbnst.pbnstBizCycle; + // return state; + // }); + // }, - pbnstBizData: (data: fcBizType) => { - return set((state: pubFacState) => { - if (state.pbnst.pbnstMngRegData) { - const regData = state.pbnst.pbnstMngRegData.find( - (item) => data.pbnstRuseFcltFk === item.pbnstRuseFcltPk - ); - if (regData) { - const bizIdx = regData.fcBizs.findIndex( - (item) => item.pbnstRuseFcltBizPk == data.pbnstRuseFcltBizPk - ); + // pbnstBizData: (data: fcBizType) => { + // return set((state: pubFacState) => { + // if (state.pbnst.pbnstMngRegData) { + // const regData = state.pbnst.pbnstMngRegData.find( + // (item) => data.pbnstRuseFcltFk === item.pbnstRuseFcltPk + // ); + // if (regData) { + // const bizIdx = regData.fcBizs.findIndex( + // (item) => item.pbnstRuseFcltBizPk == data.pbnstRuseFcltBizPk + // ); - if (bizIdx >= 0) { - regData.fcBizs[bizIdx] = data; - const pbnstData = state.pbnst.pbnstMngRegData - state.pbnst.pbnstMngRegData= [...pbnstData] + // if (bizIdx >= 0) { + // regData.fcBizs[bizIdx] = data; + // const pbnstData = state.pbnst.pbnstMngRegData + // state.pbnst.pbnstMngRegData= [...pbnstData] - } - } - } - return state; - }); - }, + // } + // } + // } + // return state; + // }); + // }, getpbnstInsertIndex: async (data: pbnstInsertIndex) => { return set((state: pubFacState) => { state.pbnst.pbnsUpdateIndex = data; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx index 0c3bb452c..a34985810 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -57,7 +57,7 @@ export type PbnstDemandComType = { dmdAplyPswd: string | ''; splyCpct: number | 0; splyFmYn:string|'Y' - dmdInfoFk:string|'' +// dmdInfoFk:string|'' } const pubHasuZod = z.object({ @@ -129,7 +129,7 @@ const fcOrgwtSchema = z.object({ }); const dmdColist = z.object({ - dmdInfoFk: z.string().default(''), + dmdInfoPk: z.string().default(''), dmdCoNm: z.string().default(''), daddr: z.string(), useUsgCd: z.string().nullish(), diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index d398b7f6e..5b3ad6813 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -3,7 +3,76 @@ import { getFetch, postFectch, putFectch } from "@/components/lib/api"; import { z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; +const validationMessages = { + required: (field: string) => `${field}을(를) 입력해주세요.`, + requiredSelect: (field: string) => `${field}을(를) 선택해주세요.`, + yearFormat: '4자리 연도만 입력하세요', +}; + export const TEST_UUID= '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e' + +const rainyObjSchema = z.object({ + bdstReuseFcltFk: z.number().nullish(), + pntfColKnd: z.string().default(""), + pntfColArea: z.number().default(0), + dtfcltCpct: z.number().default(0), + filtrTrtmfctYn: z.string().default("Y").nullish(), + filtrTrtmfctCpct: z.number().nullish().default(0), + filtrTrtmfctPrs: z.string().default(""), + annRnwtQty: z.number().default(0), + oilqMeasMthd: z.string().default("").nullish(), + rgtr:z.string().nullish(), + mdfr:z.string().nullish(), +}).refine((data) => data.pntfColKnd.length > 0, { + message: validationMessages.requiredSelect("종류"), + path: ["pntfColKnd"], +}).refine((data) => data.pntfColArea > 0, { + message: validationMessages.required("면적(m³)"), + path: ["pntfColArea"], +}); + +const reuseBuildingSchema = 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().default(""), + anlOperCst: z.number().default(0), + instlCstSprtYn: z.string().default("Y"), + instlCstSprtAmt: z.number().nullish(), + grntchBdstCertYn: z.string().default("Y"), + grntchBdstCertYr: z.string().default("") + .refine((year)=> year.length===0 || /^\d{4}$/.test(year),{ + message: validationMessages.yearFormat + }), + 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), + lawTrgtYn: z.string().default("Y"), + rgtr:z.string().nullish(), + mdfr:z.string().nullish(), + rainyObj: rainyObjSchema.default({}) +}).refine((data) => data.bdstUsgCd > 0, { + message: validationMessages.requiredSelect("건축물용도"), + path: ["bdstUsgCd"], +}); + +const chgBuildingSchema = z.object({ + bdstInfoFk: z.number().nullish(), + archChgPrmsnDt: z.coerce.date({required_error: validationMessages.required("허가일")}), + archChgArea: z.string().default("-"), + bdstChgNm: z.string().default(""), + rgtr:z.string().nullish(), + mdfr:z.string().nullish(), +}).refine(data => data.bdstChgNm.length > 0, { + message: validationMessages.requiredSelect("구분"), + path: ["bdstChgNm"] +}); + export const rainZod = z.object({ bdstInfoPk: z.number().optional(), ctpvCd: z.number().default(0), @@ -16,62 +85,9 @@ export const rainZod = z.object({ archChgArea: z.number().default(0), rgtr:z.string().nullish(), mdfr:z.string().nullish(), - reuseBuilding: z.array( - 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().default(""), - anlOperCst: z.number().default(0), - instlCstSprtYn: z.string().default(""), - instlCstSprtAmt: z.number().nullish(), - grntchBdstCertYn: z.enum(["Y", "N"]).nullish(), - grntchBdstCertYr: z.string().default("") - .refine((year)=> year.length===0 || /^\d{4}$/.test(year),{ - message:'4자리 연도만 입력하세요' - }), - 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), - lawTrgtYn: z.enum(["Y", "N"]), - rgtr:z.string().nullish(), - mdfr:z.string().nullish(), - - rainyObj: z.object({ - bdstReuseFcltFk: z.number().nullish(), - pntfColKnd: z.string().default(""), - pntfColArea: z.number().default(0), - dtfcltCpct: z.number().default(0), - filtrTrtmfctYn: z.enum(["Y", "N"]).nullish(), - filtrTrtmfctCpct: z.number().nullish().default(0), - filtrTrtmfctPrs: z.string().default(""), - annRnwtQty: z.number().default(0), - oilqMeasMthd: z.string().default("").nullish(), - rgtr:z.string().nullish(), - mdfr:z.string().nullish(), - - - }).default({}) - }) - ).default([]), - - chgBuilding: z.array( - z.object({ - bdstInfoFk: z.number().nullish(), - archChgPrmsnDt: z.coerce.date(), - archChgArea: z.string().default("-"), - bdstChgNm: z.string().default(""), - rgtr:z.string().nullish(), - mdfr:z.string().nullish(), - - }) - ).default([]) -}); + reuseBuilding: z.array(reuseBuildingSchema).default([]), + chgBuilding: z.array(chgBuildingSchema).default([]) +}) export type chgBuilding={ bdstInfoFk?: number|null, @@ -254,6 +270,3 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( } }} - - - diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index 6ce27db86..33bce5520 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -9,6 +9,7 @@ import { excelPbnstSttnParsing } from "./excel"; import type { FcPrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import type { ReturnType } from "@common/business_components/ui"; import type { WaterReuseFacility } from "./type"; +import moment from "moment"; const pbnstSttHeadList = pbnSttHeadListExport; const pbnstSttNodeList = pbnstSttNodeListExport; @@ -166,8 +167,8 @@ const hasuListFetch = async ( outUsage: usage.outUsage, operMthd: item.operList[0]?.operMthd, rprtvBzenty: item.operList[0]?.rprtvBzenty, - bgngDt: item.operList[0]?.bgngDt.toLocaleDateString ?? "", - endDt: item.operList[0]?.endDt.toLocaleDateString?? "", + bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", + endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "", searchNm: findData.bscFctNm, searchPk: findData.bscFctCd, prfList:item?.prfList??[] diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index 85e1a36b0..e5dfc8c0c 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -4,6 +4,7 @@ import { type SelectDataType, type ReturnType, filePickedBlobArray, + type SheetParameter, } from "@common/business_components/ui"; import type { RefObject } from "react"; @@ -81,7 +82,7 @@ export const excelDownload = ( export const excelArrayDownload = ( fileNm: string, sampleFile: string, - sheetArray: [] + sheetArray:SheetParameter [] ) => { if (!sheetArray) return; fetch(`/${sampleFile}`, {}).then(async (response) => { @@ -110,7 +111,12 @@ export const formatCommaNumber = ( value: number | string | undefined | null ): string => { if (value === undefined || value === null || value === "") return ""; - return Number(value).toLocaleString(); + const num = Number(value); + // 숫자로 변환할 수 없는 값이 들어올 경우 빈 문자열을 반환하여 예상치 못한 "NaN" 출력을 방지합니다. + if (isNaN(num)) { + return ""; + } + return num.toLocaleString(); }; export const getCityOrSgg = (ref: RefObject<ReturnType>) => { @@ -153,6 +159,3 @@ export const getdmdMatFlag = (flag: string|undefined) => { } return flagMat; }; - - - diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 645a2fa07..df63b3520 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -11,7 +11,6 @@ import { } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/headList"; import { fcBizSchema, - type customPbnst, type fcBizType, type PbnstRegArrrayType, type ppInstlType, @@ -25,20 +24,9 @@ import { import FcOrgwtsRegModal from "@/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal"; import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable"; import { SelectBox } from "@common/business_components"; -import { - FormUi, - SearchInputSelect, - UiModal, - type SelectDataType, -} from "@common/business_components/ui"; +import { DatePicker, FormUi, UiModal } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; -import { - Button, - DataTable, - DatePicker, - Input, - Label, -} from "@common/components"; +import { Button, DataTable, Input, Label } from "@common/components"; import { useEffect, useRef, useState } from "react"; import { useFieldArray, useForm, type UseFormReturn } from "react-hook-form"; import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail"; @@ -47,10 +35,9 @@ import SearchInputText from "@/components/ui/searchInput/searchInput"; import SdmInsertForm from "@common/business_components/ui/sdmInsertForm"; import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; import RuseMngTableForm from "@/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm"; +import type { SelectDataType } from "@common/business_components"; export function PbnstBuseForm({ - formType, - firstBizData, indexMng = 0, indexBiz = 0, setIndexBiz, @@ -68,14 +55,17 @@ export function PbnstBuseForm({ code, pbnst, demandCompList, - pbnstBizData, getpbnstInsertIndex, appendRuseFclt, - getBizCycle, getDemandCompList, regDemandCompany, } = useWrStore((state) => state); const { pbnstBizCycle, pbnstRes } = pbnst; + const { fields: fcBizs, append: appendBiz } = useFieldArray({ + control: form.control, + name: `items.${indexMng}.fcBizs`, + }); + const [bizCycle, setBizCycle] = useState("1"); const [ppiSelectList, setPpiSelectList] = useState<[{ name: string; val: SelectDataType[] }]>(); @@ -95,7 +85,6 @@ export function PbnstBuseForm({ data: DemandCompType; }>({ isMoal: false, data: {} as DemandCompType }); - useEffect(() => { const total = (form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.gvsbs`) ?? 0) + @@ -106,43 +95,29 @@ export function PbnstBuseForm({ }, [ form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.gvsbs`), form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.lcep`), - form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.cusrAlotm`) + form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.cusrAlotm`), ]); - // const form = useForm<fcBizType>({ - // resolver: zodResolver(fcBizSchema), - // defaultValues: - // formType === "reg" && - // pbnst.pbnstMngRegData && - // pbnst.pbnstMngRegData[0]?.fcBizs - // ? (pbnst.pbnstMngRegData[0].fcBizs[0] ?? {}) - // : formType === "update" && - // typeof pbnst.pbnsUpdateIndex.biz === "number" && - // pbnst.pbnsUpdateIndex.biz >= 0 && - // pbnst.pbnstRes - // ? pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]?.fcBizs[ - // pbnst.pbnsUpdateIndex.biz - // ] - // : fcBizSchema.parse({}), - // mode: "onChange", - // }); - - + // fcBizs 데이터가 변경될 때마다 차수 선택 목록을 업데이트합니다. useEffect(() => { - if (form) { - const cycleLength = form.getValues(`items.${indexMng}.fcBizs`).length; - setSelectBizCycle( - Array.from({ length: cycleLength }, (_, index) => ({ - text: `${index + 1}차`, // ✅ index + 1 - val: index, // 이건 그대로 유지 (value로는 0부터 시작) - })) - ); + const cycleLength = fcBizs.length; + const newSelectBizCycle = Array.from( + { length: cycleLength }, + (_, index) => ({ + text: `${index + 1}차`, + val: index, + }) + ); + setSelectBizCycle(newSelectBizCycle); + + // 현재 차수 인덱스가 유효하지 않게 되면 마지막 인덱스로 조정합니다. + if (indexBiz >= cycleLength && cycleLength > 0) { + setIndexBiz(cycleLength - 1); } - }, [indexMng, form]); + }, [fcBizs, indexBiz, setIndexBiz]); // 2. Define a submit handler. function addRuseFcltObj() { const formRuse = form.getValues(`items.${indexMng}`); - const formBizs = form.getValues(`items.${indexMng}.fcBizs`); const pbnstBizCycle = formBizs.length; @@ -154,25 +129,13 @@ export function PbnstBuseForm({ pplInstls: undefined, fcDemands: undefined, }); - const index = pbnst.pbnsUpdateIndex.mng; appendBiz(newItem); - const cycleLength = form.getValues(`items.${indexMng}.fcBizs`).length; - setSelectBizCycle( - Array.from({ length: cycleLength }, (_, index) => ({ - text: `${index + 1}차`, // ✅ index + 1 - val: index, // 이건 그대로 유지 (value로는 0부터 시작) - })) - ); + setIndexBiz(pbnstBizCycle); // 새로 추가된 차수로 포커스 이동 } useEffect(() => { - console.log("form ", form.watch()); + //console.log("form ", form.watch()); }, [form.formState]); - const { fields: fcBizs, append: appendBiz } = useFieldArray({ - control: form.control, - name: `items.${indexMng}.fcBizs`, - }); - const { fields: fcDemands, append: appendDemand, @@ -186,7 +149,6 @@ export function PbnstBuseForm({ control: form.control, name: `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, }); - console.log(" fcOrgwtFiled ", fcOrgwtFiled); const { fields: pplInstls, append: appendPpl, @@ -202,10 +164,6 @@ export function PbnstBuseForm({ } }, [ppiYn, indexMng, indexBiz]); - useEffect(() => { - console.log("pbnst. bug pbnstMngRegData ", pbnst.pbnstMngRegData); - }, [pbnst.pbnstMngRegData]); - const plusHist = () => { if ( form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltBizPk`) @@ -245,7 +203,7 @@ export function PbnstBuseForm({ form.getValues( `items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltFk` ) ?? "", - dmdInfoFk: "", + dmdInfoPk: "", //telno: "", }); }; @@ -278,9 +236,6 @@ export function PbnstBuseForm({ } }, [code]); - useEffect(() => { - console.log(" demandCompList ", demandCompList); - }, [demandCompList]); useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); @@ -295,441 +250,488 @@ export function PbnstBuseForm({ setSumCpct(sum); }, [form.formState, indexMng, indexBiz]); + // // 차수별 정보(fcBizs)가 하나도 없을 경우 플레이스홀더 UI를 보여줍니다. + // if (fcBizs.length === 0) { + // return ( + // <div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 text-gray-500 border rounded-md"> + // <p className="text-lg">등록된 차수별 정보가 없습니다.</p> + // <p className="text-sm mb-4">아래 버튼을 눌러 신규 차수 정보를 등록해주세요.</p> + // <Button + // onClick={addRuseFcltObj} + // type="button" + // size={commonButonSize} + // className="mt-2" + // > + // 신규 차수 등록 + // </Button> + // </div> + // ); + // } + + const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`); return ( <> - <div className=" !mx-[1.6rem] !p-0r"> - {/* 차수별 등록 현황 폼 */} - <div className="justify-between"> - <Form {...form}> - <form - key={indexBiz} - // onSubmit={form.handleSubmit(onSubmit)} - className="space-y-8 mx-auto w-full mt-7" - > - <div className="flex justify-between items-center mx-3 mb-3"> - <h1 className=" text-xl"></h1> - <div className="flex items-center gap-2 mx-3"> - <h1 className={formTableName}>등록차수</h1> + {pbnstBiz && pbnstBiz?.length > 0 ? ( + <div className=" !mx-[1.6rem] !p-0r"> + {/* 차수별 등록 현황 폼 */} + <div className="justify-between"> + <Form {...form}> + <form + key={indexBiz} + // onSubmit={form.handleSubmit(onSubmit)} + className="space-y-8 mx-auto w-full mt-7" + > + <div className="flex justify-between items-center mx-3 mb-3"> + <h1 className=" text-xl"></h1> + <div className="flex items-center gap-2 mx-3"> + <h1 className={formTableName}>등록차수</h1> - <SelectBox - label="" - selectArray={selectBizCycle || []} - value={selectBizCycle[indexBiz]?.val} - className={""} - selectClass={selectClass} - onSelectValue={(val) => { - setIndexBiz(Number(val)); - }} - ></SelectBox> + <SelectBox + label="" + key={`cycle-${indexMng}-${indexBiz}`} + selectArray={selectBizCycle || []} + value={selectBizCycle[indexBiz]?.val} + className={""} + selectClass={selectClass} + onSelectValue={(val) => { + setIndexBiz(Number(val)); + }} + ></SelectBox> - <Button - onClick={addRuseFcltObj} - type="button" - size={commonButonSize} - > - 추가 - </Button> - </div> - </div> - <MngRegFormDetail - formList={businessSttnInfo} - h1Title={"사업현황"} - form={form} - moClass="grid grid-cols-12 gap-4" - sonClass="col-span-4" - indexMng={indexMng} - indexBiz={indexBiz} - /> - <MngRegFormDetail - formList={businessMoneyInfo} - h1Title={"사업비"} - form={form} - moClass="grid grid-cols-12 gap-4" - sonClass="col-span-4" - indexMng={indexMng} - indexBiz={indexBiz} - /> - - <MngRegFormDetail - formList={ruseFcltinfo} - h1Title={"재처리시설"} - form={form} - moClass="grid grid-cols-12 gap-4" - sonClass="col-span-4" - indexMng={indexMng} - indexBiz={indexBiz} - /> - <MngRegFormDetail - formList={concentratedWaterInfo} - h1Title={"농축수관리"} - form={form} - moClass="grid grid-cols-12 gap-4" - sonClass="col-span-4" - indexMng={indexMng} - indexBiz={indexBiz} - /> - <MngRegFormDetail - formList={wasteWaterFcltINfo} - h1Title={"폐수배출시설 정보"} - form={form} - moClass="grid grid-cols-12 gap-4" - sonClass="col-span-4" - indexMng={indexMng} - indexBiz={indexBiz} - /> - - <h1 className={formH1Class}>재이용 원수취수 현황</h1> - <div> - <div className="text-right mb-3"> - <Button - type="button" - onClick={() => setIsFcOrgwts(true)} - size={commonButonSize} - className="" - > - 추가등록 - </Button> - </div> - <RuseMngTable - key={`fcOrgwts-${indexMng}-${indexBiz}`} // 이게 핵심! - tableData={ - form.getValues( - `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts` - ) ?? [] - } - headList={pbnst.pbnstOrgwtHeadList} - upHeadList={[]} - indexMng={indexMng} - indexBiz={indexBiz} - formNm={"fcOrgwts"} - /> - </div> - <h1 className={formH1Class}>재이용 공급관로 설치 현황</h1> - <div className="flex items-center gap-4 mx-3 mb-3"> - <Label className="text-right">공급관로설치유무</Label> - <SelectBox - label="" - selectArray={code.yn} - value={ppiYn} - className="w-32" - selectClass="w-full" - onSelectValue={(val) => setPpiYn(String(val))} - /> - <Label className="text-right">합계</Label> - <Input - type="text" - value={sumCpct} - readOnly={true} - className="w-32 border-gray-300 rounded pr-8 " - /> - {ppiYn === "Y" ? ( - <> <Button + onClick={addRuseFcltObj} type="button" size={commonButonSize} - className="!text-xl" - onClick={plusHist} + > + 추가 + </Button> + </div> + </div> + <MngRegFormDetail + key={`buziInSttn-${indexMng}-${indexBiz}`} + formList={businessSttnInfo} + h1Title={"사업현황"} + form={form} + moClass="grid grid-cols-12 gap-4" + sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} + /> + <MngRegFormDetail + key={`buziMoney-${indexMng}-${indexBiz}`} + formList={businessMoneyInfo} + h1Title={"사업비"} + form={form} + moClass="grid grid-cols-12 gap-4" + sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} + /> + + <MngRegFormDetail + key={`reprocessingFclt-${indexMng}-${indexBiz}`} + formList={ruseFcltinfo} + h1Title={"재처리시설"} + form={form} + moClass="grid grid-cols-12 gap-4" + sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} + /> + <MngRegFormDetail + key={`concertedWater-${indexMng}-${indexBiz}`} + formList={concentratedWaterInfo} + h1Title={"농축수관리"} + form={form} + moClass="grid grid-cols-12 gap-4" + sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} + /> + <MngRegFormDetail + key={`wasteFcltinfo-${indexMng}-${indexBiz}`} + formList={wasteWaterFcltINfo} + h1Title={"폐수배출시설 정보"} + form={form} + moClass="grid grid-cols-12 gap-4" + sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} + /> + + <h1 className={formH1Class}>재이용 원수취수 현황</h1> + <div> + <div className="text-right mb-3"> + <Button + type="button" + onClick={() => setIsFcOrgwts(true)} + size={commonButonSize} + className="" > 추가등록 </Button> - <Button - type="button" - size={commonButonSize} - className="!text-xl !bg-red-500 !text-white ml-1" - onClick={removeSelected} - > - 삭제 - </Button> - </> - ) : ( - <></> - )} - </div> - <div> - <RuseMngTableForm - key={`pplInstls-${indexMng}-${indexBiz}`} // 이게 핵심! - tableData={ - form.getValues( - `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` - ) ?? [] - } - headList={pbnst.pplInstlsHeadLisat} - code={ppiSelectList ?? []} - //ref={ref} + </div> + <RuseMngTable + key={`fcOrgwts-${indexMng}-${indexBiz}`} // 이게 핵심! + tableData={ + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts` + ) ?? [] + } + headList={pbnst.pbnstOrgwtHeadList} + upHeadList={[]} + indexMng={indexMng} + indexBiz={indexBiz} + /> + </div> + <h1 className={formH1Class}>재이용 공급관로 설치 현황</h1> + <div className="flex items-center gap-4 mx-3 mb-3"> + <Label className="text-right">공급관로설치유무</Label> + <SelectBox + label="" + selectArray={code.yn} + value={ppiYn} + className="w-32" + selectClass="w-full" + onSelectValue={(val) => setPpiYn(String(val))} + /> + <Label className="text-right">합계</Label> + <Input + type="text" + value={sumCpct} + readOnly={true} + className="w-32 border-gray-300 rounded pr-8 " + /> + {ppiYn === "Y" ? ( + <> + <Button + type="button" + size={commonButonSize} + className="!text-xl" + onClick={plusHist} + > + 추가등록 + </Button> + <Button + type="button" + size={commonButonSize} + className="!text-xl !bg-red-500 !text-white ml-1" + onClick={removeSelected} + > + 삭제 + </Button> + </> + ) : ( + <></> + )} + </div> + <div> + <RuseMngTableForm + key={`pplInstls-${indexMng}-${indexBiz}`} // 이게 핵심! + tableData={ + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` + ) ?? [] + } + headList={pbnst.pplInstlsHeadLisat} + code={ppiSelectList ?? []} + //ref={ref} + indexMng={indexMng} + indexBiz={indexBiz} + form={form} + formNm={"pplInstls"} + upHeadList={[]} + onTableSet={(val) => { + const pplSum = form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` + ); + if (!pplSum) return; + let sum = 0; + pplSum.forEach((item) => { + sum += Number(item.cpct) || 0; + }); + setSumCpct(sum); + }} + /> + </div> + + <MngRegFormDetail + formList={ruseWaterQulityList} + h1Title={"하수처리수 재이용시설 보증수질"} + form={form} + moClass="grid grid-cols-12 gap-4" + sonClass="col-span-4" indexMng={indexMng} indexBiz={indexBiz} - form={form} - formNm={"pplInstls"} - upHeadList={[]} - onTableSet={(val) => { - const pplSum = form.getValues( - `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` - ); - if (!pplSum) return; - let sum = 0; - pplSum.forEach((item) => { - sum += Number(item.cpct) || 0; - }); - setSumCpct(sum); - }} /> - </div> - - <MngRegFormDetail - formList={ruseWaterQulityList} - h1Title={"하수처리수 재이용시설 보증수질"} - form={form} - moClass="grid grid-cols-12 gap-4" - sonClass="col-span-4" - indexMng={indexMng} - indexBiz={indexBiz} - /> - <div key={"hasu"}> - <h1 className={formH1Class}>{"하수처리수 재이용수 수요처"}</h1> - <div className="text-right mb-3"> - <Button - type="button" - onClick={() => { - plusArray(); - }} - size={commonButonSize} - className="mt-6 mr-3" - > - 수요항목 추가 - </Button> - <Button - type="button" - onClick={() => { - setIsDmdModal({ - isMoal: true, - data: {} as DemandCompType, - }); - }} - size={commonButonSize} - className="mt-6" - > - 수요처 추가 - </Button> - </div> - {( - form.getValues( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands` - ) || [] - ).map((field, index) => ( - <div - key={`fcDemands-${indexMng}-${indexBiz}`} // 이게 핵심! - className="grid grid-cols-12 gap-4 mt-3" - > - <div key={index + "keySon1"} className="col-span-4"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdCoNm`} - render={({ field: f }) => ( - <FormUi label="수요처명"> - <SearchInputText - label={"수요처"} - initValue={f.value} - setValue={(val) => { - f.onChange(val); - if (val && val.length > 2) { - getDemandCompList(val, 3); - } - }} - setRtnData={(valList: any) => { - if (valList) { - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoFk`, - valList.dmdInfoPk - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`, - valList.daddr - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`, - valList.useUsgCd - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`, - valList.splyCpct - ); - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoFk`, - valList.dmdInfoPk?.toString() - ); - } - }} - searchList={demandCompList?.map((item) => { - return { - ...item, - searchNm: item.dmdCoNm, - searchPk: item.dmdInfoPk, - }; - })} - ></SearchInputText> - </FormUi> - )} - /> - </div> - <div key={index + "keySon2"} className="col-span-4"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`} - render={({ field: f }) => ( - <FormUi label="위치(주소)"> - <Input - placeholder="-" - type="text" - readOnly - onChange={(e) => f.onChange(e.target.value)} - value={f.value} - className={selectClass} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon3"} className="col-span-4"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`} - render={({ field: f }) => ( - <FormUi label="사용용도"> - <SelectBox - label={""} - selectClass={""} - className="w-full" - selectArray={code.dmdUszCd} - onSelectValue={f.onChange} - value={f.value ?? code.dmdUszCd[0]?.val} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon4"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyBgngDay`} - render={({ field: f }) => ( - <FormUi label="공급시작일"> - <DatePicker - mode={"single"} - selected={safeDate(f.value) || new Date()} - onSelect={(date: Date | undefined) => - f.onChange(date) - } - className={"rounded-lg !w-full"} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon5"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyEndDay`} - render={({ field: f }) => ( - <FormUi label="공급종료일"> - <DatePicker - mode={"single"} - selected={safeDate(f.value) || new Date()} - onSelect={(date: Date | undefined) => - f.onChange(date) - } - className={"rounded-lg !w-full"} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon6"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`} - render={({ field: f }) => ( - <FormUi label="(계약)공급량(m3/일)"> - <Input - placeholder="" - type="number" - value={f.value ?? 0} - onChange={(e) => { - f.onChange(Number(e.target.value)); - }} - /> - </FormUi> - )} - /> - </div> - <div key={index + "keySon7"} className="col-span-3"> - <FormField - control={form.control} - name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyFmYn`} - render={({ field: f }) => ( - <FormUi label="공급 유량계 유무"> - <SelectBox - label={""} - selectClass={""} - className="w-full" - selectArray={code.yn} - onSelectValue={(val: string | number) => - f.onChange(val) - } - value={f.value} - /> - </FormUi> - )} - /> - </div> + <div key={"hasu"}> + <h1 className={formH1Class}> + {"하수처리수 재이용수 수요처"} + </h1> + <div className="text-right mb-3"> + <Button + type="button" + onClick={() => { + plusArray(); + }} + size={commonButonSize} + className="mt-6 mr-3" + > + 수요항목 추가 + </Button> + <Button + type="button" + onClick={() => { + setIsDmdModal({ + isMoal: true, + data: {} as DemandCompType, + }); + }} + size={commonButonSize} + className="mt-6" + > + 수요처 추가 + </Button> </div> - ))} - </div> - </form> - </Form> + {( + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands` + ) || [] + ).map((field, index) => ( + <div + key={`fcDemands-${indexMng}-${indexBiz}`} // 이게 핵심! + className="grid grid-cols-12 gap-4 mt-3" + > + <div key={index + "keySon1"} className="col-span-4"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdCoNm`} + render={({ field: f }) => ( + <FormUi label="수요처명"> + <SearchInputText + label={"수요처"} + initValue={f.value} + setValue={(val) => { + f.onChange(val); + if (val && val.length > 2) { + getDemandCompList(val, 3); + } + }} + setRtnData={(valList: any) => { + if (valList) { + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`, + valList.daddr + ); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`, + valList.useUsgCd + ); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`, + valList.splyCpct + ); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoPk`, + valList.dmdInfoPk?.toString() + ); + } + }} + searchList={demandCompList?.map((item) => { + return { + ...item, + searchNm: item.dmdCoNm, + searchPk: item.dmdInfoPk, + }; + })} + ></SearchInputText> + </FormUi> + )} + /> + </div> + <div key={index + "keySon2"} className="col-span-4"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`} + render={({ field: f }) => ( + <FormUi label="위치(주소)"> + <Input + placeholder="-" + type="text" + readOnly + onChange={(e) => f.onChange(e.target.value)} + value={f.value} + className={selectClass} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon3"} className="col-span-4"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`} + render={({ field: f }) => ( + <FormUi label="사용용도"> + <SelectBox + label={""} + selectClass={""} + className="w-full" + selectArray={code.dmdUszCd} + onSelectValue={f.onChange} + value={f.value ?? code.dmdUszCd[0]?.val} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon4"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyBgngDay`} + render={({ field: f }) => ( + <FormUi label="공급시작일"> + <DatePicker + mode={"single"} + field={{ + value: safeDate(f.value) || new Date(), + onChange: (date: Date | undefined) => + f.onChange(date), + }} + selectClass={"rounded-lg !w-full"} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon5"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyEndDay`} + render={({ field: f }) => ( + <FormUi label="공급종료일"> + <DatePicker + mode={"single"} + onSelect={(date: Date | undefined) => + f.onChange(date) + } + field={{ + value: safeDate(f.value) || new Date(), + onChange: (date: Date | undefined) => + f.onChange(date), + }} + selectClass={"rounded-lg !w-full"} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon6"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`} + render={({ field: f }) => ( + <FormUi label="(계약)공급량(m3/일)"> + <Input + placeholder="" + type="number" + value={f.value ?? 0} + onChange={(e) => { + f.onChange(Number(e.target.value)); + }} + /> + </FormUi> + )} + /> + </div> + <div key={index + "keySon7"} className="col-span-3"> + <FormField + control={form.control} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyFmYn`} + render={({ field: f }) => ( + <FormUi label="공급 유량계 유무"> + <SelectBox + label={""} + selectClass={""} + className="w-full" + selectArray={code.yn} + onSelectValue={(val: string | number) => + f.onChange(val) + } + value={f.value ?? code.yn[0]?.val} + /> + </FormUi> + )} + /> + </div> + </div> + ))} + </div> + </form> + </Form> + </div> + + <UiModal + open={isFcOrgwts} + onOpenChange={(open: boolean) => setIsFcOrgwts(open)} + bodyClass={"w-[50vw] max-w-none h-[90vh]"} + body={ + <FcOrgwtsRegModal + closeModal={() => { + setIsFcOrgwts(false); + }} + onRightSet={(val) => { + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, + val + ); + }} + ></FcOrgwtsRegModal> + } + ></UiModal> + + <UiModal + bodyClass={"w-[40vw] max-w-none h-[90vh]"} + open={isDmdModal.isMoal} + onOpenChange={() => { + setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); + }} + body={ + <SdmInsertForm + selectSidoData={code.cityCd} + selectSigunData={code.sggCd} + dataList={demandCompList} + rtnValue={(searchText: string, pageCnt: number) => { + getDemandCompList(searchText, pageCnt); + }} + rtnInputData={(data) => { + regDemandCompany(data as DemandCompType); + setIsDmdModal({ + isMoal: false, + data: data as DemandCompType, + }); + }} + bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"} + ></SdmInsertForm> + } + ></UiModal> </div> - - <UiModal - open={isFcOrgwts} - onOpenChange={(open: boolean) => setIsFcOrgwts(open)} - bodyClass={"w-[50vw] max-w-none h-[90vh]"} - body={ - <FcOrgwtsRegModal - closeModal={() => { - setIsFcOrgwts(false); - }} - onRightSet={(val) => { - form.setValue( - `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, - val - ); - }} - ></FcOrgwtsRegModal> - } - ></UiModal> - - <UiModal - bodyClass={"w-[40vw] max-w-none h-[90vh]"} - open={isDmdModal.isMoal} - onOpenChange={() => { - setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); - }} - body={ - <SdmInsertForm - selectSidoData={code.cityCd} - selectSigunData={code.sggCd} - dataList={demandCompList} - rtnValue={(searchText: string, pageCnt: number) => { - getDemandCompList(searchText, pageCnt); - }} - rtnInputData={(data) => { - regDemandCompany(data as DemandCompType); - setIsDmdModal({ isMoal: false, data: data as DemandCompType }); - }} - bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"} - ></SdmInsertForm> - } - ></UiModal> - </div> + ) : ( + <div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 text-gray-500 border rounded-md"> + <p className="text-lg">등록된 차수별 정보가 없습니다.</p> + <p className="text-sm mb-4"> + 아래 버튼을 눌러 신규 차수 정보를 등록해주세요. + </p> + <Button + onClick={addRuseFcltObj} + type="button" + size={commonButonSize} + className="mt-2" + > + 신규 차수 등록 + </Button> + </div> + )} </> ); } diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index 21dc3cf83..d07d24a23 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -37,7 +37,6 @@ export type FilesType = { export function PbnstMngForm({ form, formType, - firstFcltData, indexMng, setIndexMng, }: { @@ -51,12 +50,8 @@ export function PbnstMngForm({ code, pbnst, pbnstInsert, - pbnstMngData, fileDelete, fileDownLoad, - getBizCycle, - getpbnstInsertIndex, - appendRuseFclt, } = useWrStore((state) => state); const { pbnstRes } = pbnst; @@ -67,8 +62,6 @@ export function PbnstMngForm({ const [mngMtdCode, setMngMtdCode] = useState<{ name: string; val: SelectDataType[] }[]>(); - const [progress, setProgress] = useState(0); - const { fields: fcOpersField, append, @@ -221,12 +214,19 @@ export function PbnstMngForm({ }, [pbnst.pbnstMngRegData]); useEffect(() => { - if (pbnst.pbnstRes && pbnst.pbnstRes?.length <= 0) return; - const fcltNmList = pbnst.pbnstRes?.map((item, index) => ({ - text: item.ruseUtztnFcltNm, - val: String(index), - })); - if (fcltNmList) setFcltNm(fcltNmList); + if (pbnst.pbnstRes && pbnst.pbnstRes?.length >= 0) { + + const fcltNmList = pbnst.pbnstRes?.map((item, index) => ({ + text: item.ruseUtztnFcltNm, + val: String(index), + })); + + + console.log(' fcltNmList ', fcltNmList) + if (fcltNmList) setFcltNm(fcltNmList); + }else{ + setFcltNm(null); + } }, [pbnst.pbnstRes]); // 2. Define a submit handler. @@ -253,6 +253,16 @@ export function PbnstMngForm({ } }, [code]); + + useEffect(() =>{ + // console.log(' fcltNm ', watchedItem?.ruseUtztnFcltNm) + },[watchedItem]) + + + useEffect(() => { + console.log(" form indexMng ", indexMng); + }, [indexMng]); + return ( <div className=" !mx-[1.6rem] !p-0r"> <div> @@ -266,33 +276,29 @@ export function PbnstMngForm({ </Label> {formType === "update" ? ( - <FormField - key={`items.${indexMng}.ruseUtztnFcltNm-key`} - control={form.control} - name={`items.${indexMng}.ruseUtztnFcltNm`} - render={({ field }) => ( - <FormUi label=""> - <SelectBox - label="" - selectArray={fcltNm ?? []} - onSelectValue={(val) => { - setIndexMng(Number(val)); - field.onChange(val); - }} - value={field.value ?? ""} - className={""} - selectClass={undefined} - /> - </FormUi> - )} - /> + <FormUi label=""> + <SelectBox + label="" + key={`fclt-selector-${indexMng}`} + selectArray={fcltNm ?? []} + onSelectValue={(val) => { + setIndexMng(Number(val)); + }} + value={String(indexMng)} + className={""} + selectClass={undefined} + /> + </FormUi> ) : ( <FormField control={form.control} name={`items.${indexMng}.ruseUtztnFcltNm`} + key={`items-ruseUtztnFcltNm-${indexMng}`} render={({ field }) => ( <FormUi label=""> <Input + + className="!text-2xl" placeholder="" type="text" diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx index 48a0f5056..9ec4fc5c0 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/rainRegForm.tsx @@ -60,8 +60,10 @@ export default function RainRegForm({ typeof item?.grntchBdstCertYr === "string" ? item?.grntchBdstCertYr : "", // null → "" + // Ensure enum fields are null if empty string to trigger Zod default rainyObj: { ...item?.rainyObj, + filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn === "" ? null : item?.rainyObj?.filtrTrtmfctYn, }, })), }; @@ -84,7 +86,6 @@ export default function RainRegForm({ useEffect(() => { const subscription = form.watch((value) => { }); - console.log("subscription:", subscription) return () => subscription.unsubscribe(); }, [form]); @@ -147,6 +148,7 @@ export default function RainRegForm({ ? new Date(field.value) : new Date(), // Provide a default Date value onChange: (date) => field.onChange(date), + }} selectClass={"w-full"} readOnly={readonly} @@ -243,7 +245,7 @@ export default function RainRegForm({ label={""} selectArray={code.yn} onSelectValue={readonly ? () => { } : field.onChange} - value={field.value ?? code.yn[0]?.val} + value={field.value || code.yn[0]?.val} readOnly={readonly} /> </FormUi> @@ -278,12 +280,10 @@ export default function RainRegForm({ <FormUi label="처리공정"> <Input className={selectClass} - placeholder="1,000,000" - type="" + placeholder="" + type="text" value={field.value ?? ""} - onChange={(e) => { - if (!readonly) handleCommaNumberChange(e, field.onChange); - }} + onChange={field.onChange} readOnly={filtrTrtmfctYn !== "Y"} /> </FormUi> diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index f60fb8620..315f9397f 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -45,7 +45,7 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) { const cityValue = String(val); // Ensure val is treated as a string const data = getCity(cityValue, code.sggCd); setSelectSgg(data); - + getSgg(data[0]?.val || ""); setObjSearch({ city: cityValue, sgg: '' }); }; @@ -111,6 +111,7 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) { selectClass={selectClass} selectArray={selectSgg || []} onSelectValue={getSgg} + value={objSearch.sgg || ""} > {" "} </SelectBox> diff --git a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx index d7ecee90a..b930a36bb 100644 --- a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx @@ -26,7 +26,7 @@ export function PbnstRegModal({ data: pubHasuType; form: UseFormReturn<{ items: PbnstRegArrrayType }>; }) { - const { pbnst, pbnstInsert, pbnstMngData } = useWrStore((state) => { + const { pbnst, pbnstInsert } = useWrStore((state) => { return state; }); const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>( @@ -57,48 +57,18 @@ export function PbnstRegModal({ useEffect(() => { if (data) { + const firstForm = form.getValues("items"); - - console.log('mngIndex ', firstForm.length) - setIndexMng(firstForm.length - 1) - // console.log(' firstForm ', firstForm) - // let regData; - // if (pbnstRes && pbnstRes?.length > 0) { - // regData = { - // swtrmtFcltFk: String(data.bscFctCd), - // pbnstRuseFcltPk: String(data.bscFctCd) + String(pbnstRes.length + 1), - // fcBizs: [ - // { - // pbnstRuseFcltFk: - // String(data.bscFctCd) + String(pbnstRes.length + 1), - // cycl: 1, - // } as unknown as fcBizType, - // ], - // }; - // //regData= pbnstRegZod.parse(regData) - // //setPbnstBdstForm(regData as unknown as customPbnst); - // // pbnstMngData([regData] as unknown as customPbnst[]) - // } else { - // regData = { - // swtrmtFcltFk: String(data.bscFctCd), - // pbnstRuseFcltPk: String(data.bscFctCd + "1"), - // fcBizs: [ - // { - // pbnstRuseFcltFk: String(data.bscFctCd + "1"), - // cycl: 1, - // } as unknown as fcBizType, - // ], - // }; - // //regData= pbnstRegZod.parse(regData) - // // setPbnstBdstForm(regData as unknown as customPbnst); - - // // pbnstMngData([regData] as unknown as customPbnst[]) - // } - // regData = pbnstRegZod.parse(regData); - // setPbnstBdstForm(regData as unknown as customPbnst); - } + setIndexMng(firstForm.length - 1) } }, [data, form]); + + + useEffect(() => { + console.log(' form.getValues() ' ,form.getValues()) + + }, [form.getValues()]); + return ( <> <h1 className="text-2xl font-medium text-label pl-8"> diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index 11c183f1b..acb923687 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -21,8 +21,7 @@ import { TableHeader, TableRow, } from "@common/components/ui"; -import { read } from "fs"; -import React, { useEffect, useState } from "react"; +import React from "react"; type RuseMngTableProps = { tableData: any[]; @@ -39,8 +38,6 @@ type RuseMngTableProps = { const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( ({ tableData, headList, upHeadList, code, onTableSet, indexMng, form,formNm,indexBiz }, ref) => { - - console.log('tableData ', tableData) return ( <> <Table key={`table-${indexMng}-${indexBiz}`} variant="secondary"> @@ -119,6 +116,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( field.onChange(val); } }} + readOnly ={head.readonly ? true : false} // Disabled prop removed as SelectBox does not support it ></SelectBox> ) : head.type === "date" ? ( @@ -133,6 +131,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( }, }} selectClass={"w-full"} + readOnly ={head.readonly ? true : false} /> ) : head.type === "checkbox" ? ( <Checkbox diff --git a/apps/wr/public/sample_rainy.xlsx b/apps/wr/public/sample_rainy.xlsx index ee4b23edb..73a52d89c 100644 Binary files a/apps/wr/public/sample_rainy.xlsx and b/apps/wr/public/sample_rainy.xlsx differ diff --git a/packages/common/business_components/src/ui/excel/excelStyle.tsx b/packages/common/business_components/src/ui/excel/excelStyle.tsx index 3c8f8d219..221e1387c 100644 --- a/packages/common/business_components/src/ui/excel/excelStyle.tsx +++ b/packages/common/business_components/src/ui/excel/excelStyle.tsx @@ -53,7 +53,8 @@ export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[] if (item.data && item.data.length > 0) { const numCols = item.data[0]?.length || 0; const numRows = item.data.length; - const dataRange = workbook.activeSheet(index)?.sheet(index)?.range(`A1:${String.fromCharCode(65 + numCols - 1)}${numRows}`); + const lastColLetter = getExcelColumnLetter(numCols); + const dataRange = workbook.activeSheet(index)?.sheet(index)?.range(`A1:${lastColLetter}${numRows}`); dataRange?.style((styleQ) => { styleQ.verticalAlignment("center"); }); @@ -62,4 +63,60 @@ export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[] } makeExcelFile(workbook, fileNm) -} \ No newline at end of file +} + +export const excelStyleWithKoreanHeaders = async ( + data: ArrayBuffer, + range: string = "A1:V3", + fileNm: string, + headerMapping: { [key: string]: string }, + sampleData: any +) => { + const workbook = await XlsxPopulate.Workbook.fromData(data); + const sheet = workbook.activeSheet(); + + if (!sheet) { + throw new Error('워크시트를 찾을 수 없습니다.'); + } + + // 1. 영문 헤더를 한글로 교체 + const englishHeaders = Object.keys(sampleData); + englishHeaders.forEach((englishHeader, index) => { + const koreanHeader = headerMapping[englishHeader] || englishHeader; + const cellAddress = String.fromCharCode(65 + index) + '1'; // A1, B1, C1, ... + sheet.cell(cellAddress).value(koreanHeader); + }); + + // 2. 헤더 스타일 적용 + const headerCells = sheet.range(range); + headerCells?.style((styleQ) => { + makeCellStyle(styleQ); + }); + + // 3. 모든 데이터 셀에 세로 가운데 정렬 적용 + const numCols = englishHeaders.length; + const numRows = sheet.usedRange()?.endCell()?.rowNumber() || 1; + + if (numRows > 1) { + const dataRange = sheet.range(`A1:${String.fromCharCode(65 + numCols - 1)}${numRows}`); + dataRange?.style((styleQ) => { + styleQ.verticalAlignment("center"); + styleQ.borderEach({ style: "thin", color: { rgb: "CCCCCC" } }); + }); + } + + // 4. 파일 다운로드 + await makeExcelFile(workbook, fileNm); +}; + + +const getExcelColumnLetter = (colIndex: number): string => { + let letter = ''; + while (colIndex > 0) { + const mod = (colIndex - 1) % 26; + letter = String.fromCharCode(65 + mod) + letter; + colIndex = Math.floor((colIndex - 1) / 26); + } + return letter; + }; + diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx index 96f3b3e5d..cbe77293b 100644 --- a/packages/common/business_components/src/ui/excel/index.tsx +++ b/packages/common/business_components/src/ui/excel/index.tsx @@ -1,5 +1,5 @@ import * as XLSX from 'xlsx'; -import { excelArrayStyle, excelStyle } from './excelStyle'; +import { excelArrayStyle, excelStyle, excelStyleWithKoreanHeaders } from './excelStyle'; type ExcelDownloadProps = { data: JSON | JSON[]; @@ -164,4 +164,38 @@ export const filePickedBlobArray = (oFile: ArrayBuffer, fileNm: string, sheetArr }); await excelArrayStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), sheetArray, fileNm) }); -} \ No newline at end of file +} + +type ExcelDownloadWithHeaderProps = { + data: JSON | JSON[]; + fileName: string; + sheetNameArray: string[]; + headerRange?: string; + headerMapping: { [key: string]: string }; +} + +export const downloadExcelWithKoreanHeaders = async ({ + data, + fileName = new Date().getTime().toString() + '.xlsx', + sheetNameArray = ["Sheet1"], + headerRange = 'A1:V3', + headerMapping +}: ExcelDownloadWithHeaderProps) => { + + const dataArray = Array.isArray(data) ? data : [data]; + + if (dataArray.length === 0) { + throw new Error('데이터가 없습니다.'); + } + + // 1. 원본 데이터로 워크시트 생성 + const worksheet = XLSX.utils.json_to_sheet(dataArray); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]); + + // 2. 워크북을 ArrayBuffer로 변환 + const buffer = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }); + + // 3. 헤더만 한글로 교체하는 커스텀 스타일 함수 호출 + await excelStyleWithKoreanHeaders(buffer, headerRange, fileName, headerMapping, dataArray[0]); +}; \ No newline at end of file diff --git a/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx b/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx index 96f150ee3..60bfdacfd 100644 --- a/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx +++ b/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx @@ -308,7 +308,6 @@ export const FileUploaderItem = forwardRef< {children} </div> <button - type="button" className={cn( "absolute", "!w-1/5 z-50", diff --git a/packages/common/business_components/src/ui/map/Gis.js b/packages/common/business_components/src/ui/map/Gis.js index 5b4344b57..f45fe4e12 100644 --- a/packages/common/business_components/src/ui/map/Gis.js +++ b/packages/common/business_components/src/ui/map/Gis.js @@ -223,7 +223,6 @@ function Gis({ isOpen , gisMaps, isSearchModalOpen, treeData = [], isSearch = fa {isSearch && ( <div className="absolute right-8 top-[305px] z-20"> <button - type="button" onClick={() => setIsSearchModalOpen(true)} className="overflow-hidden w-[40px] h-[40px] bg-white border border-[#9aa7b8] diff --git a/packages/common/business_components/src/ui/map/GisContent.js b/packages/common/business_components/src/ui/map/GisContent.js index a8ac408e8..a8595efb0 100644 --- a/packages/common/business_components/src/ui/map/GisContent.js +++ b/packages/common/business_components/src/ui/map/GisContent.js @@ -60,7 +60,6 @@ export default function GisContent({ edit = false, onFeatureSelect, isSearch, se {isSearch && ( <div className="absolute right-8 top-[254px] z-20"> <button - type="button" onClick={() => setIsSearchModalOpen(true)} className="overflow-hidden w-[40px] h-[40px] bg-white border border-[#9aa7b8] diff --git a/packages/common/business_components/src/ui/map/GisTab.js b/packages/common/business_components/src/ui/map/GisTab.js index 27dd36e2b..57d8a48e8 100644 --- a/packages/common/business_components/src/ui/map/GisTab.js +++ b/packages/common/business_components/src/ui/map/GisTab.js @@ -20,7 +20,6 @@ // <TabsTrigger value="layers" className="flex-1 h-10">레이어</TabsTrigger> // {/* {isSearch && ( // <button -// type="button" // onClick={() => setIsSearchModalOpen(true)} // className="h-10 w-10 flex items-center justify-center px-0" // >