99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
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';
|
|
|
|
interface Option {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
|
|
interface SidoSigunguSelectBoxProps {
|
|
sido: number;
|
|
sigungu: number;
|
|
onSidoChange: (id: number) => void;
|
|
onSigunguChange: (id: number) => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function SidoSigunguSelectBox({
|
|
sido,
|
|
sigungu,
|
|
onSidoChange,
|
|
onSigunguChange,
|
|
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);
|
|
}
|
|
), []);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
await fetchCtpvData();
|
|
await fetchSggData();
|
|
onSidoChange(0);
|
|
onSigunguChange(0);
|
|
})();
|
|
}, []);
|
|
|
|
|
|
return (
|
|
<div className={`flex items-center justify-center ${className} mr-8`}>
|
|
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시도</Label>
|
|
<SelectBox
|
|
className="w-60 mr-8"
|
|
selectClass="rounded-lg bg-white"
|
|
label=""
|
|
selectArray={
|
|
[{ val: 0, text: '전체' },
|
|
...ctpvList.map(opt => ({ val: opt.id, text: opt.name }))
|
|
]
|
|
}
|
|
value={sido}
|
|
onSelectValue={val => onSidoChange(Number(val))}
|
|
selectContentClass="z-[101]"
|
|
/>
|
|
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시군구</Label>
|
|
<SelectBox
|
|
className="w-48"
|
|
selectClass="w-48 rounded-lg bg-white truncate"
|
|
label=""
|
|
selectArray={
|
|
[{ val: 0, text: '전체' },
|
|
...sggList
|
|
.filter(opt => String(opt.id).slice(0, 2) === String(sido))
|
|
.map(opt => ({ val: opt.id, text: opt.name }))
|
|
]
|
|
}
|
|
value={sigungu}
|
|
onSelectValue={val => onSigunguChange(Number(val))}
|
|
selectContentClass="z-[101]"
|
|
/>
|
|
</div>
|
|
);
|
|
} |