Fixed issue with transactions table

This commit is contained in:
Umar Adilov 2025-05-16 17:46:51 +05:00
parent 06b886ca5d
commit bf134a99d5
8 changed files with 181 additions and 90 deletions

View File

@ -1,11 +1,10 @@
import {
TransactionRequest,
TransactionResponse,
} from '@/entities/transactions/model/types';
import { baseAPI } from '@/shared/api/base-api';
import { ClientInfo } from '../model/types/bonus-client-info.type';
import {
BonusTransactionRequest,
BonusTransactionResponse,
} from '../model/types/bonus-transactions.type';
export const bonusApi = baseAPI.injectEndpoints({
endpoints: (builder) => ({
@ -17,8 +16,8 @@ export const bonusApi = baseAPI.injectEndpoints({
},
}),
fetchBonusTransactions: builder.query<
TransactionResponse,
TransactionRequest
BonusTransactionResponse,
BonusTransactionRequest
>({
query: (request) => {
return {

View File

@ -1,23 +1,22 @@
export interface TransactionResponse {
transactions: Transaction[];
export interface BonusTransactionResponse {
transactions: BonusTransaction[];
current_page: number;
limit: number;
total_records: number;
total_pages: number;
}
export interface Transaction {
export interface BonusTransaction {
id: number;
date_create: string;
station?: string;
station_name?: string;
product_name: string;
amount: string;
price_real: string;
sum_real: string;
}
export interface TransactionRequest {
export interface BonusTransactionRequest {
start_date?: string;
end_date?: string;
page: number;

View File

@ -1,11 +1,10 @@
import {
TransactionRequest,
TransactionResponse,
} from '@/entities/transactions/model/types';
import { baseAPI } from '@/shared/api/base-api';
import { CorporateInfoResponse } from '../model/types/corporate-client-info.type';
import {
CorporateTransactionRequest,
CorporateTransactionResponse,
} from '../model/types/corporate-transactions.type';
export const corporateApi = baseAPI.injectEndpoints({
endpoints: (builder) => ({
@ -17,8 +16,8 @@ export const corporateApi = baseAPI.injectEndpoints({
},
}),
fetchCorporateTransactions: builder.query<
TransactionResponse,
TransactionRequest
CorporateTransactionResponse,
CorporateTransactionRequest
>({
query: (request) => {
return {

View File

@ -0,0 +1,24 @@
export interface CorporateTransactionResponse {
transactions: CorporateTransaction[];
current_page: number;
limit: number;
total_records: number;
total_pages: number;
}
export interface CorporateTransaction {
date_create: string;
station_name?: string;
product_name: string;
amount: string;
price_real: string;
sum_real: string;
uid: string;
}
export interface CorporateTransactionRequest {
start_date?: string;
end_date?: string;
page: number;
limit: number;
}

View File

@ -1,6 +1,7 @@
'use client';
import { deleteCookie } from 'cookies-next';
import { format } from 'date-fns';
import { Building2, LogOut, Wallet } from 'lucide-react';
import { useEffect, useState } from 'react';
@ -8,7 +9,7 @@ import {
useFetchCorporateTransactionsQuery,
useFetchMyCorporateInfoQuery,
} from '@/entities/corporate/api/corporate.api';
import { TransactionRequest } from '@/entities/transactions/model/types';
import { CorporateTransactionRequest } from '@/entities/corporate/model/types/corporate-transactions.type';
import { useTextController } from '@/shared/language/hooks/use-text-controller';
import { Button } from '@/shared/shadcn-ui/button';
@ -19,6 +20,7 @@ import {
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
import { TableCell, TableHead, TableRow } from '@/shared/shadcn-ui/table';
import { TransactionsTable } from '@/widgets/transactions-table';
@ -27,7 +29,8 @@ export function CorporateDashboard() {
const { data } = useFetchMyCorporateInfoQuery({});
const [request, setTransactionFetchRequest] = useState<TransactionRequest>({
const [request, setTransactionFetchRequest] =
useState<CorporateTransactionRequest>({
limit: 10,
page: 1,
});
@ -164,6 +167,53 @@ export function CorporateDashboard() {
<TransactionsTable
isLoading={isFetching}
renderHeaders={() => (
<TableRow>
<TableHead>
{t('corporate.transactions.tableHeaders.date')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.card')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.station')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.product')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.quantity')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.price')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.total')}
</TableHead>
</TableRow>
)}
renderRow={(transaction, index) => (
<TableRow key={index}>
<TableCell>
{format(
new Date(transaction.date_create),
'dd.MM.yyyy HH:mm',
)}
</TableCell>
<TableCell>{transaction.uid}</TableCell>
<TableCell>{transaction.station_name}</TableCell>
<TableCell>{transaction.product_name}</TableCell>
<TableCell className='text-right'>
{transaction.amount}
</TableCell>
<TableCell className='text-right'>
{transaction.price_real} {t('corporate.currency')}
</TableCell>
<TableCell className='text-right font-medium'>
{transaction.sum_real} {t('corporate.currency')}
</TableCell>
</TableRow>
)}
data={
transactionsResponse || {
limit: 10,

View File

@ -1,6 +1,7 @@
'use client';
import { deleteCookie } from 'cookies-next';
import { format } from 'date-fns';
import { ArrowUpRight, Clock, CreditCard, LogOut, User } from 'lucide-react';
import { useEffect, useState } from 'react';
@ -8,7 +9,7 @@ import {
useFetchBonusTransactionsQuery,
useFetchMyBonusInfoQuery,
} from '@/entities/bonus/api/bonus.api';
import { TransactionRequest } from '@/entities/transactions/model/types';
import { BonusTransactionRequest } from '@/entities/bonus/model/types/bonus-transactions.type';
import Loader from '@/shared/components/loader';
import { useTextController } from '@/shared/language/hooks/use-text-controller';
@ -20,13 +21,15 @@ import {
CardHeader,
CardTitle,
} from '@/shared/shadcn-ui/card';
import { TableCell, TableHead, TableRow } from '@/shared/shadcn-ui/table';
import { TransactionsTable } from '@/widgets/transactions-table';
export function CustomerDashboard() {
const { t } = useTextController();
const [request, setTransactionFetchRequest] = useState<TransactionRequest>({
const [request, setTransactionFetchRequest] =
useState<BonusTransactionRequest>({
limit: 10,
page: 1,
});
@ -162,6 +165,49 @@ export function CustomerDashboard() {
transactions: [],
}
}
renderHeaders={() => (
<TableRow>
<TableHead>
{t('corporate.transactions.tableHeaders.date')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.station')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.product')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.quantity')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.price')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.total')}
</TableHead>
</TableRow>
)}
renderRow={(transaction) => (
<TableRow key={transaction.id}>
<TableCell>
{format(
new Date(transaction.date_create),
'dd.MM.yyyy HH:mm',
)}
</TableCell>
<TableCell>{transaction.station}</TableCell>
<TableCell>{transaction.product_name}</TableCell>
<TableCell className='text-right'>
{transaction.amount}
</TableCell>
<TableCell className='text-right'>
{transaction.price_real} {t('corporate.currency')}
</TableCell>
<TableCell className='text-right font-medium'>
{transaction.sum_real} {t('corporate.currency')}
</TableCell>
</TableRow>
)}
onChange={setTransactionFetchRequest}
/>
</div>

View File

@ -5,11 +5,6 @@ import { ru } from 'date-fns/locale';
import { CalendarIcon, X } from 'lucide-react';
import { useEffect, useState } from 'react';
import {
TransactionRequest,
TransactionResponse,
} from '@/entities/transactions/model/types';
import TableLoadingOverlay from '@/shared/components/table-loading-overlay';
import { useTextController } from '@/shared/language/hooks/use-text-controller';
import { Button } from '@/shared/shadcn-ui/button';
@ -24,7 +19,6 @@ import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/shared/shadcn-ui/table';
@ -38,23 +32,40 @@ import {
PaginationPrevious,
} from './pagination';
export interface TransactionsTableProps {
onChange: (request: TransactionRequest) => void;
isLoading: boolean;
data: TransactionResponse;
export interface TransactionRequest {
start_date?: string;
end_date?: string;
page: number;
limit: number;
}
export const TransactionsTable = ({
export interface TransactionsTableProps<T> {
data: {
transactions: T[];
total_pages: number;
total_records: number;
};
isLoading: boolean;
onChange: (request: TransactionRequest) => void;
renderHeaders: () => React.ReactNode;
renderRow: (transaction: T, index: number) => React.ReactNode;
itemsPerPageOptions?: number[];
}
export const TransactionsTable = <T,>({
data,
isLoading,
onChange,
}: TransactionsTableProps) => {
renderHeaders,
renderRow,
itemsPerPageOptions = [5, 10, 20, 50],
}: TransactionsTableProps<T>) => {
const [startDate, setStartDate] = useState<Date | undefined>(
new Date(new Date().setMonth(new Date().getMonth() - 1)),
);
const [endDate, setEndDate] = useState<Date | undefined>(new Date());
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(10);
const [itemsPerPage, setItemsPerPage] = useState(itemsPerPageOptions[0]);
const handlePageChange = (page: number) => {
if (page < 1 || page > data.total_pages) return;
@ -175,57 +186,19 @@ export const TransactionsTable = ({
<div className='relative rounded-md border'>
<Table>
<TableHeader>
<TableRow>
<TableHead>
{t('corporate.transactions.tableHeaders.date')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.station')}
</TableHead>
<TableHead>
{t('corporate.transactions.tableHeaders.product')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.quantity')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.price')}
</TableHead>
<TableHead className='text-right'>
{t('corporate.transactions.tableHeaders.total')}
</TableHead>
</TableRow>
</TableHeader>
<TableHeader>{renderHeaders()}</TableHeader>
<TableBody>
{data.transactions.length > 0 ? (
data.transactions.map((transaction) => (
<TableRow key={transaction.id}>
<TableCell>
{format(new Date(transaction.date_create), 'dd.MM.yyyy')}
</TableCell>
<TableCell>
{transaction.station || transaction.station_name}
</TableCell>
<TableCell>{transaction.product_name}</TableCell>
<TableCell className='text-right'>
{transaction.amount}
</TableCell>
<TableCell className='text-right'>
{transaction.price_real} {t('corporate.currency')}
</TableCell>
<TableCell className='text-right font-medium'>
{transaction.sum_real} {t('corporate.currency')}
</TableCell>
</TableRow>
))
data.transactions.map((transaction, index) =>
renderRow(transaction, index),
)
) : (
<TableRow>
<TableCell
colSpan={6}
className='py-6 text-center text-gray-500'
>
{t('corporate.transactions.noTransactions')}
{t('corporate.transactions.no-data')}
</TableCell>
</TableRow>
)}
@ -286,10 +259,11 @@ export const TransactionsTable = ({
setCurrentPage(1); // Reset to first page when changing items per page
}}
>
<option value={5}>5</option>
<option value={10}>10</option>
<option value={20}>20</option>
<option value={50}>50</option>
{itemsPerPageOptions.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
</div>
</div>

View File

@ -29,5 +29,5 @@
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"],
"exclude": ["node_modules"]
}