diff --git a/apps/dm/app/(with-layout)/apply/status/page.tsx b/apps/dm/app/(with-layout)/apply/status/page.tsx index d5dbf68c5..97fe96ead 100644 --- a/apps/dm/app/(with-layout)/apply/status/page.tsx +++ b/apps/dm/app/(with-layout)/apply/status/page.tsx @@ -30,6 +30,19 @@ const formatValue = (value: string | number | null | undefined) => { return String(value); }; +const formatNumberWithComma = (value: string | number | null | undefined) => { + if (value === null || value === undefined || value === "") return "-"; + + const normalized = + typeof value === "string" ? Number(value.replace(/,/g, "")) : Number(value); + + if (Number.isNaN(normalized)) { + return String(value); + } + + return normalized.toLocaleString("ko-KR"); +}; + const formatBelow = (value: string | number | null | undefined) => { if (value === null || value === undefined || value === "") return "-"; if (Number(value) === -1) return "불검출"; @@ -234,9 +247,9 @@ export default function DemandStatusPage() { return [ { label: "요구시기", key: "dmndTmng", value: formatDate(selectedSdmInfoStatus.dmndTmng), required: true }, - { label: "요구수량(㎥/d)", key: "dmndQty", value: formatValue(selectedSdmInfoStatus.dmndQty) }, + { label: "요구수량(㎥/d)", key: "dmndQty", value: formatNumberWithComma(selectedSdmInfoStatus.dmndQty) }, { label: "사용용도", key: "useUsgCd", value: formatValue(selectedSdmInfoStatus.useUsgCd) }, - { label: "희망단가(원/㎥)", key: "wntUntprc", value: formatValue(selectedSdmInfoStatus.wntUntprc) }, + { label: "희망단가(원/㎥)", key: "wntUntprc", value: formatNumberWithComma(selectedSdmInfoStatus.wntUntprc) }, ]; }, [selectedSdmInfoStatus]); @@ -520,7 +533,7 @@ export default function DemandStatusPage() { {!selectedSdmInfoStatus ? (
- 상세 정보를 표시할 신청건이 없습니다. + 조회된 결과가 없습니다.
) : (
diff --git a/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx index 4d6a92229..0cae843bb 100644 --- a/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx +++ b/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx @@ -14,6 +14,7 @@ import { type DmdCoReqType, type DmdMatTableType, } from "@/app/store/matDmd/coMatRvw/type"; +import { DEFAULT_LIST_SIZE } from "@/src/shared/config"; import { formH1Class } from "@/components/lib/class/comClass"; import { formatPhoneNumber, @@ -46,6 +47,50 @@ import { useEffect, useRef, useState } from "react"; import { useForm, useWatch } from "react-hook-form"; import { z } from "zod"; +const formatNumberWithComma = (value: string | number | null | undefined) => { + if (value === null || value === undefined || value === "") return ""; + + const normalized = + typeof value === "string" ? Number(value.replace(/,/g, "")) : Number(value); + + if (Number.isNaN(normalized)) { + return String(value); + } + + return normalized.toLocaleString("ko-KR"); +}; + +const EMPTY_DETAIL_FORM: Partial = { + dmdInfoSn: 0, + dmdInfoId: "", + dmndQty: undefined, + wntUntprc: undefined, + useUsgCd: "", + dmndTmng: undefined, + grssClfg: undefined, + combResdch: undefined, + trbt: undefined, + blgcOxygDmndQnt: undefined, + smll: undefined, + crmty: undefined, + tn: undefined, + tph: undefined, + ph: undefined, + clIonQnt: undefined, + cdtnv: undefined, + rmrk: undefined, + ruseUtztnFcltNm: "", + splyCndtList: [], + totalConstCost: 0, + demandCst: { + usgPrcsProcs: "", + cstrnCst: 0, + fcltSbsdCstrnCst: 0, + prcsFcltCpctCstrnCst: 0, + }, + demandMatching: undefined, + demandCo: undefined, +}; export default function CoMatRvw() { const readOnlyInputClass = "bg-slate-50 text-gray-700"; @@ -75,6 +120,8 @@ export default function CoMatRvw() { const [toDate, setToDate] = useState( String(new Date().getFullYear()) ); + const [selectedRowIndex, setSelectedRowIndex] = useState(-1); + const [resetSelection, setResetSelection] = useState(false); const [selectData, setSelectData] = useState(null); // selectData를 null로 초기화 const [selectionVersion, setSelectionVersion] = useState(0); const bottomRef = useRef(null); @@ -100,14 +147,14 @@ export default function CoMatRvw() { if (dmdCoNm.length > 0) { coMatRvwSearch( pageNo, - 13, + DEFAULT_LIST_SIZE, String(startYear), String(endYear), sggCd, dmdCoNm ); } else { - coMatRvwInqua(pageNo, 13, String(startYear), String(endYear), sggCd); + coMatRvwInqua(pageNo, DEFAULT_LIST_SIZE, String(startYear), String(endYear), sggCd); } }; @@ -119,11 +166,22 @@ export default function CoMatRvw() { const TableCellClick = (index: number) => { if (coMatRvwRes && coMatRvwRes[index]) { + setSelectedRowIndex(index); + setResetSelection(false); setSelectData(coMatRvwRes[index]); setSelectionVersion((v) => v + 1); // 행을 클릭할 때마다 버전을 1씩 증가 bottomRef.current?.scrollIntoView({ behavior: "smooth" }); // 화면 스크롤 처리 } }; + + const resetDetailSections = () => { + setSelectedRowIndex(-1); + setResetSelection(true); + setSelectData(null); + form.reset(EMPTY_DETAIL_FORM); + setSelectionVersion((v) => v + 1); + }; + const useUsgCdWatch = useWatch({ control: form.control, name: "useUsgCd" }); const useUsgCdText = code.sewageOutFclttUse?.find((item) => item.val === useUsgCdWatch)?.text ?? @@ -166,6 +224,9 @@ export default function CoMatRvw() { }; }); setDmdMtaData(tableData(data, { code })); + } else { + setDmdMtaData([]); + setSelectData(null); } }, [coMatRvwRes]); @@ -185,7 +246,7 @@ export default function CoMatRvw() { useEffect(() => { if (!initRef.current) { - coMatRvwInit(1, 13, fromDate, toDate); + coMatRvwInit(1, DEFAULT_LIST_SIZE, fromDate, toDate); //setMounted(true); initRef.current = true; } @@ -295,6 +356,7 @@ export default function CoMatRvw() { ); } else { const con = getCurrentRegionCode(); + resetDetailSections(); //setPageNatiion(1); getSearch(1, fromNum, toNum, con, dmdCoNm); } @@ -321,8 +383,10 @@ export default function CoMatRvw() { tableData={dmdMatData || []} headlist={coRvwHeadList} widthFixed={true} - pageSize={13} + pageSize={DEFAULT_LIST_SIZE} total={coMatRvwCount} + resetSelection={resetSelection} + index={selectedRowIndex} cellClick={(index: number | undefined) => { if (index !== undefined && index >= 0) { TableCellClick(index); @@ -330,6 +394,7 @@ export default function CoMatRvw() { }} onPageChange={(val) => { const con = getCurrentRegionCode(); + resetDetailSections(); //setPageNatiion(val); getSearch(val, Number(fromDate), Number(toDate), con, dmdCoNm); }} @@ -377,12 +442,11 @@ export default function CoMatRvw() { { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly className={readOnlyInputClass} /> @@ -416,15 +480,14 @@ export default function CoMatRvw() { control={form.control} name="wntUntprc" render={({ field }) => ( - + { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly className={readOnlyInputClass} /> @@ -448,9 +511,13 @@ export default function CoMatRvw() { className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`} placeholder="" value={ - field.value != -1 ||field.value != undefined - ? `${field.value}` - : "불검출" + field.value === null || + field.value === undefined || + field.value === "" + ? "" + : field.value === -1 + ? "불검출" + : formatNumberWithComma(field.value) } readOnly /> @@ -480,7 +547,7 @@ export default function CoMatRvw() { type="text" className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`} placeholder="" - value={field.value ?? ""} + value={formatNumberWithComma(field.value)} readOnly /> @@ -504,7 +571,7 @@ export default function CoMatRvw() { placeholder="" className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`} type="text" - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly /> @@ -532,7 +599,7 @@ export default function CoMatRvw() { onChange={(e) => { field.onChange(Number(e.target.value)); }} - value={field.value ?? ""} + value={formatNumberWithComma(field.value)} readOnly /> @@ -574,7 +641,7 @@ export default function CoMatRvw() { className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`} type="text" step="0.1" - value={field.value ?? ""} + value={formatNumberWithComma(field.value)} readOnly /> @@ -601,7 +668,7 @@ export default function CoMatRvw() { onChange={(e) => { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly /> @@ -628,7 +695,7 @@ export default function CoMatRvw() { onChange={(e) => { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly /> @@ -655,7 +722,7 @@ export default function CoMatRvw() { onChange={(e) => { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly />
@@ -679,7 +746,7 @@ export default function CoMatRvw() { onChange={(e) => { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly /> @@ -701,12 +768,12 @@ export default function CoMatRvw() {
{ field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={formatNumberWithComma(field.value)} readOnly /> diff --git a/apps/wr/app/store/matDmd/coMatRvw/index.tsx b/apps/wr/app/store/matDmd/coMatRvw/index.tsx index b347a1df8..afeb36fc1 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/index.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/index.tsx @@ -1,4 +1,5 @@ import { fetchType, getFetchWithCount, putFectch } from "@/components/lib/api"; +import { DEFAULT_LIST_SIZE } from "@/src/shared/config"; import type { CommonTableProps } from "../../common/type/header"; import { constCostHeadListExport, @@ -12,6 +13,7 @@ const coRvwHeadList = coRvwHeadListExport; const coRvwNodeList = coRvwNodeListExport; const rateFeeHeadList = rateFeeHeadListExport; const constCostHeadList = constCostHeadListExport; + export type coRvwState = { coRvw: { isInit: boolean; @@ -118,7 +120,7 @@ export const coRvwActionsExport: (set: any) => coRvwActions = (set: any) => { const coMatRvwRes = await coMatInit( 1, - 10, + DEFAULT_LIST_SIZE, new Date().getFullYear().toString(), new Date().getFullYear().toString() ); diff --git a/apps/wr/app/store/matDmd/coMatRvw/type.tsx b/apps/wr/app/store/matDmd/coMatRvw/type.tsx index 388c24f45..ba618aecd 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/type.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/type.tsx @@ -75,7 +75,7 @@ export const DmdCoReqSchema = z.object({ dmndTmng: z.coerce.date().nullish(), // 요구시기 dmndQty: z.number().nullish(), // 요구수량(m³/일) blgcOxygDmndQnt: z.number().nullish(), // 생물학적 산소요구량(BOD)(mg/L) - wntUntprc: z.number().nullish(), // 희망단가(원/m3) + wntUntprc: z.number().nullish(), // 희망단가(원/m³) grssClfg: z.number().nullish(), // 총대장균군수(개/100mL) combResdch: z.number().nullish(), // 결합잔류염소(mg/L) trbt: z.number().nullish(), // 탁도(NTU) diff --git a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx index 09ed01987..2b567979c 100644 --- a/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx +++ b/apps/wr/components/ui/form/coMat/conCostForm/conCostForm.tsx @@ -28,6 +28,19 @@ import PopoverUi from "@common/business_components/ui/popover_ui"; import { Button, Checkbox, Input, Label } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; import { useForm, type UseFormReturn } from "react-hook-form"; + +const formatNumberWithComma = (value: string | number | null | undefined) => { + if (value === null || value === undefined || value === "") return ""; + + const normalized = + typeof value === "string" ? Number(value.replace(/,/g, "")) : Number(value); + + if (Number.isNaN(normalized)) { + return String(value); + } + + return normalized.toLocaleString("ko-KR"); +}; /** * ConCostForm * 호출: (with-layout)/matMng/coMat/coMatRvw @@ -456,12 +469,16 @@ export default function ConCostForm({ { field.onChange(Number(e.target.value)); }} - value={field.value ?? 0} + value={ + isSim + ? field.value ?? 0 + : formatNumberWithComma(field.value) + } readOnly={!isSim} className={!isSim ? readOnlyInputClass : ""} /> @@ -524,14 +541,13 @@ export default function ConCostForm({ { console.log("dmndQty ", e); //field.onChange(Number(e.target.value) * 365 ); }} // value={Number(field.value) * 365 || 0} - value={Number(field.value) || 0} + value={formatNumberWithComma(Number(field.value) || 0)} readOnly className={readOnlyInputClass} />