/** * Exchange Rate Store * 한국수출입은행 API에서 가져온 환율 정보를 저장하고 관리 */ import { create } from 'zustand'; import { exchangeRateApi, ExchangeRateSimple } from './api'; // 기본 환율 (API 실패 시 사용) - 2024년 12월 기준 const DEFAULT_RATES: ExchangeRateSimple = { USD: { rate: 1483, symbol: '$', name: '미국 달러' }, MNT: { rate: 0.43, symbol: '₮', name: '몽골 투그릭' }, RUB: { rate: 14.5, symbol: '₽', name: '러시아 루블' }, CNY: { rate: 203, symbol: '¥', name: '중국 위안' }, EUR: { rate: 1750, symbol: '€', name: '유로' }, JPY: { rate: 9.5, symbol: '¥', name: '일본 엔' }, }; interface ExchangeRateState { rates: ExchangeRateSimple; isLoading: boolean; lastUpdated: Date | null; error: string | null; fetchRates: () => Promise; getKrwToUsd: () => number; // KRW를 USD로 변환하는 비율 (1 KRW = X USD) getUsdToMnt: () => number; // USD를 MNT로 변환하는 비율 (1 USD = X MNT) getUsdToRub: () => number; // USD를 RUB로 변환하는 비율 (1 USD = X RUB) convertKrwTo: (krwAmount: number, currency: string) => number; } export const useExchangeRateStore = create((set, get) => ({ rates: DEFAULT_RATES, isLoading: false, lastUpdated: null, error: null, fetchRates: async () => { // 이미 로딩 중이면 스킵 if (get().isLoading) return; // 30분 이내에 업데이트했으면 스킵 const lastUpdated = get().lastUpdated; if (lastUpdated && Date.now() - lastUpdated.getTime() < 30 * 60 * 1000) { return; } set({ isLoading: true, error: null }); try { const rates = await exchangeRateApi.getSimpleRates(); set({ rates: { ...DEFAULT_RATES, ...rates }, isLoading: false, lastUpdated: new Date(), }); } catch (error) { console.error('Failed to fetch exchange rates:', error); set({ isLoading: false, error: 'Failed to fetch exchange rates', }); // 실패해도 기본값 사용 } }, getKrwToUsd: () => { const { rates } = get(); const usdRate = rates.USD?.rate || DEFAULT_RATES.USD.rate; return 1 / usdRate; // 1 KRW = 1/1450 USD }, getUsdToMnt: () => { const { rates } = get(); const usdRate = rates.USD?.rate || DEFAULT_RATES.USD.rate; const mntRate = rates.MNT?.rate || DEFAULT_RATES.MNT.rate; // MNT rate is already in KRW per MNT // So 1 USD = (USD_KRW / MNT_KRW) MNT return usdRate / mntRate; }, getUsdToRub: () => { const { rates } = get(); const usdRate = rates.USD?.rate || DEFAULT_RATES.USD.rate; const rubRate = rates.RUB?.rate || DEFAULT_RATES.RUB.rate; return usdRate / rubRate; }, convertKrwTo: (krwAmount: number, currency: string) => { const { rates } = get(); const rate = rates[currency]?.rate || DEFAULT_RATES[currency]?.rate; if (!rate) return 0; return krwAmount / rate; }, })); // 환율 초기화 함수 (앱 시작 시 호출) export async function initExchangeRates() { const store = useExchangeRateStore.getState(); await store.fetchRates(); } // 환율 변환 헬퍼 함수들 export function formatWithExchangeRate( krwAmount: number, currency: 'USD' | 'MNT' | 'RUB' | 'CNY' | 'EUR' ): string { const store = useExchangeRateStore.getState(); const converted = store.convertKrwTo(krwAmount, currency); const symbol = store.rates[currency]?.symbol || DEFAULT_RATES[currency]?.symbol || ''; return `${symbol}${converted.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: currency === 'USD' ? 0 : 0, })}`; }