feat: 재이용시설현황 상단 검색바 시설명 자동완성 검색 구현 (조회 버튼, 초기화 버튼 미구현)
This commit is contained in:
@@ -106,6 +106,7 @@ const Map = () => {
|
||||
setIsSearchModalOpen={setIsSearchModalOpen}
|
||||
isOpen={isOpen}
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -108,15 +108,15 @@ const Map = () => {
|
||||
};
|
||||
|
||||
// MapSearchBar 래퍼 컴포넌트
|
||||
const CustomMapSearchBar = (props: any) => {
|
||||
return (
|
||||
<MapSearchBar
|
||||
{...props}
|
||||
searchType="공급처 후보지 조회"
|
||||
showApplyButton={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
// const CustomMapSearchBar = (props: any) => {
|
||||
// return (
|
||||
// <MapSearchBar
|
||||
// {...props}
|
||||
// searchType="공급처 후보지 조회"
|
||||
// showApplyButton={false}
|
||||
// />
|
||||
// );
|
||||
// };
|
||||
|
||||
return (
|
||||
<div className="bg-container">
|
||||
@@ -125,10 +125,21 @@ const Map = () => {
|
||||
isSearch={false}
|
||||
gisMaps={gisMaps}
|
||||
isMiniMap={true}
|
||||
searchView={CustomMapSearchBar}
|
||||
searchView={(props: any) => (
|
||||
<MapSearchBar
|
||||
searchType="공급처 후보지 조회"
|
||||
showApplyButton={false}
|
||||
checkedLayers={checkedLayers}
|
||||
checkedLayersData={checkedLayersData}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
detailView={(props: any) => (
|
||||
<NewWindowPopup
|
||||
onClose={handlePopupClose} // 메모이제이션된 함수 사용
|
||||
checkedLayers={checkedLayers}
|
||||
checkedLayersData={checkedLayersData}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
"use client"
|
||||
|
||||
import { Button, Input, Label } from "@common/components/ui";
|
||||
import React, { useCallback, useEffect, useRef, useState, useMemo } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { MapSearchFormLeft } from "./mapSearchForm";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { SearchBaseForm } from "@common/business_components";
|
||||
import { FormUi, SelectBox, SearchFormLeft, SearchFormRight, Form, FormField } from "@common/business_components/ui";
|
||||
import type { ReturnType, SelectDataType, EnvPartSelectDataType } from "@common/business_components/ui";
|
||||
import SearchInputText from "@/components/ui/searchInput/searchInput";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import type { EnvPartSelectDataType, ReturnType, SelectDataType } from "@common/business_components/ui";
|
||||
import { SelectBox } from "@common/business_components/ui";
|
||||
import { Button, Input, Label } from "@common/components/ui";
|
||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { MapSearchFormLeft } from "./mapSearchForm";
|
||||
|
||||
|
||||
// 건물 검색 타입 정의
|
||||
@@ -49,6 +45,8 @@ type SearchBaseType = {
|
||||
showQueryButton?: boolean;
|
||||
showInitButton?: boolean;
|
||||
showApplyButton?: boolean;
|
||||
checkedLayers?: string[];
|
||||
checkedLayersData?: any[];
|
||||
}
|
||||
|
||||
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`;
|
||||
@@ -82,17 +80,29 @@ export function MapSearchBar({
|
||||
rightClassName,
|
||||
showQueryButton = true,
|
||||
showInitButton = true,
|
||||
showApplyButton = true
|
||||
showApplyButton = true,
|
||||
checkedLayers = [],
|
||||
checkedLayersData = [],
|
||||
}: SearchBaseType) {
|
||||
|
||||
// 로딩바
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
// 상세 정보 조회를 위한 상태 추가
|
||||
const [popupFeature, setPopupFeature] = useState<any>(null);
|
||||
const { code } = useWrStore((state) => state);
|
||||
const [isChHead, setIsChHead] = useState(false);
|
||||
const ref = useRef<ReturnType>({} as ReturnType);
|
||||
|
||||
// zustand store에서 건물 검색 함수와 데이터 가져오기
|
||||
const {
|
||||
code,
|
||||
bdst,
|
||||
findBdst,
|
||||
wrMap,
|
||||
// buildingSearchRes,
|
||||
buildingNmSearch,
|
||||
buildingNmSearchMultiple
|
||||
} = useWrStore((state) => state);
|
||||
|
||||
const [selectedBuilding, setSelectedBuilding] = useState<BuildingInfo | null>(null);
|
||||
const [buildingSearchText, setBuildingSearchText] = useState("");
|
||||
const [buildingList, setBuildingList] = useState<BuildingInfo[]>([]);
|
||||
@@ -141,77 +151,16 @@ export function MapSearchBar({
|
||||
];
|
||||
}, [selectedSigun]);
|
||||
|
||||
// 건물 검색 API 호출 함수
|
||||
const searchBuildings = async (searchText: string) => {
|
||||
if (!searchText.trim()) {
|
||||
setBuildingList([]);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const flg = "41"; // 적절한 플래그 값으로 설정
|
||||
const sigunCode = selectedSigun.val !== '0' ? selectedSigun.val : '';
|
||||
const apiEndpoint = `${API_URL}/v1/reuseFc/building/${flg}/${sigunCode}/${encodeURIComponent(searchText)}`;
|
||||
|
||||
const response = await fetch(apiEndpoint, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API 호출 실패: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.status === 200 && Array.isArray(result.data)) {
|
||||
// 건물 검색 결과를 demandCompList 형태로 변환
|
||||
const convertedList = result.data.map((building: BuildingInfo) => ({
|
||||
dmdInfoPk: String(building.bdstInfoPk),
|
||||
dmdCoNm: building.bdstNm,
|
||||
daddr: building.daddr,
|
||||
useUsgCd: "",
|
||||
splyCpct: 0,
|
||||
splyFmYn: "Y",
|
||||
// 추가 필드들...
|
||||
}));
|
||||
setBuildingList(result.data);
|
||||
// 글로벌 상태에도 업데이트 (SearchInputText가 사용할 수 있도록)
|
||||
// getDemandCompList를 직접 호출하는 대신 상태를 직접 설정
|
||||
const { setBuildingSearchResults } = useWrStore.getState();
|
||||
if (setBuildingSearchResults) {
|
||||
setBuildingSearchResults(convertedList);
|
||||
}
|
||||
} else {
|
||||
setBuildingList([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("건물 검색 중 오류 발생:", error);
|
||||
setBuildingList([]);
|
||||
}
|
||||
};
|
||||
|
||||
// 조회 함수
|
||||
const queryVal = () => {
|
||||
console.log("조회버튼 클릭");
|
||||
if (searchType == '공급처 후보지 조회') {
|
||||
// queryClick({
|
||||
// partValue: partValue,
|
||||
// sidoValue: sidoValue,
|
||||
// sigunValue: sigunValue,
|
||||
// regionValue: regionValue,
|
||||
// unitWaterShedValue: untitWaterShedValue,
|
||||
// middleRegionValue: middleRegionValue,
|
||||
// envPartValue: envPartValue,
|
||||
// sidoText: selectedSido.text,
|
||||
// sigunText: selectedSigun.text,
|
||||
// });
|
||||
} else if (searchType == '우리동네가뭄지도보기') {
|
||||
} else if (searchType == '지도보기') {
|
||||
|
||||
// 46 : 하수처리시설
|
||||
// 47 : 하수재이용시설
|
||||
// 48 : 빗물이용시설
|
||||
// 49 : 중수도시설
|
||||
// 50 : 온배수시설
|
||||
console.log("조회버튼 클릭: ", checkedLayers);
|
||||
if (checkedLayers && checkedLayers.includes('48')) {
|
||||
// searchBuildings
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +257,27 @@ export function MapSearchBar({
|
||||
}
|
||||
}, [partValue, sidoValue, sigunValue, regionValue, untitWaterShedValue, middleRegionValue, envPartValue, ref]);
|
||||
|
||||
// buildingSearchText가 변경될 때 API 호출
|
||||
useEffect(() => {
|
||||
if (buildingSearchText && buildingSearchText.length > 1) {
|
||||
if (checkedLayers && checkedLayers.length > 0) {
|
||||
// 다중 레이어 검색
|
||||
// buildingNmSearchMultiple(checkedLayers, selectedSigun.val || "", buildingSearchText);
|
||||
buildingNmSearch("RNB", selectedSigun.val, buildingSearchText);
|
||||
} else {
|
||||
// 단일 레이어 검색
|
||||
// buildingNmSearch(checkedLayers[0], selectedSigun.val, buildingSearchText);
|
||||
}
|
||||
} else {
|
||||
// 검색 텍스트가 짧으면 리스트 초기화
|
||||
if (checkedLayers && checkedLayers.length > 0) {
|
||||
// buildingNmSearchMultiple(checkedLayers, selectedSigun.val || "", "");
|
||||
} else {
|
||||
buildingNmSearch("RNB", selectedSigun.val || "", "");
|
||||
}
|
||||
}
|
||||
}, [buildingSearchText]);
|
||||
|
||||
return (
|
||||
<div className="absolute left-1/2 -translate-x-1/2 bg-white flex items-center justify-center p-4 rounded-md shadow-lg w-auto min-w-fit">
|
||||
<div className={leftClassName ? leftClassName : `flex items-center justify-center space-x-2 `}>
|
||||
@@ -338,32 +308,23 @@ export function MapSearchBar({
|
||||
value={selectedSigun.val}
|
||||
selectClass={'w-32'}
|
||||
/>
|
||||
{/* <Label className="w-auto text-xl text-gray-600 whitespace-nowrap">시설명</Label>
|
||||
<div className="w-44">
|
||||
<Input className="mr-4" />
|
||||
</div> */}
|
||||
<div className="flex items-center">
|
||||
<Label className="w-20 text-xl text-gray-600">시설명</Label>
|
||||
<div className="w-64">
|
||||
<SearchInputText
|
||||
label="시설명"
|
||||
initValue={buildingSearchText}
|
||||
setValue={(searchText) => {
|
||||
setBuildingSearchText(searchText || "");
|
||||
if (searchText) {
|
||||
searchBuildings(searchText);
|
||||
}
|
||||
setValue={(searchNm?: string) => {
|
||||
setBuildingSearchText(searchNm || "");
|
||||
}}
|
||||
setRtnData={(buildingData) => {
|
||||
if (buildingData && buildingData.length > 0 && buildingData[0]) {
|
||||
// 선택된 건물 정보를 찾아서 설정
|
||||
const selectedBuildingInfo = buildingList.find(building =>
|
||||
building.bdstNm === buildingData[0].dmdCoNm
|
||||
);
|
||||
setSelectedBuilding(selectedBuildingInfo || null);
|
||||
console.log("선택된 시설:", selectedBuildingInfo);
|
||||
}
|
||||
setRtnData={function (rtnData: any): void {
|
||||
// 선택된 건물 데이터 처리
|
||||
// if (rtnData && rtnData.bdstInfoPk) {
|
||||
// setSelectedBuilding(rtnData);
|
||||
// setBuildingSearchText(rtnData.bdstNm || "");
|
||||
// }
|
||||
}}
|
||||
searchList={wrMap.buildingSearchRes || []}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -159,8 +159,8 @@ export default function Home() {
|
||||
<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="map/htdflSttn">시설 현황(지도)</Link>
|
||||
<Button className="w-full" onClick={() => {router.push('/map/htdflSttn')}}>
|
||||
시설 현황(지도)
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,8 +41,12 @@ export default React.memo(function GisTree({ checkedNodes = [], setCheckedNodes
|
||||
|
||||
// 기본 체크된 레이어들을 지도에 표시
|
||||
gisCore.setLayerOnMap(defaultChecked, true);
|
||||
|
||||
// 초기 체크된 레이어 정보를 상위로 전달
|
||||
const defaultCheckedNodesData = nodes.filter(node => defaultChecked.includes(node.id));
|
||||
onCheckedChange?.(defaultChecked, defaultCheckedNodesData);
|
||||
}
|
||||
}, [nodes]);
|
||||
}, [nodes]); // onCheckedChange를 의존성에 추가
|
||||
|
||||
// 초기 표시 여부가 'Y'인 레이어들 찾기
|
||||
const getDefaultCheckedNodes = (nodes, values = []) => {
|
||||
|
||||
Reference in New Issue
Block a user