mirror of
https://github.com/kremalicious/blog.git
synced 2025-02-14 21:10:25 +01:00
move selected token to nanostore
This commit is contained in:
parent
7c82ec79be
commit
039757c671
@ -1,33 +1,28 @@
|
||||
import { useEffect, type ReactElement, useState } from 'react'
|
||||
import styles from './Conversion.module.css'
|
||||
import type { GetToken } from '../../hooks/useTokens'
|
||||
import { $selectedToken } from '../../stores/selectedToken'
|
||||
import { useStore } from '@nanostores/react'
|
||||
|
||||
export function Conversion({ amount }: { amount: string }): ReactElement {
|
||||
const selectedToken = useStore($selectedToken)
|
||||
|
||||
export function Conversion({
|
||||
amount,
|
||||
token
|
||||
}: {
|
||||
amount: string
|
||||
token: GetToken | undefined
|
||||
}): ReactElement {
|
||||
const [dollar, setDollar] = useState('0.00')
|
||||
const [euro, setEuro] = useState('0.00')
|
||||
|
||||
useEffect(() => {
|
||||
if (!token?.price || !amount) {
|
||||
if (!selectedToken?.price || !amount) {
|
||||
setDollar('0.00')
|
||||
setEuro('0.00')
|
||||
return
|
||||
}
|
||||
|
||||
const dollar = token?.price?.usd
|
||||
? (Number(amount) * token?.price?.usd).toFixed(2)
|
||||
: '0.00'
|
||||
const euro = token?.price?.eur
|
||||
? (Number(amount) * token?.price?.eur).toFixed(2)
|
||||
: '0.00'
|
||||
const { eur, usd } = selectedToken.price
|
||||
|
||||
const dollar = usd ? (Number(amount) * usd).toFixed(2) : '0.00'
|
||||
const euro = eur ? (Number(amount) * eur).toFixed(2) : '0.00'
|
||||
setDollar(dollar)
|
||||
setEuro(euro)
|
||||
}, [token?.price, amount])
|
||||
}, [selectedToken?.price, amount])
|
||||
|
||||
return (
|
||||
<div className={styles.conversion}>
|
||||
|
@ -6,19 +6,17 @@ import Alert from '../Alert/Alert'
|
||||
import { InputGroup } from '../Input'
|
||||
import styles from './index.module.css'
|
||||
import { SendNative, SendErc20 } from '../Send'
|
||||
import type { GetToken } from '../../hooks/useTokens'
|
||||
import { useSend } from '@features/Web3/hooks/useSend'
|
||||
import { useSend } from '../../hooks/useSend'
|
||||
import type { SendFormData } from './types'
|
||||
import { $selectedToken } from '../../stores/selectedToken'
|
||||
import { useStore } from '@nanostores/react'
|
||||
|
||||
export default function Web3Form(): ReactElement {
|
||||
const { address: account } = useAccount()
|
||||
const selectedToken = useStore($selectedToken)
|
||||
|
||||
const [amount, setAmount] = useState('')
|
||||
const [debouncedAmount] = useDebounce(amount, 500)
|
||||
const [tokenSelected, setTokenSelected] = useState<GetToken>({
|
||||
address: '0x0'
|
||||
} as any)
|
||||
|
||||
const [sendFormData, setSendFormData] = useState<SendFormData>()
|
||||
|
||||
const { data, send } = sendFormData || {}
|
||||
@ -31,7 +29,7 @@ export default function Web3Form(): ReactElement {
|
||||
className={styles.web3}
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault()
|
||||
if (!send || amount === '' || amount === '0') return
|
||||
if (!send || debouncedAmount === '' || debouncedAmount === '0') return
|
||||
await send()
|
||||
}}
|
||||
>
|
||||
@ -42,24 +40,18 @@ export default function Web3Form(): ReactElement {
|
||||
) : (
|
||||
<InputGroup
|
||||
amount={amount}
|
||||
token={tokenSelected}
|
||||
setAmount={setAmount}
|
||||
setTokenSelected={setTokenSelected}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
)}
|
||||
|
||||
{tokenSelected?.address === '0x0' ? (
|
||||
{selectedToken?.address === '0x0' ? (
|
||||
<SendNative
|
||||
amount={debouncedAmount}
|
||||
setSendFormData={setSendFormData}
|
||||
/>
|
||||
) : (
|
||||
<SendErc20
|
||||
amount={debouncedAmount}
|
||||
tokenAddress={tokenSelected?.address}
|
||||
setSendFormData={setSendFormData}
|
||||
/>
|
||||
<SendErc20 amount={debouncedAmount} setSendFormData={setSendFormData} />
|
||||
)}
|
||||
</form>
|
||||
)
|
||||
|
@ -4,29 +4,21 @@ import { Conversion } from '../Conversion'
|
||||
import styles from './InputGroup.module.css'
|
||||
import { TokenSelect } from '../TokenSelect'
|
||||
import config from '@config/blog.config'
|
||||
import type { GetToken } from '../../hooks/useTokens'
|
||||
|
||||
export function InputGroup({
|
||||
amount,
|
||||
token,
|
||||
isDisabled,
|
||||
setAmount,
|
||||
setTokenSelected
|
||||
setAmount
|
||||
}: {
|
||||
amount: string
|
||||
token: GetToken | undefined
|
||||
isDisabled: boolean
|
||||
setAmount: React.Dispatch<React.SetStateAction<string>>
|
||||
setTokenSelected: React.Dispatch<React.SetStateAction<GetToken>>
|
||||
}): ReactElement {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.inputGroup}>
|
||||
<div className={styles.token}>
|
||||
<TokenSelect
|
||||
selectedToken={token}
|
||||
setTokenSelected={setTokenSelected}
|
||||
/>
|
||||
<TokenSelect />
|
||||
</div>
|
||||
<Input
|
||||
type="text"
|
||||
@ -45,7 +37,7 @@ export function InputGroup({
|
||||
Make it rain
|
||||
</button>
|
||||
</div>
|
||||
<Conversion amount={amount} token={token} />
|
||||
<Conversion amount={amount} />
|
||||
<div className={styles.disclaimer}>
|
||||
This form sends tokens to my account <code>{config.author.ether}</code>
|
||||
</div>
|
||||
|
@ -1,23 +1,28 @@
|
||||
import { parseEther } from 'viem'
|
||||
import { parseUnits } from 'viem'
|
||||
import { useContractWrite, usePrepareContractWrite } from 'wagmi'
|
||||
import siteConfig from '@config/blog.config'
|
||||
import { abiErc20Transfer } from './abiErc20Transfer'
|
||||
import { useEffect } from 'react'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { $selectedToken } from '@features/Web3/stores/selectedToken'
|
||||
|
||||
export function SendErc20({
|
||||
amount,
|
||||
tokenAddress,
|
||||
setSendFormData
|
||||
}: {
|
||||
amount: string
|
||||
tokenAddress: `0x${string}` | undefined
|
||||
setSendFormData: any
|
||||
}) {
|
||||
const selectedToken = useStore($selectedToken)
|
||||
|
||||
const { config } = usePrepareContractWrite({
|
||||
address: tokenAddress,
|
||||
address: selectedToken.address,
|
||||
abi: abiErc20Transfer,
|
||||
functionName: 'transfer',
|
||||
args: [siteConfig.author.ether, parseEther(amount)]
|
||||
args: [
|
||||
siteConfig.author.ether,
|
||||
parseUnits(amount, selectedToken?.decimals || 18)
|
||||
]
|
||||
})
|
||||
|
||||
const {
|
||||
|
@ -4,17 +4,14 @@ import { Token } from './Token'
|
||||
import { ChevronDown, ChevronsDown, ChevronsUp } from '@images/components/react'
|
||||
import { TokenLoading } from './TokenLoading'
|
||||
import { useEffect } from 'react'
|
||||
import { useTokens, type GetToken } from '../../hooks/useTokens'
|
||||
import { useTokens } from '../../hooks/useTokens'
|
||||
import { useAccount, useNetwork } from 'wagmi'
|
||||
import { $selectedToken, $setSelectedToken } from '../../stores/selectedToken'
|
||||
import { useStore } from '@nanostores/react'
|
||||
|
||||
export function TokenSelect({
|
||||
selectedToken,
|
||||
setTokenSelected
|
||||
}: {
|
||||
selectedToken: GetToken | undefined
|
||||
setTokenSelected: React.Dispatch<React.SetStateAction<GetToken>>
|
||||
}) {
|
||||
export function TokenSelect() {
|
||||
const { data: tokens, isLoading } = useTokens()
|
||||
const selectedToken = useStore($selectedToken)
|
||||
const { chain } = useNetwork()
|
||||
const { address } = useAccount()
|
||||
|
||||
@ -25,21 +22,22 @@ export function TokenSelect({
|
||||
function handleValueChange(value: `0x${string}`) {
|
||||
const token = tokens?.find((token) => token.address === value)
|
||||
if (!token) return
|
||||
setTokenSelected(token)
|
||||
$setSelectedToken(token)
|
||||
}
|
||||
|
||||
// Set default token data to native token
|
||||
useEffect(() => {
|
||||
if (!chain?.id || !address || !tokens) return
|
||||
|
||||
handleValueChange('0x0')
|
||||
}, [chain?.id, address, tokens])
|
||||
if (!selectedToken || !selectedToken?.address) handleValueChange('0x0')
|
||||
}, [chain?.id, address, tokens, selectedToken])
|
||||
|
||||
return (
|
||||
<Select.Root
|
||||
defaultValue={selectedToken?.address}
|
||||
onValueChange={(value: `0x${string}`) => handleValueChange(value)}
|
||||
disabled={!tokens || isLoading}
|
||||
value={selectedToken?.address}
|
||||
>
|
||||
<Select.Trigger
|
||||
className="SelectTrigger"
|
||||
|
13
src/features/Web3/stores/selectedToken.ts
Normal file
13
src/features/Web3/stores/selectedToken.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { action, map } from 'nanostores'
|
||||
import type { GetToken } from '../hooks/useTokens'
|
||||
|
||||
export const $selectedToken = map<GetToken>()
|
||||
|
||||
export const $setSelectedToken = action(
|
||||
$selectedToken,
|
||||
'setSelectedToken',
|
||||
(store, token: GetToken) => {
|
||||
store.set(token)
|
||||
return store.get()
|
||||
}
|
||||
)
|
Loading…
Reference in New Issue
Block a user