From 2f13c29d1babc87b6b36cb8fe4d819dbf1aa7c51 Mon Sep 17 00:00:00 2001 From: "focp212@naver.com" Date: Fri, 24 Oct 2025 18:34:21 +0900 Subject: [PATCH] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/vat-return/ui/list-wrap.tsx | 49 +++++++++++++++-- .../transaction/all-transaction/list-page.tsx | 3 +- src/pages/transaction/billing/list-page.tsx | 52 +++++++++++++++++-- .../transaction/cash-receipt/list-page.tsx | 50 +++++++++++++++++- src/pages/transaction/escrow/list-page.tsx | 26 +++++++++- 5 files changed, 168 insertions(+), 12 deletions(-) diff --git a/src/entities/vat-return/ui/list-wrap.tsx b/src/entities/vat-return/ui/list-wrap.tsx index 994c49b..4318383 100644 --- a/src/entities/vat-return/ui/list-wrap.tsx +++ b/src/entities/vat-return/ui/list-wrap.tsx @@ -16,10 +16,12 @@ import { useVatReturnListMutation } from '../api/use-vat-return-list-mutation'; import { ListDateGroup } from './list-date-group'; import { useStore } from '@/shared/model/store'; import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet'; +import useIntersectionObserver from '@/widgets/intersection-observer'; export const ListWrap = () => { const userMid = useStore.getState().UserStore.mid; + const [onActionIntersect, setOnActionIntersect] = useState(false); const [filterOn, setFilterOn] = useState(false); const [sortType, setSortType] = useState(SortTypeKeys.LATEST); const [listItems, setListItems] = useState>([]); @@ -33,8 +35,27 @@ export const ListWrap = () => { const [emailBottomSheetOn, setEmailBottomSheetOn] = useState(false); const { mutateAsync: vatReturnList } = useVatReturnListMutation(); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { + entries.forEach((entry: IntersectionObserverEntry) => { + if(entry.isIntersecting){ + console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); + if(onActionIntersect && !!pageParam.cursor){ + callList('page'); + } + } + else{ + console.log('Element is no longer intersecting with the root.'); + } + }); + }; - const callList = () => { + const { setTarget } = useIntersectionObserver({ + threshold: 1, + onIntersect + }); + + const callList = (type?: string) => { + setOnActionIntersect(false); let params: VatReturnListParams = { mid: mid, startMonth: startMonth, @@ -48,7 +69,28 @@ export const ListWrap = () => { }; vatReturnList(params).then((rs: VatReturnListResponse) => { - setListItems(rs.content); + if(type === 'page'){ + setListItems([ + ...listItems, + ...rs.content + ]); + } + else{ + setListItems(rs.content); + } + if(rs.hasNext){ + setPageParam({ + ...pageParam, + ...{ cursor: rs.nextCursor } + }); + setOnActionIntersect(true); + } + else{ + setPageParam({ + ...pageParam, + ...{ cursor: null } + }); + } }); }; @@ -152,7 +194,8 @@ export const ListWrap = () => { >
- { getListDateGroup() } + { getListDateGroup() } +
{ const [totalAmount, setTotalAmount] = useState(0); const [emailBottomSheetOn, setEmailBottomSheetOn] = useState(false); - - + useSetHeaderTitle('거래내역 조회'); useSetHeaderType(HeaderType.LeftArrow); useSetOnBack(() => { diff --git a/src/pages/transaction/billing/list-page.tsx b/src/pages/transaction/billing/list-page.tsx index 24c3350..32dd234 100644 --- a/src/pages/transaction/billing/list-page.tsx +++ b/src/pages/transaction/billing/list-page.tsx @@ -29,12 +29,14 @@ import { useSetFooterMode } from '@/widgets/sub-layout/use-sub-layout'; import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet'; +import useIntersectionObserver from '@/widgets/intersection-observer'; export const BillingListPage = () => { const { navigate } = useNavigate(); const userMid = useStore.getState().UserStore.mid; const userInfo = useStore((state) => state.UserStore.userInfo); + const [onActionIntersect, setOnActionIntersect] = useState(false); const [sortType, setSortType] = useState(SortTypeKeys.LATEST); const [listItems, setListItems] = useState>([]); const [filterOn, setFilterOn] = useState(false); @@ -62,8 +64,27 @@ export const BillingListPage = () => { const { mutateAsync: billingList } = useBillingListMutation(); const { mutateAsync: downloadExcel } = useDownloadExcelMutation(); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { + entries.forEach((entry: IntersectionObserverEntry) => { + if(entry.isIntersecting){ + console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); + if(onActionIntersect && !!pageParam.cursor){ + callList('page'); + } + } + else{ + console.log('Element is no longer intersecting with the root.'); + } + }); + }; - const callList = () => { + const { setTarget } = useIntersectionObserver({ + threshold: 1, + onIntersect + }); + + const callList = (type?: string) => { + setOnActionIntersect(false); let listParams: BillingListParams = { mid: mid, searchType: searchType, @@ -80,9 +101,33 @@ export const BillingListPage = () => { ...{ sortType: sortType } } }; + if(type !== 'page' && listParams.page){ + listParams.page.cursor = null; + } billingList(listParams).then((rs: BillingListResponse) => { - setListItems(rs.content); + if(type === 'page'){ + setListItems([ + ...listItems, + ...rs.content + ]); + } + else{ + setListItems(rs.content); + } + if(rs.hasNext){ + setPageParam({ + ...pageParam, + ...{ cursor: rs.nextCursor } + }); + setOnActionIntersect(true); + } + else{ + setPageParam({ + ...pageParam, + ...{ cursor: null } + }); + } }); } @@ -167,7 +212,8 @@ export const BillingListPage = () => { + > +
diff --git a/src/pages/transaction/cash-receipt/list-page.tsx b/src/pages/transaction/cash-receipt/list-page.tsx index 5ac7341..c477b71 100644 --- a/src/pages/transaction/cash-receipt/list-page.tsx +++ b/src/pages/transaction/cash-receipt/list-page.tsx @@ -33,11 +33,13 @@ import { CashReceiptTransactionTypeBtnGroup } from '@/entities/transaction/model import { useStore } from '@/shared/model/store'; import { useCashReceiptSummaryMutation } from '@/entities/transaction/api/use-cash-receipt-summary-mutation'; import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet'; +import useIntersectionObserver from '@/widgets/intersection-observer'; export const CashReceiptListPage = () => { const { navigate } = useNavigate(); const userMid = useStore.getState().UserStore.mid; + const [onActionIntersect, setOnActionIntersect] = useState(false); const [sortType, setSortType] = useState(SortTypeKeys.LATEST); const [listItems, setListItems] = useState>([]); const [filterOn, setFilterOn] = useState(false); @@ -68,8 +70,27 @@ export const CashReceiptListPage = () => { const { mutateAsync: cashReceiptList } = useCashReceiptListMutation(); const { mutateAsync: cashReceiptSummary } = useCashReceiptSummaryMutation(); const { mutateAsync: downloadExcel } = useDownloadExcelMutation(); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { + entries.forEach((entry: IntersectionObserverEntry) => { + if(entry.isIntersecting){ + console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); + if(onActionIntersect && !!pageParam.cursor){ + callList('page'); + } + } + else{ + console.log('Element is no longer intersecting with the root.'); + } + }); + }; - const callList = () => { + const { setTarget } = useIntersectionObserver({ + threshold: 1, + onIntersect + }); + + const callList = (type?: string) => { + setOnActionIntersect(false); let listSummaryParams: CashReceiptSummaryParams = { mid: mid, startDate: startDate, @@ -88,9 +109,33 @@ export const CashReceiptListPage = () => { ...{ sortType: sortType } } }; + if(type !== 'page' && listParams.page){ + listParams.page.cursor = null; + } cashReceiptList(listParams).then((rs: CashReceiptListResponse) => { - setListItems(rs.content); + if(type === 'page'){ + setListItems([ + ...listItems, + ...rs.content + ]); + } + else{ + setListItems(rs.content); + } + if(rs.hasNext){ + setPageParam({ + ...pageParam, + ...{ cursor: rs.nextCursor } + }); + setOnActionIntersect(true); + } + else{ + setPageParam({ + ...pageParam, + ...{ cursor: null } + }); + } }); cashReceiptSummary(listSummaryParams).then((rs: CashReceiptSummaryResponse) => { setApprovalCount(rs.approvalCount); @@ -230,6 +275,7 @@ export const CashReceiptListPage = () => { listItems={ listItems } transactionCategory={ TransactionCategory.CashReceipt } > +
diff --git a/src/pages/transaction/escrow/list-page.tsx b/src/pages/transaction/escrow/list-page.tsx index 2099092..68ab610 100644 --- a/src/pages/transaction/escrow/list-page.tsx +++ b/src/pages/transaction/escrow/list-page.tsx @@ -28,12 +28,14 @@ import { useSetFooterMode } from '@/widgets/sub-layout/use-sub-layout'; import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet'; +import useIntersectionObserver from '@/widgets/intersection-observer'; export const EscrowListPage = () => { const { navigate } = useNavigate(); const userInfo = useStore((state) => state.UserStore.userInfo); const userMid = useStore.getState().UserStore.mid; + const [onActionIntersect, setOnActionIntersect] = useState(false); const [sortType, setSortType] = useState(SortTypeKeys.LATEST); const [listItems, setListItems] = useState>([]); const [filterOn, setFilterOn] = useState(false); @@ -60,8 +62,27 @@ export const EscrowListPage = () => { const { mutateAsync: escrowList } = useEscrowListMutation(); const { mutateAsync: downloadExcel } = useDownloadExcelMutation(); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { + entries.forEach((entry: IntersectionObserverEntry) => { + if(entry.isIntersecting){ + console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); + if(onActionIntersect && !!pageParam.cursor){ + callList('page'); + } + } + else{ + console.log('Element is no longer intersecting with the root.'); + } + }); + }; + + const { setTarget } = useIntersectionObserver({ + threshold: 1, + onIntersect + }); - const callList = () => { + const callList = (type?: string) => { + setOnActionIntersect(false); let listParams: EscrowListParams = { mid: mid, searchType: 'ORDER_NUMBER', @@ -170,7 +191,8 @@ export const EscrowListPage = () => { + > +