From e341a2ff19999a4da3fe775b00bc3150b7d98e68 Mon Sep 17 00:00:00 2001 From: franciscotobar <100875069+franciscotobar@users.noreply.github.com> Date: Sat, 23 Nov 2024 09:18:10 -0600 Subject: [PATCH] refactor: search context (#397) * refactor: search context * chore: remove unused code and move filter fn outside component * chore: add missing dependency --------- Co-authored-by: Antonio --- .../active-builders/ActiveBuildersContent.tsx | 17 +++---- .../active-builders/ActiveBuildersGrid.tsx | 6 +-- .../ActiveBuildersGridItem.tsx | 22 +++++---- .../leaderboard/BuildersLeaderBoardTable.tsx | 7 +-- .../backers/hooks/useGetBackerRewards.ts | 5 +- .../shared/context/SearchContext.tsx | 47 ++++++++++++------- .../Button/BecomeABuilderButton.tsx | 10 ++-- src/app/collective-rewards/utils/index.ts | 13 ----- 8 files changed, 63 insertions(+), 64 deletions(-) diff --git a/src/app/collective-rewards/active-builders/ActiveBuildersContent.tsx b/src/app/collective-rewards/active-builders/ActiveBuildersContent.tsx index 8f618623..d534fd4c 100644 --- a/src/app/collective-rewards/active-builders/ActiveBuildersContent.tsx +++ b/src/app/collective-rewards/active-builders/ActiveBuildersContent.tsx @@ -11,20 +11,17 @@ export const isActive = (stateFlags?: BuilderStateFlags) => { return activeFlags.some(flag => stateFlags?.[flag]) } -export type BuilderWithStatus = Builder & { builderStatus: 'active' | 'inProgress' } +const filterFunction = (builder: Builder, status: string) => { + if (status === 'all') return true + if (status === 'active') return isActive(builder.stateFlags) + if (status === 'inProgress') return !isActive(builder.stateFlags) + return false +} export const ActiveBuildersContent = () => { const { data: builders, isLoading, error } = useGetBuildersByState(undefined, true) useHandleErrors({ error, title: 'Error loading builders' }) - const buildersWithStatus = builders.map(builder => { - const builderStatus = isActive(builder.stateFlags) ? 'active' : 'inProgress' - return { - ...builder, - builderStatus, - } - }) - const status = [ { label: 'All', value: 'all' }, { label: 'Active', value: 'active' }, @@ -33,7 +30,7 @@ export const ActiveBuildersContent = () => { return ( <> - + {withSpinner(ActiveBuildersGrid)({ isLoading })} diff --git a/src/app/collective-rewards/active-builders/ActiveBuildersGrid.tsx b/src/app/collective-rewards/active-builders/ActiveBuildersGrid.tsx index dd9e9178..958dac71 100644 --- a/src/app/collective-rewards/active-builders/ActiveBuildersGrid.tsx +++ b/src/app/collective-rewards/active-builders/ActiveBuildersGrid.tsx @@ -1,10 +1,10 @@ import { FC } from 'react' -import { ActiveBuildersGridItem, BuilderWithStatus } from '@/app/collective-rewards/active-builders' +import { ActiveBuildersGridItem } from '@/app/collective-rewards/active-builders' import { useSearchContext } from '@/app/collective-rewards/shared' +import { Builder } from '@/app/collective-rewards/types' export const ActiveBuildersGrid: FC = () => { - const { getValues } = useSearchContext() - const items = getValues() + const { data: items } = useSearchContext() return (
diff --git a/src/app/collective-rewards/active-builders/ActiveBuildersGridItem.tsx b/src/app/collective-rewards/active-builders/ActiveBuildersGridItem.tsx index 5d97b946..9cc29c27 100644 --- a/src/app/collective-rewards/active-builders/ActiveBuildersGridItem.tsx +++ b/src/app/collective-rewards/active-builders/ActiveBuildersGridItem.tsx @@ -3,14 +3,14 @@ import { Badge } from '@/components/Badge' import { Popover } from '@/components/Popover' import { Paragraph, Span, Typography } from '@/components/Typography' import { useRouter } from 'next/navigation' -import { FC, ReactNode } from 'react' +import { FC, HtmlHTMLAttributes, ReactNode } from 'react' import { Jdenticon } from '@/components/Header/Jdenticon' import { shortAddress } from '@/lib/utils' import { isAddress, Address } from 'viem' -import { crStatusColorClasses } from '@/app/collective-rewards/utils' -import { BuilderWithStatus } from '@/app/collective-rewards/active-builders' +import { Builder, BuilderState } from '@/app/collective-rewards/types' +import { isActive } from '@/app/collective-rewards/active-builders' -type ActiveBuildersGridItemProps = BuilderWithStatus +type ActiveBuildersGridItemProps = Builder const Card = ({ header, body }: { header: ReactNode; body: ReactNode }) => { return ( @@ -26,15 +26,21 @@ const builderStatusMap = { inProgress: 'In Progress', } +const crStatusColorClasses: Record['className']> = { + active: 'bg-[#DBFEE5] text-secondary', + inProgress: 'bg-[#4B5CF0] color-text-primary', +} as const + // TODO: this content can be moved to a different component and become a generic card export const ActiveBuildersGridItem: FC = ({ address, builderName, - builderStatus, + stateFlags, proposal: { id: proposalId, date: joiningDate, name: proposalName }, }) => { const router = useRouter() const shortenAddress = shortAddress(address as Address) + const builderState = isActive(stateFlags) ? 'active' : 'inProgress' const Header = (
@@ -61,14 +67,14 @@ export const ActiveBuildersGridItem: FC = ({ /> - {builderStatus === 'active' && ( + {builderState === 'active' && ( Joined {joiningDate} )}
diff --git a/src/app/collective-rewards/leaderboard/BuildersLeaderBoardTable.tsx b/src/app/collective-rewards/leaderboard/BuildersLeaderBoardTable.tsx index c343cf08..59e68552 100644 --- a/src/app/collective-rewards/leaderboard/BuildersLeaderBoardTable.tsx +++ b/src/app/collective-rewards/leaderboard/BuildersLeaderBoardTable.tsx @@ -1,7 +1,7 @@ import { BuildersRewards } from '@/app/collective-rewards/rewards' import { TableBody, TableCore, TableHead, TableRow } from '@/components/Table' import { useBasicPaginationUi } from '@/shared/hooks/usePaginationUi' -import { FC, useContext, useEffect, useMemo, useState } from 'react' +import { FC, useMemo, useState } from 'react' import { ISortConfig, TableHeader, @@ -13,8 +13,6 @@ import { TotalAllocationCell, useSearchContext, } from '@/app/collective-rewards/shared' -import { PaginatedDataContext } from '../context/PaginatedDataContext' -import { Pagination } from '../shared/components/Pagination' enum RewardsColumnKeyEnum { builder = 'builder', @@ -42,8 +40,7 @@ const tableHeaders: TableHeader[] = [ ] export const BuildersLeaderBoardTable: FC = () => { - const { getValues } = useSearchContext() - const rewardsData = getValues() + const { data: rewardsData } = useSearchContext() const [sortConfig, setSortConfig] = useState({ key: RewardsColumnKeyEnum.totalAllocationPercentage, diff --git a/src/app/collective-rewards/rewards/backers/hooks/useGetBackerRewards.ts b/src/app/collective-rewards/rewards/backers/hooks/useGetBackerRewards.ts index e031102f..88bbf6f5 100644 --- a/src/app/collective-rewards/rewards/backers/hooks/useGetBackerRewards.ts +++ b/src/app/collective-rewards/rewards/backers/hooks/useGetBackerRewards.ts @@ -6,7 +6,6 @@ import { RifSvg, RbtcSvg, } from '@/app/collective-rewards/rewards' -import { useBuilderContext } from '@/app/collective-rewards/user' import { useGaugesGetFunction } from '@/app/collective-rewards//shared' import { Address } from 'viem' import { usePricesContext } from '@/shared/context/PricesContext' @@ -73,8 +72,8 @@ export const useGetBackerRewards = ( const rbtcPrice = prices[rbtc.symbol]?.price ?? 0 const data = buildersV2.map(({ address, builderName, gauge, stateFlags }) => { - const builderTotalAllocation = totalAllocation[gauge] - const backerAllocationOf = allocationOf[gauge] + const builderTotalAllocation = totalAllocation[gauge] ?? 0n + const backerAllocationOf = allocationOf[gauge] ?? 0n const totalAllocationPercentage = builderTotalAllocation ? (backerAllocationOf * 100n) / builderTotalAllocation : 0n diff --git a/src/app/collective-rewards/shared/context/SearchContext.tsx b/src/app/collective-rewards/shared/context/SearchContext.tsx index a6eed3a4..ed7af26f 100644 --- a/src/app/collective-rewards/shared/context/SearchContext.tsx +++ b/src/app/collective-rewards/shared/context/SearchContext.tsx @@ -1,18 +1,28 @@ -import { createContext, Dispatch, FC, ReactNode, SetStateAction, useContext, useMemo, useState } from 'react' +import { + Context, + createContext, + Dispatch, + ReactNode, + SetStateAction, + useContext, + useMemo, + useState, +} from 'react' type StateWithUpdate = { value: T onChange: Dispatch> } -type SearchContextValue = { - getValues: () => T[] +type SearchContextValue = { + data: Type[] search: StateWithUpdate filterBy: StateWithUpdate } -export const SearchContext = createContext({ - getValues: () => [], +type SearchValue = { builderName: string; address: string } +export const SearchContext = createContext>({ + data: [], search: { value: '', onChange: () => {}, @@ -23,14 +33,18 @@ export const SearchContext = createContext({ }, }) -type SearchValue = { builderName: string; address: string; builderStatus?: string } -type SearchProviderProps = { +type SearchProviderProps = { children: ReactNode - builders: SearchValue[] + builders: T[] + filterFunction?: (param: T, status: string) => boolean } const lowerCaseCompare = (a: string, b: string) => a?.toLowerCase().includes(b?.toLowerCase()) -export const SearchContextProvider: FC = ({ children, builders }) => { +export const SearchContextProvider = ({ + children, + builders, + filterFunction, +}: SearchProviderProps) => { const [search, setSearch] = useState('') const [filterBy, setFilterBy] = useState('all') @@ -46,17 +60,15 @@ export const SearchContextProvider: FC = ({ children, build ) } - if (filterBy !== 'all') { - filteredBuilders = filteredBuilders.filter(builder => builder.builderStatus === filterBy) + if (filterBy !== 'all' && filterFunction) { + filteredBuilders = filteredBuilders.filter(builder => filterFunction(builder, filterBy)) } return filteredBuilders - }, [builders, search, filterBy]) + }, [builders, search, filterBy, filterFunction]) - const getValues = () => data as T[] - - const valueOfContext: SearchContextValue = { - getValues, + const valueOfContext: SearchContextValue = { + data, search: { value: search, onChange: setSearch }, filterBy: { value: filterBy, onChange: setFilterBy }, } @@ -64,4 +76,5 @@ export const SearchContextProvider: FC = ({ children, build return {children} } -export const useSearchContext = () => useContext(SearchContext) +export const useSearchContext = () => + useContext(SearchContext as unknown as Context>) diff --git a/src/app/collective-rewards/user/components/Button/BecomeABuilderButton.tsx b/src/app/collective-rewards/user/components/Button/BecomeABuilderButton.tsx index 93c197fc..22c2da29 100644 --- a/src/app/collective-rewards/user/components/Button/BecomeABuilderButton.tsx +++ b/src/app/collective-rewards/user/components/Button/BecomeABuilderButton.tsx @@ -11,7 +11,7 @@ import { BuilderState, BuilderStateFlags } from '@/app/collective-rewards/types' import { useHandleErrors } from '@/app/collective-rewards/utils' type StatusBadgeProps = { - builderStatus?: BuilderState + builderState?: BuilderState } const BuilderRegistrationButton = () => { @@ -24,7 +24,7 @@ const BuilderRegistrationButton = () => { ) } -const StatusBadge: FC = ({ builderStatus }) => { +const StatusBadge: FC = ({ builderState }) => { const InProgressComponent = ( ) @@ -38,7 +38,7 @@ const StatusBadge: FC = ({ builderStatus }) => { inProgress: InProgressComponent, active: WhitelistedComponent, undefined: BuilderRegistrationButton, - }[builderStatus as BuilderState] + }[builderState as BuilderState] } const getBuilderState = (builderStateFlags?: BuilderStateFlags): BuilderState => { @@ -51,7 +51,7 @@ export const BecomeABuilderHandler = ({ address }: { address: Address }) => { const { getBuilderByAddress, isLoading: builderLoading, error: builderLoadingError } = useBuilderContext() const builder = getBuilderByAddress(address) - const builderStatus = getBuilderState(builder?.stateFlags) + const builderState = getBuilderState(builder?.stateFlags) useHandleErrors({ error: builderLoadingError, title: `Error loading builder with address ${address}` }) @@ -63,7 +63,7 @@ export const BecomeABuilderHandler = ({ address }: { address: Address }) => { return } - return + return } export const BecomeABuilderButton = ({ address }: { address: Address }) => { diff --git a/src/app/collective-rewards/utils/index.ts b/src/app/collective-rewards/utils/index.ts index 2031e6ff..4dbdee48 100644 --- a/src/app/collective-rewards/utils/index.ts +++ b/src/app/collective-rewards/utils/index.ts @@ -1,19 +1,6 @@ -import { HtmlHTMLAttributes } from 'react' -import { BuilderState } from '../types' - export * from './applyPrecision' export * from './getBuilderGauge' export * from './getBuilderState' export * from './getCoinbaseAddress' export * from './getMostAdvancedProposal' export * from './handleErrors' - -export const crStatusLabels: Record = { - active: 'Active', - inProgress: 'In Progress', -} as const - -export const crStatusColorClasses: Record['className']> = { - active: 'bg-[#DBFEE5] text-secondary', - inProgress: 'bg-[#4B5CF0] color-text-primary', -} as const