crypto-viewer/src/store/coins-prices.ts
2026-01-27 19:45:34 +01:00

98 lines
3.0 KiB
TypeScript

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<ICoinPricesState>((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);
};