fix(format): convert price by exchange rate on landings and gift page

formatPrice from utils/format.ts only swapped the currency symbol
(220 ₽ -> ¥220) without converting the underlying amount, because it
had no source of exchange rates and the landing/gift pages never called
the useCurrency hook that knew how to fetch them.

- Add a module-level rates cache in utils/format with setExchangeRates
  setter. formatPrice now converts kopeks/100 from RUB to the target
  currency via currencyApi.convertFromRub when rates are cached.
- useCurrency pushes its loaded rates into that cache so any subsequent
  formatPrice call benefits, including subcomponents that cannot easily
  receive a prop.
- Call useCurrency in QuickPurchase, GiftSubscription, and
  AdminLandingEditor — the only entry points whose subcomponents still
  use the synchronous formatPrice (everything else already routes
  through useCurrency.formatAmount).

For RU locale behavior is unchanged. For EN/ZH/FA the amount is now
divided by the per-currency rate and formatted via Intl.NumberFormat
with 2 fraction digits (0 for IRR since amounts are large).
This commit is contained in:
Fringg
2026-05-13 04:56:15 +03:00
parent 1fdafbd0a1
commit 6ffd0ae824
5 changed files with 54 additions and 9 deletions

View File

@@ -1,7 +1,8 @@
import { useCallback, useMemo } from 'react';
import { useCallback, useEffect, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { currencyApi, type ExchangeRates } from '../api/currency';
import { setExchangeRates as setGlobalExchangeRates } from '../utils/format';
// Map language to currency
const LANGUAGE_CURRENCY_MAP: Record<string, keyof ExchangeRates | 'RUB'> = {
@@ -30,6 +31,12 @@ export function useCurrency() {
retry: 2,
});
// Делимся курсом с синхронным formatPrice из utils/format.ts —
// у него нет своего источника rates, а на лендинге его дёргают subcomponents.
useEffect(() => {
setGlobalExchangeRates(exchangeRates);
}, [exchangeRates]);
// Get current language and currency
const currentLanguage = i18n.language;
const targetCurrency = LANGUAGE_CURRENCY_MAP[currentLanguage] || 'USD';