Merge commit '41df013bb382c91a18b3023e35f5e1f3f384b877' into iipbs/wr/form_fuction

This commit is contained in:
jyha00
2025-05-29 20:12:25 +09:00
24 changed files with 758 additions and 627 deletions
@@ -15,7 +15,7 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components";
import { useEffect, useState } from "react";
import ListDiv from "@common/business_components/ui/list_div";
import { tableData } from "@/components/lib/func/commom";
import type { customPbnst, fcBizSchema, fcBizType, ruseFcltType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { customPbnst, fcBizSchema, fcBizType, pubHasuType, ruseFcltType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm";
import { z } from "zod";
@@ -31,13 +31,13 @@ export default function PublicReuseFaciltyInsert() {
const [issNewReg, setIsNewReg] = useState<boolean>(false);
const [searchTxt, setSearchTxt] = useState<string>();
const [bdstTable, setbdstTable] = useState<customPbnst[]>();
const [selectBdst, setSelectBdst] = useState<customPbnst[] | null>(null);
const [selectedRow, setSelectedRow] = useState<customPbnst | null>(null);
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
const [selectBdst, setSelectBdst] = useState<customPbnst | null>(null);
const [selectedRow, setSelectedRow] = useState<pubHasuType | null>(null);
useEffect(() => {
if (!pbnst.isInit ) {
pubHasuInit(undefined);
pubHasuInit('1','11');
pbnstRegInit( '41');
}
@@ -46,7 +46,6 @@ useEffect(() => {
useEffect(() => {
console.log("pbnstHasuRes", pbnstHasuRes);
if (code.sggCd.length > 0 && pbnstHasuRes.length > 0) {
setbdstTable(tableData(pbnstHasuRes, { code }));
}
@@ -57,17 +56,16 @@ useEffect(() => {
};
const cellClick = (val: number | undefined) => {
if (val === undefined) return;
console.log("pbnstRes", pbnstRes)
const selectRow = pbnstHasuRes?.[val];
setSelectedRow(selectRow);
console.log("아제발", selectRow)
if (selectRow) {
setSelectedRow(selectRow);
}
if (pbnstRes === null){
alert("등록된 재이용시설 정보가 없습니다. 신규등록 하십시오.")
return;
}
setSelectBdst(pbnstRes);
setPbnstBiz(pbnstRes?.fcBizs)
// setSelectBdst(pbnstRes);
// setPbnstBiz(pbnstRes?.fcBizs)
};
const resetContents = () => {
setFcltMng([]); // 빈 배열로 설정하여 신규 모드로 전환
@@ -136,14 +134,20 @@ useEffect(() => {
</ListDiv>
</div>
<ListDiv className="col-span-2 pr-6 ">
<ScrollArea className="h-[60vh]">
<Tabs defaultValue="mng" onValueChange={handleTabChange}>
<TabsList className="">
<TabsTrigger className="!text-xl" value="mng">시설정보</TabsTrigger>
<TabsTrigger className="!text-xl" value="buse">차수별정보</TabsTrigger>
<Button size={"sm"} className="!justify-end">
저장
</Button>
</TabsList>
<TabsContent className="max-h-full" value="mng">
<PbnstMngForm data={selectBdst || []} />
<PbnstMngForm data={selectBdst || null} />
</TabsContent>
<TabsContent className="max-h-full" value="buse">
<PbnstBuseForm data={pbnstBiz || []} />
+3 -2
View File
@@ -1,4 +1,4 @@
import { getFetch } from "@/components/lib/api"
import { fetchType, getFetch, postFectch } from "@/components/lib/api"
import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type"
export type comFcltState = {
searchFclts: pubHasuType
@@ -6,6 +6,7 @@ export type comFcltState = {
export type comFcltActions = {
getSwtrmtFcltNm: (searchNm: string) => void
}
export const searchActions: (set: any) => comFcltActions = (set: any) => {
return {
getSwtrmtFcltNm: async (searchNm: string) => {
@@ -23,6 +24,6 @@ export const searchActions: (set: any) => comFcltActions = (set: any) => {
searchFclts: fcltNmCd
}
))
}
},
}
}
@@ -1,10 +1,6 @@
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
import type { TableUpperProps } from "../rainReg";
export const pubFacHeadListExport: TableUpperProps[] = [
{ id: "sido", title: "시도" },
{ id: "gugun", title: "시군구" },
@@ -18,119 +14,121 @@ export const pubFacHeadListExport: TableUpperProps[] = [
export const pbnstMngUpHeadListExport: TableUpperProps[] = [
{ id: "choose", title: "선택", type: "checkbox" },
{ id: "operMthd", title: "운영방식", edit: true},
{ id: "rprtvBzenty", title: "대행업체", edit: true},
{ id: "bgngDt", title: "시작일", upName: "upChangeRe", upSequnce: 1, type: "date"},
{ id: "endDt", title: "종료일", upName: "upChangeRe", upSequnce: 2, type: "date"},
];
{ id: "operMthd", title: "운영방식", edit: true },
{ id: "rprtvBzenty", title: "대행업체", edit: true },
{
id: "bgngDt",
title: "시작일",
upName: "upChangeRe",
upSequnce: 1,
type: "date",
},
{
id: "endDt",
title: "종료일",
upName: "upChangeRe",
upSequnce: 2,
type: "date",
},
];
export const pplInstlsHeadListExport: TableUpperProps[] = [
{ id: "choose", title: "선택", type: "checkbox" },
{ id: "ppMqlt", title: "관재질", type: "select", selectData:'pplQulity' },
{ id: "pdmt", title: "관경", type: "select", selectData:'pplLenght'},
{ id: "ppMqlt", title: "관재질", type: "select", selectData: "pplQulity" },
{ id: "pdmt", title: "관경", type: "select", selectData: "pplLenght" },
{ id: "cpct", title: "연장", edit: true, type: "number" },
];
export const pbnstDemandHeadListExport: TableUpperProps[] = [
{ id: "dmdCoNm", title: "수요처명" },
{ id: "daddr", title: "위치(주소)" },
{ id: "useUsgCd", title: "사용용도", },
{ id: "splyBgngDay", title: "공급시작일", },
{ id: "splyEndDay", title: "공급종료일", },
{ id: "splyCpct", title: "공급량(m³/일)", },
{ id: "splyFmYon", title: "공급유량계 유무", },
{ id: "useUsgCd", title: "사용용도" },
{ id: "splyBgngDay", title: "공급시작일" },
{ id: "splyEndDay", title: "공급종료일" },
{ id: "splyCpct", title: "공급량(m³/일)" },
{ id: "splyFmYon", title: "공급유량계 유무" },
];
export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [
{ id: "ruseUtztnFcltNm", title: "운영방식" },
{ id: "ruseUtztnFcltNm", title: "운영방식" },
{ id: "orgwtWtritQnt", title: "원수취수량" },
{ id: "tmsYn", title: "하수처리량TMS 전후", },
{ id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​", },
{ id: "dtlPstnExpln", title: "상세위치 설명", },
{ id: "tmsYn", title: "하수처리량TMS 전후" },
{ id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​" },
{ id: "dtlPstnExpln", title: "상세위치 설명" },
];
export const fcOrgwtsHeadListExport: TableUpperProps[] = [
{ id: "choose", title: "선택", type: "checkbox" },
{ id: "sido", title: "시도" },
{ id: "gugun", title: "시군구" },
{ id: "gugun", title: "시군구" },
{ id: "bscFctNm", title: "시설명" },
{ id: "addr", title: "위치" },
]
];
export const pbnstMngNmExport: chHeadType[] = [
{ headNm: "upChangeRe", text: "운영대행기간", length: 2 },
];
export type formDetailType ={
id:string,
lable:string
type?:string
}
export type formDetailType = {
id: string;
lable: string;
type?: string;
};
export const wasteWaterFcltINfo: formDetailType[] = [
{ id: "wwtEmsnFcltPrmsnYn", lable: "폐수배출물신고 허가여부" },
{ id: "tmsInstlYn", lable: "Tms설치여부" },
{ id: "pbnstDrngInflwExclYn", lable: "공공하수도유입제외 허가여부" },
];
export const wasteWaterFcltINfo:formDetailType[]=[
{id:'wwtEmsnFcltPrmsnYn' , lable:'폐수배출물신고 허가여부'},
{id:'tmsInstlYn' , lable:'Tms설치여부'},
{id:'pbnstDrngInflwExclYn' , lable:'공공하수도유입제외 허가여부'},
]
export const concentratedWaterInfo: formDetailType[] = [
{ id: "erctWtrOcrnCpct", lable: "눙축수 발생량(m³/일)", type: "number" },
{ id: "erctUswtrLinkSpt", lable: "눙축수연계지점" },
{ id: "erctUswtrFcltCpct", lable: "시설용량(m³/일)", type: "number" },
{ id: "erctUswtrPrcsMeth", lable: "눙축수처리방식" },
{ id: "erctUswtrPrcsMsrcCd", lable: "눙축수처리공법" },
];
export const concentratedWaterInfo:formDetailType[]=[
{id:'erctWtrOcrnCpct' , lable:'눙축수 발생량(m³/일)'},
{id:'erctUswtrLinkSpt' , lable:'눙축수연계지점'},
{id:'erctUswtrFcltCpct' , lable:'시설용량(m³/일)'},
{id:'erctUswtrPrcsMeth' , lable:'눙축수처리방식'},
{id:'erctUswtrPrcsMsrcCd' , lable:'눙축수처리공법'},
]
export const ruseFcltinfo: formDetailType[] = [
{ id: "rprcsFcltCpct", lable: "시설용량(m³/일)", type: "number" },
{ id: "majorPrcsMsrcCd", lable: "주처리공법" },
{ id: "addr", lable: "위치(주소)" },
{ id: "rprcsMthdCd", lable: "재처리방식" },
{ id: "inoutYn", lable: "위치(처리장 내외)" }, // 머가 내? 외?,
{ id: "mainSplyPumpCpct", lable: "메인공급펌프 용량", type: "number" },
];
export const ruseFcltinfo:formDetailType[]=[
{id:'rprcsFcltCpct' , lable:'시설용량(m³/일)'},
{id:'majorPrcsMsrcCd' , lable:'주처리공법'},
{id:'addr' , lable:'위치(주소)'},
{id:'rprcsMthdCd' , lable:'재처리방식'},
{id:'inoutYn' , lable:'위치(처리장 내외)'},// 머가 내? 외?,
{id:'mainSplyPumpCpct' , lable:'메인공급펌프 용량'},
]
export const businessMoneyInfo: formDetailType[] = [
{ id: "gvsbs", lable: "국고", type: "number" },
{ id: "lcep", lable: "지방비", type: "number" },
{ id: "cusrAlotm", lable: "민간투자비", type: "number" },
{ id: "etc", lable: "기타" },
{ id: "totalMoney", lable: "합계", type: "number" },
];
export const businessMoneyInfo:formDetailType[]=[
{id:'gvsbs' , lable:'국고'},
{id:'lcep' , lable:'지방비'},
{id:'username' , lable:'민간투자비'},
{id:'cusrAlotm' , lable:'원인자부담금'},
{id:'etc' , lable:'기타'},
{id:'totalMoney' , lable:'합계'},
]
export const businessSttnInfo:formDetailType[]=[
{id:'seCd' , lable:'구분'},
{id:'bizMthdCd' , lable:'사업방식'},
{id:'bizCmcnDay' , lable:'사업준공일' ,type:'date'},
{id:'instlAprvSncnDt' , lable:'설치승인인가일' ,type:'date'} ,
]
export const ruseFcltIntakeList:formDetailType[]=[
{id:'seCd' , lable:'구분'},
{id:'bizMthdCd' , lable:'사업방식'},
{id:'bizCmcnDay' , lable:'사업준공일' ,type:'date'},
{id:'instlAprvSncnDt' , lable:'설치승인인가일' ,type:'date'} ,
]
export const ruseWaterQulityList:formDetailType[]=[
{id:'bod' , lable:'BOD(mg/L)'},
{id:'grssClfg' , lable:'총대장균군수(개/mg)'},
{id:'combResdch' , lable:'결합잔류염소(mh/L)'},
{id:'trbt' , lable:'탁도(NTU)'},
{id:'smll' , lable:'냄새'},
{id:'crmty' , lable:'색도'},
{id:'tn' , lable:'총질소(mg/L)'},
{id:'tph' , lable:'총인(mg/L)'},
{id:'ph' , lable:'수소이온농도'},
{id:'clIonQnt' , lable:'염화물(mg/L)'},
{id:'cdtnv' , lable:'전기전도도(μs/cm)​'},
]
export const businessSttnInfo: formDetailType[] = [
{ id: "seCd", lable: "구분" },
{ id: "bizMthdCd", lable: "사업방식" },
{ id: "bizCmcnDay", lable: "사업준공일", type: "date" },
{ id: "instlAprvSncnDt", lable: "설치승인인가일", type: "date" },
];
export const ruseFcltIntakeList: formDetailType[] = [
{ id: "seCd", lable: "구분" },
{ id: "bizMthdCd", lable: "사업방식" },
{ id: "bizCmcnDay", lable: "사업준공일", type: "date" },
{ id: "instlAprvSncnDt", lable: "설치승인인가일", type: "date" },
];
export const ruseWaterQulityList: formDetailType[] = [
{ id: "bod", lable: "BOD(mg/L)", type: "number" },
{ id: "grssClfg", lable: "총대장균군수(개/mg)", type: "number" },
{ id: "combResdch", lable: "결합잔류염소(mh/L)", type: "number" },
{ id: "trbt", lable: "탁도(NTU)", type: "number" },
{ id: "smll", lable: "냄새", type: "number" },
{ id: "crmty", lable: "색도", type: "number" },
{ id: "tn", lable: "총질소(mg/L)", type: "number" },
{ id: "tph", lable: "총인(mg/L)", type: "number" },
{ id: "ph", lable: "수소이온농도", type: "number" },
{ id: "clIonQnt", lable: "염화물(mg/L)", type: "number" },
{ id: "cdtnv", lable: "전기전도도(μs/cm)​", type: "number" },
];
@@ -1,11 +1,17 @@
import { z } from "zod";
import type { TableUpperProps } from "../rainReg";
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import {
deleteFectch,
fetchType,
getFetch,
postFectch,
} from "@/components/lib/api";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
import {
exampleData,
fcBizSchema,
type customPbnst,
type fcBizType,
type pubHasuType,
} from "./type";
import type { SelectDataType } from "@common/business_components/ui";
@@ -26,8 +32,7 @@ const pbnstOrgwtHeadList = pbnstOrgwtHeadListRxport;
const pbnstMngNm = pbnstMngNmExport;
const pplInstlsHeadLisat = pplInstlsHeadListExport;
const pbnstDemandHeadList = pbnstDemandHeadListExport;
const fcOrgwtsHeadList=fcOrgwtsHeadListExport
const fcOrgwtsHeadList = fcOrgwtsHeadListExport;
export type pubFacState = {
pbnst: {
@@ -43,14 +48,20 @@ export type pubFacState = {
pplInstlsHeadLisat: TableUpperProps[];
pbnstDemandHeadList: TableUpperProps[];
fcOrgwtsHeadList: TableUpperProps[];
pbnstMngRegData: customPbnst[];
};
};
type pubFacActions = {
pubHasuInit: (txt: string | undefined) => void;
pubHasuInit: (page:string, sggOrCity:string) => void;
pbnstRegInit: (sgg: string) => void;
pbnstRegSearch: (txt: string | undefined, sgg: string) => void;
pbnstReg: (txt: string | undefined) => void;
pbnstUpdate(pbnstRes: customPbnst) : Promise<void>;
pbnstUpdate(pbnstRes: customPbnst): Promise<void>;
fileDelete: (atflCd: string) => void;
fileDownLoad: (atflCd: string) => void;
pbnstMngData: (data: customPbnst[]) => void;
pbnstBizData(data: fcBizType): void;
};
export type pubFacType = pubFacState & pubFacActions;
@@ -69,6 +80,7 @@ export const pubFacStateExport: pubFacState = {
pplInstlsHeadLisat: pplInstlsHeadLisat,
pbnstDemandHeadList: pbnstDemandHeadList,
fcOrgwtsHeadList: fcOrgwtsHeadList,
pbnstMngRegData: [],
},
};
@@ -77,12 +89,11 @@ const checkWrRegList = async () => {
return wrRegList;
};
const hasuListFetch = async (txt: string | undefined) => {
const hasuListFetch = async (page:string, sggOrCity:string) => {
const checkWrRegListRes = await checkWrRegList();
// prcsFclt/ruseInfo/1/20/A/11/0/1/SW
const rainRes = await postFectch(
`/prcsFclt/ruseInfo/1/10/A/11` + "/0" + "/1" + "/SW",
`/prcsFclt/ruseInfo/${page?page:1}/10/A/${sggOrCity?sggOrCity:"11"}/0/1/SW`,
checkWrRegListRes,
fetchType.COMMON
);
@@ -102,24 +113,24 @@ const getBizCycle = (fcBizs: z.infer<typeof fcBizSchema>[]) => {
return {
text: `${item.cycl}차`,
val: item.cycl,
superkey: "", // Add default superkey value
};
});
return pbnstBizCycle;
};
const initFetch = async (code:string|undefined) => {
const pbnstRes =await getFetch("wr", `${code}`);
const initFetch = async (code: string | undefined) => {
const pbnstRes = await getFetch("wr", `${code}`);
return pbnstRes;
};
export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
return {
pubHasuInit: async (txt: string | undefined) => {
pubHasuInit: async (page:string, sggOrCity:string) => {
try {
const pbnstHasuRes = await hasuListFetch(txt);
const pbnstHasuRes = await hasuListFetch(page, sggOrCity);
console.log("qwe ", pbnstHasuRes);
return set((state: pubFacState) => ({
...state,
@@ -138,9 +149,10 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
try {
// const pbnstRes = await initFetch(txt);
const pbnstRes = exampleData;
const pbnstRes = [exampleData];
const pbnstBizCycle = pbnstRes ? getBizCycle(pbnstRes.fcBizs) : []; // pbnstRes가 null일 수 있으므로 체크
const pbnstBizCycle = pbnstRes && pbnstRes.length > 0 ? getBizCycle(pbnstRes[0]?.fcBizs || []) : []; // pbnstRes가 null일 수 있으므로 체크
return set((state: pubFacState) => ({
...state,
@@ -155,29 +167,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
console.log(errorHasu);
}
},
pbnstRegSearch: async (txt: string | undefined, sgg: string) => {
try {
const pbnstRes = await getFetch(
"wr",
`/api/v1/reuseFc/pubFc` + (txt ? `/${txt}` : "") + `/${sgg}`
);
// API 응답이 pbnstRegZod 타입의 단일 객체라고 가정
const pbnstBizCycle =
pbnstRes && pbnstRes.fcBizs ? getBizCycle(pbnstRes.fcBizs) : [];
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
pbnstReg: pbnstRes,
pbnstBizCycle: pbnstBizCycle,
isInit: false,
},
}));
} catch (errorHasu) {
console.log(errorHasu);
}
},
pbnstReg: async (txt: string | undefined) => {
try {
const pbnstRes = await hasuListFetch(txt);
@@ -211,17 +201,62 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
} catch (error) {
console.error("Error updating pbnst:", error);
}
},fileDelete(atflCd:string){
},
fileDelete: async (atflCd: string) => {
try {
const response = postFectch(
`/ratfl/attachments/atflCd/${atflCd}`,
null,
fetchType.COMMON
const response = await deleteFectch(
`/attach-service/api/v1/atfl/attachments/atflCd//${atflCd}`,
undefined,
fetchType.CS
);
return response;
console.log("File deleted successfully:", response);
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
isInit: false,
},
}));
} catch (error) {
console.error("Error deleting file:", error);
}
},
fileDownLoad: async (atflCd: string) => {
try {
const response = await getFetch(
fetchType.CS,
`/api/v1/atflcd/download/${atflCd}`
);
if (!response.ok) {
throw new Error(`Error downloading file: ${response.statusText}`);
}
} catch (error) {
console.error("Error downloading file:", error);
}
},
pbnstMngData: (data: customPbnst[]) => {
return set((state: pubFacState) => {
state.pbnst.pbnstMngRegData = data;
return state;
});
},
pbnstBizData:(data:fcBizType)=>{
return set((state:pubFacState)=>{
if(state.pbnst.pbnstMngRegData){
const regData = state.pbnst.pbnstMngRegData.find(item=>
data.pbnstRuseFcltFk===item.pbnstRuseFcltPk
)
if(regData){
const bizIdx = regData.fcBizs.findIndex(item=>item.pbnstRuseFcltBizPk==data.pbnstRuseFcltBizPk)
if(bizIdx>=0){
regData.fcBizs[bizIdx] = data;
}
}
}
return state;
})
}
};
};
@@ -44,140 +44,122 @@ export type fcOrgwtType = z.infer<typeof fcOrgwtSchema>;
export type ppInstlType = z.infer<typeof pplInstlSchema>;
export type operType = z.infer<typeof fcOperSchema>;
export type fcFileType = z.infer<typeof fcFileSchema>;
const pplInstlSchema = z.object({
ruseFcltBizFk: z.string(),
pdmt: z.string(),
ppMqlt: z.string(),
cpct: z.string(),
choose:z.boolean().default(false),
pdmt: z.string().default(''),
ppMqlt: z.string().default(""),
cpct: z.number().default(0),
});
const fcFileSchema = z.object({
ruseFcltFk: z.number().default(0),
fileTkn: z.string().default("test"),
filePath: z.string().default("test"),
fileKnd: z.string().default("test"),
regDt: z.date().default(new Date()),
rgtr: z.string(),
mdfcnDt: z.date().default(new Date()),
mdfr: z.string(),
ruseFcltFk: z.number().nullish(),
fileTkn: z.string(),
filePath: z.string(),
fileKnd: z.string(),
regDt: z.date().default(new Date()).nullish(),
rgtr: z.string().nullish(),
mdfcnDt: z.date().default(new Date()).nullish(),
mdfr: z.string().nullish(),
});
const fcOperSchema = z.object({
pbnstRuseFcltOperInfoPk: z.number().default(0),
pbnstRuseFcltFk: z.number().default(0),
pbnstRuseFcltOperInfoPk: z.number().nullish(),
pbnstRuseFcltFk: z.number().nullish(),
operMthd: z.string(),
rprtvBzenty: z.string(),
bgngDt: z.date().default(new Date()),
endDt: z.date().default(new Date()),
regDt: z.date().nullish(),
rgtr: z.string(),
rgtr: z.string().default(""),
mdfcnDt: z.date().nullish(),
mdfr: z.string().default("test"),
mdfr: z.string().default(""),
choose: z.boolean().default(false),
});
const fcOrgwtSchema = z.object({
pbnstRuseFcltBizFk: z.number().default(0),
swtrmtFcltFk: z.string().default(''),
orgwtWtritQnt: z.string(),
tmsYn: z.string(),
dschgFmYn: z.string(),
dtlPstnExpln: z.string(),
regDt: z.string().nullish(),
rgtr: z.string(),
mdfcnDt: z.string().nullish(),
mdfr: z.string(),
pbnstRuseFcltBizFk: z.number().nullish(),
swtrmtFcltFk: z.number().default(0),
orgwtWtritQnt: z.number(),
tmsYn: z.enum(["Y", "N"] ).default("N"),
dschgFmYn: z.enum(["Y", "N"] ).default("N"),
dtlPstnExpln: z.string().default(''),
regDt: z.date().nullish(),
rgtr: z.string().default(''),
mdfcnDt: z.date().nullish(),
mdfr: z.string().default(''),
choose: z.boolean().default(false),
});
const fcPrfmncSchema = z.object({
pbnstRuseFcltFk: z.number().default(0),
ym: z.string(),
wshwtr: z.string(),
coolUswtr: z.string(),
cleanUswtr: z.string(),
drwtUswtr: z.string(),
dltnUswtr: z.string(),
ithlRswtr: z.string(),
ithlEtcUswtr: z.string(),
cleanToilUswtr: z.string(),
resn: z.string(),
lndwtr: z.string(),
hydUswtr: z.string(),
rvrKeepUswtr: z.string(),
farmUswtr: z.string(),
ugwtChr: z.string(),
indstUswtr: z.string(),
regDt: z.date().nullish(),
rgtr: z.string(),
mdfcnDt: z.date().nullish(),
mdfr: z.string(),
});
export const fcBizSchema = z.object({
pbnstRuseFcltBizPk: z.number().default(0),
pbnstRuseFcltFk: z.number().default(0),
cycl: z.string(),
pbnstRuseFcltBizPk: z.number().default(1),
pbnstRuseFcltFk: z.number().nullish(),
superkey: z.string().default("").nullish(),
cycl: z.number(),
seCd: z.string(),
bizMthdCd: z.string(),
instlAprvSncnDt: z.string(),
bizCmcnDay: z.string(),
gvsbs: z.string(),
lcep: z.string(),
cusrAlotm: z.string(),
etc: z.string(),
totalMoney: z.string(),
rprcsFcltCpct: z.string(),
instlAprvSncnDt: z.date().nullish(),
bizCmcnDay: z.date().nullish(),
gvsbs: z.number().default(0),
lcep: z.number().default(0),
cusrAlotm: z.number().default(0),
etc: z.string().default(''),
totalMoney: z.number().default(0).nullish(),
rprcsFcltCpct: z.number(),
majorPrcsMsrcCd: z.string(),
addr: z.string(),
rprcsMthdCd: z.string(),
inoutYn: z.string(),
mainSplyPumpCpct: z.string(),
erctWtrOcrnCpct: z.string(),
erctUswtrLinkSpt: z.string(),
erctUswtrFcltCpct: z.string(),
erctUswtrPrcsMeth: z.string(),
erctUswtrPrcsMsrcCd: z.string(),
wwtEmsnFcltPrmsnYn: z.string(),
tmsInstlYn: z.string(),
pbnstDrngInflwExclYn: z.string(),
bod: z.string(),
grssClfg: z.string(),
combResdch: z.string(),
trbt: z.string(),
clIonQnt: z.string(),
smll: z.string(),
crmty: z.string(),
tph: z.string(),
tn: z.string(),
ph: z.string(),
cdtnv: z.string(),
designCst: z.string(),
cstrnSpvsCst: z.string(),
fcltSbsdCst: z.string(),
wstCst: z.string(),
cnstCmcnCst: z.string(),
mntrgEqpmntInstlCst: z.string(),
gisDbCst: z.string(),
elpwrMtrngCst: z.string(),
mchnCst: z.string(),
archCst: z.string(),
pplCst: z.string(),
ruseFcltCst: z.string(),
designCstClcln: z.string(),
cstrnSpvsCstClcln: z.string(),
fcltSbsdCstClcln: z.string(),
wstCstClcln: z.string(),
cnstCmcnCstClcln: z.string(),
mntrgEqpmntInstlCstClcln: z.string(),
gisDbCstClcln: z.string(),
elpwrMtrngCstClcln: z.string(),
mchnCstClcln: z.string(),
archCstClcln: z.string(),
pplCstClcln: z.string(),
ruseFcltCstClcln: z.string(),
inoutYn: z.enum(["Y", "N"]),
mainSplyPumpCpct: z.number().nullish(),
erctWtrOcrnCpct: z.number().nullish(),
erctUswtrLinkSpt: z.string().nullish(),
erctUswtrFcltCpct: z.number().nullish(),
erctUswtrPrcsMeth: z.string().nullish(),
erctUswtrPrcsMsrcCd: z.string().nullish(),
wwtEmsnFcltPrmsnYn: z.enum(["Y", "N"]),
tmsInstlYn: z.enum(["Y", "N"]),
pbnstDrngInflwExclYn: z.enum(["Y", "N"]),
bod: z.number(),
grssClfg: z.number(),
combResdch: z.number(),
trbt: z.number(),
clIonQnt: z.number(),
smll: z.number(),
crmty: z.number(),
tph: z.number(),
tn: z.number(),
ph: z.number(),
cdtnv: z.number(),
designCst: z.number().nullish(),
cstrnSpvsCst: z.number().nullish(),
fcltSbsdCst: z.number().nullish(),
wstCst: z.number().nullish(),
cnstCmcnCst: z.number().nullish(),
mntrgEqpmntInstlCst: z.number().nullish(),
gisDbCst: z.number().nullish(),
elpwrMtrngCst: z.number().nullish(),
mchnCst: z.number().nullish(),
archCst: z.number().nullish(),
pplCst: z.number().nullish(),
ruseFcltCst: z.number().nullish(),
designCstClcln: z.number().nullish(),
cstrnSpvsCstClcln: z.number().nullish(),
fcltSbsdCstClcln: z.number().nullish(),
wstCstClcln: z.number().nullish(),
cnstCmcnCstClcln: z.number().nullish(),
mntrgEqpmntInstlCstClcln: z.number(),
gisDbCstClcln: z.number().nullish(),
elpwrMtrngCstClcln: z.number().nullish(),
mchnCstClcln: z.number().nullish(),
archCstClcln: z.number().nullish(),
pplCstClcln: z.number().nullish(),
ruseFcltCstClcln: z.number().nullish(),
fcOrgwts: z.array(fcOrgwtSchema),
pplInstls: z.array(pplInstlSchema),
flg: z.string(),
flg: z.string().nullish(),
regDt: z.string().nullish(),
rgtr: z.string(),
mdfcnDt: z.string().nullish(),
@@ -185,12 +167,13 @@ export const fcBizSchema = z.object({
});
export const pbnstRegZod = z.object({
pbnstRuseFcltPk: z.number().default(0),
pbnstRuseFcltPk: z.number().default(1),
swtrmtFcltFk: z.string().default(""),
superkey:z.string().default(""),
ruseUtztnFcltNm: z.string().default(""),
fcltCpct: z.string().default(""),
ruseCpct: z.string().default(""),
splyExtraCpct: z.string().default(""),
fcltCpct: z.number().default(0),
ruseCpct: z.number().default(0),
splyExtraCpct: z.number().default(0),
regDt: z.date().default(new Date()),
rgtr: z.string().default("test"),
mdfcnDt: z.date().default(new Date()),
+57 -42
View File
@@ -1,69 +1,84 @@
//8880
import { DEV_URL_FO, DEV_URL_WR } from "../config/";
import { CS_URL, DEV_URL_FO, DEV_URL_WR, LOCAL_URL } from "../config/";
export const fetchType={COMMON: "common", WR: "wr"}
export const fetchType = { COMMON: "common", WR: "wr", LOCAL: "LOCAL" , CS: "CS" };
export const getFetch = async( type:string , url: string) => {
const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR
const response = await fetch( div+url , {
export const getFetch = async (type: string, url: string) => {
const div =
type === fetchType.COMMON
? DEV_URL_FO
: type === fetchType.LOCAL
? LOCAL_URL
: type === fetchType.CS
? ''
: DEV_URL_WR;
const response = await fetch(div + url, {
method: "GET",
headers: {
accept: "application/json",
accept: "application/json",
},
});
if(!response.ok) {
if (!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
const res = await response.json()
const res = await response.json();
return res.data;
}
};
export const postFectch = async (url: string, params: any , type?:string) => {
const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR
export const postFectch = async (url: string, params: any, type?: string) => {
const div = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR;
const response = await fetch(div+url, {
const response = await fetch(div + url, {
method: "POST",
headers: {
'accept': 'application/json',
accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(params),
});
if(!response.ok) {
if (!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
return await response.json();
}
};
export const putFectch = async (url: string, params: any) => {
const response = await fetch(DEV_URL_WR + url, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(params),
});
if (!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
return response;
};
const response = await fetch(DEV_URL_WR+url, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(params),
});
if(!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
return response;
}
export const deleteFectch = async (url: string, params?: any, type?: string) => {
const div =
type === fetchType.COMMON
? DEV_URL_FO
: type === fetchType.LOCAL
? LOCAL_URL
: type === fetchType.CS
? ''
: DEV_URL_WR;
export const deleteFectch = async (url: string, params: any) => {
const response = await fetch(DEV_URL_WR+url, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(params),
});
if(!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
return response;
}
console.log("deleteFectch url", div + url);
const response = await fetch(div + url, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: params?JSON.stringify(params):undefined,
});
if (!response.ok) {
throw new Error(`오류 발생: ${response.status}`);
}
return await response.text();
};
+2 -2
View File
@@ -1,5 +1,5 @@
const LOCAL_PORT = "3000";
const LOCAL_PORT = "3001";
const DEV_PORT = "11080";
const DEV_PORT_NEW="11082"
@@ -12,6 +12,6 @@ export const DEV_URL_WR = `http://con.mind-one.co.kr:${DEV_PORT}/api/v1`;
export const DEV_URL_FO = `http://con.mind-one.co.kr:${DEV_PORT_NEW}/api/v1`;
export const LOCAL_URL = `http://localhost:${LOCAL_PORT}`;
export const CS_URL= 'http://dev.onasys.co.kr:8000'
export const CS_TUS_UPLOAD= "/attach-service/api/v1/tus/upload";
@@ -13,11 +13,9 @@ import {
fcBizSchema,
type fcBizType,
type fcOrgwtType,
type ppInstlType
type ppInstlType,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import {
selectClass
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
commonButonSize,
formH1Class,
@@ -26,10 +24,7 @@ import {
import FcOrgwtsRegModal from "@/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal";
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
import { SelectBox } from "@common/business_components";
import {
UiModal,
type SelectDataType
} from "@common/business_components/ui";
import { UiModal, type SelectDataType } from "@common/business_components/ui";
import { Form } from "@common/business_components/ui/form";
import { Button, Input, Label } from "@common/components";
import { zodResolver } from "@hookform/resolvers/zod";
@@ -39,10 +34,8 @@ import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail";
export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
// const ref = useRef<ppInstlType[] | null>(data[0]?.pplInstls ?? null);
const ref = useRef<ppInstlType[] | null>(
Array.isArray(data) && data.length > 0 ? data[0]?.pplInstls ?? null : null
);
const { code, pbnst } = useWrStore((state) => state);
const ref = useRef<ppInstlType[] |null>( null);
const { code, pbnst, pbnstBizData } = useWrStore((state) => state);
const { pbnstBizCycle, pbnstRes } = pbnst;
const [getBizCycle, setBizCycle] = useState("1");
const [ppiSelectList, setPpiSelectList] =
@@ -51,8 +44,6 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
const [isFcOrgwts, setIsFcOrgwts] = useState<boolean>(false);
const [modalData, setModalData] = useState<fcOrgwtType | null>(null);
const form = useForm<fcBizType>({
resolver: zodResolver(fcBizSchema),
});
@@ -67,25 +58,51 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
name: "fcOrgwts",
});
const { fields: pplInstls, append, remove } = useFieldArray({
const {
fields: pplInstls,
append,
remove,
} = useFieldArray({
control: form.control,
name: "pplInstls",
});
useEffect(() => {
const formData = form.watch()
formData.pplInstls = ref.current? [...ref.current]:[] // ← form 내부 상태 기준으로 복사
console.log("formData pplReg", formData)
pbnstBizData(formData as fcBizType);
}, [form.formState]);
useEffect(() => {
console.log("pbnst.pbnstMngRegData ", pbnst.pbnstMngRegData);
}, [pbnst.pbnstMngRegData]);
const buttonClick = () => {
setIsFcOrgwts(true);
const moData = data[0]?.fcOrgwts;
const moData = data[0]?.fcOrgwts?.[0] ?? null;
setModalData(moData);
}
};
const plusHist = () => {
append({
const plusHist = () => {
const regData ={
ruseFcltBizFk: ref.current?.[0]?.ruseFcltBizFk??"",
choose: false,
ppMqlt: "",
pdmt: "",
cpct: "",
pdmt: '',
cpct: 0,
}
const currentTableDataFromRef = ref.current ? [...ref.current] : [];
const newDataForRHF = [...currentTableDataFromRef, regData];
form.setValue("pplInstls", newDataForRHF, {
shouldValidate: true, // 필요하다면 유효성 검사 실행
shouldDirty: true, // 폼 상태를 dirty로 변경
});
const latestOpers = form.getValues("pplInstls");
ref.current = [...latestOpers];
};
const plusArray = () => {
@@ -93,7 +110,7 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
}
const removeSelected = () => {
if(!ref.current) return;
if (!ref.current) return;
const selectedIdxs = ref.current
.map((item, idx) => (item.choose ? idx : -1))
.filter((idx) => idx !== -1);
@@ -104,12 +121,9 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
if (data) {
const index = Number(getBizCycle) - 1;
form.reset(data[index]);
ref.current = data[index]?.pplInstls ?? null;
console.log("form reset with data:", data[index]);
ref.current = data[index]?.pplInstls ?? [];
}
console.log("어휴", data)
}, [getBizCycle, data]);
useEffect(() => {
@@ -126,7 +140,6 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
}, [code]);
useEffect(() => {
console.log("ppiSelectList:", ppiSelectList);
}, [ppiSelectList]);
useEffect(() => {
@@ -135,69 +148,71 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
return (
<>
<div className=" !mx-[1.6rem] !p-0r">
{/* 차수별 등록 현황 폼 */}
<div className="justify-between">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8 mx-auto w-full mt-7"
>
<div className="flex justify-between items-center mx-3 mb-3">
<h1 className=" text-xl"></h1>
<div className="flex items-center gap-2 mx-3">
<h1 className={formTableName}>등록차수</h1>
<div className=" !mx-[1.6rem] !p-0r">
{/* 차수별 등록 현황 폼 */}
<div className="justify-between">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8 mx-auto w-full mt-7"
>
<div className="flex justify-between items-center mx-3 mb-3">
<h1 className=" text-xl"></h1>
<div className="flex items-center gap-2 mx-3">
<h1 className={formTableName}>등록차수</h1>
<SelectBox
label=""
selectArray={pbnstBizCycle}
value={getBizCycle ?? pbnstBizCycle[0]?.val}
className={""}
selectClass={selectClass}
onSelectValue={(val) => {
setBizCycle(String(val));
}}
></SelectBox>
<SelectBox
label=""
selectArray={pbnstBizCycle}
value={getBizCycle ?? pbnstBizCycle[0]?.val}
className={""}
selectClass={selectClass}
onSelectValue={(val) => {
setBizCycle(String(val));
}}
></SelectBox>
<Button type ="submit" size={commonButonSize}>저장</Button>
<Button type="submit" size={commonButonSize}>
저장
</Button>
</div>
</div>
</div>
<MngRegFormDetail
formList={businessSttnInfo}
h1Title={"사업현황"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={businessSttnInfo}
h1Title={"사업현황"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={businessMoneyInfo}
h1Title={"사업비"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={ruseFcltinfo}
h1Title={"재처리시설"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={concentratedWaterInfo}
h1Title={"농축수관리"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={wasteWaterFcltINfo}
h1Title={"폐수배출시설 정보"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={businessMoneyInfo}
h1Title={"사업비"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={ruseFcltinfo}
h1Title={"재처리시설"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={concentratedWaterInfo}
h1Title={"농축수관리"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<MngRegFormDetail
formList={wasteWaterFcltINfo}
h1Title={"폐수배출시설 정보"}
form={form}
moClass="grid grid-cols-12 gap-4"
sonClass="col-span-4"
/>
<h1 className={formH1Class}>재이용 원수취수 현황</h1>
<div>
@@ -217,9 +232,9 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
</Button>
</div>
<RuseMngTable
tableData={fcOrgwtFiled}
headList={pbnst.pbnstOrgwtHeadList}
/>
tableData={fcOrgwtFiled}
headList={pbnst.pbnstOrgwtHeadList}
upHeadList={[]} />
</div>
<h1 className={formH1Class}>재이용 공급관로 설치 현황</h1>
<div className="flex items-center gap-4 mx-3 mb-3">
@@ -257,15 +272,6 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
</Button>
</div>
<div>
<RuseMngTable
tableData={pplInstls}
headList={pbnst.pplInstlsHeadLisat}
code={ppiSelectList ?? []}
ref={ref}
upHeadList={[]} />
</div>
<MngRegFormDetail
formList={ruseWaterQulityList}
h1Title={"하수처리수 재이용시설 보증수질"}
@@ -298,7 +304,7 @@ export function PbnstBuseForm({ data }: { data: fcBizType[] }) {
open={isFcOrgwts}
onOpenChange={(open: boolean) => setIsFcOrgwts(open)}
bodyClass={"w-[50vw] max-w-none h-[60vh]"}
body={<FcOrgwtsRegModal data={ modalData || [] } onRightSet={ (val) => { console.log("val", val); return {}; }} ></FcOrgwtsRegModal>}
body={<FcOrgwtsRegModal data={modalData ? [modalData] : []} onRightSet={(val) => { console.log("val", val); return {}; }} ></FcOrgwtsRegModal>}
></UiModal>
</div>
</>
@@ -5,9 +5,10 @@ import { FileUpload, FormUi, SelectBox } from "@common/business_components/ui";
import { Form, FormField } from "@common/business_components/ui/form";
import { Button, Input } from "@common/components";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useRef, useState } from "react";
import { use, useEffect, useRef, useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import { z } from "zod";
import moment from "moment";
import {
commonButonSize,
@@ -16,37 +17,35 @@ import {
} from "@/components/lib/class/comClass";
import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr";
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
import type { Upload } from "tus-js-client";
import {
pbnstRegZod,
type customPbnst,
type fcFileType,
type operType,
type ruseFcltType,
type selectLabel,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { Label } from "@common/business_components/ui/form/lib/label";
export type FilesType = {
atflCd: String;
atflCd: string;
file: File;
};
export function PbnstMngForm({ data }: { data: customPbnst[] }) {
const { pbnst, pbnstUpdate } = useWrStore((state) => state);
const { pbnstMngUpHeadList } = pbnst;
const [ruseOperData, setRuseOperData] = useState<operType[]>();
const [planFiles, setPlanFiles] = useState<File[] | null>(null);
export function PbnstMngForm({ data }: { data: customPbnst[] }) {
const [regFileList, setRegFileList] = useState<fcFileType[] | null>(null);
const { pbnst, pbnstUpdate ,pbnstMngData, fileDelete} = useWrStore((state) => state);
const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null);
const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [fcltNm, setFcltNm] = useState<selectLabel[]>()
const [upload, setUpload] = useState<Upload | null>(null);
const [fcltNm, setFcltNm] = useState<selectLabel[] | null>(null);
const [progress, setProgress] = useState(0);
//const new File([] as BlobPart[], "") 파일 다운로드 활용
const handleProgress = (percentage: string) => {
setProgress(Number(percentage));
};
const ref = useRef<operType[] | null>(data[0]?.fcOpers ?? null);
const ref = useRef<operType[] | null>( null);
const form = useForm<z.infer<typeof pbnstRegZod>>({
resolver: zodResolver(pbnstRegZod),
defaultValues: pbnstRegZod.parse({}),
@@ -61,18 +60,38 @@ const [fcltNm, setFcltNm] = useState<selectLabel[]>()
name: "fcOpers",
});
useEffect(() => {
const formData = form.watch();
formData.fcOpers = ref.current ? [...ref.current] : [];
formData.fcFiles = regFileList ? [...regFileList] : [];
pbnstMngData([formData] as customPbnst[]);
}, [form.formState, regFileList]);
useEffect(() => {
pbnstMngData(pbnst.pbnstMngRegData);
}, [pbnst.pbnstMngRegData]);
const fileDownload = (index: number) => {};
const plusHist = () => {
append({
const regData = {
choose: false,
rgtr: "",
mdfr: "",
pbnstRuseFcltFk: 0,
pbnstRuseFcltOperInfoPk: 0,
operMthd: "",
rprtvBzenty: "",
bgngDt: new Date(),
endDt: new Date(),
};
const currentTableDataFromRef = ref.current ? [...ref.current] : [];
const newDataForRHF = [...currentTableDataFromRef, regData];
form.setValue("fcOpers", newDataForRHF, {
shouldValidate: true, // 필요하다면 유효성 검사 실행
shouldDirty: true, // 폼 상태를 dirty로 변경
});
const latestOpers = form.getValues("fcOpers");
ref.current = [...latestOpers];
};
const removeSelected = () => {
@@ -90,36 +109,48 @@ const [fcltNm, setFcltNm] = useState<selectLabel[]>()
text: item.ruseUtztnFcltNm,
val: String(index)
}))
ref.current = data[0]?.fcOpers ?? null;
setFcltNm(fcltNmList)
}, [data]);
}, [data])
useEffect(() => {
if (!fcltNm || fcltNm.length === 0) return;
// Default to the first item in data when fcltNm changes
form.reset(data[0]);
console.log("fcltNm", fcltNm)
}, [fcltNm, data]);
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof pbnstRegZod>) {
console.log("submit", values);
// pbnstUpdate(values);
values.fcOpers = ref.current || [];
values.fcFiles = regFileList || [];
console.log("form values:", values);
pbnstUpdate(values);
}
const fileHandler = (files: File[]) => {
console.log('fileHandler', files);
let setReFiles = [...(relationfiles || [])];
if (files && (!relationfiles || relationfiles.length < files.length)) {
const fileHandler = (files: File[], type: string) => {
let fileList = [] as FilesType[];
if (type === "relation" && relationfiles) {
fileList = relationfiles;
} else if (type === "plan" && planFiles) {
fileList = planFiles;
}
let setReFiles = [...(fileList || [])];
if (files && (!fileList || fileList.length < files.length)) {
files.find((item) => {
if (
!relationfiles ||
relationfiles?.findIndex((reFile) => reFile.file === item) < 0
!fileList ||
fileList?.findIndex((reFile) => reFile.file === item) < 0
) {
TusClientUpload({ atflCd: "", file: item })
.then((tusFile) => {
setReFiles.push({ atflCd: tusFile.atflCd, file: item });
console.log("after async setReFiles", setReFiles);
setRelationFiles(setReFiles);
setReFiles.push({
atflCd: tusFile.atflCd.toString(),
file: item,
});
type === "relation"
? setRelationFiles(setReFiles)
: setPlanFiles(setReFiles);
})
.catch((e) => {
console.log(e);
@@ -127,50 +158,54 @@ useEffect(() => {
return item;
}
});
} else if (
relationfiles &&
(!files || relationfiles.length > files.length)
) {
} else if (fileList && (!files || fileList.length > files.length)) {
if (!files) {
//TODO: 파일삭제
fileList.forEach((file) => {
fileDelete(file.atflCd as string);
});
setReFiles = [];
setReFiles.length = 0;
} else {
//TODO: 파일삭제
relationfiles?.forEach((item, index) => {
fileList?.forEach((item, index) => {
const idx = files?.indexOf(item.file);
if (idx < 0) {
setReFiles.slice(index);
setReFiles.splice(index);
fileDelete(item.atflCd as string);
}
});
}
setRelationFiles(setReFiles)
type === "relation"
? setRelationFiles(setReFiles)
: setPlanFiles(setReFiles);
}
};
useEffect(() => {
console.log("relationfiles changed:", relationfiles);
}, [relationfiles]);
const regFileFilter = (
files: FilesType[],
fileKnd: string,
regFile: fcFileType[]
) => {
const planDatas = regFile?.filter((item) => item.fileKnd !== fileKnd) || [];
const data = files.map((item) => ({
fileTkn: item.atflCd,
filePath: item.file.name,
fileKnd: fileKnd,
rgtr: TEST_UUID,
mdfr: TEST_UUID,
}));
return [...planDatas, ...data];
}
useEffect(() => {
if (relationfiles) {
setRegFileList(regFileFilter(relationfiles, "계통도", regFileList || []));
}
}, [relationfiles]);
useEffect(() => {
if (planFiles) {
setRegFileList(regFileFilter(planFiles, "평면도", regFileList || []));
}
}, [planFiles]);
const testFile = () => {
// if (relationfiles && relationfiles[0])
// TusClientUpload(relationfiles[0], setUpload, {
// handleUploadStart: () => {
// console.log("handleUploadStart");
// },
// handleProgress,
// handleResponse: (req, res) => {
// console.log("handleResponse req", req);
// console.log("handleResponse res", res);
// },
// handleSuccess: (a) => {
// console.log("req", a);
// },
// });
};
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
@@ -182,14 +217,6 @@ useEffect(() => {
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className="flex justify-between items-center mx-3 mb-3">
<div className="col-span-2 flex items-top">
{/* <h2 className={formTableName + "pr-3 col-span-10 "}>
재이용 시설명
</h2> */}
{/* <span className="mt-4 ml-2">
{form.getValues("ruseUtztnFcltNm")
? ": " + form.getValues("ruseUtztnFcltNm")
: ""}
</span> */}
<Label className={formTableName + "pr-3 col-span-2 "}>재이용 시설명</Label>
<SelectBox
label=""
@@ -249,7 +276,9 @@ useEffect(() => {
<Input
placeholder=""
type="number"
onChange={field.onChange}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value}
/>
</FormUi>
@@ -265,7 +294,9 @@ useEffect(() => {
<Input
placeholder=""
type="number"
onChange={field.onChange}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value}
/>
</FormUi>
@@ -281,7 +312,9 @@ useEffect(() => {
<Input
placeholder=""
type="number"
onChange={field.onChange}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value}
/>
</FormUi>
@@ -297,7 +330,9 @@ useEffect(() => {
<Input
placeholder=""
type="number"
onChange={field.onChange}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value}
/>
</FormUi>
@@ -310,36 +345,27 @@ useEffect(() => {
</div>
<div className="grid grid-cols-12 gap-4 my-4">
<div className="col-span-6">
<FormField
control={form.control}
name="psysScdg"
render={({}) => (
<FormUi label="계통도">
<FileUpload
files={relationfiles?.map((item) => item.file) || []}
setFiles={(files: File[] | null) => {
if (files) fileHandler(files);
}}
fileTypes="PDF"
></FileUpload>
</FormUi>
)}
/>
<FormUi label="계통도">
<FileUpload
files={relationfiles?.map((item) => item.file) || []}
setFiles={(files: File[] | null) => {
if (files) fileHandler(files, "relation");
}}
fileTypes="PDF"
onFileClick={(index) => {}}
></FileUpload>
</FormUi>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="designScdg"
render={({}) => (
<FormUi label="평면도">
<FileUpload
files={planFiles || []}
setFiles={setPlanFiles}
fileTypes="PDF"
></FileUpload>
</FormUi>
)}
/>
<FormUi label="평면도">
<FileUpload
files={planFiles?.map((item) => item.file) || []}
setFiles={(files: File[] | null) => {
if (files) fileHandler(files, "plan");
}}
fileTypes="PDF"
></FileUpload>
</FormUi>
</div>
</div>
</div>
@@ -45,7 +45,7 @@ export default function MngRegFormDetail({
className={"rounded-lg !w-full"}
/>
) : item.type === "number" ? (
<Input placeholder="" type="number" value={field.value??0} onChange={field.onChange} />
<Input placeholder="" type="number" value={field.value??0} onChange={(e) =>{field.onChange(Number(e.target.value))}} />
) : (
<Input placeholder="" type="text" value={field.value??''} onChange={field.onChange} />
)}
@@ -1,58 +1,98 @@
"use client";
import { useWrStore } from "@/app/store";
import type { customPbnst, fcBizType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type {
customPbnst,
fcBizType,
pubHasuType,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { getCity } from "@/components/lib/func/commom";
import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
import { ScrollArea, SelectBox, UiTable, type SelectDataType } from "@common/business_components";
import { Button, Input, Label, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components/ui";
import {
ScrollArea,
} from "@common/business_components";
import {
Button,
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@common/components/ui";
import { useEffect, useState } from "react";
import type { objSearchType } from "../bdstRegModal/bdstRegModal";
import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm";
export function PbnstRegModal({ data }: { data: customPbnst }) {
const { code, pbnst } = useWrStore((state) => {
export function PbnstRegModal({ data }: { data: pubHasuType }) {
const { pbnst ,pbnstUpdate} = useWrStore((state) => {
return state;
});
const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst;
const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>({} as customPbnst);
const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>(
{} as customPbnst
);
const [currentTab, setCurrentTab] = useState<string>("mng");
// const nodeList = headMakeColSpan(pubFacHeadList.moUpHeadList);
const pbnstRegTotal = ()=>{
console.log(" pbnst.pbnstMngRegData ", pbnst.pbnstMngRegData)
if(pbnst.pbnstMngRegData[0])
pbnstUpdate(pbnst.pbnstMngRegData[0])
}
const handleTabChange = (value: string) => {
setCurrentTab(value);
};
useEffect(() => {
if (!data) return;
console.log("데이터", data)
if(data ){
let regData = {
superKey: String(data.bscFctCd + "1"),
swtrmtFcltFk: String(data.bscFctCd ),
pbnstRuseFcltPk: 1,
fcBizs: [{ pbnstRuseFcltFk: 1 ,cycl:1 } as unknown as fcBizType],
};
setPbnstBdstForm(regData as unknown as customPbnst);
}
}, [data]);
useEffect(() =>{
console.log('pbnst.pbnstMngRegData ', pbnst.pbnstMngRegData)
},[pbnst.pbnstMngRegData])
return (
<>
<h1 className="text-2xl font-medium text-label pl-8">하수재이용 시설 신규등록</h1>
<h1 className="text-2xl font-medium text-label pl-8">
하수재이용 시설 신규등록
</h1>
<div className="border-t border-gray-300 my-4"></div>
<ScrollArea className="h-[75vh]">
<Tabs defaultValue="mng" onValueChange={handleTabChange}>
<TabsList className="">
<TabsTrigger className="!text-xl" value="mng">시설정보</TabsTrigger>
<TabsTrigger className="!text-xl" value="buse">차수별정보</TabsTrigger>
<TabsTrigger className="!text-xl" value="mng">
시설정보
</TabsTrigger>
<TabsTrigger className="!text-xl" value="buse">
차수별정보
</TabsTrigger>
<Button onClick={pbnstRegTotal} size={"sm"} className="!justify-end">
저장
</Button>
</TabsList>
<TabsContent className="max-h-full" value="mng">
<PbnstMngForm mngForm={pbnstBdstForm as customPbnst} isModal={true} />
<PbnstMngForm data={pbnstBdstForm} />
</TabsContent>
<TabsContent className="max-h-full" value="buse">
<PbnstBuseForm buseForm={pbnstBdstForm as customPbnst} isModal={true} />
<PbnstBuseForm data={pbnstBdstForm.fcBizs} />
</TabsContent>
</Tabs>
</ScrollArea>
</>
)
);
}
@@ -32,13 +32,13 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>(
}, ref) => {
const [tableState, setTableState] = useState([...tableData]);
useEffect(() => {
console.log("tableState", tableState);
if (ref && typeof ref === "object" && "current" in ref) {
ref.current = tableState;
}
}, [tableState]);
useEffect(() => {
if(tableData)
setTableState(tableData);
}, [tableData]);
return (
@@ -78,7 +78,9 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>(
return next;
})
}}
value={tableState[i][head.id] || ""}
value={head.type === "number" ?
Number(tableState[i][head.id])||0 : tableState[i][head.id] || ""
}
/>
) : head.type === "select" ? (
<SelectBox
@@ -126,7 +128,8 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>(
}}
>
</Checkbox>
) : (
) :
(
`${item[head.id] || ""}`
)}
</TableCell>
+1 -1
View File
@@ -21,7 +21,7 @@ export function middleware(req: NextRequest) {
if (pathname.startsWith("/attach-service")) {
const requestHeaders = new Headers(req.headers);
const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDgzOTk3ODl9.wbYXSIFNSvVJKyofFW0C3Yg99AZ99oLYSCMjcoRvZB6DqfxCbqxHPxUgwWyFE6oHJWYrX6q4BvMY2TdVOtzxnA"
const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJleHAiOjE3NDg0Mzc0OTF9.JM2NHEwTpgDW9nonZY3186IK_frIh667SyxMQfPwqa_lc-5mcTFNtrWXH5b72_ng39qiPSi504iF1roFEJ0c6w"
const userId = 'a0ec7a07-752a-4f7f-89a6-854e63d2e3a0'
//const token = req.cookies.get(CLAIM_NAME)?.value;
//const userId = req.cookies.get(AUTH_USER_ID)?.value;
@@ -64,10 +64,10 @@ const CustomLegend = (props: any) => {
const { payload } = props;
return (
<div style={customStyles.legendContainer}>
{payload.map((entry, index: number) => (
{payload.map((entry: unknown, index: number) => (
<div key={`legend-${index}`} className="flex items-center gap-2">
<div className="w-[14px] h-[14px] ml-10" style={{ backgroundColor: entry.color }}></div>
<span className="text-[12px]">{entry.value}</span>
<div className="w-[14px] h-[14px] ml-10" style={{ backgroundColor: (entry as {color: string}).color }}></div>
<span className="text-[12px]">{(entry as {value: string}).value}</span>
</div>
))}
</div>
@@ -76,7 +76,15 @@ const CustomLegend = (props: any) => {
export default function Chart({chartConfig=undefined, chartData=[], chartTitle='차트', chartClassName='w-full h-full', graphSize=40, yFieldText='', showLegend=false} : BarChartProps) {
const colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEEAD", "#D4A5A5"];
const getMaxValue = (data: any[], keyPrefix: string) => {
return Math.max(...data.map(item =>
Object.keys(item)
.filter(key => key.includes(keyPrefix))
.map(key => item[key])
).flat());
};
const barMaxValue = getMaxValue(chartData, 'barVal');
return (
<>
{chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? (
@@ -102,7 +110,8 @@ export default function Chart({chartConfig=undefined, chartData=[], chartTitle='
axisLine={true}
fontSize={12}
fontWeight={500}
label={yFieldText ? { value: yFieldText, className:"text-[13px] foont-bold", position: 'top', textAnchor: 'middle', offset: 20 } : undefined}
domain={[0, Math.ceil(barMaxValue * 1)]}
label={yFieldText ? { value: yFieldText, className:"text-[13px] font-bold", position: 'insideLeft', angle: -90, offset: 20 } : undefined}
/>
<ChartTooltip cursor={false} content={<CustomTooltip active={undefined} payload={undefined} label={undefined} />}/>
{chartData && chartData.length > 0 && (
@@ -113,20 +113,21 @@ export default function Linechart({
}, []);
// 데이터의 최대값 계산
const getMaxValue = (data: ChartDataType, keyPrefix: string) => {
return Math.max(...Object.values(data).map(item =>
Object.keys(item)
.filter(key => key.includes(keyPrefix))
.map(key => item[key] as unknown as number)
).flat());
const getMaxValue = (data: ChartDataType): number => {
return Math.max(...Object.values(data).flatMap(dataset =>
dataset.map(entry => {
const val = parseFloat(entry.val);
return isNaN(val) ? 0 : val;
})
));
};
const lineMaxValue = getMaxValue(chartData, 'lineVal');
const lineMaxValue = getMaxValue(chartData);
return (
<div className={chartClassName}>
{chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? (
<div style={{ textAlign: "left", fontSize: "13px", fontWeight: "bold", marginTop:"13px", marginBottom: "10px" }}>
<div className="text-left text-[13px] font-bold mt-[13px] mb-[10px]">
{chartTitle}
</div>
) : null}
@@ -1,5 +1,6 @@
import type { sheetParameter } from '@/index';
// import type { sheetParameter } from '@/index';
import * as XlsxPopulate from '@xlsx/xlsx-populate';
import type { SheetParameter } from './index';
@@ -38,13 +39,13 @@ export const excelStyle = async (data: ArrayBuffer, range: string = "A1:V3", fil
}
export const excelArrayStyle = async (data: ArrayBuffer, range: [typeof sheetParameter], fileNm:string) => {
export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[], fileNm: string) => {
const workbook = await XlsxPopulate.Workbook.fromData(data);
if(range){
range.forEach((item , index)=>{
if (range) {
range.forEach((item, index) => {
const rangeCells = workbook.activeSheet(index)?.sheet(index)?.range(item.headerRange);
console.log(rangeCells);
rangeCells?.style((styleQ)=>{
rangeCells?.style((styleQ) => {
makeCellStyle(styleQ)
});
@@ -5,7 +5,7 @@ type ExcelDownloadProps = {
data: JSON | JSON[];
fileName: string;
sheetNameArray: string[];
headerRange: string;
headerRange?: string;
}
export const downloadExcel = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3'}: ExcelDownloadProps) => {
@@ -15,17 +15,21 @@ export const downloadExcel = ({ data, fileName = new Date().getTime().toString()
excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName);
};
export const sheetParameter ={
data:[[]], headerNum:0, headerRange:'A1:V3', sheetName:'Sheet1', startCol:0
}
export type SheetParameter = {
data: any[][];
headerNum: number;
headerRange: string;
sheetName: string;
startCol?: string;
};
export const downloadMultipleExcel = (fileName = new Date().getTime().toString() + '.xlsx', sheetArray: Array<typeof sheetParameter>): Promise<JSON | undefined> => {
export const downloadMultipleExcel = (fileName = new Date().getTime().toString() + '.xlsx', sheetArray: SheetParameter[]): Promise<JSON | undefined> => {
const workbook = XLSX.utils.book_new();
for (let i = 0; i < sheetArray.length; i++) {
// Create a new worksheet for each sheet
const worksheet = XLSX.utils.aoa_to_sheet(sheetArray[i]?.data || [[]]);
// Add data to the worksheet starting from the specified header number
if (sheetArray&&sheetArray[i]?.headerNum) {
if (sheetArray && sheetArray[i]?.headerNum) {
XLSX.utils.sheet_add_aoa(worksheet, sheetArray[i]?.data || [[]], { origin: `A${sheetArray[i]?.headerNum}` });
}
// Append the worksheet to the workbook with the specified sheet name
@@ -37,7 +41,6 @@ export const downloadMultipleExcel = (fileName = new Date().getTime().toString()
return Promise.resolve(undefined);
};
export const filePicked=(oFile: File, headerNum:number=0, dateType="yyyymmdd"):Promise<JSON | undefined> =>{
// Create A File Reader HTML5
const reader = new FileReader();
@@ -80,8 +83,6 @@ export const filePicked=(oFile: File, headerNum:number=0, dateType="yyyymmdd"):P
});
}
export const filePickedArray=(oFile: File, headerNum:number=0):Promise<JSON[] | undefined> =>{
// Create A File Reader HTML5
const reader = new FileReader();
@@ -123,8 +124,6 @@ export const filePickedArray=(oFile: File, headerNum:number=0):Promise<JSON[] |
});
}
export const filePickedBlob=(oFile: ArrayBuffer, data:[][],fileNm:string, headerNum:number=0, headerRange='A1:V3', startCol?:number):Promise<JSON | undefined> =>{ // Create A File Reader HTML5
return new Promise<JSON | undefined>(() => {
// Ready The Event For When A File Gets Selected
@@ -149,28 +148,20 @@ export const filePickedBlob=(oFile: ArrayBuffer, data:[][],fileNm:string, header
});
}
export const filePickedBlobArray= (oFile: ArrayBuffer,fileNm:string, sheetArray: [typeof sheetParameter]):Promise<JSON | undefined> =>{ // Create A File Reader HTML5
return new Promise<JSON | undefined> (async () => {
// Ready The Event For When A File Gets Selected
const wb = XLSX.read(oFile, { type: 'binary' });
// Loop Over Each Sheet
wb.SheetNames.forEach( function (sheetName, index) {
// Obtain The Current Row As CSV
if(sheetArray[index]){
const sheet = wb.Sheets[sheetName];
if (sheet) {
//오리진 확인 test 필요
// const sheet = XLSX.utils.json_to_sheet(data);
const startCol = sheetArray[index].startCol?sheetArray[index].startCol.toString():'A';
XLSX.utils.sheet_add_aoa(sheet, sheetArray[index].data, { origin: startCol+sheetArray[index].headerNum });
// XLSX.utils.book_append_sheet(wb, sheet, 'test');
} else {
console.error(`Sheet "${sheetName}" is undefined.`);
}
}
});
await excelArrayStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), sheetArray, fileNm)
});
}
export const filePickedBlobArray = (oFile: ArrayBuffer, fileNm: string, sheetArray: SheetParameter[]): Promise<JSON | undefined> => {
return new Promise<JSON | undefined>(async () => {
const wb = XLSX.read(oFile, { type: 'binary' });
wb.SheetNames.forEach(function (sheetName, index) {
if (sheetArray[index]) {
const sheet = wb.Sheets[sheetName];
if (sheet) {
const startCol = sheetArray[index].startCol ? sheetArray[index].startCol : 'A';
XLSX.utils.sheet_add_aoa(sheet, sheetArray[index].data, { origin: startCol + sheetArray[index].headerNum });
} else {
console.error(`Sheet "${sheetName}" is undefined.`);
}
}
});
await excelArrayStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), sheetArray, fileNm)
});
}
@@ -12,10 +12,12 @@ const dropZoneConfig = {
files: File[]; // 파일 배열
setFiles: (files: File[] | null) => void; // 파일 배열 세터
fileTypes?: string; // 옵션 (파일 확장자 문자열)
onFileClick?:(index:number)=> void; // 파일 클릭 핸들러
}
export const FileUpload =
({ files, setFiles, fileTypes }: FileUploadProps) => {
({ files, setFiles, fileTypes ,onFileClick}: FileUploadProps) => {
return (
<FileUploader
value={files}
@@ -43,9 +45,9 @@ export const FileUpload =
{files&&
files.length > 0 &&
files.map((file:File, i:number) => (
<FileUploaderItem key={i} index={i}>
<FileUploaderItem key={i} index={i} onFileClick={onFileClick }>
<Paperclip className="h-4 w-4 stroke-current" />
<span className="w-4/5 overflow-hidden">{file.name}</span>
<span className="w-4/5 overflow-hidden">{file.name}</span>
</FileUploaderItem>
))}
</FileUploaderContent>
@@ -286,9 +286,9 @@ FileUploaderContent.displayName = "FileUploaderContent";
export const FileUploaderItem = forwardRef<
HTMLDivElement,
{ index: number } & React.HTMLAttributes<HTMLDivElement>
>(({ className, index, children, ...props }, ref) => {
const { removeFileFromSet, activeIndex, direction } = useFileUpload();
{ index: number } & React.HTMLAttributes<HTMLDivElement> &{onFileClick?:(index:number)=>void}
>(({ className, index, children, onFileClick, ...props }, ref) => {
const { removeFileFromSet , activeIndex, direction } = useFileUpload();
const isSelected = index === activeIndex;
return (
<div
@@ -300,11 +300,13 @@ export const FileUploaderItem = forwardRef<
isSelected ? "bg-muted" : "",
)}
{...props}
onClick={() =>{
console.log('onclick');
removeFileFromSet(index)}}
>
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full !w-4/5 overflow-hidden ">
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full !w-4/5 overflow-hidden "
onClick={() =>{
}}>
{children}
</div>
<button
@@ -313,7 +315,10 @@ export const FileUploaderItem = forwardRef<
"absolute",
"!w-1/5 z-50",
direction === "rtl" ? "top-1 left-1" : "top-1 right-1",
)}
onClick={() =>{
removeFileFromSet(index)}}
>
<span className="sr-only">remove item {index}</span>
<RemoveIcon className="w-4 h-4 hover:stroke-destructive duration-200 ease-in-out" />
@@ -1,3 +1,5 @@
"use client"
import { Button } from "@common/components/ui";
import { useCallback, useEffect, useState } from "react";
import { SearchFormLeft, type EnvPartSelectDataType } from "../search_form_left";
@@ -1,4 +1,6 @@
import React, { useEffect, useState } from 'react';
"use client"
import React, { useEffect, useState } from 'react';
import type { SelectDataType } from '../search_input_select';
import { SelectBox } from '../select';
@@ -6,37 +6,41 @@ interface TabItem {
label: string;
}
interface UITabProps extends React.HTMLAttributes<HTMLDivElement> {
interface UITabProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'dir'> {
defaultValue?: string;
tabList: TabItem[];
children: React.ReactNode;
onValueChange?: (value: string) => void;
}
const UITab = React.forwardRef<
const UITab = React.forwardRef<
HTMLDivElement,
UITabProps
>(({defaultValue, tabList, children, onValueChange, ...props}, ref)=>{
return (
<Tabs
defaultValue={defaultValue || tabList[0]?.value}
className={"w-full space-x-1 border-b border-gray-200"}
onValueChange={onValueChange}
{...props}
>
<TabsList className="flex space-x-1">
{tabList.map((tab) => (
<TabsTrigger
key={tab.value}
value={tab.value}
className="py-2 px-4 text-sm font-medium border-b-2 focus:outline-none data-[state=active]:border-blue-500 data-[state=active]:text-blue-600 data-[state=inactive]:border-transparent data-[state=inactive]:text-gray-500 hover:text-gray-700 hover:border-gray-300"
>
{tab.label}
</TabsTrigger>
))}
</TabsList>
{children}
</Tabs>
)
})
>(({defaultValue, tabList, children, onValueChange, ...props}, ref) => {
return (
<Tabs
defaultValue={defaultValue || tabList[0]?.value}
className={"w-full space-x-1 border-b border-gray-200"}
onValueChange={onValueChange}
ref={ref}
{...props}
>
<TabsList className="flex space-x-1">
{tabList.map((tab) => (
<TabsTrigger
key={tab.value}
value={tab.value}
className="py-2 px-4 text-sm font-medium border-b-2 focus:outline-none data-[state=active]:border-blue-500 data-[state=active]:text-blue-600 data-[state=inactive]:border-transparent data-[state=inactive]:text-gray-500 hover:text-gray-700 hover:border-gray-300"
>
{tab.label}
</TabsTrigger>
))}
</TabsList>
{children}
</Tabs>
);
});
UITab.displayName = 'UITab';
export { UITab };
@@ -1,3 +1,5 @@
"use client"
import { Table, TableBody, TableCell, TableHeader, TableRow } from "@common/components";
import { useEffect, useState } from "react";
import { HeadMakeColSpan } from "./HeadMakeColSpan";
@@ -8,7 +8,7 @@ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav
role="navigation"
aria-label="pagination"
className={cn("mx-auto flex w-full justify-center", className)}
className={cn("mx-auto flex w-full justify-center text-lg mt-2", className)}
{...props}
/>
)
@@ -42,7 +42,7 @@ type PaginationLinkProps = {
const PaginationLink = ({
className,
isActive,
size = "icon",
size = "default",
...props
}: PaginationLinkProps) => (
<a
@@ -52,6 +52,7 @@ const PaginationLink = ({
variant: isActive ? "outline" : "ghost",
size,
}),
"px-4 py-2 text-lg",
className
)}
{...props}
@@ -66,10 +67,10 @@ const PaginationPrevious = ({
<PaginationLink
aria-label="Go to previous page"
size="default"
className={cn("gap-1 pl-2.5", className)}
className={cn("gap-2 pl-4 text-lg", className)}
{...props}
>
<ChevronLeft className="h-4 w-4" />
<ChevronLeft className="h-6 w-6" />
<span>Previous</span>
</PaginationLink>
)
@@ -82,11 +83,11 @@ const PaginationNext = ({
<PaginationLink
aria-label="Go to next page"
size="default"
className={cn("gap-1 pr-2.5", className)}
className={cn("gap-2 pr-4 text-lg", className)}
{...props}
>
<span>Next</span>
<ChevronRight className="h-4 w-4" />
<ChevronRight className="h-6 w-6" />
</PaginationLink>
)
PaginationNext.displayName = "PaginationNext"
@@ -97,10 +98,10 @@ const PaginationEllipsis = ({
}: React.ComponentProps<"span">) => (
<span
aria-hidden
className={cn("flex h-9 w-9 items-center justify-center", className)}
className={cn("flex h-12 w-12 items-center justify-center text-lg", className)}
{...props}
>
<MoreHorizontal className="h-4 w-4" />
<MoreHorizontal className="h-6 w-6" />
<span className="sr-only">More pages</span>
</span>
)