From 9da0a095cb16e4be1dd90a14d3a3a5ef88ee0067 Mon Sep 17 00:00:00 2001 From: smanylov Date: Tue, 24 Feb 2026 18:01:19 +0700 Subject: [PATCH] add tanstak table for paymenrs history(mock-data) --- src/app/[locale]/pages/refferals/page.tsx | 2 +- .../{ => table}/invitations-table.tsx | 0 .../referral-page/table/payments-history.tsx | 569 ++++++++++++++++-- src/i18n/messages/en.json | 5 +- src/i18n/messages/ru.json | 5 +- 5 files changed, 543 insertions(+), 38 deletions(-) rename src/app/ui/referral-page/{ => table}/invitations-table.tsx (100%) diff --git a/src/app/[locale]/pages/refferals/page.tsx b/src/app/[locale]/pages/refferals/page.tsx index f3d1950..324d8a6 100644 --- a/src/app/[locale]/pages/refferals/page.tsx +++ b/src/app/[locale]/pages/refferals/page.tsx @@ -3,7 +3,7 @@ import { Suspense } from 'react'; import ReferralStats from '@/app/ui/referral-page/referral-stats'; import ReferralLinkSection from '@/app/ui/referral-page/referral-link-section'; import CommissionLevels from '@/app/ui/referral-page/commission-levels'; -import InvitationsTable from '@/app/ui/referral-page/invitations-table'; +import InvitationsTable from '@/app/ui/referral-page/table/invitations-table'; import IncomeAndPayments from '@/app/ui/referral-page/Income-and-payments'; import SettingReferralProgram from '@/app/ui/referral-page/setting-referral-program'; import PageTitleColorFrame from '@/app/ui/page-title-color-frame'; diff --git a/src/app/ui/referral-page/invitations-table.tsx b/src/app/ui/referral-page/table/invitations-table.tsx similarity index 100% rename from src/app/ui/referral-page/invitations-table.tsx rename to src/app/ui/referral-page/table/invitations-table.tsx diff --git a/src/app/ui/referral-page/table/payments-history.tsx b/src/app/ui/referral-page/table/payments-history.tsx index 51a4a09..caa6bfe 100644 --- a/src/app/ui/referral-page/table/payments-history.tsx +++ b/src/app/ui/referral-page/table/payments-history.tsx @@ -1,7 +1,26 @@ 'use client' import { useGetReferralPayments } from '@/app/hooks/react-query/useGetReferralPayments'; -import { useEffect } from 'react'; +import { useEffect, useState, useMemo } from 'react'; +import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, ColumnDef, SortingState, ColumnFiltersState } from '@tanstack/react-table'; +import { IconDoubleArrowRight, IconArrowRight, IconDoubleArrowLeft, IconArrowLeft, IconArrowUp, IconArrowDown, IconFilter } from '@/app/ui/icons/icons'; +import { useTranslations, useLocale } from 'next-intl'; +import DropDownList from '@/app/components/DropDownList'; +import { useQueryClient, useQuery } from '@tanstack/react-query'; +import { pluralize } from '@/app/lib/pluralize'; +import { fetchReferralInvitees } from '@/app/actions/referralsActions'; + +type InviteesType = { + status?: string; + email?: string; + registrationData: string; +}; + +type InviteType = { + active?: string; + email?: string; + regDate: string; +}; export default function PaymentsHistory() { @@ -9,44 +28,524 @@ export default function PaymentsHistory() { useEffect(() => { console.log(paymentsData); - }, [paymentsData]) + }, [paymentsData]); + + const { + data: referralInvitees, + isLoading, + isError, + error, + } = useQuery({ + queryKey: ['referralInvitees'], + queryFn: () => { + return fetchReferralInvitees(); + }, + + select: (data: InviteType[]): InviteesType[] => { + if (!data) return [ + ]; + + return data.map((item: InviteType) => { + + return { + status: item?.active ? 'active' : 'not-active', + email: item?.email, + registrationData: item?.regDate + }; + }); + }, + }); + + const queryClient = useQueryClient(); + + // Состояния + const [sorting, setSorting] = useState([]); + const [columnFilters, setColumnFilters] = useState([]); + const [dateFilter, setDateFilter] = useState('all'); + const [statusFilter, setStatusFilter] = useState('all'); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + + const t = useTranslations("Global"); + const locale = useLocale(); + + // Определение колонок + const columns = useMemo[]>( + () => [ + { + accessorKey: 'amount', + header: ({ column }) => ( +
+ + {t('amount')} + + +
+ ), + cell: ({ row }) => ( +
+ {/* {row.original.size !== undefined ? convertBytes(row.original.size) : '-'} */} + {/* {row.original.email} */} + --- +
+ ), + }, + { + accessorKey: 'method', + header: ({ column }) => ( +
+ + {t('method')} + + +
+ ), + cell: ({ row }) => ( +
+ {/* {row.original.size !== undefined ? convertBytes(row.original.size) : '-'} */} + {/* {row.original.email} */} + --- +
+ ), + }, + { + accessorKey: 'status', + header: ({ column }) => ( +
+ + {t('status')} + + +
+ ), + cell: ({ row }) => { + return ( +
+ + {row.original.status} + +
+ ) + }, + }, + { + accessorKey: 'request-date', + header: ({ column }) => ( +
+ + {t('request-date')} + + +
+ ), + cell: ({ row }) => { + return ( +
+ {row.original.registrationData?.split('T')[0]} +
+ ) + }, + enableColumnFilter: false, + }, + { + accessorKey: 'processed', + header: ({ column }) => ( +
+ + {t('processed')} + + +
+ ), + cell: ({ row }) => { + return ( +
+ {row.original.registrationData?.split('T')[0]} +
+ ) + }, + enableColumnFilter: false, + } + ], + [] + ); + + // Фильтрация по типу файла и дате + const filteredData = useMemo(() => { + let result = referralInvitees; + if (!result) { + return []; + } + + // Фильтр по типу файла + if (statusFilter !== 'all') { + result = result.filter(item => item.status === statusFilter); + } + + // Фильтр по дате + /* if (dateFilter !== 'all') { + const now = Date.now(); + const oneDay = 24 * 60 * 60 * 1000; + const sevenDays = 7 * oneDay; + const thirtyDays = 30 * oneDay; + + switch (dateFilter) { + case 'today': + const todayStart = new Date().setHours(0, 0, 0, 0); + result = result.filter(item => { + if (item.registrationData) { + return item.registrationData >= todayStart + } else { + return 0 + } + }); + break; + case 'week': + const weekAgo = now - sevenDays; + result = result.filter(item => { + if (item.registrationData) { + return item.registrationData >= weekAgo; + } + }); + break; + case 'month': + const monthAgo = now - thirtyDays; + result = result.filter(item => { + if (item.registrationData) { + return item.registrationData >= monthAgo; + } + }); + break; + case 'older': + const monthAgo2 = now - thirtyDays; + result = result.filter(item => { + if (item.registrationData) { + return item.registrationData < monthAgo2; + } + }); + break; + } + } */ + + return result; + }, [referralInvitees, statusFilter, dateFilter]); + + useEffect(() => { + const currentPageRows = table.getRowModel().rows; + const pageCount = table.getPageCount(); + + if (currentPageRows.length === 0 && pagination.pageIndex > 0 && pageCount > 0) { + table.setPageIndex(pagination.pageIndex - 1); + } + }, [filteredData, pagination.pageIndex]); + + // Создание таблицы + const table = useReactTable({ + data: filteredData, + columns, + state: { + sorting, + columnFilters, + pagination + }, + autoResetPageIndex: false, + onPaginationChange: setPagination, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getFilteredRowModel: getFilteredRowModel(), + initialState: { + pagination: { + pageSize: 10, + }, + }, + }); + + const pluralizeFiles = (number: number) => { + const translate = [t('file'), t('files-few'), t('files')]; + return pluralize(number, translate[0], translate[1], translate[2], locale); + }; return ( - <> -

📊 История выплат

-
-
- Сумма -
-
- Способ -
-
- Статус -
-
- Дата запроса -
-
- Обработано +
+

+ История выплат +

+ {/* Фильтры */} +
+
+
+
{t('date-filter')}:
+ { + switch (dateFilter) { + case 'all': + return t('all-dates') + case 'week': + return t('for-a-week') + case 'month': + return t('for-a-month') + case 'older': + return t('older-than-a-month') + default: + return t('today') + } + })()} + callBack={setDateFilter} + > +
  • + {t('all-dates')} +
  • +
  • + {t('today')} +
  • +
  • + {t('for-a-week')} +
  • +
  • + {t('for-a-month')} +
  • +
  • + {t('older-than-a-month')} +
  • +
    +
    -
    - 0 -
    -
    - 0 -
    -
    - 0 -
    -
    - 0 -
    -
    - 0 +
    +
    {t('items-per-page')}:
    + + {[5, 10, 20, 50, 100].map(pageSize => ( +
  • + {t('show')} {pageSize} +
  • + ))} +
    - - ) + + {/* Таблица */} +
    + + + {table.getHeaderGroups().map(headerGroup => ( + + {headerGroup.headers.map(header => ( + + ))} + + ))} + + + {table.getRowModel().rows.length > 0 ? ( + table.getRowModel().rows.map(row => ( + + {row.getVisibleCells().map(cell => ( + + ))} + + )) + ) : ( + + + + )} + +
    + {header.isPlaceholder + ? null + : typeof header.column.columnDef.header === 'function' + ? header.column.columnDef.header(header.getContext()) + : header.column.columnDef.header as string} +
    + {typeof cell.column.columnDef.cell === 'function' + ? cell.column.columnDef.cell(cell.getContext()) + : cell.getValue() as string} +
    + {t('no-data-for-selected-filters')} +
    +
    + + {/* Пагинация */} +
    +
    + {/* + {t('page')}{' '} + + {table.getState().pagination.pageIndex + 1} {t('out-of')} {table.getPageCount() ? table.getPageCount() : 1} + + + + | {t('shown')} {table.getRowModel().rows.length} {t('out-of')} {filteredData.length} {pluralizeFiles(filteredData.length || 0)} + */} +
    + +
    + {table.getCanPreviousPage() && ( + + )} + {table.getCanPreviousPage() && ( + + )} + +
    + {Array.from({ length: Math.min(5, table.getPageCount()) }, (_, i) => { + const pageIndex = Math.max( + 0, + Math.min( + table.getPageCount() - 5, + table.getState().pagination.pageIndex - 2 + ) + ) + i; + + if (pageIndex < table.getPageCount()) { + return ( + + ); + } + return null; + })} +
    + + {table.getCanNextPage() && ( + + )} + {table.getCanNextPage() && ( + + )} +
    +
    +
    + ); } \ No newline at end of file diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index a8d5c82..6e12cbc 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -272,7 +272,10 @@ "email-notifications-about-new-referrals": "Email notifications about new referrals", "bank-card-number": "Bank card number", "error-bank-card": "Enter your bank card number", - "error-save": "Error saving" + "error-save": "Error saving", + "method": "Method", + "processed": "Processed", + "request-date": "Request date" }, "Login-register-form": { "and": "and", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index 1f96cf2..62ac3af 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -272,7 +272,10 @@ "email-notifications-about-new-referrals": "Email уведомления о новых рефералах", "bank-card-number": "Номер банковской карты", "error-bank-card": "Введите номер банковской карты", - "error-save": "Ошибка при сохранении" + "error-save": "Ошибка при сохранении", + "method": "Способ", + "processed": "Обработано", + "request-date": "Дата запроса" }, "Login-register-form": { "and": "и",