From 894009fe6975fab86f6ebb494321bf0481030c37 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sat, 30 Mar 2024 19:50:51 +0000 Subject: [PATCH] prepare token switching --- .../CalculationBase.module.css | 24 ++++++------ components/Content/Content.tsx | 14 ++++--- components/FormAmount/FormAmount.module.css | 37 ++---------------- components/FormAmount/FormAmount.tsx | 22 +++++++---- .../FormAmount/Inputs/InputAmount.module.css | 32 ++++++++++++++++ components/FormAmount/Inputs/InputAmount.tsx | 19 ++++++++++ .../FormAmount/Inputs/InputToken.module.css | 17 +++++++++ components/FormAmount/Inputs/InputToken.tsx | 36 ++++++++++++++++++ components/FormAmount/index.tsx | 1 + components/FormAmount/types.ts | 1 + components/Strategies/Buy.tsx | 38 +++++++++---------- components/Strategies/Swap.tsx | 37 ++++++++++-------- components/Strategies/styles.module.css | 2 +- hooks/use-prices.tsx | 2 +- package-lock.json | 9 +++++ package.json | 1 + 16 files changed, 196 insertions(+), 96 deletions(-) create mode 100644 components/FormAmount/Inputs/InputAmount.module.css create mode 100644 components/FormAmount/Inputs/InputAmount.tsx create mode 100644 components/FormAmount/Inputs/InputToken.module.css create mode 100644 components/FormAmount/Inputs/InputToken.tsx create mode 100644 components/FormAmount/types.ts diff --git a/components/CalculationBase/CalculationBase.module.css b/components/CalculationBase/CalculationBase.module.css index f768bef..e986e25 100644 --- a/components/CalculationBase/CalculationBase.module.css +++ b/components/CalculationBase/CalculationBase.module.css @@ -1,20 +1,9 @@ -.label { - font-size: 0.7rem; - color: rgba(var(--foreground-rgb), 0.6); - border: 1px solid rgba(var(--foreground-rgb), 0.2); - border-radius: var(--border-radius); - padding: 0.1rem 0.3rem; - margin-left: 0.2rem; - margin-right: 0.2rem; - vertical-align: middle; -} - .calculationBase { border-top: 1px solid rgba(var(--foreground-rgb), 0.2); border-left: 1px solid rgba(var(--foreground-rgb), 0.2); border-bottom: none; display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); border-radius: var(--border-radius); margin-top: 1.5rem; } @@ -25,3 +14,14 @@ padding: 1rem; font-size: 0.8rem; } + +.label { + font-size: 0.7rem; + color: rgba(var(--foreground-rgb), 0.6); + border: 1px solid rgba(var(--foreground-rgb), 0.2); + border-radius: var(--border-radius); + padding: 0.1rem 0.3rem; + margin-left: 0.2rem; + margin-right: 0.2rem; + vertical-align: middle; +} diff --git a/components/Content/Content.tsx b/components/Content/Content.tsx index 1aec558..ca5ef0e 100644 --- a/components/Content/Content.tsx +++ b/components/Content/Content.tsx @@ -3,18 +3,22 @@ import styles from './Content.module.css' export function Content() { return (
+

+ The fiat values are fetched from{' '} + Coingecko, and the token swap + estimations directly from Uniswap v3 + swap routes. +

All displayed values should be seen as estimates. Except for the{' '} fixed ASI exchange rate - , the fiat values fetched from{' '} - Coingecko and the quotes from{' '} - Uniswap v3 swap routes are constantly - changing. + , all other values are constantly changing based on market conditions.

+

- There is no guarantee displayed values reflect the value of your + There is no guarantee the displayed values reflect the value of your investment once the actual ASI swap mechanism is released. Use at your own risk.

diff --git a/components/FormAmount/FormAmount.module.css b/components/FormAmount/FormAmount.module.css index fa13074..f635f5c 100644 --- a/components/FormAmount/FormAmount.module.css +++ b/components/FormAmount/FormAmount.module.css @@ -1,37 +1,6 @@ .form { - display: inline-block; -} - -.input { - all: unset; - width: 70px; - padding-left: 0.2rem; - padding-right: 0.2rem; - text-align: center; - background-color: rgba(var(--background-end-rgb), 0.4); + display: inline-flex; + border: 1px solid rgba(var(--foreground-rgb), 0.15); border-radius: var(--border-radius); -} - -.input:hover { - background-color: rgba(var(--background-end-rgb), 0.5); -} - -.input:focus-within { - outline: none; - background-color: rgba(var(--background-end-rgb), 0.9); - color: rgb(var(--foreground-rgb-highlight)); -} - -@media (prefers-color-scheme: dark) { - .input { - background-color: rgba(var(--foreground-rgb), 0.15); - } - - .input:hover { - background-color: rgba(var(--foreground-rgb), 0.2); - } - - .input:focus-within { - background-color: rgba(var(--foreground-rgb), 0.3); - } + overflow: hidden; } diff --git a/components/FormAmount/FormAmount.tsx b/components/FormAmount/FormAmount.tsx index 05f9b12..17cc4a6 100644 --- a/components/FormAmount/FormAmount.tsx +++ b/components/FormAmount/FormAmount.tsx @@ -1,20 +1,26 @@ +import { InputAmount } from '@/components/FormAmount/Inputs/InputAmount' +import { InputToken } from './Inputs/InputToken' import styles from './FormAmount.module.css' +import { Dispatch, SetStateAction } from 'react' +import { Token } from './types' export function FormAmount({ amount, - setAmount + setAmount, + token, + setToken, + isFiat }: { amount: number - setAmount: (amount: number) => void + setAmount: Dispatch> + token: Token + setToken?: Dispatch> + isFiat?: boolean }) { return (
- setAmount(Number(e.target.value))} - /> + + ) } diff --git a/components/FormAmount/Inputs/InputAmount.module.css b/components/FormAmount/Inputs/InputAmount.module.css new file mode 100644 index 0000000..cc6a231 --- /dev/null +++ b/components/FormAmount/Inputs/InputAmount.module.css @@ -0,0 +1,32 @@ +.input { + all: unset; + width: 70px; + padding-left: 0.2rem; + padding-right: 0.2rem; + text-align: center; + background-color: rgba(var(--background-end-rgb), 0.4); +} + +.input:hover { + background-color: rgba(var(--background-end-rgb), 0.5); +} + +.input:focus-within { + outline: none; + background-color: rgba(var(--background-end-rgb), 0.9); + color: rgb(var(--foreground-rgb-highlight)); +} + +@media (prefers-color-scheme: dark) { + .input { + background-color: rgba(var(--foreground-rgb), 0.15); + } + + .input:hover { + background-color: rgba(var(--foreground-rgb), 0.2); + } + + .input:focus-within { + background-color: rgba(var(--foreground-rgb), 0.3); + } +} diff --git a/components/FormAmount/Inputs/InputAmount.tsx b/components/FormAmount/Inputs/InputAmount.tsx new file mode 100644 index 0000000..64c1693 --- /dev/null +++ b/components/FormAmount/Inputs/InputAmount.tsx @@ -0,0 +1,19 @@ +import { Dispatch, SetStateAction } from 'react' +import styles from './InputAmount.module.css' + +export function InputAmount({ + amount, + setAmount +}: { + amount: number + setAmount: Dispatch> +}) { + return ( + setAmount(Number(e.target.value))} + /> + ) +} diff --git a/components/FormAmount/Inputs/InputToken.module.css b/components/FormAmount/Inputs/InputToken.module.css new file mode 100644 index 0000000..d0265f9 --- /dev/null +++ b/components/FormAmount/Inputs/InputToken.module.css @@ -0,0 +1,17 @@ +.select { + display: inline-block; + all: unset; + padding: 0 0.75rem; + padding-right: 1.25rem; +} + +.selectWrapper { + position: relative; +} + +.icon { + position: absolute; + right: 0.175rem; + height: 100%; + z-index: -1; +} diff --git a/components/FormAmount/Inputs/InputToken.tsx b/components/FormAmount/Inputs/InputToken.tsx new file mode 100644 index 0000000..8d51d82 --- /dev/null +++ b/components/FormAmount/Inputs/InputToken.tsx @@ -0,0 +1,36 @@ +import { Dispatch, SetStateAction } from 'react' +import styles from './InputToken.module.css' +import { CaretDownIcon } from '@radix-ui/react-icons' +import { Token } from '../types' + +export function InputToken({ + token, + setToken, + isFiat +}: { + token: Token + isFiat?: boolean + setToken?: Dispatch> +}) { + return ( + + + {setToken ? : null} + + ) +} diff --git a/components/FormAmount/index.tsx b/components/FormAmount/index.tsx index 02478c5..c10166f 100644 --- a/components/FormAmount/index.tsx +++ b/components/FormAmount/index.tsx @@ -1 +1,2 @@ export * from './FormAmount' +export * from './types' diff --git a/components/FormAmount/types.ts b/components/FormAmount/types.ts new file mode 100644 index 0000000..e7d0690 --- /dev/null +++ b/components/FormAmount/types.ts @@ -0,0 +1 @@ +export type Token = 'ocean' | 'fet' | 'agix' | 'usd' | undefined diff --git a/components/Strategies/Buy.tsx b/components/Strategies/Buy.tsx index 954aa34..0386953 100644 --- a/components/Strategies/Buy.tsx +++ b/components/Strategies/Buy.tsx @@ -1,63 +1,61 @@ 'use client' import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants' -import { FormAmount } from '../FormAmount' import { Result } from '../ResultRow' import { useState } from 'react' import { useDebounce } from 'use-debounce' -import styles from './styles.module.css' +import stylesShared from './styles.module.css' import { usePrices } from '@/hooks' +import { FormAmount } from '@/components/FormAmount' export function Buy() { const prices = usePrices() - const [amountBuy, setAmountBuy] = useState(100) - const [debouncedAmountBuy] = useDebounce(amountBuy, 500) + const [amount, setAmount] = useState(100) + const [debouncedAmount] = useDebounce(amount, 500) return ( -
-

- Buying with $ - right now - gets you: +
+

+ Buying with{' '} + {' '} + right now gets you:

diff --git a/components/Strategies/Swap.tsx b/components/Strategies/Swap.tsx index 96b659f..b41eec8 100644 --- a/components/Strategies/Swap.tsx +++ b/components/Strategies/Swap.tsx @@ -7,43 +7,50 @@ import { tokens } from '@/constants' import { fetcher, formatNumber } from '@/utils' -import { FormAmount } from '../FormAmount' -import { Result } from '../ResultRow' -import styles from './styles.module.css' +import { Result } from '@/components/ResultRow' +import stylesShared from './styles.module.css' import { useState } from 'react' import useSWR from 'swr' import { useDebounce } from 'use-debounce' import { usePrices } from '@/hooks' +import { FormAmount, type Token } from '@/components/FormAmount' export function Swap() { const prices = usePrices() - const [amountSwap, setAmountSwap] = useState(100) - const [debouncedAmountSwap] = useDebounce(amountSwap, 500) + const [amount, setAmount] = useState(100) + const [debouncedAmount] = useDebounce(amount, 500) + const [token, setToken] = useState('ocean') const { data: dataSwapOceanToAgix } = useSWR( - `/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmountSwap}`, + `/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[2]}&amountIn=${debouncedAmount}`, fetcher ) const { data: dataSwapOceanToFet } = useSWR( - `/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmountSwap}`, + `/api/quote/?tokenIn=${tokens[0]}&tokenOut=${tokens[1]}&amountIn=${debouncedAmount}`, fetcher ) return ( -
-

- Swapping {' '} - OCEAN ({formatNumber(debouncedAmountSwap * prices.ocean, 'USD')}) right - now gets you: +
+

+ Swapping{' '} + {' '} + ({formatNumber(amount * prices[token || 'ocean'], 'USD')}) right now + gets you:

=14" } }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", + "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.1.tgz", diff --git a/package.json b/package.json index bc50a50..74431ab 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@coingecko/cryptoformat": "^0.8.1", + "@radix-ui/react-icons": "^1.3.0", "next": "14.1.4", "react": "^18", "react-dom": "^18",