-
-
+
-
>
);
};
diff --git a/apps/st/src/components/statistics/input/SubmitDailog.tsx b/apps/st/src/components/statistics/input/SubmitDailog.tsx
new file mode 100644
index 000000000..b286117b7
--- /dev/null
+++ b/apps/st/src/components/statistics/input/SubmitDailog.tsx
@@ -0,0 +1,167 @@
+"use client";
+
+import {
+ Button,
+ Dialog,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ Input,
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableRow,
+} from "@common/components";
+import { useEffect } from "react";
+import { useForm, Controller } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { statisticsInputSubmitInfoSchema, type StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
+import { type SewerageSupplyRateStatusInfo } from "@/entities/statistics/model/statistics-sewage-supply-rate-input-interface";
+
+/** 숫자만 추출 후 하이픈 포맷 (010-1234-5678, 02-123-4567 등) */
+function formatPhoneWithHyphen(value: string): string {
+ const digits = value.replace(/\D/g, "");
+ if (digits.length <= 3) return digits;
+ if (digits.startsWith("010")) {
+ if (digits.length <= 7) return `010-${digits.slice(3)}`;
+ return `010-${digits.slice(3, 7)}-${digits.slice(7, 11)}`;
+ }
+ if (digits.startsWith("02")) {
+ if (digits.length <= 5) return `02-${digits.slice(2)}`;
+ if (digits.length <= 9) return `02-${digits.slice(2, 5)}-${digits.slice(5, 9)}`;
+ return `02-${digits.slice(2, 6)}-${digits.slice(6, 10)}`;
+ }
+ if (digits.length <= 6) return `${digits.slice(0, 3)}-${digits.slice(3)}`;
+ return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
+}
+
+const PHONE_FIELDS: (keyof StatisticsInputSubmitInfoFormData)[] = ["laePicTelNo", "laeIdfrTelNo"];
+
+interface SubmitDialogProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+ statusInfo: SewerageSupplyRateStatusInfo | null;
+ /** 다이얼로그에서 저장 클릭 시 호출. 제출 정보를 넘기면 부모에서 requestData에 포함해 제출 API 호출 */
+ onConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise
;
+}
+
+const defaultValues: StatisticsInputSubmitInfoFormData = {
+ laePicNm: "",
+ laeKbrdrJbgdNm: "",
+ laeKbrdrDeptNm: "",
+ laePicTelNo: "",
+ laeIdfrNm: "",
+ laeIdfrJbgdNm: "",
+ laeIdfrDeptNm: "",
+ laeIdfrTelNo: "",
+};
+
+function statusInfoToFormData(info: SewerageSupplyRateStatusInfo): StatisticsInputSubmitInfoFormData {
+ return {
+ laePicNm: info.laePicNm ?? "",
+ laeKbrdrJbgdNm: info.laeKbrdrJbgdNm ?? "",
+ laeKbrdrDeptNm: info.laeKbrdrDeptNm ?? "",
+ laePicTelNo: info.laePicTelNo ?? "",
+ laeIdfrNm: info.laeIdfrNm ?? "",
+ laeIdfrJbgdNm: info.laeIdfrJbgdNm ?? "",
+ laeIdfrDeptNm: info.laeIdfrDeptNm ?? "",
+ laeIdfrTelNo: info.laeIdfrTelNo ?? "",
+ };
+}
+
+const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm }: SubmitDialogProps) => {
+ const { control, handleSubmit, reset, formState: { errors } } = useForm({
+ resolver: zodResolver(statisticsInputSubmitInfoSchema),
+ defaultValues,
+ });
+
+ useEffect(() => {
+ if (open) {
+ reset(statusInfo ? statusInfoToFormData(statusInfo) : defaultValues);
+ }
+ }, [open, statusInfo, reset]);
+
+ async function onSubmit(data: StatisticsInputSubmitInfoFormData) {
+ await onConfirm?.(data);
+ onOpenChange(false);
+ reset(defaultValues);
+ }
+
+ function handleCancel() {
+ onOpenChange(false);
+ reset(defaultValues);
+ }
+
+ const rows: { name: keyof StatisticsInputSubmitInfoFormData; label: string; placeholder: string }[] = [
+ { name: "laePicNm", label: "작성자 명", placeholder: "작성자 명 입력" },
+ { name: "laeKbrdrJbgdNm", label: "작성자 직제", placeholder: "작성자 직제 입력" },
+ { name: "laeKbrdrDeptNm", label: "작성자 부서", placeholder: "작성자 부서 입력" },
+ { name: "laePicTelNo", label: "작성자 연락처", placeholder: "작성자 연락처 입력" },
+ { name: "laeIdfrNm", label: "승인자명", placeholder: "승인자명 입력" },
+ { name: "laeIdfrJbgdNm", label: "승인자 직제", placeholder: "승인자 직제 입력" },
+ { name: "laeIdfrDeptNm", label: "승인자 부서", placeholder: "승인자 부서 입력" },
+ { name: "laeIdfrTelNo", label: "승인자 연락처", placeholder: "승인자 연락처" },
+ ];
+
+ return (
+
+ );
+};
+
+export default SubmitDailog;
\ No newline at end of file
diff --git a/apps/st/src/components/statistics/management/LogHistory.tsx b/apps/st/src/components/statistics/management/LogHistory.tsx
new file mode 100644
index 000000000..0b45ce9fd
--- /dev/null
+++ b/apps/st/src/components/statistics/management/LogHistory.tsx
@@ -0,0 +1,113 @@
+"use client";
+
+import { useState } from 'react';
+// import useSWR from 'swr';
+
+import {
+ Button,
+ // Input,
+ Label,
+ // Select,
+ // SelectTrigger,
+ // SelectContent,
+ // SelectItem,
+ // SelectValue
+}
+ from "@common/components";
+import DataGrid from '@/components/module/DataGrid';
+import { CodeSelect } from '@/entities/code';
+
+import { LogHistoryColumn } from '@/components/util/column/management/LogHistoryColumn';
+import { useAlertStore } from "@/shared/lib";
+// import { LwpoCodeApi } from "@/entities/code";
+
+// const getStateCdListFetcher = async () => {
+// return LwpoCodeApi.getLwpoCodeList({
+// sort: 'regDt,desc',
+// upCd: 'STITEM',
+// page: 0,
+// size: 100,
+// });
+// }
+
+const LogHistory = () => {
+ // const { setMessage: alert } = useAlertStore((state) => state);
+ const [statsCd, setStatsCd] = useState('');
+
+ // const { data: lwpoCdList } = useSWR(
+ // "lwpo-code-list",
+ // getStateCdListFetcher,
+ // {
+ // revalidateOnFocus: false,
+ // revalidateOnReconnect: false,
+ // revalidateIfStale: false,
+ // dedupingInterval: 2000,
+ // shouldRetryOnError: false,
+ // onSuccess: (data) => {
+ // if (!data.content || data.content.length == 0) {
+ // alert(`시도 목록을 불러오는데 실패했습니다.
+ // 새로고침 후 다시 시도해주세요.`);
+ // }
+ // },
+ // onError: () => {
+ // alert(`시도 목록을 불러오는데 실패했습니다.
+ // 새로고침 후 다시 시도해주세요.`);
+ // },
+ // }
+ // );
+
+ return (
+
+ );
+};
+
+export default LogHistory;
\ No newline at end of file
diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx
index 8a9df541a..3fc34a034 100644
--- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx
+++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx
@@ -1,26 +1,82 @@
-import { useState } from "react";
-
-import { DataGrid } from "@rsone/components";
+import { useState, useMemo } from "react";
+import DataGrid from "@/components/module/DataGrid";
import SearchForm from "@/components/module/SearchForm";
import SaveButton from "@/components/button/SaveButton";
import ApproveButton from "@/components/button/ApproveButton";
import ReviewOpinionButton from "@/components/button/ReviewOpinionButton";
import ReturnButton from "@/components/button/ReturnButton";
+import { LoadingWithAnimation } from "@common/components";
+import { useAlertStore } from "@/shared/lib";
import { PumpingStationInfoList } from "@/components/util/column/review/PumpingStationRvwColumn";
+import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
+import type { SearchFormValues } from "@/components/type/SearchForm.type";
+import { toGridRows } from "@/components/util/grid/gridFunction";
-// 하수도 통계 관리 05.펌프장
+// 하수도 통계 검토 05.중계펌프장
const PumpingStationRvw = () => {
+ const { setMessage: alert } = useAlertStore((state) => state);
const [rowData, setRowData] = useState[]>([]);
+ const [isLoading, setIsLoading] = useState(false);
- const approveFunc = () => { console.log('approveFunc'); };
- const saveFunc = () => { console.log('submit'); };
- const reviewOpinionFunc = () => { console.log('reviewOpinionFunc'); };
- const returnFunc = () => { console.log('returnFunc'); };
+ const columnInfo = useMemo(() => {
+ const { columns, columnLayout, fixedColumns, rowStartNum } = PumpingStationInfoList;
+ return {
+ columnLayout,
+ fixedColumns,
+ rowStartNum,
+ columns: columns.map((col) => ({
+ ...col,
+ editable: false as const, // 검토 화면이므로 읽기 전용
+ styleName: col.styleName ?? ("rg-cell-readonly" as const),
+ })),
+ };
+ }, []);
+
+ const handleReset = () => {
+ setRowData([]);
+ };
+
+ const handleSearch = async (values: SearchFormValues) => {
+ if (values.sido === '' || values.sido === 'ALL') {
+ alert('시도를 선택해주세요.');
+ return;
+ }
+
+ try {
+ setIsLoading(true);
+
+ const response = await statisticsManagementApi.getMediationPumpStationList({
+ sido: values.sido,
+ gugun: values.gugun === 'ALL' ? '' : values.gugun,
+ bsnmCd: values.bsnmCd,
+ yr: values.year,
+ bscFctNm: values.fctName, // 시설명 검색
+ });
+
+ if (response.status === 'success' && response.data) {
+ setRowData(toGridRows(response.data));
+ } else {
+ setRowData([]);
+ alert(response.message || "데이터가 없습니다.");
+ }
+ } catch (error) {
+ console.error("중계펌프장 조회 중 에러 발생:", error);
+ alert('데이터 조회 중 오류가 발생했습니다.');
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const approveFunc = () => console.log('approveFunc');
+ const saveFunc = () => console.log('submit');
+ const reviewOpinionFunc = () => console.log('reviewOpinionFunc');
+ const returnFunc = () => console.log('returnFunc');
return (
- <>
-
+
+
+
@@ -29,8 +85,24 @@ const PumpingStationRvw = () => {
-
- >
+
+ {isLoading && (
+
+ )}
+
+
+
);
};
diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx
index 03549083e..d8cdc7d0e 100644
--- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx
+++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx
@@ -1,51 +1,161 @@
-import { useState } from "react";
-
-import { TabDataGrid } from "@rsone/components";
+import { useState, useMemo, useRef } from "react";
+import TabDataGrid from "@/components/module/TabDataGrid";
import SearchForm from "@/components/module/SearchForm";
import SaveButton from "@/components/button/SaveButton";
import ApproveButton from "@/components/button/ApproveButton";
import ReviewOpinionButton from "@/components/button/ReviewOpinionButton";
import ReturnButton from "@/components/button/ReturnButton";
+import { LoadingWithAnimation } from "@common/components";
+import { useAlertStore } from "@/shared/lib";
+import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainRvwColumn";
+import type { ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.type";
+import type { SearchFormValues } from "@/components/type/SearchForm.type";
+import { toGridRows } from "@/components/util/grid/gridFunction";
+import type { SewerPipeMtcRequestParams } from "@/entities/statistics/model/statistics-sewage-pipe-mtc-review-interface";
-// 하수도 통계 관리 03. 하수관로 유지 관리
+
+// 하수도 통계 검토 03. 하수관로 유지 관리
const SewagePipeMaintainRvw = () => {
+ const { setMessage: alert } = useAlertStore((state) => state);
const [rowDataMap, setRowDataMap] = useState