merge(sn): integrate latest survey layers and upload guidance

This commit is contained in:
2026-10-01 15:59:43 +09:00
14 changed files with 526 additions and 367 deletions
@@ -20,6 +20,11 @@ import {
} from "@common/business_components";
import type { UiTableSort } from "@common/business_components/ui/table";
import { Button } from "@common/components";
import {
adjustWaterRiskStartDate,
getWaterRiskMinStartDate,
validateWaterRiskDateRange,
} from "./water-risk-date-range";
import {
fetchWaterRiskAreas,
@@ -153,11 +158,10 @@ const formatAnalysisBaseAt = (value?: string | null) => {
/** 현재 위험 조회와 검색 초기화에 사용하는 최근 1년의 기본 조회조건이다. */
const buildDefaultResultFilters = (): ResultFilters => {
const endDate = new Date();
const startDate = new Date(endDate);
startDate.setDate(startDate.getDate() - 365);
const endDateValue = formatLocalDate(endDate);
return {
startDate: formatLocalDate(startDate),
endDate: formatLocalDate(endDate),
startDate: getWaterRiskMinStartDate(endDateValue)!,
endDate: endDateValue,
ctpvCd: "ALL",
sggCd: "ALL",
areaId: "ALL",
@@ -191,12 +195,10 @@ const buildResultRowKey = (row: WaterRiskResultRow) =>
/** 실제 통수위험 API를 조회하고 선택 결과를 부모 지도에 전달하는 팝업이다. */
export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
// 팝업 최초 진입에만 지정 기간을 사용하고 초기화는 기본 조회조건을 새로 만든다.
const initialFilters = useMemo(() => ({
...buildDefaultResultFilters(),
startDate: "2026-08-15",
endDate: "2026-08-17",
}), []);
// 최초 진입과 초기화 모두 오늘을 종료일로 하는 최근 1년을 사용한다.
const initialFilters = useMemo(() => buildDefaultResultFilters(), []);
// 과거분석은 오늘까지 선택 가능하며, 시작일의 범위는 선택 종료일에 따라 달라진다.
const today = formatLocalDate(new Date());
const [resultMode, setResultMode] = useState<WaterRiskResultMode>("current");
const [draftResultFilters, setDraftResultFilters] =
useState<ResultFilters>(initialFilters);
@@ -429,15 +431,17 @@ export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
/** 검증된 검색조건을 적용하고 첫 페이지를 새로 조회한다. */
const handleApplyResultFilters = () => {
if (!draftResultFilters.startDate || !draftResultFilters.endDate) {
setErrorMessage("조회 시작일과 종료일을 입력해야 합니다.");
return;
}
if (draftResultFilters.startDate > draftResultFilters.endDate) {
setErrorMessage("조회 시작일은 종료일보다 늦을 수 없습니다.");
return;
if (resultMode === "history") {
const dateError = validateWaterRiskDateRange(
draftResultFilters.startDate, draftResultFilters.endDate, today,
);
if (dateError) {
setErrorMessage(dateError);
return;
}
}
setErrorMessage("");
setResultCurrentPage(1);
setAppliedResultFilters({ ...draftResultFilters });
setReloadVersion((version) => version + 1);
@@ -524,6 +528,8 @@ export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
<input
type="date"
value={draftResultFilters.startDate}
min={getWaterRiskMinStartDate(draftResultFilters.endDate)}
max={draftResultFilters.endDate || today}
onChange={(event) =>
setDraftResultFilters((current) => ({
...current,
@@ -537,9 +543,11 @@ export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
<input
type="date"
value={draftResultFilters.endDate}
max={today}
onChange={(event) =>
setDraftResultFilters((current) => ({
...current,
startDate: adjustWaterRiskStartDate(current.startDate, event.target.value),
endDate: event.target.value,
}))
}
@@ -674,6 +682,8 @@ export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
setAppliedResultFilters(defaultFilters);
setResultCurrentPage(1);
setSelectedResultKey("");
setErrorMessage("");
setReloadVersion((version) => version + 1);
}}
>
초기화
@@ -681,6 +691,12 @@ export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
</div>
</PopupSearchPanel>
{errorMessage ? (
<div role="alert" className="shrink-0 px-1 text-xl text-destructive">
{errorMessage}
</div>
) : null}
<MapPopupDataTable
rows={tableRows}
headlist={WATER_RISK_RESULT_HEADLIST}
@@ -715,11 +731,6 @@ export default function WaterRiskPopupPage(_props: WindowPopupContentProps) {
</span>
}
/>
{errorMessage ? (
<div aria-live="polite" className="px-1 text-xl text-destructive">
{errorMessage}
</div>
) : null}
</section>
</StandardPopupLayout>
);