477 lines
17 KiB
JavaScript

'use client'
import { useEffect, useState, useRef, useContext } from 'react'
import { useRouter, usePathname } from 'next/navigation'
import { useAxios } from '@/hooks/useAxios'
import { useMessage } from '@/hooks/useMessage'
import StuffQGrid from './StuffQGrid'
import { useRecoilValue, useRecoilState, useSetRecoilState, useResetRecoilState } from 'recoil'
import { stuffSearchState } from '@/store/stuffAtom'
import { queryStringFormatter, isEmptyArray } from '@/util/common-utils'
import dayjs from 'dayjs'
import { convertNumberToPriceDecimal } from '@/util/common-utils'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
import QPagination from '../common/pagination/QPagination'
import { SessionContext } from '@/app/SessionProvider'
import { QcastContext } from '@/app/QcastProvider'
export default function Stuff() {
const { setIsGlobalLoading } = useContext(QcastContext)
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
const { session } = useContext(SessionContext)
const setAppMessageState = useSetRecoilState(appMessageStore)
const stuffSearchParams = useRecoilValue(stuffSearchState)
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
const { getMessage } = useMessage()
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
const [pageSize, setPageSize] = useState(100) //페이지 당 게시물 수
const [totalCount, setTotalCount] = useState(0) //총 갯수
const [defaultSortType, setDefaultSortType] = useState('U')
const globalLocaleState = useRecoilValue(globalLocaleStore)
const { get } = useAxios(globalLocaleState)
const gridRef = useRef()
const router = useRouter()
const pathname = usePathname()
//그리드 내부 복사버튼
const copyNo = async (value) => {
// try {
// await navigator.clipboard.writeText(value)
// alert(getMessage('stuff.detail.header.successCopy'))
// } catch (error) {
// alert(getMessage('stuff.detail.header.failCopy'))
// }
// Navigator clipboard api needs a secure context (https)
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard
.writeText(value)
.then(() => {
alert(getMessage('stuff.detail.header.successCopy'))
})
.catch(() => {
alert(getMessage('stuff.detail.header.failCopy'))
})
} else {
// Use the 'out of viewport hidden text area' trick
const textArea = document.createElement('textArea')
textArea.value = value
// Move textarea out of the viewport so it's not visible
textArea.style.position = 'absolute'
textArea.style.left = '-999999px'
document.body.prepend(textArea)
textArea.select()
try {
document.execCommand('copy')
alert(getMessage('stuff.detail.header.successCopy'))
} catch (err) {
alert(getMessage('stuff.detail.header.failCopy'))
} finally {
textArea.remove()
}
}
}
//물건번호 복사버튼 옆에 영역
const onDoubleClick = (data) => {
setIsGlobalLoading(true)
if (data.tempFlg === '0') {
router.push(`${pathname}/detail?objectNo=${data.objectNo.toString()}`, { scroll: false })
} else {
router.push(`${pathname}/tempdetail?objectNo=${data.objectNo.toString()}`, { scroll: false })
}
}
const [gridProps, setGridProps] = useState({
gridData: [],
isPageable: false,
gridColumns: [
{
field: 'lastEditDatetime',
minWidth: 200,
headerName: getMessage('stuff.gridHeader.lastEditDatetime'),
cellStyle: { justifyContent: 'center' },
valueFormatter: function (params) {
if (params.value) {
return dayjs(params?.value).format('YYYY.MM.DD HH:mm:ss')
} else {
return null
}
},
},
{
field: 'objectNo',
minWidth: 230,
headerName: getMessage('stuff.gridHeader.objectNo'),
cellRenderer: function (params) {
if (params.data.objectNo) {
return (
<div className="copy-ico-wrap" onDoubleClick={() => onDoubleClick(params.data)}>
{(params.data.tempFlg === '0' && (
<>
{params.value.toLocaleString()}
<button
type="button"
className="copy_ico"
onClick={() => {
copyNo(params.value)
}}
></button>
</>
)) || <>{getMessage('stuff.gridData.tempObjectNo')}</>}
</div>
)
}
},
cellRendererParams: {
onClick: copyNo,
},
},
{
field: 'planTotCnt',
headerName: getMessage('stuff.gridHeader.planTotCnt'),
cellStyle: { justifyContent: 'center' },
},
{ field: 'objectName', headerName: getMessage('stuff.gridHeader.objectName'), cellStyle: { textAlign: 'left' } },
{
field: 'saleStoreId',
headerName: getMessage('stuff.gridHeader.saleStoreId'),
cellStyle: { textAlign: 'left' },
},
{ field: 'saleStoreName', minWidth: 300, headerName: getMessage('stuff.gridHeader.saleStoreName'), cellStyle: { textAlign: 'left' } },
{ field: 'address', headerName: getMessage('stuff.gridHeader.address'), cellStyle: { textAlign: 'left' } },
{ field: 'dispCompanyName', headerName: getMessage('stuff.gridHeader.dispCompanyName'), cellStyle: { textAlign: 'left' } },
{ field: 'receiveUser', headerName: getMessage('stuff.gridHeader.receiveUser'), cellStyle: { textAlign: 'left' } },
{
field: 'specificationConfirmDate',
headerName: getMessage('stuff.gridHeader.specificationConfirmDate'),
valueFormatter: function (params) {
if (params.value) {
return dayjs(params?.value).format('YYYY.MM.DD')
} else {
return null
}
},
cellStyle: { justifyContent: 'center' },
},
{
field: 'createDatetime',
headerName: getMessage('stuff.gridHeader.createDatetime'),
valueFormatter: function (params) {
if (params.value) {
return dayjs(params?.value).format('YYYY.MM.DD')
} else {
return null
}
},
cellStyle: { justifyContent: 'center' },
},
],
gridCount: 0,
})
//그리드 더블클릭
const getCellDoubleClicked = (event) => {
if (event.column.colId === 'objectNo') {
return
} else {
//T 면 임시 R은 진짜
if (event.data.objectNo) {
setIsGlobalLoading(true)
if (event.data.tempFlg === '0') {
router.push(`${pathname}/detail?objectNo=${event.data.objectNo.toString()}`, { scroll: false })
} else {
router.push(`${pathname}/tempdetail?objectNo=${event.data.objectNo.toString()}`, { scroll: false })
}
}
}
}
// 진입시 그리드 데이터 조회
useEffect(() => {
if (stuffSearchParams?.code === 'S') {
const params = {
saleStoreId: session.storeId,
schObjectNo: stuffSearchParams?.schObjectNo,
schAddress: stuffSearchParams?.schAddress,
schObjectName: stuffSearchParams?.schObjectName,
schSaleStoreName: stuffSearchParams?.schSaleStoreName,
schReceiveUser: stuffSearchParams?.schReceiveUser,
schDispCompanyName: stuffSearchParams?.schDispCompanyName,
schDateType: stuffSearchParams.schDateType,
schTempFlg: stuffSearchParams.schTempFlg, //임시저장 물건
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
startRow: (stuffSearch.pageNo - 1) * stuffSearchParams.pageSize + 1,
endRow: stuffSearchParams?.endRow,
schSelSaleStoreId: stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : '',
schOtherSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : '',
schSortType: stuffSearchParams.schSortType,
pageNo: stuffSearchParams?.pageNo ? stuffSearchParams.pageNo : 1,
pageSize: stuffSearchParams?.pageSize ? stuffSearchParams.pageSize : 100,
}
async function fetchData() {
const apiUrl = `/api/object/list?${queryStringFormatter(params)}`
await get({
url: apiUrl,
}).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
setTotalCount(res[0].totCnt)
} else {
setGridProps({ ...gridProps, gridData: [], count: 0 })
setTotalCount(0)
setPageNo(1)
setPageSize(stuffSearchParams.pageSize)
stuffSearchParams.pageNo = 1
stuffSearchParams.startRow = 1
stuffSearchParams.endRow = 1 * stuffSearchParams.pageSize
}
setIsGlobalLoading(false)
})
}
fetchData()
} else if (stuffSearchParams?.code === 'M') {
const params = {
schObjectNo: stuffSearchParams.schObjectNo,
schAddress: '',
schObjectName: '',
schSaleStoreName: '',
schReceiveUser: '',
schDispCompanyName: '',
schDateType: 'U',
schTempFlg: '',
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
startRow: (pageNo - 1) * pageSize + 1,
endRow: pageNo * pageSize,
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
schSortType: 'U',
code: 'E',
pageNo: 1,
pageSize: 100,
}
setStuffSearch({
...params,
})
} else if (stuffSearchParams?.code === 'E') {
stuffSearchParams.startRow = (stuffSearch.pageNo - 1) * stuffSearchParams.pageSize + 1
stuffSearchParams.endRow = stuffSearchParams.pageNo * stuffSearchParams.pageSize
stuffSearchParams.schSortType = defaultSortType
stuffSearchParams.pageNo = stuffSearchParams.pageNo
async function fetchData() {
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
await get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
setTotalCount(res[0].totCnt)
} else {
setGridProps({ ...gridProps, gridData: [], count: 0 })
setTotalCount(0)
setPageNo(1)
setPageSize(stuffSearchParams.pageSize)
stuffSearchParams.pageNo = 1
stuffSearchParams.startRow = 1
stuffSearchParams.endRow = 1 * stuffSearchParams.pageSize
}
setIsGlobalLoading(false)
})
}
fetchData()
} else if (stuffSearchParams?.code === 'C') {
resetStuffRecoil()
setIsGlobalLoading(false)
} else if (stuffSearchParams?.code === 'FINISH') {
stuffSearchParams.startRow = 1
stuffSearchParams.endRow = 1 * pageSize
stuffSearchParams.schSortType = defaultSortType
setPageNo(1)
async function fetchData() {
const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
await get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
setTotalCount(res[0].totCnt)
} else {
setGridProps({ ...gridProps, gridData: [], count: 0 })
setTotalCount(0)
}
})
setIsGlobalLoading(false)
}
fetchData()
} else if (stuffSearchParams?.code === 'DELETE') {
const newParams = {
saleStoreId: session.storeId,
schObjectNo: '',
schAddress: '',
schObjectName: '',
schSaleStoreName: '',
schReceiveUser: '',
schDispCompanyName: '',
schDateType: 'U',
schTempFlg: '',
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
startRow: 1,
endRow: 100,
schSelSaleStoreId: '',
schOtherSelSaleStoreId: '',
schSortType: 'U',
code: 'S',
pageNo: 1,
pageSize: 100,
}
setStuffSearch({
...newParams,
})
setIsGlobalLoading(false)
} else {
stuffSearchParams.code = 'DELETE'
setIsGlobalLoading(false)
}
}, [stuffSearchParams])
//페이지 갯수 변경 이벤트
const onChangePerPage = (e) => {
let startRow = (1 - 1) * e.target.value + 1
stuffSearchParams.startRow = startRow
stuffSearchParams.endRow = 1 * e.target.value
stuffSearchParams.schSelSaleStoreId = stuffSearchParams.schSelSaleStoreId
stuffSearchParams.schOtherSelSaleStoreId = stuffSearchParams.schOtherSelSaleStoreId
stuffSearchParams.pageNo = startRow
stuffSearchParams.pageSize = 1 * e.target.value
setPageSize(e.target.value)
setStuffSearch({
...stuffSearch,
code: 'E',
startRow: startRow,
endRow: 1 * e.target.value,
pageSize: e.target.value,
})
setPageNo(1)
}
//최근 등록일 수정일 정렬 이벤트
const onChangeSortType = (e) => {
let startRow = (1 - 1) * stuffSearchParams.pageSize + 1
stuffSearchParams.startRow = startRow
stuffSearchParams.endRow = startRow * stuffSearchParams.pageSize
stuffSearchParams.schSelSaleStoreId = stuffSearchParams.schSelSaleStoreId
stuffSearchParams.schOtherSelSaleStoreId = stuffSearchParams.schOtherSelSaleStoreId
stuffSearchParams.pageNo = startRow
stuffSearchParams.pageSize = 1 * stuffSearchParams.pageSize
setPageSize(stuffSearchParams.pageSize)
stuffSearchParams.schSortType = e.target.value
setDefaultSortType(e.target.value)
setStuffSearch({
...stuffSearch,
code: 'E',
startRow: startRow,
endRow: startRow * stuffSearchParams.pageSize,
pageSize: stuffSearchParams.pageSize,
schSortType: e.target.value,
})
setPageNo(1)
}
useEffect(() => {
if (globalLocaleState === 'ko') {
setAppMessageState(KO)
} else {
setAppMessageState(JA)
}
}, [globalLocaleState])
// 페이징 현재페이지 변경
const handleChangePage = (page) => {
stuffSearchParams.code = 'S'
stuffSearchParams.schSelSaleStoreId = stuffSearchParams.schSelSaleStoreId
stuffSearchParams.schOtherSelSaleStoreId = stuffSearchParams.schOtherSelSaleStoreId
setStuffSearch({
...stuffSearch,
code: 'E',
startRow: (page - 1) * pageSize + 1,
endRow: page * stuffSearchParams?.pageSize,
pageNo: page,
})
setPageNo(page)
}
useEffect(() => {
setIsGlobalLoading(true)
}, [])
return (
<>
{/* 퍼블시작 */}
<div className="sub-table-box">
<div className="table-box-title-wrap">
<div className="title-wrap">
<h3>{getMessage('stuff.search.grid.title')}</h3>
<ul className="info-wrap">
<li>
{getMessage('stuff.search.grid.all')}
<span>{convertNumberToPriceDecimal(totalCount)}</span>
</li>
<li></li>
</ul>
</div>
<div className="left-unit-box">
<div className="select-box mr5" style={{ width: '110px' }}>
<select className="select-light black" onChange={onChangeSortType} value={stuffSearch.schSortType}>
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
</select>
</div>
<div className="select-box" style={{ width: '80px' }}>
<select className="select-light black" onChange={onChangePerPage} value={stuffSearch.pageSize}>
<option value="100">100</option>
<option value="200">200</option>
<option value="300">300</option>
</select>
</div>
</div>
</div>
<div className="grid-table-wrap">
<div className="q-grid">
<StuffQGrid {...gridProps} getCellDoubleClicked={getCellDoubleClicked} gridRef={gridRef} />
<div className="pagination-wrap">
<QPagination
pageNo={stuffSearch.pageNo}
pageSize={stuffSearch.pageSize}
pagePerBlock={10}
totalCount={totalCount}
handleChangePage={handleChangePage}
/>
</div>
</div>
</div>
</div>
{/* 퍼블종료 */}
</>
)
}