From 5967fcd896d9f4a589cac859a035adf2e39bf4a0 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Tue, 10 Jun 2025 13:06:41 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=EC=88=98=EC=9A=94=EB=A7=A4=EC=B9=AD?= =?UTF-8?q?=EA=B2=80=ED=86=A0,=20=EC=9E=AC=EC=9D=B4=EC=9A=A9=EA=B2=80?= =?UTF-8?q?=ED=86=A0=EC=9D=B4=EB=A0=A5=20=ED=8D=BC=EB=B8=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/matDmd/coMatRvw/page.tsx | 833 +++++++++++++----- .../app/matMng/matDmd/ruseRvwHstry/page.tsx | 14 +- 2 files changed, 608 insertions(+), 239 deletions(-) diff --git a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx b/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx index aeaf07ec8..9ab1414c0 100644 --- a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useWrStore } from "@/app/store"; -import { formTableName } from "@/components/lib/class/comClass"; +import { formH1Class, formTableName } from "@/components/lib/class/comClass"; import { getCity } from "@/components/lib/func/commom"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; @@ -79,7 +79,7 @@ export default function CoMatRvw() { onSelectValue={getSelCity} />
- +
{ if (date) setFromDate(date) }} /> - ~ + ~ { if (date) setToDate(date) }} /> @@ -125,7 +125,7 @@ export default function CoMatRvw() {
-
+
{ }} >
-
-

표준공사비 산정

-
-

처리시설 표준공사비 산정

- - - - -
-
-
- ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? ""} - /> - - )} - /> -
-
- ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - - )} - /> -
-
- - - ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value || ""} - className="mt-2" - /> - - )} - /> -
-
- ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - - )} - /> -
-
-
- - -
- ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - - )} - /> -
-
-
- - -
- ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - - )} - /> -
- -
- - ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - - )} - /> -
-
-
- - -
- ( - - { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? ""} - /> - - )} - /> -
- -
-
+ +

수요신청 상세현황

+ +
+
( - + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? ""} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+

요구수질

+
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ ( + + { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + + )} + /> +
+
+

공급처 후보지

+
+
+ ( + + { + field.onChange(String(e.target.value)); + }} + value={field.value ?? ""} + /> + + )} + /> +
+
+ ( + + { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + + )} + /> +
+
+ ( + + { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + + )} + /> +
+
+ +
+
+

표준공사비 산정

+
+

처리시설 표준공사비 산정

+ + + + +
+
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? ""} + /> + + )} + /> +
+
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+ + + ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value || ""} + className="mt-2" + /> + + )} + /> +
+
+ ( + + { field.onChange(Number(e.target.value)); @@ -365,23 +605,121 @@ export default function CoMatRvw() { )} />
-
- - -
-
+
+
+ + +
( -
+
+
+ + +
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+ +
+ + ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + + )} + /> +
+
+
+ + +
+ ( + + { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? ""} + /> + + )} + /> +
+ +
+
+ ( + { field.onChange(Number(e.target.value)); }} - readOnly={true} value={field.value ?? 0} /> - - )} - /> + )} + /> +
+
+ + +
+
+ ( + + )} + /> +
-
- + +
diff --git a/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx b/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx index 166e1902c..d6a2b47ac 100644 --- a/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx +++ b/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx @@ -69,7 +69,7 @@ return ( {""}
- +
{ if (date) setFromDate(date) }} /> - ~ + ~ { if (date) setToDate(date) }} /> @@ -100,7 +100,7 @@ return ( }} /> { @@ -148,7 +148,7 @@ return (

수요신청 상세현황

-

표준공사비 산정

+

표준공사비 산정

처리시설 표준공사비 산정

-
+
From a3e46f3230b5e50748c38bf270fec3457e3b064a Mon Sep 17 00:00:00 2001 From: jyha00 Date: Tue, 10 Jun 2025 19:53:04 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=EC=8B=A4=EC=A0=81=20=EC=B0=A8=ED=8A=B8=20?= =?UTF-8?q?=EB=B0=8F=20=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/matDmd/coMatRvw/page.tsx | 41 +- .../prfmncSttn/pbnstPrfmncSttn/page.tsx | 553 +++++++++++++++++- .../prfmncSttn/pbnstPrfmncSttn/index.tsx | 40 +- 3 files changed, 596 insertions(+), 38 deletions(-) diff --git a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx b/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx index 9ab1414c0..01f3cef8a 100644 --- a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx @@ -4,7 +4,7 @@ import { useWrStore } from "@/app/store"; import { formH1Class, formTableName } from "@/components/lib/class/comClass"; import { getCity } from "@/components/lib/func/commom"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; +import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, DatePicker, Input, Label } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -20,6 +20,9 @@ export default function CoMatRvw() { const [toDate, setToDate] = useState(new Date()); const [selectSgg, setSelectSgg] = useState() const [objSearch, setObjSearch] = useState({ sgg: "", city: "" }); + const [isPrcsMo, setIsPrcsMo] = useState<{ + isModal: boolean; + }>({ isModal: false }); const schema = z.object({ @@ -566,7 +569,7 @@ export default function CoMatRvw() { />
- +
+ + { }} + onPageChange={() => { }} + /> + + } + bodyClass="w-[25vw] max-w-none h-[60vh]" + open={isPrcsMo.isModal} + onOpenChange={(open) => { + setIsPrcsMo({ isModal: open }); + }} + />
diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index 6a49580ad..f2040f023 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -2,54 +2,528 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; -import type { FcPrfType, PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; -import type { prfmncType } from "@/app/store/prfmncSttn/pbnstPrfmncSttn/headList"; +import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { yearOptions } from "@/components/lib/func/commom"; -import { ContentsDiv, Title, SearchBaseForm, SelectBox, SearchInput, UiTable, type ReturnType, MainChart, type ChartConfig } from "@common/business_components"; +import { InputTableBody } from "@/components/lib/func/TableData"; +import { ContentsDiv, Title, SearchBaseForm, SelectBox, SearchInput, UiTable, type ReturnType, MainChart, type ChartConfig, CHART_FORM, ScrollArea } from "@common/business_components"; import DoughnutChart from "@common/business_components/ui/chart/DoughnutChart"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, Label } from "@common/components/ui"; +import { Button, Label, Table, TableBody, TableHeader } from "@common/components/ui"; import { useEffect, useRef, useState } from "react"; +import { headMakeprfmnc } from "../../prfmncReg/chkgdnReg/TableHead"; export default function PbnstPrfmncSttn() { - const { code, tableHeadMaker, pbnstPrfmncSttn, pbnstPrfmncInit, pbnstPrfmncSearch } = useWrStore((state) => state); - const { pbnstPrfHeadList, pbnstPrfmncRes, prfmncRes, rawData } = pbnstPrfmncSttn; + const { code, tableHeadMaker, pbnstPrfmncSttn, pbnstPrfmncInit, pbnstPrfmncSearch, prfmnc } = useWrStore((state) => state); + const { monthHeadList } = prfmnc + const { pbnstPrfHeadList, pbnstPrfmncRes, prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn; const [isChHead, setIsChHead] = useState(false); const [fromDate, setFromDate] = useState(String(new Date().getFullYear())); const [toDate, setToDate] = useState(String(new Date().getFullYear())); const [year, setYear] = useState(String(new Date().getFullYear())); - const [pbnstTable, setPbnstTable] = useState(); const [bdstTable, setbdstTable] = useState(); const ref = useRef({} as ReturnType); const [swtrmtFcltNm, setSwtrmtFcltNm] = useState(); - const [chartConfig, setChartConfig] = useState(); - + const [chartConfig, setChartConfig] = useState({}); + const [chartData, setChartData] = useState([]); + const [dnInUsage, setDnInUsage] = useState([]); + const [dnInChartConfig, setDnInChartConfig] = useState({}); + const [dnOutUsage, setDnOutUsage] = useState([]); + const [dnOutChartConfig, setDnOutChartConfig] = useState({}); + const [barData, setBarData] = useState([]); + const [barChartConfig, setBarChartConfig] = useState({}); + const [prfData, setPrfData] = useState(); + const [lnInChartConfig, setLnInChartConfig] = useState({}); + const [lnOutChartConfig, setLnOutChartConfig] = useState({}); + const [inLineData, setInLineData] = useState<{ + chartData1: lineChartDataProps[]; + chartData2: lineChartDataProps[]; + chartData3: lineChartDataProps[]; + chartData4: lineChartDataProps[]; + chartData5: lineChartDataProps[]; + chartData6: lineChartDataProps[]; + chartData7: lineChartDataProps[]; + chartData8: lineChartDataProps[]; + chartData9: lineChartDataProps[]; + }>(); + // const [lnInChartConfig, setLnInChartConfig] = useState({}); + const [outLineData, setOutLineData] = useState<{ + chartData1: lineChartDataProps[]; + chartData2: lineChartDataProps[]; + chartData3: lineChartDataProps[]; + chartData4: lineChartDataProps[]; + chartData5: lineChartDataProps[]; + chartData6: lineChartDataProps[]; + }>(); + + + + type dnChartForm = { label: string, val: number, fill?: string }; + type barChartForm = { label: string, inUsage: number, outUsage: number }; + type lineChartDataProps = { label: string, val: number, color: string }; + + const prfTableData = (prfList: PrfType[], year:string) => { + const inUsageData = initValInUsage; + const outUsageData = initValOutUsage; + + const inSubtotal = subTotalObj; + const outSubtotal = subTotalObj; + + + const prfFilter = prfList?.filter((e) => e.ym.slice(0, 4) === year) + if (prfList && prfFilter.length > 0) { + prfList?.forEach((prfItem) => { + const month = Number(prfItem?.ym?.slice(4)); // "MM" + const monthKey = `${month}월`; + + inUsageData.forEach((inData: any) => { + const usageKey = inData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + inData[monthKey] = value; + inData.total += value; + + if (inSubtotal && usageKey !== "subtotal") { + (inSubtotal as any)[monthKey] = + ((inSubtotal as any)[monthKey] ?? 0) + value; + inSubtotal.total += value; + } + }); + + outUsageData.forEach((outData: any) => { + const usageKey = outData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + outData[monthKey] = value; + outData.total += value; + + if (usageKey !== "subtotal") { + (outSubtotal as any)[monthKey] = + ((outSubtotal as any)[monthKey] ?? 0) + value; + outSubtotal.total += value; + } + }); + }); + inUsageData.push(inSubtotal); + outUsageData.push(outSubtotal); + const usageTotalObj: { [key: string]: any } = totalObj; + for (const key in usageTotalObj) { + if (["usage", "gubun", "edit"].includes(key)) continue; + const val = + (Number((inSubtotal as any)[key]) || 0) + + (Number((outSubtotal as any)[key]) || 0); + + (usageTotalObj as any)[key] = val; + } + const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; + setPrfData(tableData); + + } else { + setPrfData([]); + } + } useEffect(() => { - console.log("ㅇㅇ", rawData) + let wshwtr = 0; + let coolUswtr = 0; + let cleanUswtr = 0; + let drwtUswtr = 0; + let dltnUswtr = 0; + let ithlRswtr = 0; + let ithlEtcUswtr = 0; + let cleanToilUswtr = 0; + let resn = 0; + let lndwtr = 0; + let hydUswtr = 0; + let ugwtChr = 0; + let farmUswtr = 0; + let rvrKeepUswtr = 0; + let indstUswtr = 0; if (rawData) { rawData.forEach((item) => { - item.prfList.forEach((element) => { + prfTableData(item.prfList, year); + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + + wshwtr += element.wshwtr; //세척수 + coolUswtr += element.coolUswtr; //냉각수 + cleanUswtr += element.cleanUswtr; //청소수 + drwtUswtr += element.drwtUswtr; //식수대 + dltnUswtr += element.dltnUswtr //희석용수 + ithlRswtr += element.ithlRswtr //중수도 + ithlEtcUswtr += element.ithlEtcUswtr //기타 + cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 + resn += element.resn //세척살수용수 + + lndwtr += element.lndwtr; //조경용수 + hydUswtr += element.hydUswtr; //친수용수 + ugwtChr += element.ugwtChr; //지하수충전 + farmUswtr += element.farmUswtr //농업용수 + rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 + indstUswtr += element.indstUswtr //공업용수 }); }) + const data: dnChartForm[] = [] + data?.push({ label: "세척수", val: wshwtr, fill: "red" }) + data?.push({ label: "냉각수", val: coolUswtr, fill: "orange" }) + data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) + data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) + data?.push({ label: "희석용수", val: dltnUswtr, fill: "skyblue" }) + data?.push({ label: "중수도", val: ithlRswtr, fill: "blue" }) + data?.push({ label: "기타", val: ithlEtcUswtr, fill: "purple" }) + data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "red" }) + data?.push({ label: "세척살수용수", val: resn, fill: "orange" }) + data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) + data?.push({ label: "친수용수", val: hydUswtr, fill: "green" }) + data?.push({ label: "지하수충전", val: ugwtChr, fill: "skyblue" }) + data?.push({ label: "농업용수", val: farmUswtr, fill: "blue" }) + data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "purple" }) + data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) + setChartData(data); } - }, [rawData]) + }, [rawData, year]) + + + useEffect(() => { + const newChartConfig = chartData.reduce((config, element) => { + config[element.label] = { + label: element.label, + fill: element.fill + }; + return config; + }, {} as Record) satisfies ChartConfig; + setChartConfig(newChartConfig); + }, [chartData]); + + // 장내용수 도넛차트 + useEffect(() => { + let wshwtr = 0; + let coolUswtr = 0; + let cleanUswtr = 0; + let drwtUswtr = 0; + let dltnUswtr = 0; + let ithlRswtr = 0; + let ithlEtcUswtr = 0; + let cleanToilUswtr = 0; + let resn = 0; + if (rawData) { + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + wshwtr += element.wshwtr; //세척수 + coolUswtr += element.coolUswtr; //냉각수 + cleanUswtr += element.cleanUswtr; //청소수 + drwtUswtr += element.drwtUswtr; //식수대 + dltnUswtr += element.dltnUswtr //희석용수 + ithlRswtr += element.ithlRswtr //중수도 + ithlEtcUswtr += element.ithlEtcUswtr //기타 + cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 + resn += element.resn //세척살수용수 + }); + }) + const data: dnChartForm[] = [] + data?.push({ label: "세척수", val: wshwtr, fill: "yellow" }) + data?.push({ label: "냉각수", val: coolUswtr, fill: "green" }) + data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) + data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) + data?.push({ label: "희석용수", val: dltnUswtr, fill: "yellow" }) + data?.push({ label: "중수도", val: ithlRswtr, fill: "green" }) + data?.push({ label: "기타", val: ithlEtcUswtr, fill: "yellow" }) + data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "green" }) + data?.push({ label: "세척살수용수", val: resn, fill: "yellow" }) + setDnInUsage(data); + } + }, [rawData, year]) + + useEffect(() => { + const newChartConfig = dnInUsage.reduce((config, element) => { + config[element.label] = { + label: element.label, + fill: element.fill + }; + return config; + }, {} as Record) satisfies ChartConfig; + setDnInChartConfig(newChartConfig); + }, [dnInUsage]); + + // 장외용수 도넛차트 + useEffect(() => { + let lndwtr = 0; + let hydUswtr = 0; + let ugwtChr = 0; + let farmUswtr = 0; + let rvrKeepUswtr = 0; + let indstUswtr = 0; + if (rawData) { + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + lndwtr += element.lndwtr; //조경용수 + hydUswtr += element.hydUswtr; //친수용수 + ugwtChr += element.ugwtChr; //지하수충전 + farmUswtr += element.farmUswtr //농업용수 + rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 + indstUswtr += element.indstUswtr //공업용수 + + }); + }) + const data: dnChartForm[] = [] + data?.push({ label: "조경용수", val: lndwtr, fill: "white" }) + data?.push({ label: "친수용수", val: hydUswtr, fill: "red" }) + data?.push({ label: "지하수충전", val: ugwtChr, fill: "white" }) + data?.push({ label: "농업용수", val: farmUswtr, fill: "orange" }) + data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "white" }) + data?.push({ label: "공업용수", val: indstUswtr, fill: "yellow" }) + setDnOutUsage(data); + } + }, [rawData, year]) + + useEffect(() => { + const newChartConfig = dnOutUsage.reduce((config, element) => { + config[element.label] = { + label: element.label, + fill: element.fill + }; + return config; + }, {} as Record) satisfies ChartConfig; + setDnOutChartConfig(newChartConfig); + }, [dnOutUsage]); + + //월별 장내외 용수 총 실적 막대차트 + useEffect(() => { + let wshwtr = 0; + let coolUswtr = 0; + let cleanUswtr = 0; + let drwtUswtr = 0; + let dltnUswtr = 0; + let ithlRswtr = 0; + let ithlEtcUswtr = 0; + let cleanToilUswtr = 0; + let resn = 0; + let lndwtr = 0; + let hydUswtr = 0; + let ugwtChr = 0; + let farmUswtr = 0; + let rvrKeepUswtr = 0; + let indstUswtr = 0; + let inUsageSum = 0; + let outUsageSum = 0; + let inUsageArr = []; + let outUsageArr = []; + + + if (rawData) { + const data: barChartForm[] = [] + rawData.forEach((item) => { + item.prfList + .filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + + wshwtr = element.wshwtr; //세척수 + coolUswtr = element.coolUswtr; //냉각수 + cleanUswtr = element.cleanUswtr; //청소수 + drwtUswtr = element.drwtUswtr; //식수대 + dltnUswtr = element.dltnUswtr //희석용수 + ithlRswtr = element.ithlRswtr //중수도 + ithlEtcUswtr = element.ithlEtcUswtr //기타 + cleanToilUswtr = element.cleanToilUswtr //청소화장실용수 + resn = element.resn //세척살수용수 + + lndwtr = element.lndwtr; //조경용수 + hydUswtr = element.hydUswtr; //친수용수 + ugwtChr = element.ugwtChr; //지하수충전 + farmUswtr = element.farmUswtr //농업용수 + rvrKeepUswtr = element.rvrKeepUswtr //하천등유지용수 + indstUswtr = element.indstUswtr //공업용수 + + inUsageSum = wshwtr + coolUswtr + cleanUswtr + drwtUswtr + dltnUswtr + ithlRswtr + ithlEtcUswtr + cleanToilUswtr + resn; + inUsageArr.push(inUsageSum) + outUsageSum = lndwtr + hydUswtr + ugwtChr + farmUswtr + rvrKeepUswtr + indstUswtr; + outUsageArr.push(outUsageSum) + + const month = Number(element.ym.slice(4, 6)) + data.push({ label: `${month}월`, inUsage: inUsageSum, outUsage: outUsageSum }) + + }, + ); + + }) + + setBarData(data); + } + }, [rawData, year]) + + useEffect(() => { + const newChartConfig = barData.reduce((config, element) => { + config[element.label] = { + label: element.label, + }; + return config; + + }, {} as Record) satisfies ChartConfig; + setBarChartConfig(newChartConfig); + }, [barData]); + + //월별 장내 용수 실적 라인차트 + useEffect(() => { + + if (rawData) { + const wshwtrData: lineChartDataProps[] = [] + const coolUswtrData: lineChartDataProps[] = [] + const cleanUswtrData: lineChartDataProps[] = [] + const drwtUswtrData: lineChartDataProps[] = [] + const dltnUswtrData: lineChartDataProps[] = [] + const ithlRswtrData: lineChartDataProps[] = [] + const ithlEtcUswtrData: lineChartDataProps[] = [] + const cleanToilUswtrData: lineChartDataProps[] = [] + const resnData: lineChartDataProps[] = [] + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + const month = Number(element.ym.slice(4, 6)) + wshwtrData.push({ label: `${month}월`, val: element.wshwtr, color: "red" }) + coolUswtrData.push({ label: `${month}월`, val: element.coolUswtr, color: "red" }) + cleanUswtrData.push({ label: `${month}월`, val: element.cleanUswtr, color: "red" }) + drwtUswtrData.push({ label: `${month}월`, val: element.drwtUswtr, color: "red" }) + dltnUswtrData.push({ label: `${month}월`, val: element.dltnUswtr, color: "red" }) + ithlRswtrData.push({ label: `${month}월`, val: element.ithlRswtr, color: "red" }) + ithlEtcUswtrData.push({ label: `${month}월`, val: element.ithlEtcUswtr, color: "red" }) + cleanToilUswtrData.push({ label: `${month}월`, val: element.cleanToilUswtr, color: "red" }) + resnData.push({ label: `${month}월`, val: element.resn, color: "red" }) + + }, + ); + }) + const rtndata = { + chartData1: wshwtrData, + chartData2: coolUswtrData, + chartData3: cleanUswtrData, + chartData4: drwtUswtrData, + chartData5: dltnUswtrData, + chartData6: ithlRswtrData, + chartData7: ithlEtcUswtrData, + chartData8: cleanToilUswtrData, + chartData9: resnData + } + + setInLineData(rtndata) + } + }, [rawData, year]) + + useEffect(() => { + if (inLineData?.chartData1) { + const newChartConfig = { + chartData1: { + label: '세척수', + color: "red", + }, + chartData2: { + label: '냉각수', + color: "orange", + }, + chartData3: { + label: '청소수', + color: "yellow", + }, + chartData4: { + label: '식수대', + color: "pink", + }, + chartData5: { + label: '희석용수', + color: "purple", + }, + chartData6: { + label: '중수도', + color: "green", + }, + chartData7: { + label: '기타', + color: "blue", + }, + chartData8: { + label: '청소화장실용수', + color: "black", + }, + chartData9: { + label: '세척살수용수', + color: "skyblue", + }, + } satisfies ChartConfig; + setLnInChartConfig(newChartConfig); + } + }, [inLineData]); + + //월별 장외 용수 실적 라인차트 + useEffect(() => { + if (rawData) { + const lndwtrData: lineChartDataProps[] = [] + const hydUswtrData: lineChartDataProps[] = [] + const ugwtChrData: lineChartDataProps[] = [] + const farmUswtrData: lineChartDataProps[] = [] + const rvrKeepUswtrData: lineChartDataProps[] = [] + const indstUswtrData: lineChartDataProps[] = [] + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + const month = Number(element.ym.slice(4, 6)) + lndwtrData.push({ label: `${month}월`, val: element.lndwtr, color: "red" }) + hydUswtrData.push({ label: `${month}월`, val: element.hydUswtr, color: "red" }) + ugwtChrData.push({ label: `${month}월`, val: element.ugwtChr, color: "red" }) + farmUswtrData.push({ label: `${month}월`, val: element.farmUswtr, color: "red" }) + rvrKeepUswtrData.push({ label: `${month}월`, val: element.rvrKeepUswtr, color: "red" }) + indstUswtrData.push({ label: `${month}월`, val: element.indstUswtr, color: "red" }) + }, + ); + }) + setOutLineData({ + chartData1: lndwtrData, + chartData2: hydUswtrData, + chartData3: ugwtChrData, + chartData4: farmUswtrData, + chartData5: rvrKeepUswtrData, + chartData6: indstUswtrData, + }) + } + }, [rawData, year]) + + useEffect(() => { + if (outLineData?.chartData1) { + const newChartConfig = { + chartData1: { + label: '조경용수', + color: "red", + }, + chartData2: { + label: '친수용수', + color: "orange", + }, + chartData3: { + label: '지하수충전', + color: "yellow", + }, + chartData4: { + label: '농업용수', + color: "pink", + }, + chartData5: { + label: '하천등유지용수', + color: "purple", + }, + chartData6: { + label: '공업용수', + color: "green", + }, + } satisfies ChartConfig; + setLnOutChartConfig(newChartConfig); + } + }, [outLineData]); useEffect(() => { if (!pbnstPrfmncSttn.isInit) { pbnstPrfmncInit("1", "11"); } }, [pbnstPrfmncSttn.isInit, pbnstPrfmncInit]); + useEffect(() => { - console.log("prfmncRes", prfmncRes) setbdstTable(prfmncRes); }, [prfmncRes]); - - useEffect(() => { - }, [ref.current]); return ( <> @@ -118,6 +592,7 @@ export default function PbnstPrfmncSttn() { alert("최대 5년까지 선택 가능합니다."); } else { tableHeadMaker(fromNum, toNum); + } } } @@ -148,23 +623,57 @@ export default function PbnstPrfmncSttn() { className="h-full w-1/12 text-2xl" label="" selectClass={""} - selectArray={yearOptions} + selectArray={selectYearList} value={year} onSelectValue={(val: string | number) => setYear(String(val))} />

장내·외 용도별 하수재이용실적 현황(계)

- { }} chartData={[]} chartTitle={"장내·외 용수 총 실적"} chartForm={"daughnut"} /> -
-
\ - { }} chartData={[]} chartTitle={"장내용수 실적"} chartForm={"daughnut"} /> +
- { }} chartData={[]} chartTitle={"장외용수 실적"} chartForm={"daughnut"} /> + +
+
+

장내·외 월별 하수재이용실적 현황

+
+
+ +
+
+ +
+
+ +
+
+

하수재이용실적 현황

+ + +
+

+ {"하수처리수재이용 실적(m3) 등록결과"} +

+
+ + + +
+
+
diff --git a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx index 581b56fa0..e47301b48 100644 --- a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx +++ b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx @@ -1,8 +1,8 @@ -import { fetchType, getFetch } from "@/components/lib/api"; +import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import type { TableUpperProps } from "../../common/type/header"; import { pbnstPrfmncSttnHeadListExport, pbnstYearHeadListExport } from "./headList"; import type { FcPrfType, PrfType } from "../../prfmncReg/pbnstPrfmncReg/type"; -import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; +import type { pubHasuType, selectLabel } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; import type { ReturnType } from "@common/business_components"; type pbnstPrfmncSttnActions = { @@ -20,7 +20,8 @@ export type pbnstPrfmncSttnState = { pbnstPrfmncRes: PrfType[]; prfmncRes: any[]; isInit: boolean; - rawData:any[]; + rawData: any[]; + selectYearList: selectLabel[] } } @@ -32,7 +33,8 @@ export const pbnstPrfmncSttnExport: pbnstPrfmncSttnState = { pbnstPrfmncRes: pbnstPrfmncRes, prfmncRes: prfmncRes, isInit: false, - rawData:[] + rawData: [], + selectYearList: [] } } @@ -69,20 +71,29 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions return { tableHeadMaker: (startYear: number, endYear: number) => { let yearHeader: TableUpperProps[] = [...pbnstPrfmncSttnHeadListExport]; + const selectList = [] as unknown as selectLabel[] for (let i = startYear; i <= endYear; i++) { const yearHead = JSON.parse(JSON.stringify(pbnstYearHeadListExport)); if (yearHead) { - yearHead.forEach((item: { id?: number; }) => {if(item.id)item.id = i + item.id;}) + yearHead.forEach((item: { id?: number; }) => { + if (item.id) { + item.id = i + item.id; + + } + + }) if (yearHead[0]) yearHead[0].title = i + "년도" } yearHeader = [...yearHeader, ...yearHead] + selectList.push({text: i + "년도", val: String(i)} ) } set((state: pbnstPrfmncSttnState) => { return { ...state, pbnstPrfmncSttn: { - pbnstPrfHeadList: [...yearHeader] + pbnstPrfHeadList: [...yearHeader], + selectYearList: selectList }, }; }); @@ -152,27 +163,28 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions const yearVal = { year: year, pbnstRuseFcltPk: acc.pbnstRuseFcltFk } yearVal[year + 'inUsage'] = inUsageSum; yearVal[year + 'outUsage'] = outUsageSum; - yearVal[year + 'total'] = inUsageSum+outUsageSum; + yearVal[year + 'total'] = inUsageSum + outUsageSum; yearsData.push(yearVal); } }) }) - const resData:any[] = [] - pbnstRes.forEach((acc) => { let data = yearsData.find((item) => item.pbnstRuseFcltPk.substring(0, 11) === acc.bscFctCd) - if(data){ - resData.push({...data, ...acc}) + const resData: any[] = [] + pbnstRes.forEach((acc) => { + let data = yearsData.find((item) => item.pbnstRuseFcltPk.substring(0, 11) === acc.bscFctCd) + if (data) { + resData.push({ ...data, ...acc }) } }) - + return set((state: pbnstPrfmncSttnState) => ({ ...state, pbnstPrfmncSttn: { ...state.pbnstPrfmncSttn, - prfmncRes:resData, - rawData:res.data + prfmncRes: resData, + rawData: res.data }, })); } From 57351b671bfd242033a0ae84d29fd15f3ed83ad0 Mon Sep 17 00:00:00 2001 From: jyha00 Date: Wed, 11 Jun 2025 10:09:50 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=EC=9A=B0=EB=A6=AC=EB=8F=99=EB=84=A4?= =?UTF-8?q?=EA=B0=80=EB=AD=84=20=ED=8D=BC=EB=B8=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/matDmd/drgtSttn/page.tsx | 125 ++++++++++++++++++ apps/wr/app/page.tsx | 5 + .../prfmncSttn/pbnstPrfmncSttn/page.tsx | 24 ++-- .../wr/app/store/matDmd/drgtSttn/headList.tsx | 68 ++++++++++ apps/wr/app/store/matDmd/drgtSttn/index.tsx | 27 ++++ apps/wr/app/store/store.tsx | 13 +- 6 files changed, 246 insertions(+), 16 deletions(-) create mode 100644 apps/wr/app/matMng/matDmd/drgtSttn/page.tsx create mode 100644 apps/wr/app/store/matDmd/drgtSttn/headList.tsx create mode 100644 apps/wr/app/store/matDmd/drgtSttn/index.tsx diff --git a/apps/wr/app/matMng/matDmd/drgtSttn/page.tsx b/apps/wr/app/matMng/matDmd/drgtSttn/page.tsx new file mode 100644 index 000000000..c7b93fe9f --- /dev/null +++ b/apps/wr/app/matMng/matDmd/drgtSttn/page.tsx @@ -0,0 +1,125 @@ +"use client"; +import { useWrStore } from "@/app/store"; +import { btnClass } from "@/app/store/common/code"; +import type { customCoSttnBdst } from "@/app/store/matDmd/coSttn"; +import { drgtHeadListExport } from "@/app/store/matDmd/drgtSttn/headList"; +import { getCity } from "@/components/lib/func/commom"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import { ContentsDiv, SearchDiv, SearchFormLeft, SearchFormRight, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button, DatePicker, Label } from "@common/components/ui"; +import { useState } from "react"; + +export default function drgtSttn() { + const { code, } = useWrStore((state) => state); + const [fromDate, setFromDate] = useState(new Date()); + const [toDate, setToDate] = useState(new Date()); + const [selectSgg, setSelectSgg] = useState(); + const [objSearch, setObjSearch] = useState({ sgg: "", city: "" }); + + const getSelCity = (val: string | number) => { + const cityValue = String(val); // Ensure val is treated as a string + const data = getCity(cityValue, code.sggCd); + setSelectSgg(data); + setObjSearch({ city: cityValue, sgg: '' }); + }; + + const getSgg = (val: string | number) => { + console.log(val); + setObjSearch({ ...objSearch, sgg: String(val) }) + }; + return ( + <> + +
+
+ + <SearchDiv> + <SearchFormLeft> + <div className="col-span-10 flex flex-row"> + <SelectBox + className="col-span-2 w-1/6 h-full text-2xl" + label="시도" + selectClass={""} + selectArray={code.cityCd || []} + onSelectValue={getSelCity} + /> + <SelectBox + className="col-span-2 w-1/6 h-full text-2xl" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <div className="col-span-5 w-auto"> + <div className="flex flex-row items-center"> + <Label className="text-xl text-gray-600">조회기간</Label> + <div className="flex flex-row w-1/4"> + <DatePicker mode={'single'} + selected={fromDate} + onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }} /> + <span>~</span> + <DatePicker mode={'single'} + selected={toDate} + onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} /> + </div> + </div> + </div> + </div> + </SearchFormLeft> + <SearchFormRight + className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> + <div className="flex flex-row space-x-2"> + <Button + size={"sm"} + onClick={(e) => { }} + > + 조회 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { }} + > + 상세보기 + </Button> + <Button + size={"sm"} + className={`${btnClass} green`} + onClick={() => { + /* 저장 로직 */ + }} + > + 다운로드 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { }} + > + 지도보기 + </Button> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={[]} + tableData={[]} + headlist={drgtHeadListExport} + pageSize={20} + total={10000} + cellClick={(index: number | undefined, headId: string) => { }} + onPageChange={() => { }} + ></UiTable> + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/app/page.tsx b/apps/wr/app/page.tsx index d40e79eaf..dde060704 100644 --- a/apps/wr/app/page.tsx +++ b/apps/wr/app/page.tsx @@ -124,6 +124,11 @@ export default function Home() { <Link href="matMng/matDmd/ldrmntCoSttn">잠재수요처 관리</Link> </Button> </div> + <div className="col-span-2"> + <Button className="w-full"> + <Link href="matMng/matDmd/drgtSttn">우리동네가뭄</Link> + </Button> + </div> </div> </div> diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx index f2040f023..cfeddb170 100644 --- a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -60,7 +60,7 @@ export default function PbnstPrfmncSttn() { type dnChartForm = { label: string, val: number, fill?: string }; - type barChartForm = { label: string, inUsage: number, outUsage: number }; + type barChartForm = { label: string, "장내용수": number, "장외용수": number }; type lineChartDataProps = { label: string, val: number, color: string }; const prfTableData = (prfList: PrfType[], year:string) => { @@ -266,12 +266,12 @@ export default function PbnstPrfmncSttn() { }); }) const data: dnChartForm[] = [] - data?.push({ label: "조경용수", val: lndwtr, fill: "white" }) - data?.push({ label: "친수용수", val: hydUswtr, fill: "red" }) - data?.push({ label: "지하수충전", val: ugwtChr, fill: "white" }) - data?.push({ label: "농업용수", val: farmUswtr, fill: "orange" }) - data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "white" }) - data?.push({ label: "공업용수", val: indstUswtr, fill: "yellow" }) + data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) + data?.push({ label: "친수용수", val: hydUswtr, fill: "black" }) + data?.push({ label: "지하수충전", val: ugwtChr, fill: "yellow" }) + data?.push({ label: "농업용수", val: farmUswtr, fill: "black" }) + data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "yellow" }) + data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) setDnOutUsage(data); } }, [rawData, year]) @@ -339,7 +339,7 @@ export default function PbnstPrfmncSttn() { outUsageArr.push(outUsageSum) const month = Number(element.ym.slice(4, 6)) - data.push({ label: `${month}월`, inUsage: inUsageSum, outUsage: outUsageSum }) + data.push({ label: `${month}월`, "장내용수": inUsageSum, "장외용수": outUsageSum }) }, ); @@ -439,7 +439,7 @@ export default function PbnstPrfmncSttn() { }, chartData8: { label: '청소화장실용수', - color: "black", + color: "magenta", }, chartData9: { label: '세척살수용수', @@ -499,15 +499,15 @@ export default function PbnstPrfmncSttn() { }, chartData4: { label: '농업용수', - color: "pink", + color: "green", }, chartData5: { label: '하천등유지용수', - color: "purple", + color: "blue", }, chartData6: { label: '공업용수', - color: "green", + color: "purple", }, } satisfies ChartConfig; setLnOutChartConfig(newChartConfig); diff --git a/apps/wr/app/store/matDmd/drgtSttn/headList.tsx b/apps/wr/app/store/matDmd/drgtSttn/headList.tsx new file mode 100644 index 000000000..8666d70d2 --- /dev/null +++ b/apps/wr/app/store/matDmd/drgtSttn/headList.tsx @@ -0,0 +1,68 @@ +import type { CommonTableProps } from "../../common/type/header"; + +export const drgtHeadListExport: CommonTableProps[] = [ + { + id: "ctpvCd", + title: "시도", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sggCd", + title: "시군구", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "haengjung", + title: "행정동", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "normal", + title: "정상(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "attention", + title: "관심(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "caution", + title: "주의(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "warning", + title: "관심+주의(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "ranking", + title: "가뭄순위", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +]; \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/drgtSttn/index.tsx b/apps/wr/app/store/matDmd/drgtSttn/index.tsx new file mode 100644 index 000000000..edbbc2f28 --- /dev/null +++ b/apps/wr/app/store/matDmd/drgtSttn/index.tsx @@ -0,0 +1,27 @@ +import type { CommonTableProps } from "../../common/type/header"; +import { drgtHeadListExport } from "./headList"; + +const drgtHeadList = drgtHeadListExport; + +export type drgtState = { + drgt:{ + drgtHeadList: CommonTableProps[]; + } +} + +type drgtActions = { +}; + +export type drgtType = drgtState & drgtActions; + +export const drgtStateExport: drgtState = { + drgt: { + drgtHeadList: drgtHeadList, + } +} + +export const drgtActionsExport: (set: any) => drgtActions = ( + set: any +) => { + return {}; +}; \ No newline at end of file diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index dda146e98..fe16e72f8 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -92,6 +92,7 @@ import { pbnstPrfmncActionsExport, pbnstPrfmncStateExport, type pbnstPrfmncState import { coRvwActionsExport, coRvwStateExport, type coRvwState, type coRvwType } from "./matDmd/coMatRvw"; import { ruseHstryActionsExport, ruseHstryStateExport, type ruseHstryState, type ruseHstryType } from "./matDmd/ruseRvwHstry"; import { pbnstPrfmncSttnActionsExport, pbnstPrfmncSttnExport, type pbnstPrfmncSttnState, type pbnstPrfmncSttnType } from "./prfmncSttn/pbnstPrfmncSttn"; +import { drgtActionsExport, drgtStateExport, type drgtState, type drgtType } from "./matDmd/drgtSttn"; export type WrStore = comCodeType & pubFacType & @@ -114,7 +115,8 @@ export type WrStore = comCodeType & pbnstPrfmncType& coRvwType& ruseHstryType& - pbnstPrfmncSttnType + pbnstPrfmncSttnType& + drgtType ; export const StoreZus = ( @@ -138,7 +140,8 @@ export const StoreZus = ( pbnstPrfmncState& coRvwState& ruseHstryState& - pbnstPrfmncSttnState + pbnstPrfmncSttnState& + drgtState = { ...comCodeStateExport, ...pubFacStateExport, @@ -160,7 +163,8 @@ export const StoreZus = ( ...pbnstPrfmncStateExport, ...coRvwStateExport, ...ruseHstryStateExport, - ...pbnstPrfmncSttnExport + ...pbnstPrfmncSttnExport, + ...drgtStateExport } ) => { return createStore<WrStore>()((set) => { @@ -193,7 +197,8 @@ export const StoreZus = ( ...pbnstPrfmncActionsExport(set), ...coRvwActionsExport(set), ...ruseHstryActionsExport(set), - ...pbnstPrfmncSttnActionsExport(set) + ...pbnstPrfmncSttnActionsExport(set), + ...drgtActionsExport(set) }; }); }; From bcbcca9900778079ab5f2822f91abba817e2de2f Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Wed, 11 Jun 2025 13:46:45 +0900 Subject: [PATCH 4/5] =?UTF-8?q?=EB=A7=A4=EC=B9=AD=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD,=20?= =?UTF-8?q?=EC=88=98=EC=9A=94=EC=B2=98=20=EB=A7=A4=EC=B9=AD=20=EA=B2=80?= =?UTF-8?q?=ED=86=A0=20=EB=B0=8F=20=EC=9E=AC=EC=9D=B4=EC=9A=A9=20=EA=B2=80?= =?UTF-8?q?=ED=86=A0=EC=9D=B4=EB=A0=A5=20=ED=8C=9D=EC=97=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{matDmd => coMat}/coMatRvw/page.tsx | 56 +++++-- .../{matDmd => coMat}/ruseCaseMng/page.tsx | 0 .../{matDmd => coMat}/ruseRvwHstry/page.tsx | 103 ++++++++++--- .../matMng/{matDmd => coMng}/coReg/page.tsx | 0 .../matMng/{matDmd => coMng}/coSttn/page.tsx | 0 .../matMng/{matDmd => coMng}/dmdReg/page.tsx | 0 .../{matDmd => coMng}/drgtSttn/page.tsx | 0 .../{matDmd => coMng}/ldrmntCoSttn/page.tsx | 0 apps/wr/app/page.tsx | 14 +- .../wr/app/store/matDmd/coMatRvw/headList.tsx | 145 +++++++++++++++++- .../components/ui/modal/coMat/cmpttnModal.tsx | 36 +++++ .../components/ui/modal/coMat/coMatModal.tsx | 32 ++++ 12 files changed, 348 insertions(+), 38 deletions(-) rename apps/wr/app/matMng/{matDmd => coMat}/coMatRvw/page.tsx (95%) rename apps/wr/app/matMng/{matDmd => coMat}/ruseCaseMng/page.tsx (100%) rename apps/wr/app/matMng/{matDmd => coMat}/ruseRvwHstry/page.tsx (80%) rename apps/wr/app/matMng/{matDmd => coMng}/coReg/page.tsx (100%) rename apps/wr/app/matMng/{matDmd => coMng}/coSttn/page.tsx (100%) rename apps/wr/app/matMng/{matDmd => coMng}/dmdReg/page.tsx (100%) rename apps/wr/app/matMng/{matDmd => coMng}/drgtSttn/page.tsx (100%) rename apps/wr/app/matMng/{matDmd => coMng}/ldrmntCoSttn/page.tsx (100%) create mode 100644 apps/wr/components/ui/modal/coMat/cmpttnModal.tsx create mode 100644 apps/wr/components/ui/modal/coMat/coMatModal.tsx diff --git a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx similarity index 95% rename from apps/wr/app/matMng/matDmd/coMatRvw/page.tsx rename to apps/wr/app/matMng/coMat/coMatRvw/page.tsx index 01f3cef8a..248a45484 100644 --- a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx @@ -3,10 +3,13 @@ import { useWrStore } from "@/app/store"; import { formH1Class, formTableName } from "@/components/lib/class/comClass"; import { getCity } from "@/components/lib/func/commom"; +import { CmpttnModal } from "@/components/ui/modal/coMat/cmpttnModal"; +import { CoMatModal } from "@/components/ui/modal/coMat/coMatModal"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, DatePicker, Input, Label } from "@common/components/ui"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@common/components/ui/tooltip"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useFieldArray, useForm } from "react-hook-form"; @@ -23,6 +26,12 @@ export default function CoMatRvw() { const [isPrcsMo, setIsPrcsMo] = useState<{ isModal: boolean; }>({ isModal: false }); + const [isTrfMo, setIsTrfMo] = useState<{ + isModal: boolean; + }>({ isModal: false, }); + const [isCmpttnMo, setIsCmpttnMo] = useState<{ + isModal: boolean; + }>({ isModal: false, }); const schema = z.object({ @@ -48,15 +57,6 @@ export default function CoMatRvw() { setObjSearch({ ...objSearch, sgg: String(val) }) }; - const { - fields: [], - append, - remove, - } = useFieldArray({ - control: form.control, - name: "", - }); - useEffect(() => { if (fromDate > toDate) { const newFromDate = new Date(toDate); @@ -613,7 +613,7 @@ export default function CoMatRvw() { <Label>처리시설용량에 따른 공사비(백만원)</Label> <Button size={"sm"} - onClick={(e) => { }} + onClick={(e) => setIsCmpttnMo({ isModal: true })} className="bg-none" > 공사비 산정표 보기 @@ -642,7 +642,7 @@ export default function CoMatRvw() { <Label>시설부대경비 요율(%)</Label> <Button size={"sm"} - onClick={(e) => { }} + onClick={(e) => setIsTrfMo({ isModal: true })} > 요율표 보기 </Button> @@ -667,7 +667,19 @@ export default function CoMatRvw() { </div> <div className="col-span-3 mt-4"> - <Label>총사업비 (백만원)<i className="diveicon di-search" /></Label> + <Label>총사업비 (백만원) + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <i className="diveicon di-search" /> + </TooltipTrigger> + <TooltipContent> + <div className="font-bold mb-1 text-xl">총사업비 계산방법</div> + <div className="text-lg">하수처리수 재이용시설 총 사업비 = 공사비+시설부대경비 </div> + </TooltipContent> + </Tooltip> + </TooltipProvider> + </Label> <FormField control={form.control} name="" @@ -808,6 +820,26 @@ export default function CoMatRvw() { setIsPrcsMo({ isModal: open }); }} /> + <UiModal + body={ + <CoMatModal data={[]}></CoMatModal> + } + bodyClass="w-[40vw] max-w-none h-[70vh]" + open={isTrfMo.isModal} + onOpenChange={(open) => { + setIsTrfMo({ isModal: open }); + }} + /> + <UiModal + body={ + <CmpttnModal data={[]}></CmpttnModal> + } + bodyClass="w-[70vw] max-w-none h-[50vh]" + open={isCmpttnMo.isModal} + onOpenChange={(open) => { + setIsCmpttnMo({ isModal: open }); + }} + /> </div> </ContentsDiv > </> diff --git a/apps/wr/app/matMng/matDmd/ruseCaseMng/page.tsx b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx similarity index 100% rename from apps/wr/app/matMng/matDmd/ruseCaseMng/page.tsx rename to apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx diff --git a/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx similarity index 80% rename from apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx rename to apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx index d6a2b47ac..70d57d0b9 100644 --- a/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx @@ -3,10 +3,13 @@ import { useWrStore } from "@/app/store"; import { formTableName } from "@/components/lib/class/comClass"; import { getCity } from "@/components/lib/func/commom"; +import { CmpttnModal } from "@/components/ui/modal/coMat/cmpttnModal"; +import { CoMatModal } from "@/components/ui/modal/coMat/coMatModal"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; +import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, DatePicker, Input, Label } from "@common/components/ui"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@common/components/ui/tooltip"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useFieldArray, useForm } from "react-hook-form"; @@ -40,18 +43,17 @@ export default function RuseRvwHstry() { fcltCpct: 0, } }); + const [isPrcsMo, setIsPrcsMo] = useState<{ + isModal: boolean; + }>({ isModal: false }); + const [isTrfMo, setIsTrfMo] = useState<{ + isModal: boolean; + }>({ isModal: false, }); + const [isCmpttnMo, setIsCmpttnMo] = useState<{ + isModal: boolean; + }>({ isModal: false, }); - const { - fields: [], - append, - remove, - } = useFieldArray({ - control: form.control, - name: "", - }); - -return ( - <> + return ( <ContentsDiv> <div className="grid grid-cols-4 gap-4"> <div className="col-span-4"> @@ -204,7 +206,7 @@ return ( /> </div> <div className="col-span-3 mt-4"> - <Label className="">용도에 따른 처리공정<i className="diveicon di-search" /></Label> + <Label className="">용도에 따른 처리공정<i className="diveicon di-search" onClick={(e) => setIsPrcsMo({ isModal: true })} /></Label> <FormField control={form.control} @@ -248,7 +250,7 @@ return ( <Label>처리시설용량에 따른 공사비(백만원)</Label> <Button size={"sm"} - onClick={(e) => { }} + onClick={(e) => setIsCmpttnMo({ isModal: true })} className="bg-none" > 공사비 산정표 보기 @@ -277,7 +279,7 @@ return ( <Label>시설부대경비 요율(%)</Label> <Button size={"sm"} - onClick={(e) => { }} + onClick={(e) => setIsTrfMo({ isModal: true })} > 요율표 보기 </Button> @@ -302,7 +304,19 @@ return ( </div> <div className="col-span-3 mt-4"> - <Label>총사업비 (백만원)<i className="diveicon di-search" /></Label> + <Label>총사업비 (백만원) + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <i className="diveicon di-search" /> + </TooltipTrigger> + <TooltipContent> + <div className="font-bold mb-1 text-xl">총사업비 계산방법</div> + <div className="text-lg">하수처리수 재이용시설 총 사업비 = 공사비+시설부대경비 </div> + </TooltipContent> + </Tooltip> + </TooltipProvider> + </Label> <FormField control={form.control} name="" @@ -360,8 +374,61 @@ return ( </Form> </ListDiv> </div> + <UiModal + body={ + <> + <UiTable + headName={"용도에 따른 처리공정"} + tableData={[ + { usage: "청소", process: "총인처리시설 + 염소소독" }, + { usage: "화장실용수", process: "총인처리시설 + 염소소독" }, + { usage: "세척", process: "총인처리시설 + UV소독" }, + { usage: "살수", process: "총인처리시설 + UV소독" }, + { usage: "조경", process: "총인처리시설 + UV소독" }, + { usage: "농업", process: "총인처리시설 + UV소독" }, + { usage: "하천", process: "총인처리시설 + UV소독" }, + { usage: "지하수", process: "전처리시설 + RO" }, + { usage: "공업용수", process: "전처리시설 + RO" }, + + ]} + headlist={[ + { id: "usage", title: "용도" }, + { id: "process", title: "단위공정" } + ]} + pageSize={0} + total={0} + cellClick={() => { }} + onPageChange={() => { }} + /> + </> + } + bodyClass="w-[25vw] max-w-none h-[60vh]" + open={isPrcsMo.isModal} + onOpenChange={(open) => { + setIsPrcsMo({ isModal: open }); + }} + /> + <UiModal + body={ + <CoMatModal data={[]}></CoMatModal> + } + bodyClass="w-[40vw] max-w-none h-[70vh]" + open={isTrfMo.isModal} + onOpenChange={(open) => { + setIsTrfMo({ isModal: open }); + }} + /> + <UiModal + body={ + <CmpttnModal data={[]}></CmpttnModal> + } + bodyClass="w-[70vw] max-w-none h-[50vh]" + open={isCmpttnMo.isModal} + onOpenChange={(open) => { + setIsCmpttnMo({ isModal: open }); + }} + /> </div> </ContentsDiv > - </> -) + ) } \ No newline at end of file diff --git a/apps/wr/app/matMng/matDmd/coReg/page.tsx b/apps/wr/app/matMng/coMng/coReg/page.tsx similarity index 100% rename from apps/wr/app/matMng/matDmd/coReg/page.tsx rename to apps/wr/app/matMng/coMng/coReg/page.tsx diff --git a/apps/wr/app/matMng/matDmd/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx similarity index 100% rename from apps/wr/app/matMng/matDmd/coSttn/page.tsx rename to apps/wr/app/matMng/coMng/coSttn/page.tsx diff --git a/apps/wr/app/matMng/matDmd/dmdReg/page.tsx b/apps/wr/app/matMng/coMng/dmdReg/page.tsx similarity index 100% rename from apps/wr/app/matMng/matDmd/dmdReg/page.tsx rename to apps/wr/app/matMng/coMng/dmdReg/page.tsx diff --git a/apps/wr/app/matMng/matDmd/drgtSttn/page.tsx b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx similarity index 100% rename from apps/wr/app/matMng/matDmd/drgtSttn/page.tsx rename to apps/wr/app/matMng/coMng/drgtSttn/page.tsx diff --git a/apps/wr/app/matMng/matDmd/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx similarity index 100% rename from apps/wr/app/matMng/matDmd/ldrmntCoSttn/page.tsx rename to apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx diff --git a/apps/wr/app/page.tsx b/apps/wr/app/page.tsx index dde060704..af9ef6950 100644 --- a/apps/wr/app/page.tsx +++ b/apps/wr/app/page.tsx @@ -111,22 +111,22 @@ export default function Home() { <div className="grid grid-cols-12 gap-4"> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/coReg">수요처 등록</Link> + <Link href="matMng/coMng/coReg">수요처 등록</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/coSttn">수요처 관리</Link> + <Link href="matMng/coMng/coSttn">수요처 관리</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/ldrmntCoSttn">잠재수요처 관리</Link> + <Link href="matMng/coMng/ldrmntCoSttn">잠재수요처 관리</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/drgtSttn">우리동네가뭄</Link> + <Link href="matMng/coMng/drgtSttn">우리동네가뭄</Link> </Button> </div> </div> @@ -138,17 +138,17 @@ export default function Home() { <div className="grid grid-cols-12 gap-4"> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/coMatRvw">수요처 매칭 검토</Link> + <Link href="matMng/coMat/coMatRvw">수요처 매칭 검토</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/ruseRvwHstry">재이용검토이력</Link> + <Link href="matMng/coMat/ruseRvwHstry">재이용검토이력</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/ruseCaseMng">물재이용사례 관리</Link> + <Link href="matMng/coMat/ruseCaseMng">물재이용사례 관리</Link> </Button> </div> </div> diff --git a/apps/wr/app/store/matDmd/coMatRvw/headList.tsx b/apps/wr/app/store/matDmd/coMatRvw/headList.tsx index d77dff8c9..8caf7e1b2 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/headList.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/headList.tsx @@ -106,4 +106,147 @@ export const coRvwNodeListExport: CommonTableProps[] = [ colSpan: 1, }, -]; \ No newline at end of file +]; + +export const cmpttnHeadListExport: CommonTableProps[] = [ + { + id: "ctpv", + title: "구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sgg", + title: "처리시설 용량(m³)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "500", + title: "500", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "1000", + title: "1,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + },{ + id: "2000", + title: "2,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "3000", //바꾸기 + title: "3,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "5000", //바꾸기 + title: "5,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "10000", //바꾸기 + title: "10,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "20000", //바꾸기 + title: "20,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "30000", //바꾸기 + title: "30,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "50000", //바꾸기 + title: "50,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "100000", //바꾸기 + title: "100,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + +]; + + +export const coModalHeadListExport: CommonTableProps[] = [ + { + id: "gubun", + title: "공사비/구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "a", + title: "기본조사설계비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aa", + title: "실시설계비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaa", + title: "공사감리비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaa", + title: "시설부대비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +] \ No newline at end of file diff --git a/apps/wr/components/ui/modal/coMat/cmpttnModal.tsx b/apps/wr/components/ui/modal/coMat/cmpttnModal.tsx new file mode 100644 index 000000000..ab18e3542 --- /dev/null +++ b/apps/wr/components/ui/modal/coMat/cmpttnModal.tsx @@ -0,0 +1,36 @@ +"use client" + +import { cmpttnHeadListExport } from "@/app/store/matDmd/coMatRvw/headList"; +import { yearOptions } from "@/components/lib/func/commom" +import { SelectBox, UiTable } from "@common/business_components/ui" +import { Label } from "@common/components/ui" +import { useState } from "react"; + +export function CmpttnModal({ data }: { data: [] }) { + const [year, setYear] = useState<string>(String(new Date().getFullYear())); + return ( + <> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label">공사비 산정표 보기</h3> + <hr/> + <div className="flex items-center"> + <Label className="text-xl text-gray-600">기준년도</Label> + <SelectBox + className="h-full text-2xl" + label="" + selectClass={"ml-4"} + selectArray={yearOptions} + value={year} + onSelectValue={(val: string | number) => setYear(String(val))} /> + </div> + <UiTable + headName={""} + tableData={[]} + headlist={cmpttnHeadListExport} + pageSize={0} + total={0} + cellClick={() => { }} + onPageChange={() => { }} + /> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/coMat/coMatModal.tsx b/apps/wr/components/ui/modal/coMat/coMatModal.tsx new file mode 100644 index 000000000..4717a89a3 --- /dev/null +++ b/apps/wr/components/ui/modal/coMat/coMatModal.tsx @@ -0,0 +1,32 @@ +"use client" + +import { coModalHeadListExport } from "@/app/store/matDmd/coMatRvw/headList"; +import { yearOptions } from "@/components/lib/func/commom" +import { SelectBox, UiTable } from "@common/business_components/ui" +import { Label } from "@common/components/ui" +import { useState } from "react"; + +export function CoMatModal({ data }: { data: [] }) { + const [year, setYear] = useState<string>(String(new Date().getFullYear())); + return ( + <> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label">요율표 보기</h3> + <hr/> + <div className="flex items-center"> + <Label className="text-xl text-gray-600">기준년도</Label> + <SelectBox + className="h-full text-2xl" + label="" + selectClass={"ml-4"} + selectArray={yearOptions} + value={year} + onSelectValue={(val: string | number) => setYear(String(val))} /> + </div> + <UiTable + headName={""} + tableData={[]} + headlist={coModalHeadListExport} + onPageChange={() => { }} pageSize={0} total={0} cellClick={undefined} /> + </> + ) +} \ No newline at end of file From b85cd78614e9be72cdeaa1a888cbb1cf0ca3bdcb Mon Sep 17 00:00:00 2001 From: jyha00 <jyha@mind-one.co.kr> Date: Thu, 12 Jun 2025 13:28:28 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=EC=9E=A0=EC=9E=AC=EC=88=98=EC=9A=94?= =?UTF-8?q?=EC=B2=98=20=ED=8D=BC=EB=B8=94=20=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=ED=98=84=ED=99=A9=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EC=97=91=EC=85=80=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMng/coReg/page.tsx | 84 -- apps/wr/app/matMng/coMng/drgtSttn/page.tsx | 19 +- .../wr/app/matMng/coMng/ldrmntCoSttn/page.tsx | 89 +- .../wr/app/store/matDmd/drgtSttn/headList.tsx | 36 +- .../store/matDmd/ldrmntCoSttn/headList.tsx | 359 ++++++++ .../app/store/matDmd/ldrmntCoSttn/index.tsx | 220 ++++- apps/wr/app/store/store.tsx | 10 +- .../ui/modal/coMat/drgtDetailModal.tsx | 48 + .../fcltReg/bdstRegModal/bdstRegModal.tsx | 2 - .../ui/modal/ldrmntSttn/ldrmntExcelModal.tsx | 67 ++ .../sttn/sttnDetailModal/coDatailModal.tsx | 826 +++++++++++++++++- apps/wr/public/sample_drgtSttn.xlsx | Bin 0 -> 9903 bytes 12 files changed, 1560 insertions(+), 200 deletions(-) delete mode 100644 apps/wr/app/matMng/coMng/coReg/page.tsx create mode 100644 apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx create mode 100644 apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx create mode 100644 apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx create mode 100644 apps/wr/public/sample_drgtSttn.xlsx diff --git a/apps/wr/app/matMng/coMng/coReg/page.tsx b/apps/wr/app/matMng/coMng/coReg/page.tsx deleted file mode 100644 index b0f911449..000000000 --- a/apps/wr/app/matMng/coMng/coReg/page.tsx +++ /dev/null @@ -1,84 +0,0 @@ -"use client"; -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import * as z from "zod"; -import { - Form, - FormField, - FormUi, - ScrollArea, - SelectBox, -} from "@common/business_components/ui"; -import { Button } from "@common/components/ui"; -import { CoRegForm } from "@/components/ui/form/matDmd/coRegForm/component"; -import toast, { Toaster } from "react-hot-toast"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; - -const formSchema = z.object({ - ctpv: z.string(), - sgg: z.string(), - coNm: z.string().min(1).max(20), - bznmNo: z.string().min(1).min(9).max(12), - addr: z.string().min(1).min(6).max(20), - telNo: z.string().min(8).max(12), - -}); - -export default function MyForm() { - - - - const form = useForm<z.infer<typeof formSchema>>({ - resolver: zodResolver(formSchema), - defaultValues: { - coNm:'', - bznmNo:'', - addr:'', - telNo:'', - }, - }); - - function onSubmit(values: z.infer<typeof formSchema>) { - try { - toast.dismiss(); - //ToastFormUi("수요신청 화면으로 이동하시겠습니까?", "수요처 등록 완료", "./dmdReg", "이동") - - } catch (error) { - console.error("Form submission error", error); - toast.error("수요처 등록이 실패하였습니다."); - } - } - - return ( - <> - <div className="grid h-40 grid-cols-3 place-content-center"> - <h1 className=" col-start-2 col-span-1 text-4xl underline"> - 수요처 정보입력 - </h1> - </div> - - <div className="grid grid-cols-5 gap-4 overflow-hidden"> - <div className="col-span-1 "/> - <div className="col-span-3 "> - <div> - <Form {...form}> - <form - onSubmit={form.handleSubmit(onSubmit)} - className="space-y-8 max-w-3xl mx-auto" - > - <CoRegForm>{form}</CoRegForm> - - - <Button type="submit">수요처등록</Button> - </form> - </Form> - </div> - </div> - <div className="col-span-1 " > - <Toaster position="top-center" /> - </div> - </div> - </> - ); -} - diff --git a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx index c7b93fe9f..77bbe4a5a 100644 --- a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx @@ -3,14 +3,14 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { customCoSttnBdst } from "@/app/store/matDmd/coSttn"; import { drgtHeadListExport } from "@/app/store/matDmd/drgtSttn/headList"; -import { getCity } from "@/components/lib/func/commom"; +import { excelDownload, getCity } from "@/components/lib/func/commom"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { ContentsDiv, SearchDiv, SearchFormLeft, SearchFormRight, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { Button, DatePicker, Label } from "@common/components/ui"; -import { useState } from "react"; +import { useCallback, useState } from "react"; -export default function drgtSttn() { +export default function DrgtSttn() { const { code, } = useWrStore((state) => state); const [fromDate, setFromDate] = useState<Date>(new Date()); const [toDate, setToDate] = useState<Date>(new Date()); @@ -28,6 +28,15 @@ export default function drgtSttn() { console.log(val); setObjSearch({ ...objSearch, sgg: String(val) }) }; + + const excelClick = useCallback(() => { + excelDownload( + [[]], + "우리동네가뭄", + "sample_drgtSttn.xlsx", + "A1:H1" + ); + }, []); return ( <> <ContentsDiv> @@ -86,9 +95,7 @@ export default function drgtSttn() { <Button size={"sm"} className={`${btnClass} green`} - onClick={() => { - /* 저장 로직 */ - }} + onClick={excelClick} > 다운로드 </Button> diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx index 2a730f8d5..d4039eb9d 100644 --- a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -2,18 +2,18 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; -import type { customCoBdst } from "@/app/store/matDmd/coReg"; +import type { customLdrmntBdst } from "@/app/store/matDmd/ldrmntCoSttn"; +import { ldrmntNodeListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList"; import { excelDownload, - getCity, - tableData, + getCity } from "@/components/lib/func/commom"; import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcel"; import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import LdrmntExcelModal from "@/components/ui/modal/ldrmntSttn/ldrmntExcelModal"; import CoDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/coDatailModal"; import { ContentsDiv, - SearchBaseForm, SearchDiv, SearchFormLeft, SearchFormRight, @@ -23,40 +23,45 @@ import { UiModal, UiTable, type ReturnType, - type SelectDataType, + type SelectDataType } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, DatePicker, Label } from "@common/components/ui"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { Button } from "@common/components/ui"; +import { useCallback, useRef, useState } from "react"; export default function LdrmntCoSttn() { - const { code, ldrmntCoSttn } = useWrStore( + const { code, ldrmnt } = useWrStore( (state) => state ); - const { ldrmntCoSttnRes } = ldrmntCoSttn; - const [bdstTable, setBdstTable] = useState<customCoBdst[]>(); - const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customCoBdst | undefined }>({ data: undefined, isOpen: false }) + const { ldrmntCoList } = ldrmnt; + const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customLdrmntBdst | undefined }>({ data: undefined, isOpen: false }) const [pageNation, setPageNation] = useState(1); const [isRegExcel, setIsRegExcel] = useState(false); const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); - + const [bdstTable, setBdstTable] = useState<customLdrmntBdst[]>(); const ref = useRef<ReturnType>({} as ReturnType); const excelClick = useCallback(() => { excelDownload( [[]], "잠재수요처 관리", - "sample_ldrmntCoSttn.xlsx", + "sample_ldrmnt.xlsx", "A1:AL1", 2 ); }, []); + const [isExcelOpen, setIsExcelOPen] = useState<{ + isModal: boolean; + }>({ isModal: false}); + const cellClick = (index: number | undefined, headId: string) => { - if (index !== undefined && bdstTable !== undefined) { - setDetailModal({ isOpen: true, data: bdstTable[index] }) + if (index !== undefined) { + setDetailModal({ isOpen: true, data: ldrmntCoList[index] }); } + console.log("detailModal", detailModal); + } const getSelCity = (val: string | number) => { @@ -71,21 +76,6 @@ export default function LdrmntCoSttn() { setObjSearch({ ...objSearch, sgg: String(val) }) }; - useEffect(() => { - if (ldrmntCoSttnRes.length > 0 && code.cityCd.length > 0) { - const data = tableData(ldrmntCoSttnRes, { code }); - console.log("data", data); - const chData = data - .map((item: any) => ({ - ...item - - })) - .filter((item: any) => item !== undefined); - - setBdstTable(chData); - } - }, [code, ldrmntCoSttnRes, ldrmntCoSttn.ldrmntCoSttHeadList]); - return ( <> <ContentsDiv> @@ -130,7 +120,9 @@ export default function LdrmntCoSttn() { <Button size={"sm"} className={btnClass} - onClick={() => { }} + onClick={() => { + setIsExcelOPen({ ...isExcelOpen, isModal: true }); + }} > 엑셀등록 </Button> @@ -157,17 +149,19 @@ export default function LdrmntCoSttn() { </div> <div className="grid grid-cols-6 gap-4 "> <div className="col-span-6"> - <ListDiv> - <UiTable - headName={[]} - tableData={bdstTable || []} - headlist={ldrmntCoSttn.ldrmntCoSttHeadList} - pageSize={20} - total={10000} - cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} - onPageChange={setPageNation} - ></UiTable> - </ListDiv> + <div className="overflow-x-auto"> + <ListDiv className="min-w-max"> + <UiTable + headName={[]} + tableData={ldrmntCoList || []} + headlist={ldrmntNodeListExport} + pageSize={20} + total={10000} + cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} + onPageChange={setPageNation} + /> + </ListDiv> + </div> </div> <UiModal open={detailModal.isOpen} @@ -175,7 +169,8 @@ export default function LdrmntCoSttn() { setDetailModal({ ...detailModal, isOpen: !detailModal.isOpen }) }} bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"} - body={<CoDetailModal formObj={detailModal.data} />} /> + body={<CoDetailModal formObj={detailModal.data} />} + /> <UiModal bodyClass={"w-[40vw] max-w-none"} @@ -183,6 +178,14 @@ export default function LdrmntCoSttn() { body={<CoRegExcel></CoRegExcel>} onOpenChange={setIsRegExcel} /> + <UiModal + bodyClass={""} + body={<LdrmntExcelModal data={isExcelOpen.data}></LdrmntExcelModal>} + open={isExcelOpen.isModal} + onOpenChange={() => { + setIsExcelOPen({ isModal: false, }); + }} + ></UiModal> </div> </ContentsDiv> diff --git a/apps/wr/app/store/matDmd/drgtSttn/headList.tsx b/apps/wr/app/store/matDmd/drgtSttn/headList.tsx index 8666d70d2..40eae47e3 100644 --- a/apps/wr/app/store/matDmd/drgtSttn/headList.tsx +++ b/apps/wr/app/store/matDmd/drgtSttn/headList.tsx @@ -65,4 +65,38 @@ export const drgtHeadListExport: CommonTableProps[] = [ rowSpan: 1, colSpan: 1, }, -]; \ No newline at end of file +]; + +export const drgtDetailHeadListExport: CommonTableProps[] = [ + { + id: "year", + title: "년", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "month", + title: "월", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + },{ + id: "day", + title: "일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "state", + title: "가뭄상태", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +] \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx new file mode 100644 index 000000000..d8641d40a --- /dev/null +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx @@ -0,0 +1,359 @@ +import type { CommonTableProps } from "../../common/type/header"; + +export const ldrmntHeadListExport: CommonTableProps[] = [ + { + id: "ctpvCd", + title: "시도", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sggCd", + title: "시군구", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa1", + title: "회사명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa33", + title: "공장주소", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa35", + title: "공장관리번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa11", + title: "전화번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +] + +export const ldrmntNodeListExport: CommonTableProps[] = [ + { + id: "ctpvCd", + title: "시도", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sggCd", + title: "시군구", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa", + title: "관리기관", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa1", + title: "회사명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa2", + title: "공장구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa3", + title: "단지명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa4", + title: "설립구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa5", + title: "입주형태", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa6", + title: "보유구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa7", + title: "최초승인일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa8", + title: "최초등록일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa9", + title: "등록구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa10", + title: "등록일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa11", + title: "전화번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa12", + title: "남자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa13", + title: "여자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa14", + title: "외국인남자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa15", + title: "외국인여자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa16", + title: "종업원합계", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa17", + title: "생산품", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa18", + title: "원자재", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa19", + title: "공장규모", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa20", + title: "용도지역", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa21", + title: "지목", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa22", + title: "용지면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa23", + title: "제조시설면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa24", + title: "부대시설면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa25", + title: "건축면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa26", + title: "지식산업센터명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa27", + title: "대표업종", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa28", + title: "업종명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa29", + title: "업종코드", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa30", + title: "차수", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa31", + title: "법인주소", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa32", + title: "필지수", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa33", + title: "공장주소", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa34", + title: "공장주소_지번", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa35", + title: "공장관리번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +]; \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx index 2c071aac3..4aec34e2f 100644 --- a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx @@ -1,67 +1,201 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; -import { coSttHeadListExport, coSttNodeListExport } from "../coSttn/headList"; -import type { customCoSttnBdst } from "../coSttn"; +import { z } from "zod"; +import { ldrmntHeadListExport, ldrmntNodeListExport } from "./headList"; +import { deleteFectch, fetchType, getFetch, postFectch } from "@/components/lib/api"; + +export const ldrmntZod = z.object({ + ctpvCd: z.number().default(0), + sggCd: z.number().default(0), + aaaaaa: z.string().default(''), + aaaaaa1: z.string().default(''), + aaaaaa2: z.string().default(''), + aaaaaa3: z.string().default(''), + aaaaaa4: z.string().default(''), + aaaaaa5: z.string().default(''), + aaaaaa6: z.string().default(''), + aaaaaa7: z.date().default(() => new Date()), + aaaaaa8: z.date().default(() => new Date()), + aaaaaa9: z.string().default(''), + aaaaaa10: z.date().default(() => new Date()), + aaaaaa11: z.string().default(''), + aaaaaa12: z.string().default(''), + aaaaaa13: z.string().default(''), + aaaaaa14: z.string().default(''), + aaaaaa15: z.string().default(''), + aaaaaa16: z.string().default(''), + aaaaaa17: z.string().default(''), + aaaaaa18: z.string().default(''), + aaaaaa19: z.string().default(''), + aaaaaa20: z.string().default(''), + aaaaaa21: z.string().default(''), + aaaaaa22: z.string().default(''), + aaaaaa23: z.string().default(''), + aaaaaa24: z.string().default(''), + aaaaaa25: z.string().default(''), + aaaaaa26: z.string().default(''), + aaaaaa27: z.string().default(''), + aaaaaa28: z.string().default(''), + aaaaaa29: z.string().default(''), + aaaaaa30: z.string().default(''), + aaaaaa31: z.string().default(''), + aaaaaa32: z.string().default(''), + aaaaaa33: z.string().default(''), + aaaaaa34: z.string().default(''), + aaaaaa35: z.string().default(''), +}) // 테이블 헤드 리스트 -const coSttNodeList = coSttNodeListExport; -const coSttHeadList = coSttHeadListExport; - -const ldrmntCoSttnRes: customCoSttnBdst[] = []; +const ldrmntHeadList = ldrmntHeadListExport; +const ldrmntNodeList = ldrmntNodeListExport; const ldrmntCoList = [{ - ctpvCd: "이거머임", - sggCd: "01", - dmdCoNm: "회사요", - bznmNo: "abc123", - dmdInfoPk: "1111", - daddr: "서울 강남구", - telno: "010-1234-5678" + ctpvCd: "서울특별시", + sggCd: "종로구", + aaaaaa: "서울특별시 종로구", + aaaaaa1: "남일문화 (주)", + aaaaaa2: "개별입지", + aaaaaa3: "", + aaaaaa4: "일반", + aaaaaa5: "해당없음", + aaaaaa6: "임대", + aaaaaa7: "19980101", + aaaaaa8: "20050202", + aaaaaa9: "등록변경", + aaaaaa10: "20221207", + aaaaaa11: "02-720-1511", + aaaaaa12: "0", + aaaaaa13: "2", + aaaaaa14: "0", + aaaaaa15: "0", + aaaaaa16: "2", + aaaaaa17: "인쇄물", + aaaaaa18: "문구, 차드", + aaaaaa19: "소기업", + aaaaaa20: "도시지역 / 주거지역 / 제2종일반주거지역", + aaaaaa21: "대", + aaaaaa22: "238", + aaaaaa23: "57.12", + aaaaaa24: "69.44", + aaaaaa25: "126.56", + aaaaaa26: "", + aaaaaa27: "18111", + aaaaaa28: "경 인쇄업 외 2 종", + aaaaaa29: "18111, 18113, 18119", + aaaaaa30: "10", + aaaaaa31: "", + aaaaaa32: "1", + aaaaaa33: "서울특별시 종로구 자하문로16길 8 (창성동)", + aaaaaa34: "서울특별시 종로구 창성동 87-1번지", + aaaaaa35: "111102005091210", }] -export type ldrmntCoSttnState = { - ldrmntCoSttn: { - ldrmntCoSttnRes: customCoSttnBdst[]; - ldrmntCoSttHeadList: CommonTableProps[]; - ldrmntCoSttNodeList: CommonTableProps[]; + +export type customLdrmntBdst = z.infer<typeof ldrmntZod>; + +const ldrmntRes: customLdrmntBdst[] = []; + +export type ldrmntState = { + ldrmnt: { + ldrmntHeadList: CommonTableProps[]; + ldrmntNodeList: CommonTableProps[]; excelList: []; isInit: boolean; + ldrmntCoList: typeof ldrmntCoList; + ldrmntRes: customLdrmntBdst[]; }; }; -type ldrmntCoSttnActions = { +type ldrmntActions = { }; -export type ldrmntCoSttnType = ldrmntCoSttnState & ldrmntCoSttnActions; +export type ldrmntType = ldrmntState & ldrmntActions; -export const ldrmntCoSttnStateExport: ldrmntCoSttnState = { - ldrmntCoSttn: { - ldrmntCoSttHeadList: coSttHeadList, - ldrmntCoSttNodeList: coSttNodeList, - ldrmntCoSttnRes: ldrmntCoList, +export const ldrmntStateExport: ldrmntState = { + ldrmnt: { + ldrmntHeadList: ldrmntHeadList, + ldrmntNodeList: ldrmntNodeList, excelList: [], isInit: false, + ldrmntCoList: ldrmntCoList, + ldrmntRes: ldrmntRes, }, }; -export const ldrmntCoSttnActionsExport: (set: any) => ldrmntCoSttnActions = ( +export const ldrmntActionsExport: (set: any) => ldrmntActions = ( set: any ) => { return { - ldrmntCoSttnInit: async (code: string | number) => { - try{ - - set((state: ldrmntCoSttnState) => { - return { - ...state, - ldrmntCoSttn: { - ...state.ldrmntCoSttn, - ldrmntCoSttnRes: ldrmntCoSttnRes, - isInit: false, - }, - }; - }); - }catch(e){ - console.log(e) - } - }, + ldrmntInit: async (code: string | number) => { + try { + + set((state: ldrmntState) => { + return { + ...state, + ldrmnt: { + ...state.ldrmnt, + isInit: false, + ldrmntCoList: ldrmntCoList, + }, + }; + }); + } catch (e) { + console.log(e) + } + }, + ldrmntInsert: async (ldrmntRes: []) => { + try { + + const response = await postFectch( + `/reuseFc/request`, + [] + // JSON.stringify(writeRgtrAndMdfr([ldrmntRes])) + ); + + return set((state: ldrmntState) => ({ + ...state, + ldrmnt: { + ...state.ldrmnt, + ldrmntRes: response.data, + isInit: false, + }, + })); + } catch (error) { + console.error("Error updating ldrmnt:", error); + } + }, + fileDelete: async (atflCd: string) => { + try { + const response = await deleteFectch( + `/attach-service/api/v1/atfl/attachments/atflCd//${atflCd}`, + undefined, + fetchType.CS + ); + + console.log("File deleted successfully:", response); + return set((state: ldrmntState) => ({ + ...state, + ldrmnt: { + ...state.ldrmnt, + isInit: false, + }, + })); + } catch (error) { + console.error("Error deleting file:", error); + } + }, + fileDownLoad: async (atflCd: string) => { + try { + const response = await getFetch( + fetchType.CS, + `/attach-service/api/v1/atflcd/download/${atflCd}` + ); + + if (!response.ok) { + throw new Error(`Error downloading file: ${response.statusText}`); + } + } catch (error) { + console.error("Error downloading file:", error); + } + }, + } } \ No newline at end of file diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index 6097b8196..4557662f8 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -86,7 +86,6 @@ import { import { rswtChkStateExport, rswtChkSttnActionsExport, type rswtChkSttnState, type rswtChkSttnType } from "./prfmncSttn/chkgdnSttn/rswtChkgdnSttn"; import { pbnstSttnActionsExport, pbnstSttnStateExport, type pbnstSttnState, type pbnstSttnType } from "./ruseFcltMng/fcltSttn/pbnstSttn"; import { coSttnActionsExport, coSttnStateExport, type coSttnState, type coSttnType } from "./matDmd/coSttn"; // 옮겨야함 -import { ldrmntCoSttnActionsExport, ldrmntCoSttnStateExport, type ldrmntCoSttnState, type ldrmntCoSttnType } from "./matDmd/ldrmntCoSttn"; // 옮겨야함 import { searchActions, type comFcltActions, type comFcltState } from "./common/searchCode"; import { pbnstPrfmncActionsExport, pbnstPrfmncStateExport, type pbnstPrfmncState, type pbnstPrfmncType } from "./prfmncReg/pbnstPrfmncReg"; import { coRvwActionsExport, coRvwStateExport, type coRvwState, type coRvwType } from "./matDmd/coMatRvw"; @@ -97,6 +96,7 @@ import { ruseCaseActionsExport, ruseCaseStateExport, type ruseCaseType, type rus import { rainStatActionsExport, rainStatExport, type rainStatState, type rainStatType } from "./stats/rainStat"; import { type rswtStatType, type rswtStatState, rswtStatExport, rswtStatActionsExport } from "./stats/rswtStat"; import { matStatActionsExport, matStatExport, type matStatState, type matStatType } from "./stats/matStat"; +import { ldrmntActionsExport, ldrmntStateExport, type ldrmntState, type ldrmntType } from "./matDmd/ldrmntCoSttn"; export type WrStore = comCodeType & pubFacType & @@ -115,7 +115,7 @@ export type WrStore = comCodeType & pbnstSttnType& comFcltActions&comFcltState& coSttnType& // 옮겨야함 - ldrmntCoSttnType& // 옮겨야함 + ldrmntType& // 옮겨야함 pbnstPrfmncType& coRvwType& ruseHstryType& @@ -144,7 +144,7 @@ export const StoreZus = ( rswtChkSttnState & pbnstSttnState& coSttnState& // 옮겨야함 - ldrmntCoSttnState& // 옮겨야함 + ldrmntState& // 옮겨야함 pbnstPrfmncState& coRvwState& ruseHstryState& @@ -171,7 +171,7 @@ export const StoreZus = ( ...rswtChkStateExport, ...pbnstSttnStateExport, ...coSttnStateExport, // 옮겨야함 - ...ldrmntCoSttnStateExport, // 옮겨야함 + ...ldrmntStateExport, // 옮겨야함 ...pbnstPrfmncStateExport, ...coRvwStateExport, ...ruseHstryStateExport, @@ -209,7 +209,7 @@ export const StoreZus = ( ...rswtChkSttnActionsExport(set), ...pbnstSttnActionsExport(set), ...coSttnActionsExport(set), // 옮겨야함 - ...ldrmntCoSttnActionsExport(set), // 옮겨야함 + ...ldrmntActionsExport(set), // 옮겨야함 ...pbnstPrfmncActionsExport(set), ...coRvwActionsExport(set), ...ruseHstryActionsExport(set), diff --git a/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx b/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx new file mode 100644 index 000000000..a6b05ca77 --- /dev/null +++ b/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx @@ -0,0 +1,48 @@ +"use client" + +import { btnClass } from "@/app/store/common/code" +import { drgtDetailHeadListExport } from "@/app/store/matDmd/drgtSttn/headList" +import { ContentsDiv, Title, UiTable } from "@common/business_components/ui" +import ListDiv from "@common/business_components/ui/list_div" +import { Button } from "@common/components/ui" + +export default function DrgtDetailModal() { + return ( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4 "> + <div className="col-span-4"> + <Title title={"우리동네가뭄 상세내용"} /> + <div className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> + <div className="flex flex-row space-x-2"> + <Button + size={"sm"} + className={`${btnClass} green`} + onClick={() => { }} + > + 다운로드 + </Button> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={[]} + tableData={[]} + headlist={drgtDetailHeadListExport} + pageSize={10} + total={10000} + cellClick={(index: number | undefined, headId: string) => { }} + onPageChange={() => { }} + ></UiTable> + </ListDiv> + </div> + </div> + </div> + </div> + </div> + + </ContentsDiv> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index d6f196b22..3d0eed82f 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -94,7 +94,6 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) { useEffect(()=>{ setbdstTable([]) // 초기화 작업 },[]) - const nodeList = headMakeColSpan(bdst.moUpHeadList); return ( <> <div className="grid grid-cols-12 gap-4 mt-4 items-center"> @@ -135,7 +134,6 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) { onPageChange={function (page: number): void { throw new Error("Function not implemented."); }}> - {nodeList} </UiTable> </div> </ScrollArea> diff --git a/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx b/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx new file mode 100644 index 000000000..5427c5dd2 --- /dev/null +++ b/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx @@ -0,0 +1,67 @@ +import { useWrStore } from "@/app/store"; +import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList"; +import type { FcPrfType, PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import { yearOptions } from "@/components/lib/func/commom"; +import { FileUpload, Form, FormField, FormUi, SelectBox, Title } from "@common/business_components/ui"; +import { Button, Input } from "@common/components/ui"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import type { z } from "zod"; + +export default function LdrmntExcelModal({ data }: { data: FcPrfType }) { + const { prfmnRegData } = useWrStore((state) => state); + const [excelData, setExcelData] = useState<PrfType[]>(); + const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({ + resolver: zodResolver(pbnPrfRegExcelZod), + defaultValues: { + ym: String(new Date().getFullYear()), + }, + }); + const onSubmit = (values: z.infer<typeof pbnPrfRegExcelZod>) => { + if (excelData) { + prfmnRegData(excelData as unknown as PrfType); + } + }; + const [files, setFiles] = useState<File[] | null>(null); + return ( + <> + <div> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)}> + <div> + <Title title={"잠재수요처 등록"}> +
+
+

+ {"잠재수요처 파일"} +

+ + +
+
+ ( + + { + if (files) setFiles(files); + }} + fileTypes="xlsx" + > + + )} + /> +
+ + +
+ + ) + +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx index bc50c3554..255ff0fc7 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx @@ -1,30 +1,824 @@ "use client"; import { useWrStore } from "@/app/store"; import type { CommonTableProps } from "@/app/store/common/type/header"; -import { Title } from "@common/business_components/ui"; +import { ldrmntZod, type customLdrmntBdst } from "@/app/store/matDmd/ldrmntCoSttn"; +import { rainZod, selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { handleCommaNumberChange, formatCommaNumber } from "@/components/lib/func/commom"; +import { DatePicker, Form, FormField, FormUi, ScrollArea, Title, UiTable } from "@common/business_components/ui"; +import { Button, Input } from "@common/components/ui"; +import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import type { z } from "zod"; -export default function SttnDetailModal( - {formObj,}: {formObj: any;}) { - const { code, rainSttn, rswtSttn, rainSttnChkSearch } = useWrStore( - (state) => state - ); - const [detailData, setDetailData] = useState({ - head: [] as CommonTableProps[], - node:[] as CommonTableProps[], - data: {} as any, +export default function SttnDetailModal({ + formObj, +}: { + formObj: any; +}) { + const defaultValues: z.infer = ldrmntZod.parse({}); + const form = useForm>({ + resolver: zodResolver(ldrmntZod), + defaultValues: defaultValues, }); - useEffect(() =>{ - setDetailData({data:[] , head:[], node:[]}) + const onSubmit = (values: z.infer) => { - },[]) + }; + + useEffect(() => { + if (ldrmntZod) form.reset(formObj); + + console.log("이거", formObj) + }, [formObj]); return ( -
- - + +
+ +
+

+ 잠재수요처 상세정보 +

+ +
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + field.onChange(date), + }} + selectClass={"w-full"} + /> + + )} + /> +
+ +
+ ( + + field.onChange(date), + }} + selectClass={"w-full"} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + field.onChange(date), + }} + selectClass={"w-full"} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + + +
+ +
); } diff --git a/apps/wr/public/sample_drgtSttn.xlsx b/apps/wr/public/sample_drgtSttn.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7a0c868cdc1f35cb25274f2a8197cf9ca8f21de4 GIT binary patch literal 9903 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