Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT]: paginate homepage #156

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion @noun-auction/hooks/useNounishAuctionQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function useNounishAuctionQuery({
setTimeout(() => revalidate({ retryCount }), 5000)
},
dedupingInterval: 5000,
refreshInterval: 5000,
refreshInterval: 30000,
}
)

Expand Down
119 changes: 119 additions & 0 deletions @shared/hooks/usePagination.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { useCallback, useEffect, useMemo, useState } from 'react'

export type PaginationProps = {
// The initial index
initialIndex?: number
// The total number of results
length: number
// Allow to loop backwards and forwards
loop?: boolean
// The number of items per page
maxPerPage?: number
// number of proximity pages to show
proximityMax?: number
}

export type PaginationActions = {
first: () => void
last: () => void
next: () => void
previous: () => void
set: (index: number) => void
}

export type PaginationState = {
actions: PaginationActions
displayIndex: number
index: number
previous: number
next: number
isFirst: boolean
isLast: boolean
percent: number
proximity: number[]
totalPages: number
}

// List of page numbers to show

function getProximityList(index: number, totalPages: number, max: number): number[] {
const items: number[] = Array.from(Array(totalPages).keys())
const last: number = totalPages - 1

// Placeholder to id the gap
const placeholder: number = -1

// small list
if (totalPages - 1 <= max) return items

// start
if (index < max) return [...items.slice(0, max), placeholder, last]

// end
if (index > totalPages - (max + 1))
return [0, placeholder, ...items.slice(totalPages - max, totalPages)]

// middle
return [...items.slice(index - (max - 1), index + 1), placeholder, last]
}

export function usePagination({
initialIndex = 0,
length,
loop = false,
maxPerPage = 1,
proximityMax = 3,
}: PaginationProps): PaginationState {
const [index, setIndex] = useState<number>(initialIndex)

const totalPages: number = useMemo(
() => Math.ceil(length / maxPerPage),
[length, maxPerPage]
)

// If length changes, reset index
useEffect(() => setIndex(0), [length])

const isFirst: boolean = index === 0
const isLast: boolean = index === totalPages - 1

const prevIndex: number = index - 1
const loopPrevious: number = (prevIndex + totalPages) % totalPages
const previous: number = loop ? loopPrevious : isFirst ? index : prevIndex

const nextIndex: number = index + 1
const loopNext: number = nextIndex % totalPages
const next: number = loop ? loopNext : isLast ? index : nextIndex

const percent: number = index / totalPages

const proximity: number[] = useMemo(
() => getProximityList(index, totalPages, proximityMax),
[index, proximityMax, totalPages]
)

// Actions
const firstPage = useCallback(() => setIndex(0), [])
const lastPage = useCallback(() => setIndex(totalPages - 1), [totalPages])
const nextPage = useCallback(() => setIndex(next), [next])
const previousPage = useCallback(() => setIndex(previous), [previous])

return {
index,
displayIndex: index + 1,
previous,
next,
isFirst,
isLast,
percent,
proximity,
totalPages,
actions: {
set: setIndex,
first: firstPage,
last: lastPage,
next: nextPage,
previous: previousPage,
},
}
}
8 changes: 4 additions & 4 deletions compositions/CollectionMenu/CollectionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import { CollectionNavList } from './CollectionNavList'

export function CollectionMenu() {
const { currentCollection, currentCollectionCount } = useCollectionsContext()
const daos = useNounsDaos({ limit: 50 })
const daoCount = useMemo(() => daos.length, [daos])
const { daos } = useNounsDaos({ limit: 50, keyModifier: 'collectionMenu' })
const { hasScrolled, scrollEvent } = useHasScrolled()
const [filter, setFilter] = useState<string>('')
const filteredItems = useMemo(
() => daos.filter((item) => item?.name?.toLowerCase().includes(filter.toLowerCase())),
() =>
daos?.filter((item) => item?.name?.toLowerCase().includes(filter.toLowerCase())),
[filter, daos]
)
const hasResults = useMemo(() => filteredItems.length > 0, [filteredItems])
Expand Down Expand Up @@ -75,7 +75,7 @@ export function CollectionMenu() {
<Heading as="h2">
Browse
<Text as="span" color="text3" ml="x2">
{daoCount}
{daos?.length}
</Text>
</Heading>
<SearchInput
Expand Down
6 changes: 0 additions & 6 deletions compositions/Daos/DaoRow.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,6 @@ export const placeholderCell = style([
},
])

export const header = style([
{
height: '40px!important',
},
])

// mobile

export const mobileCardWrapper = style([
Expand Down
80 changes: 61 additions & 19 deletions compositions/Daos/DaoRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useToken } from 'hooks/useToken'
import { TypeSafeDao } from 'validators/dao'

import { EthAmount, RPCTokenInfo, lightFont, useNounishAuctionQuery } from '@noun-auction'
import { numberFormatter, useWindowWidth } from '@shared'
import { isAddressMatch, numberFormatter, useWindowWidth } from '@shared'
import { Box, Flex, Label } from '@zoralabs/zord'

import {
Expand All @@ -26,44 +26,86 @@ export const DaoRow = ({ dao, index }: { dao: TypeSafeDao; index: number }) => {
const { activeAuction } = useNounishAuctionQuery({
collectionAddress: dao.collectionAddress,
})

// dao.contractAddress ??
const { token } = useToken({
// collectionAddress: dao.collectionAddress,
collectionAddress: dao.collectionAddress,
// FIXME: @oleg
tokenId: activeAuction?.tokenId ?? '',
})

if (!token || !activeAuction) return null

const highestBid = activeAuction.highestBidPrice?.chainTokenPrice?.raw || '0'
const tokenId = activeAuction.tokenId
const collectionAddress = activeAuction.collectionAddress
// if (!token || !activeAuction) {
// console.log('NOT RENDERING DAO', dao.collectionAddress)
// console.log('TOKEN', token, 'AUCTION', activeAuction)
// // return null
// return (
// <Box>
// {/* {dao.collectionAddress} {token?.tokenId} {activeAuction?.address} */}
// {dao.collectionAddress} {token?.tokenId} {activeAuction?.address}
// </Box>
// )
// }

// const { tokenId, collectionAddress, highestBidPrice } = activeAuction!
// const highestBid = highestBidPrice?.chainTokenPrice?.raw || '0'

// const auctionStatus =
// Date.now() - parseInt(activeAuction!.endTime) * 1000 > 0 ? 'Settling' : 'Live'

// if (
// isAddressMatch('0xd310a3041dfcf14def5ccbc508668974b5da7174', dao.collectionAddress)
// ) {
// console.log('DUPE?')
// }

// return (
// <Box>
// {dao.collectionAddress} {token?.tokenId} {activeAuction?.address}
// </Box>
// )

console.log(
'DAO: ',
dao.collectionAddress,
'AUCTION: ',
activeAuction?.collectionAddress
)

const auctionStatus =
Date.now() - parseInt(activeAuction.endTime) * 1000 > 0 ? 'Settling' : 'Live'
const auctionStatus = !activeAuction
? 'Inactive'
: Date.now() - parseInt(activeAuction!.endTime) * 1000 > 0
? 'Settling'
: 'Live'

return (
// (token && activeAuction && (
<DaoRowComponent
index={index}
tokenId={tokenId}
tokenName={token.name}
collectionAddress={collectionAddress}
collectionName={dao.name ?? token.collectionName ?? '...'}
highestBid={highestBid}
tokenId={activeAuction?.tokenId}
tokenName={token?.name}
// collectionAddress={activeAuction!.collectionAddress}
collectionAddress={dao.collectionAddress}
treasuryAddress={dao.treasuryAddress}
collectionName={dao.name ?? token?.collectionName! ?? '...'}
highestBid={activeAuction?.highestBidPrice?.chainTokenPrice?.raw || '0'}
tokenImage={token?.image.url ?? undefined}
auctionStatus={auctionStatus}
auctionStatus={
auctionStatus
// Date.now() - parseInt(activeAuction!.endTime) * 1000 > 0 ? 'Settling' : 'Live'
}
/>
// )) ||
// null
)
}

type DaoRowProps = {
index: number
tokenId: string
tokenId?: string
collectionAddress: string
tokenImage?: string
collectionName: string
tokenName: string
tokenName?: string
highestBid: string
treasuryAddress: string
auctionStatus: string
Expand All @@ -72,7 +114,7 @@ type DaoRowProps = {
export const DaoRowComponent = ({
index,
collectionAddress,
tokenId,
tokenId = '1',
tokenImage,
tokenName,
collectionName,
Expand Down Expand Up @@ -136,7 +178,7 @@ export const DaoRowComponent = ({
}

return (
<Box className={[rowWrap, index === 0 ? noBorder : '']}>
<Box as="li" data-index={index} className={[rowWrap, index === 0 && noBorder]}>
<Box className={[daoMeta]}>
<RPCTokenInfo
tokenImage={tokenImage}
Expand Down
44 changes: 44 additions & 0 deletions compositions/Daos/DaoTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { DAODescriptionModal } from 'modals'

import React from 'react'
import { TypeSafeDao } from 'validators/dao'

import { useWindowWidth } from '@shared'
import { Flex, Heading, Stack, StackProps } from '@zoralabs/zord'

import { DaoRow } from './DaoRow'
import { DaoTableHeader } from './DaoTableHeader'
import { daosWrapper } from './Daos.css'

interface DaoTableProps extends StackProps {
routePrefix?: string
daos: TypeSafeDao[]
}

export function DaoTable({ routePrefix, daos, className, ...props }: DaoTableProps) {
console.log('DaoTable', daos)

const { isLarge } = useWindowWidth()
return (
<Stack className={[daosWrapper, className]} {...props}>
<Flex gap="x2" align="center">
<Heading as="h2" size="lg">
DAOs
</Heading>
<DAODescriptionModal />
</Flex>
<Stack>
{daos && isLarge && <DaoTableHeader />}
<ul className="nouns-dao-table">
{daos.map((dao, index) => {
// console.log(dao.collectionAddress)
return (
// <DaoRow dao={dao} index={index} key={dao.contractAddress} />
<DaoRow dao={dao} index={index} key={dao.collectionAddress} />
)
})}
</ul>
</Stack>
</Stack>
)
}
40 changes: 40 additions & 0 deletions compositions/Daos/DaoTableHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'

import { lightFont } from '@noun-auction'
import { Box, BoxProps, Label } from '@zoralabs/zord'

import {
cell,
daoMeta,
metadataCells,
noBorder,
placeholderCell,
rowWrap,
} from './DaoRow.css'
import { header } from './Daos.css'

export function DaoTableHeader({ className, ...props }: BoxProps) {
return (
<Box className={[rowWrap, noBorder, header, className]}>
<Box className={[daoMeta]}></Box>
<Box className={[metadataCells]}>
<Box className={[cell]}>
<Label color="tertiary" className={[lightFont]}>
Treasury
</Label>
</Box>
<Box className={[cell]}>
<Label color="tertiary" className={[lightFont]}>
Auction Status
</Label>
</Box>
<Box className={[cell]}>
<Label color="tertiary" className={[lightFont]}>
Current Bid
</Label>
</Box>
</Box>
<Box className={[placeholderCell]}></Box>
</Box>
)
}
6 changes: 6 additions & 0 deletions compositions/Daos/Daos.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,9 @@ export const daosRow = style([
},
}),
])

export const header = style([
{
height: '40px!important',
},
])
Loading