원수취수 모달 고정

This commit is contained in:
leedj312
2025-06-28 16:19:54 +09:00
parent 27997ca4bb
commit 9d5bffb403
2 changed files with 138 additions and 128 deletions
@@ -247,23 +247,6 @@ export function PbnstBuseForm({
setSumCpct(sum);
}, [form.formState, indexMng, indexBiz]);
// // 차수별 정보(fcBizs)가 하나도 없을 경우 플레이스홀더 UI를 보여줍니다.
// if (fcBizs.length === 0) {
// return (
// <div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 text-gray-500 border rounded-md">
// <p className="text-lg">등록된 차수별 정보가 없습니다.</p>
// <p className="text-sm mb-4">아래 버튼을 눌러 신규 차수 정보를 등록해주세요.</p>
// <Button
// onClick={addRuseFcltObj}
// type="button"
// size={commonButonSize}
// className="mt-2"
// >
// 신규 차수 등록
// </Button>
// </div>
// );
// }
const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`);
return (
@@ -672,7 +655,7 @@ export function PbnstBuseForm({
<UiModal
open={isFcOrgwts}
onOpenChange={(open: boolean) => setIsFcOrgwts(open)}
bodyClass={"w-[50vw] max-w-none h-[90vh]"}
bodyClass={"w-[70vw] max-w-none max-h-[90vh] overflow-y-auto"}
body={
<FcOrgwtsRegModal
closeModal={() => {
@@ -1,6 +1,10 @@
"use client";
import { useWrStore } from "@/app/store";
import type { pubHasuType, fcBizType, fcOrgwtType,} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type {
pubHasuType,
fcBizType,
fcOrgwtType,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { TableUpperProps } from "@/app/store/common/type/header";
import { tableData } from "@/components/lib/func/commom";
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
@@ -11,138 +15,161 @@ import { Input } from "@common/components/ui";
import { ArrowLeft, ArrowRight } from "lucide-react";
import { useEffect, useRef, useState } from "react";
export default function FcOrgwtsRegModal({ onRightSet, closeModal }: { onRightSet?: (rightData:fcOrgwtType[]) => void,closeModal?:(val:boolean) =>void }) {
const { code, pbnst, getSwtrmtFcltNm, searchFclts } = useWrStore((state) => state);
export default function FcOrgwtsRegModal({
onRightSet,
closeModal,
}: {
onRightSet?: (rightData: fcOrgwtType[]) => void;
closeModal?: (val: boolean) => void;
}) {
const { code, pbnst, getSwtrmtFcltNm, searchFclts } = useWrStore(
(state) => state
);
const { fcOrgwtsHeadList, pbnstHasuRes } = pbnst;
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
const rightRef = useRef<pubHasuType[] | null>([] as pubHasuType[]);
const leftRef = useRef<pubHasuType[] | null>([] as pubHasuType[]);
const [rightData, setRightData] = useState<pubHasuType[]>();
const [inputVal, setInputVal] = useState<string>("");
useEffect(()=>{
if(Array.isArray(searchFclts)){
useEffect(() => {
if (Array.isArray(searchFclts)) {
const filteredData = searchFclts.filter((item) => {
if(rightData){
if(rightData.find(rightItem =>rightItem.bscFctCd===item.bscFctCd))
if (rightData) {
if (
rightData.find((rightItem) => rightItem.bscFctCd === item.bscFctCd)
)
return false;
}
return true
})
setbdstTable(Array.isArray(filteredData) ? [...filteredData] : [])
return true;
});
setbdstTable(Array.isArray(filteredData) ? [...filteredData] : []);
}
}, [searchFclts])
}, [searchFclts]);
useEffect(() => {
if (code.sggCd.length > 0 && pbnstHasuRes.length > 0) {
setbdstTable(tableData(pbnstHasuRes, { code }));
console.log('bdstTable ', bdstTable)
console.log("bdstTable ", bdstTable);
}
}, [code, pbnstHasuRes]);
useEffect(() => {
console.log('rightData ', rightData)
if(onRightSet)
onRightSet(
(rightData as pubHasuType[])?.map(item => ({
swtrmtFcltFk: item.bscFctCd, // 임시값, 실제 데이터에 맞게 수정
orgwtWtritQnt: Number(item.fctCpc), // 임시값, 실제 데이터에 맞게 수정
tmsYn: "N", // 임시값, 실제 데이터에 맞게 수정
dschgFmYn: "N", // 임시값, 실제 데이터에 맞게 수정
dtlPstnExpln: item.addr, // 임시값, 실제 데이터에 맞게 수정
choose: false, // 임시값, 실제 데이터에 맞게 수정
// 필요한 경우 다른 속성들도 추가
})) as unknown as fcOrgwtType[]
);
}, [rightData])
console.log("rightData ", rightData);
if (onRightSet)
onRightSet(
(rightData as pubHasuType[])?.map((item) => ({
swtrmtFcltFk: item.bscFctCd, // 임시값, 실제 데이터에 맞게 수정
orgwtWtritQnt: Number(item.fctCpc), // 임시값, 실제 데이터에 맞게 수정
tmsYn: "N", // 임시값, 실제 데이터에 맞게 수정
dschgFmYn: "N", // 임시값, 실제 데이터에 맞게 수정
dtlPstnExpln: item.addr, // 임시값, 실제 데이터에 맞게 수정
choose: false, // 임시값, 실제 데이터에 맞게 수정
// 필요한 경우 다른 속성들도 추가
})) as unknown as fcOrgwtType[]
);
}, [rightData]);
return (
<>
<div className="flex flex-col h-full">
<div className="flex items-center justify-between">
<Title title={"취수하수처리장 추가"} />
<Button className="m-2" size={"sm"}
onClick={() => {closeModal && closeModal(false) }}>저장</Button>
</div>
<div className="flex flex-col h-[80vh]">
<div className="shrink-0 p-4 border-b z-10 bg-white">
<div className="flex items-center">
<Title title="취수하수처리장 추가" />
{/* <Button size="sm" onClick={() => closeModal?.(false)}>저장</Button> */}
<div className="flex items-center gap-2 mt-8">
<div className="flex flex-row flex-grow gap-4 mt-4">
<div className="w-3/7">
<div className="flex items-center justify-between">
<Label className="w-full text-2xl text-gray-600 text-left">공공하수처리시설 목록</Label>
<div className="flex items-center">
<Label className="w-full text-xl text-gray-600 text-right">시설명</Label>
<Input className="w-1/2 !text-xl ml-2" type="text" value={inputVal} onChange={(e) => {setInputVal(e.target.value)}} />
<Button className="m-2" size={"sm"} onClick={() => getSwtrmtFcltNm(inputVal)}>조회</Button>
</div>
</div>
<div className="border-t border-gray-300 my-4"></div>
<RuseMngTable
tableData={bdstTable || []}
headList={fcOrgwtsHeadList}
upHeadList={[]} // TODO: Replace with actual upHeadList data if available
ref={leftRef}
/>
</div>
<div className="flex flex-col items-center justify-center w-1/7 gap-2">
<ArrowRight
type="button"
onClick={() => {
if (leftRef && typeof leftRef === "object" && "current" in leftRef) {
const checked = leftRef.current?.filter((item) => ((item as unknown as pubHasuType)?.choose))
const unchecked = leftRef.current?.filter((item) => !(item as unknown as pubHasuType)?.choose)
if (checked && checked.length > 0) {
checked.forEach(item=>(item as unknown as pubHasuType).choose = false)
setRightData([...(checked as unknown as pubHasuType[]),
...((rightRef.current ?? []) as unknown as pubHasuType[])
])
}
if (unchecked && unchecked.length > 0) {
setbdstTable([...(unchecked as unknown as pubHasuType[])])
}else{
setbdstTable([])
}
}
}
}
className="w-12 h-12 text-gray-500 cursor-pointer"
/>
<ArrowLeft
type="button"
onClick={() => {
if (rightRef && typeof rightRef === "object" && "current" in rightRef) {
const checked = rightRef.current?.filter((item) => ((item as unknown as pubHasuType)?.choose))
const unchecked = rightRef.current?.filter((item) => !(item as unknown as pubHasuType)?.choose)
if (checked && checked.length > 0) {
checked.forEach(item=>(item as unknown as pubHasuType).choose = false)
setbdstTable([
...(checked as unknown as pubHasuType[]),
...((leftRef.current ?? []) as unknown as pubHasuType[])
])
}
if (unchecked && unchecked.length > 0) {
setRightData([...(unchecked as unknown as pubHasuType[])])
}else{
setRightData([])
}
}
}}
className="w-12 h-12 text-gray-500 cursor-pointer mt-5" />
</div>
{/* Right Table container: Takes 2/5 of the width */}
<div className="w-3/7">
<Label className="w-full text-2xl text-gray-600 text-right">취수하수처리장 목록</Label>
<div className="border-t border-gray-300 my-4"></div>
<RuseMngTable
tableData={rightData || []}
headList={fcOrgwtsHeadList}
upHeadList={[]} // TODO: Replace with actual upHeadList data if available
ref={rightRef}
/>
<Label className="text-xl text-gray-600">시설명</Label>
<Input
className="w-48 text-xl"
type="text"
value={inputVal}
onChange={(e) => setInputVal(e.target.value)}
/>
<Button size="sm" onClick={() => getSwtrmtFcltNm(inputVal)}>
조회
</Button>
</div>
</div>
</div>
</>
{/* <div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Label className="text-xl text-gray-600">시설명</Label>
<Input
className="w-48 text-xl"
type="text"
value={inputVal}
onChange={(e) => setInputVal(e.target.value)}
/>
<Button size="sm" onClick={() => getSwtrmtFcltNm(inputVal)}>조회</Button>
</div>
</div>
</div> */}
{/* 테이블 영역 */}
<div className="flex flex-row gap-4 flex-grow p-4 overflow-x-auto">
{/* 왼쪽 테이블 */}
<div className="w-5/12 min-w-[400px]">
<Label className="text-2xl text-gray-600 mb-2 block text-right">
공공하수처리시설 목록
</Label>
<RuseMngTable
tableData={bdstTable || []}
headList={fcOrgwtsHeadList}
upHeadList={[]}
ref={leftRef}
/>
</div>
{/* 중간 이동 버튼 */}
<div className="flex flex-col justify-center items-center gap-4 w-[200px] min-w-[120px]">
<ArrowRight
onClick={() => {
const checked = leftRef.current?.filter((item) => item.choose);
const unchecked = leftRef.current?.filter((item) => !item.choose);
if (checked?.length) {
checked.forEach((item) => (item.choose = false));
setRightData([
...(checked as pubHasuType[]),
...(rightRef.current ?? []),
]);
}
setbdstTable(unchecked ?? []);
}}
className="w-8 h-8 text-gray-500 cursor-pointer"
/>
<ArrowLeft
onClick={() => {
const checked = rightRef.current?.filter((item) => item.choose);
const unchecked = rightRef.current?.filter(
(item) => !item.choose
);
if (checked?.length) {
checked.forEach((item) => (item.choose = false));
setbdstTable([
...(checked as pubHasuType[]),
...(leftRef.current ?? []),
]);
}
setRightData(unchecked ?? []);
}}
className="w-8 h-8 text-gray-500 cursor-pointer"
/>
</div>
{/* 오른쪽 테이블 */}
<div className="w-5/12 min-w-[400px]">
<Label className="text-2xl text-gray-600 mb-2 block text-right">
취수하수처리장 목록
</Label>
<RuseMngTable
tableData={rightData || []}
headList={fcOrgwtsHeadList}
upHeadList={[]}
ref={rightRef}
/>
</div>
</div>
</div>
);
}