수요처관리, 잠재수요처관리 페이지 초안

This commit is contained in:
jyha00
2025-05-19 17:09:10 +09:00
parent 613bfd035b
commit 185de5b48c
8 changed files with 568 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
"use client";
import { useWrStore } from "@/app/store";
import { Button } from "@common/components/ui";
import { btnClass } from "@/app/store/common/code";
import ListDiv from "@common/business_components/ui/list_div";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import type { customCoBdst } from "@/app/store/matDmd/coReg";
import {
ContentsDiv,
SearchBaseForm,
Title,
UiModal,
UiTable,
type ReturnType,
} from "@common/business_components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
export default function coSttn() {
const [bdstTable, setBdstTable] = useState<customCoBdst[]>();
const [pageNation, setPageNation] = useState(1);
const { code, coSttn } = useWrStore(
(state) => state
);
const ref = useRef<ReturnType>({} as ReturnType);
const excelClick = useCallback(() => {
}, []);
return(
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
<div className="col-span-4">
<Title title={"수요처 관리"} />
<SearchBaseForm
selectSidoData={code.cityCd}
selectSigunData={code.sggCd}
selectRegionData={code.rvbsnCd}
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
rightChildren={
<div>
<Button
className={btnClass}
onClick={() => {
/* 등록 로직 */
}}
>
등록
</Button>
<Button
className={btnClass}
onClick={() => {
/* 저장 로직 */
}}
>
저장
</Button>
</div>
}
leftChildren={undefined}
queryClick={function (returnType: ReturnType): void {
// '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}'
let con;
if (returnType.sigunValue != "0") {
con = returnType.sigunValue;
} else {
con = returnType.sidoValue;
}
// coSttnSearch(1, "20", con);
}}
excelClick={excelClick}
initClick={function (): void {}}
btnClass={btnClass}
ref={ref}
/>
</div>
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<ListDiv>
<UiTable
headName={[]}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={coSttn.coSttNodeList} />
}
headlist={coSttn.coSttHeadList}
pageSize={20}
total={10000}
cellClick={(index: number | undefined,headId:string)=>{cellClick(index ?? undefined,headId)} }
onPageChange={setPageNation}
></UiTable>
</ListDiv>
</div>
</div>
</ContentsDiv>
</>
)
}
@@ -0,0 +1,147 @@
"use client";
import { useWrStore } from "@/app/store";
import { Button } from "@common/components/ui";
import { btnClass } from "@/app/store/common/code";
import ListDiv from "@common/business_components/ui/list_div";
import {
tableData,
} from "@/components/lib/func/commom";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import type { customCoBdst } from "@/app/store/matDmd/coReg";
import {
ContentsDiv,
SearchBaseForm,
Title,
UiModal,
UiTable,
type ReturnType,
} from "@common/business_components/ui";
import CoDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/coDatailModal";
import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcel";
import { useCallback, useEffect, useRef, useState } from "react";
export default function ldrmntCoSttn() {
const { code, ldrmntCoSttn } = useWrStore(
(state) => state
);
const { ldrmntCoSttnRes } = ldrmntCoSttn;
const [bdstTable, setBdstTable] = useState<customCoBdst[]>();
const [detailModal, setDetailModal] = useState<{isOpen:boolean,data:customCoBdst|undefined}>({data:undefined,isOpen:false })
const [pageNation, setPageNation] = useState(1);
const [isRegExcel, setIsRegExcel] = useState(false);
const ref = useRef<ReturnType>({} as ReturnType);
const excelClick = useCallback(() => {
}, []);
const cellClick=(index:number|undefined, headId: string)=>{
if(index!==undefined && bdstTable!==undefined){
setDetailModal({isOpen:true ,data:bdstTable[index] })
}
}
useEffect(() => {
if (ldrmntCoSttnRes.length > 0 && code.cityCd.length > 0) {
const data = tableData(ldrmntCoSttnRes, { code });
console.log("data", data);
const chData = data
.map((item: any) => ({
...item
}))
.filter((item: any) => item !== undefined);
setBdstTable(chData);
}
}, [code, ldrmntCoSttnRes, ldrmntCoSttn.ldrmntCoSttHeadList]);
return(
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
<div className="col-span-4">
<Title title={"잠재수요처 관리"} />
<SearchBaseForm
selectSidoData={code.cityCd}
selectSigunData={code.sggCd}
selectRegionData={code.rvbsnCd}
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
rightChildren={
<div>
<Button
className={btnClass}
onClick={() => setIsRegExcel(!isRegExcel)}
>
엑셀등록
</Button>
<Button
className={btnClass}
onClick={() => {
// 저장 로직
}}
>
양식받기
</Button>
</div>
}
leftChildren={undefined}
queryClick={function (returnType: ReturnType): void {
// '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}'
let con;
if (returnType.sigunValue != "0") {
con = returnType.sigunValue;
} else {
con = returnType.sidoValue;
}
// ldrmntCoSttnSearch(1, "20", con);
}}
excelClick={excelClick}
initClick={function (): void {}}
btnClass={btnClass}
ref={ref}
/>
</div>
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<ListDiv>
<UiTable
headName={[]}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={ldrmntCoSttn.ldrmntCoSttNodeList} />
}
headlist={ldrmntCoSttn.ldrmntCoSttHeadList}
pageSize={20}
total={10000}
cellClick={(index: number | undefined,headId:string)=>{cellClick(index ?? undefined,headId)} }
onPageChange={setPageNation}
></UiTable>
</ListDiv>
</div>
<UiModal
open={detailModal.isOpen}
onOpenChange={()=>{
setDetailModal({...detailModal, isOpen:!detailModal.isOpen})
}}
bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"}
body={<CoDetailModal formObj={detailModal.data}/>}/>
<UiModal
bodyClass={"w-[40vw] max-w-none"}
open={isRegExcel}
body={<CoRegExcel></CoRegExcel>}
onOpenChange={setIsRegExcel}
/>
</div>
</ContentsDiv>
</>
)
}
+13
View File
@@ -0,0 +1,13 @@
import { z } from "zod";
export const coZod = z.object({
ctpv: z.string(),
sgg: z.string(),
coNm: z.string().min(1).max(20),
bznmNo: z.string().min(1).min(9).max(12),
addr: z.string().min(1).min(6).max(20),
telNo: z.string().min(8).max(12)
});
export type customCoBdst = z.infer<typeof coZod>;
@@ -0,0 +1,99 @@
import type { CommonTableProps } from "@/app/store/common/type/headder";
import { z } from "zod";
export const sttnHeadListType = z.array(
z.object({
id: z.string(),
title: z.string(),
visible: z.boolean(),
})
);
export const coRegExcel = z.object({
file: z.instanceof(File)
});
export const coSttHeadListExport: 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: "bznmNo",
title: "공장관리번호",
visible: true,
},
{
id: "telNo",
title: "전화번호",
visible: true,
},
];
// id는 다확인해야함
export const coSttNodeListExport: 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: "bznmNo",
title: "공장관리번호",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "telNo",
title: "전화번호",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
];
+43
View File
@@ -0,0 +1,43 @@
import type { z } from "zod";
import type { CommonTableProps } from "@/app/store/common/type/headder";
import { coSttNodeListExport, coSttHeadListExport } from "./headList";
import type { customCoBdst } from "../../matDmd/coReg";
import type { sttnHeadListType } from "../coSttn/headList";
// 테이블 헤드 리스트
const coSttNodeList = coSttNodeListExport;
const coSttHeadList = coSttHeadListExport;
export type coSttnState = {
coSttn: {
coSttnRes: customCoBdst[];
coSttHeadList: CommonTableProps[];
coSttNodeList: CommonTableProps[];
excelList: [];
isInit: boolean;
};
};
type coSttnActions = {
};
export type coSttnType = coSttnState & coSttnActions;
export const coSttnStateExport: coSttnState = {
coSttn: {
coSttHeadList: coSttHeadList,
coSttNodeList: coSttNodeList,
coSttnRes: [],
excelList: [],
isInit: false,
},
};
export const coSttnActionsExport: (set: any) => coSttnActions = (
set: any
) => {
return {
}
}
@@ -0,0 +1,66 @@
import type { z } from "zod";
import type { CommonTableProps } from "@/app/store/common/type/headder";
import { coSttNodeListExport, coSttHeadListExport } from "../coSttn/headList";
import type { customCoBdst } from "../../matDmd/coReg";
import type { sttnHeadListType } from "../coSttn/headList";
// 테이블 헤드 리스트
const coSttNodeList = coSttNodeListExport;
const coSttHeadList = coSttHeadListExport;
const ldrmntCoSttnRes: customCoBdst[] = [];
const ldrmntCoList = {ctpv: "이거머임",
sgg: "01",
coNm: "회사요",
bznmNo: "abc123",
addr: "서울 강남구",
telNo: "010-1234-5678"}
export type ldrmntCoSttnState = {
ldrmntCoSttn: {
ldrmntCoSttnRes: customCoBdst[];
ldrmntCoSttHeadList: CommonTableProps[];
ldrmntCoSttNodeList: CommonTableProps[];
excelList: [];
isInit: boolean;
};
};
type ldrmntCoSttnActions = {
};
export type ldrmntCoSttnType = ldrmntCoSttnState & ldrmntCoSttnActions;
export const ldrmntCoSttnStateExport: ldrmntCoSttnState = {
ldrmntCoSttn: {
ldrmntCoSttHeadList: coSttHeadList,
ldrmntCoSttNodeList: coSttNodeList,
ldrmntCoSttnRes: [ldrmntCoList],
excelList: [],
isInit: false,
},
};
export const ldrmntCoSttnActionsExport: (set: any) => ldrmntCoSttnActions = (
set: any
) => {
return {
ldrmntCoSttnInit: async (code: string | number) => {
try{
set((state: ldrmntCoSttnState) => {
return {
...state,
ldrmntCoSttn: {
...state.ldrmntCoSttn,
ldrmntCoSttnRes: ldrmntCoSttnRes,
isInit: false,
},
};
});
}catch(e){
console.log(e)
}
},
}
}
@@ -0,0 +1,63 @@
import { useState, useEffect } from "react";
import { useForm, FormProvider } from "react-hook-form";
import { useWrStore } from "@/app/store";
import { type customCoBdst } from "@/app/store/matDmd/coReg";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import { filePicked, FileUpload, FormUi, Title } from "@common/business_components/ui";
import { Button } from "@common/components/ui";
import type { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { coRegExcel } from "@/app/store/matDmd/coSttn/headList";
export default function CoRegExcel() {
const [excelData, setExcelData] = useState<customCoBdst[]>();
const [files, setFiles] = useState<File[] | null>(null);
const form = useForm<z.infer<typeof coRegExcel>>({
resolver: zodResolver(coRegExcel),
defaultValues: { file: [] },
});
useEffect(() => {
if (!files || files.length === 0) return;
const file = files[0];
if (!file) return;
filePicked(file, 0).then((res) => {
if (res) {
}
});
}, [files]);
const onSubmit = (values: z.infer<typeof coRegExcel>) => {
if (!excelData || excelData.length === 0) {
ToastFormUi({
title: "잠재수요처 등록",
body: "빈 파일 및 파일 오류 입니다.",
});
return;
}
// rainChkExcelDataUPload(excelData);
};
return (
<FormProvider {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<Title title="잠재수요처 등록" />
<div className="flex justify-between items-center mb-4">
<h3 className="text-2xl font-bold text-gray-900">○ 잠재수요처</h3>
<Button type="submit">등록</Button>
</div>
<FormUi label="잠재수요처 파일">
<FileUpload
files={files || []}
setFiles={(files: File[] | null) => {if (files) setFiles(files);}}
fileTypes="xlsx"
></FileUpload>
</FormUi>
</form>
</FormProvider>
);
}
@@ -0,0 +1,30 @@
"use client";
import { useWrStore } from "@/app/store";
import type { CommonTableProps } from "@/app/store/common/type/headder";
import { Title } from "@common/business_components/ui";
import { useEffect, useState } from "react";
export default function SttnDetailModal(
{formObj,}: {formObj: any;}) {
const { code, rainSttn, rswtSttn, rainSttnChkSearch } = useWrStore(
(state) => state
);
const [detailData, setDetailData] = useState({
head: [] as CommonTableProps[],
node:[] as CommonTableProps[],
data: {} as any,
});
useEffect(() =>{
setDetailData({data:[] , head:[], node:[]})
},[])
return (
<div>
<Title title="잠재수요처 상세정보"></Title>
</div>
);
}