mirror of
https://github.com/oceanprotocol/market.git
synced 2024-11-15 09:44:53 +01:00
construct pricing form data flow
This commit is contained in:
parent
9ce1358fe1
commit
de421d3c00
@ -4,7 +4,6 @@ import styles from './InputElement.module.css'
|
|||||||
import { InputProps } from '.'
|
import { InputProps } from '.'
|
||||||
import FilesInput from '../../molecules/FormFields/FilesInput'
|
import FilesInput from '../../molecules/FormFields/FilesInput'
|
||||||
import Terms from '../../molecules/FormFields/Terms'
|
import Terms from '../../molecules/FormFields/Terms'
|
||||||
import Price from '../../molecules/FormFields/Price'
|
|
||||||
import Datatoken from '../../molecules/FormFields/Datatoken'
|
import Datatoken from '../../molecules/FormFields/Datatoken'
|
||||||
|
|
||||||
const DefaultInput = ({
|
const DefaultInput = ({
|
||||||
@ -88,8 +87,6 @@ export default function InputElement({
|
|||||||
)
|
)
|
||||||
case 'files':
|
case 'files':
|
||||||
return <FilesInput name={name} {...field} {...props} />
|
return <FilesInput name={name} {...field} {...props} />
|
||||||
case 'price':
|
|
||||||
return <Price name={name} {...field} {...props} />
|
|
||||||
case 'datatoken':
|
case 'datatoken':
|
||||||
return <Datatoken name={name} {...field} {...props} />
|
return <Datatoken name={name} {...field} {...props} />
|
||||||
case 'terms':
|
case 'terms':
|
||||||
|
@ -20,6 +20,7 @@ export default function Coin({
|
|||||||
readOnly?: boolean
|
readOnly?: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [field, meta] = useField(name)
|
const [field, meta] = useField(name)
|
||||||
|
console.log(field)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.coin}>
|
<div className={styles.coin}>
|
||||||
@ -41,6 +42,8 @@ export default function Coin({
|
|||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
prefix={datatokenOptions?.symbol || 'DT'}
|
prefix={datatokenOptions?.symbol || 'DT'}
|
||||||
min="1"
|
min="1"
|
||||||
|
name={name}
|
||||||
|
value={field.value}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
{datatokenOptions?.symbol === 'OCEAN' && (
|
{datatokenOptions?.symbol === 'OCEAN' && (
|
@ -1,32 +1,28 @@
|
|||||||
import { DataTokenOptions, useOcean } from '@oceanprotocol/react'
|
import { DataTokenOptions, useOcean } from '@oceanprotocol/react'
|
||||||
import PriceUnit from '../../../atoms/Price/PriceUnit'
|
import PriceUnit from '../../../atoms/Price/PriceUnit'
|
||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import { PriceOptionsMarket } from '../../../../@types/MetaData'
|
|
||||||
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
||||||
import { isCorrectNetwork } from '../../../../utils/wallet'
|
import { isCorrectNetwork } from '../../../../utils/wallet'
|
||||||
import Alert from '../../../atoms/Alert'
|
import Alert from '../../../atoms/Alert'
|
||||||
import FormHelp from '../../../atoms/Input/Help'
|
import FormHelp from '../../../atoms/Input/Help'
|
||||||
import Tooltip from '../../../atoms/Tooltip'
|
import Tooltip from '../../../atoms/Tooltip'
|
||||||
import Wallet from '../../Wallet'
|
import Wallet from '../../../molecules/Wallet'
|
||||||
import Coin from './Coin'
|
import Coin from './Coin'
|
||||||
import styles from './Dynamic.module.css'
|
import styles from './Dynamic.module.css'
|
||||||
import Fees from './Fees'
|
import Fees from './Fees'
|
||||||
import stylesIndex from './index.module.css'
|
import stylesIndex from './index.module.css'
|
||||||
|
import { useFormikContext } from 'formik'
|
||||||
|
|
||||||
export default function Dynamic({
|
export default function Dynamic({
|
||||||
ocean,
|
|
||||||
priceOptions,
|
|
||||||
datatokenOptions,
|
datatokenOptions,
|
||||||
content
|
content
|
||||||
}: {
|
}: {
|
||||||
ocean: number
|
|
||||||
priceOptions: PriceOptionsMarket
|
|
||||||
datatokenOptions: DataTokenOptions
|
datatokenOptions: DataTokenOptions
|
||||||
content: any
|
content: any
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { appConfig } = useSiteMetadata()
|
const { appConfig } = useSiteMetadata()
|
||||||
const { account, balance, networkId, refreshBalance } = useOcean()
|
const { account, balance, networkId, refreshBalance } = useOcean()
|
||||||
const { weightOnDataToken } = priceOptions
|
const { values } = useFormikContext()
|
||||||
|
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
const correctNetwork = isCorrectNetwork(networkId)
|
const correctNetwork = isCorrectNetwork(networkId)
|
||||||
@ -40,12 +36,19 @@ export default function Dynamic({
|
|||||||
setError(`No account connected. Please connect your Web3 wallet.`)
|
setError(`No account connected. Please connect your Web3 wallet.`)
|
||||||
} else if (!correctNetwork) {
|
} else if (!correctNetwork) {
|
||||||
setError(`Wrong Network. Please connect to ${desiredNetworkName}.`)
|
setError(`Wrong Network. Please connect to ${desiredNetworkName}.`)
|
||||||
} else if (Number(balance.ocean) < Number(ocean)) {
|
} else if (Number(balance.ocean) < Number(values.price)) {
|
||||||
setError(`Insufficient balance. You need at least ${ocean} OCEAN`)
|
setError(`Insufficient balance. You need at least ${values.price} OCEAN`)
|
||||||
} else {
|
} else {
|
||||||
setError(undefined)
|
setError(undefined)
|
||||||
}
|
}
|
||||||
}, [ocean, networkId, account, balance, correctNetwork, desiredNetworkName])
|
}, [
|
||||||
|
values.price,
|
||||||
|
networkId,
|
||||||
|
account,
|
||||||
|
balance,
|
||||||
|
correctNetwork,
|
||||||
|
desiredNetworkName
|
||||||
|
])
|
||||||
|
|
||||||
// refetch balance periodically
|
// refetch balance periodically
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -57,7 +60,7 @@ export default function Dynamic({
|
|||||||
return () => {
|
return () => {
|
||||||
clearInterval(balanceInterval)
|
clearInterval(balanceInterval)
|
||||||
}
|
}
|
||||||
}, [ocean, networkId, account])
|
}, [networkId, account])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.dynamic}>
|
<div className={styles.dynamic}>
|
||||||
@ -81,14 +84,14 @@ export default function Dynamic({
|
|||||||
|
|
||||||
<div className={styles.tokens}>
|
<div className={styles.tokens}>
|
||||||
<Coin
|
<Coin
|
||||||
name="price.price"
|
name="price"
|
||||||
datatokenOptions={{ symbol: 'OCEAN', name: 'Ocean Token' }}
|
datatokenOptions={{ symbol: 'OCEAN', name: 'Ocean Token' }}
|
||||||
weight={`${100 - Number(Number(weightOnDataToken) * 10)}%`}
|
weight={`${100 - Number(Number(values.weightOnDataToken) * 10)}%`}
|
||||||
/>
|
/>
|
||||||
<Coin
|
<Coin
|
||||||
name="price.tokensToMint"
|
name="dtAmount"
|
||||||
datatokenOptions={datatokenOptions}
|
datatokenOptions={datatokenOptions}
|
||||||
weight={`${Number(weightOnDataToken) * 10}%`}
|
weight={`${Number(values.weightOnDataToken) * 10}%`}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
@ -1,7 +1,6 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import Tooltip from '../../../atoms/Tooltip'
|
import Tooltip from '../../../atoms/Tooltip'
|
||||||
import styles from './Fees.module.css'
|
import styles from './Fees.module.css'
|
||||||
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
|
||||||
import { useField } from 'formik'
|
import { useField } from 'formik'
|
||||||
import Input from '../../../atoms/Input'
|
import Input from '../../../atoms/Input'
|
||||||
import Error from './Error'
|
import Error from './Error'
|
||||||
@ -11,8 +10,7 @@ export default function Fees({
|
|||||||
}: {
|
}: {
|
||||||
tooltips: { [key: string]: string }
|
tooltips: { [key: string]: string }
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { appConfig } = useSiteMetadata()
|
const [field, meta] = useField('swapFee')
|
||||||
const [field, meta] = useField('price.swapFee')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
@ -8,7 +8,7 @@ import Input from '../../../atoms/Input'
|
|||||||
import Error from './Error'
|
import Error from './Error'
|
||||||
|
|
||||||
export default function Fixed({ content }: { content: any }): ReactElement {
|
export default function Fixed({ content }: { content: any }): ReactElement {
|
||||||
const [field, meta] = useField('price.price')
|
const [field, meta] = useField('price')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.fixed}>
|
<div className={styles.fixed}>
|
||||||
@ -19,7 +19,7 @@ export default function Fixed({ content }: { content: any }): ReactElement {
|
|||||||
<Input
|
<Input
|
||||||
label="Ocean Token"
|
label="Ocean Token"
|
||||||
value={field.value}
|
value={field.value}
|
||||||
name="price.price"
|
name="price"
|
||||||
type="number"
|
type="number"
|
||||||
prefix="OCEAN"
|
prefix="OCEAN"
|
||||||
min="1"
|
min="1"
|
@ -1,12 +1,12 @@
|
|||||||
import React, { ReactElement, useState, useEffect } from 'react'
|
import React, { ReactElement, useEffect } from 'react'
|
||||||
import { graphql, useStaticQuery } from 'gatsby'
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
import { InputProps } from '../../../atoms/Input'
|
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import Tabs from '../../../atoms/Tabs'
|
import Tabs from '../../../atoms/Tabs'
|
||||||
import Fixed from './Fixed'
|
import Fixed from './Fixed'
|
||||||
import Dynamic from './Dynamic'
|
import Dynamic from './Dynamic'
|
||||||
import { useField } from 'formik'
|
import { useFormikContext } from 'formik'
|
||||||
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
||||||
|
import ddo from '../../../../../tests/unit/__fixtures__/ddo'
|
||||||
import { PriceOptionsMarket } from '../../../../@types/MetaData'
|
import { PriceOptionsMarket } from '../../../../@types/MetaData'
|
||||||
|
|
||||||
const query = graphql`
|
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 { debug } = useUserPreferences()
|
||||||
const data = useStaticQuery(query)
|
const data = useStaticQuery(query)
|
||||||
const content = data.content.edges[0].node.childPagesJson.price
|
const content = data.content.edges[0].node.childPagesJson.price
|
||||||
|
|
||||||
const [field, meta, helpers] = useField(props.name)
|
const { values, setFieldValue } = useFormikContext()
|
||||||
const { price }: PriceOptionsMarket = field.value
|
const { price, weightOnDataToken, type } = values as PriceOptionsMarket
|
||||||
|
|
||||||
const [tokensToMint, setTokensToMint] = useState<number>()
|
|
||||||
|
|
||||||
function handleTabChange(tabName: string) {
|
function handleTabChange(tabName: string) {
|
||||||
const type = tabName.toLowerCase()
|
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(() => {
|
useEffect(() => {
|
||||||
const tokensToMint = Number(price) * Number(field.value.weightOnDataToken)
|
const dtAmount = Number(price) * Number(weightOnDataToken)
|
||||||
setTokensToMint(tokensToMint)
|
setFieldValue('dtAmount', dtAmount)
|
||||||
helpers.setValue({ ...field.value, tokensToMint })
|
|
||||||
}, [price])
|
}, [price])
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
@ -69,9 +66,7 @@ export default function Price(props: InputProps): ReactElement {
|
|||||||
title: content.dynamic.title,
|
title: content.dynamic.title,
|
||||||
content: (
|
content: (
|
||||||
<Dynamic
|
<Dynamic
|
||||||
ocean={price}
|
datatokenOptions={ddo.dataTokenInfo}
|
||||||
priceOptions={{ ...field.value, tokensToMint }}
|
|
||||||
datatokenOptions={field.value.datatoken}
|
|
||||||
content={content.dynamic}
|
content={content.dynamic}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@ -83,11 +78,11 @@ export default function Price(props: InputProps): ReactElement {
|
|||||||
<Tabs
|
<Tabs
|
||||||
items={tabs}
|
items={tabs}
|
||||||
handleTabChange={handleTabChange}
|
handleTabChange={handleTabChange}
|
||||||
defaultIndex={field?.value?.type === 'fixed' ? 0 : 1}
|
defaultIndex={type === 'fixed' ? 0 : 1}
|
||||||
/>
|
/>
|
||||||
{debug === true && (
|
{debug === true && (
|
||||||
<pre>
|
<pre>
|
||||||
<code>{JSON.stringify(field.value, null, 2)}</code>
|
<code>{JSON.stringify(values, null, 2)}</code>
|
||||||
</pre>
|
</pre>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
@ -7,6 +7,7 @@ import { usePricing } from '@oceanprotocol/react'
|
|||||||
import { PriceOptionsMarket } from '../../../@types/MetaData'
|
import { PriceOptionsMarket } from '../../../@types/MetaData'
|
||||||
import Alert from '../../atoms/Alert'
|
import Alert from '../../atoms/Alert'
|
||||||
import styles from './Pricing.module.css'
|
import styles from './Pricing.module.css'
|
||||||
|
import Price from './Price'
|
||||||
|
|
||||||
export default function Pricing({ ddo }: { ddo: DDO }): ReactElement {
|
export default function Pricing({ ddo }: { ddo: DDO }): ReactElement {
|
||||||
const { createPricing } = usePricing(ddo)
|
const { createPricing } = usePricing(ddo)
|
||||||
@ -32,27 +33,7 @@ export default function Pricing({ ddo }: { ddo: DDO }): ReactElement {
|
|||||||
setSubmitting(false)
|
setSubmitting(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{() => (
|
{(props) => <Price name="price" {...props} />}
|
||||||
<>
|
|
||||||
<Field name="price">
|
|
||||||
{({
|
|
||||||
field,
|
|
||||||
form
|
|
||||||
}: {
|
|
||||||
field: FieldInputProps<PriceOptionsMarket>
|
|
||||||
form: any
|
|
||||||
}) => (
|
|
||||||
<Input
|
|
||||||
type="price"
|
|
||||||
name="price"
|
|
||||||
label="Create Price"
|
|
||||||
field={field}
|
|
||||||
form={form}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Formik>
|
</Formik>
|
||||||
) : (
|
) : (
|
||||||
<Alert
|
<Alert
|
||||||
|
@ -3,9 +3,7 @@ import * as Yup from 'yup'
|
|||||||
|
|
||||||
export const validationSchema = Yup.object().shape<PriceOptionsMarket>({
|
export const validationSchema = Yup.object().shape<PriceOptionsMarket>({
|
||||||
price: Yup.number().min(1, 'Must be greater than 0').required('Required'),
|
price: Yup.number().min(1, 'Must be greater than 0').required('Required'),
|
||||||
tokensToMint: Yup.number()
|
dtAmount: Yup.number().min(1, 'Must be greater than 0').required('Required'),
|
||||||
.min(1, 'Must be greater than 0')
|
|
||||||
.required('Required'),
|
|
||||||
type: Yup.string()
|
type: Yup.string()
|
||||||
.matches(/fixed|dynamic/g)
|
.matches(/fixed|dynamic/g)
|
||||||
.required('Required'),
|
.required('Required'),
|
||||||
@ -20,7 +18,7 @@ export const validationSchema = Yup.object().shape<PriceOptionsMarket>({
|
|||||||
export const initialValues: Partial<PriceOptionsMarket> = {
|
export const initialValues: Partial<PriceOptionsMarket> = {
|
||||||
price: 1,
|
price: 1,
|
||||||
type: 'dynamic',
|
type: 'dynamic',
|
||||||
tokensToMint: 1,
|
dtAmount: 1,
|
||||||
weightOnDataToken: '9', // 90% on data token
|
weightOnDataToken: '9', // 90% on data token
|
||||||
swapFee: 0.1 // in %
|
swapFee: 0.1 // in %
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user