feat: fileUploadForm.tsx 첨부파일명 표시 및 SELECTBOX 제거
This commit is contained in:
@@ -1,13 +1,20 @@
|
||||
"use client"
|
||||
import { SelectBox } from '@common/business_components/ui';
|
||||
import { Button } from '@common/components/ui';
|
||||
import React, { useState } from 'react'
|
||||
import { Button, Input } from '@common/components/ui';
|
||||
import React, { useState, useId } from 'react'
|
||||
import type { HttpResponse, Upload } from "tus-js-client";
|
||||
import { FileUploader } from "@common/components";
|
||||
import { handleUpload } from "@utils";
|
||||
import { set } from 'react-hook-form';
|
||||
|
||||
const FileUploadForm = ({ title, onSubmit }: { title: string, onSubmit: (files: string, year: string, quarter: string, code:string, id:string) => void }) => {
|
||||
interface FileUploadFormProps {
|
||||
onSubmit: (files: string, year: string, quarter: string, code: string, id: string) => void;
|
||||
showButton?: boolean; // 버튼 표시 여부 (기본값 true)
|
||||
showPreview?: boolean; // 파일명 프리뷰 표시 여부
|
||||
accept?: string; // 파일 형식 지정
|
||||
}
|
||||
|
||||
const FileUploadForm = ({ onSubmit, showButton = true, showPreview = false, accept = ".jpeg,.jpg,.png", }: FileUploadFormProps) => {
|
||||
const [atflCd, setAtflCd] = useState<string | null>(null);
|
||||
const [atflId, setAtflId] = useState<string | null>(null);
|
||||
const handleUploadResponse = (file: File) => async (res: HttpResponse) => {
|
||||
@@ -30,76 +37,66 @@ const FileUploadForm = ({ title, onSubmit }: { title: string, onSubmit: (files:
|
||||
const [selectedYear, setSelectedYear] = useState<string>(yearOptions[0]?.val || '');
|
||||
const [selectedQuarter, setSelectedQuarter] = useState<string>(quater[0]?.val || '');
|
||||
const [upload, setUpload] = useState<Upload | null>(null);
|
||||
const uniqueId = useId(); // 각 FileUploadForm 인스턴스에 대한 고유 ID 생성
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='card-header'>
|
||||
<h3 className="text-2xl font-medium">{title}</h3>
|
||||
</div>
|
||||
<div className="card p-6">
|
||||
<div className="grid grid-col-2 items-center space-x-4">
|
||||
<div className='flex'>
|
||||
<SelectBox
|
||||
className="w-50 mr-3 ml-4"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="년도"
|
||||
selectArray={yearOptions}
|
||||
onSelectValue={(value: string | number) => setSelectedYear(String(value))}
|
||||
/><SelectBox
|
||||
className="w-50"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="분기"
|
||||
selectArray={quater}
|
||||
onSelectValue={(value: string | number) => setSelectedQuarter(String(value))}
|
||||
<div> {/* 컴포넌트 루트 div */}
|
||||
<div className="card p-6"> {/* 카드 스타일링 */}
|
||||
<div className='flex items-center gap-2'> {/* FileUploader와 Button을 정렬하는 메인 flex 컨테이너 */}
|
||||
<div className="w-[220px] mr-4"> {/* FileUploader의 너비와 오른쪽 여백을 제어하는 컨테이너 */}
|
||||
<FileUploader
|
||||
id={uniqueId}
|
||||
className="!h-auto !max-w-none flex-row items-center gap-2"
|
||||
accept={accept}
|
||||
onUpload={(e) => {
|
||||
const selectedFiles = e.target.files;
|
||||
if (!selectedFiles) return;
|
||||
|
||||
setFiles(selectedFiles);
|
||||
if (selectedFiles[0]) {
|
||||
handleUpload(selectedFiles, {
|
||||
handleUploadStart: setUpload,
|
||||
handleSuccess: setUpload,
|
||||
handleResponse: handleUploadResponse(selectedFiles[0]),
|
||||
});
|
||||
}
|
||||
}}
|
||||
customPreview={
|
||||
showPreview ? (
|
||||
<div className="file-uploader-preview">
|
||||
{files && files.length > 0
|
||||
? Array.from(files).map((file) => file.name).join(", ")
|
||||
: "파일을 선택하세요."}
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
<div className='flex ml-5 items-center'>
|
||||
<div className="w-[80px] mr-4">
|
||||
<FileUploader
|
||||
id="atflCd"
|
||||
className="!h-auto !max-w-none flex-col !items-start"
|
||||
accept=".jpeg,.jpg,.png"
|
||||
onUpload={(e) => {
|
||||
const selectedFiles = e.target.files;
|
||||
if (!selectedFiles) return;
|
||||
|
||||
setFiles(selectedFiles);
|
||||
if (selectedFiles[0]) {
|
||||
handleUpload(selectedFiles, {
|
||||
handleUploadStart: setUpload,
|
||||
handleSuccess: setUpload,
|
||||
handleResponse: handleUploadResponse(selectedFiles[0]),
|
||||
});
|
||||
}
|
||||
|
||||
}}
|
||||
customPreview={<></>}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
console.log(files?.[0]?.name)
|
||||
if (!files) {
|
||||
alert('파일을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!selectedYear) {
|
||||
alert('등록년도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!selectedQuarter) {
|
||||
alert('분기를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
const fileNm = files?.[0]?.name || '';
|
||||
onSubmit(fileNm, selectedYear, selectedQuarter, atflCd || '', atflId || '');
|
||||
}}
|
||||
>
|
||||
등록
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{showButton ? (
|
||||
<Button
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
console.log(files?.[0]?.name)
|
||||
if (!files) {
|
||||
alert('파일을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!selectedYear) {
|
||||
alert('등록년도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!selectedQuarter) {
|
||||
alert('분기를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
const fileNm = files?.[0]?.name || '';
|
||||
onSubmit(fileNm, selectedYear, selectedQuarter, atflCd || '', atflId || '');
|
||||
}}
|
||||
>
|
||||
등록
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
"use client"
|
||||
import { SelectBox } from '@common/business_components/ui';
|
||||
import { Button } from '@common/components/ui';
|
||||
import React, { useState } from 'react'
|
||||
import type { HttpResponse, Upload } from "tus-js-client";
|
||||
import { FileUploader } from "@common/components";
|
||||
import { handleUpload } from "@utils";
|
||||
import { set } from 'react-hook-form';
|
||||
|
||||
const operFileUploadForm = ({ title, onSubmit }: { title: string, onSubmit: (files: string, year: string, quarter: string, code:string, id:string) => void }) => {
|
||||
const [atflCd, setAtflCd] = useState<string | null>(null);
|
||||
const [atflId, setAtflId] = useState<string | null>(null);
|
||||
const handleUploadResponse = (file: File) => async (res: HttpResponse) => {
|
||||
const fileInfo = res.getHeader("X-File-Info");
|
||||
if (!fileInfo) return;
|
||||
const { atflCd, atflId } = JSON.parse(fileInfo) ?? {};
|
||||
const orgnlFileNm = file.name;
|
||||
console.log('orgnlFileNm', orgnlFileNm, atflCd, atflId);
|
||||
setAtflCd(atflCd);
|
||||
setAtflId(atflId);
|
||||
};
|
||||
|
||||
// 현재 년도부터 10년 전까지의 년도 옵션 생성
|
||||
const yearOptions = Array.from({ length: 10 }, (_, i) => {
|
||||
const year = new Date().getFullYear() - i;
|
||||
return { text: `${year}년`, val: year.toString() };
|
||||
});
|
||||
const quater = [{ text: '1분기', val: '1' }, { text: '2분기', val: '2' }, { text: '3분기', val: '3' }, { text: '4분기', val: '4' }]
|
||||
const [files, setFiles] = useState<FileList | null>(null);
|
||||
const [selectedYear, setSelectedYear] = useState<string>(yearOptions[0]?.val || '');
|
||||
const [selectedQuarter, setSelectedQuarter] = useState<string>(quater[0]?.val || '');
|
||||
const [upload, setUpload] = useState<Upload | null>(null);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='card-header'>
|
||||
<h3 className="text-2xl font-medium">{title}</h3>
|
||||
</div>
|
||||
<div className="card p-6">
|
||||
<div className="grid grid-col-2 items-center space-x-4">
|
||||
<div className='flex'>
|
||||
<SelectBox
|
||||
className="w-50 mr-3 ml-4"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="년도"
|
||||
selectArray={yearOptions}
|
||||
onSelectValue={(value: string | number) => setSelectedYear(String(value))}
|
||||
/><SelectBox
|
||||
className="w-50"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="분기"
|
||||
selectArray={quater}
|
||||
onSelectValue={(value: string | number) => setSelectedQuarter(String(value))}
|
||||
/>
|
||||
<div className='flex ml-5 items-center'>
|
||||
<div className="w-[80px] mr-4">
|
||||
<FileUploader
|
||||
id="atflCd"
|
||||
className="!h-auto !max-w-none flex-col !items-start"
|
||||
accept=".jpeg,.jpg,.png"
|
||||
onUpload={(e) => {
|
||||
const selectedFiles = e.target.files;
|
||||
if (!selectedFiles) return;
|
||||
|
||||
setFiles(selectedFiles);
|
||||
if (selectedFiles[0]) {
|
||||
handleUpload(selectedFiles, {
|
||||
handleUploadStart: setUpload,
|
||||
handleSuccess: setUpload,
|
||||
handleResponse: handleUploadResponse(selectedFiles[0]),
|
||||
});
|
||||
}
|
||||
|
||||
}}
|
||||
customPreview={<></>}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
console.log(files?.[0]?.name)
|
||||
if (!files) {
|
||||
alert('파일을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!selectedYear) {
|
||||
alert('등록년도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!selectedQuarter) {
|
||||
alert('분기를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
const fileNm = files?.[0]?.name || '';
|
||||
onSubmit(fileNm, selectedYear, selectedQuarter, atflCd || '', atflId || '');
|
||||
}}
|
||||
>
|
||||
등록
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default operFileUploadForm
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { Button, DatePicker, Input } from '@common/components/ui'
|
||||
import { Button, DatePicker, Input, FileUploader } from '@common/components/ui'
|
||||
import { z } from 'zod'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { useForm } from 'react-hook-form'
|
||||
@@ -8,7 +8,10 @@ import FormSection from '@/components/ui/formSection'
|
||||
import BaseLayout from '../BaseLayout'
|
||||
import { filePicked, FileUpload } from '@common/business_components/ui'
|
||||
import { excelToflowRateData, excelToMatchingResultData, excelToTimePatternData } from '../../components/lib/utils/excelToJson'
|
||||
import { postData } from '@/components/lib/api'
|
||||
import { handleUpload } from '../../components/lib/utils/fileUploadUtil'
|
||||
import type { HttpResponse, Upload } from "tus-js-client";
|
||||
import FileUploadForm from '@/components/ui/fileUploadForm'
|
||||
import { deleteData, getData, postData } from '@/components/lib/api'
|
||||
|
||||
const formSchema = z.object({
|
||||
managenm: z.string(),
|
||||
@@ -33,104 +36,199 @@ const IrSetting = () => {
|
||||
pattern: ""
|
||||
}
|
||||
})
|
||||
const [file1, setFile1] = useState<File | null>(null);
|
||||
const [file2, setFile2] = useState<File | null>(null);
|
||||
const [file3, setFile3] = useState<File | null>(null);
|
||||
const [file4, setFile4] = useState<File | null>(null);
|
||||
const [selectedDate, setSelectedDate] = useState(new Date())
|
||||
const fileInputRef1 = useRef<HTMLInputElement>(null)
|
||||
const fileInputRef2 = useRef<HTMLInputElement>(null)
|
||||
const fileInputRef3 = useRef<HTMLInputElement>(null)
|
||||
const fileInputRef4 = useRef<HTMLInputElement>(null)
|
||||
|
||||
const handleUploadResponse = (file: File) => async (res: HttpResponse) => {
|
||||
const fileInfo = res.getHeader("X-File-Info");
|
||||
if (!fileInfo) return;
|
||||
const { atflCd, atflId } = JSON.parse(fileInfo) ?? {};
|
||||
const orgnlFileNm = file.name;
|
||||
console.log('orgnlFileNm', orgnlFileNm, atflCd, atflId);
|
||||
setAtflCd(atflCd);
|
||||
setAtflId(atflId);
|
||||
};
|
||||
|
||||
// const fileInputRef1 = useRef<HTMLInputElement>(null);
|
||||
// const fileInputRef2 = useRef<HTMLInputElement>(null);
|
||||
// const fileInputRef3 = useRef<HTMLInputElement>(null);
|
||||
// const fileInputRef4 = useRef<HTMLInputElement>(null);
|
||||
const [fileInfos, setFileInfos] = useState([
|
||||
{ atflId: null, atflCd: null }, // 파일1
|
||||
{ atflId: null, atflCd: null }, // 파일2
|
||||
{ atflId: null, atflCd: null }, // 파일3
|
||||
{ atflId: null, atflCd: null }, // 파일4
|
||||
]);
|
||||
const fileInputRef1 = useRef<HTMLInputElement>(null);
|
||||
const fileInputRef2 = useRef<HTMLInputElement>(null);
|
||||
const fileInputRef3 = useRef<HTMLInputElement>(null);
|
||||
const [atflCd, setAtflCd] = useState<string | null>(null);
|
||||
const [atflId, setAtflId] = useState<string | null>(null);
|
||||
const [upload, setUpload] = useState<Upload | null>(null);
|
||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||
const [input1, setInput1] = useState('');
|
||||
const [input2, setInput2] = useState('');
|
||||
const [select1, setSelect1] = useState('');
|
||||
const [select2, setSelect2] = useState('');
|
||||
const [select3, setSelect3] = useState('');
|
||||
const [select4, setSelect4] = useState('');
|
||||
|
||||
const registFile = async (
|
||||
fileNm: string,
|
||||
year: string,
|
||||
quater: string,
|
||||
cd: string,
|
||||
id: string,
|
||||
fileIdx: number // 추가: 파일 구분용 인덱스
|
||||
) => {
|
||||
const data = await postData('v1/sbmrgPrevnt', {
|
||||
atflNm: fileNm,
|
||||
mngYr: year,
|
||||
mngQu: quater,
|
||||
atflCd: cd,
|
||||
atflId: id
|
||||
});
|
||||
if (data.ok) {
|
||||
setFileInfos(prev =>
|
||||
prev.map((info, idx) =>
|
||||
idx === fileIdx
|
||||
? { atflId: data.atflId, atflCd: data.atflCd }
|
||||
: info
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 버튼 클릭 핸들러
|
||||
const handleAnalysisClick = async () => {
|
||||
const file1 = fileInputRef1.current?.files?.[0]
|
||||
const file2 = fileInputRef2.current?.files?.[0]
|
||||
const file3 = fileInputRef3.current?.files?.[0]
|
||||
const file1 = fileInputRef1.current?.files?.[0];
|
||||
const fileRefs = [fileInputRef1, fileInputRef2, fileInputRef3];
|
||||
const files = fileRefs.map(ref => ref.current?.files?.[0]);
|
||||
const [file2, file3, file4] = files;
|
||||
|
||||
if (!file1 || !file2 || !file3) {
|
||||
alert('모든 파일을 선택해주세요.')
|
||||
return
|
||||
}
|
||||
// if (!fileInputRef1.current?.files?.[0] || files.some(f => !f)) {
|
||||
// alert('모든 파일을 select해주세요.');
|
||||
// return;
|
||||
// }
|
||||
|
||||
let json2: any = null;
|
||||
let json3: any = null;
|
||||
const filePickers = [
|
||||
{ file: file2, parser: excelToMatchingResultData },
|
||||
{ file: file3, parser: excelToTimePatternData },
|
||||
{ file: file4, parser: excelToflowRateData }
|
||||
];
|
||||
|
||||
await filePicked(file2, 0).then((res) => {
|
||||
if (res !== undefined) json2 = excelToMatchingResultData(res);
|
||||
});
|
||||
await filePicked(file3, 0).then((res) => {
|
||||
if (res !== undefined) json3 = excelToTimePatternData(res);
|
||||
});
|
||||
console.log(file2);
|
||||
console.log(file3);
|
||||
console.log(file4);
|
||||
|
||||
const [json2, json3, json4] = await Promise.all(
|
||||
filePickers.map(async ({ file, parser }) => {
|
||||
if (!file) return null;
|
||||
const res = await filePicked(file, 0);
|
||||
return res !== undefined ? parser(res) : null;
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
console.log(file1)
|
||||
console.log(json2)
|
||||
console.log(json3)
|
||||
}
|
||||
|
||||
|
||||
// 버튼 클릭 핸들러
|
||||
const handleUploadClick = async () => {
|
||||
const file4 = fileInputRef4.current?.files?.[0];
|
||||
|
||||
if (!file4) {
|
||||
alert('파일을 선택해주세요.')
|
||||
return
|
||||
}
|
||||
let json4: any = null;
|
||||
await filePicked(file4, 0).then((res) => {
|
||||
console.log(res);
|
||||
if (res !== undefined) json4 = excelToflowRateData(res);
|
||||
});
|
||||
console.log(json4);
|
||||
|
||||
// json4가 존재하면 postData로 백엔드에 전송
|
||||
if (json4) {
|
||||
try {
|
||||
const response = await postData('your-backend-endpoint', json4); // 'your-backend-endpoint'를 실제 API 경로로 변경
|
||||
console.log('업로드 결과:', response);
|
||||
alert('업로드가 완료되었습니다.');
|
||||
} catch (error) {
|
||||
console.error('업로드 실패:', error);
|
||||
alert('업로드에 실패했습니다.');
|
||||
}
|
||||
}
|
||||
// console.log(file1);
|
||||
// console.log(json2);
|
||||
// console.log(json3);
|
||||
// console.log(json4);
|
||||
console.log(`선택된 날짜: ${selectedDate}`);
|
||||
console.log(`오수전환율: ${input1}`);
|
||||
console.log(`분석 정보: ${input2}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<BaseLayout titleName={{ mainTitle: '침입수 분석', firstCardTitle: '침입수 분석 자료 입력', secondCardTitle: '실측자료 등록' }} form={form} onSubmitEvent={() => { }} graphBtn={false} searchBox={{ title: '분석 대장지역 선택' }} >
|
||||
<BaseLayout
|
||||
titleName={{ mainTitle: '침입수 분석', firstCardTitle: '침입수 분석 자료 입력', secondCardTitle: '실측자료 등록' }}
|
||||
form={form}
|
||||
onSubmitEvent={() => { }}
|
||||
graphBtn={false}
|
||||
searchBox={{ title: '분석 대장지역 선택' }} >
|
||||
<div className="grid gap-4">
|
||||
<FormSection name='suyeongaPlace' form={form} titleNm='▷ 오수관망도'><div className="">
|
||||
<Input id="fileNm" ref={fileInputRef1} type="file" />
|
||||
</div></FormSection>
|
||||
<FormSection name='suyeonga' form={form} titleNm='▷ 수용가-맨홀 매칭결과'><div className="w-[150px]">
|
||||
<Input id="fileNm" ref={fileInputRef2} type="file" accept=".xls, .xlsx, .xlsm, .xltx" />
|
||||
</div></FormSection>
|
||||
<FormSection name='pattern' form={form} titleNm='▷ 오수량 시간패턴'><div className="w-[150px]">
|
||||
<Input id="fileNm" ref={fileInputRef3} type="file" accept=".xls, .xlsx, .xlsm, .xltx" />
|
||||
</div></FormSection>
|
||||
<FormSection name='inputdate' form={form} titleNm='▷ 상수사용량 적용기간'>
|
||||
<DatePicker selected={selectedDate} onSelect={(date: Date | undefined) => { if (date) setSelectedDate(date) }} mode={"single"} />
|
||||
<FormSection name='suyeongaPlace' form={form} titleNm='▷ 오수관망도'>
|
||||
<FileUploadForm
|
||||
onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id, 0) }}
|
||||
showButton={false}
|
||||
showPreview={true}
|
||||
accept={""} />
|
||||
</FormSection>
|
||||
<FormSection name='suyeonga' form={form} titleNm='▷ 수용가-맨홀 매칭결과'>
|
||||
{/* <FileUploadForm
|
||||
onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id, 1) }}
|
||||
showButton={false}
|
||||
showPreview={true}
|
||||
accept={".xls, .xlsx, .xlsm, .xltx"} /> */}
|
||||
<Input id="fileNm" ref={fileInputRef1} type="file" accept=".xls, .xlsx, .xlsm, .xltx" />
|
||||
</FormSection>
|
||||
<FormSection name='pattern' form={form} titleNm='▷ 오수량 시간패턴'>
|
||||
{/* <FileUploadForm
|
||||
onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id, 2) }}
|
||||
showButton={false}
|
||||
showPreview={true}
|
||||
accept={".xls, .xlsx, .xlsm, .xltx"} /> */}
|
||||
<Input id="fileNm" ref={fileInputRef2} type="file" accept=".xls, .xlsx, .xlsm, .xltx" />
|
||||
</FormSection>
|
||||
<FormSection
|
||||
name='inputdate'
|
||||
form={form}
|
||||
titleNm='▷ 상수사용량 적용기간'>
|
||||
<DatePicker
|
||||
className="ml-5"
|
||||
selected={selectedDate}
|
||||
onSelect={(date: Date | undefined) => { if (date) setSelectedDate(date) }}
|
||||
mode={"single"} />
|
||||
</FormSection>
|
||||
<FormSection
|
||||
name='rtkSource'
|
||||
form={form}
|
||||
titleNm='▷ 오수전환율'>
|
||||
<Input
|
||||
value={input1}
|
||||
onChange={(e) => {
|
||||
const newValue = e.target.value;
|
||||
|
||||
if (newValue === "") {
|
||||
setInput1(newValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// 숫자와 '.'만 허용하고, '.'은 최대 하나인지 확인
|
||||
const isValidChars = /^[0-9]*\.?[0-9]*$/.test(newValue);
|
||||
if (!isValidChars) return; // 유효하지 않은 문자 또는 여러 개의 '.' 포함
|
||||
|
||||
// '.' 기호가 포함된 경우, 처음이나 끝에 오면 안 됨
|
||||
if (newValue.includes('.') && newValue.startsWith('.')) return; // '.'이 처음에는 올 수 없음
|
||||
|
||||
setInput1(newValue);
|
||||
}}
|
||||
className="ml-5 h-[3.2rem] text-center text-xl w-[150px]"
|
||||
placeholder="예: 0.75" />
|
||||
</FormSection>
|
||||
<FormSection
|
||||
name='analysis information'
|
||||
form={form}
|
||||
titleNm='▷ 분석 정보'>
|
||||
<Input
|
||||
value={input2}
|
||||
onChange={(e) => setInput2(e.target.value)}
|
||||
className="ml-5 h-[3.2rem] text-center text-xl w-[150px]" />
|
||||
</FormSection>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<FormSection
|
||||
name='region' form={form} titleNm='▷ 유량자료 등록'>
|
||||
{/* <FileUploadForm
|
||||
onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id, 3) }}
|
||||
showButton={false}
|
||||
showPreview={true}
|
||||
accept={".xls, .xlsx, .xlsm, .xltx"} /> */}
|
||||
<Input id="fileNm" ref={fileInputRef3} type="file" accept=".xls, .xlsx, .xlsm, .xltx" />
|
||||
</FormSection>
|
||||
<FormSection name='rtkSource' form={form} titleNm='▷ 오수전환율'><Input className="h-[3.2rem] text-center text-xl w-[150px]" /></FormSection>
|
||||
<FormSection name='analysis information' form={form} titleNm='▷ 분석 정보'><Input className="h-[3.2rem] text-center text-xl w-[150px]" /></FormSection>
|
||||
<div className="flex justify-center mt-1">
|
||||
<Button type="submit" onClick={handleAnalysisClick}>침입수분석 실행</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-24">
|
||||
<FormSection name='region' form={form} titleNm='▷ 유량자료 등록'>
|
||||
<div className="w-[150px]">
|
||||
<Input id="fileNm" ref={fileInputRef4} type="file" accept=".xls, .xlsx, .xlsm, .xltx" />
|
||||
</div>
|
||||
</FormSection>
|
||||
<div className='mt-1'>
|
||||
<Button type="submit" onClick={handleUploadClick}>자료 업로드</Button>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { SearchDiv, SearchFormLeft, SearchFormRight, UiTable } from '@common/business_components/ui'
|
||||
import { Button, DatePicker, Input, Label } from '@common/components/ui'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import FileUploadForm from '../../components/ui/fileUploadForm'
|
||||
import OperFileUploadForm from '../../components/ui/operFileUploadForm'
|
||||
import ListDiv from '@common/business_components/ui/list_div'
|
||||
import ContentLayout from '@/components/ui/contentLayout'
|
||||
import { searchData } from '@/components/lib/common/apiHelpers'
|
||||
@@ -136,7 +136,7 @@ const Page = () => {
|
||||
<UiTable headName='' tableData={tableData} headlist={tableHeadlist} pageSize={10} total={10} cellClick={(index) => { if (index != null) { const fileName = tableData[index]?.fileNm ?? ""; setFileNm(fileName); setSbmrgPrevntBizSn(tableData[index]?.sbmrgPrevntBizSn) } }} onPageChange={async (page:number)=>{setCurPage(page); await fetchData()}}></UiTable>
|
||||
</ListDiv>
|
||||
<ListDiv className="mt-4">
|
||||
<FileUploadForm title='도시침수 예방사업 사업추진현황 등록' onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id) }} />
|
||||
<OperFileUploadForm title='도시침수 예방사업 사업추진현황 등록' onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id) }} />
|
||||
</ListDiv>
|
||||
</ContentLayout>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { SearchDiv, SearchFormLeft, SearchFormRight, UiTable } from '@common/business_components/ui'
|
||||
import { Button, DatePicker, Input, Label } from '@common/components/ui'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import FileUploadForm from '../../components/ui/fileUploadForm'
|
||||
import OperFileUploadForm from '../../components/ui/operFileUploadForm'
|
||||
import ListDiv from '@common/business_components/ui/list_div'
|
||||
import ContentLayout from '@/components/ui/contentLayout'
|
||||
import { tableHeadlist } from '..'
|
||||
@@ -140,7 +140,7 @@ const Page = () => {
|
||||
<UiTable headName='' tableData={tableData} headlist={tableHeadlist} pageSize={10} total={20} children={undefined} cellClick={(index) => { if (index != null) { const fileName = tableData[index]?.fileNm ?? ""; setFileNm(fileName); setSbmrgPrevntBizSn(tableData[index]?.sbmrgPrevntBizSn) } }} onPageChange={async (page:number)=>{setCurPage(page); await fetchData()}}></UiTable>
|
||||
</ListDiv>
|
||||
<ListDiv className="mt-4">
|
||||
<FileUploadForm title='노후 하수관로 정비사업 주진현황 등록' onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id) }} />
|
||||
<OperFileUploadForm title='노후 하수관로 정비사업 주진현황 등록' onSubmit={async (file, year, quater, cd, id) => { await registFile(file, year, quater, cd, id) }} />
|
||||
</ListDiv>
|
||||
</ContentLayout>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user