diff --git a/pages/pools/[id]/index.tsx b/pages/pools/[id]/index.tsx index 2ccaf39..b9f3775 100644 --- a/pages/pools/[id]/index.tsx +++ b/pages/pools/[id]/index.tsx @@ -28,17 +28,16 @@ import Tabs from "components/tabs"; import { Row } from "components/styled/row"; import { SearchInput } from "components/styled/search-input"; import RenderIf from "components/render-if"; -import TokensTable from "components/tokens-table/tokens-table"; -import { useQueryTokens } from "hooks/tokens"; +import LiquidityProvidersTable from "components/liquidity-provider-table/liquidity-provider-table"; +import { useLiquidityProviders } from "../../../src/hooks/use-liquidity-providers"; +import { shouldFilterEvent } from "utils/filters"; import { useState } from "react"; -import { shouldFilterEvent, shouldFilterToken } from "utils/filters"; const PoolPage = () => { const router = useRouter(); const { id } = router.query; const { handleSavePool, isPoolSaved } = useSavedPools(); - const eventsFilter = useEventTopicFilter(); const events = useQueryAllEvents({ @@ -46,9 +45,8 @@ const PoolPage = () => { type: eventsFilter.topic, }); - const tokens = useQueryTokens(); - const pool = useQueryPool({ poolAddress: id as string }); + const liquidityProviders = useLiquidityProviders({ poolAddress: id as string }); const token0 = pool.data?.tokenA; const token1 = pool.data?.tokenB; @@ -66,12 +64,9 @@ const PoolPage = () => { const [searchValue, setSearchValue] = useState(""); - const filteredTokens = tokens.data?.filter((token) => { - return ( - (shouldFilterToken(token.asset, token0?.contract) || - shouldFilterToken(token.asset, token1?.contract)) && - shouldFilterToken(token.asset, searchValue) - ); + const filteredProviders = liquidityProviders.data?.filter((provider) => { + if (!searchValue) return true; + return provider.address.toLowerCase().includes(searchValue.toLowerCase()); }); const filteredEvents = events.data?.filter((event) => { @@ -316,7 +311,7 @@ const PoolPage = () => { ( { filters={eventsFilter} /> + + + )} diff --git a/src/components/liquidity-provider-table/liquidity-provider-table.tsx b/src/components/liquidity-provider-table/liquidity-provider-table.tsx new file mode 100644 index 0000000..5dbf531 --- /dev/null +++ b/src/components/liquidity-provider-table/liquidity-provider-table.tsx @@ -0,0 +1,186 @@ +import { + Skeleton, + Box, + Table, + TableBody, + TableHead, + TablePagination, + TableRow, + TableSortLabel, + TableContainer, +} from "soroswap-ui"; +import { visuallyHidden } from "@mui/utils"; +import * as React from "react"; +import useTable from "../../hooks/use-table"; +import { formatNumberToMoney } from "../../utils/utils"; +import { StyledCard } from "components/styled/card"; +import { StyledTableCell } from "components/styled/table-cell"; +import { useTheme } from "soroswap-ui"; +import { LiquidityProvider, LiquidityProviderTableProps } from "../../types/liquidity-providers"; + +interface HeadCell { + id: keyof LiquidityProvider; + label: string; + numeric: boolean; +} + +const headCells: readonly HeadCell[] = [ + { + id: "address", + numeric: false, + label: "Account", + }, + { + id: "tvl", + numeric: true, + label: "TVL", + }, + { + id: "poolShare", + numeric: true, + label: "Pool Share", + }, +]; + +interface TableHeadProps { + onRequestSort: ( + event: React.MouseEvent, + property: keyof LiquidityProvider + ) => void; + order: "asc" | "desc"; + orderBy: string; +} + +function LiquidityProvidersTableHead(props: TableHeadProps) { + const { order, orderBy, onRequestSort } = props; + const createSortHandler = + (property: keyof LiquidityProvider) => (event: React.MouseEvent) => { + onRequestSort(event, property); + }; + + return ( + + + # + {headCells.map((headCell) => ( + + + {headCell.label} + {orderBy === headCell.id ? ( + + {order === "desc" ? "sorted descending" : "sorted ascending"} + + ) : null} + + + ))} + + + ); +} + +export default function LiquidityProvidersTable({ + rows, + emptyMessage = "No liquidity providers found", + isLoading = false, + itemsPerPage = 10, +}: LiquidityProviderTableProps) { + const { + order, + orderBy, + handleRequestSort, + visibleRows, + emptyRows, + rowsPerPage, + page, + handleChangePage, + handleChangeRowsPerPage, + } = useTable({ + rows, + defaultOrder: "desc", + defaultOrderBy: "tvl", + itemsPerPage, + }); + + const theme = useTheme(); + + if (isLoading) { + return ; + } + + return ( + + + + + + + {visibleRows.map((row, index) => ( + + {page * rowsPerPage + index + 1} + {row.address} + + {formatNumberToMoney(row.tvl)} + + + {row.poolShare.toFixed(2)}% + + + ))} + {emptyRows > 0 && ( + + + + )} + {visibleRows.length === 0 && ( + + + {emptyMessage} + + + )} + +
+
+ +
+
+ ); +} diff --git a/src/hooks/use-liquidity-providers.ts b/src/hooks/use-liquidity-providers.ts new file mode 100644 index 0000000..5aeb291 --- /dev/null +++ b/src/hooks/use-liquidity-providers.ts @@ -0,0 +1,40 @@ +// src/hooks/use-liquidity-providers.ts +import { useQuery } from "@tanstack/react-query"; +import { LiquidityProvider } from "../types/liquidity-providers"; + +interface UseLiquidityProvidersProps { + poolAddress?: string; +} + +export const useLiquidityProviders = ({ poolAddress }: UseLiquidityProvidersProps) => { + return useQuery({ + queryKey: ["liquidityProviders", poolAddress], + queryFn: async () => { + try { + // This is temporary mock data - replace with actual API call + const mockData: LiquidityProvider[] = [ + { + address: "GBZV...DMUB", + tvl: 1234.56, + poolShare: 25.5, + }, + { + address: "GDZL...XVUC", + tvl: 5678.90, + poolShare: 15.3, + }, + // Add more mock data as needed + ]; + return mockData; + + // Uncomment this when API is ready: + // const response = await fetch(`/api/pools/${poolAddress}/liquidity-providers`); + // return await response.json(); + } catch (error) { + console.error("Error fetching liquidity providers:", error); + return []; + } + }, + enabled: !!poolAddress, + }); +}; \ No newline at end of file diff --git a/src/types/liquidity-providers.ts b/src/types/liquidity-providers.ts new file mode 100644 index 0000000..b09c5f6 --- /dev/null +++ b/src/types/liquidity-providers.ts @@ -0,0 +1,15 @@ +// src/types/liquidity-providers.ts + +export interface LiquidityProvider { + address: string; // The account address of the liquidity provider + tvl: number; // Total Value Locked for this provider + poolShare: number; // Provider's share of the pool as a percentage + } + + // If you need any additional types related to liquidity providers, add them here + export interface LiquidityProviderTableProps { + rows: LiquidityProvider[]; + emptyMessage?: string; + isLoading?: boolean; + itemsPerPage?: number; + } \ No newline at end of file