From d4515ebc77d8c5b41315848327d4e51d2115a9fe Mon Sep 17 00:00:00 2001 From: defispartan Date: Mon, 16 Dec 2024 23:42:50 -0600 Subject: [PATCH] feat: scaffold APY range select --- src/components/HistoricalAPYRow.tsx | 100 ++++++++++++++++++ src/components/TitleWithSearchBar.tsx | 7 +- .../markets/MarketAssetsListContainer.tsx | 47 ++++++-- 3 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 src/components/HistoricalAPYRow.tsx diff --git a/src/components/HistoricalAPYRow.tsx b/src/components/HistoricalAPYRow.tsx new file mode 100644 index 0000000000..81f74032af --- /dev/null +++ b/src/components/HistoricalAPYRow.tsx @@ -0,0 +1,100 @@ +import { SxProps, Theme, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material'; + +const supportedHistoricalTimeRangeOptions = ['Now', '30D', '60D', '90D'] as const; + +export enum ESupportedAPYTimeRanges { + Now = 'Now', + ThirtyDays = '30D', + SixtyDays = '60D', + NinetyDays = '90D', +} + +export const reserveHistoricalRateTimeRangeOptions = [ + ESupportedAPYTimeRanges.Now, + ESupportedAPYTimeRanges.ThirtyDays, + ESupportedAPYTimeRanges.SixtyDays, + ESupportedAPYTimeRanges.NinetyDays, +]; + +export type ReserveHistoricalRateTimeRange = typeof reserveHistoricalRateTimeRangeOptions[number]; + +export interface TimeRangeSelectorProps { + disabled?: boolean; + selectedTimeRange: ESupportedAPYTimeRanges; + onTimeRangeChanged: (value: ESupportedAPYTimeRanges) => void; + sx?: { + buttonGroup: SxProps; + button: SxProps; + }; +} + +export const HistoricalAPYRow = ({ + disabled = false, + selectedTimeRange, + onTimeRangeChanged, + ...props +}: TimeRangeSelectorProps) => { + const handleChange = ( + _event: React.MouseEvent, + newInterval: ESupportedAPYTimeRanges + ) => { + if (newInterval !== null) { + onTimeRangeChanged(newInterval); + } + }; + + return ( +
+ APY + + {supportedHistoricalTimeRangeOptions.map((interval) => { + return ( + | undefined => ({ + '&.MuiToggleButtonGroup-grouped:not(.Mui-selected), &.MuiToggleButtonGroup-grouped&.Mui-disabled': + { + border: '0.5px solid transparent', + backgroundColor: 'background.surface', + color: 'action.disabled', + }, + '&.MuiToggleButtonGroup-grouped&.Mui-selected': { + borderRadius: '4px', + border: `0.5px solid ${theme.palette.divider}`, + boxShadow: '0px 2px 1px rgba(0, 0, 0, 0.05), 0px 0px 1px rgba(0, 0, 0, 0.25)', + backgroundColor: 'background.paper', + }, + ...props.sx?.button, + })} + > + {interval} + + ); + })} + +
+ ); +}; diff --git a/src/components/TitleWithSearchBar.tsx b/src/components/TitleWithSearchBar.tsx index 8529a3ec5a..eb4ba1056e 100644 --- a/src/components/TitleWithSearchBar.tsx +++ b/src/components/TitleWithSearchBar.tsx @@ -28,13 +28,10 @@ export const TitleWithSearchBar = ({ title, }: TitleWithSearchBarProps) => { const [showSearchBar, setShowSearchBar] = useState(false); - const { breakpoints } = useTheme(); const sm = useMediaQuery(breakpoints.down('sm')); - const showSearchIcon = sm && !showSearchBar; - const showMarketTitle = !sm || !showSearchBar; - + const showMarketTitle = (!sm || !showSearchBar) && !!title; const handleCancelClick = () => { setShowSearchBar(false); onSearchTermChange(''); @@ -46,7 +43,7 @@ export const TitleWithSearchBar = ({ width: '100%', display: 'flex', alignItems: 'center', - justifyContent: 'space-between', + justifyContent: showMarketTitle && title ? 'space-between' : 'center', }} > {showMarketTitle && ( diff --git a/src/modules/markets/MarketAssetsListContainer.tsx b/src/modules/markets/MarketAssetsListContainer.tsx index 2660231fdc..0024e5d86a 100644 --- a/src/modules/markets/MarketAssetsListContainer.tsx +++ b/src/modules/markets/MarketAssetsListContainer.tsx @@ -16,6 +16,11 @@ import { getGhoReserve, GHO_MINTING_MARKETS, GHO_SYMBOL } from 'src/utils/ghoUti import { GENERAL } from '../../utils/mixPanelEvents'; import { GhoBanner } from './Gho/GhoBanner'; +import { + ESupportedAPYTimeRanges, + HistoricalAPYRow, + ReserveHistoricalRateTimeRange, +} from 'src/components/HistoricalAPYRow'; function shouldDisplayGhoBanner(marketTitle: string, searchTerm: string): boolean { // GHO banner is only displayed on markets where new GHO is mintable (i.e. Ethereum) @@ -75,6 +80,9 @@ export const MarketAssetsListContainer = () => { // marketFrozen && ['Fantom', 'Ethereum AMM'].includes(currentMarketData.marketTitle); const unfrozenReserves = filteredData.filter((r) => !r.isFrozen && !r.isPaused); const [showFrozenMarketsToggle, setShowFrozenMarketsToggle] = useState(false); + const [selectedTimeRange, setSelectedTimeRange] = useState( + ESupportedAPYTimeRanges.Now + ); const handleChange = () => { setShowFrozenMarketsToggle((prevState) => !prevState); @@ -85,15 +93,38 @@ export const MarketAssetsListContainer = () => { return ( +
+ {/* Left: Title */} +
+ {currentMarketData.marketTitle} assets - - } - searchPlaceholder={sm ? 'Search asset' : 'Search asset name, symbol, or address'} - /> + +
+ + {/* Center: Search Bar */} +
+ +
+ + {/* Right: Historical APY */} +
+ +
+
} > {displayGhoBanner && (