refactor(converter): shared page layout + reusable conversion logic/UI

Pages:
- add WalletLayout route (WalletHeader + main + Footer via <Outlet/>),
  wrap converter/swap/bridge/transactions; thin pages, drop duplicated shell CSS
- extract SwapBridgeTabs shared between swap/bridge pages

Converter reuse (FSD layers, no widget->widget imports):
- move commission tiers to entities/commission (+ CommissionTable ui)
- shared calc hook features/payment/model/useCurrencyConversion;
  useConverterSection becomes thin wrapper; HomePage Converter reuses it
- move ConvertField/DirectionSwapButton to shared/ui; delete dead useConverter

Tooling:
- add eslint.config.js (ESLint 9 flat config); fix no-explicit-any in WalletPage

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-30 14:39:53 +03:00
parent bdc8bd3d93
commit 9b1d6ffb5d
45 changed files with 684 additions and 1129 deletions

View File

@@ -0,0 +1,44 @@
import styles from './ConvertField.module.css'
export type Currency = 'USDT' | 'RUB'
export interface ConvertFieldData {
value: string
currency: Currency
onChange?: (raw: string) => void
error?: string
}
interface Props extends ConvertFieldData {
label?: string
compact?: boolean
}
export function ConvertField({ label, value, currency, onChange, error, compact }: Props) {
const readOnly = !onChange
return (
<div className={compact ? `${styles.field} ${styles.compact}` : styles.field}>
{label && <div className={styles.fieldLabel}>{label}</div>}
<div className={styles.fieldInput}>
<input
type="text"
value={value}
onChange={onChange ? (e) => onChange(e.target.value) : undefined}
readOnly={readOnly}
placeholder="0"
inputMode={readOnly ? undefined : 'decimal'}
/>
<div className={styles.currency}>
<span
className={`${styles.currencyIcon} ${currency === 'USDT' ? styles.currencyUsdt : styles.currencyRub}`}
>
{currency === 'USDT' ? '₮' : '₽'}
</span>
{currency}
</div>
</div>
{error && <div className={styles.fieldError}>{error}</div>}
</div>
)
}