mirror of
https://github.com/kremalicious/asi-calculator.git
synced 2024-12-22 17:33:18 +01:00
add isValidating behavior
This commit is contained in:
parent
1aa4ee1afc
commit
e5153b2730
@ -5,7 +5,7 @@ import styles from './CalculationBase.module.css'
|
|||||||
import { usePrices } from '@/hooks'
|
import { usePrices } from '@/hooks'
|
||||||
|
|
||||||
export function CalculationBase() {
|
export function CalculationBase() {
|
||||||
const prices = usePrices()
|
const { prices } = usePrices()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className={styles.calculationBase}>
|
<ul className={styles.calculationBase}>
|
||||||
|
@ -13,7 +13,7 @@ export function FormAmount({
|
|||||||
}: {
|
}: {
|
||||||
amount: number
|
amount: number
|
||||||
setAmount: Dispatch<SetStateAction<number>>
|
setAmount: Dispatch<SetStateAction<number>>
|
||||||
token: Token
|
token: Token | string
|
||||||
setToken?: Dispatch<SetStateAction<Token>>
|
setToken?: Dispatch<SetStateAction<Token>>
|
||||||
isFiat?: boolean
|
isFiat?: boolean
|
||||||
}) {
|
}) {
|
||||||
|
@ -8,7 +8,7 @@ export function InputToken({
|
|||||||
setToken,
|
setToken,
|
||||||
isFiat
|
isFiat
|
||||||
}: {
|
}: {
|
||||||
token: Token
|
token: Token | string
|
||||||
isFiat?: boolean
|
isFiat?: boolean
|
||||||
setToken?: Dispatch<SetStateAction<Token>>
|
setToken?: Dispatch<SetStateAction<Token>>
|
||||||
}) {
|
}) {
|
||||||
|
@ -1 +1 @@
|
|||||||
export type Token = 'ocean' | 'fet' | 'agix' | 'usd' | undefined
|
export type Token = 'ocean' | 'fet' | 'agix' | undefined
|
||||||
|
@ -56,3 +56,19 @@
|
|||||||
filter: grayscale(1);
|
filter: grayscale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.isValidating {
|
||||||
|
animation: flicker 2s infinite ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flicker {
|
||||||
|
0% {
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ type Props = {
|
|||||||
amountAsi: number
|
amountAsi: number
|
||||||
amountFiat: number
|
amountFiat: number
|
||||||
amountOriginalFiat?: number
|
amountOriginalFiat?: number
|
||||||
|
isValidating: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Result({
|
export function Result({
|
||||||
@ -18,11 +19,16 @@ export function Result({
|
|||||||
amount,
|
amount,
|
||||||
amountAsi,
|
amountAsi,
|
||||||
amountFiat,
|
amountFiat,
|
||||||
amountOriginalFiat
|
amountOriginalFiat,
|
||||||
|
isValidating
|
||||||
}: Props) {
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.result}>
|
<div className={styles.result}>
|
||||||
<div className={styles.resultLine}>
|
<div
|
||||||
|
className={`${styles.resultLine} ${
|
||||||
|
isValidating ? styles.isValidating : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<span className={styles.logo} data-symbol={tokenSymbol}>
|
<span className={styles.logo} data-symbol={tokenSymbol}>
|
||||||
<Image
|
<Image
|
||||||
src={`https://tokens.1inch.io/${tokenAddress}.png`}
|
src={`https://tokens.1inch.io/${tokenAddress}.png`}
|
||||||
@ -40,7 +46,11 @@ export function Result({
|
|||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.resultLine}>
|
<div
|
||||||
|
className={`${styles.resultLine} ${
|
||||||
|
isValidating ? styles.isValidating : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<ArrowRightIcon className={styles.iconArrow} />
|
<ArrowRightIcon className={styles.iconArrow} />
|
||||||
<strong title={`${amountAsi}`}>
|
<strong title={`${amountAsi}`}>
|
||||||
{formatNumber(amountAsi || 0, 'ASI')}
|
{formatNumber(amountAsi || 0, 'ASI')}
|
||||||
|
@ -9,7 +9,7 @@ import { usePrices } from '@/hooks'
|
|||||||
import { FormAmount } from '@/components/FormAmount'
|
import { FormAmount } from '@/components/FormAmount'
|
||||||
|
|
||||||
export function Buy() {
|
export function Buy() {
|
||||||
const prices = usePrices()
|
const { prices, isValidating } = usePrices()
|
||||||
const [amount, setAmount] = useState(100)
|
const [amount, setAmount] = useState(100)
|
||||||
const [debouncedAmount] = useDebounce(amount, 500)
|
const [debouncedAmount] = useDebounce(amount, 500)
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ export function Buy() {
|
|||||||
? (debouncedAmount / prices.ocean) * ratioOceanToAsi * prices.asi
|
? (debouncedAmount / prices.ocean) * ratioOceanToAsi * prices.asi
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
|
isValidating={isValidating}
|
||||||
/>
|
/>
|
||||||
<Result
|
<Result
|
||||||
tokenSymbol="AGIX"
|
tokenSymbol="AGIX"
|
||||||
@ -45,6 +46,7 @@ export function Buy() {
|
|||||||
? (debouncedAmount / prices.agix) * ratioAgixToAsi * prices.asi
|
? (debouncedAmount / prices.agix) * ratioAgixToAsi * prices.asi
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
|
isValidating={isValidating}
|
||||||
/>
|
/>
|
||||||
<Result
|
<Result
|
||||||
tokenSymbol="FET"
|
tokenSymbol="FET"
|
||||||
@ -58,6 +60,7 @@ export function Buy() {
|
|||||||
? (debouncedAmount / prices.fet) * ratioFetToAsi * prices.asi
|
? (debouncedAmount / prices.fet) * ratioFetToAsi * prices.asi
|
||||||
: 0
|
: 0
|
||||||
}
|
}
|
||||||
|
isValidating={isValidating}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -16,20 +16,22 @@ import { usePrices } from '@/hooks'
|
|||||||
import { FormAmount, type Token } from '@/components/FormAmount'
|
import { FormAmount, type Token } from '@/components/FormAmount'
|
||||||
|
|
||||||
export function Swap() {
|
export function Swap() {
|
||||||
const prices = usePrices()
|
const { prices, isValidating: isValidatingPrices } = usePrices()
|
||||||
const [amount, setAmount] = useState(100)
|
const [amount, setAmount] = useState(100)
|
||||||
const [debouncedAmount] = useDebounce(amount, 500)
|
const [debouncedAmount] = useDebounce(amount, 500)
|
||||||
const [token, setToken] = useState<Token>('ocean')
|
const [token, setToken] = useState<Token>('ocean')
|
||||||
|
|
||||||
const { data: dataSwapOceanToAgix } = useSWR(
|
const { data: dataSwapOceanToAgix, isValidating: isValidatingOceanToAgix } =
|
||||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmount}`,
|
useSWR(
|
||||||
fetcher
|
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmount}`,
|
||||||
)
|
fetcher
|
||||||
|
)
|
||||||
|
|
||||||
const { data: dataSwapOceanToFet } = useSWR(
|
const { data: dataSwapOceanToFet, isValidating: isValidatingOceanToFet } =
|
||||||
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmount}`,
|
useSWR(
|
||||||
fetcher
|
`/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmount}`,
|
||||||
)
|
fetcher
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={stylesShared.results}>
|
<div className={stylesShared.results}>
|
||||||
@ -51,6 +53,11 @@ export function Swap() {
|
|||||||
amountAsi={debouncedAmount * ratioOceanToAsi}
|
amountAsi={debouncedAmount * ratioOceanToAsi}
|
||||||
amountFiat={debouncedAmount * ratioOceanToAsi * prices.asi}
|
amountFiat={debouncedAmount * ratioOceanToAsi * prices.asi}
|
||||||
amountOriginalFiat={token ? debouncedAmount * prices[token] : undefined}
|
amountOriginalFiat={token ? debouncedAmount * prices[token] : undefined}
|
||||||
|
isValidating={
|
||||||
|
isValidatingOceanToAgix ||
|
||||||
|
isValidatingOceanToFet ||
|
||||||
|
isValidatingPrices
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Result
|
<Result
|
||||||
@ -74,6 +81,7 @@ export function Swap() {
|
|||||||
(dataSwapOceanToAgix?.amountOut /
|
(dataSwapOceanToAgix?.amountOut /
|
||||||
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) * prices.agix
|
Number(`1e${dataSwapOceanToAgix?.decimals}`) || 0) * prices.agix
|
||||||
}
|
}
|
||||||
|
isValidating={isValidatingOceanToAgix || isValidatingPrices}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Result
|
<Result
|
||||||
@ -95,6 +103,7 @@ export function Swap() {
|
|||||||
(dataSwapOceanToFet?.amountOut /
|
(dataSwapOceanToFet?.amountOut /
|
||||||
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) * prices.asi
|
Number(`1e${dataSwapOceanToFet?.decimals}`) || 0) * prices.asi
|
||||||
}
|
}
|
||||||
|
isValidating={isValidatingOceanToFet || isValidatingPrices}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,23 +1,12 @@
|
|||||||
.results {
|
.results {
|
||||||
border: 1px solid rgba(var(--foreground-rgb), 0.2);
|
border: 1px solid rgba(var(--foreground-rgb), 0.2);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
padding: 1.25rem 1.5rem;
|
padding: 1.5rem 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .results form {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.results input {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.results:hover form {
|
|
||||||
border-color: rgba(var(--foreground-rgb), 0.2);
|
|
||||||
} */
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
color: rgb(var(--foreground-rgb-highlight));
|
color: rgb(var(--foreground-rgb-highlight));
|
||||||
|
min-height: 58px;
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,19 @@ import { tokens } from '@/constants'
|
|||||||
import { fetcher } from '@/utils'
|
import { fetcher } from '@/utils'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
|
|
||||||
export function usePrices(): { [key: string]: number } {
|
export function usePrices(): {
|
||||||
const { data: dataPrices } = useSWR(
|
prices: { ocean: number; fet: number; agix: number; asi: number }
|
||||||
|
isValidating: boolean
|
||||||
|
} {
|
||||||
|
const { data, isValidating } = useSWR(
|
||||||
`/api/prices/?tokens=${tokens.toString()}`,
|
`/api/prices/?tokens=${tokens.toString()}`,
|
||||||
fetcher
|
fetcher
|
||||||
)
|
)
|
||||||
|
|
||||||
const ocean = dataPrices?.[tokens[0]]?.usd || 0
|
const ocean = data?.[tokens[0]]?.usd || 0
|
||||||
const fet = dataPrices?.[tokens[1]]?.usd || 0
|
const fet = data?.[tokens[1]]?.usd || 0
|
||||||
const agix = dataPrices?.[tokens[2]]?.usd || 0
|
const agix = data?.[tokens[2]]?.usd || 0
|
||||||
const asi = fet
|
const asi = fet
|
||||||
|
|
||||||
return { ocean, fet, agix, asi }
|
return { prices: { ocean, fet, agix, asi }, isValidating }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user