Files
frontend/apps/sn/app/components/ui/SidoSigunguSelectBox.tsx
T

113 lines
3.6 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;
setCtpvName?: (name: string) => void;
onSigunguChange: (id: number) => void;
setSggName?: (name: string) => void;
className?: string;
}
export function SidoSigunguSelectBox({
sido,
sigungu,
onSidoChange,
setCtpvName,
onSigunguChange,
setSggName,
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);
if (setCtpvName && setSggName) {
setCtpvName("");
setSggName("");
}
})();
}, []);
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));
if (setCtpvName) setCtpvName(ctpvList.find(opt => Number(opt.id) === Number(val))?.name || "");
}}
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))
if (setSggName) setSggName(sggList.find(opt => Number(opt.id) === Number(val))?.name || "");
}}
selectContentClass="z-[101]"
/>
</div>
);
}