Valyutani interfeysda almashtirish
1) Qonunning
1. Avval ma’no, keyin UI. Hisobvaraq valyutasini (buxgalteriya haqiqati) aks ettirish valyutasidan (qulaylik) va operatsiya valyutasidan (pulning haqiqiy konvertatsiyasi) ajrating.
2. Noaniqlik. Kod + chalkashlik xavfi bo’lgan belgini ko’rsating (’US $’,’CA $’,’MXN’,’R $’). uchun - har doim batafsil kod qoʻshing.
3. Kurslarning halolligi. Ko’rinib turibdiki: kurs manbai, oxirgi yangilanish vaqti, komissiya/spred yoqilgan.
4. Kirish barqarorligi. Valyutani o’zgartirish aniq roziliksiz (ayniqsa stavkalar/depozitlar shakllarida) kirish qiymatini «sakrab» qo’ymasligi kerak.
5. Formatlarni mahalliylashtirish. Ajratuvchilar, bo’shliqlar, valyuta belgisi - foydalanuvchining lokali bo’yicha; aniqlik - valyuta bo’yicha.
2) O’zgartirish modellari
Koʻrsatish (display-only): barcha hisob-kitoblar hisob valyutasida qoladi, UI tanlangan valyutadagi ekvivalentini koʻrsatadi. Katalog, profil va tahlillar uchun foydalaning.
Gibrid (soft convert): tanlangan valyutada koʻrsatish + hisobni tasdiqlash (ikkalasini ham koʻrsatamiz).
Operatsion (hard convert): foydalanuvchi operatsiya valyutasini (depozit/chiqarish/stavka) o’zgartiradi. Aniq kurslar, komissiyalar, qayd etish vaqti kerak.
Qoida: andoza - display-only, «qattiq» konversiyani esa faqat tegishli oqimlarda (kassa, pul yigʻish, pul oʻtkazish) kiriting.
3) Nazorat va joylashtirish
Shapka/profil panelidagi valyutani o’zgartirish (« /€/$» belgisi yoki valyuta kodi).
Selektor: kod/nom/belgi boʻyicha qidirish; tanlangan/tez-tez uchraydigan valyutalar - yuqoridan.
Shakllar ichida (depozit/stavka): yig’indining o’ng tomonidagi ixcham selektor, uning yonida «XXXdagi ≈ ekvivalenti».
Mobil pattern: filtrlash uchun roʻyxat va kirish bilan bottom sheet.
html
<button aria-haspopup="listbox" aria-expanded="false" class="currency-switch">UAH</button>
<ul role="listbox" class="currency-menu" hidden>
<li role="option" aria-selected="true">UAH — ₴</li>
<li role="option">USD — US$</li>
<li role="option">EUR — €</li>
<li role="option">TRY — ₺</li>
</ul>
4) Formatlash va aniqlik
Minor birliklar: summalarni eng kam miqdorda saqlang (tiyin, sent, satoshi).
Valyuta bo’yicha o’nlik razryadlar:- 0: JPY, KRW, CLP
- 2: USD, EUR, UAH, TRY
- 3 +: ba’zi valyutalar ZAR (2), KWD (3), kripto (4-8)
- Cryptocurrencies: 8 tagacha belgini ko’rsating (dinamik aniqlik, lekin o’qish uchun pastki chegarasi bilan).
- Jadval raqamlari:’font-variant-numeric: tabular-nums;’ustunlarni tekislash uchun.
js const fmt = (amountMinor, currency, locale) => {
const fraction = { JPY:0, KRW:0, KWD:3 }[currency]?? 2;
return new Intl.NumberFormat(locale, { style:'currency', currency, minimumFractionDigits:fraction, maximumFractionDigits:fraction })
.format(amountMinor / 10fraction);
};
fmt(200000, 'UAH', 'uk-UA'); // 2 000,00 ₴
5) Kurslar va yangilanishlar
Manba: kurs provayderini (ichki praysing/bank/FX-API) belgilang.
Kesh: kurslarni oqilona tezlikda (masalan, har 60-300 soniyada) + talabga ko’ra inkremental yangilanishlarni yangilang.
Oʻrnatish vaqti: «yangilangan N min orqaga» va amalni rasmiylashtirishda oʻrnatish vaqtini koʻrsating.
Spred/komissiya: aniq satrni ko’rsating: "Kurs 1 USD = 36,60 UAH (spred 1 kiritilgan. 5%)».
Yaxlitlash: bank yoki oddiy - birini tanlang va siyosatga kiriting.
6) UX matn va tushuntirishlar
Ekvivalenti: «≈ 52,10 €» - jim rangdagi summa yonida real vaqtda yangilanadi.
Yuridik izohlar: «Haqiqiy kurs va komissiya tasdiqlash bosqichida qayd etiladi».
Uzun kodlar: tooltips/ikkilamchi satrdan foydalaning: «US $ - AQSh dollari».
Savatdagi konvertatsiya: tushuntirishsiz «jami» ni oʻzgartirmang; qayta hisoblash satrini koʻrsating.
7) Foydalanish imkoniyati (A11y)
’role =’ listbox/option’valyuta selektorida.
Klaviaturani qoʻllab-quvvatlash: koʻrsatgich, Enter, Type-ahead kod/nom boʻyicha.
SR uchun o’qish: «Ko’rsatish valyutasi: UAH - Ukraina Grivnasi».
Rang ≠ maʼnoning yagona manbai (har doim kod/matn mavjud).
RTL: sonlar/kodlar v’dir = «ltr»’arab satrlari ichida.
8) Spektakl va keshlash
Kurslar TTL bilan + localStorage xotirasida (masalan, 5 daqiqa).
Batch yangilanishlari: ekvivalentlarni qutilar bilan qayta hisoblang (requestAnimationFrame, debauns 100-200 ms).
Kursning chegarasi o’zgarganda (masalan, 0,1%) ro’yxatning ortiqcha rerenderini triggerlemang.
9) iGaming xususiyatlari
Hisob raqami valyutasi - bazaviy hisobot (depozitlar, balans, tarix).
Stavka valyutasi: odatda = hisob valyutasi; agar topshirilgan bo’lsa, qo’shaloq blokni ko’rsating: «Hisobdan chiqarilgan X XXX to USD (≈ Y YYY to UAH)».
Hisob-kitob qilishda qayd etish: yutuqlar stavkalar emas, balki hisob-kitob paytidagi kurs bo’yicha konvertatsiya qilinadi - bu kupon/tarix tafsilotlarida ko’rinishi kerak.
Depozit/chiqarish: PSP/bank kursi va komissiyasi - alohida satrda; ETA usuli bo’yicha.
Mas’uliyatli o’yin limitlari: hisob valyutasida aniqlanadi; Agar UI boshqa valyutada boʻlsa, ikkala qiymatni ham koʻrsating.
Turnirlar va sovrinlar: sovrin fondi valyutasi qayd etiladi; ekvivalent ko’rsatilganda - taxminiy, belgi qo’yilgan holda.
10) Antipatternlar
Valyuta almashtirilganda kirish maydonidagi qiymatning «sehrli» o’zgarishi - aniq roziliksiz.
Bitta «$» belgisidan mamlakat kodisiz foydalanish.
Yashirin komissiya biladi (spred haqida satr yo’q).
Lokal va valyutani aralashtirish (’UAH’uchun’en-US’bo’yicha formatlang).
JPY/KRW uchun «2 belgi» yoki barcha kriptovalyutalar uchun «8 belgi» aniqligi.
Tarixiy tranzaksiyalarni joriy kurs bo’yicha «orqaga» qayta hisoblash - «qayta hisoblash» belgisiz.
11) Dizayn-tizim tokenlari (misol)
json
{
"currency": {
"default": "UAH",
"displayList": ["UAH","USD","EUR","TRY","PLN","BRL","MXN"],
"fractions": { "JPY":0, "KRW":0, "KWD":3, "BTC":8 },
"showCodeWithSymbol": ["USD","CAD","AUD","NZD"],
"approxPrefix": "≈ "
},
"format": {
"tabularNums": true,
"grouping": "locale",
"negative": "−"
},
"fx": {
"ttlSec": 300,
"changeThresholdPct": 0.1,
"showSpread": true
}
}
12) Snippetlar
Valyuta almashtirish (React, kontekst + Intl)
tsx import { createContext, useContext, useState, useMemo } from 'react';
type Cur = 'UAH' 'USD' 'EUR' 'TRY';
const CurrencyCtx = createContext<{cur:Cur,set:(c:Cur)=>void, rate:(from:Cur,to:Cur)=>number}>({cur:'UAH',set:()=>{},rate:()=>1});
export function CurrencyProvider({children}:{children:React.ReactNode}){
const [cur, set] = useState<Cur>('UAH');
// fx: получить из кэша/апи; здесь — заглушка const table = { UAH:{USD:0.027,EUR:0.025,TRY:0.89,UAH:1}, USD:{UAH:36.6,EUR:0.93,TRY:33.0,USD:1}, EUR:{UAH:39.2,USD:1.07,TRY:35.4,EUR:1}, TRY:{UAH:1.12,USD:0.030,EUR:0.028,TRY:1} };
const rate = (from:Cur,to:Cur)=> table[from][to];
const value = useMemo(()=>({cur, set, rate}),[cur]);
return <CurrencyCtx.Provider value={value}>{children}</CurrencyCtx.Provider>;
}
export function useCurrency(){ return useContext(CurrencyCtx); }
export function Money({minor, iso}:{minor:number, iso:Cur}){
const { cur, rate } = useCurrency();
const fraction = { JPY:0, KRW:0, KWD:3 }[cur as any]?? 2;
const v = (minor/10fraction) rate(iso, cur);
return <span style={{fontVariantNumeric:'tabular-nums'}}>{new Intl.NumberFormat(undefined,{style:'currency',currency:cur, minimumFractionDigits:fraction, maximumFractionDigits:fraction}).format(v)}</span>;
}
Ikki marta koʻrsatish (operatsion konvertatsiya)
html
<div class="amount">
<label>Сумма депозита</label>
<div class="row">
<input type="number" inputmode="decimal" aria-describedby="fxnote">
<select aria-label="Валюта операции">
<option>USD</option><option>EUR</option><option>UAH</option>
</select>
</div>
<small id="fxnote">≈ 2 000,00 ₴ · Курс будет зафиксирован на следующем шаге</small>
</div>
13) Metrika
FX latency: valyutani almashtirishdan to barcha maydonlarni yangilashgacha bo’lgan vaqt (maqsad ≤ 150 ms).
Correctness rate: "noto’g" ri summalar "bo’yicha sapportga murojaatlar ulushi (<0,2%).
Display vs account mismatch: foydalanuvchi valyutalarni chalkashtirib yuboradigan hodisalar.
Kursning CTR maslahatlari: "Kurs/komissiya to’g" risida batafsil ma’lumot ".
Obandon kassasi konversiya qilinganda: summaning «to’satdan» o’zgarishi bilan bog’liq rad etishlar ulushi.
14) QA-chek-varag’i
Maʼno va shaffoflik
- Hamma joyda hisob va/yoki operatsiya valyutasi ko’rinadi.
- $ uchun mamlakat kodi ko’rsatilgan (US $, CA $ va h.k.).
- Kurs, yangilanish sanasi va spred/komissiya haqida satr mavjud.
Formati va aniqligi
- Valyuta bo’yicha o’nlik razryadlar (JPY = 0, KWD = 3, crypto = 8 gacha).
- Raqam/valyuta lokali UI tiliga mos keladi.
- Tarixiy operatsiyalar belgilanmagan holda «joriy kurs bo’yicha» qayta hisoblanmagan.
Xatti-harakatlar
- Valyutani oʻzgartirish tasdiqlamasdan kiritishni oʻzgartirmaydi.
- «≈» ekvivalenti silliq va tez yangilanadi.
- Valyuta selektori klaviatura mavjud, Type-ahead ishlaydi.
iGaming-spetsifikasi
- Kuponda: hisobdan chiqarish/yutuq va ularning valyutasi imzolangan, belgilash kursi ko’rsatilgan.
- Kassada: PSP/bank komissiyalari alohida ko’rinadi.
- Chegaralarda: ikkala kattalik ham ko’rsatiladi (akkaunt va ko’rsatiladigan).
RTL/A11y
- Kodlar/summalar RTLda to’g "ri o’qiladi (’dir =’ltr’’sonlar uchun).
- Kontrast va fokus indikatorlari AA ga mos keladi.
15) Dizayn-tizimdagi hujjatlar
Komponentlar:’CurrencySwitch’,’Money’,’FxNote’,’DualAmount’.
Aniqlik/yaxlitlash siyosati va formatlashning yagona funksiyasi.
Qoidalar: «display-only qachon», «hard-convert qachon», «spred qanday koʻrsatiladi».
Valyuta ma’lumotnomasi: kod, belgi, razryadlar, belgilarning mintaqaviy ziddiyatlari.
Do/Don’t galereyasi: «kodsiz $», avto- sakrash, yashirin vositalar.
Qisqacha xulosa
Valyutani o’zgartirish shunchaki « /€/$» selektori emas. Bu pulning aniq modeli (akkaunt valyutasi vs ko’rsatish vs operatsiya), komissiya bilan halol kurs, lokal formatlash va kirish maydonlarining ehtiyotkor xulq-atvori. Qoidalarni dizayn tizimiga o’rnating, kurslarni formatlash va keshlashni avtomatlashtiring - foydalanuvchilar raqamlarga shubha qilmasdan va «ko’rinmas» spredlarda pul yo’qotmasdan summalar bilan ishonchli ishlaydilar.