Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOV-2469, SOV-2470: implement new funding flow #406

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
6 changes: 6 additions & 0 deletions .changeset/quick-crabs-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"frontend": patch
"@sovryn/ui": patch
---

SOV-2470: send flow mock ui
64 changes: 37 additions & 27 deletions apps/frontend/src/app/3_organisms/FastBtcDialog/FastBtcDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import {
import { useAccount } from '../../../hooks/useAccount';
import { useIsMobile } from '../../../hooks/useIsMobile';
import { translations } from '../../../locales/i18n';
import { isMainnet } from '../../../utils/helpers';
import { BridgeReceiveFlow } from './components/BridgeReceiveFlow';
import { BridgeSendFlow } from './components/BridgeSendFlow';
import { ReceiveFlow } from './components/ReceiveFlow/ReceiveFlow';
import { SendFlow } from './components/SendFlow/SendFlow';

Expand Down Expand Up @@ -43,36 +46,43 @@ export const FastBtcDialog: React.FC<FastBtcDialogProps> = ({
index !== null ? setIndex(index) : setIndex(0);
}, []);

const receiveFlow = useMemo(
() => ({
label: t(translation.tabs.receiveLabel),
infoText: t(translation.tabs.receiveInfoText),
content: isMainnet() ? (
<ReceiveFlow onClose={onClose} />
) : (
<BridgeReceiveFlow onClose={onClose} />
),
activeClassName: ACTIVE_CLASSNAME,
dataAttribute: 'funding-receive',
}),
[onClose],
);

const sendFlow = useMemo(
() => ({
label: t(translation.tabs.sendLabel),
infoText: t(translation.tabs.sendInfoText),
content: isMainnet() ? (
<SendFlow onClose={onClose} />
) : (
<BridgeSendFlow onClose={onClose} />
),
activeClassName: ACTIVE_CLASSNAME,
dataAttribute: 'funding-send',
}),
[onClose],
);

const items = useMemo(() => {
if (shouldHideSend) {
return [
{
label: t(translation.tabs.receiveLabel),
infoText: t(translation.tabs.receiveInfoText),
content: <ReceiveFlow onClose={onClose} />,
activeClassName: ACTIVE_CLASSNAME,
dataAttribute: 'funding-receive',
},
];
return [receiveFlow];
}

return [
{
label: t(translation.tabs.receiveLabel),
infoText: t(translation.tabs.receiveInfoText),
content: <ReceiveFlow onClose={onClose} />,
activeClassName: ACTIVE_CLASSNAME,
dataAttribute: 'funding-receive',
},
{
label: t(translation.tabs.sendLabel),
infoText: t(translation.tabs.sendInfoText),
content: <SendFlow onClose={onClose} />,
activeClassName: ACTIVE_CLASSNAME,
dataAttribute: 'funding-send',
},
];
}, [onClose, shouldHideSend]);
return [receiveFlow, sendFlow];
}, [receiveFlow, shouldHideSend, sendFlow]);

const dialogSize = useMemo(
() => (isMobile ? DialogSize.md : DialogSize.xl2),
Expand All @@ -88,7 +98,7 @@ export const FastBtcDialog: React.FC<FastBtcDialogProps> = ({
<Dialog
isOpen={isOpen}
width={dialogSize}
className="p-4 flex items-center sm:p-0"
className="p-4 flex items-stretch sm:p-0"
disableFocusTrap
closeOnEscape={false}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React, { useCallback, useContext, useMemo, useReducer } from 'react';

import { t } from 'i18next';

import {
Accordion,
AmountInput,
Button,
ButtonStyle,
FormGroup,
Heading,
HeadingType,
Paragraph,
SimpleTable,
SimpleTableRow,
} from '@sovryn/ui';

import { MaxButton } from '../../../../../2_molecules/MaxButton/MaxButton';
import { useAmountInput } from '../../../../../../hooks/useAmountInput';
import { useWeiAmountInput } from '../../../../../../hooks/useWeiAmountInput';
import { translations } from '../../../../../../locales/i18n';
import { ReceiveContext, ReceiveStep } from '../../../contexts/receive-context';
import { getNetwork } from '../../../utils/networks';

const translation = translations.fastBtc.receive.amountFormScreen;

// todo: replace with real data
const policies = [
{
title: t(translation.policies.minimum),
value: '50 BUSD',
},
{
title: t(translation.policies.conversion),
value: '2 BUSD',
},
{
title: t(translation.policies.fee),
value: '3 BUSD',
},
];

export const AmountForm = () => {
const { set, originNetwork, asset } = useContext(ReceiveContext);

const [amount, setAmount] = useWeiAmountInput('0');
const [slippage, setSlippage] = useAmountInput('0.5');

const [slippageOpen, toggleSlippage] = useReducer(v => !v, false);
const [policiesOpen, togglePolicies] = useReducer(v => !v, false);

// todo: replace with real data
const maxAmount = '12.345';
const handleMaxButtonClick = useCallback(
() => setAmount(maxAmount),
[setAmount],
);

const networkName = useMemo(
() => getNetwork(originNetwork!).label,
[originNetwork],
);

const onContinueClick = useCallback(
() =>
set(prevState => ({
...prevState,
step: ReceiveStep.DETAILS,
})),
[set],
);

return (
<div className="text-center">
<Heading type={HeadingType.h2} className="font-medium mb-4">
{t(translation.title, {
network: networkName,
asset: asset.toUpperCase(),
})}
</Heading>
<Paragraph className="mb-8 text-center">
{t(translation.description__dllr, { asset: asset.toUpperCase() })}
</Paragraph>

<FormGroup className="mb-8">
<div className="w-full flex flex-row justify-between gap-4 items-center mb-1">
<Paragraph>{t(translation.amount.title)}</Paragraph>

<MaxButton
onClick={handleMaxButtonClick}
value={maxAmount}
token={asset!}
dataAttribute="funding-receiver-max"
/>
</div>
<AmountInput
value={amount}
onChangeText={setAmount}
placeholder="0.00"
dataAttribute="funding-receiver-amount"
label={t(translation.amount.label)}
/>
</FormGroup>

<Accordion
className="mb-8"
label={t(translation.slippage.title)}
open={slippageOpen}
onClick={toggleSlippage}
>
<FormGroup>
<AmountInput
value={slippage}
onChangeText={setSlippage}
placeholder="%"
dataAttribute="funding-receiver-slippage"
label={t(translation.slippage.label)}
/>
</FormGroup>
</Accordion>

<Accordion
className="mb-8"
label={t(translation.policies.title)}
open={policiesOpen}
onClick={togglePolicies}
>
<SimpleTable>
{policies.map(policy => (
<SimpleTableRow
key={policy.title}
label={policy.title}
value={policy.value}
className="text-left"
/>
))}
</SimpleTable>
</Accordion>

<Heading type={HeadingType.h2} className="text-left mb-2">
{t(translation.summary.title)}
</Heading>

<SimpleTable>
<SimpleTableRow
label={t(translation.summary.expectedToReceive)}
value="500 BUSD"
className="text-left"
valueClassName="text-right text-yellow-1"
/>
<SimpleTableRow
label={t(translation.summary.minimumReceived)}
value="500 BUSD"
className="text-left"
valueClassName="text-right text-yellow-1"
/>
</SimpleTable>

<Button
onClick={onContinueClick}
text={t(translations.common.buttons.continue)}
className="w-full mt-8"
style={ButtonStyle.secondary}
dataAttribute="funding-receiver-sender-asset"
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, { useCallback, useContext, useMemo, useState } from 'react';

import { t } from 'i18next';

import { SupportedTokens } from '@sovryn/contracts';
import {
Align,
Button,
ButtonStyle,
Heading,
HeadingType,
TableBase,
TransactionId,
} from '@sovryn/ui';

import { translations } from '../../../../../../locales/i18n';
import { ReceiveContext, ReceiveStep } from '../../../contexts/receive-context';
import { getNetwork } from '../../../utils/networks';

const translation = translations.fastBtc.receive.assetScreen;

const columns = [
{
id: 'asset',
title: t(translation.table.asset),
align: Align.left,
cellRenderer: row => `${row.asset.toUpperCase()}`,
},
{
id: 'address',
title: t(translation.table.address),
align: Align.center,
cellRenderer: row => (
<TransactionId
href="#"
value={row.address}
dataAttribute={`funding-receive-transaction-id`}
/>
),
},
{
id: 'balance',
title: t(translation.table.balance),
align: Align.right,
cellRenderer: row => `${row.balance} ${row.asset.toUpperCase()}`,
},
];

export const AssetList = () => {
const { set, originNetwork } = useContext(ReceiveContext);

const networkName = useMemo(
() => getNetwork(originNetwork!).label,
[originNetwork],
);

//@TODO: Replace with real data
const walletBalance = [
{
asset: SupportedTokens.bnbs,
address: '0x1234567890123456789012345678901234567890',
balance: 0.2,
},
{
asset: SupportedTokens.dllr,
address: '0x0p42490ACCbc50F4F9c130b5876521I1q7b3C0p',
balance: 1.234,
},
{
asset: SupportedTokens.eths,
address: '0x6p42490ACCbc50F4F9c130b5876521I1q7b3C0p',
balance: 4,
},
{
asset: SupportedTokens.rusdt,
address: '0x6p42490ACCbc50F4F9c130b5876521I1q7b3C0p',
balance: 4,
},
{
asset: SupportedTokens.rdoc,
address: '0x6p42490ACCbc50F4F9c130b5876521I1q7b3C0p',
balance: 4,
},
];

const [selectedAsset, setSelectedAsset] = useState<SupportedTokens>();

const onRowClick = useCallback((row: any) => setSelectedAsset(row.asset), []);

const onContinueClick = useCallback(
() =>
set(prevState => ({
...prevState,
step: ReceiveStep.AMOUNT,
asset: selectedAsset!,
})),
[selectedAsset, set],
);

return (
<div className="text-center">
<Heading type={HeadingType.h2} className="font-medium mb-8">
{t(translation.title, { network: networkName })}
</Heading>

<TableBase
columns={columns}
rows={walletBalance}
dataAttribute="funding-receiver-asset-table"
onRowClick={onRowClick}
isClickable
/>

<Button
onClick={onContinueClick}
text={t(translations.common.buttons.continue)}
className="w-full mt-8"
style={ButtonStyle.secondary}
dataAttribute="funding-receiver-sender-asset"
disabled={!selectedAsset}
/>
</div>
);
};
Loading