Files
frontend/src/widgets/bridge-form/ui/BridgeConfirmModal.tsx
2026-07-01 16:42:37 +03:00

91 lines
3.3 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 { useState } from 'react'
import type { JumperQuote } from '@features/wallet'
import { fromBaseUnits } from '@shared/lib/utils/baseUnits'
import { truncateDecimals } from '@shared/lib/utils/truncateDecimals'
import styles from './BridgeConfirmModal.module.css'
interface Props {
quote: JumperQuote
fromAmountHuman: string
insufficientBalance?: boolean
isExecuting?: boolean
onConfirm: () => void
onClose: () => void
}
export function BridgeConfirmModal({ quote, fromAmountHuman, insufficientBalance, isExecuting, onConfirm, onClose }: Props) {
const { action, estimate, toolDetails } = quote
const toSymbol = action.toToken.symbol
const fromSymbol = action.fromToken.symbol
const [closing, setClosing] = useState(false)
// Trigger the exit animation; the real close fires on animation end so the ×
// and backdrop paths play the same closing transition.
function requestClose() {
setClosing(true)
}
function handleAnimationEnd() {
if (closing) onClose()
}
const toAmount = truncateDecimals(fromBaseUnits(estimate.toAmount, action.toToken.decimals), 8)
const toMin = truncateDecimals(fromBaseUnits(estimate.toAmountMin, action.toToken.decimals), 8)
const feesUsd = (estimate.feeCosts ?? [])
.reduce((sum, f) => sum + (parseFloat(f.amountUSD) || 0), 0)
.toFixed(2)
return (
<div className={`${styles.overlay} ${closing ? styles.closing : ''}`} onClick={requestClose}>
<div
className={`${styles.card} ${closing ? styles.closing : ''}`}
onClick={e => e.stopPropagation()}
onAnimationEnd={handleAnimationEnd}
>
<div className={styles.header}>
<span className={styles.title}>Подтвердить бридж</span>
<button className={styles.closeBtn} onClick={requestClose}>×</button>
</div>
<div className={styles.flow}>
<div className={styles.token}>
<span className={styles.tokenLabel}>Отдаёте</span>
<span className={styles.tokenAmount}>{fromAmountHuman} {fromSymbol}</span>
</div>
<div className={styles.arrow}></div>
<div className={styles.token}>
<span className={styles.tokenLabel}>Получаете</span>
<span className={styles.tokenAmount}>{toAmount} {toSymbol}</span>
<span className={styles.minOut}>Минимум: {toMin} {toSymbol}</span>
</div>
</div>
<div className={styles.details}>
<div className={styles.row}>
<span className={styles.rowLabel}>Комиссия</span>
<span className={styles.rowValue}>${feesUsd}</span>
</div>
<div className={styles.row}>
<span className={styles.rowLabel}>Мост</span>
<span className={styles.rowValue}>{toolDetails.name}</span>
</div>
</div>
{insufficientBalance && (
<p className={styles.warning}>
Введённое количество превышает баланс кошелька бридж будет отклонён.
</p>
)}
<button className={styles.confirmBtn} onClick={onConfirm} disabled={isExecuting}>
{isExecuting ? 'Обработка...' : 'Подтвердить бридж'}
</button>
</div>
</div>
)
}