Paginate bets list
This commit is contained in:
parent
5c6a143614
commit
162e73912e
|
@ -1,7 +1,7 @@
|
|||
import Link from 'next/link'
|
||||
import { uniq, groupBy, mapValues, sortBy, partition, sumBy } from 'lodash'
|
||||
import dayjs from 'dayjs'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
import { Bet } from 'web/lib/firebase/bets'
|
||||
|
@ -46,10 +46,13 @@ import { SellSharesModal } from './sell-modal'
|
|||
import { useUnfilledBets } from 'web/hooks/use-bets'
|
||||
import { LimitBet } from 'common/bet'
|
||||
import { floatingEqual } from 'common/util/math'
|
||||
import { Pagination } from './pagination'
|
||||
|
||||
type BetSort = 'newest' | 'profit' | 'closeTime' | 'value'
|
||||
type BetFilter = 'open' | 'sold' | 'closed' | 'resolved' | 'all'
|
||||
|
||||
const CONTRACTS_PER_PAGE = 20
|
||||
|
||||
export function BetsList(props: {
|
||||
user: User
|
||||
bets: Bet[] | undefined
|
||||
|
@ -62,13 +65,17 @@ export function BetsList(props: {
|
|||
|
||||
// Hide bets before 06-01-2022 if this isn't your own profile
|
||||
// NOTE: This means public profits also begin on 06-01-2022 as well.
|
||||
const bets = allBets?.filter(
|
||||
(bet) => bet.createdTime >= (hideBetsBefore ?? 0)
|
||||
const bets = useMemo(
|
||||
() => allBets?.filter((bet) => bet.createdTime >= (hideBetsBefore ?? 0)),
|
||||
[allBets, hideBetsBefore]
|
||||
)
|
||||
const [contracts, setContracts] = useState<Contract[] | undefined>()
|
||||
|
||||
const [sort, setSort] = useState<BetSort>('newest')
|
||||
const [filter, setFilter] = useState<BetFilter>('open')
|
||||
const [page, setPage] = useState(0)
|
||||
const start = page * CONTRACTS_PER_PAGE
|
||||
const end = start + CONTRACTS_PER_PAGE
|
||||
|
||||
useEffect(() => {
|
||||
if (bets) {
|
||||
|
@ -85,16 +92,14 @@ export function BetsList(props: {
|
|||
disposed = true
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [allBets, hideBetsBefore])
|
||||
}, [bets])
|
||||
|
||||
const getTime = useTimeSinceFirstRender()
|
||||
useEffect(() => {
|
||||
if (bets && contracts) {
|
||||
trackLatency('portfolio', getTime())
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [!!bets, !!contracts])
|
||||
}, [bets, contracts, getTime])
|
||||
|
||||
if (!bets || !contracts) {
|
||||
return <LoadingIndicator />
|
||||
|
@ -130,7 +135,7 @@ export function BetsList(props: {
|
|||
(filter === 'open' ? -1 : 1) *
|
||||
(c.resolutionTime ?? c.closeTime ?? Infinity),
|
||||
}
|
||||
const displayedContracts = sortBy(contracts, SORTS[sort])
|
||||
const filteredContracts = sortBy(contracts, SORTS[sort])
|
||||
.reverse()
|
||||
.filter(FILTERS[filter])
|
||||
.filter((c) => {
|
||||
|
@ -141,6 +146,7 @@ export function BetsList(props: {
|
|||
if (filter === 'sold') return !hasShares
|
||||
return hasShares
|
||||
})
|
||||
const displayedContracts = filteredContracts.slice(start, end)
|
||||
|
||||
const unsettled = contracts.filter(
|
||||
(c) => !c.isResolved && contractsMetrics[c.id].invested !== 0
|
||||
|
@ -227,6 +233,13 @@ export function BetsList(props: {
|
|||
))
|
||||
)}
|
||||
</Col>
|
||||
|
||||
<Pagination
|
||||
page={page}
|
||||
itemsPerPage={CONTRACTS_PER_PAGE}
|
||||
totalItems={filteredContracts.length}
|
||||
setPage={setPage}
|
||||
/>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
|
42
web/components/pagination.tsx
Normal file
42
web/components/pagination.tsx
Normal file
|
@ -0,0 +1,42 @@
|
|||
export function Pagination(props: {
|
||||
page: number
|
||||
itemsPerPage: number
|
||||
totalItems: number
|
||||
setPage: (page: number) => void
|
||||
}) {
|
||||
const { page, itemsPerPage, totalItems, setPage } = props
|
||||
|
||||
return (
|
||||
<nav
|
||||
className="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6"
|
||||
aria-label="Pagination"
|
||||
>
|
||||
<div className="hidden sm:block">
|
||||
<p className="text-sm text-gray-700">
|
||||
Showing{' '}
|
||||
<span className="font-medium">
|
||||
{page === 0 ? page + 1 : page * itemsPerPage}
|
||||
</span>{' '}
|
||||
to <span className="font-medium">{(page + 1) * itemsPerPage}</span> of{' '}
|
||||
<span className="font-medium">{totalItems}</span> results
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-1 justify-between sm:justify-end">
|
||||
<a
|
||||
href="#"
|
||||
className="relative inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
|
||||
onClick={() => page > 1 && setPage(page - 1)}
|
||||
>
|
||||
Previous
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="relative ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
|
||||
onClick={() => page < totalItems / itemsPerPage && setPage(page + 1)}
|
||||
>
|
||||
Next
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user