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

📜 Migrate bids list on homepage #14

Merged
merged 15 commits into from
Apr 17, 2024
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Make BidsList less generic
b-tarczynski committed Apr 17, 2024
commit 102e931217aaa13fbfb4c1b90a49acd1fae82de1
4 changes: 2 additions & 2 deletions packages/frontend/src/blockchain/hooks/useUserBid.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useAccount } from 'wagmi'
import { useBids } from '@/providers/BidsProvider'
import { useMemo } from 'react'
import { UserBid } from '@/types/bid'
import { BidWithPlace } from '@/types/bid'

export const useUserBid = (): UserBid | undefined => {
export const useUserBid = (): BidWithPlace | undefined => {
const { address } = useAccount()
const { bidList } = useBids()

7 changes: 3 additions & 4 deletions packages/frontend/src/components/bidsList/BidListEntry.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { AddressColumn, BidColumn, PlaceColumn } from '@/components/bidsList/BidsColumns'
import styled, { css } from 'styled-components'
import { useChainId, useChains } from 'wagmi'
import { Bid } from '@/types/bid'
import { BidWithPlace } from '@/types/bid'
import { Colors } from '@/styles/colors'
import { formatEther, Hex } from 'viem'

interface Props {
bid: Bid
bid: BidWithPlace
isUser?: boolean
view?: 'short' | 'full'
}
@@ -16,8 +16,7 @@ export const BidListEntry = ({ bid, isUser, view = 'full' }: Props) => {

return (
<BidsEntryRow isUser={isUser}>
{/*<PlaceColumn>{bid.place}.</PlaceColumn>*/}
<PlaceColumn>{1}.</PlaceColumn>
<PlaceColumn>{bid.place}.</PlaceColumn>
<BidColumn>
{formatEther(bid.amount)} <span>ETH</span>
</BidColumn>
41 changes: 2 additions & 39 deletions packages/frontend/src/components/bidsList/BidsListSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useMemo } from 'react'
import styled from 'styled-components'

import { useAuctionState } from '@/blockchain/hooks/useAuctionState'
@@ -7,26 +6,15 @@ import { Button } from '@/components/buttons/Button'
import { useRouter } from 'next/navigation'
import { useReadAuctionParams } from '@/blockchain/hooks/useReadAuctionParams'
import { Colors } from '@/styles/colors'
import { Bid, UserBid } from '@/types/bid'
import { useUserBid } from '@/blockchain/hooks/useUserBid'
import { BidsList } from '@/components/bidsList/BidsList'
import { ShortBidsList } from '@/components/bidsList/ShortBidsList'
import { BidsListHeaders } from '@/components/bidsList/BidsListHeaders'

const topAuctionBidsCount = 3
const bidsMaxCount = topAuctionBidsCount + 1

export const BidsListSection = () => {
const state = useAuctionState()
const { bidList } = useBids()
const userBid = useUserBid()
const { auctionWinnersCount } = useReadAuctionParams()
const router = useRouter()

const bidsShortlist = useMemo(
() => selectBids(auctionWinnersCount, bidList, userBid),
[auctionWinnersCount, bidList, userBid],
)

const isLoadingParams = auctionWinnersCount === undefined

return (
@@ -44,7 +32,7 @@ export const BidsListSection = () => {
<ColoredText>{isLoadingParams ? 0 : bidList.length}</ColoredText>
</ListHeader>
<BidsListHeaders />
<BidsList bids={bidsShortlist} view="short" isLoadingParams={isLoadingParams} />
<ShortBidsList isLoadingParams={isLoadingParams} />
</>
)}
{!isLoadingParams && bidList.length !== 0 && (
@@ -56,31 +44,6 @@ export const BidsListSection = () => {
)
}

function selectBids(auctionWinnersCount: number | undefined, bidList: Bid[], userBid: UserBid | undefined) {
if (auctionWinnersCount === undefined) {
return []
}

if (bidList.length <= bidsMaxCount) {
return bidList
}

const topAuctionBids = bidList.slice(0, topAuctionBidsCount)

const lastAuctionBidIndex = bidList.length > auctionWinnersCount ? auctionWinnersCount - 1 : bidList.length - 1
const lastAuctionBid = bidList[lastAuctionBidIndex]

return userBid && shouldUserBidBeDisplayed(userBid, lastAuctionBid, auctionWinnersCount)
? topAuctionBids.concat([userBid, lastAuctionBid])
: topAuctionBids.concat([lastAuctionBid])
}

const shouldUserBidBeDisplayed = (userBid: UserBid, lastAuctionBid: Bid, auctionWinnersCount: number) => {
return !(userBid.address === lastAuctionBid.address) && within(bidsMaxCount, auctionWinnersCount - 1, userBid.place)
}

const within = (...[lower, higher, value]: number[]) => value >= lower && value <= higher

const BidsListContainer = styled.div`
display: flex;
flex-direction: column;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EmptyBidListEntry } from './BidListEntry'
import { BidList } from './BidsList'
import { BidList } from './ShortBidsList'

const emptyBids: number[] = [1, 2, 3, 20]

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import styled from 'styled-components'
import { Bid, UserBid } from '@/types/bid'
import { Bid, BidWithPlace } from '@/types/bid'
import { useUserBid } from '@/blockchain/hooks/useUserBid'
import { Colors } from '@/styles/colors'
import { useReadAuctionParams } from '@/blockchain/hooks/useReadAuctionParams'
@@ -12,52 +12,58 @@ import { EmptyBidsList } from '@/components/bidsList/EmptyBidsList'
import { isAuctionSettled } from '@/utils/isAuctionSettled'
import { getFirstRaffleBidIndex } from '@/utils/getFirstRaffleBidIndex'

const topAuctionBidsCount = 3
const bidsMaxCount = topAuctionBidsCount + 1

interface Props {
bids: Bid[]
view?: 'short' | 'full'
isLoadingParams?: boolean
}

export const BidsList = ({ bids, view = 'full', isLoadingParams }: Props) => {
export const ShortBidsList = ({ isLoadingParams }: Props) => {
const userBid = useUserBid()
const { auctionWinnersCount, raffleWinnersCount } = useReadAuctionParams()
const { state } = useContractState()
const { bidList: allBids } = useBids()

const userRaffleBid = useMemo(() => {
return auctionWinnersCount && userBid && userBid.place > auctionWinnersCount ? userBid : undefined
const bidsShortlist = useMemo(
() => selectBids(auctionWinnersCount, allBids, userBid),
[auctionWinnersCount, allBids, userBid],
)

const isRaffleParticipant = useMemo(() => {
return !!auctionWinnersCount && !!userBid && userBid.place > auctionWinnersCount
}, [userBid, auctionWinnersCount])

const isAuctionWinner = useMemo(() => {
return isAuctionParticipant(userBid, auctionWinnersCount, raffleWinnersCount, allBids.length)
}, [auctionWinnersCount, allBids.length, raffleWinnersCount, userBid])

if (isLoadingParams) {
return <EmptyBidsList />
return <EmptyBidsList/>
}

return (
<>
<BidList>
{bids.map((bid) => (
<BidListEntry key={bid.address} bid={bid} isUser={userBid && userBid.address === bid.address} view={view} />
{bidsShortlist.map((bid) => (
<BidListEntry key={bid.address} bid={bid} isUser={userBid && userBid.address === bid.address} view="short"/>
))}
{userRaffleBid && view === 'short' && (
{isRaffleParticipant && userBid && (
<>
<Separator color={Colors.Grey} />
<BidListEntry bid={userRaffleBid} isUser view={view} />
<Separator color={Colors.Grey}/>
<BidListEntry bid={userBid} isUser view="short"/>
</>
)}
</BidList>
{view === 'short' && userBid && !isAuctionSettled(state) && (
{userBid && !isAuctionSettled(state) && (
<BidListText>You’re taking part in the {isAuctionWinner ? 'auction' : 'raffle'}!</BidListText>
)}
</>
)
}

function isAuctionParticipant(
userBid: UserBid | undefined,
userBid: BidWithPlace | undefined,
auctionWinnersCount: number | undefined,
raffleWinnersCount: number | undefined,
bidsLength: number,
@@ -69,6 +75,33 @@ function isAuctionParticipant(
return userBid.place <= firstRaffleBidIndex
}

function selectBids(auctionWinnersCount: number | undefined, bidList: Bid[], userBid: BidWithPlace | undefined): BidWithPlace[] {
if (auctionWinnersCount === undefined) {
return []
}

if (bidList.length <= bidsMaxCount) {
return bidList.map(toBidWithPlace)
}

const topAuctionBids = bidList.slice(0, topAuctionBidsCount).map(toBidWithPlace)

const lastAuctionBidIndex = bidList.length > auctionWinnersCount ? auctionWinnersCount - 1 : bidList.length - 1
const lastAuctionBid = toBidWithPlace(bidList[lastAuctionBidIndex], lastAuctionBidIndex)

return userBid && shouldUserBidBeDisplayed(userBid, lastAuctionBid, auctionWinnersCount)
? topAuctionBids.concat([userBid, lastAuctionBid])
: topAuctionBids.concat([lastAuctionBid])
}

const shouldUserBidBeDisplayed = (userBid: BidWithPlace, lastAuctionBid: Bid, auctionWinnersCount: number) => {
return !(userBid.address === lastAuctionBid.address) && within(bidsMaxCount, auctionWinnersCount - 1, userBid.place)
}

const within = (...[lower, higher, value]: number[]) => value >= lower && value <= higher

const toBidWithPlace = (bid: Bid, arrayIndex: number): BidWithPlace => ({ ...bid, place: arrayIndex + 1 })

export const BidList = styled.div`
display: flex;
flex-direction: column;
2 changes: 1 addition & 1 deletion packages/frontend/src/types/bid.ts
Original file line number Diff line number Diff line change
@@ -6,6 +6,6 @@ export interface Bid {
bidderId: bigint
}

export interface UserBid extends Bid {
export interface BidWithPlace extends Bid {
place: number
}