- wr middleware.ts에 geoserver path 추가
- mapSearchBar.tsx UI 구현 (API, 클릭 리스너 작업 필요)
- mapSearchForm.tsx css 수정
- 지도 화면에서 searchView 수정
This commit is contained in:
swcho
2025-06-17 18:17:21 +09:00
parent 0ebe5e8ab8
commit 16bed41772
6 changed files with 304 additions and 281 deletions
@@ -1,114 +0,0 @@
import { useWrStore } from "@/app/store";
import { getCityOrSgg } from "@/components/lib/func/commom";
import {
type ReturnType
} from "@common/business_components/ui";
import { SelectBox } from '@common/business_components/ui/select';
import React, { useEffect, useRef, useState } from 'react';
export type comCodeState = {
code: {
isInit: boolean;
chBuCd: SelectDataType[]
rainFcltCd: SelectDataType[];
bdstUsgCd: SelectDataType[];
cityCd: SelectDataType[];
sggCd: SelectDataType[];
rvbsnCd: SelectDataType[];
mdmbsnCd: SelectDataType[];
lgbsnCd: SelectDataType[];
lclgvrnmntCd: EnvPartSelectDataType[];
orgwtKndCd: SelectDataType[];
yn: SelectDataType[];
buildingType: {
RST: string,
RNB: string,
HTB: string
}
};
};
type SelectDataType = {
text: string;
val: string;
sido?: string; // 시도 코드 (선택 사항)
}
type EnvPartSelectDataType = SelectDataType & {
adstDliStrCd: string,
}
type SearchFormLeftProps = {
isShowPart?: boolean | undefined;
children: React.ReactNode;
selectSidoData?: SelectDataType[] | [];
selectSigunData?: SelectDataType[] | [];
selectRegionData?: SelectDataType[] | [];
selectUnitWaterShedData?: SelectDataType[] | [];
selectMiddleRegionData?: SelectDataType[] | [];
selectEnvPartData?: EnvPartSelectDataType[] | [];
selectEnvPartSidoData?: SelectDataType[] | [];
selectEnvPartSigunData?: SelectDataType[] | [];
setRtnPartValue?: (value: string) => void;
setRtnSidoValue?: (value: string) => void;
setRtnSigunValue?: (value: string) => void;
setRtnRegionValue?: (value: string) => void;
setRtnUnitWaterShedValue?: (value: string) => void;
setRtnMiddleRegionValue?: (value: string) => void;
setRtnEnvPartValue?: (value: string) => void;
setRtnEnvPartSidoValue?: (value: string) => void;
setRtnEnvPartSigunValue?: (value: { val: string, text: string }) => void; // setRtnEnvPartSigunValue prop 타입을 객체로 변경
resetTrigger?: boolean;
}
function GovSidoSigunguSearchForm({
isShowPart = false,
children,
selectSidoData = [],
selectSigunData = [],
selectRegionData = [],
selectUnitWaterShedData = [],
selectMiddleRegionData = [],
selectEnvPartData = [],
setRtnPartValue,
setRtnSidoValue,
setRtnSigunValue,
setRtnRegionValue,
setRtnUnitWaterShedValue,
setRtnMiddleRegionValue,
setRtnEnvPartValue,
setRtnEnvPartSidoValue,
setRtnEnvPartSigunValue,
resetTrigger = false
}: SearchFormLeftProps) {
const { code, pbnstSttn, pbnstSttnSearch } = useWrStore((state) => state);
const ref = useRef<ReturnType>({} as ReturnType);
const codeData = getCityOrSgg(ref);
//환경청별 시도 시군구
const [envPartValue, setEnvPartValue] = useState<string>('0');
// 환경청
const [filteredEnvPartSigunDataSelected, setFilteredEnvPartSigunDataSelected] = useState<SelectDataType[]>([]);
return (
isShowPart ? (
<div className="grid grid-cols-12 gap-5 w-11/12 m-4">
<>
<SelectBox className="col-span-2" label={'환경청'} selectArray={code.lclgvrnmntCd} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'rounded-lg bg-white truncate'} />
<SelectBox className="col-span-2" label={'시도'} selectArray={code.cityCd} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={envPartSidoValue} selectClass={'rounded-lg bg-white truncate'} />
<SelectBox className="col-span-2" label={'시군구'} selectArray={code.sggCd} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={envPartSigunValue} selectClass={'rounded-lg bg-white truncate'} />
</>
{children}
</div>
) : (
<div className="grid grid-cols-12 gap-5 w-11/12 m-4">
{children}
</div>
)
)
}
export { GovSidoSigunguSearchForm };
+14 -3
View File
@@ -1,11 +1,10 @@
"use client";
import Gis from "@common/business_components/ui/map/Gis";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import { useEffect, useRef, useState } from "react";
import SearchModal from "../searchModal";
import FeatureClickEventPopup from "../featureClickEventPopup";
import { mapService } from "../service";
import { MapSearchBar } from "../mapSearchBar";
const Map = () => {
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
@@ -90,6 +89,18 @@ const Map = () => {
// setIsOpen(true);
// setIsSearchModalOpen(false);
// };
// MapSearchBar 래퍼 컴포넌트
const CustomMapSearchBar = (props: any) => {
return (
<MapSearchBar
{...props}
searchType="우리동네가뭄지도보기"
showApplyButton={false}
/>
);
};
return (
<div className="bg-container">
<Gis
@@ -97,7 +108,7 @@ const Map = () => {
isSearch={false}
gisMaps={gisMaps}
isMiniMap={true}
searchView={SearchModal}
searchView={CustomMapSearchBar}
detailView={FeatureClickEventPopup}
setIsOpen={setIsOpen}
setFeatureData={setFeatureData}
+265 -63
View File
@@ -1,14 +1,19 @@
"use client"
import { Button } from "@common/components/ui";
import { useCallback, useEffect, useState } from "react";
import type { EnvPartSelectDataType } from "@common/business_components/ui/search_form_left";
import { Button, Input, Label } from "@common/components/ui";
import React, { useCallback, useEffect, useRef, useState, useMemo } from "react";
import { SearchFormLeft, type EnvPartSelectDataType } from "@common/business_components/ui/search_form_left";
import { SearchFormRight } from "@common/business_components/ui/search_form_right";
import type { SelectDataType } from "@common/business_components/ui/search_input_select";
import type { ReturnType } from "@common/business_components/ui/search_base_form";
import { MapSearchForm } from "./mapSearchForm";
import { MapSearchFormLeft } from "./mapSearchForm";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import { SelectBox } from "@common/business_components/ui/select";
import { SearchBaseForm } from "@common/business_components";
type SearchBaseType = {
searchType: string;
selectSidoData?: SelectDataType[] | [];
selectSigunData?: SelectDataType[] | [];
selectRegionData?: SelectDataType[] | [];
@@ -16,12 +21,11 @@ type SearchBaseType = {
selectMiddleRegionData?: SelectDataType[] | [];
selectEnvPartData?: EnvPartSelectDataType[] | [];
queryClick: (returnType: ReturnType) => void;
excelName?: string;
excelClick: (returnType: ReturnType) => void;
initClick: () => void;
btnClass: string;
ref: React.RefObject<ReturnType>;
isAdmin: boolean;
applyClick: () => void;
btnClass?: string;
ref?: React.RefObject<ReturnType>;
isAdmin?: boolean;
leftClassName?: string;
rightClassName?: string;
showQueryButton?: boolean;
@@ -29,7 +33,24 @@ type SearchBaseType = {
showApplyButton?: boolean;
}
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`;
const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`);
interface SearchModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onFeatureSelect: (row: any) => void;
}
interface SelectedDataTypeWithSggNm {
text: string;
val: string;
sggNm: string;
}
export function MapSearchBar({
searchType,
selectSidoData,
selectSigunData,
selectRegionData,
@@ -37,28 +58,77 @@ export function MapSearchBar({
selectMiddleRegionData,
selectEnvPartData,
btnClass,
excelName,
queryClick,
excelClick,
initClick,
ref,
applyClick,
isAdmin = false,
leftClassName,
rightClassName,
showQueryButton = true,
showInitButton = true,
showApplyButton = false
showApplyButton = true
}: SearchBaseType) {
// 로딩바
const [isLoading, setIsLoading] = useState(false);
// 상세 정보 조회를 위한 상태 추가
const [popupFeature, setPopupFeature] = useState<any>(null);
const { code } = useWrStore((state) => state);
const [isChHead, setIsChHead] = useState(false);
const ref = useRef<ReturnType>({} as ReturnType);
// 전체 목록
const [partValue, setPartValue] = useState<string>("A");
const [sidoValue, setSidoValue] = useState<string>("0");
const [sigunValue, setSigunValue] = useState<string>("0");
const [sidoText, setSidoText] = useState<string>("");
const [sigunText, setSigunText] = useState<string>("");
const [regionValue, setRegionValue] = useState<string>("0");
const [untitWaterShedValue, setUntitWaterShedValue] = useState<string>("0");
const [middleRegionValue, setMiddleRegionValue] = useState<string>("0");
const [envPartValue, setEnvPartValue] = useState<string>("0");
const [resetTrigger, setResetTrigger] = useState(false);
const [sidoText, setSidoText] = useState<string>("0");
const [sigunText, setSigunText] = useState<string>("0");
// 공급처 후보지 조회 필터 목록
const [selectedSido, setSelectedSido] = useState<SelectDataType>({ text: "전체", val: '0' });
const [selectedSigun, setSelectedSigun] = useState<SelectDataType>({ text: "전체", val: '0' });
const [selectedFclt, setSelectedFclt] = useState<SelectDataType>({ text: "전체", val: '0' });
// 전체 시설
let allFclt: SelectedDataTypeWithSggNm[] = [{ text: "전체", val: '0', sggNm: '전체' }];
// 우리동네가뭄지도 필터 목록
const [selectedDong, setSelectedDong] = useState<SelectDataType>({ text: "전체", val: '0' }); // 행정동
const [allSido, setAllSido] = useState<SelectDataType[]>([
{ text: "전체", val: '0' },
...(code?.cityCd || [])
]);
const [allRegion, setAllRegion] = useState<SelectDataType[]>([
{ text: "전체", val: '0' },
...(code?.rvbsnCd || [])
]);
const filteredSigunData = useMemo(() => {
if (!selectedSido || selectedSido.val === '0' || !selectedSido.val) return [{ text: "전체", val: '0' }];
return [
{ text: "전체", val: '0' },
...code.sggCd.filter(item => item.val.substring(0, 2) === selectedSido.val.substring(0, 2))
];
}, [selectedSido]);
const filteredFcltData = useMemo(() => {
if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) return [{ text: "전체", val: '0', sggNm: '전체' }];
return [
{ text: "전체", val: '0', sggNm: '전체' },
...allFclt.filter(item => item.sggNm === selectedSido.text)
];
}, [selectedSigun]);
const filteredDong = useMemo(() => {
if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) return [{ text: "전체", val: '0', sggNm: '전체' }];
return [
{ text: "전체", val: '0', sggNm: '전체' },
// ...code.dong.filter(item => item.sggNm === selectedSido.text)
];
}, [selectedSigun]);
const queryVal = () => {
console.log("조회버튼 클릭");
@@ -70,8 +140,8 @@ export function MapSearchBar({
unitWaterShedValue: untitWaterShedValue,
middleRegionValue: middleRegionValue,
envPartValue: envPartValue,
sidoText: sidoText,
sigunText: sigunText,
sidoText: selectedSido.text,
sigunText: selectedSigun.text,
});
}
@@ -80,25 +150,68 @@ export function MapSearchBar({
initClick();
}, [setResetTrigger, initClick]);
const applyVal = useCallback(() => {
if (searchType == '공급처 후보지 조회') {
} else if (searchType == '우리동네가뭄지도보기') {
} else if (searchType == '지도보기') {
}
}, [setResetTrigger, initClick]);
useEffect(() => {
if (resetTrigger) {
setResetTrigger(false);
}
}, [resetTrigger]);
const excelDownload = () => {
excelClick({
partValue: partValue,
sidoValue: sidoValue,
sigunValue: sigunValue,
regionValue: regionValue,
unitWaterShedValue: untitWaterShedValue,
middleRegionValue: middleRegionValue,
envPartValue: envPartValue,
sidoText: sidoText,
sigunText: sigunText,
})
};
// 시설 조회
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) {
allFclt = ([{ text: "전체", val: '0', sggNm: '전체' }]);
setIsLoading(false);
return;
}
try {
const queryParamsFacility = new URLSearchParams({
lyrTypeNm: 'tb_il_swage_prcs_fclt',
page: '0',
size: '100000',
sort: 'string',
});
const cqlFiltersFacility: string[] = [];
if (selectedSigun.text && selectedSigun.val !== '0') {
cqlFiltersFacility.push(`sgg_nm ILIKE '%${selectedSigun.text}%'`);
}
if (cqlFiltersFacility.length > 0) {
queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and '));
}
console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`);
const facilityRes = await fetch(`${API_URL}/v1/fclts?${queryParamsFacility.toString()}`, {
method: "GET",
headers: { accept: "application/json" }
}).then(res => res.json());
const facilities = (facilityRes.data || []).map((item: any) => ({
text: item.swtrmtFcltNm,
val: item.fid,
sggNm: item.sggNm
}));
allFclt = (facilities);
} catch (error) {
console.error("BaseLayout: 지역/시설 데이터 조회 중 오류 발생:", error);
allFclt = ([{ text: "전체", val: '0', sggNm: '전체' }]);
} finally {
setIsLoading(false);
}
};
fetchData();
}, [selectedSigun]);
useEffect(() => {
if (ref && ref.current) {
@@ -110,43 +223,132 @@ export function MapSearchBar({
customRef.unitWaterShedValue = untitWaterShedValue;
customRef.middleRegionValue = middleRegionValue;
customRef.envPartValue = envPartValue;
customRef.sidoText = sidoText;
customRef.sigunText = sigunText;
customRef.sidoText = selectedSido.text;
customRef.sigunText = selectedSigun.text;
}
}, [partValue, sidoValue, sigunValue, regionValue, untitWaterShedValue, middleRegionValue, envPartValue, sidoText, sigunText, ref]);
}, [partValue, sidoValue, sigunValue, regionValue, untitWaterShedValue, middleRegionValue, envPartValue, ref]);
return (
<div className={leftClassName ? leftClassName : `w-auto min-w-[200px] mx-5 flex items-center justify-center space-x-2 `}>
{/* 검색 조건 부분 */}
<MapSearchForm
isShowPart={true}
selectSidoData={selectSidoData}
selectSigunData={selectSigunData}
selectRegionData={selectRegionData}
selectUnitWaterShedData={selectUnitWaterShedData}
selectMiddleRegionData={selectMiddleRegionData}
selectEnvPartData={selectEnvPartData}
setRtnPartValue={setPartValue}
setRtnSidoValue={setSidoValue}
setRtnSigunValue={setSigunValue}
setRtnRegionValue={setRegionValue}
setRtnUnitWaterShedValue={setUntitWaterShedValue}
setRtnMiddleRegionValue={setMiddleRegionValue}
setRtnEnvPartValue={setEnvPartValue}
setRtnEnvPartSidoValue={setSidoValue}
setRtnEnvPartSigunValue={setSigunValue}
setRtnSidoText={setSidoText}
setRtnSigunText={setSigunText}
resetTrigger={resetTrigger}
isAdmin={isAdmin}
children={undefined}
/>
{/* 버튼 부분 */}
<div className={rightClassName ? rightClassName : `w-1/12 mx-5 flex flex-col items-center justify-center space-x-2 `}>
<div className="flex items-center justify-between gap-2">
<div className="absolute left-1/2 -translate-x-1/2 bg-white flex items-center justify-center p-4 rounded-md shadow-lg w-auto min-w-fit">
<div className={leftClassName ? leftClassName : `flex items-center justify-center space-x-2 `}>
<div className="flex gap-8 items-center">
{searchType == "공급처 후보지 조회" && (
<>
<SelectBox
className="flex items-center"
label={'시도'}
selectArray={allSido}
onSelectValue={(val) => {
const selected = code.cityCd.find(item => (item.val === val));
setSelectedSido(selected || { text: "전체", val: '0' });
}}
value={selectedSido.val}
selectClass={'w-32'}
/>
<SelectBox
className="flex items-center"
label={'시군구'}
selectArray={filteredSigunData}
onSelectValue={(val) => {
const selected = filteredSigunData.find(item => (item.val === val));
setSelectedSigun(selected || { text: "전체", val: '0' });
}}
value={selectedSigun.val}
selectClass={'w-32'}
/>
<SelectBox
className="flex items-center"
label={'시설명'}
selectArray={filteredFcltData}
onSelectValue={(val) => {
const selected = allFclt.find(item => (item.val === val));
setSelectedFclt(selected || { text: "전체", val: '0', sggNm: '전체' });
}}
value={selectedFclt.val}
selectClass={'w-32'}
/>
<Label className="w-auto text-xl text-gray-600 whitespace-nowrap">건물명</Label>
<div className="w-44">
<Input className="mr-4" />
</div>
</>
)}
{searchType == "우리동네가뭄지도보기" && (
<>
<SelectBox
className="flex items-center"
label={'시도'}
selectArray={allSido}
onSelectValue={(val) => {
const selected = code.cityCd.find(item => (item.val === val));
setSelectedSido(selected || { text: "전체", val: '0' });
}}
value={selectedSido.val}
selectClass={'w-32'}
/>
<SelectBox
className="flex items-center"
label={'시군구'}
selectArray={filteredSigunData}
onSelectValue={(val) => {
const selected = filteredSigunData.find(item => (item.val === val));
setSelectedSigun(selected || { text: "전체", val: '0' });
}}
value={selectedSigun.val}
selectClass={'w-32'}
/>
<SelectBox
className="flex items-center mr-8"
label={'행정동'}
selectArray={filteredDong}
onSelectValue={(val) => {
const selected = filteredDong.find(item => (item.val === val));
setSelectedDong(selected || { text: "전체", val: '0', sggNm: '전체' });
}}
value={selectedDong.val}
selectClass={'w-32'}
/>
</>
)}
{searchType == "지도보기" && (
<div className="flex items-center gap-2 w-[800px]">
<div className="flex min-w-0"> {/* SearchFormLeft 래퍼 */}
<MapSearchFormLeft
isShowPart={true}
selectSidoData={allSido}
selectSigunData={filteredSigunData}
selectRegionData={allRegion}
selectUnitWaterShedData={selectUnitWaterShedData}
selectMiddleRegionData={selectMiddleRegionData}
selectEnvPartData={selectEnvPartData}
setRtnPartValue={setPartValue}
setRtnSidoValue={setSidoValue}
setRtnSigunValue={setSigunValue}
setRtnRegionValue={setRegionValue}
setRtnUnitWaterShedValue={setUntitWaterShedValue}
setRtnMiddleRegionValue={setMiddleRegionValue}
setRtnEnvPartValue={setEnvPartValue}
setRtnEnvPartSidoValue={setSidoValue}
setRtnEnvPartSigunValue={setSigunValue}
setRtnSidoText={setSidoText}
setRtnSigunText={setSigunText}
resetTrigger={resetTrigger}
isAdmin={isAdmin}
children={undefined}
/>
</div>
<Label className="w-auto text-xl text-gray-600 whitespace-nowrap">시설명</Label>
<div className="w-44">
<Input className="mr-4" />
</div>
</div>
)}
</div>
{/* 버튼 부분 */}
<div className="flex items-center justify-center gap-4">
{showQueryButton && <Button className={btnClass} onClick={queryVal}>조회</Button>}
{showInitButton && <Button className={btnClass} onClick={initVal}>초기화</Button>}
{showApplyButton && <Button className={btnClass} onClick={initVal}>적용</Button>}
{showApplyButton && <Button className={btnClass} onClick={applyVal}>적용</Button>}
</div>
</div>
</div>
+13 -20
View File
@@ -1,7 +1,7 @@
"use client"
import React, { useEffect, useState } from 'react';
import type { SelectDataType } from "@common/business_components/ui/search_input_select";
import type { SelectDataType } from '@common/business_components/ui/search_input_select';
import { SelectBox } from '@common/business_components/ui/select';
/**
@@ -56,13 +56,7 @@ const selectPartData: SelectDataType[] = [
{ text: "환경청별", val: 'G' },
];
const selectType: SelectDataType[] = [
{ text: "행정별", val: 'A' },
{ text: "유역별", val: 'R' },
{ text: "환경청별", val: 'G' },
];
function MapSearchForm({ isShowPart = false, children, selectSidoData = [], selectSigunData = [], selectRegionData = [], selectUnitWaterShedData = [], selectMiddleRegionData = [], selectEnvPartData = [], setRtnPartValue, setRtnSidoValue, setRtnSidoText, setRtnSigunValue, setRtnSigunText, setRtnRegionValue, setRtnUnitWaterShedValue, setRtnMiddleRegionValue, setRtnEnvPartValue, setRtnEnvPartSidoValue, setRtnEnvPartSigunValue, resetTrigger = false, isAdmin = false }: SearchFormLeftProps) {
function MapSearchFormLeft({ isShowPart = false, children, selectSidoData = [], selectSigunData = [], selectRegionData = [], selectUnitWaterShedData = [], selectMiddleRegionData = [], selectEnvPartData = [], setRtnPartValue, setRtnSidoValue, setRtnSidoText, setRtnSigunValue, setRtnSigunText, setRtnRegionValue, setRtnUnitWaterShedValue, setRtnMiddleRegionValue, setRtnEnvPartValue, setRtnEnvPartSidoValue, setRtnEnvPartSigunValue, resetTrigger = false, isAdmin = false }: SearchFormLeftProps) {
/******************선택된 데이터******************/
const [partValue, setPartValue] = useState<string>('A');
//행정별 시도 시군구
@@ -314,27 +308,26 @@ function MapSearchForm({ isShowPart = false, children, selectSidoData = [], sele
return (
isShowPart ? (
<div className="grid grid-cols-12 gap-5 w-11/12 m-4">
<SelectBox className="col-span-3" label={'구분'} selectArray={isAdmin ? selectPartData.slice(0, 1) : selectPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'part')} value={partValue} selectClass={undefined} />
<div className="flex gap-5">
<SelectBox className="w-auto whitespace-nowrap" label={'구분'} selectArray={isAdmin ? selectPartData.slice(0, 1) : selectPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'part')} value={partValue} selectClass={'w-32'} />
{partValue === 'R' ? (
<>
<SelectBox className="col-span-3" label={'유역'} selectArray={selectRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'region')} value={regionValue} selectClass={undefined} />
<SelectBox className="col-span-3" label={'단위유역'} selectArray={filteredUnitWaterShedData} onSelectValue={(val) => onSelectValue(val.toString(), 'unitWaterShed')} value={unitWaterShedValue} selectClass={undefined} />
<SelectBox className="col-span-3" label={'중권역'} selectArray={filteredMiddleRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'middleRegion')} value={middleRegionValue} selectClass={undefined} />
<SelectBox className="w-auto whitespace-nowrap" label={'유역'} selectArray={selectRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'region')} value={regionValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'단위유역'} selectArray={filteredUnitWaterShedData} onSelectValue={(val) => onSelectValue(val.toString(), 'unitWaterShed')} value={unitWaterShedValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'중권역'} selectArray={filteredMiddleRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'middleRegion')} value={middleRegionValue} selectClass={'w-44'} />
</>
) : partValue === 'G' ? (
<>
<SelectBox className="col-span-3" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={undefined} />
<SelectBox className="col-span-3" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={sidoValue} selectClass={undefined} />
<SelectBox className="col-span-3" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={sigunValue} selectClass={undefined} />
<SelectBox className="w-auto whitespace-nowrap" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={sidoValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={sigunValue} selectClass={'w-44'} />
</>
) : (
<>
<SelectBox className="col-span-3" label={'시도'} selectArray={selectSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={undefined} />
<SelectBox className="col-span-3" label={'시군구'} selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={undefined} />
<SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={selectSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={'w-40'} />
<SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={'w-40'} />
</>
)}
{children}
</div>
) : (
<div className="grid grid-cols-12 gap-5 w-11/12 m-4">
@@ -344,4 +337,4 @@ function MapSearchForm({ isShowPart = false, children, selectSidoData = [], sele
)
}
export { MapSearchForm };
export { MapSearchFormLeft };
-80
View File
@@ -1,80 +0,0 @@
"use client"
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { MapSearchBar, type ReturnType } from "./mapSearchBar";
import { Button } from "@common/components/ui";
import { SearchFormLeft, type EnvPartSelectDataType } from "@common/business_components/ui/search_form_left";
import { SearchFormRight } from "@common/business_components/ui/search_form_right";
import type { SelectDataType } from "@common/business_components/ui/search_input_select";
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`;
const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`);
interface SearchModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onFeatureSelect: (row: any) => void;
}
// 날짜 조합 함수
const getDateString = (
year: string,
month: string,
day: string,
defaultDate: string,
) => {
if (!year && !month && !day) return defaultDate;
const y = year || defaultDate.slice(0, 4);
const m = month || defaultDate.slice(4, 6);
const d = day || defaultDate.slice(6, 8);
return `${y}${m}${d}`;
};
const SearchModal: React.FC<SearchModalProps> = ({
open,
onOpenChange,
onFeatureSelect,
}) => {
// 로딩바
const [isLoading, setIsLoading] = useState(false);
// 상세 정보 조회를 위한 상태 추가
const [popupFeature, setPopupFeature] = useState<any>(null);
const { code, pbnstSttn, pbnstSttnSearch } = useWrStore((state) => state);
const [isChHead, setIsChHead] = useState(false);
const ref = useRef<ReturnType>({} as ReturnType);
return (
<div className="absolute left-1/2 -translate-x-1/2 w-full max-w-7xl bg-white flex items-center justify-center p-4 rounded-md shadow-lg">
<MapSearchBar
selectSidoData={code.cityCd}
selectSigunData={code.sggCd}
selectRegionData={code.rvbsnCd}
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
queryClick={function (returnType: ReturnType): void {
// '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}'
let con;
if (returnType.sigunValue != "0") {
con = returnType.sigunValue;
} else {
con = returnType.sidoValue;
}
// pbnstSttnSearch(1, "20", con);
}}
initClick={function (): void { }}
btnClass={btnClass}
ref={ref} excelClick={function (returnType: ReturnType): void {
throw new Error("Function not implemented.");
}}
isAdmin={false}
/>
</div>
);
};
export default React.memo(SearchModal);
+12 -1
View File
@@ -5,6 +5,8 @@ import { CS_URL } from "./components/lib/config";
const CLAIM_NAME = "Authorization";
const AUTH_USER_ID = "token-id";
const serverApiUrl = CS_URL;
const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || "";
export function middleware(req: NextRequest) {
const pathname = req.nextUrl.pathname;
console.log(`[Middleware] Request URL: ${req.url}`);
@@ -44,9 +46,18 @@ export function middleware(req: NextRequest) {
});
}
if (pathname.startsWith("/geoserver")) {
const queryParams = searchParams.toString();
const newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${
queryParams ? `?${queryParams}` : ""
}`;
console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl));
}
return NextResponse.next();
}
export const config = {
matcher: ["/server/:path*", "/attach-service/:path*"],
matcher: ["/server/:path*", "/attach-service/:path*", "/geoserver/:path*"],
};