first commit

This commit is contained in:
2026-05-09 00:38:56 +03:00
commit 51a44ef13d
156 changed files with 9832 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
export interface Tier {
min: number
max: number
pct: number
}
export const TIERS: readonly Tier[] = [
{ min: 5_000, max: 30_000, pct: 8 },
{ min: 30_000, max: 100_000, pct: 6 },
{ min: 100_000, max: 600_000, pct: 4 },
] as const
export const TIER_MIN = TIERS[0].min
export const TIER_MAX = TIERS[TIERS.length - 1].max
export function findTier(amount: number): Pick<Tier, 'pct'> {
const match = TIERS.find((t) => amount >= t.min && amount <= t.max)
if (match) return match
if (amount > TIER_MAX) return { pct: TIERS[TIERS.length - 1].pct }
return { pct: TIERS[0].pct }
}
export function progressPercent(amount: number): number {
if (amount <= TIER_MIN) return 0
if (amount >= TIER_MAX) return 100
return ((amount - TIER_MIN) / (TIER_MAX - TIER_MIN)) * 100
}

View File

@@ -0,0 +1,51 @@
import { useMemo, useState } from 'react'
import { findTier, progressPercent } from './tiers'
export type ConverterMode = 'buy' | 'sell'
interface UseConverterArgs {
usdtRate: number
}
export function useConverter({ usdtRate }: UseConverterArgs) {
const [mode, setMode] = useState<ConverterMode>('buy')
const [rubVal, setRubVal] = useState<string>('10000')
const [agreed, setAgreed] = useState<boolean>(false)
const numRub = Number.parseFloat(rubVal) || 0
const result = useMemo(() => {
const tier = findTier(numRub)
const commission = (numRub * tier.pct) / 100
const sign = mode === 'buy' ? 1 : -1
const effectiveRate = usdtRate * (1 + (sign * tier.pct) / 100)
const usdtVal = numRub > 0 ? (numRub / effectiveRate).toFixed(2) : '0.00'
return {
tierPct: tier.pct,
commission,
effectiveRate,
usdtVal,
progress: progressPercent(numRub),
}
}, [numRub, mode, usdtRate])
function updateRub(raw: string) {
setRubVal(raw.replace(/[^0-9.]/g, ''))
}
function toggleMode() {
setMode((m) => (m === 'buy' ? 'sell' : 'buy'))
}
return {
mode,
setMode,
rubVal,
updateRub,
numRub,
agreed,
setAgreed,
toggleMode,
...result,
}
}