Skip to content

Commit

Permalink
Rays banners overview omni (#3953)
Browse files Browse the repository at this point in the history
  • Loading branch information
piekczyk authored Jun 18, 2024
1 parent 83ec869 commit 043359f
Show file tree
Hide file tree
Showing 14 changed files with 430 additions and 8 deletions.
102 changes: 102 additions & 0 deletions components/RaysSidebarBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Icon } from 'components/Icon'
import { getGradientColor } from 'helpers/getGradientColor'
import type { FC } from 'react'
import React from 'react'
import { clock_colorful, rays } from 'theme/icons'
import { Flex, Text } from 'theme-ui'

interface RaysSidebarBannerProps {
title: string
description?: string
list?: string[]
daysLeft?: string
items?: { title: string; action: () => void }[]
}

export const RaysSidebarBanner: FC<RaysSidebarBannerProps> = ({
title,
description,
daysLeft,
items,
}) => {
return (
<Flex sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
<Flex sx={{ flexDirection: 'column', rowGap: 2 }}>
<Text
as="p"
variant="paragraph3"
sx={{
fontWeight: 'semiBold',
...getGradientColor(
'linear-gradient(270.13deg, #007DA3 0.02%, #E7A77F 56.92%, #E97047 98.44%)',
),
display: 'flex',
alignItems: 'center',
columnGap: 2,
}}
>
<Icon icon={rays} size={24} />
{title}
</Text>
{description && (
<Text as="p" variant="paragraph3" color="neutral80" sx={{ mb: 2 }}>
{description}
</Text>
)}
{items && (
<Flex sx={{ flexWrap: 'wrap', ml: 4, mb: 2 }}>
{items.map((item) => (
<Text
key={item.title}
as="p"
variant="paragraph3"
onClick={item.action}
sx={{
fontWeight: 'semiBold',
cursor: 'pointer',
display: 'flex',
width: '50%',
color: 'neutral80',
'&:hover': {
color: 'primary100',
},
}}
>
{item.title}
</Text>
))}
</Flex>
)}
</Flex>
{daysLeft && (
<Flex
sx={{
alignItems: 'center',
backgroundColor: '#F2F3F4',
paddingY: 2,
paddingLeft: 2,
paddingRight: 3,
borderRadius: '100px',
height: 'fit-content',
}}
>
<Text
variant="paragraph3"
sx={{
fontWeight: 'semiBold',
...getGradientColor(
'linear-gradient(270.13deg, #007DA3 0.02%, #E7A77F 56.92%, #E97047 98.44%)',
),
display: 'flex',
alignItems: 'center',
columnGap: '5px',
}}
>
<Icon icon={clock_colorful} size={21} />
{daysLeft} days left
</Text>
</Flex>
)}
</Flex>
)
}
2 changes: 2 additions & 0 deletions components/sidebar/SidebarSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export function SidebarSection({
dropdown,
headerButton,
content,
aboveButton,
primaryButton,
secondaryButton,
textButton,
Expand Down Expand Up @@ -66,6 +67,7 @@ export function SidebarSection({
disableMaxHeight={disableMaxHeight}
/>
<SidebarSectionFooter
aboveButton={aboveButton}
primaryButton={primaryButton}
secondaryButton={secondaryButton}
textButton={textButton}
Expand Down
4 changes: 4 additions & 0 deletions components/sidebar/SidebarSectionFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { NetworkConfigHexId } from 'blockchain/networks'
import { useConnection, useWalletManagement } from 'features/web3OnBoard/useConnection'
import { useTranslation } from 'next-i18next'
import type { ReactNode } from 'react'
import React, { useMemo } from 'react'
import { Grid } from 'theme-ui'

Expand All @@ -12,6 +13,7 @@ import { SidebarSectionStatus } from './SidebarSectionStatus'
export type SidebarSectionFooterButtonSettings = Omit<SidebarSectionFooterButtonProps, 'variant'>

export interface SidebarSectionFooterProps {
aboveButton?: ReactNode
primaryButton: SidebarSectionFooterButtonSettings
secondaryButton?: SidebarSectionFooterButtonSettings
textButton?: SidebarSectionFooterButtonSettings
Expand Down Expand Up @@ -95,6 +97,7 @@ function useResolvePrimaryButton({
}

export function SidebarSectionFooter({
aboveButton,
primaryButton,
secondaryButton,
textButton,
Expand Down Expand Up @@ -123,6 +126,7 @@ export function SidebarSectionFooter({
borderTop: 'lightMuted',
}}
>
{aboveButton}
<SidebarSectionFooterButton {...resolvedPrimaryButton} />
{secondaryButton && <SidebarSectionFooterButton variant="secondary" {...secondaryButton} />}
{textButton && <SidebarSectionFooterButton variant="textual" {...textButton} />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { AutomationMetadataFlags } from 'features/omni-kit/types'
import { countBooleanValues } from 'helpers/countBooleanValues'

export const getNumberOfActiveTriggers = ({ flags }: { flags: AutomationMetadataFlags }) => {
const { trueCount } = countBooleanValues(flags)

return trueCount
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { RaysSidebarBanner } from 'components/RaysSidebarBanner'
import { TriggerAction } from 'helpers/lambda/triggers'
import { useTranslation } from 'next-i18next'
import React from 'react'

export const getOmniAutomationSidebarRaysBanner = ({
activeTriggersNumber,
action,
}: {
activeTriggersNumber: number
action: TriggerAction
}) => {
const { t } = useTranslation()

if (activeTriggersNumber === 0) {
return (
<RaysSidebarBanner
title={t('rays.sidebar.banner.boost.title', { rays: '12345' })}
description={t('rays.sidebar.banner.boost.description')}
/>
)
}

if ([TriggerAction.Add, TriggerAction.Update].includes(action)) {
return <RaysSidebarBanner title={t('rays.sidebar.banner.auto-ongoing.title')} />
}

if (action === TriggerAction.Remove) {
return (
<RaysSidebarBanner
title={t('rays.sidebar.banner.reduceAuto.title', { rays: '12345' })}
description={t('rays.sidebar.banner.reduceAuto.description')}
/>
)
}

return null
}
58 changes: 58 additions & 0 deletions features/omni-kit/helpers/getOmniSidebarRaysBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { RaysSidebarBanner } from 'components/RaysSidebarBanner'
import { VaultViewMode } from 'components/vault/GeneralManageTabBar.types'
import type { OmniSidebarBorrowPanel, OmniSidebarEarnPanel } from 'features/omni-kit/types'
import { OmniMultiplyPanel } from 'features/omni-kit/types'
import { useHash } from 'helpers/useHash'
import { useTranslation } from 'next-i18next'
import React from 'react'

export const getOmniSidebarRaysBanner = ({
isOpening,
uiDropdown,
isSupportingOptimization,
isSupportingProtection,
}: {
isOpening: boolean
uiDropdown: OmniMultiplyPanel | OmniSidebarEarnPanel | OmniSidebarBorrowPanel
isSupportingOptimization: boolean
isSupportingProtection: boolean
}) => {
const [, setHash] = useHash<string>()
const { t } = useTranslation()

if (isOpening) {
return (
<RaysSidebarBanner
title={t('rays.sidebar.banner.instant.title', { rays: '12345' })}
description={t('rays.sidebar.banner.instant.description', { raysPerYear: '12345' })}
/>
)
}

// OmniMultiplyPanel.Close and OmniBorrowPanel.Close are the same
if (uiDropdown === OmniMultiplyPanel.Close) {
return (
<RaysSidebarBanner
title={t('rays.sidebar.banner.closing.title', { rays: '12345' })}
description={t('rays.sidebar.banner.closing.description', { raysPerYear: '12345' })}
daysLeft="2"
/>
)
}

if (isSupportingOptimization || isSupportingProtection) {
return (
<RaysSidebarBanner
title={t('rays.sidebar.banner.boost.title', { rays: '12345' })}
items={[
{ title: 'Stop Loss →', action: () => setHash(VaultViewMode.Protection) },
{ title: 'Auto Sell →', action: () => setHash(VaultViewMode.Protection) },
{ title: 'Take Profit →', action: () => setHash(VaultViewMode.Optimization) },
{ title: 'Auto Buy →', action: () => setHash(VaultViewMode.Optimization) },
]}
/>
)
}

return null
}
16 changes: 9 additions & 7 deletions features/omni-kit/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,16 @@ export interface OmniSupplyMetadataHandlers {
customReset?: () => void
}

export interface AutomationMetadataFlags {
isStopLossEnabled: boolean
isTrailingStopLossEnabled: boolean
isAutoSellEnabled: boolean
isAutoBuyEnabled: boolean
isPartialTakeProfitEnabled: boolean
}

export interface AutomationMetadataValues {
flags: {
isStopLossEnabled: boolean
isTrailingStopLossEnabled: boolean
isAutoSellEnabled: boolean
isAutoBuyEnabled: boolean
isPartialTakeProfitEnabled: boolean
}
flags: AutomationMetadataFlags
triggers: {
[AutomationFeatures.STOP_LOSS]?: StopLossTriggersWithDecodedParams
[AutomationFeatures.TRAILING_STOP_LOSS]?: TrailingStopLossTriggersWithDecodedParams
Expand Down
9 changes: 9 additions & 0 deletions features/omni-kit/views/OmniAutomationFormView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { SidebarSectionProps } from 'components/sidebar/SidebarSection'
import { SidebarSection } from 'components/sidebar/SidebarSection'
import type { SidebarSectionHeaderDropdown } from 'components/sidebar/SidebarSectionHeader'
import { isOmniAutomationFormValid } from 'features/omni-kit/automation/helpers'
import { getNumberOfActiveTriggers } from 'features/omni-kit/automation/helpers/getNumberOfActiveTriggers'
import { getOmniAutomationSidebarRaysBanner } from 'features/omni-kit/automation/helpers/getOmniAutomationSidebarRaysBanner'
import { useOmniAutomationTxHandler } from 'features/omni-kit/automation/hooks/useOmniAutomationTxHandler'
import { useOmniGeneralContext, useOmniProductContext } from 'features/omni-kit/contexts'
import {
Expand All @@ -14,6 +16,7 @@ import {
import { useOmniAutomationSidebarTitle } from 'features/omni-kit/hooks'
import { OmniSidebarAutomationStep } from 'features/omni-kit/types'
import { useConnection } from 'features/web3OnBoard/useConnection'
import { getLocalAppConfig } from 'helpers/config'
import { TriggerAction } from 'helpers/lambda/triggers'
import { useAccount } from 'helpers/useAccount'
import { LendingProtocolLabel } from 'lendingProtocols'
Expand Down Expand Up @@ -91,9 +94,12 @@ export function OmniAutomationFormView({

const { connect, setChain } = useConnection()
const { walletAddress } = useAccount()
const { Rays } = getLocalAppConfig('features')

const genericSidebarTitle = useOmniAutomationSidebarTitle()

const activeTriggersNumber = getNumberOfActiveTriggers({ flags: automation.flags })

const {
isPrimaryButtonDisabled,
isPrimaryButtonHidden,
Expand Down Expand Up @@ -189,6 +195,9 @@ export function OmniAutomationFormView({
title: sidebarTitle ?? genericSidebarTitle,
dropdown,
content: <Grid gap={3}>{children}</Grid>,
aboveButton: Rays
? getOmniAutomationSidebarRaysBanner({ action: state.action, activeTriggersNumber })
: null,
primaryButton: {
label: t(primaryButtonLabel),
disabled: suppressValidation || isTxSuccess ? false : isPrimaryButtonDisabled,
Expand Down
22 changes: 21 additions & 1 deletion features/omni-kit/views/OmniFormView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
VaultChangesInformationItem,
} from 'components/vault/VaultChangesInformation'
import { ethers } from 'ethers'
import { isSupportingAutomation } from 'features/omni-kit/automation/helpers'
import { OmniDupePositionModal } from 'features/omni-kit/components'
import { useOmniGeneralContext, useOmniProductContext } from 'features/omni-kit/contexts'
import {
Expand All @@ -18,6 +19,7 @@ import {
getOmniSidebarPrimaryButtonActions,
getOmniSidebarTransactionStatus,
} from 'features/omni-kit/helpers'
import { getOmniSidebarRaysBanner } from 'features/omni-kit/helpers/getOmniSidebarRaysBanner'
import { useOmniProductTypeTransition, useOmniSidebarTitle } from 'features/omni-kit/hooks'
import { OmniSidebarStep } from 'features/omni-kit/types'
import { useConnection } from 'features/web3OnBoard/useConnection'
Expand Down Expand Up @@ -67,6 +69,7 @@ export function OmniFormView({
settings,
shouldSwitchNetwork,
positionId,
poolId,
},
steps: {
currentStep,
Expand Down Expand Up @@ -106,7 +109,7 @@ export function OmniFormView({
const { walletAddress } = useAccount()
const { openModal } = useModalContext()
const [hasDupePosition, setHasDupePosition] = useState<boolean>(false)
const { OmniKitDebug } = getLocalAppConfig('features')
const { OmniKitDebug, Rays } = getLocalAppConfig('features')

const genericSidebarTitle = useOmniSidebarTitle()

Expand Down Expand Up @@ -270,9 +273,26 @@ export function OmniFormView({
txDetails,
})

const { isSupportingOptimization, isSupportingProtection } = isSupportingAutomation({
collateralToken,
networkId,
poolId,
protocol,
quoteToken,
settings,
})

const sidebarSectionProps: SidebarSectionProps = {
title: sidebarTitle ?? genericSidebarTitle,
dropdown,
aboveButton: Rays
? getOmniSidebarRaysBanner({
isOpening,
uiDropdown: state.uiDropdown,
isSupportingOptimization,
isSupportingProtection,
})
: null,
content: (
<Grid gap={3}>
{sidebarContent}
Expand Down
Loading

0 comments on commit 043359f

Please sign in to comment.