diff --git a/apps/trading/components/competitions/games-container.tsx b/apps/trading/components/competitions/games-container.tsx index 8f0a223fa..2805ab64f 100644 --- a/apps/trading/components/competitions/games-container.tsx +++ b/apps/trading/components/competitions/games-container.tsx @@ -4,6 +4,72 @@ import { useVegaWallet } from '@vegaprotocol/wallet-react'; import { useStakeAvailable } from '../../lib/hooks/use-stake-available'; import { useMyTeam } from '../../lib/hooks/use-my-team'; import { ActiveRewardCard } from '../rewards-container/reward-card'; +import { + VegaIcon, + VegaIconNames, + TradingInput, +} from '@vegaprotocol/ui-toolkit'; +import { useState } from 'react'; +import { type AssetFieldsFragment } from '@vegaprotocol/assets'; +import { type MarketFieldsFragment } from '@vegaprotocol/markets'; +import { + type TransferNode, + DispatchMetricLabels, + EntityScopeLabelMapping, + AccountType, +} from '@vegaprotocol/types'; + +export type Filter = { + searchTerm: string; +}; + +export const applyFilter = ( + node: TransferNode & { + asset?: AssetFieldsFragment | null; + markets?: (MarketFieldsFragment | null)[]; + }, + filter: Filter +) => { + const { transfer } = node; + + // if the transfer is a staking reward then it should be displayed + if (transfer.toAccountType === AccountType.ACCOUNT_TYPE_GLOBAL_REWARD) { + return true; + } + + if (transfer.kind.__typename !== 'RecurringTransfer') { + return false; + } + + if ( + (transfer.kind.dispatchStrategy?.dispatchMetric && + DispatchMetricLabels[transfer.kind.dispatchStrategy.dispatchMetric] + .toLowerCase() + .includes(filter.searchTerm.toLowerCase())) || + transfer.asset?.symbol + .toLowerCase() + .includes(filter.searchTerm.toLowerCase()) || + ( + (transfer.kind.dispatchStrategy && + EntityScopeLabelMapping[transfer.kind.dispatchStrategy.entityScope]) || + 'Unspecified' + ) + .toLowerCase() + .includes(filter.searchTerm.toLowerCase()) || + node.asset?.name + .toLocaleLowerCase() + .includes(filter.searchTerm.toLowerCase()) || + node.markets?.some((m) => + m?.tradableInstrument?.instrument?.name + .toLocaleLowerCase() + .includes(filter.searchTerm.toLowerCase()) + ) + ) { + return true; + } + + return false; +}; export const GamesContainer = ({ data, @@ -27,6 +93,10 @@ export const GamesContainer = ({ } : undefined; + const [filter, setFilter] = useState({ + searchTerm: '', + }); + if (!data || data.length === 0) { return (

@@ -36,25 +106,43 @@ export const GamesContainer = ({ } return ( -

- {data.map((game, i) => { - // TODO: Remove `kind` prop from ActiveRewardCard - const { transfer } = game; - if ( - transfer.kind.__typename !== 'RecurringTransfer' || - !transfer.kind.dispatchStrategy?.dispatchMetric - ) { - return null; - } - return ( - - ); - })} +
+ {/** CARDS FILTER */} + {data.length > 1 && ( + + setFilter((curr) => ({ ...curr, searchTerm: e.target.value })) + } + value={filter.searchTerm} + type="text" + placeholder={t( + 'Search by reward dispatch metric, entity scope or asset name' + )} + data-testid="search-term" + className="mb-4 w-20 mr-2 max-w-xl" + prependElement={} + /> + )} + {/** CARDS */} +
+ {data + .filter((n) => applyFilter(n, filter)) + .map((game, i) => { + // TODO: Remove `kind` prop from ActiveRewardCard + const { transfer } = game; + if (!transfer.kind.dispatchStrategy?.dispatchMetric) { + return null; + } + return ( + + ); + })} +
); }; diff --git a/apps/trading/components/rewards-container/active-rewards.tsx b/apps/trading/components/rewards-container/active-rewards.tsx index c03d3f550..4451edeff 100644 --- a/apps/trading/components/rewards-container/active-rewards.tsx +++ b/apps/trading/components/rewards-container/active-rewards.tsx @@ -114,7 +114,7 @@ export const ActiveRewards = ({ currentEpoch }: { currentEpoch: number }) => { 'Search by reward dispatch metric, entity scope or asset name' )} data-testid="search-term" - className="mb-4 w-20 mr-2" + className="mb-4 w-20 mr-2 max-w-xl" prependElement={} /> )} diff --git a/apps/trading/components/rewards-container/reward-card.tsx b/apps/trading/components/rewards-container/reward-card.tsx index 09b029706..f0a5d4c2e 100644 --- a/apps/trading/components/rewards-container/reward-card.tsx +++ b/apps/trading/components/rewards-container/reward-card.tsx @@ -634,7 +634,7 @@ const RewardRequirements = ({ description={ averagePosition ? t( - 'Your average position is {{averagePosition}}, but the requirement is {{averagePositionRequirements}}', + 'Your average position is {{averagePosition}}, and the requirement is {{averagePositionRequirements}}', { averagePosition: averagePositionFormatted, averagePositionRequirements: diff --git a/libs/i18n/src/locales/en/trading.json b/libs/i18n/src/locales/en/trading.json index faeccb2f8..c2f769a15 100644 --- a/libs/i18n/src/locales/en/trading.json +++ b/libs/i18n/src/locales/en/trading.json @@ -451,7 +451,7 @@ "You need a <0>Vega wallet to start trading in this market.": "You need a <0>Vega wallet to start trading in this market.", "You need at least {{requiredStake}} VEGA staked to generate a referral code and participate in the referral program.": "You need at least {{requiredStake}} VEGA staked to generate a referral code and participate in the referral program.", "You will no longer be able to hold a position on this market when it closes in {{duration}}.": "You will no longer be able to hold a position on this market when it closes in {{duration}}.", - "Your average position is {{averagePosition}}, but the requirement is {{averagePositionRequirements}}": "Your average position is {{averagePosition}}, but the requirement is {{averagePositionRequirements}}", + "Your average position is {{averagePosition}}, and the requirement is {{averagePositionRequirements}}": "Your average position is {{averagePosition}}, and the requirement is {{averagePositionRequirements}}", "Your code has been rejected": "Your code has been rejected", "Your identity is always anonymous on Vega": "Your identity is always anonymous on Vega", "Your key's private name, can be changed in your wallet": "Your key's private name, can be changed in your wallet",