Untitled

 avatar
unknown
plain_text
17 days ago
14 kB
3
Indexable
'use client';

import React, { useState } from 'react';
import { Table, Tabs, Tab } from 'react-bootstrap';
import { TablePagination, CircularProgress } from '@mui/material';
import { formatDate } from '../../utils/dateTimeCn';
import styles from '../../styles/BinaryPortfolioSummary.module.css';
import {
  DepositWithdrawalHistoryResponse,
  FundingHistoryResponse,
  portfolioService,
} from '@/app/api/services/portfolioService';
import { config } from '../../utils/config';
import { useAuthStore } from '@/app/store/useAuthService';
import { useQuery } from '@tanstack/react-query';

interface PortfolioSummaryProps {
  onModifyOrder?: (orderId: string) => void;
  onCancelOrder?: (orderId: string) => void;
}

interface PaginationState {
  page: number;
  rowsPerPage: number;
}

const ROWS_PER_PAGE_OPTIONS = [5, 10, 25];

const OverallNAVPortfolioSummary: React.FC<PortfolioSummaryProps> = () => {
  const { isAuthenticated } = useAuthStore();
  const [activeTab, setActiveTab] = useState('fundingHistory');
  const [paginationState, setPaginationState] = useState<PaginationState>({
    page: config.defaults.pagination.defaultPage,
    rowsPerPage: config.defaults.pagination.defaultPageSize,
  });

  // TanStack Query for funding history
  const {
    data: fundingHistoryData = {
      fundingHistory: [],
      pagination: {
        previousPage: false,
        totalItems: 0,
        nextPage: false,
        pageSize: 10,
        currentPage: 1,
        totalPages: 1,
      },
    },
    isLoading: isFundingHistoryLoading,
  } = useQuery({
    queryKey: ['fundingHistory', paginationState.page, paginationState.rowsPerPage],
    queryFn: () => portfolioService.getFundingHistory(
      paginationState.page,
      paginationState.rowsPerPage
    ),
    enabled: isAuthenticated && activeTab === 'fundingHistory',
    staleTime: 5 * 60 * 1000, // 5 minutes
    refetchOnWindowFocus: false,
  });

  // TanStack Query for deposits/withdrawals
  const {
    data: depositsWithdrawalsData = {
      depositWithdrawalHistory: [],
      pagination: {
        previousPage: false,
        totalItems: 0,
        nextPage: false,
        pageSize: 10,
        currentPage: 1,
        totalPages: 1,
      },
    },
    isLoading: isDepositsWithdrawalsLoading,
  } = useQuery({
    queryKey: ['depositsWithdrawals', paginationState.page, paginationState.rowsPerPage],
    queryFn: () => portfolioService.getDepositWithdrawalHistory(
      paginationState.page,
      paginationState.rowsPerPage
    ),
    enabled: isAuthenticated && activeTab === 'depositsWithdrawals',
    staleTime: 5 * 60 * 1000, // 5 minutes
    refetchOnWindowFocus: false,
  });

  const handlePaginationChange = {
    page: (_: unknown, newPage: number) => {
      setPaginationState((prev) => ({ ...prev, page: newPage }));
    },
    rowsPerPage: (event: React.ChangeEvent<HTMLInputElement>) => {
      setPaginationState({
        page: 0,
        rowsPerPage: parseInt(event.target.value, 10),
      });
    },
  };

  const renderContent = () => {
    switch (activeTab) {
      case 'fundingHistory':
        return (
          <div className={styles.tableWrapper}>
            <Table responsive className={styles.table}>
              <thead>
                <tr>
                  <th
                    className={styles.textAlignLeft}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    Time Executed
                  </th>
                  <th
                    className={styles.textAlignLeft}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    From
                  </th>
                  <th
                    className={styles.textAlignLeft}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    To
                  </th>
                  <th
                    className={styles.textAlignRight}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    Account Value Change (USDC)
                  </th>
                </tr>
              </thead>
              <tbody>
                {isAuthenticated ? (
                  isFundingHistoryLoading ? (
                    <tr>
                      <td
                        colSpan={4}
                        style={{ textAlign: 'center', padding: '2rem' }}
                      >
                        <CircularProgress size={40} />
                      </td>
                    </tr>
                  ) : fundingHistoryData.fundingHistory.length > 0 ? (
                    fundingHistoryData.fundingHistory.map(
                      (fundingHistory, index) => (
                        <tr key={index} className={styles.depositRow}>
                          <td
                            className={styles.textAlignLeft}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {formatDate(fundingHistory.executedAt)}
                          </td>
                          <td
                            className={styles.textAlignLeft}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {fundingHistory.from}
                          </td>
                          <td
                            className={styles.textAlignLeft}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {fundingHistory.to}
                          </td>
                          <td
                            className={`${styles.textAlignRight} ${
                              fundingHistory.amount >= 0
                                ? styles.positive
                                : styles.negative
                            }`}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {fundingHistory.amount >= 0 ? '+' : ''}
                            {fundingHistory.amount.toLocaleString()}
                          </td>
                        </tr>
                      ),
                    )
                  ) : (
                    <tr>
                      <td colSpan={4}>
                        <div className={styles.emptyStateMessage}>
                          There are no results for the selected tab
                        </div>
                      </td>
                    </tr>
                  )
                ) : (
                  <tr>
                    <td colSpan={4}>
                      <div className={styles.emptyStateMessage}>
                        Please connect your wallet to view
                      </div>
                    </td>
                  </tr>
                )}
              </tbody>
            </Table>
            <div className={styles.paginationWrapper}>
              <TablePagination
                component="div"
                count={fundingHistoryData.pagination.totalItems}
                page={paginationState.page}
                onPageChange={handlePaginationChange.page}
                rowsPerPage={paginationState.rowsPerPage}
                onRowsPerPageChange={handlePaginationChange.rowsPerPage}
                rowsPerPageOptions={ROWS_PER_PAGE_OPTIONS}
                sx={{
                  '.MuiTablePagination-select': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-selectLabel': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-displayedRows': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-selectIcon': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-actions': {
                    color: 'var(--text-primary)',
                  },
                }}
              />
            </div>
          </div>
        );
      case 'depositsWithdrawals':
        return (
          <div className={styles.tableWrapper}>
            <Table responsive className={styles.table}>
              <thead>
                <tr>
                  <th
                    className={styles.textAlignLeft}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    Time Executed
                  </th>
                  <th
                    className={styles.textAlignLeft}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    Action Taken
                  </th>
                  <th
                    className={styles.textAlignLeft}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    Status
                  </th>
                  <th
                    className={styles.textAlignRight}
                    style={{ width: '25%', padding: '1rem 1.5rem' }}
                  >
                    Account Value Change (USDC)
                  </th>
                </tr>
              </thead>
              <tbody>
                {isAuthenticated ? (
                  isDepositsWithdrawalsLoading ? (
                    <tr>
                      <td
                        colSpan={4}
                        style={{ textAlign: 'center', padding: '2rem' }}
                      >
                        <CircularProgress size={40} />
                      </td>
                    </tr>
                  ) : depositsWithdrawalsData.depositWithdrawalHistory.length > 0 ? (
                    depositsWithdrawalsData.depositWithdrawalHistory.map(
                      (deposit, index) => (
                        <tr key={index} className={styles.depositRow}>
                          <td
                            className={styles.textAlignLeft}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {formatDate(deposit.executedAt)}
                          </td>
                          <td
                            className={styles.textAlignLeft}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {deposit.action}
                          </td>
                          <td
                            className={styles.textAlignLeft}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            <span
                              className={`${styles.statusBadge} ${
                                deposit.status === 'COMPLETED'
                                  ? styles.statusCompleted
                                  : styles.statusPending
                              }`}
                            >
                              {deposit.status}
                            </span>
                          </td>
                          <td
                            className={`${styles.textAlignRight} ${
                              deposit.amount >= 0
                                ? styles.positive
                                : styles.negative
                            }`}
                            style={{ padding: '1rem 1.5rem' }}
                          >
                            {deposit.amount >= 0 ? '+' : ''}
                            {deposit.amount.toLocaleString()}
                          </td>
                        </tr>
                      ),
                    )
                  ) : (
                    <tr>
                      <td colSpan={4}>
                        <div className={styles.emptyStateMessage}>
                          There are no results for the selected tab
                        </div>
                      </td>
                    </tr>
                  )
                ) : (
                  <tr>
                    <td colSpan={4}>
                      <div className={styles.emptyStateMessage}>
                        Please connect your wallet to view
                      </div>
                    </td>
                  </tr>
                )}
              </tbody>
            </Table>
            <div className={styles.paginationWrapper}>
              <TablePagination
                component="div"
                count={depositsWithdrawalsData.pagination.totalItems}
                page={paginationState.page}
                onPageChange={handlePaginationChange.page}
                rowsPerPage={paginationState.rowsPerPage}
                onRowsPerPageChange={handlePaginationChange.rowsPerPage}
                rowsPerPageOptions={ROWS_PER_PAGE_OPTIONS}
                sx={{
                  '.MuiTablePagination-select': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-selectLabel': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-displayedRows': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-selectIcon': {
                    color: 'var(--text-primary)',
                  },
                  '.MuiTablePagination-actions': {
                    color: 'var(--text-primary)',
                  },
                }}
              />
            </div>
          </div>
        );
      default:
        return null;
    }
  };

  return (
    <div className={styles.portfolioSummary}>
      <Tabs
        activeKey={activeTab}
        onSelect={(k) => k && setActiveTab(k)}
        className={styles.tabs}
      >
        <Tab
          eventKey="fundingHistory"
          title="Funding History"
          tabClassName={styles.tab}
        >
          {activeTab === 'fundingHistory' && renderContent()}
        </Tab>
        <Tab
          eventKey="depositsWithdrawals"
          title="Deposits & Withdrawals"
          tabClassName={styles.tab}
        >
          {activeTab === 'depositsWithdrawals' && renderContent()}
        </Tab>
      </Tabs>
    </div>
  );
};

export default OverallNAVPortfolioSummary;
Editor is loading...
Leave a Comment