diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx index d5ebba35f..789b74ab9 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -87,8 +87,8 @@ export default function Home() { return ( <> -
-
+
+
<SearchDiv> <SearchFormLeft> @@ -100,8 +100,6 @@ export default function Home() { throw new Error("Function not implemented."); }} /> - {/* <div className='w-4/5 grid grid-cols-12 gap-1 mx-4'> - </div> */} </SearchFormLeft> <SearchFormRight> <Button className="mr-4 rounded-lg">조회</Button> @@ -111,13 +109,12 @@ export default function Home() { body={<BdstReg></BdstReg>} bodyClass="sm:max-w-7xl" /> - {/* <Button className='mr-4 rounded-lg' onClick={()=>bdstRegModal('ㅁ',divTest())}>신규등록</Button> */} </SearchFormRight> - {/* <div className='w-1/5 flex items-center justify-end'> - </div> */} </SearchDiv> </div> - <div className="colsapn-1"> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-4"> <ListDiv> <UiTable tableData={bdstTable || []} @@ -131,16 +128,18 @@ export default function Home() { </UiTable> </ListDiv> </div> - <div className="colsapn-1 max-h-full ovreflow-y-scroll"> + <div className="col-span-2 max-h-full ovreflow-y-scroll"> <ListDiv> <ScrollArea> <RainRegForm - rainForm={rainForm || null} + rainForm={rainForm || undefined} isModal={false} ></RainRegForm> </ScrollArea> </ListDiv> </div> + + </div> </ContentsDiv> </> diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index dc92e0863..3d1250119 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -1,7 +1,7 @@ import { getFectch } from "@/components/lib/api"; // Description: 공통코드 -type selectArray = { +export type selectArray = { text: string; val: string | number; }; @@ -44,9 +44,18 @@ export const rainFcltCd = [ { val: "10", text: "확인불가" }, ]; +export const chBuCd = [ + { val: "1", text: "증축" }, + { val: "2", text: "개축" }, + { val: "3", text: "재축" }, +] + + + export type comCodeState = { code: { isInit: boolean; + chBuCd:selectArray[] rainFcltCd: selectArray[]; bdstUsgCd: selectArray[]; cityCd: selectArray[]; @@ -89,6 +98,7 @@ export const comCodeStateExport: comCodeState = { isInit: false, rainFcltCd: rainFcltCd, bdstUsgCd: bdstUsgCd, + chBuCd:chBuCd, cityCd: [], sggCd: [], yn:yn @@ -126,6 +136,7 @@ export const codeActionExport: (set: any) => comCodeActions = (set: any) => { }, })); }, + divCityCd: async(cd: number) => { set((state: comCodeState) => ({ code: { diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx index 20cf4cdb6..ffa920f39 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx @@ -1,4 +1,5 @@ import { getFectch } from "@/components/lib/api"; +import type { RainyBuilding } from "../rainReg"; type TableUpperProps = { id: string; @@ -18,24 +19,30 @@ type TableUpperProps = { { id: "archChgArea", title: "면적", upName: "upChangeRe", upSequnce: 3 }, ]; -const bdstBase: bdstType[] = []; +const bdstBase: RainyBuilding[] = []; + + export type bdstFulType = bdstState & bdstActions; export type bdstState = { bdst: { - bdstBase: bdstType[]; + bdstBase: RainyBuilding[]; moUpHeadList:TableUpperProps[] }; }; type bdstActions = { - findBdst: (val: string) => Promise<void>; + findBdst: (sggCd:string, searchTxt:string) => void ; }; - + const findBdstInfo = async(sggCd:string, searchTxt:string)=>{ + return await getFectch('wr', `/reuseFc/building/${sggCd}`+(searchTxt?`/${searchTxt}`:'')) + + } + export const bdstStateExport: bdstState = { bdst: { bdstBase: bdstBase, // Updated to match the array type @@ -47,24 +54,25 @@ export const bdstActionsExport: (set: any) => bdstActions = ( set: any ) => { return { - findBdst: async(val:string) =>{ - try { - console.log(" val ", val); - // (val!=='' ?"/"+val:'') - const res = await getFectch('wr', "/reuseFc/building/42" +(val!=='' ?"/"+val:'')); - console.log("res ", res) - // 여기서 상태 업데이트 - return set((state: bdstState) => ({ - bdst: { - ...state.bdst, - bdstBase:res, + + findBdst: async(sggCd:string, searchTxt:string) =>{ + try{ + + const bdst = await findBdstInfo(sggCd, searchTxt); + return set((state:bdstState) =>({ + ...state, + bdst:{ + ...state.bdst, + bdstBase:bdst + } + + })) + }catch(error1){ + console.log("error ", error1) + + }finally{ + } - })); - } catch (error) { - console.log('error', error); - } finally { - console.log('finally'); - } }, }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index 9268edcb5..2e06ebe8a 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -1,27 +1,119 @@ +import type { selectArray } from "@/app/store/common/code"; import { getFectch, postFectch, putFectch } from "@/components/lib/api"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + + + + +export const rainZod = +{ ctpvCd: z.number(), + sggCd: z.number(), + bdstNm: z.string(), + daddr: z.string(), + frstArchPrmsnDt: z.date(), + archArea: z.number(), + bdstInfoPk: z.number().nullish() , + lawTrgtYn: z.string().nullish(), + bdstUsgCd: z.number(), + bdstRuseFcltPk: z.number().nullish(), + bdstInfoFk: z.number().nullish(), + operMngCd: z.number().nullish(), + anlOperCst: z.number().nullish(), + instlCmptnDt: z.date(), + instlCst: z.number(), + instlCstSprtYn: z.string(), + instlCstSprtAmt: z.number(), + grntchBdstCertYn: z.string(), + grntchBdstCertNo: z.string(), + grntchBdstCertGrd: z.string(), + grntchBdstCertYr: z.string(), + bdstReuseFcltFk:z.number().nullish(), + pntfColKnd: z.string(), + pntfColArea: z.number(), + dtfcltCpct:z.number().nullish(), + filtrTrtmfctCpct: z.number(), + filtrTrtmfctYn: z.string(), + filtrTrtmfctPrs: z.string(), + annRnwtQty:z.number().nullish(), + oilqMeasMthd:z.string().nullish(), + + chgBuilding: z.array( + z.object({ + archChgPrmsnDt: z.date().nullish(), + archChgArea: z.number().nullish(), + bdstChgNm: z.string().nullish(), + }) + ).default([]), // + + } + + +export const rainDefZod= { + instlCmptnDt: new Date(), + instlCst: 0, + pntfColKnd: "", + pntfColArea: 0, + filtrTrtmfctYn: "Y", + filtrTrtmfctCpct: 0, + filtrTrtmfctPrs: "", + instlCstSprtYn: "", + instlCstSprtAmt: 0, + grntchBdstCertYn: "", + grntchBdstCertYr: "", + grntchBdstCertNo: "", + grntchBdstCertGrd: "", +} + + +export const bdstDefZod={ + ctpvCd: 0, // 시도 + sggCd: 0, // 시군구 + daddr: '', // 위치 + bdstUsgCd: 0, // 건축물용도 + frstArchPrmsnDt: new Date(), // 최초건축허가일 + archArea: 0, // 건축면적 + lawTrgtYn: '', // 법적의무대상여부 + bdstNm: '', + + bdstChgnm:'', + archChgPrmsnDt: new Date(), // 건축변경 허가일시 + archChgArea: 0, // 변경 면적 +} + + +export type chgBuilding={ + bdstInfoFk: number, + archChgPrmsnDt: Date, + archChgArea: number, + bdstChgNm: string +} + export type RainyBuilding = { - ctpvCd: string; - sggCd: string; + ctpvCd: number; + sggCd: number; bdstNm: string; daddr: string; - frstArchPrmsnDt: string; + frstArchPrmsnDt: Date; archArea: string; - archChgArea: string; + archChgArea: number; bdstInfoPk: number; reuseBuilding: reuseBuilding[]; + chgBuilding:chgBuilding[] }; export type reuseBuilding = { lawTrgtYn: string|undefined; - bdstUsgCd: string|undefined; + bdstUsgCd: number|undefined; bdstRuseFcltPk: number; bdstInfoFk: number; operMngCd: number; anlOperCst: number; - instlCmptnDt: Date; + instlCmptnDt: Date|undefined; instlCst: number|undefined; - archChgPrmsnDt: string; + //archChgPrmsnDt: string; instlCstSprtYn: string|undefined; instlCstSprtAmt: number|undefined; grntchBdstCertYn: string|undefined; @@ -65,11 +157,56 @@ export const upHeadList: TableUpperProps[] = [ const rainRes: RainyBuilding[] = []; -export type selectArray = { - text: string; - val: string; + + const regRainForm:RainyBuilding = { + ctpvCd: 0, + sggCd: 0, + bdstNm: "", + daddr: "", + frstArchPrmsnDt:new Date(), + archArea: "", + archChgArea: 0, + bdstInfoPk: 0, + reuseBuilding: [{ + rainyObj: { + bdstReuseFcltFk: 0, + pntfColKnd: undefined, + pntfColArea: undefined, + dtfcltCpct: 0, + filtrTrtmfctCpct: undefined, + filtrTrtmfctYn: undefined, + filtrTrtmfctPrs: undefined, + annRnwtQty: 0, + oilqMeasMthd: undefined + }, + lawTrgtYn: undefined, + bdstUsgCd: undefined, + bdstRuseFcltPk: 0, + bdstInfoFk: 0, + operMngCd: 0, + anlOperCst: 0, + instlCmptnDt: undefined, + instlCst: undefined, + // archChgPrmsnDt: "", + instlCstSprtYn: undefined, + instlCstSprtAmt: undefined, + grntchBdstCertYn: undefined, + grntchBdstCertNo: undefined, + grntchBdstCertGrd: undefined, + grntchBdstCertYr: undefined + }], + //추가됨 + chgBuilding:[{ + bdstInfoFk: 0, + archChgPrmsnDt: new Date(), + archChgArea: 0, + bdstChgNm: "" + + }] }; + + export const selectClass = "w-full h-full text-2xl"; const selectYN = [ { text: "Y", val: "1" }, @@ -81,6 +218,8 @@ export type rainFacState = { upHeadList: TableUpperProps[]; selectYN: selectArray[]; rainRes: RainyBuilding[]; + regRainForm:RainyBuilding, + }; }; type rainFacSActions = { @@ -98,9 +237,19 @@ export const rainFacStateExport: rainFacState = { rainRes: rainRes, upHeadList: upHeadList, selectYN: selectYN, + regRainForm:regRainForm, + }, }; +const findBdstInfo = async(sggCd:string, searchTxt:string)=>{ + return await getFectch('wr', `/reuseFc/building/${sggCd}/${searchTxt}`) + +} + +const initFetch = async () => { + return await getFectch("wr", "/reuseFc/rainyInfoList/1/20/41"); +}; export const rainFacActionsExport: (set: any) => rainFacSActions = ( set: any ) => { @@ -108,7 +257,7 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( init: async () => { try { // 파라이터 수정 통합관리자 =0, 시관리자=시코드, 시군구 관리자= 시군구 코드 를 세번째 파라미터로 지정 / 건축물 서치가 있을경우 4번째 파라미터로 던지기 즉 1/20/42(서울시)/영현빌딩 이런식으로) - const rainRes = await getFectch("wr", "/reuseFc/rainyInfoList/1/20/42"); + const rainRes = await initFetch(); // 여기서 상태 업데이트 return set((state: rainFacState) => ({ ...state, @@ -125,7 +274,7 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( } }, dataInit: () => - set(async (state: rainFacState) => { + set((state: rainFacState) => { console.log(" state ", state.rain); return { rain: { @@ -134,30 +283,51 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( }, }; }), + rainReg: async (data: RainyBuilding) => { + try { + const res = await postFectch("/reuseFc/rainyInfo", data); + const rainRes = await initFetch(); + set((state: rainFacState) => ({ + ...state, + rain: { + ...state.rain, + rainRes: rainRes, + isInit: false, + }, + })); + } catch (e) { + console.log("e", e); + alert("등록 오류입니다."); + } finally { + alert("등록이 완료되었습니다."); + } + }, + rainUpdate: async (data: RainyBuilding) => { + try { + console.log("data ", data) + const res = await putFectch("/reuseFc/rainyInfo", data); + console.log('rainUpdate', res); + if(res.ok){ + alert(" 수정이 완료되었습니다.") + } + + const rainRes = await initFetch(); + set((state: rainFacState) => ({ + ...state, + rain: { + ...state.rain, + rainRes: rainRes, + isInit: false, + }, + })); + } catch (e) { + console.log("e", e); + alert("업데이트 오류입니다."); + } finally { + } + } + }} + + + - rainReg: (data: RainyBuilding) => - set(async () => { - try { - const res = postFectch("/reuseFc/rainyInfo", data); - console.log("res", res); - } catch (e) { - console.log("e", e); - alert("등록이 오류입니다."); - } finally { - alert("등록이 완료되었습니다."); - } - }), - rainUpdate: (data: RainyBuilding) => - set(async () => { - try { - const res = putFectch("/reuseFc/rainyInfo", data); - console.log("res", res); - } catch (e) { - console.log("e", e); - alert("업데이트 오류입니다."); - } finally { - alert("업데이트가 완료되었습니다."); - } - }), - }; -}; diff --git a/apps/wr/components/lib/api/index.ts b/apps/wr/components/lib/api/index.ts index ff690f411..0f7e6c0ee 100644 --- a/apps/wr/components/lib/api/index.ts +++ b/apps/wr/components/lib/api/index.ts @@ -1,6 +1,6 @@ //8880 -import { DEV_URL_COMMON, DEV_URL_WR } from "../config/env"; +import { DEV_URL_COMMON, DEV_URL_WR } from "../config/"; @@ -36,6 +36,7 @@ export const postFectch = async (url: string, params: any) => { export const putFectch = async (url: string, params: any) => { + const response = await fetch(DEV_URL_WR+url, { method: "PUT", headers: { diff --git a/apps/wr/components/lib/config/api.ts b/apps/wr/components/lib/config/api.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/wr/components/lib/config/env.ts b/apps/wr/components/lib/config/env.ts deleted file mode 100644 index 24352c2f3..000000000 --- a/apps/wr/components/lib/config/env.ts +++ /dev/null @@ -1,11 +0,0 @@ - -const LOCAL_PORT = "3000"; -const DEV_PORT = "8880"; - - -const DEV_PORT_COMMON = "8881"; // common - -export const LOCAL_URL_WR = `http://localhost:${LOCAL_PORT}/api/v1`; -export const DEV_URL_WR = `http://192.168.1.193:${DEV_PORT}/api/v1`; - -export const DEV_URL_COMMON = `http:///192.168.1.193:${DEV_PORT_COMMON}/api/v1`; diff --git a/apps/wr/components/lib/config/index.ts b/apps/wr/components/lib/config/index.ts index e7f55b887..24352c2f3 100644 --- a/apps/wr/components/lib/config/index.ts +++ b/apps/wr/components/lib/config/index.ts @@ -1 +1,11 @@ -export * from './env'; \ No newline at end of file + +const LOCAL_PORT = "3000"; +const DEV_PORT = "8880"; + + +const DEV_PORT_COMMON = "8881"; // common + +export const LOCAL_URL_WR = `http://localhost:${LOCAL_PORT}/api/v1`; +export const DEV_URL_WR = `http://192.168.1.193:${DEV_PORT}/api/v1`; + +export const DEV_URL_COMMON = `http:///192.168.1.193:${DEV_PORT_COMMON}/api/v1`; diff --git a/apps/wr/components/lib/func/commom.ts b/apps/wr/components/lib/func/commom.ts new file mode 100644 index 000000000..0351f2fc9 --- /dev/null +++ b/apps/wr/components/lib/func/commom.ts @@ -0,0 +1,16 @@ +import type { selectArray } from "@/app/store/common/code"; + + + + + +export const getCity = (val: string, sggCd: selectArray[]) => { + const data = sggCd + .filter((item) => String(item.val).substring(0, 2) === val) + .map((item) => ({ + val: String(item.val), + text: item.text // 한국어 텍스트 + })); + return data + + }; diff --git a/apps/wr/components/lib/type/zod/fcltReg/controlZod.ts b/apps/wr/components/lib/type/zod/fcltReg/controlZod.ts deleted file mode 100644 index 796167e91..000000000 --- a/apps/wr/components/lib/type/zod/fcltReg/controlZod.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { z } from "zod"; - - -export const rainZod = -{ ctpvCd: z.string(), - sggCd: z.string(), - bdstNm: z.string(), - daddr: z.string(), - frstArchPrmsnDt: z.date(), - archArea: z.number(), - archChgArea: z.string(), - bdstInfoPk: z.number(), - - lawTrgtYn: z.string(), - bdstUsgCd: z.string(), - bdstRuseFcltPk: z.number(), - bdstInfoFk: z.number(), - operMngCd: z.number(), - anlOperCst: z.number(), - instlCmptnDt: z.date(), - instlCst: z.number(), - archChgPrmsnDt: z.string(), - instlCstSprtYn: z.string(), - instlCstSprtAmt: z.number(), - grntchBdstCertYn: z.string(), - grntchBdstCertNo: z.string(), - grntchBdstCertGrd: z.string(), - grntchBdstCertYr: z.string(), - - bdstReuseFcltFk:z.number(), - pntfColKnd: z.string(), - pntfColArea: z.number(), - dtfcltCpct:z.number(), - filtrTrtmfctCpct: z.number(), - filtrTrtmfctYn: z.string(), - filtrTrtmfctPrs: z.string(), - annRnwtQty:z.number(), - oilqMeasMthd:z.string(), -} - -// = { -// instlCmptnDt: z.date(), -// instlCst: z.number(), -// pntfColKnd: z.string(), -// pntfColArea: z.number(), -// filtrTrtmfctPrs: z.string(), -// filtrTrtmfctYn: z.string(), -// filtrTrtmfctCpct: z.number(), -// instlCstSprtYn: z.string(), -// instlCstSprtAmt: z.number(), -// grntchCstSprtYn: z.string(), -// // grntchCstSprtCst: z.string(), -// grntchBdstCertYn: z.string(), -// grntchBdstCertYr: z.string(), -// grntchBdstCertNo: z.string(), -// grntchBdstCertGrd: z.string(), -// } - -export const rainDefZod= { - instlCmptnDt: new Date(), - instlCst: 0, - pntfColKnd: "", - pntfColArea: 0, - filtrTrtmfctYn: "Y", - filtrTrtmfctCpct: 0, - filtrTrtmfctPrs: "", - instlCstSprtYn: "", - instlCstSprtAmt: 0, - grntchCstSprtYn: "", - // grntchCstSprtCst: "", - grntchBdstCertYn: "", - grntchBdstCertYr: "", - grntchBdstCertNo: "", - grntchBdstCertGrd: "", -} -// export const bdstZod ={ -// ctpvCd: z.string(), // 시도 -// sggCd: z.string(), // 시군구 -// daddr: z.string(), // 위치 -// bdstUsgCd: z.string(), // 건축물용도 -// frstArchPrmsnDt: z.date(), // 최초건축허가일 -// archArea: z.number(), // 건축면적 -// lawTrgtYn: z.string(), // 법적의무대상여부 -// // archChgPrmsnDt: z.string(), // 건축변경 허가일시 -// // archChgArea: z.number(), // 변경 면적 -// bdstNm: z.string(), -// } - -export const bdstDefZod={ - ctpvCd: '', // 시도 - sggCd: '', // 시군구 - daddr: '', // 위치 - bdstUsgCd: '', // 건축물용도 - frstArchPrmsnDt: new Date(), // 최초건축허가일 - archArea: 0, // 건축면적 - lawTrgtYn: '', // 법적의무대상여부 - // archChgPrmsnDt: '', // 건축변경 허가일시 - // archChgArea: 0, // 변경 면적 - bdstNm: '', -} - diff --git a/apps/wr/components/ui/form/fcltReg/bdstReg/component.tsx b/apps/wr/components/ui/form/fcltReg/bdstReg/component.tsx index 7445af885..277c1f0cf 100644 --- a/apps/wr/components/ui/form/fcltReg/bdstReg/component.tsx +++ b/apps/wr/components/ui/form/fcltReg/bdstReg/component.tsx @@ -1,24 +1,28 @@ import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { FormField, FormUi, SelectBox } from "@common/business_components"; +import type { selectArray } from "@/app/store/common/code"; +import { selectClass, type RainyBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { getCity } from "@/components/lib/func/commom"; +import type { objSearchType } from "@/components/ui/modal/bdstReg/component"; +import { FormField, FormUi, DatePicker, SelectBox } from "@common/business_components"; import { Button, Input } from "@common/components"; +import { useEffect, useRef, useState } from "react"; import { useFieldArray } from "react-hook-form"; -export default function BdstReg(form: any ) { +export default function BdstReg({ form, ud }: { form: any, ud: RainyBuilding }) { const { code } = useWrStore((state) => { return state; }); const { fields, append, remove } = useFieldArray({ - control: form.control, - name: "history" + name: "chgBuilding", + control: form?.control, // Provide a fallback to avoid errors }); const plusHist = () => { append({ - bdstNm: '', - daddr: '', - bdstUsgCd: '' + bdstNm: "", + daddr: "", + bdstUsgCd: "", }); }; @@ -26,193 +30,260 @@ export default function BdstReg(form: any ) { if (fields.length > 0) { remove(fields.length - 1); } - }; + }; + const [selectSgg, setSelectSgg] = useState<selectArray[] | undefined>() + const [objSearch, setObjSearch] = useState<objSearchType>({sgg:"",city:""}); + + const getSelCity = (val: string) => { + const data= getCity(val,code.sggCd) + setSelectSgg(data); + const sgg =form.getValues('sggCd') + + setObjSearch({ city:val , sgg:''}) + + }; + + const getSgg = (val: string | number) => { + + const sgg =form.getValues('sggCd') + setObjSearch({...objSearch,sgg: val!=''?String(val):sgg }) + }; + + // useEffect(()=>{ + // console.log("18", ud); + // console.log("form", form.getValues()); + // const city =form?.getValues('ctpvCd') + // const sgg =form?.getValues('sggCd') + // console.log('city ㄴㄴㄴ ', city) + // console.log('sgg ', sgg) + // if(city>0 && sgg>0){ + // console.log(' if city ', city) + + // // form?.setValue('ctpvCd' , city) + // //form?.setValue('sggCd' , sgg) + // //setSelectSgg(getCity(city,code.sggCd)) + // } + // },[ud]) + useEffect(()=>{ + const city =form.getValues('ctpvCd') + const sgg =form.getValues('sggCd') + setObjSearch({city:city , sgg:sgg }) + + }, [selectSgg]) + + useEffect(() => { + const subscription = form.form?.watch((value) => { + console.log('vale', value) + }); + + return () => subscription?.unsubscribe(); + }, [form]); + + + const safeDate = (value: any): Date | undefined => { + const date = new Date(value); + return isNaN(date.getTime()) ? undefined : date; + }; + + return ( <> - - <h1 className="bg-gray-400 text-xl text-center border-2 p-2 mt-4 pl-6"> - 건축물 시설 정보 - </h1> - <div className="grid grid-cols-6 gap-2 mt-4"> - <div className="col-span-3"> - <FormField - control={form.control} - name="ctpvCd" - render={({ field }) => ( - <FormUi label="시도"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.cityCd} - onSelectValue={(val) => { - field.onChange(val); - }} - value={field.value} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3"> - <FormField - control={form.control} - name="sggCd" - render={({ field }) => ( - <FormUi label="시군구"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.sggCd } - onSelectValue={(val) => { - field.onChange(val); - }} - value={field.value} - /> - </FormUi> - )} - /> - </div> + <h1 className="bg-gray-400 text-xl text-center border-2 p-2 mt-4 pl-6"> + 건축물 시설 정보 + </h1> + <div className="grid grid-cols-6 gap-2 mt-4"> + <div className="col-span-3"> + <FormField + control={form.control} + name="ctpvCd" + render={({ field }) => ( + <FormUi label="시도"> + <SelectBox + className="col-span-3 " + label={""} + selectClass={selectClass} + selectArray={code.cityCd} + + onSelectValue={(val)=>{ + getSelCity(String(val)) + field.onChange(Number(val) ); + } + + } + value={field.value} + + /> + </FormUi> + )} + /> </div> - <div className="grid grid-cols-6 gap-2 mt-4 "> - <div className="col-span-2"> - <FormField - control={form.control} - name="bdstNm" - render={({ field }) => ( - <FormUi label="건축물명"> - <Input - className="" - placeholder="1,000,000" - type="text" - {...field} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="daddr" - render={({ field }) => ( - <FormUi label="위치"> - <Input - className="" - placeholder="1,000,000" - type="search" - {...field} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="bdstUsgCd" - render={({ field }) => ( - <FormUi label="건축물용도"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.bdstUsgCd} - onSelectValue={(val) => { - field.onChange(val); - }} - value={field.value} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="frstArchPrmsnDt" - render={({ field }) => ( - <FormUi label="최초건축허가일"> - <Input + <div className="col-span-3"> + <FormField + control={form.control} + name="sggCd" + render={({ field }) => ( + <FormUi label="시군구"> + <SelectBox + className="col-span-3" + label={""} + selectClass={selectClass} + selectArray={selectSgg? selectSgg:code.sggCd || []} + onSelectValue={(val) =>{ + getSgg(val) + field.onChange(Number(val)) + }} + value={field.value} + + /> + </FormUi> + )} + /> + </div> + </div> + <div className="grid grid-cols-6 gap-2 mt-4 "> + <div className="col-span-2"> + <FormField + control={form.control} + name="bdstNm" + render={({ field }) => ( + <FormUi label="건축물명"> + <Input className="" - type="date" - onChange={(e) => - field.onChange( - e.target.value ? new Date(e.target.value) : undefined - ) - } - value={ - field.value ? field?.value.toISOString().split("T")[0] : "" - } - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="archArea" - render={({ field }) => ( - <FormUi label="건축면적(m³)"> - <Input - className="" - placeholder="1,000,000" - type="number" - {... field} - onChange={(e) => { - const value = e.target.value; - field.onChange(value === '' ? '' : Number(value)); - }} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-2"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="법정의무대상여부"> - <SelectBox - className={""} - selectClass={selectClass} - label={""} - selectArray={code.yn} - onSelectValue={(val) => { - field.onChange(val); - }} - value={field.value} - /> - </FormUi> - )} - /> - </div> + placeholder="1,000,000" + type="text" + {...field} + /> + </FormUi> + )} + /> </div> - <h1 className="bg-gray-400 text-xl text-center border-2 p-2 mt-4"> - 중축, 개축, 증축 - </h1> - <div className="flex justify-end gap-2"> - <Button className="rounded-lg" onClick={plusHist}>이력추가</Button> - <Button className="rounded-lg bg-red-500 text-white" onClick={removeLastItem}>삭제</Button> + <div className="col-span-2"> + <FormField + control={form.control} + name="daddr" + render={({ field }) => ( + <FormUi label="위치"> + <Input + className="" + placeholder="1,000,000" + type="search" + {...field} + /> + </FormUi> + )} + /> </div> + <div className="col-span-2"> + <FormField + control={form.control} + name="bdstUsgCd" + render={({ field }) => ( + <FormUi label="건축물용도"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.bdstUsgCd} + onSelectValue={(val) => { + field.onChange(Number(val)); + }} + value={field.value} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-2"> + <FormField + control={form.control} + name="frstArchPrmsnDt" + render={({ field }) => ( + <FormUi label="최초건축허가일"> + <DatePicker + mode={"single"} + field={{ + value: new Date(field.value), + onChange: (date: Date | undefined) => + field.onChange(date), + }} + selectClass={selectClass} + ></DatePicker> + + </FormUi> + )} + /> + </div> + <div className="col-span-2"> + <FormField + control={form.control} + name="archArea" + render={({ field }) => ( + <FormUi label="건축면적(m³)"> + <Input + className="" + placeholder="1,000,000" + type="number" + {...field} + onChange={(e) => { + const value = e.target.value; + field.onChange(value === "" ? "" : Number(value)); + }} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-2"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="법정의무대상여부"> + <SelectBox + className={""} + selectClass={selectClass} + label={""} + selectArray={code.yn} + onSelectValue={(val) => { + field.onChange(val); + }} + value={field.value} + /> + </FormUi> + )} + /> + </div> + </div> + <h1 className="bg-gray-400 text-xl text-center border-2 p-2 mt-4"> + 중축, 개축, 재축 + </h1> + <div className="flex justify-end gap-2"> + <Button type="button" className="rounded-lg" onClick={plusHist}> + 이력추가 + </Button> + <Button + type="button" + className="rounded-lg bg-red-500 text-white" + onClick={removeLastItem} + > + 삭제 + </Button> + </div> {fields.map((field, index) => ( <div key={field.id} className="grid grid-cols-6 gap-2 mt-4"> <div className="col-span-2"> <FormField control={form.control} - name={`history.${index}.bdstNm`} + name={`chgBuilding.${index}.bdstChgNm`} render={({ field }) => ( <FormUi label="구분"> <SelectBox className={""} selectClass={selectClass} label={""} - selectArray={code.cityCd} + selectArray={code.chBuCd} onSelectValue={(val) => { field.onChange(val); }} @@ -225,15 +296,18 @@ export default function BdstReg(form: any ) { <div className="col-span-2"> <FormField control={form.control} - name={`history.${index}.daddr`} + name={`chgBuilding.${index}.archChgPrmsnDt`} render={({ field }) => ( <FormUi label="허가일"> - <Input - className="" - placeholder="1,000,000" - type="search" - {...field} - /> + <DatePicker + mode={"single"} + field={{ + value: safeDate(field.value) || new Date(), + onChange: (date: Date | undefined) => + field.onChange(date), + }} + selectClass={selectClass} + ></DatePicker> </FormUi> )} /> @@ -241,7 +315,7 @@ export default function BdstReg(form: any ) { <div className="col-span-2"> <FormField control={form.control} - name={`history.${index}.bdstUsgCd`} + name={`chgBuilding.${index}.archChgArea`} render={({ field }) => ( <FormUi label="면적"> <Input diff --git a/apps/wr/components/ui/form/fcltReg/rainReg/component.tsx b/apps/wr/components/ui/form/fcltReg/rainReg/component.tsx index a8591ff4a..bf57cc97e 100644 --- a/apps/wr/components/ui/form/fcltReg/rainReg/component.tsx +++ b/apps/wr/components/ui/form/fcltReg/rainReg/component.tsx @@ -3,31 +3,25 @@ import { useWrStore } from "@/app/store"; import { selectClass, - type RainyBuilding, -} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { bdstDefZod, rainDefZod, rainZod, -} from "@/components/lib/type/zod/fcltReg/controlZod"; + type RainyBuilding, +} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { DatePicker, FormUi } from "@common/business_components"; import { Form, FormField, SelectBox } from "@common/business_components/ui"; import { Button, Input } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; +import { useEffect, useState } from "react"; +import { useForm, type UseFormReturn } from "react-hook-form"; import { z } from "zod"; import BdstReg from "../bdstReg/component"; -export function RainRegForm({ - rainForm, - isModal, -}: { - rainForm: RainyBuilding | undefined; - isModal: boolean; -}) { - const formSchema = z.object(rainZod); - const form = useForm<z.infer<typeof formSchema>>({ +export const formToObj = ( + isModal: boolean, + formSchema: z.ZodObject<any, "strip", z.ZodTypeAny, any, any> +) => { + return useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), defaultValues: isModal ? { @@ -38,14 +32,26 @@ export function RainRegForm({ ...rainDefZod, }, }); +}; - const { code, rainReg, rainUpdate, init } = useWrStore( - (state) => state - ); +const formSchema = z.object(rainZod); +export type RainFormType = UseFormReturn<z.infer<typeof formSchema>>; + +export function RainRegForm({ + rainForm, + isModal, +}: { + rainForm: RainyBuilding; + isModal: boolean; +}) { + + const form = formToObj(isModal, formSchema); + const { code, rainReg, rainUpdate, rain } = useWrStore((state) => state); const { rainFcltCd } = code; useEffect(() => { - // console.log( " data ", data) + console.log(rainForm); + if (rainForm != null) { const data = rainForm; @@ -55,101 +61,109 @@ export function RainRegForm({ String(data?.reuseBuilding?.at(0)?.rainyObj?.pntfColKnd ?? "") ); let formData; + + if (data?.reuseBuilding?.at(0)) { const rb = data.reuseBuilding?.at(0); formData = { + ...data, ...rb?.rainyObj, ...data.reuseBuilding?.at(0), pntfColKnd: selectedOption ? String(selectedOption.val) : undefined, + frstArchPrmsnDt: new Date(data.frstArchPrmsnDt) }; form.reset(formData); } else { formData = { - ctpvCd: data.ctpvCd, - sggCd: data.sggCd, - bdstNm: data.bdstNm, - daddr: data.daddr, - frstArchPrmsnDt: new Date(data.frstArchPrmsnDt), + ...data }; + form.reset(formData); } } - }, [rainForm, rainFcltCd]); + }, [rainForm]); // form 값이 변경될 때마다 로그 출력 useEffect(() => { - const subscription = form.watch((value) => {}); + const subscription = form.watch((value) => { + }); return () => subscription.unsubscribe(); }, [form]); - function onSubmit(values: z.infer<typeof formSchema>) { - console.log("valuesd"); - console.log(values); - let regRainForm = { ...rainForm }; - const raw = values; - const rawVal = { - ctpvCd: raw?.ctpvCd, + const objToForm = (raw: z.infer<typeof formSchema>) => { + let regRainForm: RainyBuilding; + + // 1. 기본 정보 정리 + const obj = !rainForm ? rain.regRainForm : rainForm; + regRainForm = { + ...obj, + ctpvCd: raw?.ctpvCd , sggCd: raw?.sggCd, daddr: raw?.daddr, bdstNm: raw?.bdstNm, - frstArchPrmsnDt: raw?.frstArchPrmsnDt.toISOString(), + frstArchPrmsnDt: raw?.frstArchPrmsnDt , archArea: raw?.archArea + "", + // archChgArea: raw?.archChgArea || 0, // Ensure archChgArea is always a string }; - // 1. 기본 정보 정리 - if (isModal) - regRainForm = {...rawVal}; - if(regRainForm?.reuseBuilding?.at(0)?.rainyObj){ - const rainObj = regRainForm?.reuseBuilding?.at(0)?.rainyObj; - regRainForm.reuseBuilding[0].rainyObj = { - ...rainObj, - pntfColKnd: raw.pntfColKnd || rainObj?.pntfColKnd, - pntfColArea: raw.pntfColArea || rainObj?.pntfColArea, - filtrTrtmfctCpct: raw.filtrTrtmfctCpct || rainObj?.filtrTrtmfctCpct, - filtrTrtmfctYn: raw.filtrTrtmfctYn || rainObj?.filtrTrtmfctYn, - filtrTrtmfctPrs: raw.filtrTrtmfctPrs || rainObj?.filtrTrtmfctPrs, - oilqMeasMthd: rainObj?.oilqMeasMthd, - }; - regRainForm.reuseBuilding[0] = { - ...rainForm?.reuseBuilding[0], - instlCmptnDt: raw.instlCmptnDt, - instlCst: raw.instlCst || rainForm?.reuseBuilding[0]?.instlCst, - instlCstSprtYn: - raw.instlCstSprtYn || rainForm?.reuseBuilding[0]?.instlCstSprtYn, - instlCstSprtAmt: - raw.instlCstSprtAmt || rainForm?.reuseBuilding[0]?.instlCstSprtAmt, - grntchBdstCertYn: - raw.grntchBdstCertYn || rainForm?.reuseBuilding[0]?.grntchBdstCertYn, - grntchBdstCertYr: - raw.grntchBdstCertYr || rainForm?.reuseBuilding[0]?.grntchBdstCertYr, - grntchBdstCertNo: - raw.grntchBdstCertNo || rainForm?.reuseBuilding[0]?.grntchBdstCertNo, - grntchBdstCertGrd: - raw.grntchBdstCertGrd || rainForm?.reuseBuilding[0]?.grntchBdstCertGrd, - bdstUsgCd: raw.bdstUsgCd || rainForm?.reuseBuilding[0]?.bdstUsgCd, - lawTrgtYn: raw.lawTrgtYn || rainForm?.reuseBuilding[0]?.lawTrgtYn, - }; + const rainObj = regRainForm?.reuseBuilding?.at(0)?.rainyObj; + + if (!regRainForm.reuseBuilding) { + regRainForm.reuseBuilding = []; } + regRainForm.reuseBuilding[0] = { + ...rainForm?.reuseBuilding?.at(0), + + instlCmptnDt: raw.instlCmptnDt, + instlCst: raw.instlCst || rainForm?.reuseBuilding?.at(0)?.instlCst, + instlCstSprtYn: + raw.instlCstSprtYn || rainForm?.reuseBuilding?.at(0)?.instlCstSprtYn, + instlCstSprtAmt: + raw.instlCstSprtAmt || rainForm?.reuseBuilding?.at(0)?.instlCstSprtAmt, + grntchBdstCertYn: + raw.grntchBdstCertYn || rainForm?.reuseBuilding?.at(0)?.grntchBdstCertYn, + grntchBdstCertYr: + raw.grntchBdstCertYr || rainForm?.reuseBuilding?.at(0)?.grntchBdstCertYr, + grntchBdstCertNo: + raw.grntchBdstCertNo || rainForm?.reuseBuilding?.at(0)?.grntchBdstCertNo, + grntchBdstCertGrd: + raw.grntchBdstCertGrd || rainForm?.reuseBuilding?.at(0)?.grntchBdstCertGrd, + bdstUsgCd: raw.bdstUsgCd || rainForm?.reuseBuilding?.at(0)?.bdstUsgCd, + lawTrgtYn: raw.lawTrgtYn || rainForm?.reuseBuilding?.at(0)?.lawTrgtYn, + } + regRainForm.reuseBuilding[0].rainyObj = { + ...rainObj, + pntfColKnd: raw.pntfColKnd || rainObj?.pntfColKnd, + pntfColArea: raw.pntfColArea || rainObj?.pntfColArea, + filtrTrtmfctCpct: raw.filtrTrtmfctCpct || rainObj?.filtrTrtmfctCpct, + filtrTrtmfctYn: raw.filtrTrtmfctYn || rainObj?.filtrTrtmfctYn, + filtrTrtmfctPrs: raw.filtrTrtmfctPrs || rainObj?.filtrTrtmfctPrs, + }; if (isModal) { - rainReg(raw); + rainReg(regRainForm); } else { - rainUpdate(raw); + console.log(" regRainForm ", regRainForm) + rainUpdate(regRainForm); } + }; - init(); + function onSubmit(values: z.infer<typeof formSchema>) { + console.log(values); + objToForm(values); } useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); + + return ( <div className=""> <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)}> - {/* <div className="flex justify-between items-center mx-3"> */} <div> <div className="grid grid-cols-12"> <h1 className="pl-3 text-xl col-span-10"> @@ -160,7 +174,7 @@ export function RainRegForm({ </Button> </div> </div> - {isModal ? <BdstReg form={form}></BdstReg> : <></>} + {isModal&&rainForm!=undefined ? <BdstReg form={form} ud={rainForm}/> : <></>} {isModal ? ( <h1 className="pl-3 text-xl col-span-10 mt-4 "> ○ 빗물이용시설 운영정보{" "} @@ -179,20 +193,6 @@ export function RainRegForm({ name="instlCmptnDt" render={({ field }) => ( <FormUi label="설치완료일"> - {/* <Input - className="" - type="date" - onChange={(e) => - field.onChange( - e.target.value ? new Date(e.target.value) : undefined - ) - } - value={ - field.value - ? field?.value.toISOString().split("T")[0] - : "" - } - /> */} <DatePicker mode={"single"} field={{ @@ -394,7 +394,7 @@ export function RainRegForm({ <div className="col-span-3 pl-6"> <FormField control={form.control} - name="grntchCstSprtYn" + name="grntchBdstCertYn" render={({ field }) => ( <FormUi label="인증여부"> <SelectBox diff --git a/apps/wr/components/ui/modal/bdstReg/component.tsx b/apps/wr/components/ui/modal/bdstReg/component.tsx index aba76c7f9..e0a389182 100644 --- a/apps/wr/components/ui/modal/bdstReg/component.tsx +++ b/apps/wr/components/ui/modal/bdstReg/component.tsx @@ -3,41 +3,38 @@ import { headMakeColSpan } from "@/app/ruseFcltMng/fcltReg/rainReg/page"; import { useWrStore } from "@/app/store"; import { selectClass, - type bdstType, - type RainyInfoResponse, - type selectArray, + type RainyBuilding, } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { ScrollArea, SearchInput, SelectBox, UiTable } from "@common/business_components"; import { Button, Input, Label } from "@common/components"; import { useEffect, useState } from "react"; import { RainRegForm } from "../../form/fcltReg/rainReg/component"; +import { getCityCd, type selectArray } from "@/app/store/common/code"; +import { getCity } from "@/components/lib/func/commom"; + +export type objSearchType = { + sgg: string|number; + city: string|number; + }; + export function BdstReg() { - const { rain, code, bdst, findBdst } = useWrStore((state) => { + const { rain, code, bdst,findBdst } = useWrStore((state) => { return state; }); - type objSearchType = { - sgg: string; - city: string; - }; - const [bdstTable, setbdstTable] = useState<RainyInfoResponse[]>(); - const [rainBdstForm, setRainBdstForm] = useState<RainyInfoResponse | undefined>(); - const { bdstObj, rainRuseObj } = rain; - const [selectSgg, setSelectSgg] = useState<selectArray[] | undefined>() + const [bdstTable, setbdstTable] = useState<RainyBuilding[]>(); + const [rainBdstForm, setRainBdstForm] = useState<RainyBuilding>({} as RainyBuilding); const [searchTxt, setSearchTxt] = useState<string>() + const [selectSgg, setSelectSgg] = useState<selectArray[] | undefined>() const [objSearch, setObjSearch] = useState<objSearchType>({sgg:"",city:""}); - const getCity = (val: string) => { - const data = code.sggCd - .filter((item) => String(item.val).substring(0, 2) === val) - .map((item) => ({ - val: String(item.val), - text: item.text // 한국어 텍스트 - })); + const getSelCity = (val: string) => { + const data= getCity(val,code.sggCd) setSelectSgg(data); setObjSearch({ city:val , sgg:''}) + }; const getSgg = (val: string | number) => { @@ -46,20 +43,19 @@ export function BdstReg() { }; const searchBdst=()=>{ - if(objSearch.sgg===""){ + if(objSearch.city===""){ alert('시도조건은 필수 입니다.') + return } + let data =objSearch.city; + if(objSearch.sgg !=="" ){ + data = objSearch.sgg + } + + findBdst(String(data), searchTxt || "") + } - - - useEffect(()=>{ - - findBdst(searchTxt || "") - },[searchTxt]) - - - useEffect(() => { if (code.sggCd.length > 0) { const table = bdst?.bdstBase?.map((item) => { @@ -77,14 +73,14 @@ export function BdstReg() { } }, [code, bdst]); + const tableClick: (val: number | undefined) => void = (val) => { - + if(val!==undefined && bdst?.bdstBase.length>0){ const data =bdst?.bdstBase[val] - setRainBdstForm([data]); - } - } - + setRainBdstForm(data); + } + } const nodeList = headMakeColSpan(bdst.moUpHeadList); return ( <> @@ -94,7 +90,7 @@ export function BdstReg() { label={"시도"} selectClass={selectClass} selectArray={code.cityCd} - onSelectValue={getCity} + onSelectValue={getSelCity} > {" "} </SelectBox> @@ -108,7 +104,7 @@ export function BdstReg() { {" "} </SelectBox> <Label className="w-20 text-base text-gray-600 mt-4 text-right">건축물명</Label> - <Input className="w-full h-full text-2xl col-span-2 col-start-8" type="text" value={searchTxt} onChange={(e) => setSearchTxt(e.target.value)}/> + <Input className="w-full h-full text-2xl col-span-2 col-start-8" type="text" value={searchTxt || ''} onChange={(e) => setSearchTxt(e.target.value)}/> {/* <SearchInput className="col-span-3 col-start-8" label="건물명" @@ -135,7 +131,7 @@ export function BdstReg() { <div className="border-t border-gray-300 my-4"></div> <ScrollArea className="h-[60vh]"> <div> - <RainRegForm rainForm={rainBdstForm ||undefined} isModal={true}></RainRegForm> + <RainRegForm rainForm={rainBdstForm } isModal={true}/> </div> </ScrollArea> </div>