diff --git a/src/api/getAssetsByWallet.ts b/src/api/getAssetsByWallet.ts deleted file mode 100644 index eff9538..0000000 --- a/src/api/getAssetsByWallet.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { handleApiResponse } from "api/handleApiResponse"; -import { API_URL } from "constants/settings"; -import { ApiAsset } from "types"; - -export const getAssetsByWallet = async ( - token: string, - walletId: string, -): Promise => { - const response = await fetch(`${API_URL}/assets?wallet=${walletId}`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }); - - return handleApiResponse(response); -}; diff --git a/src/api/getCountries.ts b/src/api/getCountries.ts deleted file mode 100644 index 835e0ae..0000000 --- a/src/api/getCountries.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { handleApiResponse } from "api/handleApiResponse"; -import { API_URL } from "constants/settings"; -import { ApiCountry } from "types"; - -export const getCountries = async (token: string): Promise => { - const response = await fetch(`${API_URL}/countries`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }); - - return handleApiResponse(response); -}; diff --git a/src/apiQueries/useCountries.ts b/src/apiQueries/useCountries.ts new file mode 100644 index 0000000..64dcf0f --- /dev/null +++ b/src/apiQueries/useCountries.ts @@ -0,0 +1,17 @@ +import { useQuery } from "@tanstack/react-query"; +import { API_URL } from "constants/settings"; +import { fetchApi } from "helpers/fetchApi"; +import { ApiCountry, AppError } from "types"; + +export const useCountries = () => { + const query = useQuery({ + queryKey: ["countries"], + queryFn: async () => { + return await fetchApi(`${API_URL}/countries`); + }, + // Keeping the fetched data for longer since it won't change that often + staleTime: 5 * 60 * 1000, + }); + + return query; +}; diff --git a/src/components/DisbursementDetails/index.tsx b/src/components/DisbursementDetails/index.tsx index 15c9ec1..e2179dd 100644 --- a/src/components/DisbursementDetails/index.tsx +++ b/src/components/DisbursementDetails/index.tsx @@ -1,4 +1,3 @@ -import { useEffect } from "react"; import { Card, Input, @@ -6,16 +5,12 @@ import { Title, Notification, } from "@stellar/design-system"; -import { useDispatch } from "react-redux"; - -import { AppDispatch } from "store"; -import { getCountriesAction } from "store/ducks/countries"; import { useWallets } from "apiQueries/useWallets"; import { useAssetsByWallet } from "apiQueries/useAssetsByWallet"; +import { useCountries } from "apiQueries/useCountries"; import { InfoTooltip } from "components/InfoTooltip"; import { formatUploadedFileDisplayName } from "helpers/formatUploadedFileDisplayName"; -import { useRedux } from "hooks/useRedux"; import { ApiAsset, ApiCountry, @@ -61,8 +56,6 @@ export const DisbursementDetails: React.FC = ({ onChange, onValidate, }: DisbursementDetailsProps) => { - const { countries } = useRedux("countries"); - enum FieldId { NAME = "name", COUNTRY_CODE = "country_code", @@ -76,23 +69,20 @@ export const DisbursementDetails: React.FC = ({ isLoading: isWalletsLoading, } = useWallets(); + const { + data: countries, + error: countriesError, + isLoading: isCountriesLoading, + } = useCountries(); + const { data: walletAssets, error: walletError, isFetching: isWalletAssetsFetching, } = useAssetsByWallet(details.wallet.id); - const dispatch: AppDispatch = useDispatch(); - - // Don't fetch again if we already have them in store - useEffect(() => { - if (!countries.status) { - dispatch(getCountriesAction()); - } - }, [dispatch, countries.status]); - const apiErrors = [ - countries.errorString, + countriesError?.message, walletsError?.message, walletError?.message, ]; @@ -141,9 +131,7 @@ export const DisbursementDetails: React.FC = ({ switch (id) { case FieldId.COUNTRY_CODE: // eslint-disable-next-line no-case-declarations - const country = countries.items.find( - (c: ApiCountry) => c.code === value, - ); + const country = countries?.find((c: ApiCountry) => c.code === value); updateState({ country: { @@ -244,10 +232,10 @@ export const DisbursementDetails: React.FC = ({ fieldSize="sm" onChange={updateDraftDetails} value={details.country.code} - disabled={countries.status === "PENDING"} + disabled={isCountriesLoading} > - {renderDropdownDefault(countries.status === "PENDING")} - {countries.items.map((country: ApiCountry) => ( + {renderDropdownDefault(isCountriesLoading)} + {countries?.map((country: ApiCountry) => ( diff --git a/src/store/ducks/countries.ts b/src/store/ducks/countries.ts deleted file mode 100644 index a58eb1a..0000000 --- a/src/store/ducks/countries.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; -import { RootState } from "store"; -import { getCountries } from "api/getCountries"; -import { handleApiErrorString } from "api/handleApiErrorString"; -import { endSessionIfTokenInvalid } from "helpers/endSessionIfTokenInvalid"; -import { - ApiCountry, - ApiError, - CountriesInitialState, - RejectMessage, -} from "types"; - -export const getCountriesAction = createAsyncThunk< - ApiCountry[], - undefined, - { rejectValue: RejectMessage; state: RootState } ->( - "countries/getCountriesAction", - async (_, { rejectWithValue, getState, dispatch }) => { - const { token } = getState().userAccount; - - try { - const countries = await getCountries(token); - return countries; - } catch (error: unknown) { - const errorString = handleApiErrorString(error as ApiError); - endSessionIfTokenInvalid(errorString, dispatch); - - return rejectWithValue({ - errorString: `Error fetching countries: ${errorString}`, - }); - } - }, -); - -const initialState: CountriesInitialState = { - items: [], - status: undefined, - errorString: undefined, -}; - -const countriesSlice = createSlice({ - name: "countries", - initialState, - reducers: {}, - extraReducers: (builder) => { - builder.addCase(getCountriesAction.pending, (state = initialState) => { - state.status = "PENDING"; - }); - builder.addCase(getCountriesAction.fulfilled, (state, action) => { - state.items = action.payload; - state.status = "SUCCESS"; - state.errorString = undefined; - }); - builder.addCase(getCountriesAction.rejected, (state, action) => { - state.status = "ERROR"; - state.errorString = action.payload?.errorString; - }); - }, -}); - -export const countriesSelector = (state: RootState) => state.countries; -export const { reducer } = countriesSlice; diff --git a/src/store/index.ts b/src/store/index.ts index 9a62def..2adf36f 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -9,7 +9,6 @@ import BigNumber from "bignumber.js"; import { RESET_STORE_ACTION_TYPE } from "constants/settings"; -import { reducer as countries } from "store/ducks/countries"; import { reducer as disbursementDetails } from "store/ducks/disbursementDetails"; import { reducer as disbursementDrafts } from "store/ducks/disbursementDrafts"; import { reducer as disbursements } from "store/ducks/disbursements"; @@ -32,7 +31,6 @@ const isSerializable = (value: any) => BigNumber.isBigNumber(value) || isPlain(value); const reducers = combineReducers({ - countries, disbursementDetails, disbursementDrafts, disbursements, diff --git a/src/types/index.ts b/src/types/index.ts index 4e4f80d..cb094bd 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -60,12 +60,6 @@ export type UserAccountInitialState = { restoredPathname?: string; }; -export type CountriesInitialState = { - items: ApiCountry[]; - status: ActionStatus | undefined; - errorString?: string; -}; - export type DisbursementDraftsInitialState = { items: DisbursementDraft[]; status: ActionStatus | undefined; @@ -119,7 +113,6 @@ export type ProfileInitialState = { }; export interface Store { - countries: CountriesInitialState; disbursementDetails: DisbursementDetailsInitialState; disbursementDrafts: DisbursementDraftsInitialState; disbursements: DisbursementsInitialState;