From 819f698eb8b124e2a29ca8df8da914eb45f3ee96 Mon Sep 17 00:00:00 2001 From: Mayur Date: Fri, 29 Nov 2024 14:54:37 +0530 Subject: [PATCH] feat: Added pagination in Transaction --- .../get-transaction-command.ts | 7 ++++ .../get-transaction-history.usecase.ts | 31 ++++++++++++++---- apps/api/src/app/user/user.controller.ts | 19 +++++++++-- apps/web/hooks/useTransactionHistory.tsx | 24 +++++++++++--- apps/web/pages/transactions/index.tsx | 17 ++++++++-- .../src/payment/payment.api.service.ts | 32 ++++++++++++++++--- pnpm-lock.yaml | 14 ++++---- 7 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 apps/api/src/app/user/usecases/get-transaction-history/get-transaction-command.ts diff --git a/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-command.ts b/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-command.ts new file mode 100644 index 000000000..dc04383b6 --- /dev/null +++ b/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-command.ts @@ -0,0 +1,7 @@ +import { PaginationCommand } from '@shared/commands/pagination.command'; +import { IsString } from 'class-validator'; + +export class GetTransactionHistoryCommand extends PaginationCommand { + @IsString() + projectId: string; +} diff --git a/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-history.usecase.ts b/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-history.usecase.ts index a0ae28e79..54bfb88ae 100644 --- a/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-history.usecase.ts +++ b/apps/api/src/app/user/usecases/get-transaction-history/get-transaction-history.usecase.ts @@ -1,21 +1,30 @@ import { Injectable } from '@nestjs/common'; import { PaymentAPIService } from '@impler/services'; import { EnvironmentRepository } from '@impler/dal'; +import { PaginationCommand } from '@shared/commands/pagination.command'; +import { PaginationResult } from '@impler/shared'; +import { GetTransactionHistoryCommand } from './get-transaction-command'; @Injectable() -export class GetTransactionHistory { +export class GetTransactionHistory extends PaginationCommand { constructor( private paymentApiService: PaymentAPIService, private environmentRepository: EnvironmentRepository - ) {} + ) { + super(); + } - async execute(projectId: string) { + async execute({ projectId, limit, page }: GetTransactionHistoryCommand): Promise { const teamOwner = await this.environmentRepository.getTeamOwnerDetails(projectId); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore - const transactions = await this.paymentApiService.getTransactionHistory(teamOwner._userId.email); + const transactions = await this.paymentApiService.getTransactionHistory({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + email: teamOwner._userId.email, + limit, + page, + }); - return transactions.map((transactionItem) => ({ + const data = transactions.data.map((transactionItem) => ({ transactionDate: transactionItem.transactionDate, planName: transactionItem.planName, transactionStatus: transactionItem.transactionStatus, @@ -27,5 +36,13 @@ export class GetTransactionHistory { currency: transactionItem.currency, _id: transactionItem.id, })); + + return { + data, + limit, + page, + totalPages: transactions.totalPages, + totalRecords: transactions.data.length, + }; } } diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index a6cc000f5..63fa7100b 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -16,7 +16,7 @@ import { UpdateSubscriptionPaymentMethod, } from './usecases'; import { JwtAuthGuard } from '@shared/framework/auth.gaurd'; -import { IJwtPayload, ACCESS_KEY_NAME } from '@impler/shared'; +import { IJwtPayload, ACCESS_KEY_NAME, Defaults } from '@impler/shared'; import { UserSession } from '@shared/framework/user.decorator'; import { CancelSubscriptionDto } from './dto/cancel-subscription.dto'; @@ -131,8 +131,21 @@ export class UserController { @ApiOperation({ summary: 'Get Transaction History for User', }) - async getTransactionHistoryRoute(@UserSession() user: IJwtPayload) { - return this.getTransactionHistory.execute(user._projectId); + async getTransactionHistoryRoute( + @UserSession() user: IJwtPayload, + @Query('page') page = Defaults.ONE, + @Query('limit') limit = Defaults.PAGE_LIMIT + ) { + if (isNaN(page)) page = Defaults.ONE; + else page = Number(page); + if (isNaN(limit)) limit = Defaults.PAGE_LIMIT; + else limit = Number(limit); + + return this.getTransactionHistory.execute({ + projectId: user._projectId, + limit, + page, + }); } @Get('/coupons/:couponCode/apply/:planCode') diff --git a/apps/web/hooks/useTransactionHistory.tsx b/apps/web/hooks/useTransactionHistory.tsx index 909024819..c7fff6f4f 100644 --- a/apps/web/hooks/useTransactionHistory.tsx +++ b/apps/web/hooks/useTransactionHistory.tsx @@ -1,22 +1,38 @@ +import { useState } from 'react'; import { commonApi } from '@libs/api'; -import { IErrorObject } from '@impler/shared'; +import { IErrorObject, IPaginationData } from '@impler/shared'; import { useQuery } from '@tanstack/react-query'; -import { API_KEYS } from '@config'; +import { API_KEYS, VARIABLES } from '@config'; export function useTransactionHistory() { + const [page, setPage] = useState(); + const [limit, setLimit] = useState(VARIABLES.TEN); const { data: transactions, refetch: refetchTransactions, isLoading: isTransactionsLoading, isFetched: isTransactionsFetched, - } = useQuery([API_KEYS.TRANSACTION_HISTORY], () => - commonApi(API_KEYS.TRANSACTION_HISTORY as any, {}) + } = useQuery, [string, number, number | undefined]>( + [API_KEYS.TRANSACTION_HISTORY, limit, page], + () => + commonApi>(API_KEYS.TRANSACTION_HISTORY as any, { + query: { + limit, + page, + }, + }) ); + function onLimitChange(newLimit: number) { + setLimit(newLimit); + } + return { transactions, refetchTransactions, isTransactionsLoading, isTransactionsFetched, + onLimitChange, + onPageChange: setPage, }; } diff --git a/apps/web/pages/transactions/index.tsx b/apps/web/pages/transactions/index.tsx index 8d6d4bb5b..84e302a51 100644 --- a/apps/web/pages/transactions/index.tsx +++ b/apps/web/pages/transactions/index.tsx @@ -2,9 +2,10 @@ import Link from 'next/link'; import { Group, LoadingOverlay, Stack, Title } from '@mantine/core'; import dayjs from 'dayjs'; -import { ROUTES, DATE_FORMATS } from '@config'; +import { ROUTES, DATE_FORMATS, VARIABLES } from '@config'; import { Table } from '@ui/table'; import { Button } from '@ui/button'; +import { Pagination } from '@ui/pagination'; import { Checkbox } from '@ui/checkbox'; import { AppLayout } from '@layouts/AppLayout'; import { capitalizeFirstLetter } from '@shared/utils'; @@ -12,7 +13,7 @@ import { LeftArrowIcon } from '@assets/icons/LeftArrow.icon'; import { useTransactionHistory } from '@hooks/useTransactionHistory'; export default function Transactions() { - const { transactions, isTransactionsLoading } = useTransactionHistory(); + const { transactions, isTransactionsLoading, onLimitChange, onPageChange } = useTransactionHistory(); return ( @@ -83,9 +84,19 @@ export default function Transactions() { }, }, ]} - data={transactions || []} + data={transactions?.data || []} /> + ); } diff --git a/libs/services/src/payment/payment.api.service.ts b/libs/services/src/payment/payment.api.service.ts index 246ee2d6c..96322bef4 100644 --- a/libs/services/src/payment/payment.api.service.ts +++ b/libs/services/src/payment/payment.api.service.ts @@ -1,5 +1,10 @@ import axios from 'axios'; -import { ISubscriptionData, AVAILABLE_BILLABLEMETRIC_CODE_ENUM, constructQueryString } from '@impler/shared'; +import { + ISubscriptionData, + AVAILABLE_BILLABLEMETRIC_CODE_ENUM, + constructQueryString, + PaginationResult, +} from '@impler/shared'; interface ICheckData { uploadId: string; @@ -251,17 +256,36 @@ export class PaymentAPIService { return response.data; } - - async getTransactionHistory(email: string) { + async getTransactionHistory({ + email, + limit, + page, + }: { + email: string; + limit: number; + page: number; + }): Promise { if (!this.PAYMENT_API_BASE_URL) return; const url = `${this.PAYMENT_API_BASE_URL}/api/v1/transaction/${email}/history`; const response = await axios.get(url, { headers: { [this.AUTH_KEY]: this.AUTH_VALUE, }, + params: { + page, + limit, + }, }); - return response.data; + const { data, metadata } = response.data; + + return { + data, + limit, + page, + totalPages: metadata.totalPages, + totalRecords: metadata.total, + }; } async checkAppliedCoupon(couponCode: string, userEmail: string, planCode: string) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dd9fee3b4..c630b9cbd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -791,8 +791,8 @@ importers: specifier: '>=12.0.0' version: 18.2.11(rxjs@7.8.1)(zone.js@0.14.10) '@impler/client': - specifier: ^0.27.1 - version: 0.27.1 + specifier: ^0.27.2 + version: 0.27.2 devDependencies: '@angular/compiler': specifier: ^12.0.0 @@ -858,8 +858,8 @@ importers: packages/react: dependencies: '@impler/client': - specifier: ^0.27.1 - version: 0.27.1 + specifier: ^0.27.2 + version: 0.27.2 react: specifier: '>=16.8.0' version: 18.2.0 @@ -2268,8 +2268,8 @@ packages: resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} - '@impler/client@0.27.1': - resolution: {integrity: sha512-5nU1rZwgRVq1ZK75lsA7yeBLElcmiqPpQ2yOb5rkaI1VlPS3ntKPH4yGNPKU1pVNqSKE51z2sZD17T3/0C8TQg==} + '@impler/client@0.27.2': + resolution: {integrity: sha512-cxqwFJItReoClou5uYm692XRk2TZ0TIBaniH7jMoUkespFvX7AXsXZyA1ldnQfUUPA4pnaI66TvkTW8rvUTn4w==} engines: {node: '>=10'} '@isaacs/cliui@8.0.2': @@ -15280,7 +15280,7 @@ snapshots: '@hutson/parse-repository-url@3.0.2': {} - '@impler/client@0.27.1': {} + '@impler/client@0.27.2': {} '@isaacs/cliui@8.0.2': dependencies: