import { create } from "zustand"; import axios, { AxiosError } from "axios"; import { join } from "../utils/path"; import { messages } from "../utils/constants"; import { apiBaseUrl, apiKey } from "../utils/conf"; import { ICoinPrice } from "../utils/interfaces" const init = { coinId: null, coinPrices: null, loading: false, error: null, } interface ICoinPricesState { coinId: string | null; coinPrices: ICoinPrice[] | null; loading: boolean; error: string | null; reset: () => void; persistCoinPrices: (coinId: string, coinPrices: ICoinPrice[]) => void; setError: (message: string) => void; fetch: (coinId: string, limit: number) => void; } export const useCoinPricesStore = create((set, get) => { return { ...init, reset: () => { set(state => ({ ...init, })) }, persistCoinPrices: (coinId, coinPrices) => { set(state => ({ coinId: coinId, coinPrices: coinPrices, })) }, setError: (message) => { set(state => ({ error: message, })) }, fetch: async (coinId, limit) => { try { set({ loading: true }); const keyParam = (apiKey()) ? `&x_cg_demo_api_key=${apiKey()}` : ""; const url = join(apiBaseUrl(), `coins/${coinId}/market_chart?vs_currency=usd&days=${limit}${keyParam}`); const res = await axios.get(url); let prices: ICoinPrice[] = res.data?.["prices"].map((item: any) => { let price: ICoinPrice = { price: item[1], timestamp: item[0], } return price; }); get().persistCoinPrices(coinId, prices); } catch (err) { if (axios.isAxiosError(err)) { switch (err.code) { case 'ERR_NETWORK': get().setError(messages.serverOverload); break; default: get().setError(err.message); } } else { get().setError((err as Error).message); } } finally { set({ loading: false }); } } } }); export const reset = () => { useCoinPricesStore.getState().reset(); } export const persist = (coinId: string, prices: ICoinPrice[]) => { useCoinPricesStore.getState().persistCoinPrices(coinId, prices); }; export const toggleLoading = (isLoading: boolean) => { useCoinPricesStore.setState({ loading: isLoading }) }; export const errorLoading = (message: string) => { useCoinPricesStore.setState({ error: message }); }; export const fetchCoinPrices = (coinId: string, limit = 10) => { useCoinPricesStore.getState().fetch(coinId, limit); };