Files

61 lines
2.0 KiB
TypeScript

import { formatMoney } from "@vmall/shared";
import type { Currency } from "@vmall/shared";
export function usePrice() {
const { currency } = usePrefs();
const { locale } = useI18n();
const { $api } = useNuxtApp();
const currencies = useState<Currency[]>("mall-currencies", () => []);
const cache = useState<Map<string, number>>("mall-price-cache", () => new Map());
const currencyRequest = useState<Promise<Currency[]> | null>("mall-currency-request", () => null);
async function ensureCurrencies(): Promise<Currency[]> {
if (currencies.value.length > 0) return currencies.value;
if (!currencyRequest.value) {
currencyRequest.value = $api.listCurrencies().then((list) => {
currencies.value = list;
return list;
}).finally(() => {
currencyRequest.value = null;
});
}
return currencyRequest.value;
}
function exponentFor(code: string): number {
return currencies.value.find((item) => item.code === code)?.exponent ?? 2;
}
async function convertAmount(amountMinor: number, from: string, to = currency.value): Promise<number> {
if (from === to) return amountMinor;
const key = `${amountMinor}:${from}:${to}`;
const cached = cache.value.get(key);
if (cached !== undefined) return cached;
const converted = await $api.convert(amountMinor, from, to);
cache.value.set(key, converted.amount_minor);
return converted.amount_minor;
}
async function formatPrice(amountMinor: number, from: string, to = currency.value): Promise<string> {
await ensureCurrencies();
const amount = await convertAmount(amountMinor, from, to);
return formatMoney(amount, to, exponentFor(to), locale.value);
}
async function formatAmount(amountMinor: number, code: string): Promise<string> {
await ensureCurrencies();
return formatMoney(amountMinor, code, exponentFor(code), locale.value);
}
return {
currency,
currencies,
cache,
ensureCurrencies,
exponentFor,
convertAmount,
formatPrice,
formatAmount,
};
}