963 lines
33 KiB
TypeScript
963 lines
33 KiB
TypeScript
import ModalSimilarPage from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page";
|
|
import { useDmStore } from "@/app/store";
|
|
import {
|
|
CANDIDATE,
|
|
// DatePicker,
|
|
FormField,
|
|
FormLabel,
|
|
FormUi,
|
|
SelectBox,
|
|
UiModal,
|
|
} from "@common/business_components";
|
|
import { Input } from "@common/components";
|
|
import { Button, Label } from "@common/components/ui";
|
|
import { useSearchParams } from "next/navigation";
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { AccessibleFormField } from "./AccessibleFormField";
|
|
import {
|
|
type ControllerRenderProps,
|
|
type UseFormReturn,
|
|
type FieldError,
|
|
useWatch,
|
|
} from "react-hook-form";
|
|
import SearchInputText from "../common/searhDemandInput/component";
|
|
import React from "react";
|
|
import { formatDateToYMD, sanitizeInput } from "../common/utils/utils";
|
|
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
|
import type { SdmInfoFormData } from "@/app/store/sdmMng";
|
|
|
|
export interface SdmInfoRegFormProps {
|
|
form: UseFormReturn<SdmInfoFormData>;
|
|
onCheckboxChange?: (checked: boolean) => void;
|
|
facilityName?: string;
|
|
}
|
|
|
|
type FieldComponent = (
|
|
field: ControllerRenderProps<SdmInfoFormData, keyof SdmInfoFormData>
|
|
) => JSX.Element;
|
|
|
|
export function SdmInfoRegForm({
|
|
form,
|
|
onCheckboxChange,
|
|
facilityName,
|
|
}: SdmInfoRegFormProps) {
|
|
const { initializeCommonData, Sdm } = useDmStore((state) => state);
|
|
const { useTypesData, defaultRules, disableRules } = Sdm;
|
|
const searchParams = useSearchParams();
|
|
|
|
const [sdmNmValue, setSdmNmValue] = useState<string>(
|
|
searchParams.get("dmdCoNm") || ""
|
|
);
|
|
|
|
const [frontPHdata, setFrontPHdata] = useState("0");
|
|
const [backPHdata, setBackPHdata] = useState("0");
|
|
const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(false);
|
|
const [isSimilarCase, setIsSimilarCase] = useState(false);
|
|
const [key, setKey] = useState(0);
|
|
// 후보지 팝업 오픈 상태
|
|
|
|
//모달 조회에 필요한 데이터
|
|
const [sply, setSply] = useState<number>(0);
|
|
const [usageCd, setUsageCd] = useState<string>("청소");
|
|
const [money, setMoney] = useState<number>(0);
|
|
|
|
useEffect(() => {
|
|
initializeCommonData();
|
|
}, [initializeCommonData]);
|
|
|
|
useEffect(() => {
|
|
console.log("candidateTitle ", form.getValues("candidateTitle"));
|
|
}, [form.getValues]);
|
|
|
|
useEffect(() => {
|
|
if (useTypesData && useTypesData.length > 0) {
|
|
setTimeout(() => {
|
|
form.setValue("usePurpose", useTypesData[0]?.val?.toString() || "");
|
|
}, 500);
|
|
}
|
|
}, [useTypesData, form.setValue, form]);
|
|
|
|
useEffect(() => {
|
|
if (facilityName) {
|
|
setSdmNmValue(facilityName);
|
|
form.setValue("sdmNm", facilityName);
|
|
setKey((prev) => prev + 1);
|
|
}
|
|
}, [facilityName, form.setValue, form]);
|
|
|
|
useEffect(() => {
|
|
if (searchParams.get("dmdCoNm")) {
|
|
form.setValue("sdmNm", searchParams.get("dmdCoNm") || "");
|
|
setSdmNmValue(searchParams.get("dmdCoNm") || "");
|
|
setKey((prev) => prev + 1);
|
|
}
|
|
}, [searchParams, form.setValue, form]);
|
|
|
|
const searchCandidate = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
const dmdInfoId = JSON.parse(
|
|
sessionStorage.getItem("user") || "{}"
|
|
)?.dmdInfoId?.toString();
|
|
|
|
const url = `/map/popup?dmdInfoId=${encodeURIComponent(dmdInfoId)}`;
|
|
const width = window.screen.availWidth;
|
|
const height = window.screen.availHeight;
|
|
const left = 0;
|
|
const top = 0;
|
|
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`;
|
|
window.open(url, "candidatePopup", popupOptions);
|
|
};
|
|
|
|
const searchSimilarCase = (e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setIsSimilarCase(true);
|
|
};
|
|
|
|
const handleCheckboxChange = (checked: boolean) => {
|
|
setIsBznmTotNoDisabled(checked);
|
|
onCheckboxChange?.(checked);
|
|
};
|
|
|
|
useEffect(() => {
|
|
const watchPH = form.getValues(`ph`);
|
|
if (watchPH && watchPH !== undefined) {
|
|
const [frontPH, backPH] = watchPH.split("~");
|
|
if (frontPH) {
|
|
setFrontPHdata(frontPH);
|
|
}
|
|
if (backPH) {
|
|
setBackPHdata(backPH);
|
|
}
|
|
} else {
|
|
setFrontPHdata("0");
|
|
setBackPHdata("0");
|
|
}
|
|
}, [form.getValues(`ph`)]);
|
|
|
|
const isSetPh = useCallback(
|
|
(typePHdata: string, index: number) => {
|
|
const PHdata = form.getValues("ph");
|
|
const isPH = PHdata?.split("~")[index] || "";
|
|
if (index == 0) {
|
|
form.setValue("ph", `${isPH}~${typePHdata}`);
|
|
setBackPHdata(typePHdata);
|
|
} else if (index == 1) {
|
|
form.setValue("ph", `${typePHdata}~${isPH}`);
|
|
setFrontPHdata(typePHdata);
|
|
}
|
|
},
|
|
[form]
|
|
);
|
|
|
|
const usePurpose = useWatch({ control: form.control, name: "usePurpose" });
|
|
|
|
useEffect(() => {
|
|
if (!usePurpose) return;
|
|
|
|
// Apply default values
|
|
const defaults = defaultRules[usePurpose];
|
|
|
|
if (defaults) {
|
|
Object.entries(defaults).forEach(([field, value]) => {
|
|
form.setValue(field as keyof SdmInfoFormData, value, {
|
|
shouldDirty: true,
|
|
});
|
|
});
|
|
}
|
|
}, [form.getValues("usePurpose")]);
|
|
|
|
// 시설 선택시 이벤트
|
|
const selectComp = useCallback(
|
|
(rtnData: DemandCompType[]) => {
|
|
const rtnCompData = rtnData?.[0];
|
|
form.setValue("sdmNm", rtnCompData?.dmdCoNm || "");
|
|
},
|
|
[form]
|
|
);
|
|
|
|
const formFields: Array<{
|
|
name: keyof SdmInfoFormData;
|
|
label: string;
|
|
component: FieldComponent | undefined;
|
|
formIndex: number;
|
|
required?: boolean;
|
|
}> = [
|
|
{
|
|
name: "sdmNm",
|
|
label: "수요처선택",
|
|
formIndex: 0,
|
|
required: true,
|
|
component: (field) => (
|
|
<div key={key}>
|
|
<SearchInputText
|
|
label="수요처명"
|
|
setValue={(val) => {
|
|
setSdmNmValue(val || "");
|
|
field.onChange(val || "");
|
|
}}
|
|
setRtnData={selectComp}
|
|
initValue={facilityName || sdmNmValue}
|
|
{...field}
|
|
/>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "demandYmd",
|
|
label: "요구시기",
|
|
formIndex: 0,
|
|
required: true,
|
|
component: (field) => (
|
|
<div className="relative w-64">
|
|
{/* <DatePicker
|
|
mode="single"
|
|
selected={field.value as Date}
|
|
onSelect={(date) => {
|
|
field.onChange(date as Date);
|
|
}}
|
|
className=""
|
|
//defaultMonth={field.value as Date}
|
|
field={{
|
|
value: field.value as Date,
|
|
onChange: (date: Date | undefined) => {
|
|
field.onChange(date as Date);
|
|
},
|
|
}}
|
|
showOutsideDays={true}
|
|
selectClass={undefined}
|
|
/> */}
|
|
{/* 네이티브 input */}
|
|
<Input
|
|
className="w-full !text-xl text-right"
|
|
type="date"
|
|
onChange= {(e) => {
|
|
const selectedDate = e.target.value ? new Date(e.target.value) : null;
|
|
field.onChange(selectedDate);
|
|
}}
|
|
value={ formatDateToYMD(field.value as Date) }
|
|
/>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "demandQnty",
|
|
label: "요구수량(㎥/d)",
|
|
formIndex: 0,
|
|
required: true,
|
|
component: (field) => (
|
|
<Input
|
|
type="text"
|
|
className="!text-xl text-gray-600"
|
|
value={field.value as string}
|
|
onChange={(e) => {
|
|
field.onChange(e);
|
|
setSply(Number(e.target.value));
|
|
}}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
name: "usePurpose",
|
|
label: "사용용도",
|
|
formIndex: 0,
|
|
required: true,
|
|
component: (field) => (
|
|
<SelectBox
|
|
selectClass={undefined}
|
|
label=""
|
|
selectArray={useTypesData}
|
|
onSelectValue={(val) => {
|
|
field.onChange(val.toString());
|
|
setUsageCd(val.toString());
|
|
}}
|
|
className=""
|
|
value={field.value as string}
|
|
/>
|
|
),
|
|
},
|
|
{
|
|
name: "money",
|
|
label: "희망단가(원)",
|
|
formIndex: 0,
|
|
required: true,
|
|
component: (field) => (
|
|
<FormUi
|
|
onCheckboxChange={handleCheckboxChange}
|
|
isDisabled={isBznmTotNoDisabled}
|
|
>
|
|
<Input
|
|
type="text"
|
|
className="!text-xl text-gray-600"
|
|
value={field.value as string}
|
|
onChange={(e) => {
|
|
field.onChange(e);
|
|
setMoney(Number(e.target.value));
|
|
}}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
</FormUi>
|
|
),
|
|
},
|
|
{
|
|
name: "reqWaterQlty",
|
|
label: "요구수질",
|
|
formIndex: 0,
|
|
required: true,
|
|
component: undefined,
|
|
},
|
|
|
|
{
|
|
name: "candidateTitle",
|
|
label: CANDIDATE || "공급처 후보지 선택(필수아님)",
|
|
formIndex: 2,
|
|
component: () => (
|
|
<div>
|
|
<div className="-mt-14 float-right flex gap-10">
|
|
<Button
|
|
className="rounded-md"
|
|
color="sky"
|
|
size={"sm"}
|
|
onClick={searchCandidate}
|
|
>
|
|
후보지 조회
|
|
</Button>
|
|
<Button
|
|
className="rounded-md"
|
|
color="sky"
|
|
size={"sm"}
|
|
onClick={searchSimilarCase}
|
|
>
|
|
유사사례
|
|
</Button>
|
|
</div>
|
|
<div className="flex justify-center gap-10 mt-5">
|
|
{(form.getValues("candidateTitle") || []).map(
|
|
(candidate: any, index: number) => (
|
|
<Input
|
|
key={index}
|
|
placeholder={`후보지${index + 1}`}
|
|
type="text"
|
|
className="!text-xl w-[130px] text-gray-600"
|
|
value={candidate.ruseUtztnFcltNm}
|
|
readOnly
|
|
/>
|
|
)
|
|
)}
|
|
</div>
|
|
</div>
|
|
),
|
|
},
|
|
];
|
|
|
|
const normalFields = formFields.filter(
|
|
(f) => f.formIndex === 0 && f.component
|
|
);
|
|
|
|
const candidateFields = formFields.filter(
|
|
(f) => f.formIndex === 2 && f.component
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{normalFields.map(({ name, label, component, required }) =>
|
|
component ? (
|
|
<FormField
|
|
key={name}
|
|
control={form.control}
|
|
name={name}
|
|
render={({ field }) =>
|
|
name === "money" ? (
|
|
<div>
|
|
<Label className="text-black">희망단가(원)*</Label>
|
|
{component(field)}
|
|
</div>
|
|
) : (
|
|
// <FormUi label={label + "*"}>{component(field)}</FormUi>
|
|
<AccessibleFormField
|
|
field={field}
|
|
label={label}
|
|
required={required}
|
|
error={
|
|
typeof form.formState.errors[name]?.message === "string"
|
|
? (form.formState.errors[name] as FieldError)
|
|
: undefined
|
|
}
|
|
inputComponent={component(field)}
|
|
/>
|
|
)
|
|
}
|
|
/>
|
|
) : null
|
|
)}
|
|
|
|
<div className="mt-10">
|
|
<FormLabel className="text-xl">요구수질</FormLabel>
|
|
<div className="grid grid-cols-2 gap-x-10 gap-y-6 mt-3 mb-3">
|
|
<FormField
|
|
control={form.control}
|
|
name={`grssClfg`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={
|
|
!isDisabled ? `총대장균군수(개/mg)*` : "총대장균군수(개/mg)"
|
|
}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: "불검출"
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
{/* TODO: 총대장균군수 확인 필요*/}
|
|
{field.value !== null ? (
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`tn`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={
|
|
!isDisabled ? `총질소(T-N)(mg/L)*` : "총질소(T-N)(mg/L)"
|
|
}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`combResdch`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={
|
|
!isDisabled ? `결합잔류염소(mg/L)*` : "결합잔류염소(mg/L)"
|
|
}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const cleanValue = sanitizeInput(
|
|
e.target.value,
|
|
true
|
|
);
|
|
field.onChange(
|
|
cleanValue === "" ? null : Number(cleanValue)
|
|
);
|
|
}}
|
|
value={field.value ?? ""}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이상
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`tph`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={!isDisabled ? `총인(T-P)(mg/L)*` : "총인(T-P)(mg/L)"}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const cleanValue = sanitizeInput(
|
|
e.target.value,
|
|
true
|
|
);
|
|
field.onChange(
|
|
cleanValue === "" ? null : Number(cleanValue)
|
|
);
|
|
}}
|
|
value={field.value ?? ""}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`trbt`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi label={!isDisabled ? `탁도(NTU)*` : "탁도(NTU)"}>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<div className="col-span-1">
|
|
<Label className="text-xl">수소이온농도(PH)</Label>
|
|
<div className="flex flex-row items-center gap-2">
|
|
<Input
|
|
className="!text-xl w-36"
|
|
placeholder=""
|
|
type="text"
|
|
onChange={(e) => {
|
|
const cleanValue = sanitizeInput(e.target.value, true);
|
|
isSetPh(cleanValue, 1);
|
|
}}
|
|
value={frontPHdata ?? ""}
|
|
maxLength={5}
|
|
/>
|
|
<span className="text-xl mx-2">~</span>
|
|
<Input
|
|
className="!text-xl w-36 "
|
|
placeholder=""
|
|
type="text"
|
|
onChange={(e) => {
|
|
const cleanValue = sanitizeInput(e.target.value, true);
|
|
isSetPh(cleanValue, 0);
|
|
}}
|
|
value={backPHdata ?? ""}
|
|
maxLength={5}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<FormField
|
|
control={form.control}
|
|
name={`bod`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={
|
|
!isDisabled
|
|
? `생물학적 산소요구량(BOD)(mg/L)*`
|
|
: "생물학적 산소요구량(BOD)(mg/L)"
|
|
}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`clIonQnt`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={!isDisabled ? `염화물(mgCL/L)*` : "염화물(mgCL/L)"}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`smll`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi label={!isDisabled ? `냄새*` : "냄새"}>
|
|
<SelectBox
|
|
className="!text-2xl rounded-md"
|
|
label={""}
|
|
selectClass={undefined}
|
|
selectArray={[
|
|
{ text: "불쾌하지않을것", val: "불쾌하지않을것" },
|
|
{ text: "해당사항없음", val: "해당사항없음" },
|
|
]}
|
|
onSelectValue={(val: string | number) => {
|
|
field.onChange(val.toString());
|
|
}}
|
|
value={field.value}
|
|
readOnly={isDisabled}
|
|
onBlur={field.onBlur}
|
|
ref={field.ref}
|
|
/>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`cdtnv`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi
|
|
label={
|
|
!isDisabled ? `전기전도도(㎲/cm)*` : "전기전도도(㎲/cm)"
|
|
}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`crmty`}
|
|
render={({ field }) => {
|
|
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
|
const isDisabled = disabledFields
|
|
? disabledFields.includes(field.name)
|
|
: true;
|
|
return (
|
|
<FormUi label={!isDisabled ? `색도(도)*` : "색도(도)"}>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
const inputValue = e.target.value.replace(
|
|
/[^0-9]/g,
|
|
""
|
|
); // 정수만
|
|
field.onChange(
|
|
inputValue === "" ? null : Number(inputValue)
|
|
);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== null
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
maxLength={6}
|
|
disabled={isDisabled}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
|
이하
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name={`rmrk`}
|
|
render={({ field }) => {
|
|
return (
|
|
<FormUi label={"비고"}>
|
|
<div className="flex items-center gap-2">
|
|
<div className="relative flex-1 min-w-0">
|
|
<Input
|
|
type="text"
|
|
className="w-full pr-16 border py-2 text-right rounded-md"
|
|
placeholder=""
|
|
onChange={(e) => {
|
|
field.onChange(e.target.value);
|
|
}}
|
|
value={
|
|
field.value !== undefined && field.value !== ""
|
|
? `${field.value}`
|
|
: ""
|
|
}
|
|
onBlur={field.onBlur}
|
|
name={field.name}
|
|
ref={field.ref}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</FormUi>
|
|
);
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{candidateFields.map(({ name, label, component, required }, index) =>
|
|
component ? (
|
|
<FormField
|
|
key={name + index}
|
|
control={form.control}
|
|
name={name}
|
|
render={({ field }) => (
|
|
// <FormUi label={label}>
|
|
// {component(field)}
|
|
// </FormUi>
|
|
<AccessibleFormField
|
|
field={field}
|
|
label={label}
|
|
required={required}
|
|
error={
|
|
typeof form.formState.errors[name]?.message === "string"
|
|
? (form.formState.errors[name] as FieldError)
|
|
: undefined
|
|
}
|
|
inputComponent={component?.(field)}
|
|
/>
|
|
)}
|
|
/>
|
|
) : null
|
|
)}
|
|
|
|
{isSimilarCase && (
|
|
<UiModal
|
|
body={
|
|
<ModalSimilarPage sply={sply} usageCd={usageCd} money={money} />
|
|
}
|
|
bodyClass="sm:max-w-[100vw] w-[1400px] h-[900px]"
|
|
open={isSimilarCase}
|
|
onOpenChange={(open) => !open && setIsSimilarCase(false)}
|
|
noHeaderYn="Y"
|
|
noFooterYn="Y"
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|