1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

refactor to use Formik for better live validation

This commit is contained in:
Matthias Kretschmann 2020-10-15 13:47:03 +02:00
parent 8bec69986c
commit 5a7955f7aa
Signed by: m
GPG Key ID: 606EEEF3C479A91F

View File

@ -12,7 +12,9 @@ import Actions from './Actions'
import Tooltip from '../../../atoms/Tooltip' import Tooltip from '../../../atoms/Tooltip'
import { ReactComponent as Caret } from '../../../../images/caret.svg' import { ReactComponent as Caret } from '../../../../images/caret.svg'
import { graphql, useStaticQuery } from 'gatsby' import { graphql, useStaticQuery } from 'gatsby'
import FormHelp from '../../../atoms/Input/Help' import * as Yup from 'yup'
import { Field, Formik } from 'formik'
import Input from '../../../atoms/Input'
const contentQuery = graphql` const contentQuery = graphql`
query PoolAddQuery { query PoolAddQuery {
@ -37,6 +39,10 @@ const contentQuery = graphql`
} }
` `
const initialValues: Partial<{ amount: number }> = {
amount: 1
}
export default function Add({ export default function Add({
setShowAdd, setShowAdd,
poolAddress, poolAddress,
@ -58,21 +64,12 @@ export default function Add({
const content = data.content.edges[0].node.childContentJson.pool.add const content = data.content.edges[0].node.childContentJson.pool.add
const { ocean, accountId, balance } = useOcean() const { ocean, accountId, balance } = useOcean()
const [amount, setAmount] = useState('')
const [txId, setTxId] = useState<string>('') const [txId, setTxId] = useState<string>('')
const [isLoading, setIsLoading] = useState<boolean>() const [isLoading, setIsLoading] = useState<boolean>()
const [coin, setCoin] = useState<string>('OCEAN') const [coin, setCoin] = useState<string>('OCEAN')
const [dtBalance, setDtBalance] = useState<string>() const [dtBalance, setDtBalance] = useState<string>()
const [amountMax, setAmountMax] = useState<string>() const [amountMax, setAmountMax] = useState<string>()
const newPoolTokens =
totalBalance &&
((Number(amount) / Number(totalBalance.ocean)) * 100).toFixed(2)
const newPoolShare =
totalBalance &&
((Number(newPoolTokens) / Number(totalPoolTokens)) * 100).toFixed(2)
// Get datatoken balance when datatoken selected // Get datatoken balance when datatoken selected
useEffect(() => { useEffect(() => {
if (!ocean || coin === 'OCEAN') return if (!ocean || coin === 'OCEAN') return
@ -98,16 +95,21 @@ export default function Add({
getMaximum() getMaximum()
}, [ocean, poolAddress, coin]) }, [ocean, poolAddress, coin])
async function handleAddLiquidity() { async function handleAddLiquidity(amount: number, resetForm: () => void) {
setIsLoading(true) setIsLoading(true)
try { try {
const result = const result =
coin === 'OCEAN' coin === 'OCEAN'
? await ocean.pool.addOceanLiquidity(accountId, poolAddress, amount) ? await ocean.pool.addOceanLiquidity(
: await ocean.pool.addDTLiquidity(accountId, poolAddress, amount) accountId,
poolAddress,
`${amount}`
)
: await ocean.pool.addDTLiquidity(accountId, poolAddress, `${amount}`)
setTxId(result?.transactionHash) setTxId(result?.transactionHash)
resetForm()
} catch (error) { } catch (error) {
console.error(error.message) console.error(error.message)
toast.error(error.message) toast.error(error.message)
@ -116,13 +118,15 @@ export default function Add({
} }
} }
function handleAmountChange(e: ChangeEvent<HTMLInputElement>) { const validationSchema = Yup.object().shape<{ amount: number }>({
setAmount(e.target.value) amount: Yup.number()
} .min(1, 'Must be more or equal to 1')
.max(
function handleMax() { Number(amountMax),
setAmount(amountMax) `Must be less or equal to ${Number(amountMax).toFixed(2)}`
} )
.required('Required')
})
// TODO: this is only a prototype and is an accessibility nightmare. // TODO: this is only a prototype and is an accessibility nightmare.
// Needs to be refactored to either use custom select element instead of tippy.js, // Needs to be refactored to either use custom select element instead of tippy.js,
@ -139,73 +143,100 @@ export default function Add({
<> <>
<Header title={content.title} backAction={() => setShowAdd(false)} /> <Header title={content.title} backAction={() => setShowAdd(false)} />
<div className={styles.addInput}> <Formik
<div className={styles.userLiquidity}> initialValues={initialValues}
<div> validationSchema={validationSchema}
<span>Available:</span> onSubmit={async (values, { setSubmitting, resetForm }) => {
{coin === 'OCEAN' ? ( console.log('Hello')
<PriceUnit price={balance.ocean} symbol="OCEAN" small /> // kick off
) : ( await handleAddLiquidity(values.amount, resetForm)
<PriceUnit price={dtBalance} symbol={dtSymbol} small /> setSubmitting(false)
)} }}
</div> >
<div> {({ values, setFieldValue, submitForm }) => {
<span>Maximum:</span> const newPoolTokens =
<PriceUnit price={amountMax} symbol={coin} small /> totalBalance &&
</div> ((values.amount / Number(totalBalance.ocean)) * 100).toFixed(2)
</div>
<InputElement const newPoolShare =
value={amount} totalBalance &&
name="coin" ((Number(newPoolTokens) / Number(totalPoolTokens)) * 100).toFixed(2)
type="number"
max={amountMax}
prefix={
<Tooltip
content={<CoinSelect />}
trigger="click focus"
className={styles.coinswitch}
placement="bottom"
>
{coin}
<Caret aria-hidden="true" />
</Tooltip>
}
placeholder="0"
onChange={handleAmountChange}
/>
{(balance.ocean || dtBalance) > amount && ( return (
<Button <>
className={styles.buttonMax} <div className={styles.addInput}>
style="text" <div className={styles.userLiquidity}>
size="small" <div>
onClick={handleMax} <span>Available:</span>
> {coin === 'OCEAN' ? (
Use Max <PriceUnit price={balance.ocean} symbol="OCEAN" small />
</Button> ) : (
)} <PriceUnit price={dtBalance} symbol={dtSymbol} small />
</div> )}
</div>
<div>
<span>Maximum:</span>
<PriceUnit price={amountMax} symbol={coin} small />
</div>
</div>
<div className={styles.output}> <Field name="amount">
<div> {({ field }: { field: any }) => (
<p>{content.output.titleIn}</p> <Input
<Token symbol="pool shares" balance={newPoolTokens} /> type="number"
<Token symbol="% of pool" balance={newPoolShare} /> max={amountMax}
</div> prefix={
<div> <Tooltip
<p>{content.output.titleOut}</p> content={<CoinSelect />}
<Token symbol="% swap fee" balance={swapFee} /> trigger="click focus"
</div> className={styles.coinswitch}
</div> placement="bottom"
>
{coin}
<Caret aria-hidden="true" />
</Tooltip>
}
placeholder="0"
field={field}
/>
)}
</Field>
<Actions {(Number(balance.ocean) || dtBalance) > values.amount && (
isLoading={isLoading} <Button
loaderMessage="Adding Liquidity..." className={styles.buttonMax}
actionName={content.action} style="text"
action={handleAddLiquidity} size="small"
txId={txId} onClick={() => setFieldValue('amount', amountMax)}
/> >
Use Max
</Button>
)}
</div>
<div className={styles.output}>
<div>
<p>{content.output.titleIn}</p>
<Token symbol="pool shares" balance={newPoolTokens} />
<Token symbol="% of pool" balance={newPoolShare} />
</div>
<div>
<p>{content.output.titleOut}</p>
<Token symbol="% swap fee" balance={swapFee} />
</div>
</div>
<Actions
isLoading={isLoading}
loaderMessage="Adding Liquidity..."
actionName={content.action}
action={submitForm}
txId={txId}
/>
</>
)
}}
</Formik>
</> </>
) )
} }