Merge branch 'iipbs/wr/dev' into iipbs/dm/dev

This commit is contained in:
2026-06-23 11:42:50 +09:00
6 changed files with 72 additions and 137 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ type IntroCardItem = {
const INTRO_CARDS: IntroCardItem[] = [
{
title: "물 재이용 법",
title: "물재이용법",
desc: "물의 재이용 촉진 및 지원에 관한 법률을 시행하고, 일부 법률은 개정되었습니다.",
image: card01,
href: "/intro#law-plan",
+8 -8
View File
@@ -83,14 +83,14 @@ const MOCK: Record<TabKey, CaseItem[]> = {
sewage: [
{
id: "sewage-1",
title: "구리시 하수 재이용",
title: "구리시 하수처리수 재이용",
desc: "고농도 미세먼지 발생 및 폭염의 급증에 따라 공공하수처리시설 발생 재이용수 일부를 도로자동청소시스템에 활용하여 미세먼지 저감 및 폭염 취약성 완화",
imageSrc: "/images/landing/business/sewage/guri_01.png",
href: "/example#example-sewage-guri",
},
{
id: "sewage-2",
title: "부천시 하수재이용",
title: "부천시 하수처리수 재이용",
desc: "굴포하수처리시설 하수처리수 재이용수 생산시설 설치 운영을 통해 여월천 등 부천 관내 하천의 건천화 방지, 하천 생태계 보존 및 주민들에게 친수 공간 제공",
imageSrc: "/images/landing/business/sewage/bucheon_01.png",
href: "/example#example-sewage-bucheon",
@@ -104,42 +104,42 @@ const MOCK: Record<TabKey, CaseItem[]> = {
},
{
id: "sewage-4",
title: "파주시 하수 재이용 시설",
title: "파주시 하수처리수 재이용",
desc: "운정 및 금촌하수처리시설의 하수처리수를 막공법으로 재처리하여 파주LCD산업단지 내 3개 업체에 공업용수를 공급(LG디스플레이, 희성전자, 엔비텍)",
imageSrc: "/images/landing/business/sewage/paju_01.png",
href: "/example#example-sewage-paju",
},
{
id: "sewage-5",
title: "포항시 하수 재이용 시설",
title: "포항시 하수처리수 재이용",
desc: "포항시 내 공단 개발 확대로 지속적이고 안정적인 공업용수 공급 추진(포스코, 동국산업 등), 포항하수처리장 하수처리수를 재처리하여 공업용수로 공급",
imageSrc: "/images/landing/business/sewage/pohang_01.png",
href: "/example#example-sewage-pohang",
},
{
id: "sewage-6",
title: "울산광역시 하수 재이용 시설",
title: "울산광역시 하수처리수 재이용",
desc: "18년 갈수기시 낙동강 수질 악화로 울산석유화학단지 용수 공급 부족을 해소하기 위해 미포산단 내 한화케미칼 등 8개사 공업용수 공급",
imageSrc: "/images/landing/business/sewage/ulsan_01.png",
href: "/example#example-sewage-ulsan",
},
{
id: "sewage-7",
title: "여수시 하수 재이용 시설",
title: "여수시 하수처리수 재이용",
desc: "수요자가 원하는 양질의 공업용수를 저렴하게 공급하여 한정된 수자원의 효율적 이용 및 지역적 물 부족 해소, 하수재이용을 통한 오염총량 저감 및 방류수역 수질개선을 위한 여수국가산단 내 공업용수 공급(GS칼텍스, YNCC 등)",
imageSrc: "/images/landing/business/sewage/yeosu_01.png",
href: "/example#example-sewage-yeosu",
},
{
id: "sewage-8",
title: "보령시 하수 재이용 시설",
title: "보령시 하수처리수 재이용",
desc: "한국중부발전(주)의 보령 및 신보령화력발전소에 10,000㎥/일의 탈황용수 공급을 위해 보령하수처리시설의 하수처리수 재이용 사업 추진, 하수처리수 재이용을 통한 수자원 절약 및 지역 물 부족 해소",
imageSrc: "/images/landing/business/sewage/boryeong_01.png",
href: "/example#example-sewage-boryeong",
},
{
id: "sewage-9",
title: "아산시 하수 재이용 시설",
title: "아산시 하수처리수 재이용",
desc: "신도시 개발에 따른 인구 급증으로 발생하는 하수를 재처리하여 탕정산업단지(삼성디스플레이)에 공업용수를 안정적으로 공급함으로써 지역기반 및 활성화를 도모",
imageSrc: "/images/landing/business/sewage/asan_01.png",
href: "/example#example-sewage-asan",
@@ -1,10 +1,10 @@
import type { TableUpperProps } from "@/app/store/common/type/header";
export const htdTableHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도", widthPercent: 10 },
{ id: "cityText", title: "시도", widthPercent: 12 },
{ id: "sggText", title: "시군구", widthPercent: 10 },
{ id: "bdstNm", title: "시설명", widthPercent: 20 },
{ id: "daddr", title: "위치", widthPercent: 30 },
{ id: "frstArchPrmsnDt", title: "준공년도", widthPercent: 15 },
{ id: "frstArchPrmsnDt", title: "준공년도", widthPercent: 13 },
{ id: "archArea", title: "건축면적(㎡)", widthPercent: 15 },
];
@@ -69,12 +69,12 @@ export type chgBuilding = {
export type customRainBdst = z.infer<typeof rainZod>;
export const upHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도", widthPercent: 8 },
{ id: "cityText", title: "시도", widthPercent: 10 },
{ id: "sggText", title: "시군구", widthPercent: 8 },
{ id: "bdstNm", title: "시설명", widthPercent: 14 },
{ id: "bdstNm", title: "시설명", widthPercent: 15 },
{ id: "daddr", title: "위치", widthPercent: 22 },
{ id: "bdsgUsgText", title: "건축물용도", widthPercent: 12 },
{ id: "frstArchPrmsnDt", title: "최초건축허가일", widthPercent: 12 },
{ id: "frstArchPrmsnDt", title: "최초\n건축허가일", widthPercent: 9 },
{ id: "archArea", title: "건축면적(㎡)", widthPercent: 9 },
{ id: "lawTrgtYn", title: "법적의무대상여부", widthPercent: 8 },
{ id: "bdstChgYn", title: "건축물변경여부", widthPercent: 7 },
@@ -58,12 +58,12 @@ export type customRswtBdst = z.infer<typeof rswtZod>;
const rswtRes: customRswtBdst[] = [];
export const rswtUpHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도", widthPercent: 7 },
{ id: "cityText", title: "시도", widthPercent: 8 },
{ id: "sggText", title: "시군구", widthPercent: 7 },
{ id: "bdstNm", title: "건축물명", widthPercent: 13 },
{ id: "bdstNm", title: "건축물명", widthPercent: 14 },
{ id: "daddr", title: "위치", widthPercent: 20 },
{ id: "bdstUsgText", title: "건축물용도", widthPercent: 11 },
{ id: "frstArchPrmsnDt", title: "최초건축허가일", widthPercent: 11 },
{ id: "frstArchPrmsnDt", title: "최초\n건축허가일", widthPercent: 9 },
{ id: "archArea", title: "건축면적(㎡)", widthPercent: 8 },
{ id: "lawTrgtYn", title: "법적의무대상여부", widthPercent: 8 },
{ id: "chBuildingYn", title: "증축/개축/재축여부", widthPercent: 8 },
@@ -4,7 +4,6 @@ import React, { useCallback, useEffect, useState } from "react";
import type { ControllerRenderProps, UseFormReturn } from "react-hook-form";
import { FormField } from "../form";
import { FormUi } from "../form_ui";
import { SelectBox } from "../select";
import { SdmSearchForm } from "./sdmNameBox";
import { SearchAddressModal } from "../search_address/SearchAddressModal";
@@ -80,6 +79,11 @@ type FieldComponent = (
field: ControllerRenderProps<FormSchema, keyof FormSchema>,
) => React.ReactElement;
const getReadonlyInputClassName = (isReadonly?: boolean) =>
isReadonly
? "!text-xl text-gray-600 bg-gray-100 cursor-default"
: "!text-xl text-gray-600";
export function SdmRegForm({
form,
onCheckboxChange,
@@ -92,11 +96,6 @@ export function SdmRegForm({
readOnly,
openNetwork,
}: 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>("");
@@ -134,46 +133,12 @@ export function SdmRegForm({
const initializeSigunData = useCallback(
(sidoCd: string) => {
if (sidoCd === "0") {
setSigunValue("0");
setFilteredSigunData([{ text: "전체", val: "0" }]);
form.setValue("sggCd", "");
} else {
const newFilteredData = [
{ text: "전체", val: "0" },
...selectSigunData.filter(
(item: SelectDataType) => item.val.substring(0, 2) === sidoCd,
),
];
setSigunValue("0");
setFilteredSigunData(newFilteredData);
form.setValue("sggCd", "");
}
},
[selectSigunData],
);
const onSelectValue = useCallback(
(
val: string,
type: string,
field: ControllerRenderProps<FormSchema, keyof FormSchema> | undefined,
) => {
if (!updateList?.dmdInfoId)
switch (type) {
case "ctpvCd":
initializeSigunData(val);
setSidoValue(val);
field?.onChange(val);
form.setValue("dmdInfoId", "");
form.setValue("bznmTotNo", "");
break;
case "sggCd":
setSigunValue(val);
field?.onChange(val);
form.setValue("dmdInfoId", "");
form.setValue("bznmTotNo", "");
break;
}
},
[initializeSigunData, form, updateList],
[form],
);
const handleCheckboxChange = useCallback(
@@ -207,13 +172,11 @@ export function SdmRegForm({
// 수요처 불러온 후 사업자번호를 바꿀경우를 대비함
setOrgBznmNo(rtnCompData?.dmdInfoId);
const sidoCd = rtnCompData?.ctpvCd.trim() || "";
setSidoValue(sidoCd);
form.setValue("ctpvCd", sidoCd);
initializeSigunData(sidoCd);
setTimeout(() => {
const sigunCd = rtnCompData?.sggCd.trim() || "";
setSigunValue(sigunCd);
form.setValue("sggCd", sigunCd);
}, 100);
@@ -258,7 +221,6 @@ export function SdmRegForm({
);
if (!matchedSido) return;
setSidoValue(matchedSido.val);
form.setValue("ctpvCd", matchedSido.val, { shouldValidate: true });
initializeSigunData(matchedSido.val);
@@ -279,7 +241,6 @@ export function SdmRegForm({
if (!matchedSigun) return;
setSigunValue(matchedSigun.val);
form.setValue("sggCd", matchedSigun.val, { shouldValidate: true });
},
[form, initializeSigunData, selectSidoData, selectSigunData],
@@ -364,68 +325,6 @@ export function SdmRegForm({
label: string;
component: FieldComponent;
}> = [
{
name: "ctpvCd",
label: "시도",
component: (field) =>
updateList?.dmdInfoId ? (
<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?.dmdInfoId}
/>
) : (
<SelectBox
selectClass={undefined}
label=""
selectArray={selectSidoData}
onSelectValue={(val) =>
onSelectValue(val.toString(), "ctpvCd", field ?? "")
}
className=""
value={sidoValue}
/>
),
},
{
name: "sggCd",
label: "시군구",
component: (field) =>
updateList?.dmdInfoId ? (
<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?.dmdInfoId}
/>
) : (
<SelectBox
selectClass={"!text-xl text-gray-600"}
label=""
selectArray={filteredSigunData}
onSelectValue={(val) =>
onSelectValue(val.toString(), "sggCd", field)
}
className=""
value={sigunValue}
/>
),
},
{
name: "dmdCoNm",
label: "회사명",
@@ -449,7 +348,7 @@ export function SdmRegForm({
<Input
placeholder="사업자등록번호를 입력하세요"
type="text"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(!!updateList?.dmdInfoId)}
onChange={(e) => bznNoChange(e, "dmdInfoId", field)}
value={formatBusinessNumber(field.value ?? "")}
readOnly={!!updateList?.dmdInfoId}
@@ -468,7 +367,7 @@ export function SdmRegForm({
<Input
placeholder="여러사업장이 있을 경우 입력해주세요"
type="text"
className="!mt-5 !text-xl text-gray-600"
className={`${getReadonlyInputClassName(!!updateList?.dmdInfoId)} !mt-5`}
disabled={isBznmTotNoDisabled}
onChange={(e) => bznNoChange(e, "bznmTotNo", field)}
// {...field}
@@ -488,7 +387,7 @@ export function SdmRegForm({
{/* 우편번호 */}
<Input
type="text"
className="!text-xl text-gray-600 w-64"
className={`${getReadonlyInputClassName(true)} w-64`}
readOnly={true}
value={form.watch("zip") ?? ""}
placeholder="우편번호"
@@ -498,7 +397,7 @@ export function SdmRegForm({
{/* 주소 */}
<Input
type="text"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(true)}
readOnly={true}
value={address ?? ""}
placeholder="주소"
@@ -507,7 +406,7 @@ export function SdmRegForm({
<Input
placeholder="상세 주소를 입력하세요"
type="text"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(readOnly)}
readOnly={readOnly}
onChange={(e) => {
const value = e.target.value;
@@ -521,13 +420,51 @@ export function SdmRegForm({
<Input
placeholder="주소를 입력하세요"
type="text"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(readOnly)}
readOnly={readOnly}
{...field}
value={field.value ?? ""}
/>
),
},
{
name: "ctpvCd",
label: "시도",
component: (field) => (
<Input
placeholder="시도"
type="text"
className={getReadonlyInputClassName(true)}
onChange={(e) => {
field.onChange(e.target.value);
}}
value={
selectSidoData.find((item) => item.val === field.value?.trim())
?.text ?? ""
}
readOnly={true}
/>
),
},
{
name: "sggCd",
label: "시군구",
component: (field) => (
<Input
placeholder="시군구"
type="text"
className={getReadonlyInputClassName(true)}
onChange={(e) => {
field.onChange(e.target.value);
}}
value={
selectSigunData.find((item) => item.val === field.value?.trim())
?.text ?? ""
}
readOnly={true}
/>
),
},
{
name: "telno",
label: "전화번호",
@@ -538,7 +475,7 @@ export function SdmRegForm({
<Input
placeholder="전화번호를 입력하세요"
type="text"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(readOnly)}
value={formattedValue}
readOnly={readOnly}
onChange={(e) => {
@@ -557,7 +494,7 @@ export function SdmRegForm({
<Input
placeholder="패스워드를 입력하세요"
type="password"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(readOnly)}
readOnly={readOnly}
{...field}
value={field.value ?? ""}
@@ -571,7 +508,7 @@ export function SdmRegForm({
<Input
placeholder="패스워드를 입력하세요"
type="password"
className="!text-xl text-gray-600"
className={getReadonlyInputClassName(readOnly)}
readOnly={readOnly}
{...field}
value={field.value ?? ""}
@@ -595,8 +532,6 @@ export function SdmRegForm({
const inputId = `${name}-input`;
const errorId = `${name}-error`;
const isRequired = [
"ctpvCd",
"sggCd",
"dmdCoNm",
"dmdInfoId",
"daddr",