Files
frontend/packages/common/business_components/src/ui/sdmInsertForm/index.tsx
T

196 lines
6.7 KiB
TypeScript

"use client";
import { SdmRegForm, type DemandCompType } from "./form";
import { Button } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useCallback, useEffect, useState } from "react";
import { FormProvider, useForm, type SubmitHandler } from "react-hook-form";
import { toast, Toaster } from "sonner";
import * as z from "zod";
import type { SelectDataType } from "../search_input_select";
type thisProps = {
selectSidoData: SelectDataType[];
selectSigunData: SelectDataType[];
dataList: DemandCompType[];
rtnValue: (searchText: string, pageCnt: number) => void;
rtnInputData: (data: DemandCompType) => void;
bodyClassNm?: string;
updateList?:DemandCompType
}
const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean ,updateList?:DemandCompType) => z.object({
ctpvCd: z.string().min(1, "시/도를 선택해주세요"),
sggCd: z.string().min(1, "시/군/구를 선택해주세요"),
dmdCoNm: z.string()
.min(1, "회사명을 입력해주세요")
.max(20, "회사명은 20자 이내로 입력해주세요"),
dmdInfoPk: z.string()
.min(1, "사업자등록번호를 입력해주세요")
.regex(/^\d{10}$/, "사업자등록번호는 10자리 숫자만 입력 가능합니다")
.refine(() => isBznmTotNoDisabled ? !isDuplicate : true, "이미 등록된 사업자등록번호입니다"),
bznmTotNo: isBznmTotNoDisabled
? z.string().optional()
: z.string()
.length(4, "종사업자등록번호는 4자리 숫자만 입력 가능합니다")
.refine(() => !isDuplicate, "이미 등록된 사업자등록번호입니다"),
daddr: z.string()
.min(1, "주소를 입력해주세요")
.min(6, "주소는 6자 이상 입력해주세요")
.max(40, "주소는 40자 이내로 입력해주세요"),
telno: z.string()
.min(8, "전화번호는 8자 이상 입력해주세요")
.max(11, "전화번호는 11자 이내로 입력해주세요")
.regex(/^[0-9]+$/, "전화번호는 숫자만 입력 가능합니다"),
rgtr: z.string().optional(),
dmdAplyPswd : updateList?.dmdInfoPk // 업데이트일경우
? z.string().optional() // 패스워드는 선택 사항이며 길이 제한 없음
: z.string().optional()
.refine((val) => !val || (val.length >= 8 && val.length <= 16), "패스워드는 8자 이상 16자 이내로 입력해주세요"),
});
type FormSchema = z.infer<ReturnType<typeof createFormSchema>>;
const defaultValues: FormSchema = {
ctpvCd: '',
sggCd: '',
dmdCoNm: '',
dmdInfoPk: '',
bznmTotNo: '',
daddr: '',
telno: '',
rgtr: '',
dmdAplyPswd: '',
};
/**
* 수요처 등록 폼
* @param selectSidoData 시/도 데이터
* @param selectSigunData 시/군/구 데이터
* @param dataList 수요처 목록
* @param rtnValue 검색 결과(텍스트) 콜백
* @param rtnInputData 수요처 리스트 콜백
* @returns
*/
/**
* 페이지에서 작업
const {Common, initializeCommonData, getDemandCompList, insertSdmData, Sdm} = useDmStore((state) => state);
const { selectSidoData, selectSigunData } = Common;
const { demandCompList } = Sdm;
// 공통데이터 (시도, 시군구 데이터 호출)
useEffect(() => {
initializeCommonData();
}, [initializeCommonData]);
// 컴포넌트에서 텍스트 검색 호출
const callback = useCallback((searchText: string, pageCnt: number) => {
searchText = searchText.trim();
if(searchText.length > 0) {
getDemandCompList(searchText, pageCnt);
}
}, [getDemandCompList]);
// 컴포넌트에서 수요처 등록 호출
const handleInsertSdmData = useCallback((data: DemandCompType) => {
insertSdmData(data);
}, [insertSdmData]);
*/
export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm, updateList}: thisProps) {
/* const { insertSdmData } = useDmStore((state) => state);
const router = useRouter(); */
const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(false);
const [isDuplicate, setIsDuplicate] = useState(false);
const formSchema = createFormSchema(isBznmTotNoDisabled, isDuplicate, updateList );
const form = useForm<FormSchema>({
resolver: zodResolver(formSchema),
defaultValues,
mode: "onChange",
criteriaMode: "all",
shouldFocusError: false,
shouldUnregister: false
});
// 체크박스 상태가 변경될 때마다 bznmTotNo 필드의 에러를 초기화
useEffect(() => {
if (isBznmTotNoDisabled===true) {
form.clearErrors('bznmTotNo');
form.setValue('bznmTotNo', '');
}
}, [isBznmTotNoDisabled, form]);
const setRtnValue = useCallback((searchText: string, pageCnt: number) => {
rtnValue(searchText, pageCnt);
}, [rtnValue]);
const onSubmit: SubmitHandler<FormSchema> = async (data) => {
try {
// form 에러 체크
const formErrors = form.formState.errors;
if (Object.keys(formErrors).length > 0) {
const errorMessage = Object.values(formErrors)[0]?.message || '입력값을 확인해주세요.';
toast.error(errorMessage);
return;
}
const dmdInfoPk = data.dmdInfoPk + (data.bznmTotNo || '0000');
const formData = {
...data,
dmdInfoPk,
bzmnNo: data.dmdInfoPk,
};
console.log(' formData ', formData)
/* await insertSdmData(formData); */
rtnInputData(formData as DemandCompType);
//router.push(`/pages/sdmMng/sdmInfoInsert?${queryParams.toString()}`);
} catch (error) {
console.error('Error submitting form:', error);
}
};
return (
<>
<div className="text-center mb-8">
<h1 className="text-4xl font-bold text-gray-900 underline">
수요처등록
</h1>
</div>
<div className= {bodyClassNm?bodyClassNm:"!max-w-3xl mx-auto bg-white rounded-lg shadow-md p-6"}>
<FormProvider {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<SdmRegForm
form={form}
onCheckboxChange={setIsBznmTotNoDisabled}
selectSidoData={selectSidoData}
selectSigunData={selectSigunData}
dataList={dataList}
rtnValue={setRtnValue}
setIsDuplicate={setIsDuplicate}
updateList={updateList}
/>
<div className="flex justify-center pt-4">
<Button
type="submit"
className="w-32 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
>
수요처등록
</Button>
</div>
</form>
</FormProvider>
</div>
<Toaster position="top-center" />
</>
);
}