diff --git a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx index 248a45484..d661e60d6 100644 --- a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx @@ -1,847 +1,942 @@ "use client"; import { useWrStore } from "@/app/store"; +import {DmdCoReqSchema, type DmdCoReqType, type DmdMatTableType} from "@/app/store/matDmd/coMatRvw/type"; import { formH1Class, formTableName } from "@/components/lib/class/comClass"; -import { getCity } from "@/components/lib/func/commom"; +import { getCity, tableData, yearOptions } from "@/components/lib/func/commom"; import { CmpttnModal } from "@/components/ui/modal/coMat/cmpttnModal"; import { CoMatModal } from "@/components/ui/modal/coMat/coMatModal"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui"; +import { + ContentsDiv, + Form, + FormField, + FormUi, + ScrollArea, + SearchDiv, + SearchFormLeft, + SearchFormRight, + SearchInput, + SelectBox, + Title, + UiModal, + UiTable, + type SelectDataType, +} from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, DatePicker, Input, Label } from "@common/components/ui"; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@common/components/ui/tooltip"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@common/components/ui/tooltip"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { useFieldArray, useForm } from "react-hook-form"; +import toast, { Toaster } from "react-hot-toast"; import { z } from "zod"; - +import moment from "moment"; export default function CoMatRvw() { - const { code, coRvw, } = useWrStore((state) => state); - const { coRvwHeadList, } = coRvw; - const [fromDate, setFromDate] = useState(new Date()); - const [toDate, setToDate] = useState(new Date()); - const [selectSgg, setSelectSgg] = useState() - const [objSearch, setObjSearch] = useState({ sgg: "", city: "" }); - const [isPrcsMo, setIsPrcsMo] = useState<{ - isModal: boolean; - }>({ isModal: false }); - const [isTrfMo, setIsTrfMo] = useState<{ - isModal: boolean; - }>({ isModal: false, }); - const [isCmpttnMo, setIsCmpttnMo] = useState<{ - isModal: boolean; - }>({ isModal: false, }); + const { code, coRvw ,coMatRvwInit} = useWrStore((state) => state); +const {coMatRvwRes} = coRvw + + const initRef = useRef(false); + const { coRvwHeadList } = coRvw; + const [dmdMatData, setDmdMtaData] = useState([]); + const [selectSgg, setSelectSgg] = useState(); + const [objSearch, setObjSearch] = useState({ + sgg: "", + city: "", + }); + const [isPrcsMo, setIsPrcsMo] = useState<{ + isModal: boolean; + }>({ isModal: false }); + const [isTrfMo, setIsTrfMo] = useState<{ + isModal: boolean; + }>({ isModal: false }); + const [isCmpttnMo, setIsCmpttnMo] = useState<{ + isModal: boolean; + }>({ isModal: false }); + const [fromDate, setFromDate] = useState( + String(new Date().getFullYear()) + ); + const [toDate, setToDate] = useState( + String(new Date().getFullYear()) + ); + const [selectData, setSelectData] = useState({} as DmdCoReqType) + const form = useForm>({ + resolver: zodResolver(DmdCoReqSchema), + }) + + const TableCellClick = (index:number) =>{ + console.log(coMatRvwRes ) + if(coMatRvwRes && coMatRvwRes[index]){ + + console.log(dmdMatData[index]) - const schema = z.object({ - fcltCpct: z.number().optional(), - }); + setSelectData(coMatRvwRes[index] ) + } - const form = useForm>({ - resolver: zodResolver(schema), - defaultValues: { - fcltCpct: 0, - } - }); + } - const getSelCity = (val: string | number) => { - const cityValue = String(val); // Ensure val is treated as a string - const data = getCity(cityValue, code.sggCd); - setSelectSgg(data); - setObjSearch({ city: cityValue, sgg: '' }); - }; + useEffect(()=>{ + if(coMatRvwRes){ + const data =coMatRvwRes.map((item)=>{ + return ({ + ...item, + regDt: moment(item.regDt).format('YYYY-MM-DD') , + state:'' + })}) + setDmdMtaData(tableData(data,{code}) ) + } + },[coMatRvwRes]) - const getSgg = (val: string | number) => { - console.log(val); - setObjSearch({ ...objSearch, sgg: String(val) }) - }; + const getSelCity = (val: string | number) => { + const cityValue = String(val); // Ensure val is treated as a string + const data = getCity(cityValue, code.sggCd); + setSelectSgg(data); + setObjSearch({ city: cityValue, sgg: "" }); + }; - useEffect(() => { - if (fromDate > toDate) { - const newFromDate = new Date(toDate); - newFromDate.setDate(toDate.getDate() - 1); - setFromDate(newFromDate); - } - }, [toDate]); + const getSgg = (val: string | number) => { + setObjSearch({ ...objSearch, sgg: String(val) }); + }; - return ( - <> - -
-
- - <SearchDiv> - <SearchFormLeft> - <div className="col-span-8 flex flex-row"> - <SelectBox - className="col-span-2 w-1/3 h-full text-2xl" - label="시도" - selectClass={""} - selectArray={code.cityCd || []} - onSelectValue={getSelCity} - /> - <SelectBox - className="col-span-2 w-1/3 h-full text-2xl ml-4" - label="시군구" - selectClass={""} - selectArray={selectSgg || []} - onSelectValue={getSgg} - /> - <div className="col-span-5 w-full"> - <div className="flex flex-row items-center"> - <Label className="text-xl text-gray-600 ml-4 mr-4">수요신청년도</Label> - <div className="flex flex-row"> - <DatePicker mode={'single'} - selected={fromDate} - onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }} /> - <span className="ml-2 mr-2">~</span> - <DatePicker mode={'single'} - selected={toDate} - onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} /> - </div> - </div> - </div> - <SearchInput - className={"text-2xl"} - label="회사명" - textValue={""} - setText={(e) => { - }} - /> - </div> - </SearchFormLeft> - <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 - size={"sm"} - onClick={(e) => { }} - > - 조회 - </Button> - </div> - </div> - </SearchFormRight> - </SearchDiv> + +useEffect(() =>{ + if(!initRef.current){ + coMatRvwInit(1,13,'11',fromDate,toDate) + initRef.current = true; + } + +},[coMatRvwInit,initRef,fromDate,toDate]) + + +useEffect(() =>{ + if(selectData){ + console.log(selectData) + form.reset(selectData) + } + +},[selectData,form ] ) + return ( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4"> + <div className="col-span-4"> + <Title title={"수요매칭검토"} /> + <SearchDiv> + <SearchFormLeft> + <div className="col-span-10 flex flex-row"> + <SelectBox + className="col-span-2 w-1/3 h-full text-2xl" + label="시도" + selectClass={""} + selectArray={code.cityCd || []} + onSelectValue={getSelCity} + /> + <SelectBox + className="col-span-2 w-1/3 h-full text-2xl ml-4" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <div className="col-span-7 w-full"> + <div className="flex flex-row items-center"> + <Label className="text-xl text-gray-600 mx-6"> + 하수 재이용년도 + </Label> + <SelectBox + className="h-full w-32 text-2xl" + label="" + selectClass={""} + selectArray={yearOptions} + value={fromDate} + onSelectValue={(val: string | number) => + setFromDate(String(val)) + } + /> + <span className="mx-6">~</span> + <SelectBox + className="h-full w-32 text-2xl" + label="" + selectClass={""} + selectArray={yearOptions} + value={toDate} + onSelectValue={(val: string | number) => + setToDate(String(val)) + } + /> + <div className="col-span-2 ml-6"> + <SearchInput + className={"text-2xl"} + label="회사명" + textValue={""} + setText={(e) => {}} + /> + </div> </div> + </div> </div> + </SearchFormLeft> + <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 + size={"sm"} + onClick={(e) => { + if (fromDate && toDate) { + const fromNum = Number(fromDate); + const toNum = Number(toDate); + if (fromNum > toNum) { + toast.error( + "시작년도가 종료년도 이후로 설정할 수 없습니다." + ); + } else { + } + } + }} + > + 조회 + </Button> + </div> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> - <div className="grid grid-cols-6 gap-4"> - <div className="col-span-6"> - <ListDiv> - <UiTable - headName={"수요매칭검토현황"} - tableData={[]} - children={undefined} - headlist={coRvwHeadList} - pageSize={20} - total={100000} - cellClick={(index: number | undefined, headId: string) => { + <div className="grid grid-cols-6 g ap-4"> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={"수요매칭검토현황"} + tableData={dmdMatData||[]} + headlist={coRvwHeadList} + pageSize={20} + total={100000} + cellClick={(index:number|undefined, headId:string) =>{ + if(index !==undefined&& index>=0){ + + TableCellClick(index) + } + } } + onPageChange={() => {}} + ></UiTable> + </ListDiv> + <hr /> + <ScrollArea className="h-[49vh]"> + <ListDiv> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label"> + 수요신청 상세현황 + </h3> + <Form {...form}> + <div className="grid grid-cols-12 gap-4 ml-4 mr-4"> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="regDt" + render={({ field }) => ( + <FormUi label="요구시기"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={ moment(field.value).format('YYYY-MM-DD') ?? ""} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="dmndQty" + render={({ field }) => ( + <FormUi label="요구수량(M3/d)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="useUsgCd" + render={({ field }) => ( + <FormUi label="사용용도"> + <Input + placeholder="" + type="text" + step="0.1" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ''} + readOnly + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="wntUntprc" + render={({ field }) => ( + <FormUi label="희망단가(원/m3)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-12 w-full"> + <h1 className={formH1Class}>요구수질</h1> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="grssClfg" + render={({ field }) => ( + <FormUi label="총대장균군수 (개/100ml)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="combResdch" + render={({ field }) => ( + <FormUi label="결합잔류염소(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="trbt" + render={({ field }) => ( + <FormUi label="탁도(NTU)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="blgcOxygDmndQnt" + render={({ field }) => ( + <FormUi label="생물학적 산소요구량(BOD)(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="smll" + render={({ field }) => ( + <FormUi label="냄새"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="crmty" + render={({ field }) => ( + <FormUi label="색도(도)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="tn" + render={({ field }) => ( + <FormUi label="총질소 (T-N)(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="tph" + render={({ field }) => ( + <FormUi label="총인(T-P)(mg/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="ph" + render={({ field }) => ( + <FormUi label="수소이온농도(pH)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="clIonQnt" + render={({ field }) => ( + <FormUi label="염화물(mgCL/L)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="cdtnv" + render={({ field }) => ( + <FormUi label="전기전도도(㎲/cm)"> + <Input + placeholder="" + type="number" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="rmrk" + render={({ field }) => ( + <FormUi label="비고"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-12 w-full"> + <h1 className={formH1Class}>공급처 후보지</h1> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="후보지1"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(String(e.target.value)); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="후보지2"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="후보지3"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + </div> + </Form> + <hr className="mt-8" /> + <Form {...form}> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label"> + 표준공사비 산정 + </h3> + <div className="flex items-center mx-3 mb-3"> + <h1 className="">처리시설 표준공사비 산정</h1> + + <Button size={"sm"} onClick={(e) => {}}> + 계산 + </Button> + <Button size={"sm"} onClick={(e) => {}}> + 저장 + </Button> + </div> + <div className="grid grid-cols-12 gap-4 ml-4 mr-4"> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="용도"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="요구수량(M3/d)"> + <Input + placeholder="" + type="number" + step="0.1" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <Label className=""> + 용도에 따른 처리공정 + <i + className="diveicon di-search" + onClick={(e) => setIsPrcsMo({ isModal: true })} + /> + </Label> + + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label=""> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value || ""} + className="mt-2" + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="처리시설 용량(요구수량 * 365일)"> + <Input + placeholder="" + type="number" + step="0.001" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <div className="flex items-center justify-between"> + <Label>처리시설용량에 따른 공사비(백만원)</Label> + <Button + size={"sm"} + onClick={(e) => setIsCmpttnMo({ isModal: true })} + className="bg-none" + > + 공사비 산정표 보기 + </Button> + </div> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label=""> + <Input + placeholder="" + type="number" + step="0.001" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <div className="flex items-center justify-between"> + <Label>시설부대경비 요율(%)</Label> + <Button + size={"sm"} + onClick={(e) => setIsTrfMo({ isModal: true })} + > + 요율표 보기 + </Button> + </div> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label=""> + <Input + placeholder="" + type="number" + step="0.01" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + + <div className="col-span-3 mt-4"> + <Label> + 총사업비 (백만원) + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <i className="diveicon di-search" /> + </TooltipTrigger> + <TooltipContent> + <div className="font-bold mb-1 text-xl"> + 총사업비 계산방법 + </div> + <div className="text-lg"> + 하수처리수 재이용시설 총 사업비 = + 공사비+시설부대경비{" "} + </div> + </TooltipContent> + </Tooltip> + </TooltipProvider> + </Label> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label=""> + <Input + placeholder="" + className="mt-2" + type="number" + step="0.01" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <div className="flex items-center justify-between"> + <Label>공급처 선정</Label> + <Button + size={"sm"} + onClick={(e) => {}} + className="bg-none" + > + 후보지 조회 + </Button> + </div> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label=""> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + + <div className="col-span-4 mt-4"> + <div> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="공급관로 표준공사비(백만원)"> + <Input + placeholder="" + type="text" + step="0.001" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="mt-4"> + <Label>관로 표준공사비 산정 프로그램</Label> + <Button + size={"sm"} + onClick={(e) => {}} + className="bg-none" + > + 다운로드 + </Button> + </div> + <div className="col-span-4 mt-4 mb-3"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <Label className="text-xl"> + 처리시설 + 공급관로 총사업비(백만원) + <FormUi label=""> + <Input + placeholder="" + type="text" + step="0.001" + onChange={(e) => { + field.onChange(Number(e.target.value)); }} - onPageChange={() => { }} - ></UiTable> - <hr /> - <ScrollArea className="h-[49vh]"> - <h3 className="mt-4 ml-2 text-2xl font-medium text-label">수요신청 상세현황</h3> - <Form {...form}> - <div className="grid grid-cols-12 gap-4 ml-4 mr-4"> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="요구시기"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="요구수량(M3/d)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="사용용도"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="희망단가(원/m3)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-12 w-full"> - <h1 className={formH1Class}>요구수질</h1> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="총대장균군수 (개/100ml)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="결합잔류염소(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="탁도(NTU)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="생물학적 산소요구량(BOD)(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="냄새"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="색도(도)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="총질소 (T-N)(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="총인(T-P)(mg/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="수소이온농도(pH)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="염화물(mgCL/L)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="전기전도도(㎲/cm)"> - <Input - placeholder="" - type="number" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="비고"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-12 w-full"> - <h1 className={formH1Class}>공급처 후보지</h1> - </div> - <div className="col-span-4 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="후보지1"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(String(e.target.value)); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="후보지2"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-4 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="후보지3"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(e.target.value); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - </div> - </Form> - <hr className="mt-8" /> - <Form {...form}> - <h3 className="mt-4 ml-2 text-2xl font-medium text-label">표준공사비 산정</h3> - <div className="flex items-center mx-3 mb-3"> - <h1 className="">처리시설 표준공사비 산정</h1> - - <Button - size={"sm"} - onClick={(e) => { }} - > - 계산 - </Button> - <Button - size={"sm"} - onClick={(e) => { }} - > - 저장 - </Button> - - </div> - <div className="grid grid-cols-12 gap-4 ml-4 mr-4"> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="용도"> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="요구수량(M3/d)"> - <Input - placeholder="" - type="number" - step="0.1" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <Label className="">용도에 따른 처리공정<i className="diveicon di-search" onClick={(e) => setIsPrcsMo({ isModal: true })} /></Label> - - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label=""> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value || ""} - className="mt-2" - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="처리시설 용량(요구수량 * 365일)"> - <Input - placeholder="" - type="number" - step="0.001" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <div className="flex items-center justify-between"> - <Label>처리시설용량에 따른 공사비(백만원)</Label> - <Button - size={"sm"} - onClick={(e) => setIsCmpttnMo({ isModal: true })} - className="bg-none" - > - 공사비 산정표 보기 - </Button> - </div> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label=""> - <Input - placeholder="" - type="number" - step="0.001" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <div className="flex items-center justify-between"> - <Label>시설부대경비 요율(%)</Label> - <Button - size={"sm"} - onClick={(e) => setIsTrfMo({ isModal: true })} - > - 요율표 보기 - </Button> - </div> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label=""> - <Input - placeholder="" - type="number" - step="0.01" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-3 mt-4"> - <Label>총사업비 (백만원) - <TooltipProvider> - <Tooltip> - <TooltipTrigger asChild> - <i className="diveicon di-search" /> - </TooltipTrigger> - <TooltipContent> - <div className="font-bold mb-1 text-xl">총사업비 계산방법</div> - <div className="text-lg">하수처리수 재이용시설 총 사업비 = 공사비+시설부대경비 </div> - </TooltipContent> - </Tooltip> - </TooltipProvider> - </Label> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label=""> - <Input - placeholder="" - className="mt-2" - type="number" - step="0.01" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <div className="flex items-center justify-between"> - <Label>공급처 선정</Label> - <Button - size={"sm"} - onClick={(e) => { }} - className="bg-none" - > - 후보지 조회 - </Button> - </div> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label=""> - <Input - placeholder="" - type="text" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? ""} - /> - </FormUi> - )} - /> - </div> - - <div className="col-span-4 mt-4"> - <div> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <FormUi label="공급관로 표준공사비(백만원)"> - <Input - placeholder="" - type="text" - step="0.001" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="mt-4"> - <Label>관로 표준공사비 산정 프로그램</Label> - <Button - size={"sm"} - onClick={(e) => { }} - className="bg-none" - > - 다운로드 - </Button> - </div> - <div className="col-span-4 mt-4 mb-3"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <Label className="text-xl">처리시설 + 공급관로 총사업비(백만원) - <FormUi label=""> - <Input - placeholder="" - type="text" - step="0.001" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - readOnly={true} - value={field.value ?? 0} - /> - </FormUi> - </Label> - )} - /> - </div> - </div> - </div> - </Form> - </ScrollArea> - </ListDiv> + readOnly={true} + value={field.value ?? 0} + /> + </FormUi> + </Label> + )} + /> </div> - <UiModal - body={ - <> - <UiTable - headName={"용도에 따른 처리공정"} - tableData={[ - { usage: "청소", process: "총인처리시설 + 염소소독" }, - { usage: "화장실용수", process: "총인처리시설 + 염소소독" }, - { usage: "세척", process: "총인처리시설 + UV소독" }, - { usage: "살수", process: "총인처리시설 + UV소독" }, - { usage: "조경", process: "총인처리시설 + UV소독" }, - { usage: "농업", process: "총인처리시설 + UV소독" }, - { usage: "하천", process: "총인처리시설 + UV소독" }, - { usage: "지하수", process: "전처리시설 + RO" }, - { usage: "공업용수", process: "전처리시설 + RO" }, - - ]} - headlist={[ - { id: "usage", title: "용도" }, - { id: "process", title: "단위공정" } - ]} - pageSize={0} - total={0} - cellClick={() => { }} - onPageChange={() => { }} - /> - </> - } - bodyClass="w-[25vw] max-w-none h-[60vh]" - open={isPrcsMo.isModal} - onOpenChange={(open) => { - setIsPrcsMo({ isModal: open }); - }} - /> - <UiModal - body={ - <CoMatModal data={[]}></CoMatModal> - } - bodyClass="w-[40vw] max-w-none h-[70vh]" - open={isTrfMo.isModal} - onOpenChange={(open) => { - setIsTrfMo({ isModal: open }); - }} - /> - <UiModal - body={ - <CmpttnModal data={[]}></CmpttnModal> - } - bodyClass="w-[70vw] max-w-none h-[50vh]" - open={isCmpttnMo.isModal} - onOpenChange={(open) => { - setIsCmpttnMo({ isModal: open }); - }} - /> + </div> </div> - </ContentsDiv > - </> - ) -} \ No newline at end of file + </Form> + </ListDiv> + </ScrollArea> + </div> + <UiModal + body={ + <> + <UiTable + headName={"용도에 따른 처리공정"} + tableData={[ + { usage: "청소", process: "총인처리시설 + 염소소독" }, + { usage: "화장실용수", process: "총인처리시설 + 염소소독" }, + { usage: "세척", process: "총인처리시설 + UV소독" }, + { usage: "살수", process: "총인처리시설 + UV소독" }, + { usage: "조경", process: "총인처리시설 + UV소독" }, + { usage: "농업", process: "총인처리시설 + UV소독" }, + { usage: "하천", process: "총인처리시설 + UV소독" }, + { usage: "지하수", process: "전처리시설 + RO" }, + { usage: "공업용수", process: "전처리시설 + RO" }, + ]} + headlist={[ + { id: "usage", title: "용도" }, + { id: "process", title: "단위공정" }, + ]} + pageSize={0} + total={0} + cellClick={() => {}} + onPageChange={() => {}} + /> + </> + } + bodyClass="w-[25vw] max-w-none h-[60vh]" + open={isPrcsMo.isModal} + onOpenChange={(open) => { + setIsPrcsMo({ isModal: open }); + }} + /> + <UiModal + body={<CoMatModal data={[]}></CoMatModal>} + bodyClass="w-[40vw] max-w-none h-[70vh]" + open={isTrfMo.isModal} + onOpenChange={(open) => { + setIsTrfMo({ isModal: open }); + }} + /> + <UiModal + body={<CmpttnModal data={[]}></CmpttnModal>} + bodyClass="w-[70vw] max-w-none h-[50vh]" + open={isCmpttnMo.isModal} + onOpenChange={(open) => { + setIsCmpttnMo({ isModal: open }); + }} + /> + </div> + </ContentsDiv> + <Toaster position="top-center" /> + </> + ); +} diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx index b7e6c6c8e..19c17f9c9 100644 --- a/apps/wr/app/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -2,11 +2,14 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; -import type { customCoSttnBdst } from "@/app/store/matDmd/coSttn"; -import { excelDownload, getCity, getCityOrSgg, tableData } from "@/components/lib/func/commom"; +import { + excelDownload, + getCity, + getCityOrSgg, + tableData, +} from "@/components/lib/func/commom"; import { ContentsDiv, - SearchBaseForm, SearchDiv, SearchFormLeft, SearchFormRight, @@ -15,58 +18,79 @@ import { Title, UiModal, UiTable, - type ReturnType, - type SelectDataType + type SelectDataType, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, DatePicker, Label } from "@common/components/ui"; -import { useCallback, useEffect, useRef, useState } from "react"; -import SdmInsertForm, { type DemandCompType } from "@common/business_components/ui/sdmInsertForm"; +import { Button } from "@common/components/ui"; +import { useCallback, useEffect, useState } from "react"; +import SdmInsertForm, { +} from "@common/business_components/ui/sdmInsertForm"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; - +import toast, { Toaster } from "react-hot-toast"; +import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; +import { fetchType, getFetch } from "@/components/lib/api"; +import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; export default function CoSttn() { - const [bdstTable, setBdstTable] = useState<customCoSttnBdst[]>(); - + const { + code, + coSttn, + coSttnInit, + coSttnSearch, + getDemandCompList, + regDemandCompany, + updateDemandCompany, + coSttnTxtSearch, + checkDemand, + demandCompList, + dmdIsSucees + } = useWrStore((state) => state); + const [bdstTable, setBdstTable] = useState<DemandCompType[]>(); const [pageNation, setPageNation] = useState(1); - const { code, coSttn, coSttnInit, coSttnSearch, getDemandCompList, regDemandCompany, demandCompList } = useWrStore((state) => state); const { coSttnRes } = coSttn; - const [isDmdModal, setIsDmdModal] = useState<{ isMoal: boolean, data: DemandCompType }>({ isMoal: false, data: {} as DemandCompType }) - const [fromDate, setFromDate] = useState<Date>(new Date()); - const [toDate, setToDate] = useState<Date>(new Date()); - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() - const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); - const ref = useRef<ReturnType>({} as ReturnType); - const codeData = getCityOrSgg(ref); + const [isDmdModal, setIsDmdModal] = useState<{ + isMoal: boolean; + data: DemandCompType; + }>({ isMoal: false, data: {} as DemandCompType }); + const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(); + const [objSearch, setObjSearch] = useState<objSearchType>({ + sgg: "", + city: "", + }); + + const [seartchTxt, setSearchTxt] = useState<string>(); + const [upadateData, setUpdateData] = useState<DemandCompType>(); + const getSelCity = (val: string | number) => { const cityValue = String(val); // Ensure val is treated as a string const data = getCity(cityValue, code.sggCd); setSelectSgg(data); - setObjSearch({ city: cityValue, sgg: '' }); + setObjSearch({ city: cityValue, sgg: "" }); }; const getSgg = (val: string | number) => { - console.log(val); - setObjSearch({ ...objSearch, sgg: String(val) }) + setObjSearch({ ...objSearch, sgg: String(val) }); }; useEffect(() => { if (!coSttn.isInit) { - coSttnInit(codeData ?? "0"); + + coSttnInit("1", "13", "0"); } }, [coSttn.isInit, coSttnInit]); useEffect(() => { - if (coSttnRes.length > 0 && code.cityCd.length > 0) { + if (coSttnRes?.length > 0 && code.cityCd.length > 0) { const data = tableData(coSttnRes, { code }); - const chData = data - .map((item: any) => ({ - ...item - })) + const chData = data.map((item: any) => ({ + ...item, + })); // .filter((item: any) => item !== undefined); setBdstTable(chData); + } else if (coSttnRes.length == 0) { + setBdstTable([]); } }, [coSttnRes]); @@ -84,10 +108,20 @@ export default function CoSttn() { }, [coSttn.excelList]); const excelClick = useCallback(() => { - console.log("??") - coSttnSearch("마인드원", 1); - }, [coSttnSearch]); + const con = objSearch.sgg ? objSearch.sgg : objSearch.city; + if (con) coSttnSearch("1", "10000", String(con)); + }, [coSttnSearch, objSearch.city, objSearch.sgg]); + const searchClick = () => { + const con = objSearch.sgg ? objSearch.sgg : objSearch.city; + if (con) { + if (seartchTxt && seartchTxt?.length > 0) { + coSttnTxtSearch("1", "13", String(con), seartchTxt ?? ""); + } else { + coSttnSearch("1", "13", String(con)); + } + } + }; return ( <> <ContentsDiv> @@ -111,42 +145,27 @@ export default function CoSttn() { selectArray={selectSgg || []} onSelectValue={getSgg} /> - <div className="col-span-5 w-auto"> - <div className="flex flex-row items-center"> - <Label className="text-xl text-gray-600">수요신청년도</Label> - <div className="flex flex-row w-1/4"> - <DatePicker mode={'single'} - selected={fromDate} - onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }} /> - <span>~</span> - <DatePicker mode={'single'} - selected={toDate} - onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} /> - </div> - </div> - </div> <SearchInput - className={"text-2xl"} + className={"!text-3xl"} label="회사명" - textValue={""} + textValue={seartchTxt ?? ""} setText={(e) => { + setSearchTxt(e); }} /> </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="flex flex-row space-x-2"> - <Button - size={"sm"} - onClick={(e) => { }} - > + <Button size={"sm"} onClick={searchClick}> 조회 </Button> <Button size={"sm"} className={btnClass} onClick={() => { + + setUpdateData(undefined); setIsDmdModal({ ...isDmdModal, isMoal: true }); }} > @@ -157,6 +176,13 @@ export default function CoSttn() { className={btnClass} onClick={() => { /* 저장 로직 */ + if (!upadateData) { + <ToastFormUi body={"수요처 변경을 원하는 행을 선택해주세요"} title={"수요처관리"}></ToastFormUi>; + }else{ + setIsDmdModal({ + ...isDmdModal, + isMoal: true}) + } }} > 저장 @@ -182,7 +208,9 @@ export default function CoSttn() { headlist={coSttn.coSttHeadList} pageSize={20} total={10000} - cellClick={(index: number | undefined, headId: string) => { }} + cellClick={(index: number | undefined, headId: string) => { + setUpdateData(coSttnRes[index as number]); + }} onPageChange={setPageNation} ></UiTable> </ListDiv> @@ -192,7 +220,7 @@ export default function CoSttn() { bodyClass={"w-[40vw] max-w-none h-[90vh]"} open={isDmdModal.isMoal} onOpenChange={() => { - setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); + setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); }} body={ <SdmInsertForm @@ -202,18 +230,32 @@ export default function CoSttn() { rtnValue={(searchText: string, pageCnt: number) => { getDemandCompList(searchText, pageCnt); }} - rtnInputData={(data) => { - console.log(" rtn data ", data); - regDemandCompany(data as DemandCompType); + rtnInputData={ async(data) => { + if(upadateData?.dmdInfoPk){ + updateDemandCompany(data as DemandCompType) + }else{ + const dmd= await getFetch(fetchType.WR,`/reuseFc/request/${data.dmdInfoPk}`) + if(dmd) { + toast.error(`사업자번호 ${dmd.dmdInfoPk}는 이미 등록되었습니다. 다시등록해주세요`) + return + } + regDemandCompany(data as DemandCompType); + } + if(dmdIsSucees ==='success'){ + toast.success(`수요처 등록 및 수정 완료되었습니다..`) setIsDmdModal({ isMoal: false, data: data as DemandCompType }); + }else{ + toast.error(`수요처 등록 및 수정 에러입니다.`) + } + }} bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"} + updateList={upadateData} ></SdmInsertForm> } ></UiModal> </ContentsDiv> + <Toaster position="top-center" /> </> - - ) - -} \ No newline at end of file + ); +} diff --git a/apps/wr/app/page.tsx b/apps/wr/app/page.tsx index 82607af9e..5e1cd2333 100644 --- a/apps/wr/app/page.tsx +++ b/apps/wr/app/page.tsx @@ -109,11 +109,7 @@ export default function Home() { <div> <h2 className="text-xl font-semibold mb-4">수요처 관리</h2> <div className="grid grid-cols-12 gap-4"> - <div className="col-span-2"> - <Button className="w-full"> - <Link href="matMng/coMng/coReg">수요처 등록</Link> - </Button> - </div> + <div className="col-span-2"> <Button className="w-full"> <Link href="matMng/coMng/coSttn">수요처 관리</Link> diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index a30aec3fe..3c489837d 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -12,20 +12,28 @@ import { import { Button } from "@common/components"; import { useWrStore } from "../../../store"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import ListDiv from "@common/business_components/ui/list_div"; import { tableData } from "@/components/lib/func/commom"; import type { customPbnst, fcBizType, + PbnstRegArrrayType, pubHasuType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { + pbnstRegZod, + pbnstRegArrayZod, + fcBizSchema, +} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; import { PbnstRegModal } from "@/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal"; -import { Toaster } from "react-hot-toast"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; +import toast, { Toaster } from "react-hot-toast"; import { writeRgtrAndMdfr } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg"; +import { useFieldArray, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; export default function PublicReuseFaciltyInsert() { const { @@ -34,11 +42,10 @@ export default function PublicReuseFaciltyInsert() { searchFclts, pubHasuInit, pbnstRegClick, - getSwtrmtFcltNm, pbnstMngData, pbnstRuseFcltUpdate, + pubHasuSearch, pbnstRuseBizUpdate, - getHasuFlow } = useWrStore((state) => state); const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst; const [currentTab, setCurrentTab] = useState<string>("mng"); @@ -48,54 +55,69 @@ export default function PublicReuseFaciltyInsert() { data: pubHasuType; }>({ isModal: false, data: {} as pubHasuType }); + const [indexMng, setIndexMng] = useState<number>(0); + const [indexBiz, setIndexBiz] = useState<number>(0); const [searchTxt, setSearchTxt] = useState<string>(); const [bdstTable, setbdstTable] = useState<pubHasuType[]>(); + const [selectRow, setSelectRow] = useState<pubHasuType>(); + // const form = useForm<z.infer<typeof pbnstRegArrayZod>>({ + // resolver: zodResolver(pbnstRegArrayZod), + // defaultValues: pbnstRegArrayZod.parse([]), + // mode: "onChange", + // }); + const form = useForm<{ + items: z.infer<typeof pbnstRegZod>[]; + }>({ + resolver: zodResolver(z.object({ items: pbnstRegArrayZod })), + defaultValues: { items: pbnstRegArrayZod.parse([]) }, + mode:"onChange" + }); + const { + fields: items, + append, + remove, + } = useFieldArray({ + control: form.control, + name: `items`, + }); useEffect(() => { if (!pbnst.isInit) { pubHasuInit("1", "11"); } }, [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 saveRuseData = async ()=>{ - const data = writeRgtrAndMdfr(pbnst.pbnstMngRegData) - let bizs =[] as fcBizType[] - data.forEach((fclt) =>{ - bizs = [ - ...bizs, - ...fclt.fcBizs - ] - }) + await pbnstRuseFcltUpdate(data); - - await pbnstRuseFcltUpdate(data) - - await pbnstRuseBizUpdate(bizs) - - } - + await pbnstRuseBizUpdate(bizs); + }; useEffect(() => { - if(code.sggCd.length){ - if(searchFclts){ + if (code.sggCd.length) { + if (searchFclts) { setbdstTable(tableData(searchFclts, { code })); - }else if (code.sggCd.length > 0 && pbnstHasuRes.length > 0) { + } else if (code.sggCd.length > 0 && pbnstHasuRes.length > 0) { setbdstTable(tableData(pbnstHasuRes, { code })); } } - }, [code, pbnstHasuRes,searchFclts]); + }, [code, pbnstHasuRes, searchFclts]); const cellClick = (val: number | undefined) => { if (val === undefined) return; const selectRow = pbnstHasuRes?.[val]; + setSelectRow(pbnstHasuRes?.[val]) if (selectRow) { - setIsRuseReg({ ...isRuseReg, data: selectRow }); + //setIsRuseReg({ ...isRuseReg, data: selectRow }); pbnstRegClick(selectRow); - - getHasuFlow(selectRow.gugun, selectRow.bscFctNm) } }; @@ -103,6 +125,51 @@ export default function PublicReuseFaciltyInsert() { setCurrentTab(value); }; + useEffect(() => { + if (pbnst.pbnstRes) { + form.reset({ items: pbnstRegArrayZod.parse(pbnst.pbnstRes) }); + } + }, [pbnst.pbnstRes]); + useEffect(() => { + if (indexMng) { + setIndexBiz(0); + } + }, [indexMng]); + + useEffect(() => { + console.log("form errors:", form.formState.errors); + }, [form.formState.errors]); + + const appendPbnstRuseFclt = useCallback(() => { + if (pbnstRes && pbnstRes.length > 0) { + const lastPbnst = pbnstRes[pbnstRes.length - 1]; + console.log('lastPbnst.swtrmtFcltFk ', lastPbnst) + if(lastPbnst){ + append( + pbnstRegZod.parse({ + pbnstRuseFcltPk: String(lastPbnst.pbnstRuseFcltPk) + String(pbnstRes.length + 1), + ruseUtztnFcltNm: "", + fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(lastPbnst.pbnstRuseFcltPk) + String(pbnstRes.length + 1),cycl:1})] as fcBizType[], + }) + ); + setIsRuseReg({ ...isRuseReg, isModal: true }) + } + } else { + if(selectRow){ + 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,pbnstRes,append,selectRow]) + return ( <> <ContentsDiv> @@ -125,8 +192,8 @@ export default function PublicReuseFaciltyInsert() { size={"sm"} onClick={(e) => { searchTxt && searchTxt?.length > 0 - ? getSwtrmtFcltNm(searchTxt) - : pubHasuInit("1", "11") + ? pubHasuSearch("1", "11", searchTxt) + : pubHasuInit("1", "11"); }} > 조회 @@ -136,12 +203,13 @@ export default function PublicReuseFaciltyInsert() { className="" onClick={() => { pbnstMngData([] as customPbnst[]); - isRuseReg.data.bscFctCd - ? setIsRuseReg({ ...isRuseReg, isModal: true }) - : ToastFormUi({ - body: "하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요", - title: "재이용시설 등록", - }); + if(!selectRow){ + toast.error("하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요") + return + }else{ + appendPbnstRuseFclt() + + } }} > 신규등록 @@ -179,15 +247,34 @@ export default function PublicReuseFaciltyInsert() { <TabsTrigger className="!text-xl" value="buse"> 차수별정보 </TabsTrigger> - <Button size={"sm"} onClick={ saveRuseData}className="!justify-end"> + <Button + size={"sm"} + onClick={form.handleSubmit(onSubmit)} + className="!justify-end" + > 저장 </Button> </TabsList> <TabsContent className="max-h-full" value="mng"> - <PbnstMngForm formType="update" /> + <PbnstMngForm + formType="update" + form={form} + setIndexMng={(index: number) => { + setIndexMng(index); + }} + indexMng={indexMng} + /> </TabsContent> <TabsContent className="max-h-full" value="buse"> - <PbnstBuseForm formType="update" /> + <PbnstBuseForm + formType="update" + form={form} + setIndexBiz={(index: number) => { + setIndexBiz(index); + }} + indexMng={indexMng} + indexBiz={indexBiz} + /> </TabsContent> </Tabs> </ScrollArea> @@ -195,12 +282,14 @@ export default function PublicReuseFaciltyInsert() { <UiModal body={ <PbnstRegModal + form={form} data={isRuseReg.data || ({} as customPbnst)} ></PbnstRegModal> } bodyClass="w-[68vw] max-w-none h-[90vh]" open={isRuseReg.isModal} onOpenChange={(open) => { + remove(form.getValues("items").length - 1) setIsRuseReg({ data: {} as pubHasuType, isModal: open }); }} /> diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index fed0338f0..46ec39658 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -134,6 +134,8 @@ export default function prfmncPrfmncReg() { } const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; setPbnstRuseFcltPk(prfmncRes[index].pbnstRuseFcltPk); + + console.log(' tableData ' ,tableData) setInputData(tableData); } else { setInputData([]); diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index cd506f08a..74c566c03 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -11,6 +11,7 @@ import ListDiv from "@common/business_components/ui/list_div"; import { Button, Label, Table, TableBody, TableHeader } from "@common/components/ui"; import { useEffect, useRef, useState } from "react"; import { headMakeprfmnc } from "../../prfmncReg/chkgdnReg/TableHead"; +import toast, { Toaster } from "react-hot-toast"; @@ -70,7 +71,7 @@ export default function PbnstPrfmncSttn() { const inSubtotal = subTotalObj; const outSubtotal = subTotalObj; - + console.log(' prfList ', prfList) const prfFilter = prfList?.filter((e) => e.ym.slice(0, 4) === year) if (prfList && prfFilter.length > 0) { prfList?.forEach((prfItem) => { @@ -191,7 +192,7 @@ export default function PbnstPrfmncSttn() { fill: element.fill }; return config; - }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; + }, {} as Record<string, { label: string; fill?: string }>) satisfies ChartConfig; setChartConfig(newChartConfig); }, [chartData]); @@ -209,6 +210,7 @@ export default function PbnstPrfmncSttn() { if (rawData) { rawData.forEach((item) => { item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + wshwtr += element.wshwtr; //세척수 coolUswtr += element.coolUswtr; //냉각수 cleanUswtr += element.cleanUswtr; //청소수 @@ -567,7 +569,7 @@ export default function PbnstPrfmncSttn() { <SearchInput className={"text-2xl"} label="시설명" - textValue={swtrmtFcltNm} + textValue={swtrmtFcltNm ?? ""} setText={(e) => { setSwtrmtFcltNm(e); }} /> @@ -586,10 +588,10 @@ export default function PbnstPrfmncSttn() { const fromNum = Number(fromDate); const toNum = Number(toDate); if (fromNum > toNum) { - alert("시작년도가 종료년도 이후로 설정할 수 없습니다."); + toast.error("시작년도가 종료년도 이후로 설정할 수 없습니다."); } else { if (toNum - fromNum > 5) { - alert("최대 5년까지 선택 가능합니다."); + toast.error("최대 5년까지 선택 가능합니다."); } else { tableHeadMaker(fromNum, toNum); @@ -678,6 +680,7 @@ export default function PbnstPrfmncSttn() { </div> </div> </ContentsDiv> + <Toaster position="top-center"/> </> ) } diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index 3f6da6dec..6caabcb5c 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -102,6 +102,12 @@ const dmdUszCd = [ ] +const ruseMngMtd = [ + { val: "자체운영", text: "자체운영" }, + { val: "공기업", text: "공기업" }, + { val: "민간(대행)", text: "민간(대행)" }, +] + const pplQulity = [ { val: "도복장강관", text: "도복장강관" }, @@ -154,6 +160,7 @@ export type comCodeState = { RNB:string, HTB:string } + ruseMngMtd:SelectDataType[] }; }; @@ -292,6 +299,7 @@ export const comCodeStateExport: comCodeState = { yn: yn, dmdUszCd:dmdUszCd, buildingType:buildingType, + ruseMngMtd:ruseMngMtd, }, }; diff --git a/apps/wr/app/store/common/searchCode/index.ts b/apps/wr/app/store/common/searchCode/index.ts index 96bac028a..97d5faa76 100644 --- a/apps/wr/app/store/common/searchCode/index.ts +++ b/apps/wr/app/store/common/searchCode/index.ts @@ -1,16 +1,22 @@ -import { fetchType, getFetch, postFectch } from "@/components/lib/api"; +import { + fetchType, + getFetch, + postFectch, + putFectch, +} from "@/components/lib/api"; import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; -import type { DemandCompType } from "@common/business_components/ui"; +import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; export type comFcltState = { - - searchFclts: pubHasuType; demandCompList: DemandCompType[]; + dmdIsSucees: string; + checkDemand: DemandCompType; }; export type comFcltActions = { getSwtrmtFcltNm: (searchNm: string) => void; - getDemandCompList :(searchNm: string,cnt:number) => void - regDemandCompany:(data:DemandCompType ) => void + getDemandCompList: (searchNm: string, cnt: number) => void; + regDemandCompany: (data: DemandCompType) => void; + updateDemandCompany: (data: DemandCompType) => void; }; export const searchActions: (set: any) => comFcltActions = (set: any) => { @@ -18,9 +24,9 @@ export const searchActions: (set: any) => comFcltActions = (set: any) => { getSwtrmtFcltNm: async (searchNm: string) => { const fcltNm = await getFetch( "common", - `/prcsFclt/info/1/20/${searchNm}` + `/prcsFclt/info/1/11/${searchNm}` ); - const fcltNmCd: pubHasuType[] = fcltNm.map((item: any) => ({ + const searchFclts: pubHasuType[] = fcltNm.map((item: any) => ({ bscFctCd: item.bscFctCd, sido: item.sido, gugun: item.gugun, @@ -28,27 +34,65 @@ export const searchActions: (set: any) => comFcltActions = (set: any) => { addr: item.addr, fctCpc: item.fctCpc, })); - return set((state: comFcltState) => ({ + set((state: comFcltState) => ({ ...state, - searchFclts: fcltNmCd, + searchFclts: searchFclts, })); }, - getDemandCompList: async (searchNm: string ,cnt:number) => { + getDemandCompList: async (searchNm: string, cnt: number) => { const coList = await getFetch( fetchType.WR, - `/reuseFc/request/${searchNm}/${cnt}` + `/reuseFc/request/${searchNm}/${cnt}` ); - return set((state: comFcltState) => { - state.demandCompList= coList - return state + + console.log(coList); + set((state: comFcltState) => { + return state.demandCompList = [...coList]; }); - },regDemandCompany: async (data:DemandCompType)=>{ - - try{ - const response = await postFectch('/reuseFc/request',data,fetchType.WR ) - }catch(err){ - console.log(err) - } + }, + regDemandCompany: async (data: DemandCompType) => { + try { + const response = await postFectch( + "/reuseFc/request", + data, + fetchType.WR + ); + let message = ""; + if (response.status === 200) { + message = "success"; + } else { + message = "fail"; + } + set((state: comFcltState) => { + state.dmdIsSucees = message; + return state; + + }); + } catch (err) { + console.log(err); + } + }, + updateDemandCompany: async (data: DemandCompType) => { + try { + const response = await putFectch("/reuseFc/request", data); + + let message = ""; + if (response.status === 200) { + message = "success"; + } else { + message = "fail"; + } + + set((state: comFcltState) => { + state.dmdIsSucees = message; + return state; + + }); + + + } catch (err) { + console.log(err); + } } - }; + } }; diff --git a/apps/wr/app/store/matDmd/coMatRvw/headList.tsx b/apps/wr/app/store/matDmd/coMatRvw/headList.tsx index 8caf7e1b2..571deb001 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/headList.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/headList.tsx @@ -11,27 +11,27 @@ export const sttnHeadListType = z.array( export const coRvwHeadListExport: z.infer<typeof sttnHeadListType> = [ { - id: "ctpv", + id: "cityText", title: "시도", visible: true, }, { - id: "sgg", + id: "sggText", title: "시군구", visible: true, }, { - id: "coNm", + id: "dmdCoNm", title: "회사명", visible: true, }, { - id: "addr", + id: "daddr", title: "공장주소", visible: true, }, { - id: "telNo", + id: "telno", title: "전화번호", visible: true, }, diff --git a/apps/wr/app/store/matDmd/coMatRvw/index.tsx b/apps/wr/app/store/matDmd/coMatRvw/index.tsx index 906a7bedd..31d818ba5 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/index.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/index.tsx @@ -2,6 +2,8 @@ import type { z } from "zod"; import type { sttnHeadListType } from "../coSttn/headList"; import { coRvwHeadListExport, coRvwNodeListExport } from "./headList"; import type { CommonTableProps } from "../../common/type/header"; +import type { DmdCoReqType } from "./type"; +import { fetchType, getFetch } from "@/components/lib/api"; const coRvwHeadList = coRvwHeadListExport; const coRvwNodeList = coRvwNodeListExport; @@ -9,26 +11,54 @@ const coRvwNodeList = coRvwNodeListExport; export type coRvwState = { coRvw: { isInit: boolean; - coRvwHeadList: z.infer<typeof sttnHeadListType>; + coMatRvwRes: DmdCoReqType[]; + coRvwHeadList: CommonTableProps[]; coRvwNodeList: CommonTableProps[]; - }; }; export const coRvwStateExport: coRvwState = { coRvw: { isInit: false, + coMatRvwRes: [], coRvwHeadList: coRvwHeadList, coRvwNodeList: coRvwNodeList, - } -} + }, +}; export type coRvwType = coRvwState & coRvwActions; type coRvwActions = { + coMatRvwInit: ( + pageCnt: number, + pageNo: number, + sggCd: string, + startYear: string, + endYear: string + ) => void; }; export const coRvwActionsExport: (set: any) => coRvwActions = (set: any) => { return { - } -} \ No newline at end of file + coMatRvwInit: async ( + pageCnt: number, + pageNo: number, + sggCd: string, + startYear: string, + endYear: string + ) => { + const tempData = `/reuseFc/request/10000000000000`; + const url = `/reuseFc/request/${pageNo}/${pageCnt}/${sggCd}/${startYear}/${endYear}}`; + const coMatRvwRes = await getFetch(fetchType.WR, tempData); + + return set((state: coRvwState) => ({ + ...state, + coRvw: { + ...state.coRvw, + init: false, + coMatRvwRes: [coMatRvwRes], + }, + })); + }, + }; +}; diff --git a/apps/wr/app/store/matDmd/coMatRvw/type.tsx b/apps/wr/app/store/matDmd/coMatRvw/type.tsx new file mode 100644 index 000000000..eeaaaf8f5 --- /dev/null +++ b/apps/wr/app/store/matDmd/coMatRvw/type.tsx @@ -0,0 +1,70 @@ +import { z } from "zod"; +const DmdInfoSchema = z.object({ + dmdInfoSn: z.number(), + dmdInfoFk: z.string(), + dmndTmng: z.coerce.date(), + dmndQty: z.number(), + wntUntprc: z.number(), + grssClfg: z.number(), + combResdch: z.number(), + trbt: z.number(), + blgcOxygDmndQnt: z.number(), + smll: z.number(), + crmty: z.number(), + tn: z.number(), + tph: z.number(), + ph: z.number(), + clIonQnt: z.number(), + cdtnv: z.number(), + rmrk: z.string(), + useUsgCd: z.string(), +}); +const DmdMatSchema = z.object({ + dmdInfoFk: z.string(), + splyFcltFk: z.string(), + splyFcltFlg: z.string(), + pbnstRuseFcltBizFk: z.number(), + splyBgngDay: z.coerce.date(), + splyEndDay: z.coerce.date(), + splyCpct: z.number(), + splyFmYn: z.string(), + useUsgCd: z.string(), +}); + +export const DmdCoReqSchema = + z.object({ + cityText:z.string().nullish(), + sggText:z.string().nullish(), + dmdInfoPk: z.string(), + dmdCoNm: z.string(), + ctpvCd: z.string(), + sggCd: z.string(), + daddr: z.string(), + splyBgngDay: z.coerce.date(), + splyEndDay: z.coerce.date(), + splyCpct: z.number(), + splyFmYn: z.string(), + telno: z.string(), + useUsgCd: z.string(), + regDt: z.coerce.date(), + rgtr: z.string(), + mdfcnDt: z.coerce.date(), + mdfr: z.string(), + dmdAplyPswd: z.string(), + demandInfo: z.array(DmdInfoSchema), + demandMatchings: z.array(DmdMatSchema), + }) + + + + +export type DmdCoReqType = z.infer<typeof DmdCoReqSchema>; +export type DmdMatTableType = { + cityText:string, + sggText:string, + dmdCoNm:string, + daddr:string, + telno:string, + regDt:string, + state:string +} \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/coReg/index.tsx b/apps/wr/app/store/matDmd/coReg/index.tsx deleted file mode 100644 index c4e64614c..000000000 --- a/apps/wr/app/store/matDmd/coReg/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { z } from "zod"; - -export const coZod = z.object({ - ctpv: z.string(), - sgg: z.string(), - coNm: z.string().min(1).max(20), - bznmNo: z.string().min(1).min(9).max(12), - addr: z.string().min(1).min(6).max(20), - telNo: z.string().min(8).max(12) - -}); - -export type customCoBdst = z.infer<typeof coZod>; diff --git a/apps/wr/app/store/matDmd/coSttn/headList.tsx b/apps/wr/app/store/matDmd/coSttn/headList.tsx index 376b0dea0..80fed0d76 100644 --- a/apps/wr/app/store/matDmd/coSttn/headList.tsx +++ b/apps/wr/app/store/matDmd/coSttn/headList.tsx @@ -15,12 +15,12 @@ export const coRegExcel = z.object({ export const coSttHeadListExport: z.infer<typeof sttnHeadListType> = [ { - id: "ctpvCd", + id: "cityText", title: "시도", visible: true, }, { - id: "sggCd", + id: "sggText", title: "시군구", visible: true, }, @@ -31,12 +31,12 @@ export const coSttHeadListExport: z.infer<typeof sttnHeadListType> = [ }, { id: "daddr", - title: "공장주소", + title: "주소", visible: true, }, { id: "dmdInfoPk", - title: "공장관리번호", + title: "사업자번호", visible: true, }, { @@ -48,7 +48,7 @@ export const coSttHeadListExport: z.infer<typeof sttnHeadListType> = [ export const coSttNodeListExport: CommonTableProps[] = [ { - id: "ctpvCd", + id: "cityText", title: "시도", visible: true, row: 1, @@ -56,7 +56,7 @@ export const coSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "sggCd", + id: "sggText", title: "시군구", visible: true, row: 1, @@ -73,7 +73,7 @@ export const coSttNodeListExport: CommonTableProps[] = [ }, { id: "daddr", - title: "공장주소", + title: "주소", visible: true, row: 1, rowSpan: 1, @@ -81,7 +81,7 @@ export const coSttNodeListExport: CommonTableProps[] = [ }, { id: "dmdInfoPk", - title: "공장관리번호", + title: "사업자번호", visible: true, row: 1, rowSpan: 1, diff --git a/apps/wr/app/store/matDmd/coSttn/index.tsx b/apps/wr/app/store/matDmd/coSttn/index.tsx index 716c1475e..4b8c60436 100644 --- a/apps/wr/app/store/matDmd/coSttn/index.tsx +++ b/apps/wr/app/store/matDmd/coSttn/index.tsx @@ -1,29 +1,18 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; import { fetchType, getFetch } from "@/components/lib/api"; -import { z } from "zod"; import { coSttHeadListExport, coSttNodeListExport } from "./headList"; import { excelCoSttnParsing } from "./excel"; +import type { DemandCompType } from "@common/business_components/ui"; // 테이블 헤드 리스트 const coSttNodeList = coSttNodeListExport; const coSttHeadList = coSttHeadListExport; -const coSttnRes: customCoSttnBdst[] = []; +const coSttnRes: DemandCompType[] = []; -const coSttnZod = z.object({ - ctpvCd: z.string(), - sggCd: z.string(), - dmdCoNm: z.string().min(1).max(20), - dmdInfoPk: z.string().min(1).min(10).max(14), - daddr: z.string().min(1).min(6).max(20), - telno: z.string().min(11).max(12) - -}); - -export type customCoSttnBdst = z.infer<typeof coSttnZod>; export type coSttnState = { coSttn: { - coSttnRes: customCoSttnBdst[]; + coSttnRes: DemandCompType[]; coSttHeadList: CommonTableProps[]; coSttNodeList: CommonTableProps[]; excelList: []; @@ -32,8 +21,9 @@ export type coSttnState = { }; type coSttnActions = { - coSttnInit:(con:string) => void; - coSttnSearch: (txt: string, cnt: number) => void; + coSttnInit:(pageNo:string, pageCnt:string, con: string) => void; + coSttnSearch: (pageNo:string, pageCnt:string, con: string) => void; + coSttnTxtSearch:(pageNo:string, pageCnt:string, con: string,txt:string) => void; }; export type coSttnType = coSttnState & coSttnActions; @@ -48,17 +38,20 @@ export const coSttnStateExport: coSttnState = { }, }; + export const coSttnActionsExport: (set: any) => coSttnActions = ( set: any ) => { return { - coSttnInit: async (con: string) => { + coSttnInit: async (pageNo:string, pageCnt:string, con: string) => { try { const coSttnRes = await getFetch( fetchType.WR, - `/reuseFc/request/마인드원/3` + `/reuseFc/request/${pageNo}/${pageCnt}/${con}` ); + + set((state: coSttnState) => { return { ...state, @@ -73,13 +66,13 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( console.log(e) } }, - coSttnSearch: async (txt: string, cnt: number) => { + coSttnSearch: async (pageNo:string, pageCnt:string, con: string) => { try { const coSttnRes = await getFetch( fetchType.WR, - `/reuseFc/request/${txt}/${cnt}` + `/reuseFc/request/${pageNo}/${pageCnt}/${con}` ); - if (Number(cnt) > 0) { + if (Number(pageCnt) >= 10000) { const coExcel = excelCoSttnParsing(coSttnRes); set((state: coSttnState) => { return { @@ -87,6 +80,7 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( coSttn: { ...state.coSttn, excelList: coExcel, + isInit: false, }, }; }); @@ -105,5 +99,22 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( console.log("error", erTxt); } }, + coSttnTxtSearch: async (pageNo:string, pageCnt:string, con: string, txt: string) => { + try { + const coSttnRes = await getFetch( + fetchType.WR, + `/reuseFc/request/${pageNo}/${pageCnt}/${con}/${txt}`) + set((state: coSttnState) => { + return { + ...state, + coSttn: { + ...state.coSttn, + coSttnRes: coSttnRes, + isInit: false, + }}}) + } catch (erTxt) { + console.log("error", erTxt); + } + } } } \ No newline at end of file diff --git a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx index 86bf5bc82..b985cd944 100644 --- a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx +++ b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx @@ -2,7 +2,6 @@ import { rswtHeadNmExport } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/he import { rswtChkSttnHeadListExport, rswtDetailSttnHeadListExport } from "./headList"; import type { TableUpperProps } from "@/app/store/common/type/header"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { sheetParameter } from "@common/business_components/ui"; import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; import { getFetch } from "@/components/lib/api"; import { buildingExcelRswtSttn } from "./excel"; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index ec73ddb24..536114f3f 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -14,20 +14,16 @@ export const pubFacHeadListExport: TableUpperProps[] = [ export const pbnstMngUpHeadListExport: TableUpperProps[] = [ { id: "choose", title: "선택", type: "checkbox" }, - { id: "operMthd", title: "운영방식", edit: true }, + { id: "operMthd", title: "운영방식",type: "select", selectData: "ruseMngMtd" }, { id: "rprtvBzenty", title: "대행업체", edit: true }, { id: "bgngDt", title: "시작일", - upName: "upChangeRe", - upSequnce: 1, type: "date", }, { id: "endDt", title: "종료일", - upName: "upChangeRe", - upSequnce: 2, type: "date", }, ]; @@ -50,7 +46,7 @@ export const pbnstDemandHeadListExport: TableUpperProps[] = [ ]; export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [ - { id: "ruseUtztnFcltNm", title: "운영방식" }, + { id: "ruseUtztnFcltNm", title: "하수처리장명" }, { id: "orgwtWtritQnt", title: "원수취수량" }, { id: "tmsYn", title: "하수처리량TMS 전후" }, { id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​" }, @@ -73,6 +69,7 @@ export type formDetailType = { id: string; lable: string; type?: string; + option?:string }; export const wasteWaterFcltINfo: formDetailType[] = [ @@ -103,7 +100,7 @@ export const businessMoneyInfo: formDetailType[] = [ { id: "lcep", lable: "지방비", type: "number" }, { id: "cusrAlotm", lable: "민간투자비", type: "number" }, { id: "etc", lable: "기타" }, - { id: "totalMoney", lable: "합계", type: "number" }, + { id: "totalMoney", lable: "합계", type: "number" ,option:"readOnly" }, ]; export const businessSttnInfo: formDetailType[] = [ diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index e22037892..9fde9c092 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -51,7 +51,6 @@ export type pubFacState = { fcOrgwtsHeadList: TableUpperProps[]; pbnstMngRegData: customPbnst[]; pbnsUpdateIndex: pbnstInsertIndex; - efflAmnt:string dmdComList: any[]; }; }; @@ -69,7 +68,7 @@ type pubFacActions = { getpbnstInsertIndex: (data: pbnstInsertIndex) => void; pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; - getHasuFlow: (sggCd:string, swtrmtFcltNm:string) => void + pubHasuSearch :(page: string, sggOrCity: string , searchTxt:string) => void }; export type pubFacType = pubFacState & pubFacActions; @@ -80,15 +79,14 @@ export const pubFacStateExport: pubFacState = { pbnstMngUpHeadList: pbnstMngUpHeadList, pbnstMngNm: pbnstMngNm, pbnstOrgwtHeadList: pbnstOrgwtHeadList, - pbnstHasuRes: [], - efflAmnt:'', - pbnstResObj: null, // 초기값을 null로 변경 - pbnstRes: [], // 초기값을 null로 변경 - pbnstBizCycle: [{ text: "없음", val: "1" }], - selectLabel: selectLabel, pplInstlsHeadLisat: pplInstlsHeadLisat, pbnstDemandHeadList: pbnstDemandHeadList, fcOrgwtsHeadList: fcOrgwtsHeadList, + selectLabel: selectLabel, + pbnstResObj: null, // 초기값을 null로 변경 + pbnstHasuRes: [], + pbnstRes: [], // 초기값을 null로 변경 + pbnstBizCycle: [{ text: "없음", val: "1" }], pbnstMngRegData: [], pbnsUpdateIndex: {} as pbnstInsertIndex, dmdComList: [], @@ -100,11 +98,15 @@ const checkWrRegList = async () => { return wrRegList; }; -const hasuListFetch = async (page: string, sggOrCity: string) => { +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`; +if(searchTxt){ + url= url +`/${searchTxt}` +} const rainRes = await postFectch( - `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`, + url, checkWrRegListRes, fetchType.COMMON ); @@ -146,12 +148,12 @@ export const writeRgtrAndMdfr = (data: customPbnst[]) => { }); return item; }); - pbnst.fcOpers = pbnst.fcOpers.map((oper) => { + pbnst.fcOpers = pbnst?.fcOpers?.map((oper) => { oper.rgtr = TEST_UUID; oper.mdfr = TEST_UUID; return oper; }); - pbnst.fcFiles = pbnst.fcFiles.map((file) => { + pbnst.fcFiles = pbnst.fcFiles?.map((file) => { file.rgtr = TEST_UUID; file.mdfr = TEST_UUID; return file; @@ -179,8 +181,22 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } catch (errorHasu) { console.log(errorHasu); } - }, + },pubHasuSearch : async(page: string, sggOrCity: string , searchTxt:string)=> { + try{ + const pbnstHasuRes = await hasuListFetch(page, sggOrCity,searchTxt); + return set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + pbnstHasuRes: pbnstHasuRes, + isInit: false, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, pbnstRegClick: async (pubHasuRes: pubHasuType) => { try { const pbnstRes = await initFetch(pubHasuRes.bscFctCd); @@ -218,7 +234,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { const response = await postFectch( `/reuseFc/pubFc`, - JSON.stringify( writeRgtrAndMdfr([pbnstRes])) + JSON.stringify( pbnstRes) ); return set((state: pubFacState) => ({ @@ -321,7 +337,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { pbnstMngData: (data: customPbnst[]) => { if (data.length > 0) { } - console.log('data', data) return set((state: pubFacState) => { state.pbnst.pbnstMngRegData = data; state.pbnst.pbnstBizCycle = @@ -373,21 +388,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } catch (e) { console.log(e); } - },getHasuFlow: async(sggCd:string, swtrmtFcltNm:string) =>{ - try{ - const year = new Date().getFullYear()-1 - const flow = await getFetch( fetchType.COMMON, `/fclt/flow/1/1/${year}/A/${sggCd}/0/1/${swtrmtFcltNm}`) - - return set((state: pubFacState) => ({ - ...state, - pbnst: { - ...state.pbnst, - efflAmnt: flow[0].efflAmnt, - }, - })); - }catch(e){ - console.log(e) - } } }; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx index 972e245cd..fb9515bcf 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -58,67 +58,8 @@ export type PbnstDemandComType = { splyCpct: number | 0; splyFmYn:string|'Y' dmdInfoFk:string|'' - } - - -export type fcBizType = z.infer<typeof fcBizSchema>; -export type fcOrgwtType = z.infer<typeof fcOrgwtSchema>; -export type ppInstlType = z.infer<typeof pplInstlSchema>; - -export type operType = z.infer<typeof fcOperSchema>; -export type fcFileType = z.infer<typeof fcFileSchema>; - - -const pplInstlSchema = z.object({ - ruseFcltBizFk: z.number().nullish(), - choose:z.boolean().default(false), - pdmt: z.string().default(''), - ppMqlt: z.string().default(""), - cpct: z.number().default(0), -}); -const fcFileSchema = z.object({ - ruseFcltFk: z.number().nullish(), - fileTkn: z.string(), - filePath: z.string(), - fileKnd: z.string(), - regDt: z.date().default(new Date()).nullish(), - rgtr: z.string().nullish(), - mdfcnDt: z.date().default(new Date()).nullish(), - mdfr: z.string().nullish(), -}); - -export const fcOperSchema = z.object({ - pbnstRuseFcltOperInfoPk: z.number().nullish(), - pbnstRuseFcltFk: z.string().nullish(), - operMthd: z.string(), - rprtvBzenty: z.string(), - bgngDt: z.date().default(new Date()), - endDt: z.date().default(new Date()), - regDt: z.date().nullish(), - rgtr: z.string().default(""), - mdfcnDt: z.date().nullish(), - mdfr: z.string().default(""), - choose: z.boolean().default(false), -}); - -const fcOrgwtSchema = z.object({ - pbnstRuseFcltBizFk: z.string().nullish(), - swtrmtFcltFk: z.number().default(0), - orgwtWtritQnt: z.number(), - tmsYn: z.enum(["Y", "N"] ).default("N"), - dschgFmYn: z.enum(["Y", "N"] ).default("N"), - dtlPstnExpln: z.string().default(''), - regDt: z.date().nullish(), - rgtr: z.string().default(''), - mdfcnDt: z.date().nullish(), - mdfr: z.string().default(''), - choose: z.boolean().default(false), -}); - - - const pubHasuZod = z.object({ choose: z.boolean().default(false), bscFctCd: z.string(), @@ -130,97 +71,141 @@ const pubHasuZod = z.object({ addr:z.string().nullish() }); -const demandInfoList = z.object({ - -}) - export type pubHasuType = z.infer<typeof pubHasuZod>; +const zDate = z.preprocess((v) => (v ? new Date(v as string) : undefined), z.date()).nullish() ; +const zDateNullish = zDate.nullish(); +const zDateDefaultNow = zDate.default(new Date()); +const zNum = z.preprocess((v) => (v !== null && v !== undefined ? Number(v) : v), z.number()); +const zNumNullish = zNum.nullish(); +const zNumDefaultZero = zNum.default(0).nullish(); +const pplInstlSchema = z.object({ + ruseFcltBizFk: zNumNullish, + choose: z.boolean().default(false), + pdmt: z.string().default(''), + ppMqlt: z.string().default(""), + cpct: zNumDefaultZero, +}); + +const fcFileSchema = z.object({ + ruseFcltFk: z.string().nullish(), + fileTkn: z.string(), + filePath: z.string(), + fileKnd: z.string(), + regDt: zDateDefaultNow.nullish(), + rgtr: z.string().nullish(), + mdfcnDt: zDateDefaultNow.nullish(), + mdfr: z.string().nullish(), +}); + +export const fcOperSchema = z.object({ + pbnstRuseFcltOperInfoPk: zNumNullish, + pbnstRuseFcltFk: z.string().nullish(), + operMthd: z.string(), + rprtvBzenty: z.string(), + bgngDt: zDateDefaultNow, + endDt: zDateDefaultNow, + regDt: zDateNullish, + rgtr: z.string().default(""), + mdfcnDt: zDateNullish, + mdfr: z.string().default(""), + choose: z.boolean().default(false), +}); + +const fcOrgwtSchema = z.object({ + pbnstRuseFcltBizFk:zNumNullish, + swtrmtFcltFk: z.string().nullish(), + orgwtWtritQnt: zNum, + tmsYn: z.enum(["Y", "N"]).default("N"), + dschgFmYn: z.enum(["Y", "N"]).default("N"), + dtlPstnExpln: z.string().default(''), + regDt: zDateNullish, + rgtr: z.string().default(''), + mdfcnDt: zDateNullish, + mdfr: z.string().default(''), + choose: z.boolean().default(false), +}); const dmdColist = z.object({ - dmdInfoFk:z.string().default(''), + dmdInfoFk: z.string().default(''), dmdCoNm: z.string().default(''), daddr: z.string(), useUsgCd: z.string().default(""), - splyBgngDay: z.date().default(new Date()), - splyEndDay: z.date().default(new Date()), - splyCpct: z.number().default(0), + splyBgngDay: zDateDefaultNow, + splyEndDay: zDateDefaultNow, + splyCpct: zNumDefaultZero, splyFmYn: z.string().default('Y'), rgtr: z.string().nullish(), mdfr: z.string().nullish(), - pbnstRuseFcltBizPk: z.number(), + pbnstRuseFcltBizPk: zNumDefaultZero, pbnstRuseFcltFk: z.string().nullish(), - //telno:z.string().default('') }); - - - export const fcBizSchema = z.object({ - pbnstRuseFcltBizPk: z.number().nullish(), + pbnstRuseFcltBizPk: zNumNullish, pbnstRuseFcltFk: z.string().nullish(), superkey: z.string().default("").nullish(), - cycl: z.number().default(1), + cycl: zNum.default(1), seCd: z.string().default(""), bizMthdCd: z.string().default(""), - instlAprvSncnDt: z.date().nullish(), - bizCmcnDay: z.date().nullish(), - gvsbs: z.number().default(0), - lcep: z.number().default(0), - cusrAlotm: z.number().default(0), + instlAprvSncnDt: zDateDefaultNow, + bizCmcnDay: zDateDefaultNow, + gvsbs: zNumDefaultZero, + lcep: zNumDefaultZero, + cusrAlotm: zNumDefaultZero, etc: z.string().default(''), - totalMoney: z.number().default(0).nullish(), - rprcsFcltCpct: z.number().default(0), + totalMoney: zNumNullish.default(0), + rprcsFcltCpct: zNumDefaultZero, majorPrcsMsrcCd: z.string().default(""), addr: z.string().default(''), rprcsMthdCd: z.string().default(""), inoutYn: z.enum(["Y", "N"]).default("Y"), - mainSplyPumpCpct: z.number().nullish(), - erctWtrOcrnCpct: z.number().nullish(), + mainSplyPumpCpct: zNumNullish, + erctWtrOcrnCpct: zNumNullish, erctUswtrLinkSpt: z.string().nullish(), - erctUswtrFcltCpct: z.number().nullish(), + erctUswtrFcltCpct: zNumNullish, erctUswtrPrcsMeth: z.string().nullish(), erctUswtrPrcsMsrcCd: z.string().nullish(), - wwtEmsnFcltPrmsnYn: z.enum(["Y", "N"]).default("Y"), - tmsInstlYn: z.enum(["Y", "N"]).default("Y"), - pbnstDrngInflwExclYn: z.enum(["Y", "N"]).default("Y"), - bod: z.number().default(0), - grssClfg: z.number().default(0), - combResdch: z.number().default(0), - trbt: z.number().default(0), - clIonQnt: z.number().default(0), - smll: z.number().default(0), - crmty: z.number().default(0), - tph: z.number().default(0), - tn: z.number().default(0), - ph: z.number().default(0), - cdtnv: z.number().default(0), - designCst: z.number().nullish(), - cstrnSpvsCst: z.number().nullish(), - fcltSbsdCst: z.number().nullish(), - wstCst: z.number().nullish(), - cnstCmcnCst: z.number().nullish(), - mntrgEqpmntInstlCst: z.number().nullish(), - gisDbCst: z.number().nullish(), - elpwrMtrngCst: z.number().nullish(), - mchnCst: z.number().nullish(), - archCst: z.number().nullish(), - pplCst: z.number().nullish(), - ruseFcltCst: z.number().nullish(), - designCstClcln: z.number().nullish(), - cstrnSpvsCstClcln: z.number().nullish(), - fcltSbsdCstClcln: z.number().nullish(), - wstCstClcln: z.number().nullish(), - cnstCmcnCstClcln: z.number().nullish(), - mntrgEqpmntInstlCstClcln: z.number().default(0), - gisDbCstClcln: z.number().nullish(), - elpwrMtrngCstClcln: z.number().nullish(), - mchnCstClcln: z.number().nullish(), - archCstClcln: z.number().nullish(), - pplCstClcln: z.number().nullish(), - ruseFcltCstClcln: z.number().nullish(), + wwtEmsnFcltPrmsnYn: z.string().default("Y"), + tmsInstlYn: z.string().default("Y"), + pbnstDrngInflwExclYn: z.string().default("Y"), + bod: zNumDefaultZero, + grssClfg: zNumDefaultZero, + combResdch: zNumDefaultZero, + trbt: zNumDefaultZero, + clIonQnt: zNumDefaultZero, + smll: zNumDefaultZero, + crmty: zNumDefaultZero, + tph: zNumDefaultZero, + tn: zNumDefaultZero, + ph: zNumDefaultZero, + cdtnv: zNumDefaultZero, + designCst: zNumNullish, + cstrnSpvsCst: zNumNullish, + fcltSbsdCst: zNumNullish, + wstCst: zNumNullish, + cnstCmcnCst: zNumNullish, + mntrgEqpmntInstlCst: zNumNullish, + gisDbCst: zNumNullish, + elpwrMtrngCst: zNumNullish, + mchnCst: zNumNullish, + archCst: zNumNullish, + pplCst: zNumNullish, + ruseFcltCst: zNumNullish, + designCstClcln: zNumNullish, + cstrnSpvsCstClcln: zNumNullish, + fcltSbsdCstClcln: zNumNullish, + wstCstClcln: zNumNullish, + cnstCmcnCstClcln: zNumNullish, + mntrgEqpmntInstlCstClcln: zNumDefaultZero, + gisDbCstClcln: zNumNullish, + elpwrMtrngCstClcln: zNumNullish, + mchnCstClcln: zNumNullish, + archCstClcln: zNumNullish, + pplCstClcln: zNumNullish, + ruseFcltCstClcln: zNumNullish, fcOrgwts: z.array(fcOrgwtSchema).nullish(), pplInstls: z.array(pplInstlSchema).nullish(), fcDemands: z.array(dmdColist).default([]).nullish(), @@ -230,19 +215,30 @@ export const fcBizSchema = z.object({ mdfcnDt: z.string().nullish(), mdfr: z.string().nullish(), }); + export const pbnstRegZod = z.object({ pbnstRuseFcltPk: z.string().default(''), swtrmtFcltFk: z.string().default(""), ruseUtztnFcltNm: z.string().default(""), - fcltCpct: z.number().default(0), - ruseCpct: z.number().default(0), - splyExtraCpct: z.number().default(0), - regDt: z.date().default(new Date()), + fcltCpct: zNumDefaultZero, + ruseCpct: zNumDefaultZero, + splyExtraCpct: zNumDefaultZero, + regDt: zDateDefaultNow, rgtr: z.string().default("test"), - mdfcnDt: z.date().default(new Date()), + mdfcnDt: zDateDefaultNow, mdfr: z.string().default("test"), - fcFiles: z.array(fcFileSchema).default([]), + fcFiles: z.array(fcFileSchema).default([]).nullish(), fcBizs: z.array(fcBizSchema).default([]), - fcOpers: z.array(fcOperSchema).default([]), - hasuhasu: z.number().default(0), + fcOpers: z.array(fcOperSchema).default([]).nullish(), }); + +export const pbnstRegArrayZod = z.array(pbnstRegZod) + +export type PbnstRegArrrayType = z.infer<typeof pbnstRegArrayZod> + +export type fcBizType = z.infer<typeof fcBizSchema>; +export type fcOrgwtType = z.infer<typeof fcOrgwtSchema>; +export type ppInstlType = z.infer<typeof pplInstlSchema>; +export type operType = z.infer<typeof fcOperSchema>; +export type fcFileType = z.infer<typeof fcFileSchema>; + diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index 327ad9b22..7d4eff124 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -21,6 +21,7 @@ export const getCity = (val: string, sggCd: SelectDataType[]) => { // cd text 넣기 export const tableData = (data: any, code: comCodeState) => { const chCode = code.code; + return data?.map( (item: { sggCd: string; @@ -29,17 +30,16 @@ export const tableData = (data: any, code: comCodeState) => { }) => { let returnData = {}; const sggText = chCode.sggCd.find( - (cd) => cd.val === String(item.sggCd) + (cd) => cd.val === String(item.sggCd).trim() )?.text; const cityText = chCode.cityCd.find( - (cd) => cd.val === String(item.ctpvCd) + (cd) => cd.val === String(item.ctpvCd).trim() )?.text; if (item?.reuseBuilding?.length > 0) { const bdsgUsgText = chCode.bdstUsgCd.find( (cd) => Number(cd.val) === item?.reuseBuilding[0]?.bdstUsgCd )?.text; const lawTrgtYn = item?.reuseBuilding[0]?.lawTrgtYn; - returnData = { ...item, sggText: sggText ?? "없음", @@ -54,7 +54,6 @@ export const tableData = (data: any, code: comCodeState) => { cityText: cityText ?? "없음", }; } - return returnData; } ); @@ -82,7 +81,7 @@ export const excelDownload = ( export const excelArrayDownload = ( fileNm: string, sampleFile: string, - sheetArray: [typeof sheetParameter] + sheetArray: [] ) => { if (!sheetArray) return; fetch(`/${sampleFile}`, {}).then(async (response) => { 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 f1d1ee464..645a2fa07 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -13,7 +13,7 @@ import { fcBizSchema, type customPbnst, type fcBizType, - type PbnstDemandComType, + type PbnstRegArrrayType, type ppInstlType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; @@ -39,22 +39,29 @@ import { Input, Label, } from "@common/components"; -import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useRef, useState } from "react"; -import { useFieldArray, useForm } from "react-hook-form"; +import { useFieldArray, useForm, type UseFormReturn } from "react-hook-form"; import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail"; import { safeDate } from "@/components/lib/func/commom"; import SearchInputText from "@/components/ui/searchInput/searchInput"; -import SdmInsertForm, { - type DemandCompType, -} from "@common/business_components/ui/sdmInsertForm"; +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"; export function PbnstBuseForm({ formType, firstBizData, + indexMng = 0, + indexBiz = 0, + setIndexBiz, + form, }: { formType: string; firstBizData?: fcBizType[]; + form: UseFormReturn<{ items: PbnstRegArrrayType }>; + indexMng: number; + indexBiz: number; + setIndexBiz: (index: number) => void; }) { const ref = useRef<ppInstlType[] | null>(null); const { @@ -73,62 +80,98 @@ export function PbnstBuseForm({ const [ppiSelectList, setPpiSelectList] = useState<[{ name: string; val: SelectDataType[] }]>(); const [ppiYn, setPpiYn] = useState("Y"); + + const [selectBizCycle, setSelectBizCycle] = useState< + { + text: string; + val: number; + }[] + >([{ text: "없음", val: 0 }]); const [isFcOrgwts, setIsFcOrgwts] = useState<boolean>(false); const [sumCpct, setSumCpct] = useState<number>(0); + const [getDmdList, setGetFmdList] = useState<number>(0); const [isDmdModal, setIsDmdModal] = useState<{ isMoal: boolean; data: DemandCompType; }>({ isMoal: false, data: {} as DemandCompType }); - 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({}), - }); - // 2. Define a submit handler. - function onSubmit(values: fcBizType) { - // console.log(values); - } + useEffect(() => { + const total = + (form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.gvsbs`) ?? 0) + + (form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.lcep`) ?? 0) + + (form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.cusrAlotm`) ?? 0); + form.setValue(`items.${indexMng}.fcBizs.${indexBiz}.totalMoney`, total); + }, [ + form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.gvsbs`), + form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.lcep`), + 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", + // }); + + + 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부터 시작) + })) + ); + } + }, [indexMng, form]); // 2. Define a submit handler. function addRuseFcltObj() { - const newItem = fcBizSchema.parse({}); + const formRuse = form.getValues(`items.${indexMng}`); + + const formBizs = form.getValues(`items.${indexMng}.fcBizs`); + const pbnstBizCycle = formBizs.length; + + // 🧩 새로운 fcBizs 기본 객체 생성 (필수값만 채우고 나머지는 default로) + const newItem = fcBizSchema.parse({ + cycl: pbnstBizCycle + 1, + pbnstRuseFcltFk: formRuse.pbnstRuseFcltPk, + fcOrgwts: undefined, + pplInstls: undefined, + fcDemands: undefined, + }); const index = pbnst.pbnsUpdateIndex.mng; - - let regData: fcBizType = {} as fcBizType; - if ( - pbnst.pbnstRes && - pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng] && - pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]?.fcBizs - ) { - regData = { - pbnstRuseFcltFk: - String(pbnst.pbnstRes[0]?.swtrmtFcltFk) + - String(pbnst.pbnstRes.length + 1), - cycl: Number( - (pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]?.fcBizs?.length || 0) + 1 - ), - } as fcBizType; - - const newPbnstRes = [...(pbnst.pbnstRes as customPbnst[])]; - newPbnstRes[index]?.fcBizs?.length && - newPbnstRes[index]?.fcBizs?.push(regData); - getBizCycle(newPbnstRes[index] as customPbnst); - appendRuseFclt(newPbnstRes); - } + 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부터 시작) + })) + ); } + useEffect(() => { + console.log("form ", form.watch()); + }, [form.formState]); + + const { fields: fcBizs, append: appendBiz } = useFieldArray({ + control: form.control, + name: `items.${indexMng}.fcBizs`, + }); const { fields: fcDemands, @@ -136,79 +179,54 @@ export function PbnstBuseForm({ remove: removeDemand, } = useFieldArray({ control: form.control, - name: "fcDemands", + name: `items.${indexMng}.fcBizs.${indexBiz}.fcDemands`, }); const { fields: fcOrgwtFiled } = useFieldArray({ control: form.control, - name: "fcOrgwts", + name: `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, }); - + console.log(" fcOrgwtFiled ", fcOrgwtFiled); const { fields: pplInstls, - append, - remove, + append: appendPpl, + remove: removePpl, } = useFieldArray({ control: form.control, - name: "pplInstls", + name: `items.${indexMng}.fcBizs.${indexBiz}.pplInstls`, }); - // 등록할때 신규 값을 계속 가지고 있으려고 - useEffect(() => { - const formData = form.watch(); - - formData.pplInstls = ref.current ? [...ref.current] : []; // ← form 내부 상태 기준으로 복사 - formData.fcDemands = fcDemands; - formData.fcOrgwts = fcOrgwtFiled; - if (formType === "reg") { - if ( - firstBizData && - firstBizData[0] && - (form.getValues("pbnstRuseFcltFk") === "" || - form.getValues("pbnstRuseFcltFk") === undefined) - ) { - form.setValue( - "pbnstRuseFcltFk", - String(firstBizData[0].pbnstRuseFcltFk) - ); - form.setValue("cycl", firstBizData[0].cycl); - } - pbnstBizData(formData as fcBizType); - }else if(formType === "update"){ - - pbnstBizData(formData as fcBizType); - - - } - }, [firstBizData, form.formState, formType, pbnst.pbnstRes]); - - useEffect(() => { if (ppiYn === "N") { - form.setValue("pplInstls", []); + form.setValue(`items.${indexMng}.fcBizs.${indexBiz}.pplInstls`, []); } - }, [ppiYn]); + }, [ppiYn, indexMng, indexBiz]); useEffect(() => { console.log("pbnst. bug pbnstMngRegData ", pbnst.pbnstMngRegData); }, [pbnst.pbnstMngRegData]); const plusHist = () => { - const regData = { - ruseFcltBizFk: ref.current?.[0]?.ruseFcltBizFk ?? form.getValues('pbnstRuseFcltBizPk'), - choose: false, - ppMqlt: "", - pdmt: "", - cpct: 0, - }; - const currentTableDataFromRef = ref.current ? [...ref.current] : []; - const newDataForRHF = [...currentTableDataFromRef, regData]; - form.setValue("pplInstls", newDataForRHF, { - shouldValidate: true, // 필요하다면 유효성 검사 실행 - shouldDirty: true, // 폼 상태를 dirty로 변경 - }); - const latestOpers = form.getValues("pplInstls"); - ref.current = [...latestOpers]; + if ( + form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltBizPk`) + ) { + appendPpl({ + ruseFcltBizFk: form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltBizPk` + ), + choose: false, + ppMqlt: "", + pdmt: "", + cpct: 0, + }); + } else { + appendPpl({ + choose: false, + ppMqlt: "", + pdmt: "", + cpct: 0, + }); + } }; const plusArray = () => { @@ -220,29 +238,31 @@ export function PbnstBuseForm({ splyEndDay: new Date(), splyCpct: 0, splyFmYn: "Y", - pbnstRuseFcltBizPk: form.getValues('pbnstRuseFcltBizPk'), - pbnstRuseFcltFk: form.getValues('pbnstRuseFcltFk')??'', - dmdInfoFk: '', + pbnstRuseFcltBizPk: form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltBizPk` + ), + pbnstRuseFcltFk: + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltFk` + ) ?? "", + dmdInfoFk: "", //telno: "", }); }; const removeSelected = () => { - if (!ref.current) return; - const selectedIdxs = ref.current + const nowPPl = form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` + ); + + if (!nowPPl) return; + + const selectedIdxs = nowPPl .map((item, idx) => (item.choose ? idx : -1)) .filter((idx) => idx !== -1); - selectedIdxs.reverse().forEach((idx) => remove(idx)); + selectedIdxs.reverse().forEach((idx) => removePpl(idx)); }; - useEffect(() => { - if (bizCycle && formType !== "reg") { - const index = Number(bizCycle) - 1; - form.reset(pbnst.pbnstResObj?.fcBizs[index]); - ref.current = pbnst.pbnstResObj?.fcBizs[index]?.pplInstls ?? []; - } - }, [bizCycle, pbnst.pbnstResObj, formType]); - useEffect(() => { const ppl = [] as { name: string; val: SelectDataType[] }[]; if (code.pplLenght) { @@ -258,10 +278,23 @@ export function PbnstBuseForm({ } }, [code]); + useEffect(() => { + console.log(" demandCompList ", demandCompList); + }, [demandCompList]); useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); + useEffect(() => { + const pplSum = form.watch(`items.${indexMng}.fcBizs.${indexBiz}.pplInstls`); + if (!pplSum) return; + let sum = 0; + pplSum.forEach((item) => { + sum += Number(item.cpct) || 0; + }); + setSumCpct(sum); + }, [form.formState, indexMng, indexBiz]); + return ( <> <div className=" !mx-[1.6rem] !p-0r"> @@ -269,25 +302,23 @@ export function PbnstBuseForm({ <div className="justify-between"> <Form {...form}> <form - onSubmit={form.handleSubmit(onSubmit)} + 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={pbnstBizCycle} - value={bizCycle ?? pbnstBizCycle[0]?.val} + selectArray={selectBizCycle || []} + value={selectBizCycle[indexBiz]?.val} className={""} selectClass={selectClass} onSelectValue={(val) => { - setBizCycle(String(val)); - getpbnstInsertIndex({ - ...pbnst.pbnsUpdateIndex, - biz: Number(val), - }); + setIndexBiz(Number(val)); }} ></SelectBox> @@ -296,7 +327,7 @@ export function PbnstBuseForm({ type="button" size={commonButonSize} > - 저장 + 추가 </Button> </div> </div> @@ -306,6 +337,8 @@ export function PbnstBuseForm({ form={form} moClass="grid grid-cols-12 gap-4" sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} /> <MngRegFormDetail formList={businessMoneyInfo} @@ -313,13 +346,18 @@ export function PbnstBuseForm({ 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} @@ -327,6 +365,8 @@ export function PbnstBuseForm({ form={form} moClass="grid grid-cols-12 gap-4" sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} /> <MngRegFormDetail formList={wasteWaterFcltINfo} @@ -334,6 +374,8 @@ export function PbnstBuseForm({ form={form} moClass="grid grid-cols-12 gap-4" sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} /> <h1 className={formH1Class}>재이용 원수취수 현황</h1> @@ -349,9 +391,17 @@ export function PbnstBuseForm({ </Button> </div> <RuseMngTable - tableData={fcOrgwtFiled} + 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> @@ -396,16 +446,28 @@ export function PbnstBuseForm({ )} </div> <div> - <RuseMngTable - tableData={pplInstls} + <RuseMngTableForm + key={`pplInstls-${indexMng}-${indexBiz}`} // 이게 핵심! + tableData={ + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` + ) ?? [] + } headList={pbnst.pplInstlsHeadLisat} code={ppiSelectList ?? []} - ref={ref} + //ref={ref} + indexMng={indexMng} + indexBiz={indexBiz} + form={form} + formNm={"pplInstls"} upHeadList={[]} onTableSet={(val) => { - if (!ref.current) return; + const pplSum = form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.pplInstls` + ); + if (!pplSum) return; let sum = 0; - ref.current.forEach((item) => { + pplSum.forEach((item) => { sum += Number(item.cpct) || 0; }); setSumCpct(sum); @@ -419,6 +481,8 @@ export function PbnstBuseForm({ form={form} moClass="grid grid-cols-12 gap-4" sonClass="col-span-4" + indexMng={indexMng} + indexBiz={indexBiz} /> <div key={"hasu"}> <h1 className={formH1Class}>{"하수처리수 재이용수 수요처"}</h1> @@ -447,74 +511,61 @@ export function PbnstBuseForm({ 수요처 추가 </Button> </div> - {fcDemands.map((field, index) => ( + {( + form.getValues( + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands` + ) || [] + ).map((field, index) => ( <div - key={index + "loot"} + 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={`fcDemands.${index}.dmdCoNm`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdCoNm`} render={({ field: f }) => ( <FormUi label="수요처명"> <SearchInputText - label={'수요처'} + label={"수요처"} initValue={f.value} setValue={(val) => { f.onChange(val); - if (val) getDemandCompList(val, 3); + if (val && val.length > 2) { + getDemandCompList(val, 3); + } }} - setRtnData={(valList: any[]) => { - if ( - valList.length > 0 && - valList['0'] - ) { + setRtnData={(valList: any) => { + if (valList) { form.setValue( - `fcDemands.${index}.pbnstRuseFcltBizPk`, - form.getValues('pbnstRuseFcltBizPk') + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoFk`, + valList.dmdInfoPk ); form.setValue( - `fcDemands.${index}.pbnstRuseFcltFk`, - form.getValues('pbnstRuseFcltFk')??'' - + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`, + valList.daddr ); form.setValue( - `fcDemands.${index}.dmdCoNm`, - valList['0'].dmdCoNm + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`, + valList.useUsgCd ); form.setValue( - `fcDemands.${index}.daddr`, - valList['0'].daddr + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`, + valList.splyCpct ); form.setValue( - `fcDemands.${index}.useUsgCd`, - valList['0'].useUsgCd - ); - form.setValue( - `fcDemands.${index}.splyCpct`, - valList['0'].splyCpct - ); - form.setValue( - `fcDemands.${index}.splyFmYn`, - valList['0'].splyFmYn ?? "Y" - ); - form.setValue( - `fcDemands.${index}.dmdInfoFk`, - valList['0'].dmdInfoPk?.toString() ?? "" + `items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.dmdInfoFk`, + valList.dmdInfoPk?.toString() ); } - }} - searchList={demandCompList?.map((item=>{ - return({ + searchList={demandCompList?.map((item) => { + return { ...item, - searchNm:item.dmdCoNm, - searchPk:item.dmdInfoPk - }) - })) - } - + searchNm: item.dmdCoNm, + searchPk: item.dmdInfoPk, + }; + })} ></SearchInputText> </FormUi> )} @@ -523,7 +574,7 @@ export function PbnstBuseForm({ <div key={index + "keySon2"} className="col-span-4"> <FormField control={form.control} - name={`fcDemands.${index}.daddr`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.daddr`} render={({ field: f }) => ( <FormUi label="위치(주소)"> <Input @@ -541,16 +592,16 @@ export function PbnstBuseForm({ <div key={index + "keySon3"} className="col-span-4"> <FormField control={form.control} - name={`fcDemands.${index}.useUsgCd`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.useUsgCd`} render={({ field: f }) => ( <FormUi label="사용용도"> - <SelectBox + <SelectBox label={""} selectClass={""} className="w-full" selectArray={code.dmdUszCd} onSelectValue={f.onChange} - value={f.value?? code.dmdUszCd[0]?.val} + value={f.value ?? code.dmdUszCd[0]?.val} /> </FormUi> )} @@ -559,7 +610,7 @@ export function PbnstBuseForm({ <div key={index + "keySon4"} className="col-span-3"> <FormField control={form.control} - name={`fcDemands.${index}.splyBgngDay`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyBgngDay`} render={({ field: f }) => ( <FormUi label="공급시작일"> <DatePicker @@ -577,7 +628,7 @@ export function PbnstBuseForm({ <div key={index + "keySon5"} className="col-span-3"> <FormField control={form.control} - name={`fcDemands.${index}.splyEndDay`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyEndDay`} render={({ field: f }) => ( <FormUi label="공급종료일"> <DatePicker @@ -595,7 +646,7 @@ export function PbnstBuseForm({ <div key={index + "keySon6"} className="col-span-3"> <FormField control={form.control} - name={`fcDemands.${index}.splyCpct`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyCpct`} render={({ field: f }) => ( <FormUi label="(계약)공급량(m3/일)"> <Input @@ -613,7 +664,7 @@ export function PbnstBuseForm({ <div key={index + "keySon7"} className="col-span-3"> <FormField control={form.control} - name={`fcDemands.${index}.splyFmYn`} + name={`items.${indexMng}.fcBizs.${indexBiz}.fcDemands.${index}.splyFmYn`} render={({ field: f }) => ( <FormUi label="공급 유량계 유무"> <SelectBox @@ -640,14 +691,17 @@ export function PbnstBuseForm({ <UiModal open={isFcOrgwts} onOpenChange={(open: boolean) => setIsFcOrgwts(open)} - bodyClass={"w-[50vw] max-w-none h-[60vh]"} + bodyClass={"w-[50vw] max-w-none h-[90vh]"} body={ <FcOrgwtsRegModal closeModal={() => { setIsFcOrgwts(false); }} onRightSet={(val) => { - form.setValue("fcOrgwts", val); + form.setValue( + `items.${indexMng}.fcBizs.${indexBiz}.fcOrgwts`, + val + ); }} ></FcOrgwtsRegModal> } @@ -668,7 +722,6 @@ export function PbnstBuseForm({ getDemandCompList(searchText, pageCnt); }} rtnInputData={(data) => { - console.log(" rtn data ", data); regDemandCompany(data as DemandCompType); setIsDmdModal({ isMoal: false, data: data as DemandCompType }); }} 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 7e7374ef4..66acb0bf8 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -1,12 +1,16 @@ "use client"; import { useWrStore } from "@/app/store"; -import { FileUpload, FormUi, SelectBox } from "@common/business_components/ui"; +import { + FileUpload, + FormUi, + SelectBox, + type SelectDataType, +} from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import { Button, Input } from "@common/components"; -import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useRef, useState } from "react"; -import { useFieldArray, useForm } from "react-hook-form"; +import { useFieldArray, useForm, type UseFormReturn } from "react-hook-form"; import { z } from "zod"; import { commonButonSize, @@ -14,31 +18,37 @@ import { formTableName, } from "@/components/lib/class/comClass"; import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr"; -import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable"; import { pbnstRegZod, type customPbnst, - type fcBizType, type fcFileType, - type operType, + type PbnstRegArrrayType, type selectLabel, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { Label } from "@common/business_components/ui/form/lib/label"; import React from "react"; +import RuseMngTableForm from "@/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm"; export type FilesType = { atflCd: string; file: File; }; export function PbnstMngForm({ + form, formType, firstFcltData, + indexMng , + setIndexMng, }: { +form: UseFormReturn<{items:PbnstRegArrrayType}>; formType: string; firstFcltData?: customPbnst; + indexMng: number; + setIndexMng: (index: number) => void; }) { const { + code, pbnst, pbnstInsert, pbnstMngData, @@ -49,86 +59,84 @@ export function PbnstMngForm({ appendRuseFclt, } = useWrStore((state) => state); + const { pbnstRes } = pbnst; const [regFileList, setRegFileList] = useState<fcFileType[] | null>(null); const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null); const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null); const [fcltNm, setFcltNm] = useState<selectLabel[] | null>(null); - const [fcOpresData, setFcOpresData] = useState<operType[] | null>(null); + //const [fcOpresData, setFcOpresData] = useState<operType[] | null>(null); + const [mngMtdCode, setMngMtdCode] = + useState<{ name: string; val: SelectDataType[] }[]>(); const [progress, setProgress] = useState(0); //const new File([] as BlobPart[], "") 파일 다운로드 활용 - const ref = useRef<operType[] | null>(null); + //const ref = useRef<operType[] | null>(null); - const form = useForm<z.infer<typeof pbnstRegZod>>({ - resolver: zodResolver(pbnstRegZod), - defaultValues: - formType === "reg" && pbnst.pbnstMngRegData - ? pbnst.pbnstMngRegData[0] - : formType === "update" && - typeof pbnst.pbnsUpdateIndex.mng === "number" && - pbnst.pbnsUpdateIndex.mng >= 0 && - pbnst.pbnstRes - ? pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng] - : formType === "sttn" && firstFcltData - ? { - ruseUtztnFcltNm: firstFcltData?.ruseUtztnFcltNm, - fcltCpct: firstFcltData?.fcltCpct, - hasuhasu: firstFcltData?.hasuhasu, - ruseCpct: firstFcltData?.ruseCpct, - splyExtraCpct: firstFcltData?.splyExtraCpct, - fcOpers: firstFcltData?.fcOpers, - fcFiles: firstFcltData?.fcFiles, - } - : pbnstRegZod.parse({}), - }); + + // const form = useForm<z.infer<typeof pbnstRegZod>>({ + // resolver: zodResolver(pbnstRegZod), + // defaultValues: + // formType === "reg" && pbnst.pbnstMngRegData + // ? pbnst.pbnstMngRegData[0] + // : formType === "update" && + // typeof pbnst.pbnsUpdateIndex.mng === "number" && + // pbnst.pbnsUpdateIndex.mng >= 0 && + // pbnst.pbnstRes + // ? pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng] + // : formType === "sttn" && firstFcltData + // ? { + // ruseUtztnFcltNm: firstFcltData?.ruseUtztnFcltNm, + // fcltCpct: firstFcltData?.fcltCpct, + // ruseCpct: firstFcltData?.ruseCpct, + // splyExtraCpct: firstFcltData?.splyExtraCpct, + // fcOpers: firstFcltData?.fcOpers, + // fcFiles: firstFcltData?.fcFiles, + // } + // : pbnstRegZod.parse({}), + // mode: "onChange", + // }); const { fields: fcOpersField, append, remove, } = useFieldArray({ control: form.control, - name: "fcOpers", + name: `items.${indexMng}.fcOpers`, }); - const handleProgress = (percentage: string) => { - setProgress(Number(percentage)); - }; + const selectFclt = (val: number) => { - if (pbnst.pbnstRes && pbnst.pbnstRes[val]) { - getBizCycle(pbnst.pbnstRes[val]); - form.reset(pbnst.pbnstRes[val]); + // if (pbnst.pbnstRes && pbnst.pbnstRes[val]) { + // getBizCycle(pbnst.pbnstRes[val]); + // // form.reset(pbnst.pbnstRes[val]); - form.setValue("hasuhasu", Number(pbnst.efflAmnt) ?? 0); - getpbnstInsertIndex({ ...pbnst.pbnsUpdateIndex, mng: val }); - } + // getpbnstInsertIndex({ ...pbnst.pbnsUpdateIndex, mng: val }); + // } }; const plusHist = () => { - const currentTableDataFromRef = ref.current ? [...ref.current] : []; - const regData = { + append( { choose: false, - pbnstRuseFcltFk: form.getValues("pbnstRuseFcltPk") ?? "", + pbnstRuseFcltFk: form.getValues(`items.${indexMng}.pbnstRuseFcltPk`) ?? "", rgtr: "", mdfr: "", operMthd: "", rprtvBzenty: "", bgngDt: new Date(), endDt: new Date(), - }; - const newDataForRHF = [...currentTableDataFromRef, regData]; - form.setValue("fcOpers", newDataForRHF, { - shouldValidate: true, // 필요하다면 유효성 검사 실행 - shouldDirty: true, // 폼 상태를 dirty로 변경 - }); + }) + }; const removeSelected = () => { - if (!ref.current) return; - const selectedIdxs = ref.current - .map((item, idx) => (item.choose ? idx : -1)) - .filter((idx) => idx !== -1); - selectedIdxs.reverse().forEach((idx) => remove(idx)); + + const nowOpers = form.getValues(`items.${indexMng}.fcOpers`); + if(!nowOpers) return; + + const selectedIdxs = nowOpers.map((item, idx) => (item.choose ? idx : -1)) + .filter((idx) => idx !== -1); + selectedIdxs.reverse().forEach((idx) => remove(idx)); }; const fileHandler = (files: File[], type: string) => { @@ -203,79 +211,87 @@ export function PbnstMngForm({ // 등록할때 신규 값을 계속 가지고 있으려고 useEffect(() => { - if ( - formType === "reg" && - firstFcltData && - (form.getValues("swtrmtFcltFk") === "" || - form.getValues("swtrmtFcltFk") === undefined) - ) { - form.setValue("swtrmtFcltFk", firstFcltData.swtrmtFcltFk); - form.setValue("pbnstRuseFcltPk", String(firstFcltData.pbnstRuseFcltPk)); - form.setValue("fcBizs", firstFcltData.fcBizs); - } - }, [firstFcltData]); + // if ( + // formType === "reg" && + // firstFcltData && + // (form.getValues(`items.${indexMng}.swtrmtFcltFk`) === "" || + // form.getValues(`items.${indexMng}.swtrmtFcltFk`) === undefined) + // ) { + // form.setValue(`items.${indexMng}.swtrmtFcltFk`, firstFcltData.swtrmtFcltFk); + // form.setValue( + // `items.${indexMng}.pbnstRuseFcltPk`, + // String(firstFcltData.pbnstRuseFcltPk) + // ); + // form.setValue(`items.${indexMng}.fcBizs`, firstFcltData.fcBizs); + // } + console.log('indexMng ', indexMng) + }, [indexMng]); useEffect(() => { - const defaultFiles = form.getValues("fcFiles"); - - if (defaultFiles && defaultFiles.length > 0) { - const relationFileList = defaultFiles.filter( - (item) => item.fileKnd === "계통도" - ); - - const planFileList = defaultFiles.filter( - (item) => item.fileKnd === "평면도" - ); - if (relationFileList.length > 0) - setRelationFiles( - relationFileList.map((item) => ({ - atflCd: item.fileTkn, - file: new File([] as BlobPart[], item.filePath), - })) - ); // 또는 파일 형식 변환 로직이 있다면 여기에 추가 - - if (planFileList.length > 0) - setPlanFiles( - planFileList.map((item) => ({ - atflCd: item.fileTkn, - file: new File([] as BlobPart[], item.filePath), - })) + if(indexMng>=0){ + const defaultFiles = form.getValues(`items.${indexMng}.fcFiles`); + if (defaultFiles && defaultFiles.length > 0) { + const relationFileList = defaultFiles.filter( + (item) => item.fileKnd === "계통도" ); + + const planFileList = defaultFiles.filter( + (item) => item.fileKnd === "평면도" + ); + if (relationFileList.length > 0) + setRelationFiles( + relationFileList.map((item) => ({ + atflCd: item.fileTkn, + file: new File([] as BlobPart[], item.filePath), + })) + ); // 또는 파일 형식 변환 로직이 있다면 여기에 추가 + + if (planFileList.length > 0) + setPlanFiles( + planFileList.map((item) => ({ + atflCd: item.fileTkn, + file: new File([] as BlobPart[], item.filePath), + })) + ); + }else{ + setRelationFiles(null); + setPlanFiles(null); + } } - }, [form.formState.defaultValues]); // 초기화 이후 1회 실행 + }, [form.watch(`items.${indexMng}`),indexMng]); // 초기화 이후 1회 실행 // 등록할때 신규 값을 계속 가지고 있으려고 useEffect(() => { - if ( - formType === "update" && - pbnst.pbnsUpdateIndex.biz >= 0 && - pbnst.pbnstRes - ) { - const bizData = pbnst.pbnstRes[pbnst.pbnsUpdateIndex.biz]; + // if ( + // formType === "update" && + // pbnst.pbnsUpdateIndex.biz >= 0 && + // pbnst.pbnstRes + // ) { + // const bizData = pbnst.pbnstRes[pbnst.pbnsUpdateIndex.biz]; - if (bizData) { - getBizCycle(bizData); - } - } + // if (bizData) { + // getBizCycle(bizData); + // } + // } }, [pbnst.pbnsUpdateIndex, pbnst.pbnstRes, formType, getBizCycle]); //신규 등록시 입력할때 데이터 넣기 useEffect(() => { - const formData = form.watch(); - formData.fcOpers = ref.current ? [...ref.current] : []; - formData.fcFiles = regFileList ? [...regFileList] : []; - if (formType === "reg") { - console.log("formData ", formData); - pbnstMngData([formData] as customPbnst[]); - } else if (formType === "update") { - const updateRes = pbnst.pbnstRes?.map((item) => { - if (item.pbnstRuseFcltPk === item.pbnstRuseFcltPk) { - item = formData as customPbnst; - } - return item; - }); - pbnstMngData(updateRes as customPbnst[]); - } + // const formData = form.watch(); + // formData.fcOpers = ref.current ? [...ref.current] : []; + // formData.fcFiles = regFileList ? [...regFileList] : []; + // if (formType === "reg") { + // console.log("formData ", formData); + // pbnstMngData([formData] as customPbnst[]); + // } else if (formType === "update") { + // const updateRes = pbnst.pbnstRes?.map((item) => { + // if (item.pbnstRuseFcltPk === item.pbnstRuseFcltPk) { + // item = formData as customPbnst; + // } + // return item; + // }); + // pbnstMngData(updateRes as customPbnst[]); + // } }, [form.formState, regFileList, formType, pbnst.pbnstRes]); useEffect(() => { @@ -288,13 +304,12 @@ export function PbnstMngForm({ text: item.ruseUtztnFcltNm, val: String(index), })); - if (fcltNmList) setFcltNm(fcltNmList); }, [pbnst.pbnstRes]); // 2. Define a submit handler. function onSubmit(values: z.infer<typeof pbnstRegZod>) { - values.fcOpers = fcOpresData || []; + values.fcOpers = []; values.fcFiles = regFileList || []; pbnstInsert(values); } @@ -310,15 +325,21 @@ export function PbnstMngForm({ } }, [planFiles]); + useEffect(() => { - console.log("form errors:", form.formState.errors); - }, [form.formState.errors]); + if (code.ruseMngMtd) { + setMngMtdCode([{ name: "ruseMngMtd", val: code.ruseMngMtd }]); + } + }, [code]); + + return ( <div className=" !mx-[1.6rem] !p-0r"> <div> <Form {...form}> - <form onSubmit={form.handleSubmit(onSubmit)}> + {/* <form onSubmit={form.handleSubmit()}> */} + <form> <div className="flex justify-between items-center mx-3 mb-3"> <div className="col-span-2 flex items-top"> <Label className={formTableName + "pr-3 col-span-2 "}> @@ -326,20 +347,30 @@ export function PbnstMngForm({ </Label> {formType === "update" ? ( - <SelectBox - label="" - className="mt-4 ml-2" - selectClass={undefined} - selectArray={fcltNm ?? []} - onSelectValue={(val) => { - selectFclt(Number(val)); - }} - value={""} + <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> + )} /> ) : ( <FormField control={form.control} - name="ruseUtztnFcltNm" + name={`items.${indexMng}.ruseUtztnFcltNm`} render={({ field }) => ( <FormUi label=""> <Input @@ -356,10 +387,6 @@ export function PbnstMngForm({ /> )} </div> - - {/* <Button onClick={addRuseFcltObj} type="button" size={commonButonSize}> - 추가 - </Button> */} </div> <div> @@ -385,27 +412,33 @@ export function PbnstMngForm({ </Button> </div> </div> - <RuseMngTable - tableData={fcOpersField} + <RuseMngTableForm + tableData={form.getValues(`items.${indexMng}.fcOpers`)||[]} headList={pbnst.pbnstMngUpHeadList} upHeadList={pbnst.pbnstMngNm} + code={mngMtdCode || []} onTableSet={(val) => { - setFcOpresData(val); + //setFcOpresData(val); }} - ref={ref} - ></RuseMngTable> + indexMng={indexMng} + form={form} + formNm={"fcOpers"} + // ref={ref} + ></RuseMngTableForm> </div> </div> <div> <h1 className={formH1Class}>재이용수 공급 가능량</h1> <div className="grid grid-cols-12 gap-4"> - <div className="col-span-3 mt-4"> + <div className="col-span-4 mt-4"> <FormField + key={`FormField-items.${indexMng}.splyExtraCpct`} control={form.control} - name="fcltCpct" + name={`items.${indexMng}.fcltCpct`} render={({ field }) => ( - <FormUi label="시설용량(m³/일)"> + <FormUi label="재이용 시설용량(m³/일)"> <Input + key={`items.${indexMng}.fcltCpct`} placeholder="" type="number" onChange={(e) => { @@ -417,32 +450,16 @@ export function PbnstMngForm({ )} /> </div> - <div className="col-span-3 mt-4"> + + <div className="col-span-4 mt-4"> <FormField + key={`FormField-items.${indexMng}.ruseCpct`} control={form.control} - name="hasuhasu" + name={`items.${indexMng}.ruseCpct`} render={({ field }) => ( - <FormUi label="하수처리량(m³/일)"> - <Input - placeholder="" - type="number" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - readOnly - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="ruseCpct" - render={({ field }) => ( - <FormUi label="재이용량(m³/일)"> + <FormUi label="재이용수공급량(m³/일)"> <Input + key={`items.${indexMng}.ruseCpct`} placeholder="" type="number" onChange={(e) => { @@ -454,13 +471,15 @@ export function PbnstMngForm({ )} /> </div> - <div className="col-span-3 mt-4"> + <div className="col-span-4 mt-4"> <FormField + key={`FormField-items.${indexMng}.splyExtraCpct`} control={form.control} - name="splyExtraCpct" + name={`items.${indexMng}.splyExtraCpct`} render={({ field }) => ( <FormUi label="공급여유량(m³/일)"> <Input + key={`items.${indexMng}.splyExtraCpct`} placeholder="" type="number" onChange={(e) => { diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx index 7f9ff4fef..971888e10 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegFormDetail/mngRegFormDetail.tsx @@ -1,16 +1,17 @@ -'use client' +"use client"; import { useWrStore } from "@/app/store"; import type { formDetailType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/headList"; import { formH1Class } from "@/components/lib/class/comClass"; import { safeDate } from "@/components/lib/func/commom"; import { + DatePicker, FormField, FormUi, SearchInputSelect, SelectBox, type SelectDataType, } from "@common/business_components/ui"; -import { DatePicker, Input } from "@common/components/ui"; +import { Input } from "@common/components/ui"; import { useState } from "react"; export default function MngRegFormDetail({ @@ -19,48 +20,55 @@ export default function MngRegFormDetail({ form, moClass, sonClass, - cycle, - onIputData, - searchSelectData + indexBiz, + indexMng, }: { formList: formDetailType[]; h1Title?: string; form: any; moClass?: string; - cycle?: string; + indexBiz?: number; + indexMng?: number; sonClass?: string; - onIputData?: (data: any) => void; - searchSelectData?: SelectDataType[]; }) { const { code } = useWrStore((state) => state); - const [searchData, setSearchData]= useState<string>('') - return ( <> {h1Title ? <h1 className={formH1Class}>{h1Title}</h1> : <></>} <div className={moClass}> - {formList?.map((item, index) => { - const fieldId = cycle ? `${cycle}.${item.id}` : item.id; + {formList?.map((formHead, index) => { + const fieldId = + typeof indexMng === "number" && + indexMng >= 0 && + typeof indexBiz === "number" && + indexBiz >= 0 + ? `items.${indexMng}.fcBizs.${indexBiz}.${formHead.id}` + : typeof indexMng === "number" && indexMng >= 0 + ? `items.${indexMng}.${formHead.id}` + : formHead.id; + return ( - <div className={sonClass} key={index + `${item.id}`}> + <div className={sonClass} key={index + `${formHead.id}`}> <FormField control={form.control} name={fieldId} render={({ field }) => ( - <FormUi label={item.lable}> - {item.type === "select" ? ( + <FormUi label={formHead.lable}> + {formHead.type === "select" ? ( <Input placeholder="" type="text" {...field} /> - ) : item.type === "date" ? ( + ) : formHead.type === "date" ? ( <DatePicker mode={"single"} - selected={safeDate(field.value) || new Date()} - onSelect={(date: Date | undefined) => - field.onChange(date) - } className={"rounded-lg !w-full"} + field={{ + value: safeDate(field.value) || new Date(), + onChange: (date: Date | undefined) => + field.onChange(date), + }} + selectClass={"w-full"} /> - ) : item.type === "number" ? ( + ) : formHead.type === "number" ? ( <Input placeholder="" type="number" @@ -68,8 +76,9 @@ export default function MngRegFormDetail({ onChange={(e) => { field.onChange(Number(e.target.value)); }} + readOnly={formHead.option === "readOnly"?true:false} /> - ) : item.type === "selectYn" ? ( + ) : formHead.type === "selectYn" ? ( <SelectBox label={""} selectClass={""} @@ -78,7 +87,7 @@ export default function MngRegFormDetail({ onSelectValue={(val: string | number) => field.onChange(val) } - value={field.value} + value={field.value ?? "Y"} /> ) : ( <Input @@ -86,6 +95,7 @@ export default function MngRegFormDetail({ type="text" value={field.value ?? ""} onChange={field.onChange} + readOnly={formHead.option === "readOnly"?true:false} /> )} </FormUi> @@ -98,4 +108,3 @@ export default function MngRegFormDetail({ </> ); } - diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index 3d0eed82f..f60fb8620 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -10,7 +10,6 @@ import { useEffect, useState } from "react"; import { getCity, tableData } from "@/components/lib/func/commom"; import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { headMakeColSpan } from "@/app/ruseFcltMng/fcltReg/rainReg/TableHead"; import RainRegForm from "@/components/ui/form/fcltReg/rainReg/rainRegForm"; import RswtrRegForm from "@/components/ui/form/fcltReg/rswtrReg/rswtrRegForm"; import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm"; diff --git a/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx index 1b6b3950e..92b40e146 100644 --- a/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx @@ -10,7 +10,6 @@ import { Button } from "@common/business_components/ui/table/lib/button"; import { Input } from "@common/components/ui"; import { ArrowLeft, ArrowRight } from "lucide-react"; import { useEffect, useRef, useState } from "react"; -import { useFieldArray } from "react-hook-form"; export default function FcOrgwtsRegModal({ onRightSet, closeModal }: { onRightSet?: (rightData:fcOrgwtType[]) => void,closeModal?:(val:boolean) =>void }) { const { code, pbnst, getSwtrmtFcltNm, searchFclts } = useWrStore((state) => state); @@ -22,7 +21,6 @@ export default function FcOrgwtsRegModal({ onRightSet, closeModal }: { onRightS const [inputVal, setInputVal] = useState<string>(""); useEffect(()=>{ - console.log("searchFclts", searchFclts); if(Array.isArray(searchFclts)){ const filteredData = searchFclts.filter((item) => { if(rightData){ diff --git a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx index 736fa6b41..a899f8128 100644 --- a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx @@ -1,9 +1,8 @@ "use client"; import { useWrStore } from "@/app/store"; import { - pbnstRegZod, type customPbnst, - type fcBizType, + type PbnstRegArrrayType, type pubHasuType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; @@ -17,64 +16,88 @@ import { } from "@common/components/ui"; import { useEffect, useState } from "react"; import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; +import { useFieldArray, type UseFormReturn } from "react-hook-form"; +import { writeRgtrAndMdfr } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg"; -export function PbnstRegModal({ data }: { data: pubHasuType }) { +export function PbnstRegModal({ + data, + form, +}: { + data: pubHasuType; + form: UseFormReturn<{ items: PbnstRegArrrayType }>; +}) { const { pbnst, pbnstInsert, pbnstMngData } = useWrStore((state) => { return state; }); - - const { pbnstRes } = pbnst; const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>( {} as customPbnst ); const [currentTab, setCurrentTab] = useState<string>("mng"); + const [indexMng, setIndexMng] = useState<number>(0); + const [indexBiz, setIndexBiz] = useState<number>(0); + const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => { + + const item = valuse.items[indexMng]; + const data = item ? writeRgtrAndMdfr([item]) : []; - const pbnstRegTotal = () => { - if (pbnst.pbnstMngRegData[0]) pbnstInsert(pbnst.pbnstMngRegData[0]); - }; + if(data && data[0]){ + pbnstInsert(data[0]) + } + }; const handleTabChange = (value: string) => { setCurrentTab(value); - }; + }; + + useEffect(() => { + console.log("form errors:", form.formState.errors); + }, [form.formState.errors]); + + useEffect(() => { if (data) { - 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); + const firstForm = form.getValues("items"); - // pbnstMngData([regData] as unknown as customPbnst[]) - } - regData = pbnstRegZod.parse(regData); - setPbnstBdstForm(regData as unknown as customPbnst); + 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); } - }, [data, pbnstRes]); + }, [data, form]); return ( <> @@ -93,7 +116,7 @@ export function PbnstRegModal({ data }: { data: pubHasuType }) { 차수별정보 </TabsTrigger> <Button - onClick={pbnstRegTotal} + onClick={ form.handleSubmit(onSubmit)} size={"sm"} className="!justify-end" > @@ -101,10 +124,22 @@ export function PbnstRegModal({ data }: { data: pubHasuType }) { </Button> </TabsList> <TabsContent className="max-h-full" value="mng"> - <PbnstMngForm formType={"reg"} firstFcltData={pbnstBdstForm} /> + <PbnstMngForm + form={form} + formType={"reg"} + firstFcltData={pbnstBdstForm} + indexMng={indexMng} + setIndexMng={function (index: number): void { + throw new Error("Function not implemented."); + }} + /> </TabsContent> <TabsContent className="max-h-full" value="buse"> <PbnstBuseForm + form={form} + indexMng={indexMng} + indexBiz={indexBiz} + setIndexBiz={setIndexBiz} formType={"reg"} firstBizData={pbnstBdstForm.fcBizs} /> diff --git a/apps/wr/components/ui/searchInput/searchInput.tsx b/apps/wr/components/ui/searchInput/searchInput.tsx index e7097363f..796c8c298 100644 --- a/apps/wr/components/ui/searchInput/searchInput.tsx +++ b/apps/wr/components/ui/searchInput/searchInput.tsx @@ -8,7 +8,7 @@ type thisProps = { label: string | undefined; initValue: string | undefined; setValue: (searchNm?: string) => void; - setRtnData: (rtnData: any[]) => void; + setRtnData: (rtnData: any) => void; searchList?: any[]; }; export default function SearchInputText({ @@ -42,7 +42,7 @@ export default function SearchInputText({ setTextValue(dmdCoNm); setValue(dmdCoNm); setIsOpen(false); - setRtnData(searchList || []); + setRtnData(searchList?.find((item) => item.dmdCoNm === dmdCoNm) || {}); }, [searchList, setRtnData, setValue] ); @@ -62,7 +62,9 @@ export default function SearchInputText({ document.removeEventListener("mousedown", handleClickOutside); }; }, []); - +useEffect(() =>{ + console.log('searchList ', searchList) +},[searchList]) return ( <div ref={wrapperRef}> diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx index 43a08e203..e4ffc1f8d 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx @@ -1,9 +1,13 @@ import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { customPbnst as OriginalCustomPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { selectClass, type TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { DatePicker, SelectBox, type SelectDataType } from "@common/business_components/ui"; +import { + DatePicker, + SelectBox, + type SelectDataType, +} from "@common/business_components/ui"; import { Checkbox, Input, @@ -20,44 +24,41 @@ type RuseMngTableProps = { tableData: any[]; headList: TableUpperProps[]; upHeadList: chHeadType[]; - code?: { name: string, val: SelectDataType[] }[]; - onTableSet?:(item:any)=> void; + code?: { name: string; val: SelectDataType[] }[]; + onTableSet?: (item: any) => void; + indexMng?: number; + indexBiz?: number; }; const RuseMngTable = React.forwardRef<any, RuseMngTableProps>( - ({ - tableData, - headList, - upHeadList, - code, - onTableSet - }, ref) => { + ( + { tableData, headList, upHeadList, code, onTableSet, indexMng, indexBiz }, + ref + ) => { const [tableState, setTableState] = useState([...tableData]); useEffect(() => { if (ref && typeof ref === "object" && "current" in ref) { ref.current = tableState; } - if(onTableSet) - onTableSet (tableState) - }, [tableState,onTableSet]); - - - + if (onTableSet) onTableSet(tableState); + }, [tableState, onTableSet]); useEffect(() => { - if(tableData) - setTableState(tableData); + if (tableData) setTableState(tableData); }, [tableData]); return ( <> - <Table variant="secondary"> + <Table key={`table-${indexMng}-${indexBiz}`} variant="secondary"> <TableHeader className="font-bold"> {upHeadList ? ( headMakeprfmnc(headList, upHeadList) ) : ( <TableRow key={"table-row-test"}> {headList.map((head) => ( - <TableHead key={"table-head-row " + head.id} className={`border border-gray-600 px-2 py-1 `}> + <TableHead + key={"table-head-row " + head.id} + className={`border border-gray-600 px-2 py-1 `} + > {head.title} </TableHead> ))} @@ -72,54 +73,58 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>( <TableCell key={`${head.id}-${j}`} className="text-center whitespace-nowrap" - onClick={() => { }} + onClick={() => {}} > {head.edit === true ? ( <Input className={`${head.type === "number" ? "text-right" : "text-center"} !text-xl`} type={head.type} onChange={(txt) => { - setTableState(prev => { + setTableState((prev) => { const next = [...prev]; - next[i] = { ...next[i], [head.id]: txt.target.value }; + next[i] = { + ...next[i], + [head.id]: txt.target.value, + }; return next; - }) + }); }} - value={head.type === "number" ? - Number(tableState[i][head.id])||0 : tableState[i][head.id] || "" + value={ + head.type === "number" + ? Number(tableState[i][head.id]) || 0 + : tableState[i][head.id] || "" } /> ) : head.type === "select" ? ( <SelectBox label="" - selectArray={code.find(item => item.name === head.selectData)?.val ?? []} - value={ - tableState[i][head.id] || "" + selectArray={ + code?.find((item) => item.name === head.selectData) + ?.val ?? [] } + value={tableState[i][head.id] || ""} className={""} selectClass={selectClass} onSelectValue={(val) => { setTableState((prev) => { - prev[i][head.id] = val - return [...prev] - }) + prev[i][head.id] = val; + return [...prev]; + }); }} ></SelectBox> ) : head.type === "date" ? ( <DatePicker mode="single" field={{ - value: - tableState[i][head.id], // Provide a default Date value + value: tableState[i][head.id], // Provide a default Date value onChange: (date) => { - setTableState(prev => { + setTableState((prev) => { const next = [...prev]; next[i] = { ...next[i], [head.id]: date }; return next; - }) - } - } - } + }); + }, + }} selectClass={"w-full"} /> ) : head.type === "checkbox" ? ( @@ -129,14 +134,12 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>( onCheckedChange={(checked) => { console.log("checked", checked); setTableState((prev) => { - prev[i][head.id] = checked - return [...prev] - }) + prev[i][head.id] = checked; + return [...prev]; + }); }} - > - </Checkbox> - ) : - ( + ></Checkbox> + ) : ( `${item[head.id] || ""}` )} </TableCell> @@ -147,5 +150,6 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>( </Table> </> ); - }) -export default RuseMngTable; \ No newline at end of file + } +); +export default RuseMngTable; diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx new file mode 100644 index 000000000..2eeba6c69 --- /dev/null +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -0,0 +1,163 @@ +import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead"; +import type { TableUpperProps } from "@/app/store/common/type/header"; +import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; +import type { customPbnst as OriginalCustomPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; + +import { + DatePicker, + FormField, + FormUi, + SelectBox, + type SelectDataType, +} from "@common/business_components/ui"; +import { + Checkbox, + Input, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@common/components/ui"; +import React, { useEffect, useState } from "react"; + +type RuseMngTableProps = { + tableData: any[]; + headList: TableUpperProps[]; + upHeadList: chHeadType[]; + code?: { name: string; val: SelectDataType[] }[]; + onTableSet?: (item: any) => void; + indexMng?: number; + indexBiz?: number; + form?: any; + formNm?:string +}; + +const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>( + ({ tableData, headList, upHeadList, code, onTableSet, indexMng, form,formNm,indexBiz }, ref) => { + // const [tableState, setTableState] = useState([...tableData]); + + // // useEffect(() => { + + // // if (ref && typeof ref === "object" && "current" in ref) { + // // ref.current = tableState; + // // } + // // if (onTableSet) onTableSet(tableState); + // // }, [tableState, onTableSet]); + + // useEffect(() => { + + // if (tableData) + // setTableState(tableData); + // }, [tableData]); + + return ( + <> + <Table key={`table-${indexMng}-${indexBiz}`} variant="secondary"> + <TableHeader className="font-bold"> + {upHeadList ? ( + headMakeprfmnc(headList, upHeadList) + ) : ( + <TableRow key={"table-row-test"}> + {headList.map((head) => ( + <TableHead + key={"table-head-row " + head.id} + className={`border border-gray-600 px-2 py-1 `} + > + {head.title} + </TableHead> + ))} + </TableRow> + )} + </TableHeader> + + <TableBody> + {tableData.map((item, i) => ( + <TableRow key={i}> + {headList.map((head, j) => ( + <TableCell + key={`${head.id}-${j}`} + className="text-center whitespace-nowrap" + onClick={() => {}} + > + <FormField + control={form.control} + name={ + typeof indexMng === "number" && + indexMng >= 0 && + typeof indexBiz === "number" && + indexBiz >= 0? + `items.${indexMng}.fcBizs.${indexBiz}.${formNm}.${i}.${head.id}`: + typeof indexMng === "number" && indexMng >= 0? + `items.${indexMng}.${formNm}.${i}.${head.id}`: + `items.${indexMng}.${formNm}.${i}.${head.id}`} + render={({ field }) => ( + <FormUi label=""> + {head.edit === true ? ( + <Input + className={`${head.type === "number" ? "text-right" : "text-center"} !text-xl`} + type={head.type} + onChange={(txt) => { + field.onChange(txt.target.value); + }} + value={ + head.type === "number" + ? (Number(field.value) ?? 0) + : field.value || "" + } + /> + ) : head.type === "select" ? ( + <SelectBox + label="" + selectArray={ + code?.find( + (item) => item.name === head.selectData + )?.val ?? [] + } + value={ + field.value || "" + } + className={""} + selectClass={selectClass} + onSelectValue={(val) => { + field.onChange(val); + }} + ></SelectBox> + ) : head.type === "date" ? ( + <DatePicker + mode="single" + field={{ + value: field.value || new Date(), + onChange: (date: Date | undefined) => + field.onChange(date), + }} + selectClass={"w-full"} + /> + ) : head.type === "checkbox" ? ( + <Checkbox + className="" + checked={ field.value || false} + onCheckedChange={(checked) => { + field.onChange(checked); + + }} + ></Checkbox> + ) : ( + `${item[head.id] || ""}` + )} + </FormUi> + )} + /> + </TableCell> + ))} + </TableRow> + ))} + </TableBody> + </Table> + </> + ); + } +); +export default RuseMngTableForm; diff --git a/packages/common/business_components/src/ui/form_ui/index.tsx b/packages/common/business_components/src/ui/form_ui/index.tsx index 96214b6cf..27b74bd97 100644 --- a/packages/common/business_components/src/ui/form_ui/index.tsx +++ b/packages/common/business_components/src/ui/form_ui/index.tsx @@ -39,7 +39,7 @@ const FormUi = React.forwardRef<HTMLDivElement, FormUiProps>( checked={isChecked} onCheckedChange={handleCheckboxChange} /> - <label className="w-20 text-xl text-gray-600" htmlFor="check">해당없음</label> + <label className="w-28 text-xl text-gray-600" htmlFor="check">해당없음</label> </div> </div> {children} diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index c5c0ee0db..6ccaac946 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -2,10 +2,43 @@ import { SelectBox } from "../select"; import { Input } from "@common/components"; import { FormUi } from "../form_ui"; -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import type { ControllerRenderProps, UseFormReturn } from "react-hook-form"; import { SdmSearchForm } from "./sdmNameBox"; -import type { DemandCompType } from "../../../../../../apps/dm/app/store/sdmMng"; +import { set } from "date-fns"; + +// 수요처 정보 +export type DemandCompType = { + index : number | ''; + dmdInfoPk : string | ''; + dmdInfoFk : string | ''; + bzmnNo : string | ''; + dmdCoNm : string | ''; + daddr : string | ''; + telno : string | ''; + rgtr : string | ''; + useUsgCd : string | ''; + ctpvCd : string | ''; + sggCd : string | ''; + dmdAplyPswd : string | ''; + wntUntprc : number | ''; + dmndTmng : Date | ''; + dmndQty : number | ''; + grssClfg : number | ''; + tn : number | ''; + combResdch : number | ''; + tph : number | ''; + trbt : number | ''; + ph : number | ''; + blgcOxygDmndQnt : number | ''; + clIonQnt : number | ''; + smll : number | ''; + cdtnv : number | ''; + crmty : number | ''; + rmrk : string | ''; + reqDt : string | ''; +} + type SelectDataType = { text: string; @@ -32,16 +65,19 @@ interface SdmRegFormProps { dataList: DemandCompType[]; rtnValue: (searchText: string, pageCnt: number) => void; setIsDuplicate: (value: boolean) => void; + updateList?:DemandCompType } type FieldComponent = (field: ControllerRenderProps<FormSchema, keyof FormSchema>) => JSX.Element; -export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigunData, dataList, rtnValue, setIsDuplicate }: SdmRegFormProps) { +export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigunData, dataList, rtnValue, setIsDuplicate ,updateList}: SdmRegFormProps) { const [sidoValue, setSidoValue] = useState<string>(''); const [sigunValue, setSigunValue] = useState<string>(''); const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]); const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true); const [orgBznmNo, setOrgBznmNo] = useState<string>(''); + const [updateCoNm, setUpdateNm] = useState<string >('') + const initializeSigunData = useCallback((sidoCd: string) => { if (sidoCd === '0') { @@ -62,6 +98,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun type: string, field: ControllerRenderProps<FormSchema, keyof FormSchema> | undefined ) => { + if(!updateList?.dmdInfoPk) switch (type) { case "ctpvCd": initializeSigunData(val); @@ -77,7 +114,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun form.setValue('bznmTotNo', ''); break; } - }, [initializeSigunData, form]); + }, [initializeSigunData, form,updateList]); const handleCheckboxChange = useCallback((checked: boolean) => { setIsBznmTotNoDisabled(checked); @@ -90,6 +127,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun const setRtnData = useCallback((item: DemandCompType) => { const rtnCompData = item; + form.setValue('dmdCoNm', rtnCompData?.dmdCoNm || ''); form.setValue('dmdInfoPk', rtnCompData?.dmdInfoPk.substring(0,10) || ''); form.setValue('bznmTotNo', rtnCompData?.dmdInfoPk.substring(10,14)==='0000' ? '' : rtnCompData?.dmdInfoPk.substring(10,14)); @@ -124,26 +162,46 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun form.setValue('dmdCoNm', text); }, [form]); - const bznNoChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, noType: string) => { + const bznNoChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, noType: string, field?: ControllerRenderProps<FormSchema, keyof FormSchema>) => { const value = e.target.value; - + if(noType === 'dmdInfoPk') { if(orgBznmNo.substring(0,10) === value) { setIsDuplicate(true); } else { setIsDuplicate(false); } - form.setValue('dmdInfoPk', value); + field?.onChange(value); } else { if(orgBznmNo.substring(10,14) === value) { setIsDuplicate(true); } else { setIsDuplicate(false); } - form.setValue('bznmTotNo', value); + field?.onChange(value); } + }, [orgBznmNo, setIsDuplicate]); - }, [form, orgBznmNo, setIsDuplicate]); + + useEffect(() => { + if(updateList?.dmdInfoPk){ + form.reset(updateList) + if(updateList?.dmdInfoPk.slice(10,14) !== '0000') { + handleCheckboxChange( false); + form.setValue('bznmTotNo', updateList?.dmdInfoPk.slice(10,14)); + } else { + handleCheckboxChange( true); + } + form.setValue('dmdInfoPk', updateList?.dmdInfoPk.slice(0,10)); + setUpdateNm(updateList?.dmdCoNm) + // setSigunValue(updateList?.sggCd) + }else{ + handleCheckboxChange( true); + } + }, [updateList,form]); + + useEffect(() => { + },[form.formState.errors]) const formFields: Array<{ name: keyof FormSchema; @@ -154,28 +212,51 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun name: "ctpvCd", label: "시도", component: (field) => ( - <SelectBox + updateList?.dmdInfoPk ? ( + <Input + placeholder="시도" + type="text" + className="!text-xl text-gray-600" + onChange={(e) =>{field.onChange(e.target.value)} } + value={ selectSidoData.find(item => item.val === field.value?.trim() )?.text??''} + readOnly={!!updateList?.dmdInfoPk} + /> + ) : ( + <SelectBox selectClass={undefined} label="" selectArray={selectSidoData} - onSelectValue={(val) => onSelectValue(val.toString(), 'ctpvCd', field)} + onSelectValue={(val) => onSelectValue(val.toString(), 'ctpvCd', field??'')} className="" value={sidoValue} /> + ) ) }, { name: "sggCd", label: "시군구", component: (field) => ( + updateList?.dmdInfoPk ? ( + <Input + placeholder="시도" + type="text" + className="!text-xl text-gray-600" + onChange={(e) =>{field.onChange(e.target.value)} } + value={selectSigunData.find(item => item.val === field.value?.trim() )?.text??''} + readOnly={!!updateList?.dmdInfoPk} + /> + ) : ( <SelectBox - selectClass={undefined} + selectClass={"!text-xl text-gray-600"} label="" selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sggCd', field)} className="" value={sigunValue} /> + + ) ) }, { @@ -185,7 +266,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun <SdmSearchForm rtnData={setRtnData} label="수요처명" - initValue={''} + initValue={updateCoNm} dataList={dataList} rtnValue={setRtnValue} rtnText={setRtnText} @@ -201,8 +282,9 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun placeholder="사업자등록번호를 입력하세요" type="text" className="!text-xl text-gray-600" - {...field} - onChange={(e) => bznNoChange(e, 'dmdInfoPk')} + onChange={(e) => bznNoChange(e, 'dmdInfoPk', field)} + value={field.value} + readOnly={!!updateList?.dmdInfoPk} /> ) }, @@ -220,8 +302,10 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun type="text" className="!mt-5 !text-xl text-gray-600" disabled={isBznmTotNoDisabled} - {...field} - onChange={(e) => bznNoChange(e, 'bznmTotNo')} + onChange={(e) => bznNoChange(e, 'bznmTotNo', field)} + // {...field} + value={ field.value} + readOnly={!!updateList?.dmdInfoPk} /> </FormUi> ) @@ -250,6 +334,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun /> ) }, + { name: "dmdAplyPswd", label: "패스워드", @@ -262,11 +347,18 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun /> ) } - ]; + ] return ( <> - {formFields.map(({ name, label, component }) => ( + {formFields.filter((item)=> + {if(updateList?.dmdInfoPk){ + return item.name !== 'dmdAplyPswd' + }else{ + return item + } + }) + .map(({ name, label, component }) => ( <FormField key={String(name)} control={form.control} diff --git a/packages/common/business_components/src/ui/sdmInsertForm/index.tsx b/packages/common/business_components/src/ui/sdmInsertForm/index.tsx index 4b4a94648..4e6ad06d6 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/index.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/index.tsx @@ -1,32 +1,14 @@ "use client"; - -/* import { useDmStore } from "@/app/store"; */ -import { SdmRegForm } from "./form"; +import { SdmRegForm, type DemandCompType } from "./form"; import { Button } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; -/* import { useRouter } from "next/navigation"; */ import { useCallback, useEffect, useState } from "react"; import { FormProvider, useForm, type SubmitHandler } from "react-hook-form"; import { toast, Toaster } from "sonner"; -/* import { Toaster, toast } from "react-hot-toast"; */ import * as z from "zod"; import type { SelectDataType } from "../search_input_select"; -export type DemandCompType = { - dmdInfoPk : string | ''; - bzmnNo : string | ''; - dmdCoNm : string | ''; - daddr : string | ''; - telno : string | ''; - rgtr : string | ''; - useUsgCd : string | ''; - ctpvCd : string | ''; - sggCd : string | ''; - dmdAplyPswd: string | ''; -} - - type thisProps = { selectSidoData: SelectDataType[]; selectSigunData: SelectDataType[]; @@ -34,9 +16,10 @@ type thisProps = { rtnValue: (searchText: string, pageCnt: number) => void; rtnInputData: (data: DemandCompType) => void; bodyClassNm?: string; + updateList?:DemandCompType } -const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean) => z.object({ +const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean ,updateList?:DemandCompType) => z.object({ ctpvCd: z.string().min(1, "시/도를 선택해주세요"), sggCd: z.string().min(1, "시/군/구를 선택해주세요"), dmdCoNm: z.string() @@ -57,19 +40,19 @@ const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean) => .max(40, "주소는 40자 이내로 입력해주세요"), telno: z.string() .min(8, "전화번호는 8자 이상 입력해주세요") - .max(12, "전화번호는 12자 이내로 입력해주세요") + .max(11, "전화번호는 11자 이내로 입력해주세요") .regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"), rgtr: z.string().optional(), - dmdAplyPswd : z.string() - .min(1, "패스워드를 입력해주세요") - .min(8, "패스워드는 8자 이상 입력해주세요") - .max(16, "패스워드는 16자 이내로 입력해주세요"), + dmdAplyPswd : updateList?.dmdInfoPk // 업데이트일경우 + ? z.string().optional() // 패스워드는 선택 사항이며 길이 제한 없음 + : z.string().optional() + .refine((val) => !val || (val.length >= 8 && val.length <= 16), "패스워드는 8자 이상 16자 이내로 입력해주세요"), + }); -type FormSchema = ReturnType<typeof createFormSchema>; -export type FormData = z.infer<FormSchema>; +type FormSchema = z.infer<ReturnType<typeof createFormSchema>>; -const defaultValues: FormData = { +const defaultValues: FormSchema = { ctpvCd: '', sggCd: '', dmdCoNm: '', @@ -78,7 +61,7 @@ const defaultValues: FormData = { daddr: '', telno: '', rgtr: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - dmdAplyPswd : '', + dmdAplyPswd: '', }; /** @@ -117,15 +100,15 @@ const defaultValues: FormData = { }, [insertSdmData]); */ -export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm}: thisProps) { +export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm, updateList}: thisProps) { /* const { insertSdmData } = useDmStore((state) => state); const router = useRouter(); */ - const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true); + const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(false); const [isDuplicate, setIsDuplicate] = useState(false); - const formSchema = createFormSchema(isBznmTotNoDisabled, isDuplicate); + const formSchema = createFormSchema(isBznmTotNoDisabled, isDuplicate, updateList ); - const form = useForm<z.infer<FormSchema>>({ + const form = useForm<FormSchema>({ resolver: zodResolver(formSchema), defaultValues, mode: "onChange", @@ -136,7 +119,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList // 체크박스 상태가 변경될 때마다 bznmTotNo 필드의 에러를 초기화 useEffect(() => { - if (isBznmTotNoDisabled) { + if (isBznmTotNoDisabled===true) { form.clearErrors('bznmTotNo'); form.setValue('bznmTotNo', ''); } @@ -146,7 +129,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList rtnValue(searchText, pageCnt); }, [rtnValue]); - const onSubmit: SubmitHandler<z.infer<FormSchema>> = async (data) => { + const onSubmit: SubmitHandler<FormSchema> = async (data) => { try { // form 에러 체크 const formErrors = form.formState.errors; @@ -160,27 +143,18 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList const formData = { ...data, dmdInfoPk, + bzmnNo: data.dmdInfoPk, }; + + console.log(' formData ', formData) - console.log(formData); /* await insertSdmData(formData); */ rtnInputData(formData as DemandCompType); - const queryParams = new URLSearchParams({ - dmdCoNm: data.dmdCoNm, - ctpvCd: data.ctpvCd, - sggCd: data.sggCd, - dmdInfoPk, - bznmTotNo: data.bznmTotNo || '', - daddr: data.daddr, - telno: data.telno, - }); //router.push(`/pages/sdmMng/sdmInfoInsert?${queryParams.toString()}`); - toast.success('수요처가 성공적으로 등록되었습니다.'); } catch (error) { console.error('Error submitting form:', error); - toast.error('수요처 등록에 실패했습니다.'); } }; @@ -203,6 +177,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList dataList={dataList} rtnValue={setRtnValue} setIsDuplicate={setIsDuplicate} + updateList={updateList} /> <div className="flex justify-center pt-4"> <Button diff --git a/packages/common/business_components/src/ui/sdmInsertForm/sdmNameBox.tsx b/packages/common/business_components/src/ui/sdmInsertForm/sdmNameBox.tsx index 83571b6ff..3c8fd7192 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/sdmNameBox.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/sdmNameBox.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; -import type { DemandCompType } from "../../../../../../apps/dm/app/store/sdmMng"; +import type { DemandCompType } from './form'; export type thisProps = { label: string | undefined; @@ -53,6 +53,12 @@ export const SdmSearchForm = ({label=undefined, initValue=undefined, rtnValue=() document.removeEventListener('mousedown', handleClickOutside); }; }, []); + + useEffect(() => { + if(initValue&& initValue?.length>0){ + setTextValue(initValue) + } + },[initValue]) return ( <div ref={wrapperRef}>