하수재이용실적 등록 팝업 화면 수정, 등록 오류 수정, 테이블 merge 추가, 소계 및 총합계 배경색 추가
This commit is contained in:
@@ -25,7 +25,7 @@ import {
|
||||
} from "@common/components/ui";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { set } from "react-hook-form";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import toast, { Toaster } from "react-hot-toast";
|
||||
import { headMakeprfmnc } from "../chkgdnReg/TableHead";
|
||||
import { InputTableBody } from "@/components/lib/func/TableData";
|
||||
import {
|
||||
@@ -51,8 +51,8 @@ export default function prfmncPrfmncReg() {
|
||||
}>({ isModal: false, data: {} as FcPrfType });
|
||||
const [inputData, setInputData] = useState<any[]>();
|
||||
const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState<string>();
|
||||
const [pageNation , setPageNation] = useState<number>(1);
|
||||
|
||||
const [pageNation, setPageNation] = useState<number>(1);
|
||||
const [cellNum, setCellNum] = useState<number>();
|
||||
const [searchYear, setSearchYear] = useState<string>(
|
||||
String(new Date().getFullYear())
|
||||
);
|
||||
@@ -76,7 +76,7 @@ export default function prfmncPrfmncReg() {
|
||||
);
|
||||
prfmncHasuInit(String(pageNation), "41");
|
||||
}
|
||||
}, [inputData, searchYear, pbnstRuseFcltPk,prfmncHasuInit,pageNation]);
|
||||
}, [inputData, searchYear, pbnstRuseFcltPk, prfmncHasuInit, pageNation]);
|
||||
|
||||
|
||||
|
||||
@@ -88,10 +88,16 @@ export default function prfmncPrfmncReg() {
|
||||
isModal: false,
|
||||
data: prfmncRes[index] || ({} as FcPrfType),
|
||||
});
|
||||
const inUsageData = structuredClone(initValInUsage);
|
||||
const outUsageData = structuredClone(initValOutUsage);
|
||||
const inSubtotal = structuredClone(subTotalObj);
|
||||
const outSubtotal = structuredClone(subTotalObj);
|
||||
const inUsageData = structuredClone(initValInUsage).map(row => ({
|
||||
...row,
|
||||
구분: "장내용수",
|
||||
}));
|
||||
const outUsageData = structuredClone(initValOutUsage).map(row => ({
|
||||
...row,
|
||||
구분: "장외용수",
|
||||
}));
|
||||
const inSubtotal = { ...structuredClone(subTotalObj), 구분: "장내용수" };
|
||||
const outSubtotal = { ...structuredClone(subTotalObj), 구분: "장외용수" };
|
||||
if (prfmncRes[index]?.prfList) {
|
||||
prfmncRes[index].prfList?.forEach((prfItem) => {
|
||||
const month = Number(prfItem?.ym?.slice(4)); // "MM"
|
||||
@@ -127,7 +133,7 @@ export default function prfmncPrfmncReg() {
|
||||
});
|
||||
inUsageData.push(inSubtotal);
|
||||
outUsageData.push(outSubtotal);
|
||||
const usageTotalObj: { [key: string]: any } = structuredClone(totalObj);
|
||||
const usageTotalObj: { [key: string]: any } = { ...structuredClone(totalObj), 구분: "총합계", 용수명: "" };
|
||||
for (const key in usageTotalObj) {
|
||||
if (["usage", "gubun", "edit"].includes(key)) continue;
|
||||
const val =
|
||||
@@ -162,7 +168,7 @@ export default function prfmncPrfmncReg() {
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"하수재이용 시설 등록"} />
|
||||
<Title title={"하수재이용 실적 등록"} />
|
||||
<SearchDiv>
|
||||
<SearchFormLeft>
|
||||
<div className="col-span-2 flex flex-row space-x-2">
|
||||
@@ -197,7 +203,7 @@ export default function prfmncPrfmncReg() {
|
||||
<SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
|
||||
<div className="space-y">
|
||||
<div className="flex flex-row space-x-2">
|
||||
<Button size={"sm"} onClick={(e) => {}}>
|
||||
<Button size={"sm"} onClick={(e) => { }}>
|
||||
조회
|
||||
</Button>
|
||||
<Button
|
||||
@@ -211,7 +217,12 @@ export default function prfmncPrfmncReg() {
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={() => {
|
||||
setIsExcelOPen({ ...isExcelOpen, isModal: true });
|
||||
if (cellNum === undefined) {
|
||||
toast.error("하수처리재이용시설을 선택해주세요.")
|
||||
return;
|
||||
} else {
|
||||
setIsExcelOPen({ ...isExcelOpen, isModal: true });
|
||||
}
|
||||
}}
|
||||
>
|
||||
파일등록
|
||||
@@ -238,6 +249,7 @@ export default function prfmncPrfmncReg() {
|
||||
headName={"하수재이용시설 목록"}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
cellClick(index, headId);
|
||||
setCellNum(index ?? 0);
|
||||
}}
|
||||
onPageChange={setPageNation}
|
||||
children={undefined}
|
||||
@@ -266,7 +278,7 @@ export default function prfmncPrfmncReg() {
|
||||
</div>
|
||||
</ContentsDiv>
|
||||
<UiModal
|
||||
bodyClass={""}
|
||||
bodyClass={"w-[30vw] max-w-none"}
|
||||
body={<PbnPrfExcelModal data={isExcelOpen.data}></PbnPrfExcelModal>}
|
||||
open={isExcelOpen.isModal}
|
||||
onOpenChange={() => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { TableUpperProps } from "../../common/type/header";
|
||||
export const pbnPrfRegExcelZod = z.object({
|
||||
ym: z.string().default(""),
|
||||
bscFctNm: z.string().default(""),
|
||||
pbnstRuseFcltFk:z.string(),
|
||||
pbnstRuseFcltFk: z.string(),
|
||||
pbnstRuseFcltNm: z.string().default(""),
|
||||
file: z.instanceof(File).optional(),
|
||||
});
|
||||
@@ -18,20 +18,21 @@ export const pbnstPrfmncHeadListExport: TableUpperProps[] = [
|
||||
];
|
||||
|
||||
export const monthHeadListExport: TableUpperProps[] = [
|
||||
{ id: "구분", title: "구분", mergeCell: true },
|
||||
{ id: "용수명", title: "용수명" },
|
||||
{ id: "total", title: "계" },
|
||||
{ id: "1월", title: "1월" ,edit: true },
|
||||
{ id: "2월", title: "2월" ,edit: true },
|
||||
{ id: "3월", title: "3월" ,edit: true },
|
||||
{ id: "4월", title: "4월" ,edit: true },
|
||||
{ id: "5월", title: "5월" ,edit: true },
|
||||
{ id: "6월", title: "6월" ,edit: true },
|
||||
{ id: "7월", title: "7월" ,edit: true },
|
||||
{ id: "8월", title: "8월" ,edit: true },
|
||||
{ id: "9월", title: "9월" ,edit: true },
|
||||
{ id: "10월", title: "10월" ,edit: true },
|
||||
{ id: "11월", title: "11월" ,edit: true },
|
||||
{ id: "12월", title: "12월" ,edit: true },
|
||||
{ id: "1월", title: "1월", edit: true },
|
||||
{ id: "2월", title: "2월", edit: true },
|
||||
{ id: "3월", title: "3월", edit: true },
|
||||
{ id: "4월", title: "4월", edit: true },
|
||||
{ id: "5월", title: "5월", edit: true },
|
||||
{ id: "6월", title: "6월", edit: true },
|
||||
{ id: "7월", title: "7월", edit: true },
|
||||
{ id: "8월", title: "8월", edit: true },
|
||||
{ id: "9월", title: "9월", edit: true },
|
||||
{ id: "10월", title: "10월", edit: true },
|
||||
{ id: "11월", title: "11월", edit: true },
|
||||
{ id: "12월", title: "12월", edit: true },
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -174,8 +174,6 @@ export const chRowspanTable = (
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const headVisibleChange = (headList: TableUpperProps[], isEdit: boolean) => {
|
||||
return headList.forEach((head) => {
|
||||
if (head.edit !== undefined)
|
||||
@@ -187,63 +185,124 @@ export const headVisibleChange = (headList: TableUpperProps[], isEdit: boolean)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const handleChange = (
|
||||
rowIndex: number,
|
||||
field: any,
|
||||
value: string | number,
|
||||
setInputData: (data:any) => void
|
||||
setInputData: (data: any) => void
|
||||
) => {
|
||||
if(Number(value) < 0 ||! Number(value)){
|
||||
value = 0;
|
||||
}else{
|
||||
if (Number(value) < 0 || !Number(value)) {
|
||||
value = 0;
|
||||
} else {
|
||||
value = Number(value);
|
||||
}
|
||||
setInputData((prevData:any) =>
|
||||
prevData?.map((row:any, index: number) => {
|
||||
if (index === rowIndex) {
|
||||
return {
|
||||
...row,
|
||||
[field ]: value,
|
||||
};
|
||||
}
|
||||
return row;
|
||||
})
|
||||
);
|
||||
setInputData((prevData: any) =>
|
||||
prevData?.map((row: any, index: number) => {
|
||||
if (index === rowIndex) {
|
||||
return {
|
||||
...row,
|
||||
[field]: value,
|
||||
};
|
||||
}
|
||||
return row;
|
||||
})
|
||||
);
|
||||
};
|
||||
;
|
||||
|
||||
export const InputTableBody = (
|
||||
chgRes: any[] | [],
|
||||
headList: TableUpperProps[],
|
||||
setInputData: (data: any[]) => void
|
||||
) => {
|
||||
// mergeCell 처리용
|
||||
const getRowSpan = (data: any[], key: string, rowIndex: number) => {
|
||||
if (rowIndex > 0 && data[rowIndex][key] === data[rowIndex - 1][key]) {
|
||||
return 0; // 이전과 같으면 셀을 그리지 않음
|
||||
}
|
||||
let span = 1;
|
||||
for (let i = rowIndex + 1; i < data.length; i++) {
|
||||
if (data[i][key] === data[rowIndex][key]) span++;
|
||||
else break;
|
||||
}
|
||||
return span;
|
||||
};
|
||||
|
||||
|
||||
export const InputTableBody = (chgRes: any[] | [] ,headList:TableUpperProps[], setInputData: (data: any[]) => void) => {
|
||||
return (
|
||||
return (
|
||||
<>
|
||||
{chgRes.map((data, dataIndex) => (
|
||||
<TableRow key={dataIndex + "row"}>
|
||||
{headList.map((head, headIndex) => (
|
||||
<TableCell key={head.id + headIndex} className="w-36" >
|
||||
{head.edit ===true && data.edit !==false?
|
||||
<Input
|
||||
className={`${head.id !== "utztnUsgCd" ? "text-right" : "text-center"} !text-xl h-10 w-full`}
|
||||
onChange={(e) =>
|
||||
handleChange(dataIndex, head.id, e.target.value,setInputData)
|
||||
}
|
||||
value={data[head.id as keyof any] ?? ""}
|
||||
/> : (
|
||||
<div
|
||||
className={`
|
||||
${head.id !== "utztnUsgCd" ? "text-right" : "text-center"}
|
||||
!text-xl w-full h-10
|
||||
`}
|
||||
{chgRes.map((data, dataIndex) => {
|
||||
// 소계/총합계 행 판별
|
||||
const isSubTotal = data["용수명"] === "소계";
|
||||
const isTotal = data["구분"] === 0;
|
||||
|
||||
const bgClass = isTotal
|
||||
? "bg-[#d5e1eb] font-bold"
|
||||
: isSubTotal
|
||||
? "bg-[#e6eef5] font-semibold"
|
||||
: "";
|
||||
|
||||
return (
|
||||
<TableRow key={dataIndex + "row"}>
|
||||
{headList.map((head, headIndex) => {
|
||||
// 총합계 행이면 "구분"에서 colSpan=2로 병합
|
||||
if (
|
||||
data["구분"] === 0 &&
|
||||
head.id === "구분"
|
||||
) {
|
||||
return (
|
||||
<TableCell
|
||||
key={head.id + headIndex}
|
||||
colSpan={2}
|
||||
className="font-bold text-center bg-[#d5e1eb]"
|
||||
>
|
||||
{data[head.id as keyof any] ?? ""}
|
||||
</div>
|
||||
)
|
||||
총합계
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
// 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음
|
||||
if (
|
||||
data["구분"] === 0 &&
|
||||
head.id === "용수명"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
// mergeCell 처리
|
||||
if (head.mergeCell) {
|
||||
const rowSpan = getRowSpan(chgRes, head.id, dataIndex);
|
||||
if (rowSpan === 0) return null;
|
||||
return (
|
||||
<TableCell key={head.id + headIndex} rowSpan={rowSpan} className={`w-36 align-middle text-center whitespace-nowrap ${bgClass}`}>
|
||||
{data[head.id as keyof any] ?? ""}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
// 기본 셀
|
||||
return head.edit === true && data.edit !== false ? (
|
||||
<TableCell key={head.id + headIndex} className={`w-36 ${bgClass}`}>
|
||||
<Input
|
||||
className={`${head.id !== "utztnUsgCd" ? "text-right" : "text-center"} !text-xl h-10 w-full`}
|
||||
onChange={(e) =>
|
||||
handleChange(dataIndex, head.id, e.target.value, setInputData)
|
||||
}
|
||||
value={data[head.id as keyof any] ?? ""}
|
||||
/>
|
||||
</TableCell>
|
||||
) : (
|
||||
<TableCell key={head.id + headIndex} className={`w-36 ${bgClass}`}>
|
||||
<div
|
||||
className={`
|
||||
${head.id !== "utztnUsgCd" ? "text-right" : "text-center"}
|
||||
!text-xl w-full h-10
|
||||
`}
|
||||
>
|
||||
{data[head.id as keyof any] ?? ""}
|
||||
</div>
|
||||
</TableCell>
|
||||
);
|
||||
})}
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -52,6 +52,7 @@ export default function PbnPrfExcelModal({ data }: { data: FcPrfType }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (files) {
|
||||
console.log("이런")
|
||||
const file = files[0];
|
||||
if (form.getValues("ym").length < 1) {
|
||||
ToastFormUi({
|
||||
@@ -62,11 +63,12 @@ export default function PbnPrfExcelModal({ data }: { data: FcPrfType }) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (file)
|
||||
if (file) {
|
||||
filePicked(file, 0).then((res) => {
|
||||
if (res !== undefined)
|
||||
setExcelData(excelToPbnPrfData(res as unknown as JSON[], form.getValues("ym"),form.getValues('pbnstRuseFcltFk') ) as PrfType[])
|
||||
setExcelData(excelToPbnPrfData(res as unknown as JSON[], form.getValues("ym"), form.getValues('pbnstRuseFcltFk')) as PrfType[])
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [files]);
|
||||
|
||||
@@ -75,82 +77,85 @@ export default function PbnPrfExcelModal({ data }: { data: FcPrfType }) {
|
||||
<div>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<div>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title={"하수재이용 실적등록"}></Title>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<h3 className="text-2xl font-bold text-gray-900 mt-1 ml-7">
|
||||
{"점검정보 입력"}
|
||||
</h3>
|
||||
|
||||
<Button className="" type="submit">
|
||||
<Button className="mr-6 mt-10" type="submit">
|
||||
저장
|
||||
</Button>
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-gray-900 my-3 ml-7">
|
||||
{"점검정보 입력"}
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
<div className="mx-7">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="ym"
|
||||
render={({ field }) => (
|
||||
<FormUi label="등록년도">
|
||||
<SelectBox
|
||||
className="w-1/4 text-3xl"
|
||||
className="w-1/2 pr-4 text-3xl"
|
||||
selectClass={""}
|
||||
label=""
|
||||
selectArray={yearOptions}
|
||||
value={field.value||new Date().getFullYear()}
|
||||
value={field.value || new Date().getFullYear()}
|
||||
onSelectValue={(val) => field.onChange(val)}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="bscFctNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="시설명">
|
||||
<Input
|
||||
className="w-1/4 text-3xl"
|
||||
value={field.value||''}
|
||||
onChange={field.onChange}
|
||||
readOnly
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="pbnstRuseFcltNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="재이용시설명">
|
||||
<Input
|
||||
className="w-1/4 text-3xl"
|
||||
value={field.value||''}
|
||||
onChange={field.onChange}
|
||||
readOnly
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="file"
|
||||
render={({ field }) => (
|
||||
<FormUi label="점검결과 파일">
|
||||
<FileUpload
|
||||
files={files || []}
|
||||
setFiles={(files: File[] | null) => {
|
||||
if (files) setFiles(files);
|
||||
}}
|
||||
fileTypes="xlsx"
|
||||
maxFiles={1}
|
||||
></FileUpload>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
<div className="flex gap-4 mt-4">
|
||||
<div className="flex-1">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="bscFctNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="시설명">
|
||||
<Input
|
||||
className="text-3xl"
|
||||
value={field.value || ''}
|
||||
onChange={field.onChange}
|
||||
readOnly
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="pbnstRuseFcltNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="재이용시설명">
|
||||
<Input
|
||||
className="flex-1 text-3xl"
|
||||
value={field.value || ''}
|
||||
onChange={field.onChange}
|
||||
readOnly
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="file"
|
||||
render={({ field }) => (
|
||||
<FormUi label="점검결과 파일">
|
||||
<FileUpload
|
||||
files={files || []}
|
||||
setFiles={(files: File[] | null) => {
|
||||
if (files) setFiles(files);
|
||||
}}
|
||||
fileTypes="xlsx"
|
||||
maxFiles={1}
|
||||
></FileUpload>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user