Skip to content

Commit

Permalink
Earn Protocol WIP #6 (#530)
Browse files Browse the repository at this point in the history
6 of N pull requests.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced `MainBackground` and `SummerBall` components for enhanced
visual elements.
	- Added `TableHeadWithTooltip` component for improved table headers.
	- Updated `StrategyExposureTypePicker` for selecting exposure types.
	- Enhanced `Table` component to support optional row details.
- Added new constants for user activity and rebalancing activity
columns.

- **Bug Fixes**
	- Improved state management in the `Dropdown` component.

- **Style**
	- Enhanced layout and hover effects across various components.
	- Added new CSS properties for better visual presentation.

- **Documentation**
	- Expanded exports in the main index file for easier component access.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: sebastianPiekarczyk <sebastian@oazoapps.com>
  • Loading branch information
marcinciarka and piekczyk authored Oct 10, 2024
1 parent 91f55a2 commit 280bd65
Show file tree
Hide file tree
Showing 37 changed files with 727 additions and 349 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
max-width: 1070px;
margin: 0 auto;
padding: 0 var(--space-m);
}
z-index: 2;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type FC, type PropsWithChildren } from 'react'
import { MainBackground } from '@summerfi/app-earn-ui'

import { NavigationWrapper } from '@/components/layout/Navigation/NavigationWrapper'

Expand All @@ -14,6 +15,7 @@ export const MasterPage: FC<PropsWithChildren<MasterPageProps>> = ({ children })
{children}
<div style={{ marginTop: '100px', textAlign: 'center' }}>Footer (:</div>
</div>
<MainBackground />
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const EarnNetworkSelectedStrategyPage = ({
}) => {
// particular strategy loaded
return (
<StrategiesListView selectedNetwork={params.network} selectedStrategy={params.strategy_id} />
<StrategiesListView selectedNetwork={params.network} selectedStrategyId={params.strategy_id} />
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
max-width: 1200px;
margin: 0 auto;
padding: 0 var(--space-m);
z-index: 2;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type FC, type PropsWithChildren } from 'react'
import { MainBackground } from '@summerfi/app-earn-ui'
import dynamic from 'next/dynamic'

import { NavigationWrapper } from '@/components/layout/Navigation/NavigationWrapper'
Expand Down Expand Up @@ -32,6 +33,7 @@ export const MasterPage: FC<PropsWithChildren<MasterPageProps>> = ({ children })
>
Footer <SetForkModal />
</div>
<MainBackground />
</div>
</>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { useMemo } from 'react'
import { useMemo, useState } from 'react'
import {
DataBlock,
SimpleGrid,
Expand All @@ -9,14 +9,12 @@ import {
StrategySimulationForm,
} from '@summerfi/app-earn-ui'
import { type DropdownOption, type IconNamesList, type NetworkNames } from '@summerfi/app-types'
import Link from 'next/link'
import { useRouter } from 'next/navigation'

import { strategiesList } from '@/constants/dev-strategies-list'

type StrategiesListViewProps = {
selectedNetwork?: NetworkNames | 'all-networks'
selectedStrategy?: string
selectedStrategyId?: string
}

const allNetworksOption = {
Expand All @@ -25,54 +23,87 @@ const allNetworksOption = {
value: 'all-networks',
}

const getStrategyLink = (
strategy: (typeof strategiesList)[number],
selectedNetwork?: StrategiesListViewProps['selectedNetwork'],
) => {
return `/earn/${selectedNetwork ?? 'all-networks'}/${strategy.id}`
const softRouterPush = (url: string) => {
window.history.pushState(null, '', url)
}

export const StrategiesListView = ({
selectedNetwork,
selectedStrategy,
selectedStrategyId,
}: StrategiesListViewProps) => {
const { replace } = useRouter()
const networkFilteredStrategies = useMemo(() => {
return selectedNetwork && selectedNetwork !== 'all-networks'
? strategiesList.filter((strategy) => strategy.network === selectedNetwork)
: strategiesList
}, [selectedNetwork])
const selectedNetworkOption = useMemo(() => {
return selectedNetwork
? {
iconName: 'ether_circle_color' as IconNamesList,
label: selectedNetwork,
value: selectedNetwork,
}
: allNetworksOption
}, [selectedNetwork])
const strategiesNetworksList = useMemo(() => {
return [
const [localStrategyNetwork, setLocalStrategyNetwork] =
useState<StrategiesListViewProps['selectedNetwork']>(selectedNetwork)

const [localStrategyId, setLocalStrategyId] = useState<string | undefined>(selectedStrategyId)

const networkFilteredStrategies = useMemo(
() =>
localStrategyNetwork && localStrategyNetwork !== 'all-networks'
? strategiesList.filter((strategy) => strategy.network === localStrategyNetwork)
: strategiesList,
[localStrategyNetwork],
)

const selectedNetworkOption = useMemo(
() =>
localStrategyNetwork
? {
iconName: 'ether_circle_color' as IconNamesList,
label: localStrategyNetwork,
value: localStrategyNetwork,
}
: allNetworksOption,
[localStrategyNetwork],
)
const strategiesNetworksList = useMemo(
() => [
...[...new Set(strategiesList.map(({ network }) => network))].map((network) => ({
iconName: 'ether_circle_color' as IconNamesList,
label: network,
value: network,
})),
allNetworksOption,
]
}, [])
],
[],
)

const selectedStrategyData = useMemo(() => {
return strategiesList.find((strategy) => strategy.id === selectedStrategy)
}, [selectedStrategy])
const selectedStrategyData = useMemo(
() => strategiesList.find((strategy) => strategy.id === localStrategyId),
[localStrategyId],
)

const handleChangeNetwork = (selected: DropdownOption) => {
if (selected.value === 'all-networks') {
replace('/earn')
setLocalStrategyNetwork(selected.value as StrategiesListViewProps['selectedNetwork'])
switch (selected.value) {
case 'all-networks':
// if its all networks we must check if the selected strategy is from the same network
// then we can "redirect" to the selected strategy page with the network
softRouterPush(
selectedStrategyData ? `/earn/all-networks/${selectedStrategyData.id}` : '/earn',
)

break

default:
// if its a specific network we must check if the selected strategy is from the same network
// then we can "redirect" to the selected strategy page with the network
// if not we just go to the network page and clear the selected strategy (if not available in the new view)
if (selectedStrategyData && selectedStrategyData.network !== selected.value) {
setLocalStrategyId(undefined)
}
softRouterPush(
selectedStrategyData && selectedStrategyData.network === selected.value
? `/earn/${selected.value}/${selectedStrategyData.id}`
: `/earn/${selected.value}`,
)

return
break
}
replace(`/earn/${selected.value}`)
}

const handleChangeStrategy = (strategyId: string) => {
setLocalStrategyId(strategyId)
softRouterPush(`/earn/${localStrategyNetwork ?? 'all-networks'}/${strategyId}`)
}

return (
Expand Down Expand Up @@ -103,19 +134,19 @@ export const StrategiesListView = ({
</SimpleGrid>
}
leftContent={networkFilteredStrategies.map((strategy, strategyIndex) => (
<Link key={strategy.id} href={getStrategyLink(strategy, selectedNetwork)}>
<StrategyCard
{...strategy}
secondary
withHover
selected={
selectedStrategy === strategy.id || (!selectedStrategy && strategyIndex === 0)
}
/>
</Link>
<StrategyCard
key={strategy.id}
{...strategy}
secondary
withHover
selected={localStrategyId === strategy.id || (!localStrategyId && strategyIndex === 0)}
onClick={handleChangeStrategy}
/>
))}
rightContent={
<StrategySimulationForm strategyData={selectedStrategyData ?? strategiesList[0]} />
<StrategySimulationForm
strategyData={selectedStrategyData ?? networkFilteredStrategies[0]}
/>
}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ export const MockedLineChart = () => {
padding: '20px 30px',
border: 'none',
}}
allowEscapeViewBox={{ x: false, y: true }}
/>
{dataNamesParsed.map((dataName, dataIndex) =>
dataName === 'Summer USDS Strategy' ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,10 @@
import { type FC, useMemo } from 'react'
import { Card, DataBlock, Icon, Table, TableCellText, Text, WithArrow } from '@summerfi/app-earn-ui'
import { Card, DataBlock, Table, Text, WithArrow } from '@summerfi/app-earn-ui'
import { type TokenSymbolsList } from '@summerfi/app-types'
import { formatCryptoBalance, timeAgo } from '@summerfi/app-utils'
import BigNumber from 'bignumber.js'
import Link from 'next/link'

const columns = [
{
title: 'Purpose',
key: 'purpose',
sortable: false,
},
{
title: 'Action',
key: 'action',
sortable: false,
},
{
title: 'Amount',
key: 'amount',
sortable: false,
},
{
title: 'Timestamp',
key: 'timestamp',
sortable: false,
},
{
title: 'Provider',
key: 'provider',
sortable: false,
},
]
import { rebalancingActivityColumns } from '@/components/organisms/RebalancingActivity/columns'
import { rebalancingActivityMapper } from '@/components/organisms/RebalancingActivity/mapper'

export interface RebalancingActivityRawData {
type: string
Expand All @@ -44,60 +17,6 @@ export interface RebalancingActivityRawData {
}
}

const rebalancingActivityMapper = (rawData: RebalancingActivityRawData[]) => {
return rawData.map((item) => {
return {
content: {
purpose: (
<div
style={{ display: 'flex', alignItems: 'center', gap: 'var(--spacing-space-x-small)' }}
>
<Icon
iconName={item.type === 'reduce' ? 'arrow_decrease' : 'arrow_increase'}
variant="xxs"
color="rgba(119, 117, 118, 1)"
/>
<TableCellText>{item.type === 'reduce' ? 'Reduce' : 'Increase'} Risk</TableCellText>
</div>
),
action: (
<div
style={{ display: 'flex', alignItems: 'center', gap: 'var(--spacing-space-2x-small)' }}
>
<Icon tokenName={item.action.from} variant="s" /> {item.action.from}
<Icon tokenName={item.action.to} variant="s" /> {item.action.to}
</div>
),
amount: (
<div
style={{ display: 'flex', alignItems: 'center', gap: 'var(--spacing-space-2x-small)' }}
>
<Icon tokenName={item.amount.token} variant="s" />
<TableCellText>{formatCryptoBalance(new BigNumber(item.amount.value))}</TableCellText>
</div>
),
timestamp: (
<TableCellText>
{timeAgo({ from: new Date(), to: new Date(Number(item.timestamp)) })}
</TableCellText>
),
provider: (
<Link href={item.provider.link}>
<WithArrow
as="p"
variant="p3"
style={{ color: 'var(--earn-protocol-primary-100)' }}
reserveSpace
>
{item.provider.label}
</WithArrow>
</Link>
),
},
}
})
}

interface RebalancingActivityProps {
rawData: RebalancingActivityRawData[]
}
Expand Down Expand Up @@ -135,7 +54,7 @@ export const RebalancingActivity: FC<RebalancingActivityProps> = ({ rawData }) =
for reallocating assets from lower performing strategies to higher performing ones, within
a threshold of risk.
</Text>
<Table rows={rows} columns={columns} />
<Table rows={rows} columns={rebalancingActivityColumns} />
<Link href="/" style={{ marginTop: 'var(--spacing-space-large)', width: 'fit-content' }}>
<WithArrow as="p" variant="p4semi" style={{ color: 'var(--earn-protocol-primary-100)' }}>
View all rebalances
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const rebalancingActivityColumns = [
{
title: 'Purpose',
key: 'purpose',
sortable: false,
},
{
title: 'Action',
key: 'action',
sortable: false,
},
{
title: 'Amount',
key: 'amount',
sortable: false,
},
{
title: 'Timestamp',
key: 'timestamp',
sortable: false,
},
{
title: 'Provider',
key: 'provider',
sortable: false,
},
]
Loading

0 comments on commit 280bd65

Please sign in to comment.