Files
frontend/src/widgets/converter-page/ui/ConverterSection.tsx
2026-05-13 22:37:37 +03:00

146 lines
4.7 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 { useConverter, progressPercent } from '@widgets/currency-converter'
import { useDebounce } from '@shared/lib/hooks/useDebounce'
import { usePaymentQuote, useCreateOrder } from '@features/payment'
import { CommissionPanel } from './CommissionPanel'
import { AgreementCheck } from './AgreementCheck'
import styles from './ConverterSection.module.css'
export function ConverterSection() {
const c = useConverter({ usdtRate: 0 })
const debouncedUsdt = useDebounce(c.numRub, 400)
const { data: quote, isError: quoteError } = usePaymentQuote(debouncedUsdt)
const usdtRate = Number(quote?.usdt_exchange_rate) || 0
const gasPrice = Number(quote?.gas_fee) || 0
const rubTotal = quote?.total_price ?? ''
const rubTotalNum = Number(rubTotal) || 0
const { mutate: submitOrder, isPending } = useCreateOrder()
function handlePay() {
submitOrder({
usdt_amount: c.numRub,
usdt_exchange_rate: 1,
gas_fee: 1,
total_price: Number(rubTotal) || 0,
})
}
return (
<div className={styles.wrap}>
<div className={styles.header}>
<div>
<h1 className={styles.title}>Конвертация</h1>
<div className={styles.subtitle}>Данные обновляются в реальном времени</div>
</div>
<div className={styles.pills}>
<div className={styles.pill}>
Цена газа в RUB <span className={styles.pillValue}>{gasPrice.toFixed(2)} RUB</span>
</div>
<div className={styles.pill}>
USDT/RUB <span className={styles.pillValue}>{usdtRate.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"
disabled
className={styles.tab}
data-active={c.mode === 'sell' || undefined}
onClick={() => c.setMode('sell')}
>
ПРОДАТЬ
</button>
</div>
<div className={styles.field}>
<div className={styles.fieldLabel}>Конвертируете</div>
<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>
{quoteError && (
<div className={styles.fieldError}>
Сумма слишком большая и превышает 600 000
</div>
)}
</div>
<div className={styles.swapWrap}>
<button
type="button"
className={styles.swapBtn}
onClick={c.toggleMode}
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.fieldLabel}>Платите</div>
<div className={styles.fieldInput}>
<input type="text" value={rubTotal} readOnly placeholder="0" />
<div className={styles.currency}>
<span className={`${styles.currencyIcon} ${styles.currencyRub}`}></span>
RUB
</div>
</div>
</div>
</div>
<CommissionPanel
amount={rubTotalNum}
progress={progressPercent(rubTotalNum)}
commission={c.commission}
effectiveRate={c.effectiveRate}
/>
</div>
<div className={styles.bottom}>
<AgreementCheck checked={c.agreed} onToggle={() => c.setAgreed(!c.agreed)} />
</div>
<button
type="button"
className={styles.payBtn}
onClick={handlePay}
disabled={!rubTotal || isPending}
>
{isPending ? 'Обработка...' : 'Оплатить'}
</button>
</div>
)
}