167 lines
5.3 KiB
TypeScript
167 lines
5.3 KiB
TypeScript
import React, { useState, useMemo, useEffect } from "react";
|
|
import { SelectBox } from '@common/business_components/ui'
|
|
import { Label } from '@common/components';
|
|
import useStore from '../../store/useStore';
|
|
import { getData } from '@/components/lib/api/index';
|
|
|
|
|
|
interface ApiSelectOption {
|
|
text: string;
|
|
val: string;
|
|
}
|
|
interface CtpvSggPrcsFcltSelectBoxProps {
|
|
sido: number;
|
|
sigungu: number;
|
|
sggName?: string;
|
|
onSidoChange: (id: number) => void;
|
|
onSigunguChange: (id: number) => void;
|
|
setCtpvName?: (name: string) => void;
|
|
setSggName?: (name: string) => void;
|
|
className?: string;
|
|
selectedSwagePrcsFclt?: string | number;
|
|
onSwagePrcsFcltChange?: (value: string | number) => void;
|
|
setSwtrmtFcltNm?: (name: string) => void;
|
|
setIsLoading?: (isLoading: boolean) => void;
|
|
}
|
|
|
|
const defaultOption: ApiSelectOption = { val: '0', text: '전체' };
|
|
|
|
export function CtpvSggPrcsFcltSelectBox({
|
|
sido,
|
|
sigungu,
|
|
sggName,
|
|
onSidoChange,
|
|
setCtpvName,
|
|
onSigunguChange,
|
|
setSggName,
|
|
className = "",
|
|
selectedSwagePrcsFclt,
|
|
onSwagePrcsFcltChange,
|
|
setSwtrmtFcltNm,
|
|
setIsLoading,
|
|
}: CtpvSggPrcsFcltSelectBoxProps) {
|
|
|
|
const [prcsFcltOptions, setPrcsFcltOptions] = useState<ApiSelectOption[]>([]);
|
|
const { ctpv, sgg } = useStore();
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
onSidoChange(0);
|
|
onSigunguChange(0);
|
|
if (setCtpvName && setSggName) {
|
|
setCtpvName("");
|
|
setSggName("");
|
|
}
|
|
if (setSwtrmtFcltNm) setSwtrmtFcltNm("");
|
|
})();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
onSwagePrcsFcltChange?.('0');
|
|
|
|
const fetchData = async () => {
|
|
if (!sggName) {
|
|
console.log("BaseLayout: Skipping fetchData because sigungu.val is:", sggName);
|
|
setPrcsFcltOptions([]);
|
|
if (setIsLoading) setIsLoading(false);
|
|
return;
|
|
}
|
|
|
|
if (setIsLoading) setIsLoading(true);
|
|
try {
|
|
|
|
const queryParamsFacility = new URLSearchParams({
|
|
lyrTypeNm: 'tb_il_swage_prcs_fclt',
|
|
page: '0',
|
|
size: '100000', // 요청하신 URL에 맞게 50으로 변경 가능
|
|
sort: 'string',
|
|
});
|
|
const cqlFiltersFacility: string[] = [];
|
|
if (sggName) cqlFiltersFacility.push(`sgg_nm ILIKE '%${sggName}%'`);
|
|
if (cqlFiltersFacility.length > 0) queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and '));
|
|
|
|
console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`);
|
|
|
|
const facilityRes = await getData(`v1/fclts?${queryParamsFacility.toString()}`);
|
|
|
|
console.log('facilityRes.data', facilityRes.data);
|
|
|
|
const facilities = (facilityRes.data || [])
|
|
.map((item: any) => ({
|
|
text: item.swtrmtFcltNm,
|
|
val: item.fid
|
|
}))
|
|
.sort((a: ApiSelectOption, b: ApiSelectOption) => a.text.localeCompare(b.text, 'ko'));
|
|
setPrcsFcltOptions(facilities);
|
|
} catch (error) {
|
|
console.error("BaseLayout: 지역/시설 데이터 조회 중 오류 발생:", error);
|
|
setPrcsFcltOptions([]);
|
|
} finally {
|
|
if (setIsLoading) setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchData();
|
|
}, [sggName]);
|
|
|
|
|
|
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={
|
|
[defaultOption,
|
|
...ctpv.map(opt => ({ val: opt.id, text: opt.name }))
|
|
]
|
|
}
|
|
value={sido}
|
|
onSelectValue={val => {
|
|
onSidoChange(Number(val));
|
|
if (setCtpvName) setCtpvName(ctpv.find(opt => Number(opt.id) === Number(val))?.name || "");
|
|
if (setSwtrmtFcltNm) setSwtrmtFcltNm("");
|
|
}}
|
|
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={
|
|
[defaultOption,
|
|
...sgg
|
|
.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(sgg.find(opt => Number(opt.id) === Number(val))?.name || "");
|
|
if (setSwtrmtFcltNm) setSwtrmtFcltNm("")
|
|
}}
|
|
selectContentClass="z-[101]"
|
|
/>
|
|
{selectedSwagePrcsFclt && onSwagePrcsFcltChange && (
|
|
<>
|
|
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap ml-8 mr-4">하수처리시설명</Label>
|
|
<SelectBox
|
|
className="w-[160px]"
|
|
selectClass="rounded-lg bg-white truncate"
|
|
label=""
|
|
selectArray={[defaultOption, ...prcsFcltOptions]}
|
|
value={selectedSwagePrcsFclt}
|
|
onSelectValue={(val) => {
|
|
onSwagePrcsFcltChange?.(val)
|
|
if (setSwtrmtFcltNm) setSwtrmtFcltNm(prcsFcltOptions.find(opt => String(opt.val) === String(val))?.text || "")
|
|
}}
|
|
selectContentClass="z-[101]"
|
|
/>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
} |