-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from secretkeylabs/imamahzafar/feat/stacking
Add stacking screen
- Loading branch information
Showing
11 changed files
with
446 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { useQueries } from '@tanstack/react-query'; | ||
import { useCallback } from 'react'; | ||
import { | ||
fetchDelegationState, fetchPoolStackerInfo, fetchStackingPoolInfo, getStacksInfo, StackingData, | ||
} from '@secretkeylabs/xverse-core'; | ||
import useWalletSelector from './useWalletSelector'; | ||
|
||
const useStackingData = () => { | ||
const { stxAddress, network } = useWalletSelector(); | ||
|
||
const results = useQueries({ | ||
queries: [ | ||
{ | ||
queryKey: ['stacking-core-info', network], | ||
queryFn: () => getStacksInfo(network.address), | ||
}, | ||
{ | ||
queryKey: ['stacking-delegation-state', stxAddress, network], | ||
queryFn: () => fetchDelegationState(stxAddress, network), | ||
}, | ||
{ | ||
queryKey: ['stacking-pool-info'], | ||
queryFn: () => fetchStackingPoolInfo(), | ||
}, | ||
{ | ||
queryKey: ['pool-stacker-info', stxAddress], | ||
queryFn: () => fetchPoolStackerInfo(stxAddress), | ||
}, | ||
], | ||
}); | ||
|
||
const coreInfoData = results[0].data; | ||
const delegationStateData = results[1].data; | ||
const poolInfoData = results[2].data; | ||
const stackerInfoData = results[3].data; | ||
|
||
const isStackingLoading = results.some((result) => result.isLoading); | ||
const stackingError = results.find(({ error }) => error != null)?.error; | ||
const refetchStackingData = useCallback(() => { | ||
results.forEach((result) => result.refetch()); | ||
}, [results]); | ||
|
||
const stackingData: StackingData = { | ||
poolInfo: poolInfoData, | ||
delegationInfo: delegationStateData!, | ||
coreInfo: coreInfoData!, | ||
stackerInfo: stackerInfoData, | ||
}; | ||
|
||
return { | ||
isStackingLoading, | ||
stackingError, | ||
stackingData, | ||
refetchStackingData, | ||
}; | ||
}; | ||
|
||
export default useStackingData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { useNavigate } from 'react-router-dom'; | ||
import { Ring } from 'react-spinners-css'; | ||
import { useEffect, useState } from 'react'; | ||
import styled from 'styled-components'; | ||
import useStackingData from '@hooks/useStackingData'; | ||
import useWalletSelector from '@hooks/useWalletSelector'; | ||
import AccountRow from '@components/accountRow'; | ||
import BottomBar from '@components/tabBar'; | ||
import StackingProgress from './stackingProgress'; | ||
import StartStacking from './startStacking'; | ||
|
||
const SelectedAccountContainer = styled.div((props) => ({ | ||
marginLeft: props.theme.spacing(8), | ||
marginRight: props.theme.spacing(8), | ||
})); | ||
|
||
const LoaderContainer = styled.div((props) => ({ | ||
display: 'flex', | ||
flex: 1, | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
marginTop: props.theme.spacing(12), | ||
})); | ||
|
||
function Stacking() { | ||
const { selectedAccount } = useWalletSelector(); | ||
const { isStackingLoading, stackingData } = useStackingData(); | ||
const navigate = useNavigate(); | ||
const [isStacking, setIsStacking] = useState<boolean>(false); | ||
const handleAccountSelect = () => { | ||
navigate('/account-list'); | ||
}; | ||
|
||
useEffect(() => { | ||
if (stackingData) { | ||
if (stackingData?.stackerInfo?.stacked || stackingData?.delegationInfo?.delegated) { | ||
setIsStacking(true); | ||
} | ||
} | ||
}, [stackingData]); | ||
|
||
const showStatus = !isStackingLoading && ( | ||
isStacking ? <StackingProgress /> : <StartStacking /> | ||
); | ||
|
||
return ( | ||
<> | ||
<SelectedAccountContainer> | ||
<AccountRow account={selectedAccount!} isSelected onAccountSelected={handleAccountSelect} /> | ||
</SelectedAccountContainer> | ||
{isStackingLoading && ( | ||
<LoaderContainer> | ||
<Ring color="white" size={30} /> | ||
</LoaderContainer> | ||
) } | ||
{showStatus} | ||
<BottomBar tab="stacking" /> | ||
</> | ||
|
||
); | ||
} | ||
|
||
export default Stacking; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { useTranslation } from 'react-i18next'; | ||
import styled from 'styled-components'; | ||
import StackingStatusTile from './stackingStatusTile'; | ||
|
||
const Container = styled.div((props) => ({ | ||
display: 'flex', | ||
flex: 1, | ||
flexDirection: 'column', | ||
margin: props.theme.spacing(8), | ||
borderTop: `1px solid ${props.theme.colors.background.elevation3}`, | ||
})); | ||
|
||
const TitleText = styled.h1((props) => ({ | ||
...props.theme.headline_s, | ||
marginTop: props.theme.spacing(16), | ||
})); | ||
|
||
const StackingDescriptionText = styled.h1((props) => ({ | ||
...props.theme.body_m, | ||
marginTop: props.theme.spacing(4), | ||
marginBottom: props.theme.spacing(18), | ||
color: props.theme.colors.white['200'], | ||
})); | ||
function StackingProgress() { | ||
const { t } = useTranslation('translation', { keyPrefix: 'STACKING_SCREEN' }); | ||
|
||
return ( | ||
<Container> | ||
<TitleText>{t('STACK_FOR_REWARD')}</TitleText> | ||
<StackingDescriptionText>{t('XVERSE_POOL')}</StackingDescriptionText> | ||
<StackingStatusTile /> | ||
</Container> | ||
); | ||
} | ||
|
||
export default StackingProgress; |
106 changes: 106 additions & 0 deletions
106
src/app/screens/stacking/stackingProgress/stackingStatusTile.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import styled from 'styled-components'; | ||
import TokenTicker from '@assets/img/stacking/token_ticker.svg'; | ||
import { useTranslation } from 'react-i18next'; | ||
import useStackingData from '@hooks/useStackingData'; | ||
import { StackingState } from '@secretkeylabs/xverse-core/stacking'; | ||
import { useEffect, useState } from 'react'; | ||
import { XVERSE_WEB_POOL_URL } from '@utils/constants'; | ||
|
||
const Container = styled.button((props) => ({ | ||
display: 'flex', | ||
flexDirection: 'row', | ||
justifyContent: 'space-between', | ||
alignItems: 'center', | ||
background: props.theme.colors.background.elevation1, | ||
borderRadius: props.theme.radius(2), | ||
padding: props.theme.spacing(9), | ||
})); | ||
|
||
const TextContainer = styled.div({ | ||
display: 'flex', | ||
flexDirection: 'row', | ||
flex: 1, | ||
}); | ||
|
||
const StatusContainer = styled.div((props) => ({ | ||
display: 'flex', | ||
flexDirection: 'row', | ||
justifyContent: 'space-between', | ||
alignItems: 'center', | ||
background: 'rgba(81, 214, 166, 0.15)', | ||
borderRadius: props.theme.radius(7), | ||
paddingLeft: props.theme.spacing(6), | ||
paddingRight: props.theme.spacing(6), | ||
paddingTop: props.theme.spacing(2), | ||
paddingBottom: props.theme.spacing(2), | ||
})); | ||
|
||
const Dot = styled.div((props) => ({ | ||
width: 7, | ||
height: 7, | ||
borderRadius: props.theme.radius(9), | ||
marginRight: props.theme.spacing(4), | ||
background: props.theme.colors.feedback.success, | ||
})); | ||
|
||
const ColumnContainer = styled.div((props) => ({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'flex-start', | ||
marginLeft: props.theme.spacing(6), | ||
})); | ||
|
||
const BoldText = styled.h1((props) => ({ | ||
...props.theme.body_bold_m, | ||
color: props.theme.colors.white['0'], | ||
})); | ||
|
||
const SubText = styled.h1((props) => ({ | ||
...props.theme.body_xs, | ||
color: props.theme.colors.white['400'], | ||
})); | ||
|
||
const StatusText = styled.h1((props) => ({ | ||
...props.theme.body_xs, | ||
fontWeight: 500, | ||
color: props.theme.colors.white['0'], | ||
})); | ||
|
||
function StackingStatusTile() { | ||
const { t } = useTranslation('translation', { keyPrefix: 'STACKING_SCREEN' }); | ||
const { stackingData } = useStackingData(); | ||
const [status, setStatus] = useState<StackingState>('Pending'); | ||
|
||
useEffect(() => { | ||
if (stackingData) { | ||
if (!stackingData?.stackerInfo?.stacked && stackingData?.delegationInfo?.delegated) { | ||
setStatus('Delegated'); | ||
} else if (stackingData?.stackerInfo?.stacked) { setStatus('Stacking'); } | ||
} | ||
}, [stackingData]); | ||
|
||
const handleOnClick = () => { | ||
window.open(XVERSE_WEB_POOL_URL); | ||
}; | ||
|
||
return ( | ||
<Container onClick={handleOnClick}> | ||
<TextContainer> | ||
<img src={TokenTicker} alt="Ticker" /> | ||
<ColumnContainer> | ||
<BoldText>{t('STACK_STX')}</BoldText> | ||
<SubText>{t('EARN_BTC')}</SubText> | ||
</ColumnContainer> | ||
</TextContainer> | ||
|
||
<StatusContainer> | ||
<Dot /> | ||
<StatusText> | ||
{status === 'Stacking' ? t('IN_PROGRESS') : t('DELEGATED')} | ||
</StatusText> | ||
</StatusContainer> | ||
</Container> | ||
); | ||
} | ||
|
||
export default StackingStatusTile; |
Oops, something went wrong.