- 시도, 시군구, 하수처리장 SelectBox 컴포넌트 구현
- searchBar 컴포넌트 UI 개발 (zoom 및 이동 기능 추가 필요)
This commit is contained in:
swcho
2025-08-01 19:13:37 +09:00
parent 79b038657a
commit 7c7ce750f7
4 changed files with 71 additions and 130 deletions
@@ -1,82 +1,31 @@
"use client";
import {
SearchDiv,
SearchFormLeft,
SelectBox,
type SelectDataType,
} from "@common/business_components/ui";
import { useCallback, useEffect, useState } from "react";
import { useState } from "react";
import { CtpvSggPrcsFcltSelectBox } from "@/components/ui/ctpvSggPrcsFcltSelectBox";
export function SearchBar() {
const [sidoValue, setSidoValue] = useState<string>("");
const [sigunValue, setSigunValue] = useState<string>("");
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([
{ text: "시도 선택", val: "0" },
]);
const initializeSigunData = useCallback((sidoCd: string) => {
if (sidoCd === "0") {
setSigunValue("0");
setFilteredSigunData([{ text: "시도 선택", val: "0" }]);
} else {
const newFilteredData = [
{ text: "데이터", val: "0" },
// ...Common.selectSigunData.filter(
// (item: SelectDataType) => item.val.substring(0, 2) === sidoCd,
// ),
];
setSigunValue("0");
setFilteredSigunData(newFilteredData);
}
}, []);
const onSelectValue = useCallback(
(val: string, type: string) => {
switch (type) {
case "ctpvCd":
initializeSigunData(val);
setSidoValue(val);
break;
case "sggCd":
setSigunValue(val);
}
},
[initializeSigunData],
);
const [ctpv, setCtpv] = useState<number>(0);
const [sgg, setSgg] = useState<number>(0);
const [sggName, setSggName] = useState<string>('');
const [selectedSwagePrcsFclt, setSelectedSwagePrcsFclt] = useState<string | number>('0');
return (
<>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<div className="card card-border flex">
<div className="col-span-10 flex flex-row">
<SelectBox
className="mr-10 w-[200px]"
selectClass="rounded-lg bg-white"
label="시도"
selectArray={/* Common.selectSidoData || */ []}
onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")}
value={sidoValue || /* Common.selectSidoData[0]?.val || */ ""}
<div className="flex items-center gap-4 bg-white min-h-[48px] min-w-[600px] px-5 py-3 rounded-lg shadow">
<CtpvSggPrcsFcltSelectBox
sido={ctpv}
sigungu={sgg}
sggName={sggName}
onSidoChange={(sidoId) => {
setCtpv(sidoId);
setSgg(0);
}}
onSigunguChange={setSgg}
setSggName={setSggName}
selectedSwagePrcsFclt={selectedSwagePrcsFclt}
onSwagePrcsFcltChange={setSelectedSwagePrcsFclt}
/>
<SelectBox
className="mr-10 w-[200px]"
selectClass="rounded-lg bg-white"
label="시군구"
selectArray={filteredSigunData || []}
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
value={sigunValue}
/>
<SelectBox
className="mr-3 w-[250px]"
selectClass="rounded-lg bg-white"
labelClass="w-[200px]"
label="하수처리시설명"
selectArray={filteredSigunData || []}
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
value={sigunValue}
/>
</div>
</div>
</div>
</div>
</>
);
@@ -85,10 +85,6 @@ const BaseLayout = ({
onAnalysis,
}: BaseLayout) => {
const defaultOption: ApiSelectOption = { val: '0', text: '전체' };
const [treatmentFacilityOptions, setTreatmentFacilityOptions] = useState<ApiSelectOption[]>([]);
// 파일 다운로드
const isChckFile = () => {
// Excel 다운로드 함수가 있으면 Excel 다운로드 실행
@@ -157,6 +153,7 @@ const BaseLayout = ({
<CtpvSggPrcsFcltSelectBox
sido={ctpvCd}
sigungu={sggCd}
sggName={sggName}
onSidoChange={(sidoId: number) => {
setCtpvCd(sidoId);
setSggCd(0);
@@ -53,55 +53,53 @@ export function CtpvSggPrcsFcltSelectBox({
})();
}, []);
// useEffect(() => {
// onSwagePrcsFcltChange?.('0');
useEffect(() => {
onSwagePrcsFcltChange?.('0');
// const fetchData = async () => {
// if (!sggName) {
// console.log("BaseLayout: Skipping fetchData because sigungu.val is:", sggName);
// setPrcsFcltOptions([defaultOption]);
// if (setIsLoading) setIsLoading(false);
// return;
// }
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 {
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 '));
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()}`);
console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`);
// const facilityRes = await getData(`v1/fclts?${queryParamsFacility.toString()}`);
const facilityRes = await getData(`v1/fclts?${queryParamsFacility.toString()}`);
// console.log('facilityRes.data', facilityRes.data);
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);
// console.log("BaseLayout Fetched Treatment Facilities:", prcsFcltOptions);
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);
}
};
// } catch (error) {
// console.error("BaseLayout: 지역/시설 데이터 조회 중 오류 발생:", error);
// setPrcsFcltOptions([]);
// } finally {
// if (setIsLoading) setIsLoading(false);
// }
// };
// fetchData();
// }, [sggName]);
fetchData();
}, [sggName]);
return (
@@ -112,7 +110,7 @@ export function CtpvSggPrcsFcltSelectBox({
selectClass="rounded-lg bg-white"
label=""
selectArray={
[{ val: 0, text: '전체' },
[defaultOption,
...ctpv.map(opt => ({ val: opt.id, text: opt.name }))
]
}
@@ -129,7 +127,7 @@ export function CtpvSggPrcsFcltSelectBox({
selectClass="w-48 rounded-lg bg-white truncate"
label=""
selectArray={
[{ val: 0, text: '전체' },
[defaultOption,
...sgg
.filter(opt => String(opt.id).slice(0, 2) === String(sido))
.map(opt => ({ val: opt.id, text: opt.name }))
@@ -146,11 +144,11 @@ export function CtpvSggPrcsFcltSelectBox({
<>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap ml-8 mr-4">하수처리시설명</Label>
<SelectBox
label={''}
value={selectedSwagePrcsFclt}
selectArray={[defaultOption, ...prcsFcltOptions]}
className="w-[160px]"
selectClass="rounded-lg bg-white truncate"
label=""
selectArray={[defaultOption, ...prcsFcltOptions]}
value={selectedSwagePrcsFclt}
onSelectValue={(val) => onSwagePrcsFcltChange?.(val)}
selectContentClass="z-[101]"
/>
-3
View File
@@ -31,9 +31,6 @@ export const fetchCtpvSggData = async (set: (state: any) => void) => {
}))
.sort((a: Option, b: Option) => a.name.localeCompare(b.name, 'ko'));
console.log("CTPV List:", ctpvList);
console.log("SGG List:", sggList);
set({ ctpv: ctpvList, sgg: sggList });
} catch (e: any) {
// alert("시도, 시군구 데이터 로드 실패: " + e.message);