Skip to content

Commit

Permalink
feat: Added pagination in Transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Mayur committed Nov 29, 2024
1 parent c3f2a03 commit 819f698
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PaginationCommand } from '@shared/commands/pagination.command';
import { IsString } from 'class-validator';

export class GetTransactionHistoryCommand extends PaginationCommand {
@IsString()
projectId: string;
}
Original file line number Diff line number Diff line change
@@ -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<PaginationResult> {
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,
Expand All @@ -27,5 +36,13 @@ export class GetTransactionHistory {
currency: transactionItem.currency,
_id: transactionItem.id,
}));

return {
data,
limit,
page,
totalPages: transactions.totalPages,
totalRecords: transactions.data.length,
};
}
}
19 changes: 16 additions & 3 deletions apps/api/src/app/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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')
Expand Down
24 changes: 20 additions & 4 deletions apps/web/hooks/useTransactionHistory.tsx
Original file line number Diff line number Diff line change
@@ -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<number>();
const [limit, setLimit] = useState<number>(VARIABLES.TEN);
const {
data: transactions,
refetch: refetchTransactions,
isLoading: isTransactionsLoading,
isFetched: isTransactionsFetched,
} = useQuery<unknown, IErrorObject, ITransactionHistory[], [string]>([API_KEYS.TRANSACTION_HISTORY], () =>
commonApi<ITransactionHistory[]>(API_KEYS.TRANSACTION_HISTORY as any, {})
} = useQuery<unknown, IErrorObject, IPaginationData<ITransactionHistory>, [string, number, number | undefined]>(
[API_KEYS.TRANSACTION_HISTORY, limit, page],
() =>
commonApi<IPaginationData<ITransactionHistory[]>>(API_KEYS.TRANSACTION_HISTORY as any, {
query: {
limit,
page,
},
})
);

function onLimitChange(newLimit: number) {
setLimit(newLimit);
}

return {
transactions,
refetchTransactions,
isTransactionsLoading,
isTransactionsFetched,
onLimitChange,
onPageChange: setPage,
};
}
17 changes: 14 additions & 3 deletions apps/web/pages/transactions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ 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';
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 (
<Stack spacing="xs">
Expand Down Expand Up @@ -83,9 +84,19 @@ export default function Transactions() {
},
},
]}
data={transactions || []}
data={transactions?.data || []}
/>
</Stack>
<Pagination
dataLength={transactions?.data?.length || VARIABLES.ZERO}
limit={transactions?.limit || VARIABLES.ZERO}
onLimitChange={onLimitChange}
page={transactions?.page || VARIABLES.ZERO}
size="sm"
setPage={onPageChange}
totalPages={transactions?.totalPages || VARIABLES.ZERO}
totalRecords={transactions?.totalRecords || VARIABLES.ZERO}
/>
</Stack>
);
}
Expand Down
32 changes: 28 additions & 4 deletions libs/services/src/payment/payment.api.service.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<PaginationResult> {
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) {
Expand Down
14 changes: 7 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 819f698

Please sign in to comment.