225 lines
8.1 KiB
TypeScript
225 lines
8.1 KiB
TypeScript
'use client'
|
|
import { deleteData, postData } from '@/components/lib/api'
|
|
import { searchData } from '@/components/lib/common/apiHelpers'
|
|
import { formatDate, handleDownload, yearOptions } from '@/components/lib/utils'
|
|
import LoadingOverlay from '@/components/ui/LoadingBar'
|
|
import { SearchDiv, SearchFormLeft, SearchFormRight, UiTable, UiModal } from '@common/business_components/ui'
|
|
import ListDiv from '@common/business_components/ui/list_div'
|
|
import { Button, DatePicker, Input, Label } from '@common/components/ui'
|
|
import { useEffect, useState } from 'react'
|
|
import { tableHeadlistOldPp } from '..'
|
|
import OperFileUploadForm from '../../../components/ui/operFileUploadForm'
|
|
|
|
|
|
const Page = () => {
|
|
const [fromDate, setFromDate] = useState<Date>(() => { const date = new Date(); date.setDate(date.getDate() - 7); return date });
|
|
const [toDate, setToDate] = useState<Date>(new Date());
|
|
const [usr, setUsr] = useState('')
|
|
const [pjNm, setpjNm] = useState('')
|
|
const [fileNm, setFileNm] = useState('')
|
|
const [atflId, setAtflId] = useState('')
|
|
const [dcrpPplMtncBizSn, setDcrpPplMtncBizSn] = useState('')
|
|
const [tableData, setTableData] = useState<any>([{}])
|
|
const [curPage, setCurPage] = useState(1)
|
|
const [totalData, setTotalData] = useState(0) //총 데이터 수
|
|
const [isLoading, setIsLoading] = useState(true) //로딩 상태
|
|
const [isModalOpen, setIsModalOpen] = useState(false) // 모달 상태
|
|
const [resetSelection, setResetSelection] = useState<boolean>(false); // 선택 초기화 상태
|
|
const [isResetPage, setIsResetPage] = useState<boolean>(false);
|
|
|
|
useEffect(() => {
|
|
setCurPage(1)
|
|
fetchData()
|
|
}, [])
|
|
|
|
// 페이지 변경 시마다 데이터 fetch
|
|
useEffect(() => {
|
|
setIsResetPage(false);
|
|
fetchData();
|
|
}, [curPage]);
|
|
|
|
// 조회 버튼 클릭 시 1페이지로 이동 및 데이터 초기화
|
|
const handleSearch: () => Promise<void> = async () => {
|
|
setCurPage(1); // 페이지를 1로 초기화
|
|
setIsResetPage(true); // 페이지를 초기화
|
|
await fetchData();
|
|
};
|
|
|
|
// 데이터 조회
|
|
const fetchData = async () => {
|
|
setIsLoading(true)
|
|
setResetSelection(true);
|
|
try {
|
|
const { data, total } = await searchData('v1/dcrpPpl', {
|
|
fromRegDt: formatDate(fromDate),
|
|
toRegDt: formatDate(toDate),
|
|
dcrpPplMtncBizNm: pjNm,
|
|
rgtrNm: usr,
|
|
page: curPage - 1,
|
|
size: '10'
|
|
})
|
|
// 일련번호를 추가한 데이터로 변환 (전체 데이터 기준으로 일련번호 계산)
|
|
const dataWithRowNumber = (data || []).map((item: any, index: number) => ({
|
|
...item,
|
|
rowNumber: (curPage - 1) * 10 + index + 1, // 페이지 기준 일련번호 계산
|
|
}));
|
|
setTableData(dataWithRowNumber)
|
|
setTotalData(total)
|
|
} catch (error) {
|
|
console.error('Error fetching data:', error)
|
|
} finally {
|
|
setFileNm('');
|
|
setAtflId('');
|
|
setDcrpPplMtncBizSn('');
|
|
setIsLoading(false)
|
|
setResetSelection(false);
|
|
}
|
|
}
|
|
|
|
// 파일 다운로드
|
|
const isChckFile = () => {
|
|
if (fileNm === '' || fileNm === undefined) {
|
|
alert('파일을 선택해주세요')
|
|
return false
|
|
}
|
|
handleDownload(`/attach-service/api/v1/download/${atflId}`, fileNm)
|
|
return true
|
|
}
|
|
|
|
// 파일 삭제
|
|
const isDeleteFile = async () => {
|
|
if (dcrpPplMtncBizSn === '' || dcrpPplMtncBizSn === undefined) {
|
|
alert('삭제할 파일을 선택해주세요')
|
|
return false
|
|
}
|
|
const data = await deleteData(`/attach-service/api/v1/atfl/attachments/${atflId}`)
|
|
if (data) {
|
|
const delData = await deleteData(`v1/dcrpPpl/${dcrpPplMtncBizSn}`)
|
|
if (delData.status == 200) {
|
|
alert('삭제되었습니다.')
|
|
fetchData()
|
|
} else {
|
|
alert('삭제에 실패했습니다.')
|
|
}
|
|
}
|
|
}
|
|
|
|
// 파일 등록
|
|
const registFile = async (fileNm: string, year: string, quater: string, cd: string, id: string) => {
|
|
const data = await postData('v1/dcrpPpl', {
|
|
atflNm: fileNm,
|
|
mngYr: year,
|
|
mngQu: quater,
|
|
atflCd: cd,
|
|
atflId: id,
|
|
dcrpPplMtncBizNm: fileNm
|
|
})
|
|
if (data) {
|
|
alert('파일이 등록되었습니다.');
|
|
setIsModalOpen(false);
|
|
handleSearch();
|
|
}
|
|
}
|
|
|
|
// 등록 버튼 클릭 핸들러
|
|
const handleRegisterClick = () => {
|
|
setIsModalOpen(true);
|
|
}
|
|
|
|
|
|
return (
|
|
<>
|
|
<LoadingOverlay isLoading={isLoading ?? false} />
|
|
<SearchDiv>
|
|
<SearchFormLeft>
|
|
<div className='flex items-center gap-4'>
|
|
<div className='flex items-center space-x-2'>
|
|
<Label className="w-20 text-xl text-gray-600">등록기간</Label>
|
|
<DatePicker mode={'single'}
|
|
selected={fromDate}
|
|
onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }}
|
|
modifiers={{
|
|
disabled: { after: new Date() }
|
|
}} />
|
|
<span>~</span>
|
|
<DatePicker mode={'single'}
|
|
selected={toDate}
|
|
onSelect={(date: Date | undefined) => { if (date) setToDate(date) }}
|
|
modifiers={{
|
|
disabled: { after: new Date() }
|
|
}} />
|
|
<div className='flex items-center'>
|
|
<Label className="w-20 text-xl text-gray-600">등록자</Label>
|
|
<Input
|
|
className='w-[100px] !text-2xl'
|
|
value={usr}
|
|
onChange={(e) => setUsr(e.target.value)}
|
|
/>
|
|
</div>
|
|
<div className='flex items-center'>
|
|
<Label className="w-20 text-xl text-gray-600">파일명</Label>
|
|
<Input
|
|
className='w-[100px] !text-2xl'
|
|
value={pjNm}
|
|
onChange={(e) => { setpjNm(e.target.value) }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</SearchFormLeft>
|
|
<SearchFormRight>
|
|
<div className='flex items-center gap-5'>
|
|
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700" size="sm" onClick={async () => await handleSearch()} >조회</Button>
|
|
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700" size="sm" onClick={handleRegisterClick} >등록</Button>
|
|
</div>
|
|
</SearchFormRight>
|
|
</SearchDiv>
|
|
<ListDiv className="mt-4">
|
|
<div className="card-header flex items-center justify-between">
|
|
<h3 className="text-2xl font-medium">사업정보 등록현황</h3>
|
|
<div>
|
|
<Button className="px-4 py-2 !mr-[1.2rem] bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700" size="sm" onClick={isChckFile}>파일 다운로드</Button>
|
|
<Button className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700 !mr-[1.2rem]" size="sm" onClick={isDeleteFile}>삭제</Button>
|
|
</div>
|
|
</div>
|
|
<UiTable
|
|
headName=''
|
|
tableData={tableData}
|
|
headlist={tableHeadlistOldPp}
|
|
pageSize={10}
|
|
total={totalData}
|
|
children={undefined}
|
|
cellClick={(index) => {
|
|
if (index != null) {
|
|
const fileName = tableData[index]?.dcrpPplMtncBizNm ?? "";
|
|
const id = tableData[index]?.atflId ?? '';
|
|
setFileNm(fileName);
|
|
setAtflId(id);
|
|
setDcrpPplMtncBizSn(tableData[index]?.dcrpPplMtncBizSn);
|
|
}
|
|
}}
|
|
onPageChange={setCurPage}
|
|
resetSelection={resetSelection}
|
|
/>
|
|
</ListDiv>
|
|
{/* 파일 업로드 모달 */}
|
|
<UiModal
|
|
open={isModalOpen}
|
|
onOpenChange={setIsModalOpen}
|
|
bodyClass="w-auto max-w-[90vw] min-w-[600px] h-auto"
|
|
noHeaderYn="N"
|
|
noFooterYn="Y"
|
|
body={
|
|
<OperFileUploadForm
|
|
title='노후 하수관로 정비사업 추진현황 등록'
|
|
onSubmit={async (file, year, quater, cd, id) => {
|
|
await registFile(file, year, quater, cd, id)
|
|
}}
|
|
/>
|
|
}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default Page |