Merge commit '374336f0b9dab143a31fa7815b7cc44572498c03' into iipbs/wr/dev
iipbs_wr / build (push) Has been cancelled
iipbs_wr / build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,409 @@
|
||||
"use client";
|
||||
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { 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 ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Button, DatePicker, Input, Label } from "@common/components/ui";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
export default function coMatRvw() {
|
||||
const { code, coRvw, } = useWrStore((state) => state);
|
||||
const { coRvwHeadList, } = coRvw;
|
||||
const [fromDate, setFromDate] = useState<Date>(new Date());
|
||||
const [toDate, setToDate] = useState<Date>(new Date());
|
||||
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
|
||||
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
|
||||
|
||||
|
||||
const schema = z.object({
|
||||
fcltCpct: z.number().optional(),
|
||||
});
|
||||
|
||||
const form = useForm<z.infer<typeof schema>>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
fcltCpct: 0,
|
||||
}
|
||||
});
|
||||
|
||||
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) })
|
||||
};
|
||||
|
||||
const {
|
||||
fields: [],
|
||||
append,
|
||||
remove,
|
||||
} = useFieldArray({
|
||||
control: form.control,
|
||||
name: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (fromDate > toDate) {
|
||||
const newFromDate = new Date(toDate);
|
||||
newFromDate.setDate(toDate.getDate() - 1);
|
||||
setFromDate(newFromDate);
|
||||
}
|
||||
}, [toDate]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"수요매칭검토"} />
|
||||
<SearchDiv>
|
||||
<SearchFormLeft>
|
||||
<div className="col-span-8 flex flex-row">
|
||||
<SelectBox
|
||||
className="col-span-2 w-1/3 h-full text-2xl"
|
||||
label="시도"
|
||||
selectClass={""}
|
||||
selectArray={code.cityCd || []}
|
||||
onSelectValue={getSelCity}
|
||||
/>
|
||||
<SelectBox
|
||||
className="col-span-2 w-1/3 h-full text-2xl"
|
||||
label="시군구"
|
||||
selectClass={""}
|
||||
selectArray={selectSgg || []}
|
||||
onSelectValue={getSgg}
|
||||
/>
|
||||
<div className="col-span-5 w-full">
|
||||
<div className="flex flex-row items-center">
|
||||
<Label className="text-xl text-gray-600">수요신청년도</Label>
|
||||
<div className="flex flex-row">
|
||||
<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>
|
||||
<SearchInput
|
||||
className={"text-2xl"}
|
||||
label="회사명"
|
||||
textValue={""}
|
||||
setText={(e) => {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SearchFormLeft>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</SearchFormRight>
|
||||
</SearchDiv>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-6 gap-4 ">
|
||||
<div className="col-span-6">
|
||||
<ListDiv>
|
||||
<UiTable
|
||||
headName={"수요매칭검토현황"}
|
||||
tableData={[]}
|
||||
children={undefined}
|
||||
headlist={coRvwHeadList}
|
||||
pageSize={20}
|
||||
total={100000}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
}}
|
||||
onPageChange={() => { }}
|
||||
></UiTable>
|
||||
<hr />
|
||||
<Form {...form}>
|
||||
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">표준공사비 산정</h3>
|
||||
<div className="flex items-center mx-3 mb-3">
|
||||
<h1 className="">처리시설 표준공사비 산정</h1>
|
||||
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
계산
|
||||
</Button>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
저장
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 ml-4 mr-4">
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="용도">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="요구수량(M3/d)">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.1"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<Label className="">용도에 따른 처리공정<i className="diveicon di-search" /></Label>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value || ""}
|
||||
className="mt-2"
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="처리시설 용량(요구수량 * 365일)">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.001"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>처리시설용량에 따른 공사비(백만원)</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
className="bg-none"
|
||||
>
|
||||
공사비 산정표 보기
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.001"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>시설부대경비 요율(%)</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
요율표 보기
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.01"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="col-span-3 mt-4">
|
||||
<Label>총사업비 (백만원)<i className="diveicon di-search" /></Label>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
className="mt-2"
|
||||
type="number"
|
||||
step="0.01"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>공급처 선정</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
className="bg-none"
|
||||
>
|
||||
후보지 선택
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="col-span-4 mt-4">
|
||||
<div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="공급관로 표준공사비(백만원)">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
step="0.001"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<Label>관로 표준공사비 산정 프로그램</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
className="bg-none"
|
||||
>
|
||||
다운로드
|
||||
</Button>
|
||||
</div>
|
||||
<div className="col-span-4 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<Label className="text-xl">처리시설 + 공급관로 총사업비(백만원)
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
step="0.001"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
readOnly={true}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
</Label>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</ListDiv>
|
||||
</div>
|
||||
</div>
|
||||
</ContentsDiv >
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
"use client";
|
||||
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { 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 ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Button, DatePicker, Input, Label } from "@common/components/ui";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
export default function ruseRvwHstry() {
|
||||
const { code, ruseHstry, } = useWrStore((state) => state);
|
||||
const { ruseHstryHeadList, } = ruseHstry;
|
||||
const [fromDate, setFromDate] = useState<Date>(new Date());
|
||||
const [toDate, setToDate] = useState<Date>(new Date());
|
||||
const schema = z.object({});
|
||||
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
|
||||
const [objSearch, setObjSearch] = useState<objSearchType>({ 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) })
|
||||
};
|
||||
|
||||
const form = useForm<z.infer<typeof schema>>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
fcltCpct: 0,
|
||||
}
|
||||
});
|
||||
|
||||
const {
|
||||
fields: [],
|
||||
append,
|
||||
remove,
|
||||
} = useFieldArray({
|
||||
control: form.control,
|
||||
name: "",
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"재이용검토이력"} />
|
||||
<SearchDiv>
|
||||
<SearchFormLeft>
|
||||
<div className="col-span-8 flex flex-row">
|
||||
<SelectBox
|
||||
className="col-span-2 w-1/3 h-full text-2xl"
|
||||
label="시도"
|
||||
selectClass={""}
|
||||
selectArray={code.cityCd || []}
|
||||
onSelectValue={getSelCity}
|
||||
>
|
||||
{""}
|
||||
</SelectBox>
|
||||
<SelectBox
|
||||
className="col-span-2 w-1/3 h-full text-2xl"
|
||||
label="시군구"
|
||||
selectClass={""}
|
||||
selectArray={selectSgg || []}
|
||||
onSelectValue={getSgg}
|
||||
>
|
||||
{""}
|
||||
</SelectBox>
|
||||
<div className="col-span-5 w-full">
|
||||
<div className="flex flex-row items-center">
|
||||
<Label className="text-xl text-gray-600">수요신청년도</Label>
|
||||
<div className="flex flex-row">
|
||||
<DatePicker mode={'single'}
|
||||
className="w-full"
|
||||
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>
|
||||
<SearchInput
|
||||
className={"text-2xl"}
|
||||
label="시설명"
|
||||
textValue={""}
|
||||
setText={(e) => {
|
||||
}}
|
||||
/>
|
||||
<SearchInput
|
||||
className={"text-2xl"}
|
||||
label="회사명"
|
||||
textValue={""}
|
||||
setText={(e) => {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SearchFormLeft>
|
||||
<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>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
검토완료
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SearchFormRight>
|
||||
</SearchDiv>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-6 gap-4 ">
|
||||
<div className="col-span-6">
|
||||
<ListDiv>
|
||||
<UiTable
|
||||
headName={"재이용검토현황"}
|
||||
tableData={[]}
|
||||
children={undefined}
|
||||
headlist={ruseHstryHeadList}
|
||||
pageSize={20}
|
||||
total={100000}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
}}
|
||||
onPageChange={() => { }}
|
||||
></UiTable>
|
||||
<hr />
|
||||
<Form {...form}>
|
||||
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">수요신청 상세현황</h3>
|
||||
<h1 className="mt-1 ml-3">표준공사비 산정</h1>
|
||||
<div className="flex items-center mx-3 mb-3">
|
||||
<h1 className="">처리시설 표준공사비 산정</h1>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
재계산
|
||||
</Button>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
저장
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
<div className="grid grid-cols-12 gap-4 ml-4 mr-4">
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="용도">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="요구수량(M3/d)">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.1"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<Label className="">용도에 따른 처리공정<i className="diveicon di-search" /></Label>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value || ""}
|
||||
className="mt-2"
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="처리시설 용량(요구수량 * 365일)">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.001"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>처리시설용량에 따른 공사비(백만원)</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
className="bg-none"
|
||||
>
|
||||
공사비 산정표 보기
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.001"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>시설부대경비 요율(%)</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
>
|
||||
요율표 보기
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
step="0.01"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="col-span-3 mt-4">
|
||||
<Label>총사업비 (백만원)<i className="diveicon di-search" /></Label>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
className="mt-2"
|
||||
type="number"
|
||||
step="0.01"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3 mt-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label>공급처 선정</Label>
|
||||
<Button
|
||||
size={"sm"}
|
||||
onClick={(e) => { }}
|
||||
className="bg-none"
|
||||
>
|
||||
후보지 선택
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name=""
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="col-span-4 mt-4">
|
||||
<div className="mt-4">
|
||||
<Label>관로 표준공사비 산정</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</ListDiv>
|
||||
</div>
|
||||
</div>
|
||||
</ContentsDiv >
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -41,6 +41,13 @@ export default function Home() {
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold mb-4">지도점검 결과</h2>
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-2">
|
||||
<Button className="w-full">
|
||||
<Link href="ruseFcltMng/prfmncReg/pbnstPrfmncReg">
|
||||
하수재이용실적 등록
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<Button className="w-full">
|
||||
<Link href="ruseFcltMng/prfmncReg/chkgdnReg">
|
||||
@@ -112,6 +119,23 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 수요처 매칭 */}
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold mb-4">수요처 매칭</h2>
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-2">
|
||||
<Button className="w-full">
|
||||
<Link href="matMng/matDmd/coMatRvw">수요처 매칭 검토</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<Button className="w-full">
|
||||
<Link href="matMng/matDmd/ruseRvwHstry">재이용검토이력</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
SearchFormLeft,
|
||||
SearchInput,
|
||||
Title,
|
||||
UiModal,
|
||||
UiTable,
|
||||
} from "@common/business_components";
|
||||
import { Button, Input } from "@common/components";
|
||||
@@ -14,46 +15,91 @@ 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, 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";
|
||||
import { PbnstRegModal } from "@/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
|
||||
import { writeRgtrAndMdfr } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg";
|
||||
|
||||
export default function PublicReuseFaciltyInsert() {
|
||||
const { code, pbnst, pubHasuInit } = useWrStore((state) => state);
|
||||
const { pubFacHeadList,pbnstHasuRes } = pbnst;
|
||||
|
||||
|
||||
const {pbnstRes} = pbnst
|
||||
const {
|
||||
code,
|
||||
pbnst,
|
||||
searchFclts,
|
||||
pubHasuInit,
|
||||
pbnstRegClick,
|
||||
getSwtrmtFcltNm,
|
||||
pbnstMngData,
|
||||
pbnstRuseFcltUpdate,
|
||||
pbnstRuseBizUpdate,
|
||||
} = useWrStore((state) => state);
|
||||
const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst;
|
||||
const [currentTab, setCurrentTab] = useState<string>("mng");
|
||||
const [fcltMng, setFcltMng] = useState<ruseFcltType[]>();
|
||||
const [pbnstBiz, setPbnstBiz] = useState<fcBizType[]>();
|
||||
const [isRuseReg, setIsRuseReg] = useState<{
|
||||
isModal: boolean;
|
||||
data: pubHasuType;
|
||||
}>({ isModal: false, data: {} as pubHasuType });
|
||||
|
||||
const [searchTxt, setSearchTxt] = useState<string>();
|
||||
const [bdstTable, setbdstTable] = useState<customPbnst[]>();
|
||||
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
|
||||
const [selectBdst, setSelectBdst] = useState<customPbnst | null>(null);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (!pbnst.isInit) {
|
||||
pubHasuInit(undefined);
|
||||
pubHasuInit("1", "11");
|
||||
}
|
||||
}, [pbnst.isInit, pubHasuInit]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (code.sggCd.length > 0) {
|
||||
setbdstTable(tableData(pbnstHasuRes, { code }));
|
||||
|
||||
const saveRuseData = async ()=>{
|
||||
const data = writeRgtrAndMdfr(pbnst.pbnstMngRegData)
|
||||
let bizs =[] as fcBizType[]
|
||||
data.forEach((fclt) =>{
|
||||
bizs = [
|
||||
...bizs,
|
||||
...fclt.fcBizs
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
await pbnstRuseFcltUpdate(data)
|
||||
console.log('bizs ', bizs)
|
||||
|
||||
await pbnstRuseBizUpdate(bizs)
|
||||
|
||||
console.log(' data ', data)
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(code.sggCd.length){
|
||||
if(searchFclts){
|
||||
setbdstTable(tableData(searchFclts, { code }));
|
||||
}else if (code.sggCd.length > 0 && pbnstHasuRes.length > 0) {
|
||||
setbdstTable(tableData(pbnstHasuRes, { code }));
|
||||
}
|
||||
}
|
||||
}, [code, pbnstHasuRes]);
|
||||
}, [code, pbnstHasuRes,searchFclts]);
|
||||
|
||||
|
||||
const onSelectValue = (val: string) => {
|
||||
console.log(val);
|
||||
};
|
||||
const cellClick = (val: number | undefined) => {
|
||||
if (val === undefined) return;
|
||||
|
||||
setFcltMng([]);
|
||||
};
|
||||
const resetContents = () => {
|
||||
setFcltMng([]); // 빈 배열로 설정하여 신규 모드로 전환
|
||||
const selectRow = pbnstHasuRes?.[val];
|
||||
if (selectRow) {
|
||||
setIsRuseReg({ ...isRuseReg, data: selectRow });
|
||||
pbnstRegClick(selectRow);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTabChange = (value: string) => {
|
||||
@@ -63,7 +109,7 @@ useEffect(() => {
|
||||
return (
|
||||
<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"하수재이용 시설 등록"} />
|
||||
<SearchDiv>
|
||||
@@ -81,6 +127,9 @@ useEffect(() => {
|
||||
className=""
|
||||
size={"sm"}
|
||||
onClick={(e) => {
|
||||
searchTxt && searchTxt?.length > 0
|
||||
? getSwtrmtFcltNm(searchTxt)
|
||||
: pubHasuInit("1", "11")
|
||||
}}
|
||||
>
|
||||
조회
|
||||
@@ -88,7 +137,15 @@ useEffect(() => {
|
||||
<Button
|
||||
size={"sm"}
|
||||
className=""
|
||||
onClick={() =>{}}
|
||||
onClick={() => {
|
||||
pbnstMngData([] as customPbnst[]);
|
||||
isRuseReg.data.bscFctCd
|
||||
? setIsRuseReg({ ...isRuseReg, isModal: true })
|
||||
: ToastFormUi({
|
||||
body: "하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요",
|
||||
title: "재이용시설 등록",
|
||||
});
|
||||
}}
|
||||
>
|
||||
신규등록
|
||||
</Button>
|
||||
@@ -102,37 +159,57 @@ useEffect(() => {
|
||||
<div className="col-span-4 h-full min-h-0">
|
||||
<ListDiv className="min-h-0">
|
||||
<ScrollArea className="h-[60vh]">
|
||||
<UiTable
|
||||
<UiTable
|
||||
tableData={bdstTable || []}
|
||||
headlist={pubFacHeadList}
|
||||
pageSize={100}
|
||||
total={10}
|
||||
headName={"공공 하수처리시설 등록"}
|
||||
cellClick={cellClick}
|
||||
onPageChange={(page: number) => { } } children={undefined} />
|
||||
</ScrollArea>
|
||||
onPageChange={(page: number) => {}}
|
||||
children={undefined}
|
||||
/>
|
||||
</ScrollArea>
|
||||
</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>
|
||||
<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"} onClick={ saveRuseData}className="!justify-end">
|
||||
저장
|
||||
</Button>
|
||||
</TabsList>
|
||||
<TabsContent className="max-h-full" value="mng">
|
||||
<PbnstMngForm data={fcltMng || []} />
|
||||
</TabsContent>
|
||||
<TabsContent className="max-h-full" value="buse">
|
||||
<PbnstBuseForm />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</ScrollArea>
|
||||
<TabsContent className="max-h-full" value="mng">
|
||||
<PbnstMngForm formType="update" />
|
||||
</TabsContent>
|
||||
<TabsContent className="max-h-full" value="buse">
|
||||
<PbnstBuseForm formType="update" />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</ScrollArea>
|
||||
</ListDiv>
|
||||
<UiModal
|
||||
body={
|
||||
<PbnstRegModal
|
||||
data={isRuseReg.data || ({} as customPbnst)}
|
||||
></PbnstRegModal>
|
||||
}
|
||||
bodyClass="w-[68vw] max-w-none h-[90vh]"
|
||||
open={isRuseReg.isModal}
|
||||
onOpenChange={(open) => {
|
||||
setIsRuseReg({ data: {} as pubHasuType, isModal: open });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Toaster position="top-center" />
|
||||
</ContentsDiv>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,23 +14,28 @@ import { Button } from "@common/components/ui";
|
||||
import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg";
|
||||
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { excelDownload, getCityOrSgg } from "@/components/lib/func/commom";
|
||||
|
||||
export default function PbnstSttn() {
|
||||
const { code, pbnstSttn } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
|
||||
const { code, pbnstSttn, pbnstSttnSearch } = useWrStore((state) => state);
|
||||
|
||||
const ref = useRef<ReturnType>({} as ReturnType);
|
||||
const codeData = getCityOrSgg(ref);
|
||||
|
||||
const [pageNation, setPageNation] = useState(1);
|
||||
const [isChHead, setIsChHead] = useState(false);
|
||||
const [bdstTable, setBdstTable] = useState<customPbnst[]>();
|
||||
// const nodeList = headMakeprfmnc(pbnstSttn.pbnSttHeadList, pbnstSttn.pbnSttHeadNm);
|
||||
|
||||
const excelClick = useCallback(() => {
|
||||
// if (codeData) pbnstSttnSearch(1, "10000", codeData);
|
||||
}, []);
|
||||
excelDownload(
|
||||
[[]],
|
||||
"하수재이용시설 현황",
|
||||
"sample_pbnstSttn.xlsx",
|
||||
"A1:U2"
|
||||
);
|
||||
}, [pbnstSttnSearch, codeData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -67,7 +72,7 @@ export default function PbnstSttn() {
|
||||
// pbnstSttnSearch(1, "20", con);
|
||||
}}
|
||||
excelClick={excelClick}
|
||||
initClick={function (): void {}}
|
||||
initClick={function (): void { }}
|
||||
btnClass={btnClass}
|
||||
ref={ref}
|
||||
/>
|
||||
@@ -85,7 +90,7 @@ export default function PbnstSttn() {
|
||||
headlist={pbnstSttn.pbnstSttHeadList}
|
||||
pageSize={20}
|
||||
total={100000}
|
||||
cellClick={(index: number | undefined,headId:string)=>{} }
|
||||
cellClick={(index: number | undefined, headId: string) => { }}
|
||||
onPageChange={setPageNation}
|
||||
></UiTable>
|
||||
</ListDiv>
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { excelDownload, yearOptions } from "@/components/lib/func/commom";
|
||||
import PbnPrfExcelModal from "@/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal";
|
||||
import {
|
||||
ContentsDiv,
|
||||
Title,
|
||||
SearchDiv,
|
||||
SearchFormLeft,
|
||||
SelectBox,
|
||||
SearchInput,
|
||||
SearchFormRight,
|
||||
ScrollArea,
|
||||
UiTable,
|
||||
UiModal,
|
||||
} from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Button, Label } from "@common/components/ui";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { set } from "react-hook-form";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
|
||||
export default function prfmncPrfmncReg() {
|
||||
const { code, prfmnc, prfmncHasuInit, } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const { pbnstPrfmncHeadList, monthHeadList, prfmncRes } = prfmnc;
|
||||
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
|
||||
const [searchTxt, setSearchTxt] = useState<string>();
|
||||
const [isExcelOpen, setIsExcelOPen] = useState<boolean>(false);
|
||||
|
||||
const [searchYear, setSearchYear] = useState<string>(
|
||||
String(new Date().getFullYear())
|
||||
);
|
||||
|
||||
|
||||
const excelClick = useCallback(() => {
|
||||
console.log("dd")
|
||||
excelDownload(
|
||||
[[]],
|
||||
"하수재이용실적",
|
||||
"sample_pbnstPrfmncReg.xlsx",
|
||||
"A1:O1"
|
||||
);
|
||||
}, [prfmnc.excelList])
|
||||
|
||||
useEffect(() => {
|
||||
if (!prfmnc.isInit) {
|
||||
prfmncHasuInit("1", "11");
|
||||
}
|
||||
}, [prfmnc.isInit, prfmncHasuInit]);
|
||||
useEffect(() => {
|
||||
setbdstTable(prfmncRes)
|
||||
console.log("prfmnc.prfmncRes", prfmncRes)
|
||||
}, [prfmncRes]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"하수재이용 시설 등록"} />
|
||||
<SearchDiv>
|
||||
<SearchFormLeft>
|
||||
<div className="col-span-2 flex flex-row space-x-2">
|
||||
<Label className="w-48 mt-2 text-xl text-gray-600">
|
||||
{"실적등록년도"}
|
||||
</Label>
|
||||
<SelectBox
|
||||
className="w-full h-full text-2xl"
|
||||
label=""
|
||||
selectClass={""}
|
||||
selectArray={yearOptions}
|
||||
value={searchYear}
|
||||
onSelectValue={(val: string | number) =>
|
||||
setSearchYear(String(val))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 flex flex-row space-x-2">
|
||||
<Label className="w-28 mt-2 text-xl text-gray-600">
|
||||
{"시설명"}
|
||||
</Label>
|
||||
<SearchInput
|
||||
className={"w-full text-2xl"}
|
||||
label=""
|
||||
textValue={searchTxt || ""}
|
||||
setText={(e) => {
|
||||
setSearchTxt(e);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SearchFormLeft>
|
||||
<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>
|
||||
<Button size={"sm"} onClick={() => {}}>
|
||||
저장
|
||||
</Button>
|
||||
<Button size={"sm"} onClick={() => {setIsExcelOPen(true)}}>
|
||||
파일등록
|
||||
</Button>
|
||||
<Button color="green" size={"sm"} onClick={excelClick}>
|
||||
양식받기
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SearchFormRight>
|
||||
</SearchDiv>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-12 gap-4 h-full">
|
||||
<div className="col-span-4 h-full min-h-0">
|
||||
<ListDiv className="min-h-0">
|
||||
<ScrollArea className="h-[60vh]">
|
||||
<UiTable
|
||||
tableData={bdstTable || []}
|
||||
headlist={pbnstPrfmncHeadList}
|
||||
pageSize={100}
|
||||
total={10}
|
||||
headName={"하수재이용시설 목록"}
|
||||
cellClick={() => {}}
|
||||
onPageChange={(page: number) => {}}
|
||||
children={undefined}
|
||||
/>
|
||||
</ScrollArea>
|
||||
</ListDiv>
|
||||
</div>
|
||||
<ListDiv className="col-span-8 pr-6 ">
|
||||
<ScrollArea className="h-[60vh]">
|
||||
<UiTable
|
||||
tableData={[]}
|
||||
headlist={monthHeadList}
|
||||
pageSize={100}
|
||||
total={10}
|
||||
headName={"하수처리수재이용 실적(m3) 등록결과"}
|
||||
cellClick={() => {}}
|
||||
onPageChange={() => {}}
|
||||
children={undefined}
|
||||
/>
|
||||
</ScrollArea>
|
||||
</ListDiv>
|
||||
</div>
|
||||
</ContentsDiv>
|
||||
<UiModal bodyClass={""} body={<PbnPrfExcelModal></PbnPrfExcelModal>} open={isExcelOpen} onOpenChange={() => {setIsExcelOPen(!isExcelOpen)}}></UiModal>
|
||||
<Toaster position="top-center" />
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -89,6 +89,43 @@ const chBuCd = [
|
||||
{ val: "개축", text: "개축" },
|
||||
{ val: "재축", text: "재축" },
|
||||
]
|
||||
|
||||
|
||||
|
||||
const dmdUszCd = [
|
||||
{ val: "조경용수", text: "조경용수" },
|
||||
{ val: "청소화장실용수", text: "청소화장실용수" },
|
||||
{ val: "농업용수", text: "농업용수" },
|
||||
{ val: "공업용수", text: "공업용수" },
|
||||
{ val: "친수용수", text: "친수용수" },
|
||||
{ val: "기타", text: "기타" },
|
||||
|
||||
]
|
||||
|
||||
|
||||
const pplQulity = [
|
||||
{ val: "도복장강관", text: "도복장강관" },
|
||||
{ val: "PE관", text: "PE관" },
|
||||
{ val: "스테인레스관", text: "스테인레스관" },
|
||||
{ val: "덕타일주철관", text: "덕타일주철관" },
|
||||
{ val: "유리섬유복합관", text: "유리섬유복합관" },
|
||||
{ val: "기타", text: "기타" },
|
||||
|
||||
]
|
||||
const pplLenght = [
|
||||
{ val: "D100", text: "D100" },
|
||||
{ val: "D200", text: "D200" },
|
||||
{ val: "D250", text: "D250" },
|
||||
{ val: "D300", text: "D300" },
|
||||
{ val: "D350", text: "D350" },
|
||||
{ val: "D400", text: "D400" },
|
||||
{ val: "D450", text: "D450" },
|
||||
{ val: "D500", text: "D500" },
|
||||
{ val: "D700", text: "D700" },
|
||||
{ val: "D900", text: "D900" },
|
||||
{ val: "D1000", text: "D1000" },
|
||||
|
||||
]
|
||||
export const buildingType = {
|
||||
RST:"RST",
|
||||
RNB:"RNB",
|
||||
@@ -109,6 +146,9 @@ export type comCodeState = {
|
||||
lclgvrnmntCd: EnvPartSelectDataType[];
|
||||
orgwtKndCd: SelectDataType[];
|
||||
yn: SelectDataType[];
|
||||
pplQulity: SelectDataType[];
|
||||
pplLenght: SelectDataType[];
|
||||
dmdUszCd:SelectDataType[]
|
||||
buildingType: {
|
||||
RST:string,
|
||||
RNB:string,
|
||||
@@ -247,7 +287,10 @@ export const comCodeStateExport: comCodeState = {
|
||||
mdmbsnCd: [],
|
||||
lgbsnCd: [],
|
||||
lclgvrnmntCd: [],
|
||||
pplQulity:pplQulity,
|
||||
pplLenght:pplLenght,
|
||||
yn: yn,
|
||||
dmdUszCd:dmdUszCd,
|
||||
buildingType:buildingType,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
|
||||
import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import type { DemandCompType } from "@common/business_components/ui";
|
||||
export type comFcltState = {
|
||||
searchFclts: pubHasuType;
|
||||
demandCompList: DemandCompType[];
|
||||
};
|
||||
export type comFcltActions = {
|
||||
getSwtrmtFcltNm: (searchNm: string) => void;
|
||||
getDemandCompList :(searchNm: string,cnt:number) => void
|
||||
regDemandCompany:(data:DemandCompType ) => void
|
||||
};
|
||||
|
||||
export const searchActions: (set: any) => comFcltActions = (set: any) => {
|
||||
return {
|
||||
getSwtrmtFcltNm: async (searchNm: string) => {
|
||||
const fcltNm = await getFetch(
|
||||
"common",
|
||||
`/prcsFclt/info/1/20/${searchNm}`
|
||||
);
|
||||
const fcltNmCd: pubHasuType[] = fcltNm.map((item: any) => ({
|
||||
bscFctCd: item.bscFctCd,
|
||||
sido: item.sido,
|
||||
gugun: item.gugun,
|
||||
bscFctNm: item.bscFctNm,
|
||||
addr: item.addr,
|
||||
fctCpc: item.fctCpc,
|
||||
}));
|
||||
return set((state: comFcltState) => ({
|
||||
...state,
|
||||
searchFclts: fcltNmCd,
|
||||
}));
|
||||
},
|
||||
getDemandCompList: async (searchNm: string ,cnt:number) => {
|
||||
const coList = await getFetch(
|
||||
fetchType.WR,
|
||||
`/reuseFc/request/${searchNm}/${cnt}`
|
||||
);
|
||||
return set((state: comFcltState) => ({
|
||||
...state,
|
||||
demandCompList: coList,
|
||||
}));
|
||||
},regDemandCompany: async (data:DemandCompType)=>{
|
||||
|
||||
try{
|
||||
const response = await postFectch('/reuseFc/request',data,fetchType.WR )
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
import { z } from "zod";
|
||||
import type { CommonTableProps } from "../../common/type/headder";
|
||||
|
||||
export const sttnHeadListType = z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
title: z.string(),
|
||||
visible: z.boolean(),
|
||||
})
|
||||
);
|
||||
|
||||
export const coRvwHeadListExport: z.infer<typeof sttnHeadListType> = [
|
||||
{
|
||||
id: "ctpv",
|
||||
title: "시도",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "sgg",
|
||||
title: "시군구",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "coNm",
|
||||
title: "회사명",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "addr",
|
||||
title: "공장주소",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "telNo",
|
||||
title: "전화번호",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "regDt", //바꾸기
|
||||
title: "신청일자",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "state", //바꾸기
|
||||
title: "진행상태",
|
||||
visible: true,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
// id는 다확인해야함
|
||||
export const coRvwNodeListExport: CommonTableProps[] = [
|
||||
{
|
||||
id: "ctpv",
|
||||
title: "시도",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "sgg",
|
||||
title: "시군구",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "coNm",
|
||||
title: "회사명",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "addr",
|
||||
title: "공장주소",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},{
|
||||
id: "telNo",
|
||||
title: "전화번호",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "regDt", //바꾸기
|
||||
title: "신청일자",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "state", //바꾸기
|
||||
title: "진행상태",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
|
||||
];
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { z } from "zod";
|
||||
import type { sttnHeadListType } from "../coSttn/headList";
|
||||
import { coRvwHeadListExport, coRvwNodeListExport } from "./headList";
|
||||
import type { CommonTableProps } from "../../common/type/headder";
|
||||
|
||||
const coRvwHeadList = coRvwHeadListExport;
|
||||
const coRvwNodeList = coRvwNodeListExport;
|
||||
|
||||
export type coRvwState = {
|
||||
coRvw: {
|
||||
isInit: boolean;
|
||||
coRvwHeadList: z.infer<typeof sttnHeadListType>;
|
||||
coRvwNodeList: CommonTableProps[];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const coRvwStateExport: coRvwState = {
|
||||
coRvw: {
|
||||
isInit: false,
|
||||
coRvwHeadList: coRvwHeadList,
|
||||
coRvwNodeList: coRvwNodeList,
|
||||
}
|
||||
}
|
||||
|
||||
export type coRvwType = coRvwState & coRvwActions;
|
||||
|
||||
type coRvwActions = {
|
||||
};
|
||||
|
||||
export const coRvwActionsExport: (set: any) => coRvwActions = (set: any) => {
|
||||
return {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
import { z } from "zod";
|
||||
import type { CommonTableProps } from "../../common/type/headder";
|
||||
|
||||
export const sttnHeadListType = z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
title: z.string(),
|
||||
visible: z.boolean(),
|
||||
})
|
||||
);
|
||||
|
||||
export const ruseHstryHeadListExport: z.infer<typeof sttnHeadListType> = [
|
||||
{
|
||||
id: "ctpv",
|
||||
title: "시도",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "sgg",
|
||||
title: "시군구",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "coNm",
|
||||
title: "회사명",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "addr",
|
||||
title: "공장주소",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "telNo",
|
||||
title: "전화번호",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "regDt", //바꾸기
|
||||
title: "신청일자",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "rvwDt", //바꾸기
|
||||
title: "검토일자",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "matDt", //바꾸기
|
||||
title: "매칭 완료일자",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "gong", //바꾸기
|
||||
title: "공급처",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "dmndQty", //바꾸기
|
||||
title: "요구수량(M3/d)",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "useUsgCd", //바꾸기
|
||||
title: "사용용도",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "state", //바꾸기
|
||||
title: "진행상태",
|
||||
visible: true,
|
||||
},
|
||||
{
|
||||
id: "matYn", //바꾸기
|
||||
title: "매칭완료 여부",
|
||||
visible: true,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
// id는 다확인해야함
|
||||
export const ruseHstryNodeListExport: CommonTableProps[] = [
|
||||
{
|
||||
id: "ctpv",
|
||||
title: "시도",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "sgg",
|
||||
title: "시군구",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "coNm",
|
||||
title: "회사명",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "addr",
|
||||
title: "공장주소",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},{
|
||||
id: "telNo",
|
||||
title: "전화번호",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "regDt", //바꾸기
|
||||
title: "신청일자",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "rvwDt", //바꾸기
|
||||
title: "검토일자",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},{
|
||||
id: "matDt", //바꾸기
|
||||
title: "매칭 완료일자",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},{
|
||||
id: "gong", //바꾸기
|
||||
title: "공급처",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "dmndQty", //바꾸기
|
||||
title: "요구수량(M3/d)",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "useUsgCd", //바꾸기
|
||||
title: "사용용도",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "state", //바꾸기
|
||||
title: "진행상태",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "matYn", //바꾸기
|
||||
title: "매칭완료 여부",
|
||||
visible: true,
|
||||
row: 1,
|
||||
rowSpan: 1,
|
||||
colSpan: 1,
|
||||
},
|
||||
|
||||
];
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { z } from "zod";
|
||||
import type { sttnHeadListType } from "../coSttn/headList";
|
||||
import type { CommonTableProps } from "../../common/type/headder";
|
||||
import { ruseHstryHeadListExport, ruseHstryNodeListExport } from "./headList";
|
||||
|
||||
const ruseHstryHeadList = ruseHstryHeadListExport;
|
||||
const ruseHstryNodeList = ruseHstryNodeListExport;
|
||||
|
||||
export type ruseHstryState = {
|
||||
ruseHstry: {
|
||||
isInit: boolean;
|
||||
ruseHstryHeadList: z.infer<typeof sttnHeadListType>;
|
||||
ruseHstryNodeList: CommonTableProps[];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const ruseHstryStateExport: ruseHstryState = {
|
||||
ruseHstry: {
|
||||
isInit: false,
|
||||
ruseHstryHeadList: ruseHstryHeadList,
|
||||
ruseHstryNodeList: ruseHstryNodeList,
|
||||
}
|
||||
}
|
||||
|
||||
export type ruseHstryType = ruseHstryState & ruseHstryActions;
|
||||
|
||||
type ruseHstryActions = {
|
||||
};
|
||||
|
||||
export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (set: any) => {
|
||||
return {
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,11 @@ export const rswtChkgdnStateExport: rswtChkgdnState = {
|
||||
rswtChkHeadList: rswtChkHeadList,
|
||||
rswtDetailHeadList: rswtDetailHeadList,
|
||||
rswtHeadNm: rswtHeadNm,
|
||||
excelList: [{ data: [[]], headerNum: 0, headerRange: "A1:V3" }],
|
||||
excelList: [{
|
||||
data: [[]], headerNum: 0, headerRange: "A1:V3",
|
||||
sheetName: "",
|
||||
startCol: 0
|
||||
}],
|
||||
rswtChkRes: [],
|
||||
rswtChkPolGuide: [],
|
||||
isInit: false,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
|
||||
|
||||
|
||||
const nameMap = {
|
||||
"세척수": "wshwtr",
|
||||
"냉각수": "coolUswtr",
|
||||
"청소수": "cleanUswtr",
|
||||
"식수대": "drwtUswtr",
|
||||
"희석용수": "dltnUswtr",
|
||||
"중수도": "ithlRswtr",
|
||||
"기타": "ithlEtcUswtr",
|
||||
"청소화장실용수": "cleanToilUswtr",
|
||||
"세척살수용수": "resn",
|
||||
"조경용수": "lndwtr",
|
||||
"친수용수": "hydUswtr",
|
||||
"지하수충전": "ugwtChr",
|
||||
"농업용수": "farmUswtr",
|
||||
"하천등유지용수": "rvrKeepUswtr",
|
||||
"공업용수": "indstUswtr"
|
||||
};
|
||||
|
||||
|
||||
export const excelToPbnPrfData = (excelData: any[], year: string) => {
|
||||
// 월별 데이터 하나로 병합
|
||||
const merged = {} as any;
|
||||
excelData.forEach((item: any) => {
|
||||
const key = nameMap[item["용수명"]];
|
||||
if (!key) return;
|
||||
|
||||
for (let i = 1; i <= 12; i++) {
|
||||
const month = i.toString().padStart(2, "0");
|
||||
const ym = year + month;
|
||||
|
||||
if (!merged[ym]) merged[ym] = { ym };
|
||||
merged[ym][key] = Number(item[`${i}월`] ?? 0);
|
||||
}
|
||||
});
|
||||
|
||||
const pbnPrfData = Object.values(merged);
|
||||
console.log(pbnPrfData);
|
||||
|
||||
return pbnPrfData;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { z } from "zod";
|
||||
import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg";
|
||||
|
||||
export const pbnPrfRegExcelZod = z.object({
|
||||
ym: z.string().default(""),
|
||||
bscFctNm: z.string().default(""),
|
||||
pbnstRuseFcltNm: z.string().default(""),
|
||||
file: z.instanceof(File).optional(),
|
||||
});
|
||||
|
||||
export const pbnstPrfmncHeadListExport: TableUpperProps[] = [
|
||||
{ id: "sido", title: "시도" },
|
||||
{ id: "gugun", title: "시군구" },
|
||||
{ id: "bscFctNm", title: "시설명" },
|
||||
{ id: "sisul", title: "재이용시설명" },
|
||||
{ id: "sisulCd", title: "재이용시설코드" },
|
||||
];
|
||||
|
||||
export const monthHeadListExport: TableUpperProps[] = [
|
||||
{ id: "gubun", title: "구분" },
|
||||
{ id: "total", title: "계" },
|
||||
{ id: "mon1", title: "1월" },
|
||||
{ id: "mon2", title: "2월" },
|
||||
{ id: "mon3", title: "3월" },
|
||||
{ id: "mon4", title: "4월" },
|
||||
{ id: "mon5", title: "5월" },
|
||||
{ id: "mon6", title: "6월" },
|
||||
{ id: "mon7", title: "7월" },
|
||||
{ id: "mon8", title: "8월" },
|
||||
{ id: "mon9", title: "9월" },
|
||||
{ id: "mon10", title: "10월" },
|
||||
{ id: "mon11", title: "11월" },
|
||||
{ id: "mon12", title: "12월" },
|
||||
];
|
||||
@@ -0,0 +1,79 @@
|
||||
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
|
||||
import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg";
|
||||
import {
|
||||
pbnstPrfmncHeadListExport,
|
||||
monthHeadListExport,
|
||||
} from "./headList";
|
||||
import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
|
||||
const pbnstPrfmncHeadList = pbnstPrfmncHeadListExport;
|
||||
const monthHeadList = monthHeadListExport;
|
||||
|
||||
export type pbnstPrfmncState = {
|
||||
prfmnc: {
|
||||
isInit: boolean;
|
||||
pbnstPrfmncHeadList: TableUpperProps[];
|
||||
monthHeadList: TableUpperProps[];
|
||||
prfmncRes: pubHasuType[];
|
||||
excelList: Number[];
|
||||
}
|
||||
}
|
||||
|
||||
export const pbnstPrfmncStateExport: pbnstPrfmncState = {
|
||||
prfmnc: {
|
||||
isInit: false,
|
||||
pbnstPrfmncHeadList: pbnstPrfmncHeadList,
|
||||
monthHeadList: monthHeadList,
|
||||
prfmncRes: [],
|
||||
excelList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||
}
|
||||
}
|
||||
|
||||
export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions;
|
||||
|
||||
type pbnstPrfmncActions = {
|
||||
prfmncHasuInit: (page: string, sggOrCity: string) => void;
|
||||
}
|
||||
|
||||
const checkWrRegList = async () => {
|
||||
const wrRegList = await getFetch("wr", `/reuseFc/pubFc`);
|
||||
return wrRegList;
|
||||
};
|
||||
const hasuListFetch = async (page: string, sggOrCity: string) => {
|
||||
const checkWrRegListRes = await checkWrRegList();
|
||||
|
||||
const rainRes = await postFectch(
|
||||
`/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`,
|
||||
checkWrRegListRes,
|
||||
fetchType.COMMON
|
||||
);
|
||||
|
||||
const hasuList = rainRes.data.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
ruse: item.ruse === false ? "N" : "Y",
|
||||
};
|
||||
});
|
||||
|
||||
return hasuList;
|
||||
};
|
||||
export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (set: any) => {
|
||||
return {
|
||||
prfmncHasuInit: async (page: string, sggOrCity: string) => {
|
||||
try {
|
||||
const prfmncRes = await hasuListFetch(page, sggOrCity);
|
||||
console.log("prfmncRes", prfmncRes)
|
||||
return set((state: pbnstPrfmncState) => ({
|
||||
...state,
|
||||
prfmnc: {
|
||||
...state.prfmnc,
|
||||
prfmncRes: prfmncRes,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
} catch (errorHasu) {
|
||||
console.log(errorHasu);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -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: "시군구" },
|
||||
@@ -12,65 +8,128 @@ export const pubFacHeadListExport: TableUpperProps[] = [
|
||||
{ id: "addr", title: "위치" },
|
||||
{ id: "efflWqltStndrdNm", title: "지역구분" },
|
||||
{ id: "fctCpc", title: "시설용량" },
|
||||
{ id: "yn", title: "재이용여부" },
|
||||
{ id: "authoDay", title: "등록여부" },
|
||||
{ id: "ruse", title: "재이용여부" },
|
||||
{ id: "rswtrYn", title: "등록여부" },
|
||||
];
|
||||
|
||||
export const pubMngUpHeadListExport: TableUpperProps[] = [
|
||||
{ id: "mng", title: "운영방식" },
|
||||
{ id: "subCo", title: "대행업체" },
|
||||
{ id: "startDay", title: "시작일", upName: "upChangeRe", upSequnce: 1 },
|
||||
{ id: "endDay", title: "종료일", upName: "upChangeRe", upSequnce: 2 },
|
||||
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",
|
||||
},
|
||||
];
|
||||
const date = new Date();
|
||||
|
||||
export const pubMngNmExport: chHeadType[] = [
|
||||
export const pplInstlsHeadListExport: TableUpperProps[] = [
|
||||
{ id: "choose", title: "선택", type: "checkbox" },
|
||||
{ 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: "공급유량계 유무" },
|
||||
];
|
||||
|
||||
export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [
|
||||
{ id: "ruseUtztnFcltNm", title: "운영방식" },
|
||||
{ id: "orgwtWtritQnt", 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: "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: "폐수배출물신고 허가여부", type: "selectYn" },
|
||||
{ id: "tmsInstlYn", lable: "Tms설치여부", type: "selectYn" },
|
||||
{ id: "pbnstDrngInflwExclYn", lable: "공공하수도유입제외 허가여부", type: "selectYn" },
|
||||
];
|
||||
|
||||
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: "위치(처리장 내외)" ,type: "selectYn" }, // 머가 내? 외?,
|
||||
{ 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:'cusr_alotm' , 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 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,35 +1,75 @@
|
||||
import { z } from "zod";
|
||||
import type { TableUpperProps } from "../rainReg";
|
||||
import { getFetch } from "@/components/lib/api";
|
||||
import { TEST_UUID, type TableUpperProps } from "../rainReg";
|
||||
import {
|
||||
deleteFectch,
|
||||
fetchType,
|
||||
getFetch,
|
||||
postFectch,
|
||||
putFectch,
|
||||
} from "@/components/lib/api";
|
||||
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
|
||||
import { pubFacHeadListExport, pubMngNmExport, pubMngUpHeadListExport } from "./headList";
|
||||
import { exampleData, fcBizSchema, type customPbnst, type pubHasuType } from "./type";
|
||||
import {
|
||||
exampleData,
|
||||
fcBizSchema,
|
||||
type customPbnst,
|
||||
type fcBizType,
|
||||
type pbnstInsertIndex,
|
||||
type pubHasuType,
|
||||
} from "./type";
|
||||
import type { SelectDataType } from "@common/business_components/ui";
|
||||
|
||||
import {
|
||||
pbnstMngUpHeadListExport,
|
||||
pbnstOrgwtHeadListRxport,
|
||||
pbnstMngNmExport,
|
||||
pubFacHeadListExport,
|
||||
pplInstlsHeadListExport,
|
||||
pbnstDemandHeadListExport,
|
||||
fcOrgwtsHeadListExport,
|
||||
} from "./headList";
|
||||
|
||||
const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }];
|
||||
const pubFacHeadList= pubFacHeadListExport;
|
||||
const pubMngUpHeadList = pubMngUpHeadListExport
|
||||
const pubMngNm= pubMngNmExport;
|
||||
|
||||
const pubFacHeadList = pubFacHeadListExport;
|
||||
const pbnstMngUpHeadList = pbnstMngUpHeadListExport;
|
||||
const pbnstOrgwtHeadList = pbnstOrgwtHeadListRxport;
|
||||
const pbnstMngNm = pbnstMngNmExport;
|
||||
const pplInstlsHeadLisat = pplInstlsHeadListExport;
|
||||
const pbnstDemandHeadList = pbnstDemandHeadListExport;
|
||||
const fcOrgwtsHeadList = fcOrgwtsHeadListExport;
|
||||
|
||||
export type pubFacState = {
|
||||
pbnst: {
|
||||
isInit: boolean;
|
||||
pubFacHeadList: TableUpperProps[];
|
||||
pubMngUpHeadList: TableUpperProps[];
|
||||
pubMngNm: chHeadType[];
|
||||
pbnstHasuRes: pubHasuType[]
|
||||
selectLabel: SelectDataType[];
|
||||
pbnstRes: customPbnst[];
|
||||
pbnstMngUpHeadList: TableUpperProps[];
|
||||
pbnstMngNm: chHeadType[];
|
||||
pbnstHasuRes: pubHasuType[];
|
||||
pbnstRes: customPbnst[] | null; // 배열에서 단일 객체 또는 null로 변경
|
||||
pbnstResObj: customPbnst | null; // 배열에서 단일 객체 또는 null로 변경
|
||||
pbnstBizCycle: SelectDataType[];
|
||||
selectLabel: SelectDataType[];
|
||||
pbnstOrgwtHeadList: TableUpperProps[];
|
||||
pplInstlsHeadLisat: TableUpperProps[];
|
||||
pbnstDemandHeadList: TableUpperProps[];
|
||||
fcOrgwtsHeadList: TableUpperProps[];
|
||||
pbnstMngRegData: customPbnst[];
|
||||
pbnsUpdateIndex: pbnstInsertIndex;
|
||||
dmdComList: any[];
|
||||
};
|
||||
};
|
||||
type pubFacActions = {
|
||||
pbnstRegInit: (sgg: string) => void;
|
||||
pbnstRegSearch: (txt: string | undefined, sgg: string) => void;
|
||||
pubHasuInit: (page: string, sggOrCity: string) => void;
|
||||
pbnstRegClick: (pubHasuRes: pubHasuType) => void;
|
||||
pbnstReg: (txt: string | undefined) => void;
|
||||
pubHasuInit: (txt: string | undefined) => void;
|
||||
pbnstInsert(pbnstRes: customPbnst): Promise<void>;
|
||||
appendRuseFclt(array: customPbnst[]): void;
|
||||
fileDelete: (atflCd: string) => void;
|
||||
fileDownLoad: (atflCd: string) => void;
|
||||
pbnstMngData: (data: customPbnst[]) => void;
|
||||
pbnstBizData(data: fcBizType): void;
|
||||
getBizCycle: (pbnstObj: customPbnst) => void;
|
||||
getpbnstInsertIndex: (data: pbnstInsertIndex) => void;
|
||||
pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void;
|
||||
pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void;
|
||||
};
|
||||
|
||||
export type pubFacType = pubFacState & pubFacActions;
|
||||
@@ -38,45 +78,101 @@ export const pubFacStateExport: pubFacState = {
|
||||
pbnst: {
|
||||
isInit: false,
|
||||
pubFacHeadList: pubFacHeadList,
|
||||
pubMngUpHeadList: pubMngUpHeadList,
|
||||
selectLabel: selectLabel,
|
||||
pubMngNm: pubMngNm,
|
||||
pbnstMngUpHeadList: pbnstMngUpHeadList,
|
||||
pbnstMngNm: pbnstMngNm,
|
||||
pbnstOrgwtHeadList: pbnstOrgwtHeadList,
|
||||
pbnstHasuRes: [],
|
||||
pbnstRes: [],
|
||||
pbnstBizCycle:[]
|
||||
pbnstResObj: null, // 초기값을 null로 변경
|
||||
pbnstRes: [], // 초기값을 null로 변경
|
||||
pbnstBizCycle: [{ text: "없음", val: "1" }],
|
||||
selectLabel: selectLabel,
|
||||
pplInstlsHeadLisat: pplInstlsHeadLisat,
|
||||
pbnstDemandHeadList: pbnstDemandHeadList,
|
||||
fcOrgwtsHeadList: fcOrgwtsHeadList,
|
||||
pbnstMngRegData: [],
|
||||
pbnsUpdateIndex: {} as pbnstInsertIndex,
|
||||
dmdComList: [],
|
||||
},
|
||||
};
|
||||
|
||||
const initFetch = async (txt: string | undefined) => {
|
||||
const rainRes = await getFetch(
|
||||
"common",
|
||||
`/prcsFclt/info/1/10/A/41220` + (txt ? `/${txt}` : "") + "/500" + "/1"
|
||||
);
|
||||
return rainRes;
|
||||
const checkWrRegList = async () => {
|
||||
const wrRegList = await getFetch("wr", `/reuseFc/pubFc`);
|
||||
return wrRegList;
|
||||
};
|
||||
|
||||
const getBizCycle = async (fcBizs: z.infer<typeof fcBizSchema>[] ) => {
|
||||
const pbnstBizCycle =fcBizs.map((item: z.infer<typeof fcBizSchema>) => {
|
||||
const hasuListFetch = async (page: string, sggOrCity: string) => {
|
||||
const checkWrRegListRes = await checkWrRegList();
|
||||
|
||||
const rainRes = await postFectch(
|
||||
`/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`,
|
||||
checkWrRegListRes,
|
||||
fetchType.COMMON
|
||||
);
|
||||
|
||||
const hasuList = rainRes.data.map((item: any) => {
|
||||
return {
|
||||
text: `${item.cycl}차수`,
|
||||
val: item.cycl,
|
||||
...item,
|
||||
ruse: item.ruse === false ? "N" : "Y",
|
||||
};
|
||||
});
|
||||
return pbnstBizCycle;
|
||||
}
|
||||
|
||||
return hasuList;
|
||||
};
|
||||
|
||||
const initFetch = async (ruseFcltPk: string | undefined) => {
|
||||
const pbnstRes = await getFetch("wr", `/reuseFc/pubFc/${ruseFcltPk}`);
|
||||
return pbnstRes;
|
||||
};
|
||||
|
||||
export const writeRgtrAndMdfr = (data: customPbnst[]) => {
|
||||
|
||||
data.forEach((pbnst) => {
|
||||
pbnst.rgtr = TEST_UUID;
|
||||
pbnst.mdfr = TEST_UUID;
|
||||
|
||||
pbnst.fcBizs = pbnst.fcBizs?.map((item) => {
|
||||
item.rgtr = TEST_UUID;
|
||||
item.mdfr = TEST_UUID;
|
||||
item.fcOrgwts = item.fcOrgwts?.map((orgwt) => {
|
||||
orgwt.mdfr = TEST_UUID;
|
||||
orgwt.rgtr = TEST_UUID;
|
||||
return orgwt;
|
||||
});
|
||||
|
||||
item.fcDemands = item.fcDemands?.map((dmd) => {
|
||||
dmd.mdfr = TEST_UUID;
|
||||
dmd.rgtr = TEST_UUID;
|
||||
return dmd;
|
||||
});
|
||||
return item;
|
||||
});
|
||||
pbnst.fcOpers = pbnst.fcOpers.map((oper) => {
|
||||
oper.rgtr = TEST_UUID;
|
||||
oper.mdfr = TEST_UUID;
|
||||
return oper;
|
||||
});
|
||||
pbnst.fcFiles = pbnst.fcFiles.map((file) => {
|
||||
file.rgtr = TEST_UUID;
|
||||
file.mdfr = TEST_UUID;
|
||||
return file;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
return data;
|
||||
};
|
||||
export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
|
||||
return {
|
||||
|
||||
pubHasuInit: async (txt: string | undefined) => {
|
||||
pubHasuInit: async (page: string, sggOrCity: string) => {
|
||||
try {
|
||||
const pbnstHasuRes = await initFetch(txt);
|
||||
|
||||
const pbnstHasuRes = await hasuListFetch(page, sggOrCity);
|
||||
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstHasuRes:pbnstHasuRes,
|
||||
pbnstHasuRes: pbnstHasuRes,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
@@ -85,39 +181,15 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
|
||||
}
|
||||
},
|
||||
|
||||
pbnstRegInit: async (txt: string | undefined) => {
|
||||
pbnstRegClick: async (pubHasuRes: pubHasuType) => {
|
||||
try {
|
||||
//const pbnstRes = await initFetch(txt);
|
||||
|
||||
const pbnstRes = exampleData;
|
||||
|
||||
const pbnstBizCycle = getBizCycle(pbnstRes?.fcBizs);
|
||||
const pbnstRes = await initFetch(pubHasuRes.bscFctCd);
|
||||
console.log('pbnstRes ' , pbnstRes)
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstRes: pbnstRes,
|
||||
pbnstBizCycle:pbnstBizCycle,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
} catch (errorHasu) {
|
||||
console.log(errorHasu);
|
||||
}
|
||||
},
|
||||
pbnstRegSearch: async (txt: string | undefined, sgg: string) => {
|
||||
try {
|
||||
const pbnstRes = await getFetch(
|
||||
"wr",
|
||||
`/api/v1/reuseFc/pubFc` + (txt ? `/${txt}` : "") + `/${sgg}`
|
||||
);
|
||||
const pbnstBizCycle = getBizCycle(pbnstRes.fcBizs);
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstReg: pbnstRes,
|
||||
pbnstBizCycle:pbnstBizCycle,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
@@ -125,9 +197,10 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
|
||||
console.log(errorHasu);
|
||||
}
|
||||
},
|
||||
|
||||
pbnstReg: async (txt: string | undefined) => {
|
||||
try {
|
||||
const pbnstRes = await initFetch(txt);
|
||||
const pbnstRes = await hasuListFetch("11", "11");
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
@@ -140,5 +213,167 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
|
||||
console.log(errorHasu);
|
||||
}
|
||||
},
|
||||
pbnstInsert: async (pbnstRes: customPbnst) => {
|
||||
try {
|
||||
|
||||
const response = await postFectch(
|
||||
`/reuseFc/pubFc`,
|
||||
JSON.stringify( writeRgtrAndMdfr([pbnstRes]))
|
||||
);
|
||||
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstRes: response.data,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("Error updating pbnst:", error);
|
||||
}
|
||||
},pbnstRuseFcltUpdate : async(ruseRes:customPbnst[])=>{
|
||||
try {
|
||||
|
||||
const response = await putFectch(
|
||||
`/reuseFc/pubFc`,
|
||||
ruseRes
|
||||
);
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error pbnstRuseFcltUpdate:", error);
|
||||
}
|
||||
} ,pbnstRuseBizUpdate : async(ruseRes:fcBizType[])=>{
|
||||
try {
|
||||
|
||||
console.log('ruseRes ', ruseRes)
|
||||
const response = await putFectch(
|
||||
`/reuseFc/pubFcBiz`,
|
||||
ruseRes
|
||||
);
|
||||
const pbnstRes = await hasuListFetch("11", "11");
|
||||
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstRes: pbnstRes,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("Error pbnstRuseFcltUpdate:", error);
|
||||
}
|
||||
} ,
|
||||
getBizCycle: async (pbnstObj: customPbnst) => {
|
||||
const pbnstBizCycle = pbnstObj.fcBizs.map((item) => {
|
||||
return {
|
||||
text: `${item.cycl}차`,
|
||||
val: item.cycl,
|
||||
};
|
||||
});
|
||||
|
||||
console.log(" pbnstBizCycle ", pbnstBizCycle);
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstBizCycle: pbnstBizCycle,
|
||||
pbnstResObj: pbnstObj,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
},
|
||||
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: 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,
|
||||
`/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);
|
||||
}
|
||||
},
|
||||
|
||||
pbnstMngData: (data: customPbnst[]) => {
|
||||
if (data.length > 0) {
|
||||
}
|
||||
|
||||
return set((state: pubFacState) => {
|
||||
state.pbnst.pbnstMngRegData = data;
|
||||
state.pbnst.pbnstBizCycle =
|
||||
data.length <= 0
|
||||
? [{ text: "없음", val: "1" }]
|
||||
: state.pbnst.pbnstBizCycle;
|
||||
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;
|
||||
const pbnstData = state.pbnst.pbnstMngRegData
|
||||
state.pbnst.pbnstMngRegData= [...pbnstData]
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return state;
|
||||
});
|
||||
},
|
||||
getpbnstInsertIndex: async (data: pbnstInsertIndex) => {
|
||||
return set((state: pubFacState) => {
|
||||
state.pbnst.pbnsUpdateIndex = data;
|
||||
return state;
|
||||
});
|
||||
},
|
||||
appendRuseFclt: async (array: customPbnst[]) => {
|
||||
try {
|
||||
return set((state: pubFacState) => ({
|
||||
...state,
|
||||
pbnst: {
|
||||
...state.pbnst,
|
||||
pbnstRes: array,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
import { getFetch, postFectch, putFectch } from "@/components/lib/api";
|
||||
import { z } from "zod";
|
||||
import { makeMdfr, makeRstr } from "../bdstReg";
|
||||
import type { SelectDataType } from "@common/business_components/ui";
|
||||
|
||||
export const TEST_UUID= '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e'
|
||||
export const rainZod = z.object({
|
||||
@@ -90,6 +91,7 @@ export type TableUpperProps = {
|
||||
visible?:boolean;
|
||||
rowSpan?: true;
|
||||
type?: string;
|
||||
selectData ?:string;
|
||||
};
|
||||
|
||||
export const upHeadList: TableUpperProps[] = [
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { customPbnst } from "../../fcltReg/pbnstReg/type";
|
||||
|
||||
export const excelPbnstSttnParsing = (data: any[]): string[][] => {
|
||||
const excelExportData: string[][] = [];
|
||||
|
||||
data.forEach((item) => {
|
||||
excelExportData.push([
|
||||
item.a,
|
||||
String(item.aaa),
|
||||
item.aaaa ?? "",
|
||||
item.operMngCd ?? "",
|
||||
String(item.cityText ?? ""),
|
||||
String(item.sggText ?? ""),
|
||||
String(item.bdnstNm ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
String(item.archArea ?? ""),
|
||||
])
|
||||
})
|
||||
return excelExportData;
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
import type { CommonTableProps } from "@/app/store/common/type/headder";
|
||||
import type { customPbnst } from "../../fcltReg/pbnstReg";
|
||||
import type { z } from "zod";
|
||||
import {
|
||||
pbnSttHeadListExport,
|
||||
pbnstSttNodeListExport
|
||||
} from "./headList";
|
||||
} from "./headList";
|
||||
import { fetchType, getFetch } from "@/components/lib/api";
|
||||
import { controlHeadView } from "../rainSttn";
|
||||
import type { sttnHeadListType } from "../rainSttn/headList";
|
||||
import type { customPbnst } from "../../fcltReg/pbnstReg/type";
|
||||
import { excelPbnstSttnParsing } from "./excel";
|
||||
|
||||
const pbnstSttHeadList = pbnSttHeadListExport;
|
||||
const pbnstSttNodeList = pbnstSttNodeListExport;
|
||||
@@ -26,6 +27,7 @@ type pbnstSttnActions = {
|
||||
pbnstChSttnHead: (
|
||||
headList: z.infer<typeof sttnHeadListType>,
|
||||
) => void;
|
||||
pbnstSttnSearch: (page: number, total: string, con: string) => void;
|
||||
};
|
||||
|
||||
export type pbnstSttnType = pbnstSttnState & pbnstSttnActions;
|
||||
@@ -34,8 +36,8 @@ export const pbnstSttnStateExport: pbnstSttnState = {
|
||||
pbnstSttn: {
|
||||
pbnstSttHeadList: pbnstSttHeadList,
|
||||
pbnstSttNodeList: pbnstSttNodeList,
|
||||
pbnstSttnRes:[],
|
||||
excelList:[],
|
||||
pbnstSttnRes: [],
|
||||
excelList: [],
|
||||
isInit: false,
|
||||
},
|
||||
};
|
||||
@@ -45,19 +47,52 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
) => {
|
||||
return {
|
||||
pbnstChSttnHead: async (
|
||||
headList: z.infer<typeof sttnHeadListType>
|
||||
): Promise<void> => {
|
||||
|
||||
console.log('head ', headList)
|
||||
const changeNodeList= controlHeadView(headList,pbnstSttNodeList)
|
||||
|
||||
return set((state: pbnstSttnState) => ({
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
pbnstSttHeadList: headList,
|
||||
pbnstSttNodeList: changeNodeList,
|
||||
},
|
||||
}));
|
||||
headList: z.infer<typeof sttnHeadListType>
|
||||
): Promise<void> => {
|
||||
|
||||
console.log('head ', headList)
|
||||
const changeNodeList = controlHeadView(headList, pbnstSttNodeList)
|
||||
|
||||
return set((state: pbnstSttnState) => ({
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
pbnstSttHeadList: headList,
|
||||
pbnstSttNodeList: changeNodeList,
|
||||
},
|
||||
}));
|
||||
},
|
||||
pbnstSttnSearch: async (page: number, total: string, con: string) => {
|
||||
try {
|
||||
const pbnstSttnRes = await getFetch(
|
||||
fetchType.WR,
|
||||
`/reuseFc/waterreuseFc/${page}/${total}/${con}`
|
||||
);
|
||||
if (Number(total) > 9000) {
|
||||
const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes);
|
||||
set((state: pbnstSttnState) => {
|
||||
return {
|
||||
...state,
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
excelList: pbnstExcel,
|
||||
},
|
||||
};
|
||||
});
|
||||
} else
|
||||
set((state: pbnstSttnState) => {
|
||||
|
||||
return {
|
||||
...state,
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
pbnstSttnRes: pbnstSttnRes,
|
||||
isInit: false,
|
||||
},
|
||||
};
|
||||
});
|
||||
} catch (erTxt) {
|
||||
console.log("error", erTxt);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,10 @@ import { rswtChkStateExport, rswtChkSttnActionsExport, type rswtChkSttnState, ty
|
||||
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";
|
||||
import { ruseHstryActionsExport, ruseHstryStateExport, type ruseHstryState, type ruseHstryType } from "./matDmd/ruseRvwHstry";
|
||||
|
||||
export type WrStore = comCodeType &
|
||||
pubFacType &
|
||||
@@ -103,8 +107,12 @@ export type WrStore = comCodeType &
|
||||
rainChkSttnType&
|
||||
rswtChkSttnType&
|
||||
pbnstSttnType&
|
||||
comFcltActions&comFcltState&
|
||||
coSttnType& // 옮겨야함
|
||||
ldrmntCoSttnType // 옮겨야함
|
||||
ldrmntCoSttnType& // 옮겨야함
|
||||
pbnstPrfmncType&
|
||||
coRvwType&
|
||||
ruseHstryType
|
||||
;
|
||||
|
||||
export const StoreZus = (
|
||||
@@ -124,8 +132,10 @@ export const StoreZus = (
|
||||
rswtChkSttnState &
|
||||
pbnstSttnState&
|
||||
coSttnState& // 옮겨야함
|
||||
ldrmntCoSttnState // 옮겨야함
|
||||
|
||||
ldrmntCoSttnState& // 옮겨야함
|
||||
pbnstPrfmncState&
|
||||
coRvwState&
|
||||
ruseHstryState
|
||||
= {
|
||||
...comCodeStateExport,
|
||||
...pubFacStateExport,
|
||||
@@ -144,6 +154,9 @@ export const StoreZus = (
|
||||
...pbnstSttnStateExport,
|
||||
...coSttnStateExport, // 옮겨야함
|
||||
...ldrmntCoSttnStateExport, // 옮겨야함
|
||||
...pbnstPrfmncStateExport,
|
||||
...coRvwStateExport,
|
||||
...ruseHstryStateExport,
|
||||
}
|
||||
) => {
|
||||
return createStore<WrStore>()((set) => {
|
||||
@@ -155,6 +168,7 @@ export const StoreZus = (
|
||||
getEnvPartCd(set);
|
||||
return {
|
||||
...initState,
|
||||
...searchActions(set),
|
||||
...pubFacActionsExport(set),
|
||||
...rainFacActionsExport(set),
|
||||
...rswtFacActionsExport(set),
|
||||
@@ -172,6 +186,9 @@ export const StoreZus = (
|
||||
...pbnstSttnActionsExport(set),
|
||||
...coSttnActionsExport(set), // 옮겨야함
|
||||
...ldrmntCoSttnActionsExport(set), // 옮겨야함
|
||||
...pbnstPrfmncActionsExport(set),
|
||||
...coRvwActionsExport(set),
|
||||
...ruseHstryActionsExport(set),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,67 +1,102 @@
|
||||
//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) {
|
||||
console.log(`오류 발생: ${response.status}`);
|
||||
}
|
||||
const contentType = response.headers.get("content-type") ?? "";
|
||||
|
||||
if (contentType.includes("application/json")) {
|
||||
// JSON 응답 처리
|
||||
const res = await response.json();
|
||||
return res.data;
|
||||
} else {
|
||||
// 파일 응답 처리 (ex. PDF, Excel 등)
|
||||
const blob = await response.blob();
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
const filename = "downloaded_file.PDF";
|
||||
|
||||
a.href = blobUrl;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(blobUrl);
|
||||
|
||||
return null; // 다운로드이므로 반환값 없음
|
||||
}
|
||||
};
|
||||
|
||||
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, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`오류 발생: ${response.status}`);
|
||||
}
|
||||
const res = await response.json()
|
||||
return res.data;
|
||||
}
|
||||
return await response.json();
|
||||
};
|
||||
|
||||
export const postFectch = async (url: string, params: any) => {
|
||||
|
||||
const response = await fetch(DEV_URL_WR+url, {
|
||||
method: "POST",
|
||||
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) {
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
};
|
||||
@@ -1,16 +1,17 @@
|
||||
|
||||
const LOCAL_PORT = "3000";
|
||||
const LOCAL_PORT = "3001";
|
||||
const DEV_PORT = "11080";
|
||||
const DEV_PORT_NEW="11082"
|
||||
|
||||
|
||||
export const LOCAL_URL_WR = `http://localhost:${LOCAL_PORT}/api/v1`;
|
||||
export const DEV_URL_WR = `http://con.mind-one.co.kr:${DEV_PORT}/api/v1`;
|
||||
// export const DEV_URL_WR = `http://192.168.0.91:8880/api/v1`;
|
||||
|
||||
//export const DEV_URL_FO = `http://con.mind-one.co.kr:${DEV_PORT_FO}/api/v1`;
|
||||
// export const DEV_URL_FO = `http://192.168.0.91:8882/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";
|
||||
@@ -1,53 +1,78 @@
|
||||
import { Upload, type HttpRequest, type HttpResponse, type OnSuccessPayload } from "tus-js-client";
|
||||
import {
|
||||
Upload,
|
||||
type HttpRequest,
|
||||
type HttpResponse,
|
||||
type OnSuccessPayload,
|
||||
type DetailedError,
|
||||
} from "tus-js-client";
|
||||
import { CS_TUS_UPLOAD, CS_URL } from "../config";
|
||||
import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
|
||||
|
||||
type UploadOptions = {
|
||||
handleUploadStart?: (upload: Upload) => void;
|
||||
handleProgress?: (percentage: string) => void;
|
||||
handleSuccess?: (payload :OnSuccessPayload) => void;
|
||||
handleResponse?: (req:HttpRequest, res: HttpResponse) => void;
|
||||
handleSuccess?: (payload: OnSuccessPayload) => void;
|
||||
handleResponse?: (req: HttpRequest, res: ReturnFileType) => void;
|
||||
};
|
||||
export type ReturnFileType = {
|
||||
orgnlFileNm: string;
|
||||
atflFlieSz: number;
|
||||
atflType: string;
|
||||
dwnldNocs: number;
|
||||
delYn: string;
|
||||
lnkgDmnId: string | null;
|
||||
lnkgDmnNm: string | null;
|
||||
regDt: Date | null;
|
||||
atflCd: String;
|
||||
atflSn: number;
|
||||
atflId: String;
|
||||
physFileNm: String;
|
||||
};
|
||||
export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) =>
|
||||
new Promise<ReturnFileType>((resolve, reject) => {
|
||||
try {
|
||||
const Authorization = "Authorization";
|
||||
const AUTH_USER_ID = "token-id";
|
||||
let fileInfo: string | undefined;
|
||||
//CS_URL
|
||||
const uploader = new Upload(oFile.file, {
|
||||
endpoint: CS_TUS_UPLOAD,
|
||||
chunkSize: 10 * 1024 * 1024,
|
||||
headers: {
|
||||
Authorization: "",
|
||||
AUTH_USER_ID: "",
|
||||
},
|
||||
metadata: {
|
||||
filename: oFile.file.name,
|
||||
filetype: oFile.file.type,
|
||||
},
|
||||
onError(error) {
|
||||
reject(error);
|
||||
},
|
||||
onProgress(bytesUploaded, bytesTotal) {
|
||||
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
|
||||
options?.handleProgress?.(percentage);
|
||||
},
|
||||
onAfterResponse(req, res: HttpResponse) {
|
||||
fileInfo = res.getHeader("X-File-Info");
|
||||
if (fileInfo === undefined || fileInfo === null) return;
|
||||
},
|
||||
onSuccess(payload: OnSuccessPayload) {
|
||||
options?.handleSuccess?.(payload);
|
||||
if (fileInfo) {
|
||||
console.log('fileInfo', fileInfo);
|
||||
resolve(JSON.parse(fileInfo) as ReturnFileType);
|
||||
} else reject({} as DetailedError);
|
||||
},
|
||||
});
|
||||
|
||||
export function TusClientUpload(oFile: File, setUpload: (upload: Upload) => void, options?: UploadOptions) {
|
||||
const Authorization = "Authorization";
|
||||
const AUTH_USER_ID = "token-id";
|
||||
|
||||
//CS_URL
|
||||
const uploader = new Upload(oFile, {
|
||||
endpoint: 'http://localhost:3001' + CS_TUS_UPLOAD,
|
||||
chunkSize: 10* 1024 * 1024,
|
||||
headers: {
|
||||
Authorization: "",
|
||||
AUTH_USER_ID: "",
|
||||
},
|
||||
metadata: {
|
||||
filename: oFile.name,
|
||||
filetype: oFile.type,
|
||||
},
|
||||
onError(error) {
|
||||
console.error(`Failed because: ${error}`);
|
||||
},
|
||||
onProgress(bytesUploaded, bytesTotal) {
|
||||
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
|
||||
options?.handleProgress?.(percentage);
|
||||
},
|
||||
onAfterResponse(req, res) {
|
||||
const fileInfo = res.getHeader("X-File-Info");
|
||||
if (fileInfo === undefined || fileInfo === null) return;
|
||||
|
||||
options?.handleResponse?.(res);
|
||||
},
|
||||
onSuccess(payload :OnSuccessPayload) {
|
||||
options?.handleSuccess?.(payload);
|
||||
},
|
||||
options?.handleUploadStart?.(uploader);
|
||||
uploader.start();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
reject(e as DetailedError);
|
||||
}
|
||||
// setUpload(uploader);
|
||||
});
|
||||
uploader.start();
|
||||
|
||||
options?.handleUploadStart?.(uploader);
|
||||
|
||||
console.log("upload start >>>>>", uploader);
|
||||
|
||||
|
||||
// setUpload(uploader);
|
||||
}
|
||||
//
|
||||
//
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
SelectBox,
|
||||
type SelectDataType,
|
||||
} from "@common/business_components";
|
||||
import { Button, Input } from "@common/components";
|
||||
import { Button, Checkbox, Input } from "@common/components";
|
||||
import { Check } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFieldArray } from "react-hook-form";
|
||||
|
||||
@@ -42,18 +43,15 @@ export default function BdstReg({ form }: { form: any }) {
|
||||
// remove(fields.length - 1);
|
||||
// }
|
||||
// };
|
||||
// 이건 삭제해도되는거
|
||||
const removeSelected = () => {
|
||||
// fields 배열에서 selectedIds 에 포함된 field.id 의 인덱스만 골라내기
|
||||
const idxsToRemove = fields
|
||||
.map((f, i) => selectedIds.includes(f.id) ? i : -1)
|
||||
.filter(i => i > -1)
|
||||
// 내림차순 정렬: 인덱스 뒤쪽부터 제거해야 안전합니다.
|
||||
.sort((a,b) => b - a);
|
||||
.map((item, idx) => selectedIds.includes(item.id) ? idx : -1)
|
||||
.filter(index => index > -1)
|
||||
.sort((prevIndex, nextIndex) => nextIndex - prevIndex);
|
||||
|
||||
remove(idxsToRemove);
|
||||
setSelectedIds([]);
|
||||
};
|
||||
remove(idxsToRemove);
|
||||
setSelectedIds([]);
|
||||
};
|
||||
|
||||
|
||||
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | undefined>();
|
||||
@@ -89,9 +87,6 @@ export default function BdstReg({ form }: { form: any }) {
|
||||
return () => subscription?.unsubscribe();
|
||||
}, [form.form]);
|
||||
|
||||
|
||||
|
||||
// 여기서부터는 자유롭게 삭제 가능
|
||||
const [selectedIds, setSelectedIds] = useState<string[]>([]);
|
||||
|
||||
const toggleSelect = (id: string) => {
|
||||
@@ -280,19 +275,13 @@ export default function BdstReg({ form }: { form: any }) {
|
||||
</Button>
|
||||
</div>
|
||||
{fields.map((field, index) => (
|
||||
//여기서부터 자유롭게 삭제 가능
|
||||
<div key={field.id} className="grid grid-cols-[auto,1fr,1fr,1fr] gap-2 mt-4 items-center">
|
||||
{/* 1) 체크박스 */}
|
||||
<div className="col-span-1 flex justify-center mr-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(field.id)}
|
||||
onChange={() => toggleSelect(field.id)}
|
||||
className="h-6 w-6"
|
||||
onCheckedChange={() => toggleSelect(field.id)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 2) 구분 */}
|
||||
<div className="">
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -308,8 +297,6 @@ export default function BdstReg({ form }: { form: any }) {
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 3) 허가일 */}
|
||||
<div className="">
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -328,8 +315,6 @@ export default function BdstReg({ form }: { form: any }) {
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 4) 면적 */}
|
||||
<div className="">
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
||||
@@ -1,135 +1,676 @@
|
||||
"use client";
|
||||
|
||||
import { SelectBox } from "@common/business_components";
|
||||
import {
|
||||
FormUi,
|
||||
} from "@common/business_components/ui";
|
||||
import { Form, FormField } from "@common/business_components/ui/form";
|
||||
import { Button, Input, TableHead, TableRow } from "@common/components";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { use, useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import {
|
||||
selectClass,
|
||||
type TableUpperProps,
|
||||
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import {
|
||||
commonButonSize,
|
||||
formH1Class,
|
||||
formTableName,
|
||||
} from "@/components/lib/class/comClass";
|
||||
import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail";
|
||||
import {
|
||||
businessMoneyInfo,
|
||||
businessSttnInfo,
|
||||
concentratedWaterInfo,
|
||||
ruseFcltinfo,
|
||||
ruseWaterQulityList,
|
||||
wasteWaterFcltINfo,
|
||||
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/headList";
|
||||
import { pbnstRegZod } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import {
|
||||
fcBizSchema,
|
||||
type customPbnst,
|
||||
type fcBizType,
|
||||
type PbnstDemandComType,
|
||||
type ppInstlType,
|
||||
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import {
|
||||
commonButonSize,
|
||||
formH1Class,
|
||||
formTableName,
|
||||
} from "@/components/lib/class/comClass";
|
||||
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 {
|
||||
FormUi,
|
||||
SearchInputSelect,
|
||||
UiModal,
|
||||
type SelectDataType,
|
||||
} from "@common/business_components/ui";
|
||||
import { Form, FormField } from "@common/business_components/ui/form";
|
||||
import {
|
||||
Button,
|
||||
DataTable,
|
||||
DatePicker,
|
||||
Input,
|
||||
Label,
|
||||
} from "@common/components";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFieldArray, useForm } from "react-hook-form";
|
||||
import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail";
|
||||
import { safeDate } from "@/components/lib/func/commom";
|
||||
import SearchInputText from "@/components/ui/searchInput/searchInput";
|
||||
import SdmInsertForm, {
|
||||
type DemandCompType,
|
||||
} from "@common/business_components/ui/sdmInsertForm";
|
||||
|
||||
export function PbnstBuseForm({
|
||||
formType,
|
||||
firstBizData,
|
||||
}: {
|
||||
formType: string;
|
||||
firstBizData?: fcBizType[];
|
||||
}) {
|
||||
const ref = useRef<ppInstlType[] | null>(null);
|
||||
const {
|
||||
code,
|
||||
pbnst,
|
||||
demandCompList,
|
||||
pbnstBizData,
|
||||
getpbnstInsertIndex,
|
||||
appendRuseFclt,
|
||||
getBizCycle,
|
||||
getDemandCompList,
|
||||
regDemandCompany,
|
||||
} = useWrStore((state) => state);
|
||||
const { pbnstBizCycle, pbnstRes } = pbnst;
|
||||
const [bizCycle, setBizCycle] = useState("1");
|
||||
const [ppiSelectList, setPpiSelectList] =
|
||||
useState<[{ name: string; val: SelectDataType[] }]>();
|
||||
const [ppiYn, setPpiYn] = useState("Y");
|
||||
const [isFcOrgwts, setIsFcOrgwts] = useState<boolean>(false);
|
||||
const [sumCpct, setSumCpct] = useState<number>(0);
|
||||
const [isDmdModal, setIsDmdModal] = useState<{
|
||||
isMoal: boolean;
|
||||
data: DemandCompType;
|
||||
}>({ isMoal: false, data: {} as DemandCompType });
|
||||
|
||||
export function PbnstBuseForm() {
|
||||
const { code, pbnst } = useWrStore((state) => state);
|
||||
const { pubMngUpHeadList,pbnstBizCycle } = pbnst;
|
||||
const [getBizCycle, setBizCycle] = useState('');
|
||||
|
||||
|
||||
const form = useForm<z.infer<typeof pbnstRegZod>>({
|
||||
resolver: zodResolver(pbnstRegZod),
|
||||
|
||||
const form = useForm<fcBizType>({
|
||||
resolver: zodResolver(fcBizSchema),
|
||||
defaultValues:
|
||||
formType === "reg" &&
|
||||
pbnst.pbnstMngRegData &&
|
||||
pbnst.pbnstMngRegData[0]?.fcBizs
|
||||
? (pbnst.pbnstMngRegData[0].fcBizs[0] ?? {})
|
||||
: formType === "update" &&
|
||||
typeof pbnst.pbnsUpdateIndex.biz === "number" &&
|
||||
pbnst.pbnsUpdateIndex.biz >= 0 &&
|
||||
pbnst.pbnstRes
|
||||
? pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]?.fcBizs[
|
||||
pbnst.pbnsUpdateIndex.biz
|
||||
]
|
||||
: fcBizSchema.parse({}),
|
||||
});
|
||||
|
||||
// 2. Define a submit handler.
|
||||
function onSubmit(values: z.infer<typeof pbnstRegZod>) {
|
||||
// Do something with the form values.
|
||||
// ✅ This will be type-safe and validated.
|
||||
console.log(values);
|
||||
function onSubmit(values: fcBizType) {
|
||||
// console.log(values);
|
||||
}
|
||||
const onSelectValue = (val: string) => {
|
||||
console.log(val);
|
||||
|
||||
// 2. Define a submit handler.
|
||||
function addRuseFcltObj() {
|
||||
const newItem = fcBizSchema.parse({});
|
||||
const index = pbnst.pbnsUpdateIndex.mng;
|
||||
|
||||
let regData: fcBizType = {} as fcBizType;
|
||||
if (
|
||||
pbnst.pbnstRes &&
|
||||
pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng] &&
|
||||
pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]?.fcBizs
|
||||
) {
|
||||
regData = {
|
||||
pbnstRuseFcltFk:
|
||||
String(pbnst.pbnstRes[0]?.swtrmtFcltFk) +
|
||||
String(pbnst.pbnstRes.length + 1),
|
||||
cycl: Number(
|
||||
(pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]?.fcBizs?.length || 0) + 1
|
||||
),
|
||||
} as fcBizType;
|
||||
|
||||
const newPbnstRes = [...(pbnst.pbnstRes as customPbnst[])];
|
||||
newPbnstRes[index]?.fcBizs?.length &&
|
||||
newPbnstRes[index]?.fcBizs?.push(regData);
|
||||
getBizCycle(newPbnstRes[index] as customPbnst);
|
||||
appendRuseFclt(newPbnstRes);
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
fields: fcDemands,
|
||||
append: appendDemand,
|
||||
remove: removeDemand,
|
||||
} = useFieldArray({
|
||||
control: form.control,
|
||||
name: "fcDemands",
|
||||
});
|
||||
|
||||
const { fields: fcOrgwtFiled } = useFieldArray({
|
||||
control: form.control,
|
||||
name: "fcOrgwts",
|
||||
});
|
||||
|
||||
const {
|
||||
fields: pplInstls,
|
||||
append,
|
||||
remove,
|
||||
} = useFieldArray({
|
||||
control: form.control,
|
||||
name: "pplInstls",
|
||||
});
|
||||
|
||||
// 등록할때 신규 값을 계속 가지고 있으려고
|
||||
useEffect(() => {
|
||||
const formData = form.watch();
|
||||
|
||||
formData.pplInstls = ref.current ? [...ref.current] : []; // ← form 내부 상태 기준으로 복사
|
||||
if (formType === "reg") {
|
||||
if (
|
||||
firstBizData &&
|
||||
firstBizData[0] &&
|
||||
(form.getValues("pbnstRuseFcltFk") === "" ||
|
||||
form.getValues("pbnstRuseFcltFk") === undefined)
|
||||
) {
|
||||
form.setValue(
|
||||
"pbnstRuseFcltFk",
|
||||
String(firstBizData[0].pbnstRuseFcltFk)
|
||||
);
|
||||
form.setValue("cycl", firstBizData[0].cycl);
|
||||
}
|
||||
pbnstBizData(formData as fcBizType);
|
||||
}else if(formType === "update"){
|
||||
|
||||
console.log('formdata ', formData)
|
||||
pbnstBizData(formData as fcBizType);
|
||||
|
||||
|
||||
}
|
||||
}, [firstBizData, form.formState, formType, pbnst.pbnstRes]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (ppiYn === "N") {
|
||||
form.setValue("pplInstls", []);
|
||||
}
|
||||
}, [ppiYn]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("pbnst. bug pbnstMngRegData ", pbnst.pbnstMngRegData);
|
||||
}, [pbnst.pbnstMngRegData]);
|
||||
|
||||
const plusHist = () => {
|
||||
const regData = {
|
||||
ruseFcltBizFk: ref.current?.[0]?.ruseFcltBizFk ?? form.getValues('pbnstRuseFcltBizPk'),
|
||||
choose: false,
|
||||
ppMqlt: "",
|
||||
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 = () => {
|
||||
appendDemand({
|
||||
dmdCoNm: "",
|
||||
daddr: "",
|
||||
useUsgCd: "",
|
||||
splyBgngDay: new Date(),
|
||||
splyEndDay: new Date(),
|
||||
splyCpct: 0,
|
||||
splyFmYn: "Y",
|
||||
pbnstRuseFcltBizPk: form.getValues('pbnstRuseFcltBizPk'),
|
||||
pbnstRuseFcltFk: form.getValues('pbnstRuseFcltFk')??'',
|
||||
//telno: "",
|
||||
});
|
||||
};
|
||||
|
||||
const removeSelected = () => {
|
||||
if (!ref.current) return;
|
||||
const selectedIdxs = ref.current
|
||||
.map((item, idx) => (item.choose ? idx : -1))
|
||||
.filter((idx) => idx !== -1);
|
||||
selectedIdxs.reverse().forEach((idx) => remove(idx));
|
||||
};
|
||||
|
||||
const [instlAprvDate, setInstlAprvDate] = useState(new Date());
|
||||
const [bizCmcnDate, setBizCmcnDate] = useState(new Date());
|
||||
const [files, setFiles] = useState(null);
|
||||
useEffect(() => {
|
||||
if (getBizCycle ) {
|
||||
console.log("getBizCycle", getBizCycle);
|
||||
if (bizCycle && formType !== "reg") {
|
||||
const index = Number(bizCycle) - 1;
|
||||
form.reset(pbnst.pbnstResObj?.fcBizs[index]);
|
||||
ref.current = pbnst.pbnstResObj?.fcBizs[index]?.pplInstls ?? [];
|
||||
}
|
||||
}, [getBizCycle]);
|
||||
}, [bizCycle, pbnst.pbnstResObj, formType]);
|
||||
|
||||
useEffect(() => {
|
||||
const ppl = [] as { name: string; val: SelectDataType[] }[];
|
||||
if (code.pplLenght) {
|
||||
ppl.push({ name: "pplLenght", val: code.pplLenght });
|
||||
}
|
||||
if (code.pplLenght) {
|
||||
ppl.push({ name: "pplQulity", val: code.pplQulity });
|
||||
}
|
||||
if (ppl.length > 0) {
|
||||
setPpiSelectList(ppl);
|
||||
} else {
|
||||
setPpiSelectList(undefined);
|
||||
}
|
||||
}, [code]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("form errors:", form.formState.errors);
|
||||
}, [form.formState.errors]);
|
||||
|
||||
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>
|
||||
|
||||
<SelectBox
|
||||
label=""
|
||||
selectArray={pbnstBizCycle}
|
||||
value={pbnstBizCycle.length > 0 && pbnstBizCycle[0]? pbnstBizCycle[0].val : ""}
|
||||
className={""}
|
||||
selectClass={selectClass}
|
||||
onSelectValue={(val) => {setBizCycle}}
|
||||
>
|
||||
<>
|
||||
<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={bizCycle ?? pbnstBizCycle[0]?.val}
|
||||
className={""}
|
||||
selectClass={selectClass}
|
||||
onSelectValue={(val) => {
|
||||
setBizCycle(String(val));
|
||||
getpbnstInsertIndex({
|
||||
...pbnst.pbnsUpdateIndex,
|
||||
biz: Number(val),
|
||||
});
|
||||
}}
|
||||
></SelectBox>
|
||||
|
||||
</SelectBox>
|
||||
|
||||
<Button size={commonButonSize}>저장</Button>
|
||||
<Button
|
||||
onClick={addRuseFcltObj}
|
||||
type="button"
|
||||
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={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={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"
|
||||
/>
|
||||
|
||||
<h1 className={formH1Class}>재이용 원수취수 현황</h1>
|
||||
</form>
|
||||
</Form>
|
||||
<h1 className={formH1Class}>재이용 원수취수 현황</h1>
|
||||
<div>
|
||||
<div className="text-right mb-3">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => setIsFcOrgwts(true)}
|
||||
size={commonButonSize}
|
||||
className=""
|
||||
>
|
||||
추가등록
|
||||
</Button>
|
||||
</div>
|
||||
<RuseMngTable
|
||||
tableData={fcOrgwtFiled}
|
||||
headList={pbnst.pbnstOrgwtHeadList}
|
||||
upHeadList={[]}
|
||||
/>
|
||||
</div>
|
||||
<h1 className={formH1Class}>재이용 공급관로 설치 현황</h1>
|
||||
<div className="flex items-center gap-4 mx-3 mb-3">
|
||||
<Label className="text-right">공급관로설치유무</Label>
|
||||
<SelectBox
|
||||
label=""
|
||||
selectArray={code.yn}
|
||||
value={ppiYn}
|
||||
className="w-32"
|
||||
selectClass="w-full"
|
||||
onSelectValue={(val) => setPpiYn(String(val))}
|
||||
/>
|
||||
<Label className="text-right">합계</Label>
|
||||
<Input
|
||||
type="text"
|
||||
value={sumCpct}
|
||||
readOnly={true}
|
||||
className="w-32 border-gray-300 rounded pr-8 "
|
||||
/>
|
||||
{ppiYn === "Y" ? (
|
||||
<>
|
||||
<Button
|
||||
type="button"
|
||||
size={commonButonSize}
|
||||
className="!text-xl"
|
||||
onClick={plusHist}
|
||||
>
|
||||
추가등록
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
size={commonButonSize}
|
||||
className="!text-xl !bg-red-500 !text-white ml-1"
|
||||
onClick={removeSelected}
|
||||
>
|
||||
삭제
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<RuseMngTable
|
||||
tableData={pplInstls}
|
||||
headList={pbnst.pplInstlsHeadLisat}
|
||||
code={ppiSelectList ?? []}
|
||||
ref={ref}
|
||||
upHeadList={[]}
|
||||
onTableSet={(val) => {
|
||||
if (!ref.current) return;
|
||||
let sum = 0;
|
||||
ref.current.forEach((item) => {
|
||||
sum += Number(item.cpct) || 0;
|
||||
});
|
||||
setSumCpct(sum);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MngRegFormDetail
|
||||
formList={ruseWaterQulityList}
|
||||
h1Title={"하수처리수 재이용시설 보증수질"}
|
||||
form={form}
|
||||
moClass="grid grid-cols-12 gap-4"
|
||||
sonClass="col-span-4"
|
||||
/>
|
||||
<div key={"hasu"}>
|
||||
<h1 className={formH1Class}>{"하수처리수 재이용수 수요처"}</h1>
|
||||
<div className="text-right mb-3">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
plusArray();
|
||||
}}
|
||||
size={commonButonSize}
|
||||
className="mt-6 mr-3"
|
||||
>
|
||||
수요항목 추가
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setIsDmdModal({
|
||||
isMoal: true,
|
||||
data: {} as DemandCompType,
|
||||
});
|
||||
}}
|
||||
size={commonButonSize}
|
||||
className="mt-6"
|
||||
>
|
||||
수요처 추가
|
||||
</Button>
|
||||
</div>
|
||||
{fcDemands.map((field, index) => (
|
||||
<div
|
||||
key={index + "loot"}
|
||||
className="grid grid-cols-12 gap-4 mt-3"
|
||||
>
|
||||
<div key={index + "keySon1"} className="col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.dmdCoNm`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="수요처명">
|
||||
<SearchInputText
|
||||
label={undefined}
|
||||
initValue={f.value}
|
||||
setValue={(val) => {
|
||||
f.onChange(val);
|
||||
|
||||
if (val) getDemandCompList(val, 3);
|
||||
}}
|
||||
setRtnData={(valList: PbnstDemandComType[]) => {
|
||||
console.log('valList[0] ', index)
|
||||
if (
|
||||
valList.length > 0 &&
|
||||
valList['0']
|
||||
) {
|
||||
form.setValue(
|
||||
`fcDemands.${index}.pbnstRuseFcltBizPk`,
|
||||
form.getValues('pbnstRuseFcltBizPk')
|
||||
);
|
||||
form.setValue(
|
||||
`fcDemands.${index}.pbnstRuseFcltFk`,
|
||||
form.getValues('pbnstRuseFcltFk')??''
|
||||
|
||||
);
|
||||
form.setValue(
|
||||
`fcDemands.${index}.dmdCoNm`,
|
||||
valList['0'].dmdCoNm
|
||||
);
|
||||
form.setValue(
|
||||
`fcDemands.${index}.daddr`,
|
||||
valList['0'].daddr
|
||||
);
|
||||
form.setValue(
|
||||
`fcDemands.${index}.useUsgCd`,
|
||||
valList['0'].useUsgCd
|
||||
);
|
||||
form.setValue(
|
||||
`fcDemands.${index}.splyCpct`,
|
||||
valList['0'].splyCpct
|
||||
);
|
||||
form.setValue(
|
||||
`fcDemands.${index}.splyFmYn`,
|
||||
valList['0'].splyFmYn ?? "Y"
|
||||
);
|
||||
|
||||
form.setValue(
|
||||
`fcDemands.${index}.dmdInfoPk`,
|
||||
valList['0'].dmdInfoPk ?? "Y"
|
||||
);
|
||||
}
|
||||
|
||||
}}
|
||||
></SearchInputText>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div key={index + "keySon2"} className="col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.daddr`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="위치(주소)">
|
||||
<Input
|
||||
placeholder="-"
|
||||
type="text"
|
||||
readOnly
|
||||
onChange={(e) => f.onChange(e.target.value)}
|
||||
value={f.value}
|
||||
className={selectClass}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div key={index + "keySon3"} className="col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.useUsgCd`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="사용용도">
|
||||
<SelectBox
|
||||
label={""}
|
||||
selectClass={""}
|
||||
className="w-full"
|
||||
selectArray={code.dmdUszCd}
|
||||
onSelectValue={(val: string | number) =>
|
||||
f.onChange(val)
|
||||
}
|
||||
value={f.value}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div key={index + "keySon4"} className="col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.splyBgngDay`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="공급시작일">
|
||||
<DatePicker
|
||||
mode={"single"}
|
||||
selected={safeDate(f.value) || new Date()}
|
||||
onSelect={(date: Date | undefined) =>
|
||||
f.onChange(date)
|
||||
}
|
||||
className={"rounded-lg !w-full"}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div key={index + "keySon5"} className="col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.splyEndDay`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="공급종료일">
|
||||
<DatePicker
|
||||
mode={"single"}
|
||||
selected={safeDate(f.value) || new Date()}
|
||||
onSelect={(date: Date | undefined) =>
|
||||
f.onChange(date)
|
||||
}
|
||||
className={"rounded-lg !w-full"}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div key={index + "keySon6"} className="col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.splyCpct`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="(계약)공급량(m3/일)">
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
value={f.value ?? 0}
|
||||
onChange={(e) => {
|
||||
f.onChange(Number(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div key={index + "keySon7"} className="col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`fcDemands.${index}.splyFmYn`}
|
||||
render={({ field: f }) => (
|
||||
<FormUi label="공급 유량계 유무">
|
||||
<SelectBox
|
||||
label={""}
|
||||
selectClass={""}
|
||||
className="w-full"
|
||||
selectArray={code.yn}
|
||||
onSelectValue={(val: string | number) =>
|
||||
f.onChange(val)
|
||||
}
|
||||
value={f.value}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
<UiModal
|
||||
open={isFcOrgwts}
|
||||
onOpenChange={(open: boolean) => setIsFcOrgwts(open)}
|
||||
bodyClass={"w-[50vw] max-w-none h-[60vh]"}
|
||||
body={
|
||||
<FcOrgwtsRegModal
|
||||
closeModal={() => {
|
||||
setIsFcOrgwts(false);
|
||||
}}
|
||||
onRightSet={(val) => {
|
||||
form.setValue("fcOrgwts", val);
|
||||
}}
|
||||
></FcOrgwtsRegModal>
|
||||
}
|
||||
></UiModal>
|
||||
|
||||
<UiModal
|
||||
bodyClass={"w-[40vw] max-w-none h-[90vh]"}
|
||||
open={isDmdModal.isMoal}
|
||||
onOpenChange={() => {
|
||||
setIsDmdModal({ isMoal: false, data: {} as DemandCompType });
|
||||
}}
|
||||
body={
|
||||
<SdmInsertForm
|
||||
selectSidoData={code.cityCd}
|
||||
selectSigunData={code.sggCd}
|
||||
dataList={demandCompList}
|
||||
rtnValue={(searchText: string, pageCnt: number) => {
|
||||
getDemandCompList(searchText, pageCnt);
|
||||
}}
|
||||
rtnInputData={(data) => {
|
||||
console.log(" rtn data ", data);
|
||||
regDemandCompany(data as DemandCompType);
|
||||
setIsDmdModal({ isMoal: false, data: data as DemandCompType });
|
||||
}}
|
||||
bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"}
|
||||
></SdmInsertForm>
|
||||
}
|
||||
></UiModal>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,146 +1,314 @@
|
||||
"use client";
|
||||
|
||||
import { SelectBox } from "@common/business_components";
|
||||
import { FileUpload, FormUi, UiTable } from "@common/business_components/ui";
|
||||
import { Form, FormField } from "@common/business_components/ui/form";
|
||||
import { Button, Input, TableHead, TableRow } from "@common/components";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useEffect, useState } from "react";
|
||||
import { set, useForm } from "react-hook-form";
|
||||
import { nullable, z } from "zod";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import {
|
||||
selectClass,
|
||||
type TableUpperProps,
|
||||
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
|
||||
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 { useFieldArray, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
commonButonSize,
|
||||
formH1Class,
|
||||
formH2Class,
|
||||
formTableName,
|
||||
} from "@/components/lib/class/comClass";
|
||||
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
|
||||
import { TusClientUpload } from "@/components/lib/useTus_wr/useTusWr";
|
||||
import type { Upload } from "tus-js-client";
|
||||
import type { fcltOperInfoType, ruseFcltType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
|
||||
import {
|
||||
pbnstRegZod,
|
||||
type customPbnst,
|
||||
type fcBizType,
|
||||
type fcFileType,
|
||||
type operType,
|
||||
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";
|
||||
import React from "react";
|
||||
export type FilesType = {
|
||||
atflCd: string;
|
||||
file: File;
|
||||
};
|
||||
|
||||
const formSchema = z.object({
|
||||
fcltNm: z.string().min(2).max(50),
|
||||
psysScdg: z.string(),
|
||||
designScdg: z.string(),
|
||||
fcltCpct: z.number(),
|
||||
swtrmtCpct: z.number(),
|
||||
ruseCpct: z.number(),
|
||||
splyExtraCpct: z.number(),
|
||||
});
|
||||
export function PbnstMngForm({
|
||||
formType,
|
||||
firstFcltData,
|
||||
}: {
|
||||
formType: string;
|
||||
firstFcltData?: customPbnst;
|
||||
}) {
|
||||
const {
|
||||
pbnst,
|
||||
pbnstInsert,
|
||||
pbnstMngData,
|
||||
fileDelete,
|
||||
fileDownLoad,
|
||||
getBizCycle,
|
||||
getpbnstInsertIndex,
|
||||
appendRuseFclt
|
||||
} = useWrStore((state) => state);
|
||||
|
||||
export function PbnstMngForm({ data }: { data: ruseFcltType[] }) {
|
||||
const { pbnst } = useWrStore((state) => state);
|
||||
const { pubMngUpHeadList, isInit } = pbnst;
|
||||
const [ruseOperData, setRuseOperData] = useState<fcltOperInfoType[]>();
|
||||
const [planFiles, setPlanFiles] = useState<File[] | null>(null);
|
||||
const [relationfiles, setRelationFiles] = useState<File[] | null>(null);
|
||||
const [regFileList, setRegFileList] = useState<fcFileType[] | null>(null);
|
||||
const [planFiles, setPlanFiles] = useState<FilesType[] | null>(null);
|
||||
const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null);
|
||||
const [fcltNm, setFcltNm] = useState<selectLabel[] | null>(null);
|
||||
const [fcOpresData, setFcOpresData] = useState<operType[] | null>(null);
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const [upload, setUpload] = useState<Upload | null>(null);
|
||||
const [progress, setProgress] = useState(0);
|
||||
//const new File([] as BlobPart[], "") 파일 다운로드 활용
|
||||
const ref = useRef<operType[] | null>(null);
|
||||
|
||||
const form = useForm<z.infer<typeof pbnstRegZod>>({
|
||||
resolver: zodResolver(pbnstRegZod),
|
||||
defaultValues:
|
||||
formType === "reg" && pbnst.pbnstMngRegData
|
||||
? pbnst.pbnstMngRegData[0]
|
||||
: formType === "update" &&
|
||||
typeof pbnst.pbnsUpdateIndex.mng === "number" &&
|
||||
pbnst.pbnsUpdateIndex.mng >= 0 &&
|
||||
pbnst.pbnstRes
|
||||
? pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng]
|
||||
: pbnstRegZod.parse({}),
|
||||
});
|
||||
const {
|
||||
fields: fcOpersField,
|
||||
append,
|
||||
remove,
|
||||
} = useFieldArray({
|
||||
control: form.control,
|
||||
name: "fcOpers",
|
||||
});
|
||||
|
||||
const handleProgress = (percentage: string) => {
|
||||
|
||||
console.log("handleProgress", percentage);
|
||||
setProgress(Number(percentage));
|
||||
};
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
fcltNm: "",
|
||||
psysScdg: "",
|
||||
designScdg: "",
|
||||
fcltCpct: 0,
|
||||
swtrmtCpct: 0,
|
||||
ruseCpct: 0,
|
||||
splyExtraCpct: 0,
|
||||
},
|
||||
});
|
||||
const selectFclt = (val: number) => {
|
||||
if (pbnst.pbnstRes && pbnst.pbnstRes[val]) {
|
||||
getBizCycle(pbnst.pbnstRes[val]);
|
||||
form.reset(pbnst.pbnstRes[val]);
|
||||
getpbnstInsertIndex({ ...pbnst.pbnsUpdateIndex, mng: val });
|
||||
}
|
||||
};
|
||||
|
||||
const selectOptions = data?.map((item) => ({
|
||||
text: item.fcltNm,
|
||||
val: item.pbnstRuseFcltPk,
|
||||
})) || [{ text: "없음", val: "1" }];
|
||||
|
||||
const onSelectValue = (val: string) => {};
|
||||
const plusHist = () => {
|
||||
const currentTableDataFromRef = ref.current ? [...ref.current] : [];
|
||||
const regData = {
|
||||
choose: false,
|
||||
pbnstRuseFcltFk:form.getValues('pbnstRuseFcltPk')??"",
|
||||
rgtr: "",
|
||||
mdfr: "",
|
||||
operMthd: "",
|
||||
rprtvBzenty: "",
|
||||
bgngDt: new Date(),
|
||||
endDt: new Date(),
|
||||
};
|
||||
const newDataForRHF = [...currentTableDataFromRef, regData];
|
||||
form.setValue("fcOpers", newDataForRHF, {
|
||||
shouldValidate: true, // 필요하다면 유효성 검사 실행
|
||||
shouldDirty: true, // 폼 상태를 dirty로 변경
|
||||
});
|
||||
};
|
||||
|
||||
const removeSelected = () => {
|
||||
if (!ref.current) return;
|
||||
const selectedIdxs = ref.current
|
||||
.map((item, idx) => (item.choose ? idx : -1))
|
||||
.filter((idx) => idx !== -1);
|
||||
selectedIdxs.reverse().forEach((idx) => remove(idx));
|
||||
};
|
||||
|
||||
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 (
|
||||
!fileList ||
|
||||
fileList?.findIndex((reFile) => reFile.file === item) < 0
|
||||
) {
|
||||
TusClientUpload({ atflCd: "", file: item })
|
||||
.then((tusFile) => {
|
||||
setReFiles.push({
|
||||
atflCd: tusFile.atflCd.toString(),
|
||||
file: item,
|
||||
});
|
||||
type === "relation"
|
||||
? setRelationFiles(setReFiles)
|
||||
: setPlanFiles(setReFiles);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
return item;
|
||||
}
|
||||
});
|
||||
} else if (fileList && (!files || fileList.length > files.length)) {
|
||||
if (!files) {
|
||||
fileList.forEach((file) => {
|
||||
fileDelete(file.atflCd as string);
|
||||
});
|
||||
setReFiles = [];
|
||||
setReFiles.length = 0;
|
||||
} else {
|
||||
fileList?.forEach((item, index) => {
|
||||
const idx = files?.indexOf(item.file);
|
||||
if (idx < 0) {
|
||||
setReFiles.splice(index);
|
||||
fileDelete(item.atflCd as string);
|
||||
}
|
||||
});
|
||||
}
|
||||
type === "relation"
|
||||
? setRelationFiles(setReFiles)
|
||||
: setPlanFiles(setReFiles);
|
||||
}
|
||||
};
|
||||
|
||||
const regFileFilter = (
|
||||
files: FilesType[],
|
||||
fileKnd: string,
|
||||
regFile: fcFileType[]
|
||||
) => {
|
||||
const exFileDatas =
|
||||
regFile?.filter((item) => item.fileKnd !== fileKnd) || [];
|
||||
const currentdata = files.map((item) => ({
|
||||
fileTkn: item.atflCd,
|
||||
filePath: item.file.name,
|
||||
fileKnd: fileKnd,
|
||||
rgtr: TEST_UUID,
|
||||
mdfr: TEST_UUID,
|
||||
}));
|
||||
return [...exFileDatas, ...currentdata];
|
||||
};
|
||||
|
||||
// 등록할때 신규 값을 계속 가지고 있으려고
|
||||
useEffect(() => {
|
||||
if (
|
||||
firstFcltData &&
|
||||
(form.getValues("swtrmtFcltFk") === "" ||
|
||||
form.getValues("swtrmtFcltFk") === undefined)
|
||||
) {
|
||||
form.setValue("swtrmtFcltFk", firstFcltData.swtrmtFcltFk);
|
||||
form.setValue(
|
||||
"pbnstRuseFcltPk",
|
||||
String(firstFcltData.swtrmtFcltFk + "1")
|
||||
);
|
||||
form.setValue("fcBizs", firstFcltData.fcBizs);
|
||||
}
|
||||
}, [firstFcltData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isInit) {
|
||||
form.reset();
|
||||
setRuseOperData([{}] as fcltOperInfoType[]);
|
||||
const defaultFiles = form.getValues("fcFiles");
|
||||
|
||||
if (defaultFiles && defaultFiles.length > 0) {
|
||||
const relationFileList = defaultFiles.filter(
|
||||
(item) => item.fileKnd === "계통도"
|
||||
);
|
||||
|
||||
const planFileList = defaultFiles.filter(
|
||||
(item) => item.fileKnd === "평면도"
|
||||
);
|
||||
if (relationFileList.length > 0)
|
||||
setRelationFiles(
|
||||
relationFileList.map((item) => ({
|
||||
atflCd: item.fileTkn,
|
||||
file: new File([] as BlobPart[], item.filePath),
|
||||
}))
|
||||
); // 또는 파일 형식 변환 로직이 있다면 여기에 추가
|
||||
|
||||
if (planFileList.length > 0)
|
||||
setPlanFiles(
|
||||
planFileList.map((item) => ({
|
||||
atflCd: item.fileTkn,
|
||||
file: new File([] as BlobPart[], item.filePath),
|
||||
}))
|
||||
);
|
||||
}
|
||||
}, [isInit]);
|
||||
}, [form.formState.defaultValues]); // 초기화 이후 1회 실행
|
||||
|
||||
// 등록할때 신규 값을 계속 가지고 있으려고
|
||||
useEffect(() => {
|
||||
if (
|
||||
formType === "update" &&
|
||||
pbnst.pbnsUpdateIndex.biz >= 0 &&
|
||||
pbnst.pbnstRes
|
||||
) {
|
||||
const bizData = pbnst.pbnstRes[pbnst.pbnsUpdateIndex.biz];
|
||||
|
||||
if (bizData) {
|
||||
getBizCycle(bizData);
|
||||
}
|
||||
}
|
||||
}, [pbnst.pbnsUpdateIndex, pbnst.pbnstRes, formType, getBizCycle]);
|
||||
|
||||
//신규 등록시 입력할때 데이터 넣기
|
||||
useEffect(() => {
|
||||
const formData = form.watch();
|
||||
formData.fcOpers = ref.current ? [...ref.current] : [];
|
||||
formData.fcFiles = regFileList ? [...regFileList] : [];
|
||||
if (formType === "reg") {
|
||||
pbnstMngData([formData] as customPbnst[]);
|
||||
} else if (formType === "update"){
|
||||
const updateRes = pbnst.pbnstRes?.map((item)=>{
|
||||
if(item.pbnstRuseFcltPk === item.pbnstRuseFcltPk){
|
||||
item=formData as customPbnst
|
||||
}
|
||||
return item
|
||||
})
|
||||
pbnstMngData(updateRes as customPbnst[]);
|
||||
}
|
||||
}, [form.formState, regFileList, formType, pbnst.pbnstRes]);
|
||||
|
||||
useEffect(() => {
|
||||
pbnstMngData(pbnst.pbnstMngRegData);
|
||||
}, [pbnst.pbnstMngRegData]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if ( pbnst.pbnstRes && pbnst.pbnstRes?.length<= 0) return;
|
||||
const fcltNmList = pbnst.pbnstRes?.map((item, index) => ({
|
||||
text: item.ruseUtztnFcltNm,
|
||||
val: String(index),
|
||||
}));
|
||||
|
||||
if(fcltNmList)
|
||||
setFcltNm(fcltNmList);
|
||||
|
||||
}, [pbnst.pbnstRes]);
|
||||
|
||||
// 2. Define a submit handler.
|
||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
console.log(values);
|
||||
function onSubmit(values: z.infer<typeof pbnstRegZod>) {
|
||||
values.fcOpers = fcOpresData || [];
|
||||
values.fcFiles = regFileList || [];
|
||||
pbnstInsert(values);
|
||||
}
|
||||
|
||||
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(() => {
|
||||
if (relationfiles && relationfiles[0])
|
||||
console.log("relationfiles ", relationfiles[0]);
|
||||
|
||||
// TusClientUpload(
|
||||
// relationfiles[0],{
|
||||
// handleUploadStart: setUpload,
|
||||
// handleProgress,
|
||||
// handleSuccess: setUpload,
|
||||
// })
|
||||
if (relationfiles) {
|
||||
setRegFileList(regFileFilter(relationfiles, "계통도", regFileList || []));
|
||||
}
|
||||
}, [relationfiles]);
|
||||
const headMakeColSpan = (upHeadList: TableUpperProps[]) => {
|
||||
return (
|
||||
<>
|
||||
<TableRow>
|
||||
{upHeadList.map((head: TableUpperProps) =>
|
||||
!head.upSequnce ? (
|
||||
<TableHead rowSpan={2} key={head.id}>
|
||||
{head.title}
|
||||
</TableHead>
|
||||
) : head.upName === "upChangeRe" && head.upSequnce === 1 ? (
|
||||
<TableHead key={head.id} rowSpan={1} colSpan={2}>
|
||||
{"운영대행기간"}
|
||||
</TableHead>
|
||||
) : null
|
||||
)}
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
{upHeadList.map((head: TableUpperProps) =>
|
||||
head.upName === "upChangeRe" ? (
|
||||
<TableHead key={head.id}>{head.title}</TableHead>
|
||||
) : null
|
||||
)}
|
||||
</TableRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
const nodeList = headMakeColSpan(pubMngUpHeadList);
|
||||
useEffect(() => {
|
||||
if (planFiles) {
|
||||
setRegFileList(regFileFilter(planFiles, "평면도", regFileList || []));
|
||||
}
|
||||
}, [planFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("form errors:", form.formState.errors);
|
||||
}, [form.formState.errors]);
|
||||
|
||||
return (
|
||||
<div className=" !mx-[1.6rem] !p-0r">
|
||||
@@ -149,91 +317,152 @@ export function PbnstMngForm({ data }: { data: ruseFcltType[] }) {
|
||||
<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 "}>
|
||||
<Label className={formTableName + "pr-3 col-span-2 "}>
|
||||
재이용 시설명
|
||||
</h2>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fcltNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<SelectBox
|
||||
label=""
|
||||
selectArray={selectOptions}
|
||||
className={""}
|
||||
selectClass={selectClass}
|
||||
onSelectValue={() => {}}
|
||||
{...field}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</Label>
|
||||
|
||||
{formType === "reg" ? (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="ruseUtztnFcltNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
className="!text-2xl"
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
field.onChange(String(e.target.value));
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<SelectBox
|
||||
label=""
|
||||
className="mt-4 ml-2"
|
||||
selectClass={undefined}
|
||||
selectArray={fcltNm ?? []}
|
||||
onSelectValue={(val) => {
|
||||
selectFclt(Number(val));
|
||||
}}
|
||||
value={""}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* <Button onClick={addRuseFcltObj} type="button" size={commonButonSize}>
|
||||
추가
|
||||
</Button> */}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="h-[200px] overflow-y-auto">
|
||||
<div className="h-[200px] overflow-y-auto">
|
||||
<div className="flex justify-between items-center mx-3 mb-3">
|
||||
<span className={formTableName}>재이용시설 운영정보</span>
|
||||
<Button
|
||||
type="button"
|
||||
size={commonButonSize}
|
||||
className="!text-xl"
|
||||
onClick={() => testFile()}
|
||||
>
|
||||
추가등록
|
||||
</Button>
|
||||
<div>
|
||||
<Button
|
||||
type="button"
|
||||
size={commonButonSize}
|
||||
className="!text-xl"
|
||||
onClick={plusHist}
|
||||
>
|
||||
추가등록
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
size={commonButonSize}
|
||||
className="!text-xl !bg-red-500 !text-white ml-1"
|
||||
onClick={removeSelected}
|
||||
>
|
||||
삭제
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<RuseMngTable
|
||||
tableData={[]}
|
||||
headList={pbnst.pubMngUpHeadList}
|
||||
upHeadList={pbnst.pubMngNm}
|
||||
tableData={fcOpersField}
|
||||
headList={pbnst.pbnstMngUpHeadList}
|
||||
upHeadList={pbnst.pbnstMngNm}
|
||||
onTableSet={(val) => {
|
||||
setFcOpresData(val);
|
||||
}}
|
||||
ref={ref}
|
||||
></RuseMngTable>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className={formH1Class}>재이용수 공급 가능량</h1>
|
||||
<div className="grid grid-cols-12 gap-4">
|
||||
<div className="col-span-3">
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fcltCpct"
|
||||
render={({ field }) => (
|
||||
<FormUi label="시설용량(m³/일)">
|
||||
<Input placeholder="" type="number" {...field} />
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3">
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="swtrmtCpct"
|
||||
name="hasuhasu"
|
||||
render={({ field }) => (
|
||||
<FormUi label="하수처리량(m³/일)">
|
||||
<Input placeholder="" type="number" {...field} />
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3">
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="ruseCpct"
|
||||
render={({ field }) => (
|
||||
<FormUi label="재이용량(m³/일)">
|
||||
<Input placeholder="" type="number" {...field} />
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-3">
|
||||
<div className="col-span-3 mt-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="splyExtraCpct"
|
||||
render={({ field }) => (
|
||||
<FormUi label="공급여유량(m³/일)">
|
||||
<Input placeholder="" type="number" {...field} />
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
value={field.value ?? 0}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
@@ -244,34 +473,40 @@ export function PbnstMngForm({ data }: { data: ruseFcltType[] }) {
|
||||
</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 || []}
|
||||
setFiles={setRelationFiles}
|
||||
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) => {
|
||||
fileDownLoad(
|
||||
relationfiles?.find(
|
||||
(item, fileIndex) => fileIndex === index
|
||||
)?.atflCd as string
|
||||
);
|
||||
}}
|
||||
></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"
|
||||
onFileClick={(index) => {
|
||||
fileDownLoad(
|
||||
planFiles?.find(
|
||||
(item, fileIndex) => fileIndex === index
|
||||
)?.atflCd as string
|
||||
);
|
||||
}}
|
||||
></FileUpload>
|
||||
</FormUi>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+56
-13
@@ -1,8 +1,17 @@
|
||||
'use client'
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { formDetailType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/headList";
|
||||
import { formH1Class } from "@/components/lib/class/comClass";
|
||||
import { safeDate } from "@/components/lib/func/commom";
|
||||
import { FormField, FormUi } from "@common/business_components/ui";
|
||||
import {
|
||||
FormField,
|
||||
FormUi,
|
||||
SearchInputSelect,
|
||||
SelectBox,
|
||||
type SelectDataType,
|
||||
} from "@common/business_components/ui";
|
||||
import { DatePicker, Input } from "@common/components/ui";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function MngRegFormDetail({
|
||||
formList,
|
||||
@@ -10,23 +19,34 @@ export default function MngRegFormDetail({
|
||||
form,
|
||||
moClass,
|
||||
sonClass,
|
||||
cycle,
|
||||
onIputData,
|
||||
searchSelectData
|
||||
}: {
|
||||
formList: formDetailType[];
|
||||
h1Title: string;
|
||||
h1Title?: string;
|
||||
form: any;
|
||||
moClass?: string;
|
||||
cycle?: string;
|
||||
sonClass?: string;
|
||||
onIputData?: (data: any) => void;
|
||||
searchSelectData?: SelectDataType[];
|
||||
}) {
|
||||
const { code } = useWrStore((state) => state);
|
||||
|
||||
const [searchData, setSearchData]= useState<string>('')
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className={formH1Class}>{h1Title}</h1>
|
||||
{h1Title ? <h1 className={formH1Class}>{h1Title}</h1> : <></>}
|
||||
<div className={moClass}>
|
||||
{formList?.map((item, index) => {
|
||||
const fieldId = cycle ? `${cycle}.${item.id}` : item.id;
|
||||
return (
|
||||
<div className={sonClass} key={index + `${item.id}`}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={item.id}
|
||||
name={fieldId}
|
||||
render={({ field }) => (
|
||||
<FormUi label={item.lable}>
|
||||
{item.type === "select" ? (
|
||||
@@ -34,17 +54,39 @@ export default function MngRegFormDetail({
|
||||
) : item.type === "date" ? (
|
||||
<DatePicker
|
||||
mode={"single"}
|
||||
field={{
|
||||
value: safeDate(field.value) || new Date(),
|
||||
onChange: (date: Date | undefined) =>
|
||||
field.onChange(date),
|
||||
}}
|
||||
selectClass={"rounded-lg w-full"}
|
||||
></DatePicker>
|
||||
selected={safeDate(field.value) || new Date()}
|
||||
onSelect={(date: Date | undefined) =>
|
||||
field.onChange(date)
|
||||
}
|
||||
className={"rounded-lg !w-full"}
|
||||
/>
|
||||
) : item.type === "number" ? (
|
||||
<Input placeholder="" type="number" {...field} />
|
||||
<Input
|
||||
placeholder=""
|
||||
type="number"
|
||||
value={field.value ?? 0}
|
||||
onChange={(e) => {
|
||||
field.onChange(Number(e.target.value));
|
||||
}}
|
||||
/>
|
||||
) : item.type === "selectYn" ? (
|
||||
<SelectBox
|
||||
label={""}
|
||||
selectClass={""}
|
||||
className="w-full"
|
||||
selectArray={code.yn}
|
||||
onSelectValue={(val: string | number) =>
|
||||
field.onChange(val)
|
||||
}
|
||||
value={field.value}
|
||||
/>
|
||||
) : (
|
||||
<Input placeholder="" type="" {...field} />
|
||||
<Input
|
||||
placeholder=""
|
||||
type="text"
|
||||
value={field.value ?? ""}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
)}
|
||||
</FormUi>
|
||||
)}
|
||||
@@ -56,3 +98,4 @@ export default function MngRegFormDetail({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel";
|
||||
import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList";
|
||||
import { yearOptions } from "@/components/lib/func/commom";
|
||||
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
|
||||
import {
|
||||
FileUpload,
|
||||
FormField,
|
||||
FormUi,
|
||||
SelectBox,
|
||||
Form,
|
||||
Title,
|
||||
type SelectDataType,
|
||||
filePicked,
|
||||
} from "@common/business_components/ui";
|
||||
import { Button } 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 PbnPrfExcelModal() {
|
||||
const { code, prfmnc, searchFclts } = useWrStore((state) => state);
|
||||
|
||||
|
||||
const [bscFctNmList, setBscFctNmList] = useState<SelectDataType[] | null>(null);
|
||||
const [files, setFiles] = useState<File[] | null>(null);
|
||||
const [excelData, setExcelData] = useState<any[]>();
|
||||
const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({
|
||||
resolver: zodResolver(pbnPrfRegExcelZod),
|
||||
defaultValues: {
|
||||
ym: String(new Date().getFullYear()),
|
||||
},
|
||||
});
|
||||
const onSubmit = (values: z.infer<typeof pbnPrfRegExcelZod>) => {
|
||||
console.log(values);
|
||||
};
|
||||
useEffect(() => {
|
||||
|
||||
if(prfmnc.prfmncRes.length > 0){
|
||||
|
||||
const basFctNmList = prfmnc.prfmncRes.map((item)=>(
|
||||
{
|
||||
val:item.bscFctCd,
|
||||
text:item.bscFctNm
|
||||
}
|
||||
))
|
||||
setBscFctNmList(basFctNmList)
|
||||
}
|
||||
|
||||
}, [prfmnc.prfmncRes]);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
|
||||
if(files){
|
||||
|
||||
const file = files[0];
|
||||
if (form.getValues("ym").length < 1) {
|
||||
ToastFormUi({
|
||||
body: "파일업로드 이전에 등록년도를 작성해주세요 ",
|
||||
title: "지도점검 등록",
|
||||
});
|
||||
setFiles(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(file)
|
||||
filePicked(file, 0).then((res) => {
|
||||
if (res !== undefined)
|
||||
console.log(excelToPbnPrfData(res, form.getValues("ym")))
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
},[files])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<div>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="ym"
|
||||
render={({ field }) => (
|
||||
<FormUi label="등록년도">
|
||||
<SelectBox
|
||||
className="w-1/4 text-3xl"
|
||||
selectClass={""}
|
||||
label=""
|
||||
selectArray={yearOptions}
|
||||
value={field.value}
|
||||
onSelectValue={(val) => field.onChange(val)}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="bscFctNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="시설명">
|
||||
<SelectBox
|
||||
className="w-1/4 text-3xl"
|
||||
selectClass={""}
|
||||
label=""
|
||||
selectArray={bscFctNmList || [] }
|
||||
value={field.value}
|
||||
onSelectValue={(val) => field.onChange(String(val))}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="pbnstRuseFcltNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="재이용시설명">
|
||||
<SelectBox
|
||||
className="w-1/4 text-3xl"
|
||||
selectClass={""}
|
||||
label=""
|
||||
selectArray={yearOptions}
|
||||
value={field.value}
|
||||
onSelectValue={(val) => field.onChange(String(val))}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="file"
|
||||
render={({ field }) => (
|
||||
<FormUi label="점검결과 파일">
|
||||
<FileUpload
|
||||
files={files || []}
|
||||
setFiles={(files: File[] | null) => {
|
||||
if (files) setFiles(files);
|
||||
}}
|
||||
fileTypes="xlsx"
|
||||
></FileUpload>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { pubHasuType, fcBizType, fcOrgwtType,} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { Label } from "@common/business_components/ui/form/lib/label";
|
||||
import { Button } from "@common/business_components/ui/table/lib/button";
|
||||
import { Input } from "@common/components/ui";
|
||||
import { ArrowLeft, ArrowRight } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useFieldArray } from "react-hook-form";
|
||||
|
||||
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(()=>{
|
||||
console.log("searchFclts", searchFclts);
|
||||
if(Array.isArray(searchFclts)){
|
||||
const filteredData = searchFclts.filter((item) => {
|
||||
if(rightData){
|
||||
if(rightData.find(rightItem =>rightItem.bscFctCd===item.bscFctCd))
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
})
|
||||
setbdstTable(Array.isArray(filteredData) ? [...filteredData] : [])
|
||||
}
|
||||
|
||||
}, [searchFclts])
|
||||
useEffect(() => {
|
||||
if (code.sggCd.length > 0 && pbnstHasuRes.length > 0) {
|
||||
setbdstTable(tableData(pbnstHasuRes, { code }));
|
||||
|
||||
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])
|
||||
|
||||
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-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}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type {
|
||||
customPbnst,
|
||||
fcBizType,
|
||||
pubHasuType,
|
||||
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
|
||||
import { ScrollArea } from "@common/business_components";
|
||||
import {
|
||||
Button,
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@common/components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm";
|
||||
|
||||
export function PbnstRegModal({ data }: { data: pubHasuType }) {
|
||||
const { pbnst, pbnstInsert } = useWrStore((state) => {
|
||||
return state;
|
||||
});
|
||||
const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>(
|
||||
{} as customPbnst
|
||||
);
|
||||
const [currentTab, setCurrentTab] = useState<string>("mng");
|
||||
|
||||
const pbnstRegTotal = () => {
|
||||
if (pbnst.pbnstMngRegData[0]) pbnstInsert(pbnst.pbnstMngRegData[0]);
|
||||
};
|
||||
|
||||
const handleTabChange = (value: string) => {
|
||||
setCurrentTab(value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
let regData = {
|
||||
swtrmtFcltFk: String(data.bscFctCd),
|
||||
pbnstRuseFcltPk: String(data.bscFctCd + "1"),
|
||||
fcBizs: [
|
||||
{
|
||||
pbnstRuseFcltFk: String(data.bscFctCd + "1"),
|
||||
cycl: 1,
|
||||
} as unknown as fcBizType,
|
||||
],
|
||||
};
|
||||
|
||||
setPbnstBdstForm(regData as unknown as customPbnst);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {}, [pbnstBdstForm]);
|
||||
useEffect(() => {}, [pbnst.pbnstMngRegData]);
|
||||
return (
|
||||
<>
|
||||
<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>
|
||||
<Button
|
||||
onClick={pbnstRegTotal}
|
||||
size={"sm"}
|
||||
className="!justify-end"
|
||||
>
|
||||
저장
|
||||
</Button>
|
||||
</TabsList>
|
||||
<TabsContent className="max-h-full" value="mng">
|
||||
<PbnstMngForm formType={"reg"} firstFcltData={pbnstBdstForm} />
|
||||
</TabsContent>
|
||||
<TabsContent className="max-h-full" value="buse">
|
||||
<PbnstBuseForm formType={"reg"} firstBizData={pbnstBdstForm.fcBizs} />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</ScrollArea>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
import { useWrStore } from '@/app/store';
|
||||
import type { PbnstDemandComType } from '@/app/store/ruseFcltMng/fcltReg/pbnstReg/type';
|
||||
import type { DemandCompType } from '@common/business_components/ui';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
type thisProps = {
|
||||
label: string | undefined;
|
||||
initValue: string | undefined;
|
||||
setValue : (dmdCoNm?: string) => void;
|
||||
setRtnData : (rtnData: PbnstDemandComType[]) => void;
|
||||
}
|
||||
|
||||
|
||||
export default function SearchInputText({label=undefined, initValue=undefined, setValue=()=>{}, setRtnData=()=>{}} :thisProps) {
|
||||
|
||||
const { demandCompList } = useWrStore((state) => state);
|
||||
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [textValue, setTextValue] = useState(initValue || '');
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setTextValue(value);
|
||||
setValue(value);
|
||||
if (value) {
|
||||
setIsOpen(true);
|
||||
} else {
|
||||
setIsOpen(false);
|
||||
}
|
||||
}, [ setValue]);
|
||||
|
||||
const handleSuggestionClick = useCallback((dmdCoNm: string) => {
|
||||
setTextValue(dmdCoNm);
|
||||
setValue(dmdCoNm);
|
||||
setIsOpen(false);
|
||||
setRtnData(demandCompList);
|
||||
}, [demandCompList, setRtnData, setValue]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<input
|
||||
type="text"
|
||||
value={textValue}
|
||||
onChange={handleInputChange}
|
||||
/* onFocus={() => setIsOpen(true)} */
|
||||
className="w-full h-[3.2rem] !text-xl pl-3 text-gray-600 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder={`${label}을(를) 입력하세요`}
|
||||
/>
|
||||
{isOpen && (
|
||||
<div className=" z-1 w-full mt-2 bg-white border border-gray-300 rounded-md shadow-lg h-90 overflow-auto">
|
||||
<div className="max-h-72">
|
||||
{demandCompList && demandCompList.length > 0 ? demandCompList.map((item : DemandCompType, index : number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="!text-xl w-full text-left px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto"
|
||||
onClick={() => handleSuggestionClick(item.dmdCoNm)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleSuggestionClick(item.dmdCoNm);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item.dmdInfoPk.substring(0,10)} <span className="float-right">{item.dmdCoNm}</span>
|
||||
</div>
|
||||
)) : (
|
||||
<div className="!text-xl w-full px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto">
|
||||
검색 결과가 없습니다.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,51 +1,151 @@
|
||||
import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead";
|
||||
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
|
||||
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { Input, Table, TableBody, TableCell, TableHeader, TableRow } from "@common/components/ui";
|
||||
import type { customPbnst as OriginalCustomPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
|
||||
export default function RuseMngTable({
|
||||
tableData,
|
||||
headList,
|
||||
upHeadList,
|
||||
}: {
|
||||
import { selectClass, type TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { DatePicker, SelectBox, type SelectDataType } from "@common/business_components/ui";
|
||||
import {
|
||||
Checkbox,
|
||||
Input,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@common/components/ui";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
type RuseMngTableProps = {
|
||||
tableData: any[];
|
||||
headList: TableUpperProps[];
|
||||
upHeadList: chHeadType[];
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Table variant="secondary">
|
||||
<TableHeader className="font-bold">
|
||||
{headMakeprfmnc(headList, upHeadList)}
|
||||
</TableHeader>
|
||||
code?: { name: string, val: SelectDataType[] }[];
|
||||
onTableSet?:(item:any)=> void;
|
||||
};
|
||||
|
||||
<TableBody>
|
||||
{tableData.map((item, index) => (
|
||||
<TableRow key={index}>
|
||||
{headList.map((head, index) => (
|
||||
<TableCell
|
||||
key={`${head.id}-${index}`}
|
||||
className="text-center whitespace-nowrap"
|
||||
onClick={() => {}}
|
||||
>
|
||||
{head.edit === true ? (
|
||||
<Input
|
||||
className={`${head.type === "number" ? "text-right" : "text-center"} !text-xl`}
|
||||
type={head.type}
|
||||
onChange={(e) => {
|
||||
;
|
||||
}}
|
||||
value={item[head.id] || ""}
|
||||
/>
|
||||
) : (
|
||||
`${item[head.id] || ""}`
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
}
|
||||
const RuseMngTable = React.forwardRef<any, RuseMngTableProps>(
|
||||
({
|
||||
tableData,
|
||||
headList,
|
||||
upHeadList,
|
||||
code,
|
||||
onTableSet
|
||||
}, ref) => {
|
||||
const [tableState, setTableState] = useState([...tableData]);
|
||||
useEffect(() => {
|
||||
if (ref && typeof ref === "object" && "current" in ref) {
|
||||
ref.current = tableState;
|
||||
}
|
||||
if(onTableSet)
|
||||
onTableSet (tableState)
|
||||
}, [tableState,onTableSet]);
|
||||
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(tableData)
|
||||
setTableState(tableData);
|
||||
}, [tableData]);
|
||||
return (
|
||||
<>
|
||||
<Table variant="secondary">
|
||||
<TableHeader className="font-bold">
|
||||
{upHeadList ? (
|
||||
headMakeprfmnc(headList, upHeadList)
|
||||
) : (
|
||||
<TableRow key={"table-row-test"}>
|
||||
{headList.map((head) => (
|
||||
<TableHead key={"table-head-row " + head.id} className={`border border-gray-600 px-2 py-1 `}>
|
||||
{head.title}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
)}
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{tableState.map((item, i) => (
|
||||
<TableRow key={i}>
|
||||
{headList.map((head, j) => (
|
||||
<TableCell
|
||||
key={`${head.id}-${j}`}
|
||||
className="text-center whitespace-nowrap"
|
||||
onClick={() => { }}
|
||||
>
|
||||
{head.edit === true ? (
|
||||
<Input
|
||||
className={`${head.type === "number" ? "text-right" : "text-center"} !text-xl`}
|
||||
type={head.type}
|
||||
onChange={(txt) => {
|
||||
setTableState(prev => {
|
||||
const next = [...prev];
|
||||
next[i] = { ...next[i], [head.id]: txt.target.value };
|
||||
return next;
|
||||
})
|
||||
}}
|
||||
value={head.type === "number" ?
|
||||
Number(tableState[i][head.id])||0 : tableState[i][head.id] || ""
|
||||
}
|
||||
/>
|
||||
) : head.type === "select" ? (
|
||||
<SelectBox
|
||||
label=""
|
||||
selectArray={code.find(item => item.name === head.selectData)?.val ?? []}
|
||||
value={
|
||||
tableState[i][head.id] || ""
|
||||
}
|
||||
className={""}
|
||||
selectClass={selectClass}
|
||||
onSelectValue={(val) => {
|
||||
setTableState((prev) => {
|
||||
prev[i][head.id] = val
|
||||
return [...prev]
|
||||
})
|
||||
}}
|
||||
></SelectBox>
|
||||
) : head.type === "date" ? (
|
||||
<DatePicker
|
||||
mode="single"
|
||||
field={{
|
||||
value:
|
||||
tableState[i][head.id], // Provide a default Date value
|
||||
onChange: (date) => {
|
||||
setTableState(prev => {
|
||||
const next = [...prev];
|
||||
next[i] = { ...next[i], [head.id]: date };
|
||||
return next;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
selectClass={"w-full"}
|
||||
/>
|
||||
) : head.type === "checkbox" ? (
|
||||
<Checkbox
|
||||
className=""
|
||||
checked={!!tableState[i][head.id]}
|
||||
onCheckedChange={(checked) => {
|
||||
console.log("checked", checked);
|
||||
setTableState((prev) => {
|
||||
prev[i][head.id] = checked
|
||||
return [...prev]
|
||||
})
|
||||
}}
|
||||
>
|
||||
</Checkbox>
|
||||
) :
|
||||
(
|
||||
`${item[head.id] || ""}`
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
})
|
||||
export default RuseMngTable;
|
||||
+12
-10
@@ -2,10 +2,9 @@ import { NextRequest, NextResponse } from "next/server";
|
||||
import { CS_URL } from "./components/lib/config";
|
||||
//import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config";
|
||||
|
||||
const CLAIM_NAME = "Authorization"
|
||||
const AUTH_USER_ID = "token-id"
|
||||
const serverApiUrl =
|
||||
CS_URL;
|
||||
const CLAIM_NAME = "Authorization";
|
||||
const AUTH_USER_ID = "token-id";
|
||||
const serverApiUrl = CS_URL;
|
||||
export function middleware(req: NextRequest) {
|
||||
const pathname = req.nextUrl.pathname;
|
||||
console.log(`[Middleware] Request URL: ${req.url}`);
|
||||
@@ -13,29 +12,32 @@ export function middleware(req: NextRequest) {
|
||||
|
||||
if (pathname.startsWith("/server")) {
|
||||
const queryParams = searchParams.toString();
|
||||
const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${queryParams ? `?${queryParams}` : ""
|
||||
}`;
|
||||
const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${
|
||||
queryParams ? `?${queryParams}` : ""
|
||||
}`;
|
||||
console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`);
|
||||
return NextResponse.rewrite(new URL(newUrl));
|
||||
}
|
||||
|
||||
if (pathname.startsWith("/attach-service")) {
|
||||
const requestHeaders = new Headers(req.headers);
|
||||
const token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJpYXQiOjE3NDc4MTM2MDksImV4cCI6MTc0NzgxMzkwOX0.XGiDHC-ljuEdN6M638q0nDet6XRQcO8o66LKvZZ07r4rGykn2ba8yagC_-8LVpVjrkPzIVZnW10I2fQWgAGT5Q"
|
||||
const userId = 'a0ec7a07-752a-4f7f-89a6-854e63d2e3a0';
|
||||
const token =
|
||||
"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJtbmdyWW4iOiJZIiwiZXhwIjoxNzQ4ODQ4NDkxfQ.ZiYpKxAMyyoPuUquxsWxfQbMBzYN4tsa7itZ49_OEsdGvbUUmKzrIV6Or7VVbEjtAqhh7W97nqB5EP6GRzFC9Q";
|
||||
const userId = "a0ec7a07-752a-4f7f-89a6-854e63d2e3a0";
|
||||
//const token = req.cookies.get(CLAIM_NAME)?.value;
|
||||
//const userId = req.cookies.get(AUTH_USER_ID)?.value;
|
||||
const newUrl = `${serverApiUrl}${pathname}`;
|
||||
|
||||
console.log("serverApiUrl ", serverApiUrl);
|
||||
console.log("pathname ", pathname);
|
||||
//wr:dev: pathname /attach-service/api/v1/tus/upload/5e60b70a-956e-40c3-be5a-cdd3100bf8ad
|
||||
|
||||
|
||||
//http://dev.onasys.co.kr:8000/attach-service/api/v1/tus/upload/5e60b70a-956e-40c3-be5a-cdd3100bf8ad
|
||||
if (token) requestHeaders.set(CLAIM_NAME, token);
|
||||
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
|
||||
|
||||
console.log(
|
||||
`[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`,
|
||||
`[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`
|
||||
);
|
||||
return NextResponse.rewrite(new URL(newUrl), {
|
||||
headers: requestHeaders,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.474.0",
|
||||
"moment": "^2.30.1",
|
||||
"next": "15.1.7",
|
||||
"react-hook-form": "^7.54.2",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||
|
||||
@@ -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: Array<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>{file.name}</span>
|
||||
<span className="w-4/5 overflow-hidden">{file.name}</span>
|
||||
</FileUploaderItem>
|
||||
))}
|
||||
</FileUploaderContent>
|
||||
|
||||
@@ -271,7 +271,7 @@ export const FileUploaderContent = forwardRef<
|
||||
{...props}
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex rounded-xl gap-1",
|
||||
"w-full flex rounded-xl gap-1",
|
||||
orientation === "horizontal" ? "flex-raw flex-wrap" : "flex-col",
|
||||
className,
|
||||
)}
|
||||
@@ -286,31 +286,37 @@ 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
|
||||
ref={ref}
|
||||
className={cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
"h-6 p-1 justify-between cursor-pointer relative",
|
||||
"h-6 p-1 justify-between cursor-pointer relative w-full",
|
||||
className,
|
||||
isSelected ? "bg-muted" : "",
|
||||
)}
|
||||
{...props}
|
||||
|
||||
>
|
||||
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full w-full">
|
||||
<div className="font-medium leading-none tracking-tight flex items-center gap-1.5 h-full !w-4/5 overflow-hidden "
|
||||
onClick={() =>{onFileClick?.(index)
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"absolute",
|
||||
"!w-1/5 z-50",
|
||||
direction === "rtl" ? "top-1 left-1" : "top-1 right-1",
|
||||
|
||||
)}
|
||||
onClick={() => removeFileFromSet(index)}
|
||||
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,19 +1,70 @@
|
||||
import React from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { FormControl, FormItem, FormLabel, FormMessage } from "../form";
|
||||
import { Button, Checkbox } from "@common/components/ui";
|
||||
|
||||
const FormUi = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement> & {label:string|undefined}
|
||||
>(({children, label},ref)=>{
|
||||
export const BZNM_TOT_NO = '종사업자등록번호';
|
||||
export const CANDIDATE = '공급처 후보지 선택(필수아님)';
|
||||
|
||||
interface FormUiProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
label?: string;
|
||||
onCheckboxChange?: (checked: boolean) => void;
|
||||
isDisabled?: boolean;
|
||||
}
|
||||
|
||||
interface FormElementProps extends React.HTMLAttributes<HTMLElement> {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const FormUi = React.forwardRef<HTMLDivElement, FormUiProps>(
|
||||
({ children, label, onCheckboxChange, isDisabled }, ref) => {
|
||||
const [isChecked, setIsChecked] = useState(isDisabled);
|
||||
|
||||
useEffect(() => {
|
||||
setIsChecked(isDisabled);
|
||||
}, [isDisabled]);
|
||||
|
||||
const handleCheckboxChange = useCallback((checked: boolean) => {
|
||||
setIsChecked(checked);
|
||||
onCheckboxChange?.(checked);
|
||||
}, [onCheckboxChange]);
|
||||
return (
|
||||
<FormItem ref={ref}>
|
||||
{label?<FormLabel className="text-xl">{label}</FormLabel>:<></>}
|
||||
<FormControl>
|
||||
{children}
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)
|
||||
})
|
||||
<FormItem ref={ref}>
|
||||
{label && <FormLabel className="text-xl">{label}</FormLabel>}
|
||||
{label === BZNM_TOT_NO && (
|
||||
<>
|
||||
<div className="float-right">
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="check"
|
||||
checked={isChecked}
|
||||
onCheckedChange={handleCheckboxChange}
|
||||
/>
|
||||
<label className="w-20 text-xl text-gray-600" htmlFor="check">해당없음</label>
|
||||
</div>
|
||||
</div>
|
||||
{children}
|
||||
</>
|
||||
)}
|
||||
{label === CANDIDATE && (
|
||||
<FormControl>
|
||||
{children}
|
||||
</FormControl>
|
||||
)}
|
||||
{label !== BZNM_TOT_NO && label !== CANDIDATE && (
|
||||
<FormControl>
|
||||
{React.isValidElement(children) && isDisabled
|
||||
? React.cloneElement(children, {
|
||||
disabled: isDisabled,
|
||||
...(children.props as FormElementProps)
|
||||
})
|
||||
: children}
|
||||
</FormControl>
|
||||
)}
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
FormUi.displayName = 'FormUi';
|
||||
export { FormUi };
|
||||
export { FormUi };
|
||||
@@ -19,4 +19,4 @@ export * from "./tab";
|
||||
export * from "./table";
|
||||
export * from "./table_div";
|
||||
export * from "./title";
|
||||
|
||||
export * from "./sdmInsertForm";
|
||||
@@ -0,0 +1,287 @@
|
||||
import { FormField } from "../form";
|
||||
import { SelectBox } from "../select";
|
||||
import { Input } from "@common/components";
|
||||
import { FormUi } from "../form_ui";
|
||||
import { useCallback, useState } from "react";
|
||||
import type { ControllerRenderProps, UseFormReturn } from "react-hook-form";
|
||||
import { SdmSearchForm } from "./sdmNameBox";
|
||||
import type { DemandCompType } from "../../../../../../apps/dm/app/store/sdmMng";
|
||||
|
||||
type SelectDataType = {
|
||||
text: string;
|
||||
val: string;
|
||||
};
|
||||
|
||||
interface FormSchema {
|
||||
ctpvCd: string;
|
||||
sggCd: string;
|
||||
dmdCoNm: string;
|
||||
dmdInfoPk: string;
|
||||
daddr: string;
|
||||
telno: string;
|
||||
bznmTotNo?: string;
|
||||
rgtr?: string;
|
||||
dmdAplyPswd?: string;
|
||||
}
|
||||
|
||||
interface SdmRegFormProps {
|
||||
form: UseFormReturn<FormSchema>;
|
||||
onCheckboxChange?: (checked: boolean) => void;
|
||||
selectSidoData: SelectDataType[];
|
||||
selectSigunData: SelectDataType[];
|
||||
dataList: DemandCompType[];
|
||||
rtnValue: (searchText: string, pageCnt: number) => void;
|
||||
setIsDuplicate: (value: boolean) => void;
|
||||
}
|
||||
|
||||
type FieldComponent = (field: ControllerRenderProps<FormSchema, keyof FormSchema>) => JSX.Element;
|
||||
|
||||
export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigunData, dataList, rtnValue, setIsDuplicate }: SdmRegFormProps) {
|
||||
const [sidoValue, setSidoValue] = useState<string>('');
|
||||
const [sigunValue, setSigunValue] = useState<string>('');
|
||||
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]);
|
||||
const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true);
|
||||
const [orgBznmNo, setOrgBznmNo] = useState<string>('');
|
||||
|
||||
const initializeSigunData = useCallback((sidoCd: string) => {
|
||||
if (sidoCd === '0') {
|
||||
setSigunValue('0');
|
||||
setFilteredSigunData([{ text: "전체", val: '0' }]);
|
||||
} else {
|
||||
const newFilteredData = [
|
||||
{ text: "전체", val: '0' },
|
||||
...selectSigunData.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd)
|
||||
];
|
||||
setSigunValue('0');
|
||||
setFilteredSigunData(newFilteredData);
|
||||
}
|
||||
}, [selectSigunData]);
|
||||
|
||||
const onSelectValue = useCallback((
|
||||
val: string,
|
||||
type: string,
|
||||
field: ControllerRenderProps<FormSchema, keyof FormSchema> | undefined
|
||||
) => {
|
||||
switch (type) {
|
||||
case "ctpvCd":
|
||||
initializeSigunData(val);
|
||||
setSidoValue(val);
|
||||
field?.onChange(val);
|
||||
form.setValue('dmdInfoPk', '');
|
||||
form.setValue('bznmTotNo', '');
|
||||
break;
|
||||
case "sggCd":
|
||||
setSigunValue(val);
|
||||
field?.onChange(val);
|
||||
form.setValue('dmdInfoPk', '');
|
||||
form.setValue('bznmTotNo', '');
|
||||
break;
|
||||
}
|
||||
}, [initializeSigunData, form]);
|
||||
|
||||
const handleCheckboxChange = useCallback((checked: boolean) => {
|
||||
setIsBznmTotNoDisabled(checked);
|
||||
onCheckboxChange?.(checked);
|
||||
}, [onCheckboxChange]);
|
||||
|
||||
const setRtnValue = useCallback((searchText: string, pageCnt: number) => {
|
||||
rtnValue(searchText, pageCnt);
|
||||
}, [rtnValue]);
|
||||
|
||||
const setRtnData = useCallback((item: DemandCompType) => {
|
||||
const rtnCompData = item;
|
||||
form.setValue('dmdCoNm', rtnCompData?.dmdCoNm || '');
|
||||
form.setValue('dmdInfoPk', rtnCompData?.dmdInfoPk.substring(0,10) || '');
|
||||
form.setValue('bznmTotNo', rtnCompData?.dmdInfoPk.substring(10,14)==='0000' ? '' : rtnCompData?.dmdInfoPk.substring(10,14));
|
||||
|
||||
// 수요처 불러온 후 사업자번호를 바꿀경우를 대비함
|
||||
setOrgBznmNo(rtnCompData?.dmdInfoPk);
|
||||
const sidoCd = rtnCompData?.ctpvCd.trim() || '';
|
||||
setSidoValue(sidoCd);
|
||||
form.setValue('ctpvCd', sidoCd);
|
||||
initializeSigunData(sidoCd);
|
||||
|
||||
setTimeout(() => {
|
||||
const sigunCd = rtnCompData?.sggCd.trim() || '';
|
||||
setSigunValue(sigunCd);
|
||||
form.setValue('sggCd', sigunCd);
|
||||
}, 100);
|
||||
|
||||
if(rtnCompData?.dmdInfoPk.substring(10,14) === '0000') {
|
||||
handleCheckboxChange(true);
|
||||
} else {
|
||||
handleCheckboxChange(false);
|
||||
}
|
||||
|
||||
form.setValue('daddr', rtnCompData?.daddr || '');
|
||||
form.setValue('telno', rtnCompData?.telno || '');
|
||||
|
||||
// 선택을 했을 때 중복 상태를 true로 설정
|
||||
setIsDuplicate(true);
|
||||
}, [form, handleCheckboxChange, initializeSigunData, setIsDuplicate]);
|
||||
|
||||
const setRtnText = useCallback((text: string) => {
|
||||
form.setValue('dmdCoNm', text);
|
||||
}, [form]);
|
||||
|
||||
const bznNoChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, noType: string) => {
|
||||
const value = e.target.value;
|
||||
console.log('form value : '+form.getValues('dmdInfoPk'));
|
||||
console.log('org value : '+orgBznmNo);
|
||||
|
||||
if(noType === 'dmdInfoPk') {
|
||||
if(orgBznmNo.substring(0,10) === value) {
|
||||
setIsDuplicate(true);
|
||||
} else {
|
||||
setIsDuplicate(false);
|
||||
}
|
||||
form.setValue('dmdInfoPk', value);
|
||||
} else {
|
||||
if(orgBznmNo.substring(10,14) === value) {
|
||||
setIsDuplicate(true);
|
||||
} else {
|
||||
setIsDuplicate(false);
|
||||
}
|
||||
form.setValue('bznmTotNo', value);
|
||||
}
|
||||
|
||||
}, [form, orgBznmNo, setIsDuplicate]);
|
||||
|
||||
const formFields: Array<{
|
||||
name: keyof FormSchema;
|
||||
label: string;
|
||||
component: FieldComponent;
|
||||
}> = [
|
||||
{
|
||||
name: "ctpvCd",
|
||||
label: "시도",
|
||||
component: (field) => (
|
||||
<SelectBox
|
||||
selectClass={undefined}
|
||||
label=""
|
||||
selectArray={selectSidoData}
|
||||
onSelectValue={(val) => onSelectValue(val.toString(), 'ctpvCd', field)}
|
||||
className=""
|
||||
value={sidoValue}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "sggCd",
|
||||
label: "시군구",
|
||||
component: (field) => (
|
||||
<SelectBox
|
||||
selectClass={undefined}
|
||||
label=""
|
||||
selectArray={filteredSigunData}
|
||||
onSelectValue={(val) => onSelectValue(val.toString(), 'sggCd', field)}
|
||||
className=""
|
||||
value={sigunValue}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "dmdCoNm",
|
||||
label: "회사명",
|
||||
component: (field) => (
|
||||
<SdmSearchForm
|
||||
rtnData={setRtnData}
|
||||
label="수요처명"
|
||||
initValue={''}
|
||||
dataList={dataList}
|
||||
rtnValue={setRtnValue}
|
||||
rtnText={setRtnText}
|
||||
{...field}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "dmdInfoPk",
|
||||
label: "사업자등록번호",
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="사업자등록번호를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
{...field}
|
||||
onChange={(e) => bznNoChange(e, 'dmdInfoPk')}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "bznmTotNo",
|
||||
label: "종사업자등록번호",
|
||||
component: (field) => (
|
||||
<FormUi
|
||||
label="종사업자등록번호"
|
||||
onCheckboxChange={handleCheckboxChange}
|
||||
isDisabled={isBznmTotNoDisabled}
|
||||
>
|
||||
<Input
|
||||
placeholder="여러사업장이 있을 경우 입력해주세요"
|
||||
type="text"
|
||||
className="!mt-5 !text-xl text-gray-600"
|
||||
disabled={isBznmTotNoDisabled}
|
||||
{...field}
|
||||
onChange={(e) => bznNoChange(e, 'bznmTotNo')}
|
||||
/>
|
||||
</FormUi>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "daddr",
|
||||
label: "사업자주소",
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="주소를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
{...field}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "telno",
|
||||
label: "전화번호",
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="전화번호를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
{...field}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "dmdAplyPswd",
|
||||
label: "패스워드",
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="패스워드를 입력하세요"
|
||||
type="password"
|
||||
className="!text-xl text-gray-600"
|
||||
{...field}
|
||||
/>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
{formFields.map(({ name, label, component }) => (
|
||||
<FormField
|
||||
key={String(name)}
|
||||
control={form.control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
name === 'bznmTotNo' ? component(field) : (
|
||||
<FormUi label={label}>
|
||||
{component(field)}
|
||||
</FormUi>
|
||||
)
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
"use client";
|
||||
|
||||
/* import { useDmStore } from "@/app/store"; */
|
||||
import { SdmRegForm } from "./form";
|
||||
import { Button } from "@common/components/ui";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
/* import { useRouter } from "next/navigation"; */
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { FormProvider, useForm, type SubmitHandler } from "react-hook-form";
|
||||
import { toast, Toaster } from "sonner";
|
||||
/* import { Toaster, toast } from "react-hot-toast"; */
|
||||
import * as z from "zod";
|
||||
import type { SelectDataType } from "../search_input_select";
|
||||
|
||||
|
||||
export type DemandCompType = {
|
||||
dmdInfoPk : string | '';
|
||||
bzmnNo : string | '';
|
||||
dmdCoNm : string | '';
|
||||
daddr : string | '';
|
||||
telno : string | '';
|
||||
rgtr : string | '';
|
||||
useUsgCd : string | '';
|
||||
ctpvCd : string | '';
|
||||
sggCd : string | '';
|
||||
dmdAplyPswd: string | '';
|
||||
}
|
||||
|
||||
|
||||
type thisProps = {
|
||||
selectSidoData: SelectDataType[];
|
||||
selectSigunData: SelectDataType[];
|
||||
dataList: DemandCompType[];
|
||||
rtnValue: (searchText: string, pageCnt: number) => void;
|
||||
rtnInputData: (data: DemandCompType) => void;
|
||||
bodyClassNm?: string;
|
||||
}
|
||||
|
||||
const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean) => z.object({
|
||||
ctpvCd: z.string().min(1, "시/도를 선택해주세요"),
|
||||
sggCd: z.string().min(1, "시/군/구를 선택해주세요"),
|
||||
dmdCoNm: z.string()
|
||||
.min(1, "회사명을 입력해주세요")
|
||||
.max(20, "회사명은 20자 이내로 입력해주세요"),
|
||||
dmdInfoPk: z.string()
|
||||
.min(1, "사업자등록번호를 입력해주세요")
|
||||
.regex(/^\d{10}$/, "사업자등록번호는 10자리 숫자만 입력 가능합니다")
|
||||
.refine(() => isBznmTotNoDisabled ? !isDuplicate : true, "이미 등록된 사업자등록번호입니다"),
|
||||
bznmTotNo: isBznmTotNoDisabled
|
||||
? z.string().optional()
|
||||
: z.string()
|
||||
.length(4, "종사업자등록번호는 4자리 숫자만 입력 가능합니다")
|
||||
.refine(() => !isDuplicate, "이미 등록된 사업자등록번호입니다"),
|
||||
daddr: z.string()
|
||||
.min(1, "주소를 입력해주세요")
|
||||
.min(6, "주소는 6자 이상 입력해주세요")
|
||||
.max(40, "주소는 40자 이내로 입력해주세요"),
|
||||
telno: z.string()
|
||||
.min(8, "전화번호는 8자 이상 입력해주세요")
|
||||
.max(12, "전화번호는 12자 이내로 입력해주세요")
|
||||
.regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"),
|
||||
rgtr: z.string().optional(),
|
||||
dmdAplyPswd : z.string()
|
||||
.min(1, "패스워드를 입력해주세요")
|
||||
.min(8, "패스워드는 8자 이상 입력해주세요")
|
||||
.max(16, "패스워드는 16자 이내로 입력해주세요"),
|
||||
});
|
||||
|
||||
type FormSchema = ReturnType<typeof createFormSchema>;
|
||||
export type FormData = z.infer<FormSchema>;
|
||||
|
||||
const defaultValues: FormData = {
|
||||
ctpvCd: '',
|
||||
sggCd: '',
|
||||
dmdCoNm: '',
|
||||
dmdInfoPk: '',
|
||||
bznmTotNo: '',
|
||||
daddr: '',
|
||||
telno: '',
|
||||
rgtr: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
||||
dmdAplyPswd : '',
|
||||
};
|
||||
|
||||
/**
|
||||
* 수요처 등록 폼
|
||||
* @param selectSidoData 시/도 데이터
|
||||
* @param selectSigunData 시/군/구 데이터
|
||||
* @param dataList 수요처 목록
|
||||
* @param rtnValue 검색 결과(텍스트) 콜백
|
||||
* @param rtnInputData 수요처 리스트 콜백
|
||||
* @returns
|
||||
*/
|
||||
|
||||
/**
|
||||
* 페이지에서 작업
|
||||
const {Common, initializeCommonData, getDemandCompList, insertSdmData, Sdm} = useDmStore((state) => state);
|
||||
const { selectSidoData, selectSigunData } = Common;
|
||||
const { demandCompList } = Sdm;
|
||||
|
||||
// 공통데이터 (시도, 시군구 데이터 호출)
|
||||
useEffect(() => {
|
||||
initializeCommonData();
|
||||
}, [initializeCommonData]);
|
||||
|
||||
// 컴포넌트에서 텍스트 검색 호출
|
||||
const callback = useCallback((searchText: string, pageCnt: number) => {
|
||||
searchText = searchText.trim();
|
||||
if(searchText.length > 0) {
|
||||
getDemandCompList(searchText, pageCnt);
|
||||
}
|
||||
}, [getDemandCompList]);
|
||||
|
||||
// 컴포넌트에서 수요처 등록 호출
|
||||
const handleInsertSdmData = useCallback((data: DemandCompType) => {
|
||||
insertSdmData(data);
|
||||
|
||||
}, [insertSdmData]);
|
||||
*/
|
||||
|
||||
export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm}: thisProps) {
|
||||
/* const { insertSdmData } = useDmStore((state) => state);
|
||||
const router = useRouter(); */
|
||||
|
||||
const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true);
|
||||
const [isDuplicate, setIsDuplicate] = useState(false);
|
||||
const formSchema = createFormSchema(isBznmTotNoDisabled, isDuplicate);
|
||||
|
||||
const form = useForm<z.infer<FormSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues,
|
||||
mode: "onChange",
|
||||
criteriaMode: "all",
|
||||
shouldFocusError: false,
|
||||
shouldUnregister: false
|
||||
});
|
||||
|
||||
// 체크박스 상태가 변경될 때마다 bznmTotNo 필드의 에러를 초기화
|
||||
useEffect(() => {
|
||||
if (isBznmTotNoDisabled) {
|
||||
form.clearErrors('bznmTotNo');
|
||||
form.setValue('bznmTotNo', '');
|
||||
}
|
||||
}, [isBznmTotNoDisabled, form]);
|
||||
|
||||
const setRtnValue = useCallback((searchText: string, pageCnt: number) => {
|
||||
rtnValue(searchText, pageCnt);
|
||||
}, [rtnValue]);
|
||||
|
||||
const onSubmit: SubmitHandler<z.infer<FormSchema>> = async (data) => {
|
||||
try {
|
||||
// form 에러 체크
|
||||
const formErrors = form.formState.errors;
|
||||
if (Object.keys(formErrors).length > 0) {
|
||||
const errorMessage = Object.values(formErrors)[0]?.message || '입력값을 확인해주세요.';
|
||||
toast.error(errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
const dmdInfoPk = data.dmdInfoPk + (data.bznmTotNo || '0000');
|
||||
const formData = {
|
||||
...data,
|
||||
dmdInfoPk,
|
||||
};
|
||||
|
||||
console.log(formData);
|
||||
/* await insertSdmData(formData); */
|
||||
rtnInputData(formData as DemandCompType);
|
||||
|
||||
const queryParams = new URLSearchParams({
|
||||
dmdCoNm: data.dmdCoNm,
|
||||
ctpvCd: data.ctpvCd,
|
||||
sggCd: data.sggCd,
|
||||
dmdInfoPk,
|
||||
bznmTotNo: data.bznmTotNo || '',
|
||||
daddr: data.daddr,
|
||||
telno: data.telno,
|
||||
});
|
||||
|
||||
//router.push(`/pages/sdmMng/sdmInfoInsert?${queryParams.toString()}`);
|
||||
toast.success('수요처가 성공적으로 등록되었습니다.');
|
||||
} catch (error) {
|
||||
console.error('Error submitting form:', error);
|
||||
toast.error('수요처 등록에 실패했습니다.');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="text-center mb-8">
|
||||
<h1 className="text-4xl font-bold text-gray-900 underline">
|
||||
수요처등록
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className= {bodyClassNm?bodyClassNm:"!max-w-3xl mx-auto bg-white rounded-lg shadow-md p-6"}>
|
||||
<FormProvider {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
<SdmRegForm
|
||||
form={form}
|
||||
onCheckboxChange={setIsBznmTotNoDisabled}
|
||||
selectSidoData={selectSidoData}
|
||||
selectSigunData={selectSigunData}
|
||||
dataList={dataList}
|
||||
rtnValue={setRtnValue}
|
||||
setIsDuplicate={setIsDuplicate}
|
||||
/>
|
||||
<div className="flex justify-center pt-4">
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-32 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
|
||||
>
|
||||
수요처등록
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</FormProvider>
|
||||
</div>
|
||||
<Toaster position="top-center" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import type { DemandCompType } from "../../../../../../apps/dm/app/store/sdmMng";
|
||||
|
||||
export type thisProps = {
|
||||
label: string | undefined;
|
||||
initValue: string | undefined;
|
||||
dataList : DemandCompType[];
|
||||
rtnValue : (searchText: string, pageCnt: number) => void;
|
||||
rtnData : (item: DemandCompType) => void;
|
||||
rtnText : (text: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수요처 검색 컴포넌트
|
||||
* @param label 라벨
|
||||
* @param initValue 초기값
|
||||
* @param rtnValue 검색 결과 반환 함수
|
||||
* @param dataList 검색할 때 넘기는 데이터 리스트
|
||||
* @param rtnData 검색 결과 반환 함수
|
||||
*/
|
||||
export const SdmSearchForm = ({label=undefined, initValue=undefined, rtnValue=()=>{}, dataList=[], rtnData=()=>{}, rtnText=()=>{} } :thisProps) => {
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [textValue, setTextValue] = useState(initValue || '');
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setTextValue(value);
|
||||
rtnValue(value, 10);
|
||||
rtnText(value);
|
||||
if (value) {
|
||||
setIsOpen(true);
|
||||
} else {
|
||||
setIsOpen(false);
|
||||
}
|
||||
}, [rtnValue, rtnText]);
|
||||
|
||||
const handleSuggestionClick = useCallback((item: DemandCompType) => {
|
||||
setTextValue(item.dmdCoNm);
|
||||
rtnData(item);
|
||||
setIsOpen(false);
|
||||
}, [rtnData]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<input
|
||||
type="text"
|
||||
value={textValue}
|
||||
onChange={handleInputChange}
|
||||
/* onFocus={() => setIsOpen(true)} */
|
||||
className="w-full h-[3.2rem] !text-xl pl-3 text-gray-600 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder={`${label}을(를) 입력하세요`}
|
||||
/>
|
||||
{isOpen && (
|
||||
<div className=" z-1 w-full mt-2 bg-white border border-gray-300 rounded-md shadow-lg h-90 overflow-auto">
|
||||
<div className="max-h-72">
|
||||
{dataList && dataList.length > 0 ? dataList.map((item : DemandCompType, index : number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="!text-xl w-full text-left px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto"
|
||||
onClick={() => handleSuggestionClick(item)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleSuggestionClick(item);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item.dmdInfoPk.substring(10,14) !== '0000' ? (
|
||||
<>
|
||||
<span className="text-gray-500">사업자번호 : </span> {item.dmdInfoPk.substring(0,10)}
|
||||
<span className="text-gray-500">종사업자번호 : </span> {item.dmdInfoPk.substring(10,14)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-500">사업자번호 : </span> {item.dmdInfoPk.substring(0,10)}
|
||||
</>
|
||||
)}
|
||||
<span className="float-right">{item.dmdCoNm}</span>
|
||||
</div>
|
||||
)) : (
|
||||
<div className="!text-xl w-full px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto">
|
||||
검색 결과가 없습니다.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -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})=>{
|
||||
// Exclude 'dir' if it exists and is not of the correct type
|
||||
return (
|
||||
<Tabs
|
||||
defaultValue={defaultValue || tabList[0]?.value}
|
||||
className={"w-full space-x-1 border-b border-gray-200"}
|
||||
onValueChange={onValueChange}
|
||||
>
|
||||
<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>
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
||||
return (
|
||||
<input
|
||||
className={cn(
|
||||
"flex h-[3.2rem] w-full rounded-md border border-input bg-form px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-placeholder focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"flex h-[3.2rem] w-full rounded-md border border-input bg-form px-3 py-2 text-xl ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-placeholder focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-xl",
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
Reference in New Issue
Block a user