validating style

This commit is contained in:
Matthias Kretschmann 2024-03-31 14:24:07 +01:00
parent bebb27e600
commit 1ffaab23f5
Signed by: m
GPG Key ID: 606EEEF3C479A91F
14 changed files with 115 additions and 110 deletions

View File

@ -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'],

View File

@ -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;
} }

View File

@ -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>
) )

View 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;
}

View 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>
}

View File

@ -0,0 +1 @@
export * from './Label'

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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)

View File

@ -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}

View File

@ -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
View 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;
}
}

View File

@ -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
View 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';