From ff9f742f88d2a0c38eab5135f775233c9336f02e Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 29 Sep 2025 11:36:18 +0330 Subject: [PATCH] transaction list --- src/config/Pages.ts | 4 + src/pages/payment/List.tsx | 139 ++++++++++++++++++++ src/pages/payment/hooks/usePaymentData.ts | 9 ++ src/pages/payment/service/PaymentService.ts | 9 ++ src/pages/payment/types/Types.ts | 51 +++++++ src/router/Main.tsx | 4 +- src/shared/SideBar.tsx | 4 +- 7 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 src/pages/payment/List.tsx create mode 100644 src/pages/payment/hooks/usePaymentData.ts create mode 100644 src/pages/payment/service/PaymentService.ts create mode 100644 src/pages/payment/types/Types.ts diff --git a/src/config/Pages.ts b/src/config/Pages.ts index 4e65c84..dd6daa1 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -161,4 +161,8 @@ export const Pages = { create: "/shipment/create", update: "/shipment/update/", }, + financial: { + list: "/financial/transactions", + fines: "/financial/fines", + }, }; diff --git a/src/pages/payment/List.tsx b/src/pages/payment/List.tsx new file mode 100644 index 0000000..b04e9a6 --- /dev/null +++ b/src/pages/payment/List.tsx @@ -0,0 +1,139 @@ +import { type FC, useState } from 'react' +import { useGetPayments } from './hooks/usePaymentData' +import { type Payment } from './types/Types' +import PageLoading from '../../components/PageLoading' +import Error from '../../components/Error' +import PaginationUi from '../../components/PaginationUi' +import Td from '../../components/Td' +import StatusWithText from '../../components/StatusWithText' +import { Calendar, User as UserIcon, Card } from 'iconsax-react' + +const PaymentList: FC = () => { + const [currentPage, setCurrentPage] = useState(1); + const { data: paymentsData, isLoading, error } = useGetPayments(currentPage); + + if (isLoading) { + return ( +
+ +
+ ); + } + + if (error) { + return ( +
+ +
+ ); + } + + const payments = paymentsData?.results?.payments || []; + const pager = paymentsData?.results?.pager; + + const getStatusVariant = (status: string) => { + switch (status.toLowerCase()) { + case 'success': + case 'successful': + return 'success'; + case 'failed': + case 'failure': + return 'error'; + case 'pending': + return 'warning'; + case 'processing': + return 'warning'; + default: + return 'warning'; + } + }; + + const getStatusText = (status: string) => { + switch (status.toLowerCase()) { + case 'success': + case 'successful': + return 'موفق'; + case 'failed': + case 'failure': + return 'ناموفق'; + case 'pending': + return 'در انتظار'; + case 'processing': + return 'در حال پردازش'; + default: + return status; + } + }; + + const formatPrice = (price: number) => { + return `${price.toLocaleString('fa-IR')} تومان`; + }; + + return ( +
+
+ + + + + + + {payments.length === 0 ? ( + + + + ) : ( + payments.map((payment: Payment) => ( + + + + + + + )) + )} + +
+ + + + + +
+ هیچ پرداختی یافت نشد +
+
+ + {payment.user?.fullName || '-'} +
+
+ +
+ + {payment.transaction_id || '-'} +
+
+ + + +
+ + {payment.createdAt} +
+
+
+ + { + setCurrentPage(page); + }} + /> +
+ ) +} + +export default PaymentList \ No newline at end of file diff --git a/src/pages/payment/hooks/usePaymentData.ts b/src/pages/payment/hooks/usePaymentData.ts new file mode 100644 index 0000000..9377515 --- /dev/null +++ b/src/pages/payment/hooks/usePaymentData.ts @@ -0,0 +1,9 @@ +import * as api from "../service/PaymentService"; +import { useQuery } from "@tanstack/react-query"; + +export const useGetPayments = (page: number = 1) => { + return useQuery({ + queryKey: ["payments", page], + queryFn: () => api.getPayments(page), + }); +}; diff --git a/src/pages/payment/service/PaymentService.ts b/src/pages/payment/service/PaymentService.ts new file mode 100644 index 0000000..e0b4531 --- /dev/null +++ b/src/pages/payment/service/PaymentService.ts @@ -0,0 +1,9 @@ +import axios from "../../../config/axios"; +import type { PaymentResponse } from "../types/Types"; + +export const getPayments = async ( + page: number = 1 +): Promise => { + const { data } = await axios.get(`/admin/financial/payments?page=${page}`); + return data; +}; diff --git a/src/pages/payment/types/Types.ts b/src/pages/payment/types/Types.ts new file mode 100644 index 0000000..c558ef6 --- /dev/null +++ b/src/pages/payment/types/Types.ts @@ -0,0 +1,51 @@ +export interface PaymentResponse { + status: number; + success: boolean; + results: { + pager: Pager; + payments: Payment[]; + }; +} + +export interface Payment { + _id: string; + user: User; + transaction_id: string | null; + payment_method: PaymentMethod; + priceDetails: PriceDetails; + totalPrice: number; + paymentStatus: string; + createdAt: string; +} + +export interface User { + fullName: string; +} + +export interface PaymentMethod { + _id: string; + title_fa: string; + title_en: string; + description: string; + provider: string; + isActive: boolean; + type: string; +} + +export interface PriceDetails { + shipping_cost: number; + process_cost: number; + total_retail_price: number; + total_payable_price: number; + total_discount: number; + coupon_discount: number; +} + +export interface Pager { + page: number; + limit: number; + totalItems: number; + totalPages: number; + prevPage: boolean | null; + nextPage: string | null; +} diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 4c2b4a1..64be8f5 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -37,7 +37,7 @@ import AdminList from '@/pages/admin/List' import AdminCreate from '@/pages/admin/Create' import UpdateBrand from '@/pages/brand/Update' import UpdateWarranty from '@/pages/warranty/Update' - +import PaymentList from '@/pages/payment/List' const MainRouter: FC = () => { const { hasSubMenu } = useSharedStore() @@ -95,6 +95,8 @@ const MainRouter: FC = () => { } /> } /> + + } /> diff --git a/src/shared/SideBar.tsx b/src/shared/SideBar.tsx index f7b4102..a3a69ae 100644 --- a/src/shared/SideBar.tsx +++ b/src/shared/SideBar.tsx @@ -464,8 +464,8 @@ const FinancialSubMenu: FC = () => {