Files
frontend/src/widgets/currency-converter/ui/Converter.tsx
2026-05-14 17:36:00 +03:00

124 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { USDT_RATE, GAS_PRICE } from '@shared/config/constants'
import { useConverter } from '../model/useConverter'
import { findTier, progressPercent } from '../model/tiers'
import { usePaymentConfig } from '@features/payment'
import { AgreementCheckbox } from './AgreementCheckbox'
import { CommissionTable } from './CommissionTable'
import styles from './Converter.module.css'
import { Title } from '@shared/ui/Title/Title'
export function Converter() {
const { data: config } = usePaymentConfig()
const configUsdtRate = Number(config?.usdt_exchange_rate) || USDT_RATE
const gasPriceRub = Number(config?.gas_fee) * configUsdtRate || GAS_PRICE
const c = useConverter({ usdtRate: configUsdtRate })
// c.rubVal / c.numRub used as USDT input; RUB is computed
const numUsdt = c.numRub
const approxRub = numUsdt * configUsdtRate
const { pct } = findTier(approxRub)
const effectiveRate = configUsdtRate * (1 + pct / 100)
const rubOutput = numUsdt > 0 ? (numUsdt * effectiveRate).toFixed(2) : ''
const commission = (approxRub * pct) / 100
return (
<section className={styles.section} id="converter">
<div className={styles.wrap}>
<div className={styles.header}>
<div>
<Title>Конвертация</Title>
<div className={styles.subtitle}>Данные обновляются в реальном времени</div>
</div>
<div className={styles.pills}>
<div className={styles.pill}>
Цена газа в RUB <span className={styles.pillValue}>{gasPriceRub.toFixed(2)} RUB</span>
</div>
<div className={styles.pill}>
USDT/RUB <span className={styles.pillValue}>{configUsdtRate.toFixed(2)} </span>
</div>
</div>
</div>
<div className={styles.body}>
<div>
<div className={styles.tabs}>
<button
type="button"
className={styles.tab}
data-active={c.mode === 'buy' || undefined}
onClick={() => c.setMode('buy')}
>
КУПИТЬ
</button>
<button
type="button"
className={styles.tab}
data-active={c.mode === 'sell' || undefined}
onClick={() => c.setMode('sell')}
disabled
>
ПРОДАТЬ
</button>
</div>
<div className={styles.field}>
<div className={styles.fieldInput}>
<input
type="text"
value={c.rubVal}
onChange={(e) => c.updateRub(e.target.value)}
placeholder="0"
inputMode="decimal"
/>
<div className={styles.currency}>
<span className={`${styles.currencyIcon} ${styles.currencyUsdt}`}></span> USDT
</div>
</div>
</div>
<div className={styles.swapWrap}>
<button
type="button"
className={styles.swapBtn}
aria-label="Поменять направление"
>
<svg width={16} height={16} viewBox="0 0 16 16" fill="none">
<path
d="M8 2v12M4 10l4 4 4-4"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
</div>
<div className={styles.field}>
<div className={styles.fieldInput}>
<input type="text" value={rubOutput} readOnly placeholder="0" />
<div className={styles.currency}>
<span className={`${styles.currencyIcon} ${styles.currencyRub}`}></span> RUB
</div>
</div>
</div>
</div>
<CommissionTable
amount={approxRub}
progress={progressPercent(approxRub)}
commission={commission}
effectiveRate={effectiveRate}
/>
</div>
<div className={styles.bottom}>
<AgreementCheckbox checked={c.agreed} onToggle={() => c.setAgreed(!c.agreed)} />
</div>
</div>
</section>
)
}