Files
frontend/apps/sn/app/(map-layout)/map/searchModal/swagePrcsFclt.tsx
T

168 lines
5.3 KiB
TypeScript

/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수처리시설)
*
* 📄 SwagePrcsFclt Tab
* Next.js App Router (app/) 기반 검색 모달 하수처리시설 탭 컴포넌트
*
* - 시도/시군구 선택 및 가동개시일자 범위 필터링
* - 시설용량 범위 기반 검색 기능
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*/
import React from "react";
import { YearRangeSelectBox } from "@/components/ui/YearRangeSelectBox";
import { Button, Input, Label } from "@common/components";
import { CtpvSggPrcsFcltSelectBox } from "@/components/ui/ctpvSggPrcsFcltSelectBox";
import useSearchModalStore from "../../../store/useSearchModalStore";
import useSearchModal from "./useSearchModal";
// 하수처리시설용 CQL 필터 생성
export const swagePrcsFcltCqlFilters = () => {
const {
ctpvName,
sggName,
yearFilter,
start1,
end1,
todayYear,
todayMonth,
todayDate,
getDateString,
} = useSearchModalStore.getState();
const cqlFilters: string[] = [];
// 가동개시일자 범위
const startDate = getDateString(yearFilter.start, "", "", "19000101");
const endDate = getDateString(
yearFilter.end,
"",
"",
`${todayYear}${todayMonth}${todayDate}`,
);
cqlFilters.push(
`oprtng_strt_ymd >= '${startDate}' and oprtng_strt_ymd <= '${endDate}'`,
);
// 시설용량 범위
if (start1 && end1)
cqlFilters.push(`fclt_cpct BETWEEN ${start1} AND ${end1}`);
else if (start1) cqlFilters.push(`fclt_cpct >= ${start1}`);
else if (end1) cqlFilters.push(`fclt_cpct <= ${end1}`);
// 시도
if (ctpvName) cqlFilters.push(`ctpv_nm ILIKE '%${ctpvName}%'`);
if (sggName) cqlFilters.push(`sgg_nm ILIKE '%${sggName}%'`);
// // 처리구역 면적
// if (start2 && end2)
// cqlFilters.push(`prcsZoneAreaSum BETWEEN ${start2} AND ${end2}`);
// else if (start2) cqlFilters.push(`prcsZoneAreaSum >= ${start2}`);
// else if (end2) cqlFilters.push(`prcsZoneAreaSum <= ${end2}`);
// // 하수처리시설명
// if (var1) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${var1}%'`);
return cqlFilters;
};
const SwagePrcsFclt: React.FC = () => {
const {
start1,
setStart1,
end1,
setEnd1,
ctpvCd,
setCtpvCd,
setCtpvName,
sggCd,
setSggCd,
setSggName,
yearFilter,
setYearFilter,
} = useSearchModalStore();
const { handleSearch, handleResetSearch } = useSearchModal();
return (
<div className="contents">
<div className="contents">
<CtpvSggPrcsFcltSelectBox
sido={ctpvCd}
sigungu={sggCd}
onSidoChange={(sidoId) => {
setCtpvCd(sidoId);
setSggCd("0");
}}
onSigunguChange={setSggCd}
setCtpvName={setCtpvName}
setSggName={setSggName}
/>
{/* 가동개시일자 */}
<div className="flex shrink-0 items-center gap-2">
<Label className="whitespace-nowrap text-xl font-medium text-label">
가동개시일자
</Label>
<YearRangeSelectBox
start={yearFilter.start}
end={yearFilter.end}
onChange={(range) =>
setYearFilter({
...yearFilter,
start: range.start,
end: range.end,
})
}
startLabel=""
endLabel=""
/>
</div>
{/* 시설용량 */}
<div className="flex shrink-0 items-center gap-2">
<Label className="whitespace-nowrap text-xl font-medium text-label">
시설용량(㎥/d)
</Label>
<Input
className="w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={start1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setStart1(val);
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
<span className="text-xl font-semibold">~</span>
<Input
className="w-[60px] !text-xl placeholder:text-center"
placeholder="입력"
value={end1}
onChange={(e) => {
// 숫자만 입력 허용
const val = e.target.value.replace(/[^0-9]/g, "");
setEnd1(val);
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault(); // Enter 키 기본 동작 방지
handleSearch();
}
}}
/>
</div>
{/* 조회 버튼 */}
<div className="flex min-w-fit flex-1 justify-end gap-2">
<Button onClick={handleSearch}>조회</Button>
<Button color="white" onClick={handleResetSearch}>
초기화
</Button>
</div>
</div>
</div>
);
};
export default React.memo(SwagePrcsFclt);