mirror of
https://github.com/kremalicious/asi-calculator.git
synced 2024-12-22 09:23:16 +01:00
validating style
This commit is contained in:
parent
bebb27e600
commit
1ffaab23f5
@ -1,13 +1,6 @@
|
|||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next'
|
||||||
import {
|
import { Hanken_Grotesk } from 'next/font/google'
|
||||||
Fira_Code,
|
import '@/styles/globals.css'
|
||||||
Space_Grotesk,
|
|
||||||
Jost,
|
|
||||||
Fira_Sans,
|
|
||||||
Inter,
|
|
||||||
Hanken_Grotesk
|
|
||||||
} from 'next/font/google'
|
|
||||||
import './globals.css'
|
|
||||||
|
|
||||||
const hankenGrotesk = Hanken_Grotesk({
|
const hankenGrotesk = Hanken_Grotesk({
|
||||||
subsets: ['latin'],
|
subsets: ['latin'],
|
||||||
|
@ -16,13 +16,7 @@
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.calculationBase p {
|
||||||
font-size: 0.65rem;
|
display: flex;
|
||||||
color: rgba(var(--foreground-rgb), 0.6);
|
align-items: center;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
@ -3,30 +3,37 @@
|
|||||||
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
||||||
import styles from './CalculationBase.module.css'
|
import styles from './CalculationBase.module.css'
|
||||||
import { usePrices } from '@/hooks'
|
import { usePrices } from '@/hooks'
|
||||||
|
import { Label } from '../Label'
|
||||||
|
|
||||||
export function CalculationBase() {
|
export function CalculationBase() {
|
||||||
const { prices } = usePrices()
|
const { prices, isValidating } = usePrices()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className={styles.calculationBase}>
|
<ul className={styles.calculationBase}>
|
||||||
<li>
|
<li>
|
||||||
1 ASI
|
<p>1 ASI</p>
|
||||||
<br />= ${prices.asi}
|
<p className={isValidating ? 'isValidating' : ''}>= ${prices.asi}</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
1 Fet = {ratioFetToAsi} ASI
|
<p>
|
||||||
<span className={styles.label}>fixed</span>
|
1 Fet = {ratioFetToAsi} ASI
|
||||||
<br />= ${prices.fet}
|
<Label>fixed</Label>
|
||||||
|
</p>
|
||||||
|
<p className={isValidating ? 'isValidating' : ''}>= ${prices.fet}</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
1 OCEAN = {ratioOceanToAsi} ASI
|
<p>
|
||||||
<span className={styles.label}>fixed</span>
|
1 OCEAN = {ratioOceanToAsi} ASI
|
||||||
<br />= ${prices.ocean}
|
<Label>fixed</Label>
|
||||||
|
</p>
|
||||||
|
<p className={isValidating ? 'isValidating' : ''}>= ${prices.ocean}</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
1 AGIX = {ratioAgixToAsi} ASI
|
<p>
|
||||||
<span className={styles.label}>fixed</span>
|
1 AGIX = {ratioAgixToAsi} ASI
|
||||||
<br />= ${prices.agix}
|
<Label>fixed</Label>
|
||||||
|
</p>
|
||||||
|
<p className={isValidating ? 'isValidating' : ''}>= ${prices.agix}</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
)
|
)
|
||||||
|
8
components/Label/Label.module.css
Normal file
8
components/Label/Label.module.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: rgba(var(--foreground-rgb), 0.6);
|
||||||
|
border: 1px solid rgba(var(--foreground-rgb), 0.15);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 0.05rem 0.3rem;
|
||||||
|
margin: 0 0.2rem;
|
||||||
|
}
|
5
components/Label/Label.tsx
Normal file
5
components/Label/Label.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import styles from './Label.module.css'
|
||||||
|
|
||||||
|
export function Label({ children }: { children: React.ReactNode }) {
|
||||||
|
return <span className={styles.label}>{children}</span>
|
||||||
|
}
|
1
components/Label/index.tsx
Normal file
1
components/Label/index.tsx
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './Label'
|
@ -15,11 +15,6 @@
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.resultLine:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fiat {
|
.fiat {
|
||||||
@ -63,19 +58,3 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -24,11 +24,7 @@ export function Result({
|
|||||||
}: Props) {
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.result}>
|
<div className={styles.result}>
|
||||||
<div
|
<div className={styles.resultLine}>
|
||||||
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`}
|
||||||
@ -38,7 +34,9 @@ export function Result({
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>{formatNumber(amount || 0, tokenSymbol)}</span>
|
<span className={isValidating ? 'isValidating' : ''}>
|
||||||
|
{formatNumber(amount || 0, tokenSymbol)}
|
||||||
|
</span>
|
||||||
|
|
||||||
{amountOriginalFiat ? (
|
{amountOriginalFiat ? (
|
||||||
<span className={styles.fiat}>
|
<span className={styles.fiat}>
|
||||||
@ -46,16 +44,17 @@ export function Result({
|
|||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className={styles.resultLine}>
|
||||||
className={`${styles.resultLine} ${
|
|
||||||
isValidating ? styles.isValidating : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<ArrowRightIcon className={styles.iconArrow} />
|
<ArrowRightIcon className={styles.iconArrow} />
|
||||||
<strong title={`${amountAsi}`}>
|
<strong
|
||||||
|
title={`${amountAsi}`}
|
||||||
|
className={isValidating ? 'isValidating' : ''}
|
||||||
|
>
|
||||||
{formatNumber(amountAsi || 0, 'ASI')}
|
{formatNumber(amountAsi || 0, 'ASI')}
|
||||||
</strong>
|
</strong>
|
||||||
<strong className={styles.fiat}>
|
<strong
|
||||||
|
className={`${styles.fiat} ${isValidating ? 'isValidating' : ''}`}
|
||||||
|
>
|
||||||
{formatNumber(amountFiat || 0, 'USD')}
|
{formatNumber(amountFiat || 0, 'USD')}
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
import { ratioOceanToAsi, ratioAgixToAsi, ratioFetToAsi } from '@/constants'
|
||||||
import { Result } from '../ResultRow'
|
import { Result } from '@/components/ResultRow'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useDebounce } from 'use-debounce'
|
import { useDebounce } from 'use-debounce'
|
||||||
import stylesShared from './styles.module.css'
|
import stylesShared from './styles.module.css'
|
||||||
@ -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, isValidating } = usePrices()
|
const { prices, isValidating, isLoading } = usePrices()
|
||||||
const [amount, setAmount] = useState(100)
|
const [amount, setAmount] = useState(100)
|
||||||
const [debouncedAmount] = useDebounce(amount, 500)
|
const [debouncedAmount] = useDebounce(amount, 500)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ export function Swap() {
|
|||||||
return (
|
return (
|
||||||
<div className={stylesShared.results}>
|
<div className={stylesShared.results}>
|
||||||
<h3 className={stylesShared.title}>
|
<h3 className={stylesShared.title}>
|
||||||
Swapping{' '}
|
Holding or swapping{' '}
|
||||||
<FormAmount
|
<FormAmount
|
||||||
amount={amount}
|
amount={amount}
|
||||||
token={token}
|
token={token}
|
||||||
|
@ -7,8 +7,9 @@ import useSWR from 'swr'
|
|||||||
export function usePrices(): {
|
export function usePrices(): {
|
||||||
prices: { ocean: number; fet: number; agix: number; asi: number }
|
prices: { ocean: number; fet: number; agix: number; asi: number }
|
||||||
isValidating: boolean
|
isValidating: boolean
|
||||||
|
isLoading: boolean
|
||||||
} {
|
} {
|
||||||
const { data, isValidating } = useSWR(
|
const { data, isValidating, isLoading } = useSWR(
|
||||||
`/api/prices/?tokens=${tokens.toString()}`,
|
`/api/prices/?tokens=${tokens.toString()}`,
|
||||||
fetcher
|
fetcher
|
||||||
)
|
)
|
||||||
@ -18,5 +19,5 @@ export function usePrices(): {
|
|||||||
const agix = data?.[tokens[2]]?.usd || 0
|
const agix = data?.[tokens[2]]?.usd || 0
|
||||||
const asi = fet
|
const asi = fet
|
||||||
|
|
||||||
return { prices: { ocean, fet, agix, asi }, isValidating }
|
return { prices: { ocean, fet, agix, asi }, isValidating, isLoading }
|
||||||
}
|
}
|
||||||
|
15
styles/_animations.css
Normal file
15
styles/_animations.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.isValidating {
|
||||||
|
animation: flicker 2s infinite ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flicker {
|
||||||
|
0% {
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
|
}
|
@ -26,44 +26,3 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
max-width: 100vw;
|
|
||||||
overflow-x: hidden;
|
|
||||||
font-family: var(--font-hanken-grotesk);
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
color: rgb(var(--foreground-rgb));
|
|
||||||
background: var(--background-gradient) rgb(var(--background-rgb));
|
|
||||||
line-height: 1.5;
|
|
||||||
min-height: 100vh;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
html {
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
}
|
|
44
styles/globals.css
Normal file
44
styles/globals.css
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@import './_variables.css';
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow-x: hidden;
|
||||||
|
font-family: var(--font-hanken-grotesk);
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: rgb(var(--foreground-rgb));
|
||||||
|
background: var(--background-gradient) rgb(var(--background-rgb));
|
||||||
|
line-height: 1.5;
|
||||||
|
min-height: 100vh;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@import './_animations.css';
|
Loading…
Reference in New Issue
Block a user