Skip to content

Commit

Permalink
fix: refactor, handle process section
Browse files Browse the repository at this point in the history
  • Loading branch information
galvin96 committed Dec 31, 2024
1 parent c74d02e commit 2985bd6
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 63 deletions.
8 changes: 8 additions & 0 deletions src/assets/images/dex-v2/documents.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/assets/images/dex-v2/loading.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 54 additions & 2 deletions src/pages/DexV2/Lock/LockProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,68 @@
import { Currency } from "@ixswap1/sdk-core"
import { createContext, PropsWithChildren, useContext, useState } from "react"
import { createContext, PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from "react"
import { utils } from 'ethers'
import { useVotingEscrowContract } from "hooks/useContract"
import useIXSCurrency from "hooks/useIXSCurrency"
import { useTransactionAdder } from "state/transactions/hooks"
import { safeParseUnits } from "utils/formatCurrencyAmount"
import { WEEK } from "./constants"
import { ApprovalState, useAllowance } from "hooks/useApproveCallback"
import { useWeb3React } from "hooks/useWeb3React"
import { IXS_ADDRESS, VOTING_ESCROW_ADDRESS } from 'constants/addresses'

export type UseLockResult = ReturnType<typeof _useLock>
export const LockContext = createContext<UseLockResult | null>(null)

export function _useLock() {
const [userInput, setUserInput] = useState('')
const [duration, setDuration] = useState(604800) // 7 days
const [locking, setLocking] = useState(false)
const [locked, setLocked] = useState(false)

const votingEscrowContract = useVotingEscrowContract()
const addTransaction = useTransactionAdder()
const currency = useIXSCurrency()

const handleLock = useCallback(async () => {
setLocking(true)
try {
const tx = await votingEscrowContract?.createLock(
safeParseUnits(+userInput, currency?.decimals),
duration,
)
await tx.wait()

if (!tx.hash) return
setLocked(true)
addTransaction(tx, {
summary: `Lock ${userInput} IXS in ${ Math.round(duration / WEEK) } weeks`,
})
} finally {
setLocking(false)
}
}, [userInput, duration, votingEscrowContract, addTransaction, currency])

const { chainId } = useWeb3React()
const [approvalState, approve] = useAllowance(
IXS_ADDRESS[chainId],
utils.parseUnits(userInput || '0', currency?.decimals),
VOTING_ESCROW_ADDRESS[chainId]
)

const step = useMemo(() => {
if (locked) return 3
if (locking) return 2
if (approvalState === ApprovalState.PENDING || approvalState === ApprovalState.APPROVED) return 1
return 0
}, [approvalState, locking, locked])

return {
userInput, setUserInput,
duration, setDuration,
locking,
locked,
handleLock,
step,
approvalState, approve,
}
}

Expand Down
59 changes: 27 additions & 32 deletions src/pages/DexV2/Lock/components/LockContent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useMemo, useState } from 'react'
import { useConnectModal } from '@rainbow-me/rainbowkit'
import { utils } from 'ethers'
import { Flex } from 'rebass'
import { Currency, CurrencyAmount } from '@ixswap1/sdk-core'
import styled from 'styled-components'
import { Line } from '../../Pool/Create'
import { useWeb3React } from 'hooks/useWeb3React'
import CurrencyInput from './CurrencyInput'
Expand All @@ -11,33 +11,24 @@ import { maxAmountSpend } from 'utils/maxAmountSpend'
import { useCurrencyBalance } from 'state/wallet/hooks'
import DurationSlider from './DurationSlider'
import LockExplanation from './LockExplanation'
import { ApprovalState, useAllowance } from 'hooks/useApproveCallback'
import { IXS_ADDRESS, VOTING_ESCROW_ADDRESS } from 'constants/addresses'
import { ApprovalState } from 'hooks/useApproveCallback'
import useIXSCurrency from 'hooks/useIXSCurrency'
import { PinnedContentButton } from 'components/Button'
import { useVotingEscrowContract } from 'hooks/useContract'
import { safeParseUnits } from 'utils/formatCurrencyAmount'
import { useTransactionAdder } from 'state/transactions/hooks'
import { WEEK } from '../constants'
import { ReactComponent as CheckedIcon } from 'assets/images/checked-green.svg'

const LockContent: React.FC = () => {
const [isLoading, setIsLoading] = useState(false)
const {
userInput,
setUserInput,
duration,
handleLock,
approvalState,
approve,
locked,
} = useLock()
const currency = useIXSCurrency()
const { account, chainId } = useWeb3React()
const { account } = useWeb3React()
const { openConnectModal } = useConnectModal()
const votingEscrowContract = useVotingEscrowContract()
const addTransaction = useTransactionAdder()

const [approvalState, approve] = useAllowance(
IXS_ADDRESS[chainId],
utils.parseUnits(userInput || '0', currency?.decimals),
VOTING_ESCROW_ADDRESS[chainId]
)

const primaryButtonLabel = useMemo(() => {
if (!account) {
Expand All @@ -46,21 +37,16 @@ const LockContent: React.FC = () => {
return 'Processing...'
} else if (approvalState !== ApprovalState.APPROVED) {
return 'Allow IXS'
} else if (locked) {
return (
<Flex alignItems='center' style={{ gap: 6 }}>
<CheckedIcon />
Lock Created
</Flex>
)
}
return 'Lock'
}, [account, approvalState])

async function handleLock() {
const tx = await votingEscrowContract?.createLock(
safeParseUnits(+userInput, currency?.decimals),
duration,
)
await tx.wait()
if (!tx.hash) return
addTransaction(tx, {
summary: `Lock ${userInput} IXS in ${ Math.round(duration / WEEK) } weeks`,
})
}
}, [account, approvalState, locked, isLoading])

async function handleProceed() {
try {
Expand Down Expand Up @@ -99,15 +85,24 @@ const LockContent: React.FC = () => {

<LockExplanation />

<PinnedContentButton
<StyledPrimaryButton
onClick={() => handleProceed()}
type="button"
disabled={approvalState === ApprovalState.PENDING || isLoading || !userInput}
locked={locked}
>
{primaryButtonLabel}
</PinnedContentButton>
</StyledPrimaryButton>
</Flex>
)
}

const StyledPrimaryButton = styled(PinnedContentButton)<{ locked: boolean }>`
${({ locked, theme }) => (locked && `
background-color: ${ theme.green51 };
color: ${ theme.green5 };
border: 1px solid ${ theme.green5 };
`)}
`

export default LockContent
37 changes: 22 additions & 15 deletions src/pages/DexV2/Lock/components/VerticleSteps.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import React from 'react'
import styled from 'styled-components'
import { StepIds, StepLabels } from '../types'
import { createLockSteps } from '../constants/processes'
import { useLock } from '../LockProvider'

interface VerticleStepsProps {
}

const VerticleSteps: React.FC<VerticleStepsProps> = () => {
const activeStep = StepIds.NotGranted
const steps: { [key in StepIds]: StepLabels } = {
[StepIds.NotGranted]: StepLabels.NotGranted,
[StepIds.Granting]: StepLabels.Granting,
[StepIds.Locking]: StepLabels.Locking,
[StepIds.Completed]: StepLabels.Completed,
}
const { step } = useLock()

return (
<Container>
{Object.entries(steps).map(([key, step], index) => (
<Step key={key}>
<Circle isActive={index === activeStep}>{index + 1}</Circle>
<StepLabel isActive={index === activeStep}>{step}</StepLabel>
</Step>
))}
{createLockSteps.map(({ label, icon }, index) => {
const Icon = icon
const isActive = step >= index
return (
<Step key={label}>
<Circle isActive={isActive}>
<Icon />
</Circle>
<StepLabel isActive={isActive}>{label}</StepLabel>
</Step>
)
})}
</Container>
)
}
Expand All @@ -44,12 +45,18 @@ const Circle = styled.div<{ isActive: boolean }>`
width: 32px;
height: 32px;
border-radius: 50%;
background-color: ${({ isActive }) => (isActive ? '#007bff' : 'rgba(102, 102, 255, 0.20)')};
background-color: ${({ isActive, theme }) => (isActive ? theme.bg26 : theme.white)};
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
svg {
path {
stroke: ${({ isActive, theme }) => (isActive ? theme.white : theme.blue5)};
}
}
`

const StepLabel = styled.div<{ isActive: boolean }>`
Expand Down
38 changes: 38 additions & 0 deletions src/pages/DexV2/Lock/constants/processes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

import { ReactComponent as LockIcon } from 'assets/images/dex-v2/lock.svg'
import { ReactComponent as DocumentsIcon } from 'assets/images/dex-v2/documents.svg'
import { ReactComponent as LoadingIcon } from 'assets/images/dex-v2/loading.svg'
import { ReactComponent as CheckOutline } from 'assets/images/check-success.svg'
import { FunctionComponent, SVGProps } from 'react'

export type Step = {
label: string,
icon: FunctionComponent<SVGProps<SVGSVGElement>>,
}

const NotGranted: Step = {
label: 'Allowance not granted for IXS',
icon: LockIcon,
}

const Granting: Step = {
label: 'Contracts to access IXS',
icon: DocumentsIcon,
}

const Locking: Step = {
label: 'Waiting for pending actions',
icon: LoadingIcon,
}

const Completed: Step = {
label: 'Lock Created',
icon: CheckOutline,
}

export const createLockSteps = [
NotGranted,
Granting,
Locking,
Completed,
]
14 changes: 0 additions & 14 deletions src/pages/DexV2/Lock/types/index.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/theme/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ export function colors(configColors?: WlColors): Colors {
green2: '#9DF9B1B2',
green3: '#9DF9B1B3',
green4: '#24E49F',
green5: '#1FBA66',
green51: '#1FBA661A',
yellow1: '#e3a507',
yellow2: '#ff8f00',
yellow3: '#F3B71E',
Expand Down
2 changes: 2 additions & 0 deletions src/theme/styled.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export interface Colors {
green2: Color
green3: Color
green4: Color
green5: Color
green51: Color
yellow1: Color
yellow2: Color
yellow3: Color
Expand Down

0 comments on commit 2985bd6

Please sign in to comment.