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

construct pricing form data flow

This commit is contained in:
Matthias Kretschmann 2020-10-20 14:28:51 +02:00
parent 9ce1358fe1
commit de421d3c00
Signed by: m
GPG Key ID: 606EEEF3C479A91F
14 changed files with 41 additions and 66 deletions

View File

@ -4,7 +4,6 @@ import styles from './InputElement.module.css'
import { InputProps } from '.'
import FilesInput from '../../molecules/FormFields/FilesInput'
import Terms from '../../molecules/FormFields/Terms'
import Price from '../../molecules/FormFields/Price'
import Datatoken from '../../molecules/FormFields/Datatoken'
const DefaultInput = ({
@ -88,8 +87,6 @@ export default function InputElement({
)
case 'files':
return <FilesInput name={name} {...field} {...props} />
case 'price':
return <Price name={name} {...field} {...props} />
case 'datatoken':
return <Datatoken name={name} {...field} {...props} />
case 'terms':

View File

@ -20,6 +20,7 @@ export default function Coin({
readOnly?: boolean
}): ReactElement {
const [field, meta] = useField(name)
console.log(field)
return (
<div className={styles.coin}>
@ -41,6 +42,8 @@ export default function Coin({
readOnly={readOnly}
prefix={datatokenOptions?.symbol || 'DT'}
min="1"
name={name}
value={field.value}
{...field}
/>
{datatokenOptions?.symbol === 'OCEAN' && (

View File

@ -1,32 +1,28 @@
import { DataTokenOptions, useOcean } from '@oceanprotocol/react'
import PriceUnit from '../../../atoms/Price/PriceUnit'
import React, { ReactElement, useEffect, useState } from 'react'
import { PriceOptionsMarket } from '../../../../@types/MetaData'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import { isCorrectNetwork } from '../../../../utils/wallet'
import Alert from '../../../atoms/Alert'
import FormHelp from '../../../atoms/Input/Help'
import Tooltip from '../../../atoms/Tooltip'
import Wallet from '../../Wallet'
import Wallet from '../../../molecules/Wallet'
import Coin from './Coin'
import styles from './Dynamic.module.css'
import Fees from './Fees'
import stylesIndex from './index.module.css'
import { useFormikContext } from 'formik'
export default function Dynamic({
ocean,
priceOptions,
datatokenOptions,
content
}: {
ocean: number
priceOptions: PriceOptionsMarket
datatokenOptions: DataTokenOptions
content: any
}): ReactElement {
const { appConfig } = useSiteMetadata()
const { account, balance, networkId, refreshBalance } = useOcean()
const { weightOnDataToken } = priceOptions
const { values } = useFormikContext()
const [error, setError] = useState<string>()
const correctNetwork = isCorrectNetwork(networkId)
@ -40,12 +36,19 @@ export default function Dynamic({
setError(`No account connected. Please connect your Web3 wallet.`)
} else if (!correctNetwork) {
setError(`Wrong Network. Please connect to ${desiredNetworkName}.`)
} else if (Number(balance.ocean) < Number(ocean)) {
setError(`Insufficient balance. You need at least ${ocean} OCEAN`)
} else if (Number(balance.ocean) < Number(values.price)) {
setError(`Insufficient balance. You need at least ${values.price} OCEAN`)
} else {
setError(undefined)
}
}, [ocean, networkId, account, balance, correctNetwork, desiredNetworkName])
}, [
values.price,
networkId,
account,
balance,
correctNetwork,
desiredNetworkName
])
// refetch balance periodically
useEffect(() => {
@ -57,7 +60,7 @@ export default function Dynamic({
return () => {
clearInterval(balanceInterval)
}
}, [ocean, networkId, account])
}, [networkId, account])
return (
<div className={styles.dynamic}>
@ -81,14 +84,14 @@ export default function Dynamic({
<div className={styles.tokens}>
<Coin
name="price.price"
name="price"
datatokenOptions={{ symbol: 'OCEAN', name: 'Ocean Token' }}
weight={`${100 - Number(Number(weightOnDataToken) * 10)}%`}
weight={`${100 - Number(Number(values.weightOnDataToken) * 10)}%`}
/>
<Coin
name="price.tokensToMint"
name="dtAmount"
datatokenOptions={datatokenOptions}
weight={`${Number(weightOnDataToken) * 10}%`}
weight={`${Number(values.weightOnDataToken) * 10}%`}
readOnly
/>
</div>

View File

@ -1,7 +1,6 @@
import React, { ReactElement } from 'react'
import Tooltip from '../../../atoms/Tooltip'
import styles from './Fees.module.css'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import { useField } from 'formik'
import Input from '../../../atoms/Input'
import Error from './Error'
@ -11,8 +10,7 @@ export default function Fees({
}: {
tooltips: { [key: string]: string }
}): ReactElement {
const { appConfig } = useSiteMetadata()
const [field, meta] = useField('price.swapFee')
const [field, meta] = useField('swapFee')
return (
<>

View File

@ -8,7 +8,7 @@ import Input from '../../../atoms/Input'
import Error from './Error'
export default function Fixed({ content }: { content: any }): ReactElement {
const [field, meta] = useField('price.price')
const [field, meta] = useField('price')
return (
<div className={styles.fixed}>
@ -19,7 +19,7 @@ export default function Fixed({ content }: { content: any }): ReactElement {
<Input
label="Ocean Token"
value={field.value}
name="price.price"
name="price"
type="number"
prefix="OCEAN"
min="1"

View File

@ -1,12 +1,12 @@
import React, { ReactElement, useState, useEffect } from 'react'
import React, { ReactElement, useEffect } from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import { InputProps } from '../../../atoms/Input'
import styles from './index.module.css'
import Tabs from '../../../atoms/Tabs'
import Fixed from './Fixed'
import Dynamic from './Dynamic'
import { useField } from 'formik'
import { useFormikContext } from 'formik'
import { useUserPreferences } from '../../../../providers/UserPreferences'
import ddo from '../../../../../tests/unit/__fixtures__/ddo'
import { PriceOptionsMarket } from '../../../../@types/MetaData'
const query = graphql`
@ -38,26 +38,23 @@ const query = graphql`
}
`
export default function Price(props: InputProps): ReactElement {
export default function Price(): ReactElement {
const { debug } = useUserPreferences()
const data = useStaticQuery(query)
const content = data.content.edges[0].node.childPagesJson.price
const [field, meta, helpers] = useField(props.name)
const { price }: PriceOptionsMarket = field.value
const [tokensToMint, setTokensToMint] = useState<number>()
const { values, setFieldValue } = useFormikContext()
const { price, weightOnDataToken, type } = values as PriceOptionsMarket
function handleTabChange(tabName: string) {
const type = tabName.toLowerCase()
helpers.setValue({ ...field.value, type })
setFieldValue('type', type)
}
// Always update everything when amountOcean changes
// Always update everything when price changes
useEffect(() => {
const tokensToMint = Number(price) * Number(field.value.weightOnDataToken)
setTokensToMint(tokensToMint)
helpers.setValue({ ...field.value, tokensToMint })
const dtAmount = Number(price) * Number(weightOnDataToken)
setFieldValue('dtAmount', dtAmount)
}, [price])
const tabs = [
@ -69,9 +66,7 @@ export default function Price(props: InputProps): ReactElement {
title: content.dynamic.title,
content: (
<Dynamic
ocean={price}
priceOptions={{ ...field.value, tokensToMint }}
datatokenOptions={field.value.datatoken}
datatokenOptions={ddo.dataTokenInfo}
content={content.dynamic}
/>
)
@ -83,11 +78,11 @@ export default function Price(props: InputProps): ReactElement {
<Tabs
items={tabs}
handleTabChange={handleTabChange}
defaultIndex={field?.value?.type === 'fixed' ? 0 : 1}
defaultIndex={type === 'fixed' ? 0 : 1}
/>
{debug === true && (
<pre>
<code>{JSON.stringify(field.value, null, 2)}</code>
<code>{JSON.stringify(values, null, 2)}</code>
</pre>
)}
</div>

View File

@ -7,6 +7,7 @@ import { usePricing } from '@oceanprotocol/react'
import { PriceOptionsMarket } from '../../../@types/MetaData'
import Alert from '../../atoms/Alert'
import styles from './Pricing.module.css'
import Price from './Price'
export default function Pricing({ ddo }: { ddo: DDO }): ReactElement {
const { createPricing } = usePricing(ddo)
@ -32,27 +33,7 @@ export default function Pricing({ ddo }: { ddo: DDO }): ReactElement {
setSubmitting(false)
}}
>
{() => (
<>
<Field name="price">
{({
field,
form
}: {
field: FieldInputProps<PriceOptionsMarket>
form: any
}) => (
<Input
type="price"
name="price"
label="Create Price"
field={field}
form={form}
/>
)}
</Field>
</>
)}
{(props) => <Price name="price" {...props} />}
</Formik>
) : (
<Alert

View File

@ -3,9 +3,7 @@ import * as Yup from 'yup'
export const validationSchema = Yup.object().shape<PriceOptionsMarket>({
price: Yup.number().min(1, 'Must be greater than 0').required('Required'),
tokensToMint: Yup.number()
.min(1, 'Must be greater than 0')
.required('Required'),
dtAmount: Yup.number().min(1, 'Must be greater than 0').required('Required'),
type: Yup.string()
.matches(/fixed|dynamic/g)
.required('Required'),
@ -20,7 +18,7 @@ export const validationSchema = Yup.object().shape<PriceOptionsMarket>({
export const initialValues: Partial<PriceOptionsMarket> = {
price: 1,
type: 'dynamic',
tokensToMint: 1,
dtAmount: 1,
weightOnDataToken: '9', // 90% on data token
swapFee: 0.1 // in %
}