feat: 시도, 시군구 zustand Store로 메인 화면에서 호출 후 SearchModal.tsx에서 사용
This commit is contained in:
@@ -6,6 +6,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
import SearchModal from "./searchModal/searchModal";
|
||||
import FeatureClickEventPopup from "./components/popupComponent/featureClickEventPopup";
|
||||
import useStore from "../../store/useStore";
|
||||
|
||||
// 타입 정의 추가
|
||||
export type LyrStngProps = {
|
||||
@@ -38,6 +39,12 @@ const Map = () => {
|
||||
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
|
||||
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태
|
||||
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
|
||||
const { fetchCtpvData, fetchSggData } = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
fetchCtpvData();
|
||||
fetchSggData();
|
||||
}, [fetchCtpvData, fetchSggData]);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
|
||||
@@ -29,19 +29,13 @@ interface SwagePrcsFcltProps {
|
||||
}
|
||||
|
||||
const SwagePrcsFclt: React.FC<SwagePrcsFcltProps> = ({
|
||||
var1,
|
||||
start1,
|
||||
start2,
|
||||
end1,
|
||||
end2,
|
||||
city,
|
||||
sgg,
|
||||
yearFilter,
|
||||
setVar1,
|
||||
setStart1,
|
||||
setStart2,
|
||||
setEnd1,
|
||||
setEnd2,
|
||||
setCity,
|
||||
setCtpvName,
|
||||
setSgg,
|
||||
@@ -114,57 +108,6 @@ const SwagePrcsFclt: React.FC<SwagePrcsFcltProps> = ({
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{/* 처리구역 면적 */}
|
||||
{/* <Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">처리구역 면적(m²)</Label>
|
||||
<Input
|
||||
className="w-[60px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
value={start2}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
setStart2(val);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault(); // Enter 키 기본 동작 방지
|
||||
handleSearch();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span className="mx-2 text-xl font-semibold">~</span>
|
||||
<Input
|
||||
className="mr-8 w-[60px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
value={end2}
|
||||
onChange={(e) => {
|
||||
// 숫자만 입력 허용
|
||||
const val = e.target.value.replace(/[^0-9]/g, "");
|
||||
setEnd2(val);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault(); // Enter 키 기본 동작 방지
|
||||
handleSearch();
|
||||
}
|
||||
}}
|
||||
/> */}
|
||||
{/* 하수처리시설명 */}
|
||||
{/* <Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리시설명</Label>
|
||||
<Input
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
value={var1}
|
||||
onChange={(e) => {
|
||||
setVar1(e.target.value);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault(); // Enter 키 기본 동작 방지
|
||||
handleSearch();
|
||||
}
|
||||
}}
|
||||
/> */}
|
||||
{/* 조회 버튼 */}
|
||||
<div className="flex-1 flex justify-end">
|
||||
<Button className="text-base py-2" onClick={handleSearch}>조회</Button>
|
||||
|
||||
@@ -40,13 +40,13 @@ const swagePrcsZone: React.FC<swagePrcsZoneProps> = ({
|
||||
}}
|
||||
onSigunguChange={setSgg}
|
||||
/>
|
||||
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리구역명</Label>
|
||||
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리시설명</Label>
|
||||
<Input
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
className='!text-xl w-[120px] placeholder:text-center mr-8'
|
||||
placeholder="입력"
|
||||
value={var1}
|
||||
value={var2}
|
||||
onChange={(e) => {
|
||||
setVar1(e.target.value);
|
||||
setVar2(e.target.value);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
@@ -55,13 +55,13 @@ const swagePrcsZone: React.FC<swagePrcsZoneProps> = ({
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리시설명</Label>
|
||||
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">하수처리구역명</Label>
|
||||
<Input
|
||||
className='!text-xl w-[120px] placeholder:text-center mr-8'
|
||||
className="mr-8 w-[100px] !text-xl placeholder:text-center"
|
||||
placeholder="입력"
|
||||
value={var2}
|
||||
value={var1}
|
||||
onChange={(e) => {
|
||||
setVar2(e.target.value);
|
||||
setVar1(e.target.value);
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useMemo, useEffect } from "react";
|
||||
import { SelectBox } from '@common/business_components/ui'
|
||||
import { Label } from '@common/components';
|
||||
import { getGeoData } from '@/components/lib/api';
|
||||
import useStore from '../../store/useStore';
|
||||
|
||||
interface Option {
|
||||
id: number;
|
||||
@@ -28,38 +28,10 @@ export function SidoSigunguSelectBox({
|
||||
className = "",
|
||||
}: SidoSigunguSelectBoxProps) {
|
||||
|
||||
const [ctpvList, setCtpvList] = useState<Option[]>([]);
|
||||
const [sggList, setSggList] = useState<Option[]>([]);
|
||||
|
||||
// 선택된 시도에 따라 시군구 리스트를 가져옴
|
||||
const fetchCtpvData = useMemo(() => (
|
||||
async () => {
|
||||
const ctpvData = await getGeoData('/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_ctpv&outputFormat=application%2Fjson');
|
||||
const ctpvList: Option[] = ctpvData.features
|
||||
.map((feature: any) => ({
|
||||
id: feature.properties.mctpv_cd.trim(),
|
||||
name: feature.properties.mctpv_korn_nm
|
||||
}))
|
||||
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko')); // 가나다순 정렬
|
||||
setCtpvList(ctpvList);
|
||||
}
|
||||
), []);
|
||||
|
||||
// 선택된 시도에 따라 시군구 리스트를 가져옴
|
||||
const fetchSggData = useMemo(() => (
|
||||
async () => {
|
||||
const sggData = await getGeoData('/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_sgg&outputFormat=application%2Fjson');
|
||||
const sggList: Option[] = sggData.features
|
||||
.map((feature: any) => ({ id: feature.properties.sgg_cd, name: feature.properties.sgg_korn_nm }))
|
||||
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko')); // 가나다순 정렬
|
||||
setSggList(sggList);
|
||||
}
|
||||
), []);
|
||||
const { ctpv, sgg} = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
await fetchCtpvData();
|
||||
await fetchSggData();
|
||||
onSidoChange(0);
|
||||
onSigunguChange(0);
|
||||
if (setCtpvName && setSggName) {
|
||||
@@ -79,13 +51,13 @@ export function SidoSigunguSelectBox({
|
||||
label=""
|
||||
selectArray={
|
||||
[{ val: 0, text: '전체' },
|
||||
...ctpvList.map(opt => ({ val: opt.id, text: opt.name }))
|
||||
...ctpv.map(opt => ({ val: opt.id, text: opt.name }))
|
||||
]
|
||||
}
|
||||
value={sido}
|
||||
onSelectValue={val => {
|
||||
onSidoChange(Number(val));
|
||||
if (setCtpvName) setCtpvName(ctpvList.find(opt => Number(opt.id) === Number(val))?.name || "");
|
||||
if (setCtpvName) setCtpvName(ctpv.find(opt => Number(opt.id) === Number(val))?.name || "");
|
||||
}}
|
||||
selectContentClass="z-[101]"
|
||||
/>
|
||||
@@ -96,7 +68,7 @@ export function SidoSigunguSelectBox({
|
||||
label=""
|
||||
selectArray={
|
||||
[{ val: 0, text: '전체' },
|
||||
...sggList
|
||||
...sgg
|
||||
.filter(opt => String(opt.id).slice(0, 2) === String(sido))
|
||||
.map(opt => ({ val: opt.id, text: opt.name }))
|
||||
]
|
||||
@@ -104,7 +76,7 @@ export function SidoSigunguSelectBox({
|
||||
value={sigungu}
|
||||
onSelectValue={val => {
|
||||
onSigunguChange(Number(val))
|
||||
if (setSggName) setSggName(sggList.find(opt => Number(opt.id) === Number(val))?.name || "");
|
||||
if (setSggName) setSggName(sgg.find(opt => Number(opt.id) === Number(val))?.name || "");
|
||||
}}
|
||||
selectContentClass="z-[101]"
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useMemo } from "react";
|
||||
import { create } from "zustand";
|
||||
import { getGeoData } from "@/components/lib/api";
|
||||
import { get } from "http";
|
||||
|
||||
interface Option { id: number, name: string }
|
||||
|
||||
interface SnStoreState {
|
||||
ctpv: Option[];
|
||||
sgg: Option[];
|
||||
fetchCtpvData: () => Promise<void>;
|
||||
fetchSggData: () => Promise<void>;
|
||||
}
|
||||
|
||||
const useStore = create<SnStoreState>((set) => ({
|
||||
// Define your store state and actions here
|
||||
ctpv: [],
|
||||
sgg: [],
|
||||
fetchCtpvData: async () => {
|
||||
const ctpvData = await getGeoData('/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_ctpv&outputFormat=application%2Fjson');
|
||||
const ctpvList: Option[] = ctpvData.features
|
||||
.map((feature: any) => ({
|
||||
id: feature.properties.mctpv_cd.trim(),
|
||||
name: feature.properties.mctpv_korn_nm
|
||||
}))
|
||||
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko'));
|
||||
set({ ctpv: ctpvList });
|
||||
},
|
||||
fetchSggData: async () => {
|
||||
const sggData = await getGeoData('/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_sgg&outputFormat=application%2Fjson');
|
||||
const sggList: Option[] = sggData.features
|
||||
.map((feature: any) => ({
|
||||
id: feature.properties.sgg_cd,
|
||||
name: feature.properties.sgg_korn_nm
|
||||
}))
|
||||
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko'));
|
||||
set({ sgg: sggList });
|
||||
}
|
||||
}));
|
||||
|
||||
export default useStore;
|
||||
Reference in New Issue
Block a user