Skip to content

Commit

Permalink
feat: Add common slice and common service (#877)
Browse files Browse the repository at this point in the history
* feat: Add common slice and common service

* chore

* Add types file

* chore

* Review changes

* chore
  • Loading branch information
Hemanthghs authored Nov 20, 2023
1 parent 20f713b commit ee2b387
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 0 deletions.
23 changes: 23 additions & 0 deletions frontend/src/store/features/common/commonService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';

import Axios, { AxiosResponse } from 'axios';
import { cleanURL } from '../../../utils/util';

const BASE_URL = process.env.BACKEND_URI;

const fetchPriceInfo = (denom: string): Promise<AxiosResponse> => {
const uri = `${cleanURL(BASE_URL)}/tokens-info/${denom}`;
return Axios.get(uri);
};

const fetchAllTokensPriceInfo = (): Promise<AxiosResponse> => {
const uri = `${cleanURL(BASE_URL)}/tokens-info`;
return Axios.get(uri);
};

const result = {
tokenInfo: fetchPriceInfo,
allTokensInfo: fetchAllTokensPriceInfo,
};

export default result;
154 changes: 154 additions & 0 deletions frontend/src/store/features/common/commonSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
'use client';

import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import commonService from './commonService';
import { AxiosError } from 'axios';
import { ERR_UNKNOWN } from '../../../utils/errors';

const initialState: CommonState = {
errState: {
message: '',
type: '',
},
txSuccess: {
hash: '',
},
txLoadRes: { load: false },
tokensInfoState: {
error: '',
info: {
denom: '',
coingecko_name: '',
enabled: false,
last_updated: '',
info: { usd: NaN, usd_24h_change: NaN },
},
status: 'idle',
},
allTokensInfoState: {
error: '',
info: {},
status: 'idle',
},
selectedNetwork: {
chainName: '',
},
};

export const getTokenPrice = createAsyncThunk(
'common/getTokenPrice',
async (data: string, { rejectWithValue }) => {
try {
const response = await commonService.tokenInfo(data);
return response.data;
} catch (error) {
if (error instanceof AxiosError) return rejectWithValue(error.message);
return rejectWithValue(ERR_UNKNOWN);
}
}
);

export const getAllTokensPrice = createAsyncThunk(
'common/getAllTokensPrice',
async (data, { rejectWithValue }) => {
try {
const response = await commonService.allTokensInfo();
return response.data;
} catch (error) {
if (error instanceof AxiosError) return rejectWithValue(error.message);
return rejectWithValue(ERR_UNKNOWN);
}
}
);

export const commonSlice = createSlice({
name: 'common',
initialState,
reducers: {
setError: (state, action: PayloadAction<ErrorState>) => {
state.errState = {
message: action.payload.message,
type: action.payload.type,
};
},
setTxHash: (state, action: PayloadAction<TxSuccess>) => {
state.txSuccess = {
hash: action.payload.hash,
};
},
setTxLoad: (state) => {
state.txLoadRes = { load: true };
},
resetTxLoad: (state) => {
state.txLoadRes = { load: false };
},
resetTxHash: (state) => {
state.txSuccess = {
hash: '',
};
},
resetError: (state) => {
state.errState = {
message: '',
type: '',
};
},
setSelectedNetwork: (state, action: PayloadAction<SelectedNetwork>) => {
state.selectedNetwork.chainName = action.payload.chainName;
},
},
extraReducers: (builder) => {
builder
.addCase(getTokenPrice.pending, (state) => {
state.tokensInfoState.status = 'pending';
state.tokensInfoState.error = '';
})
.addCase(getTokenPrice.fulfilled, (state, action) => {
state.tokensInfoState.status = 'idle';
state.tokensInfoState.error = '';
state.tokensInfoState.info =
action.payload.data || initialState.tokensInfoState.info;
})
.addCase(getTokenPrice.rejected, (state, action) => {
state.tokensInfoState.status = 'rejected';
state.tokensInfoState.error = JSON.stringify(action.payload) || '';
state.tokensInfoState.info = initialState.tokensInfoState.info;
});

builder
.addCase(getAllTokensPrice.pending, (state) => {
state.allTokensInfoState.status = 'pending';
state.allTokensInfoState.error = '';
})
.addCase(getAllTokensPrice.fulfilled, (state, action) => {
const data = action.payload.data || [];
const tokensPriceInfo = data.reduce(
(result: Record<string, InfoState>, tokenInfo: InfoState) => {
result[tokenInfo.denom] = tokenInfo;
return result;
},
{}
);
state.allTokensInfoState.status = 'idle';
state.allTokensInfoState.error = '';
state.allTokensInfoState.info = tokensPriceInfo;
})
.addCase(getAllTokensPrice.rejected, (state, action) => {
state.allTokensInfoState.status = 'rejected';
state.allTokensInfoState.error = JSON.stringify(action.payload) || '';
state.allTokensInfoState.info = {};
});
},
});

export const {
setError,
resetError,
setTxLoad,
resetTxLoad,
setTxHash,
resetTxHash,
setSelectedNetwork,
} = commonSlice.actions;

export default commonSlice.reducer;
2 changes: 2 additions & 0 deletions frontend/src/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import { configureStore } from '@reduxjs/toolkit';
import multisigSlice from './features/multisig/multisigSlice';
import walletSlice from './features/wallet/walletSlice';
import commonSlice from './features/common/commonSlice';
import stakeSlice from './features/staking/stakeSlice';
import bankSlice from './features/bank/bankSlice';

export const store = configureStore({
reducer: {
wallet: walletSlice,
multisig: multisigSlice,
common: commonSlice,
staking: stakeSlice,
bank: bankSlice,
},
Expand Down
50 changes: 50 additions & 0 deletions frontend/src/types/common.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
interface ErrorState {
message: string;
type: string;
}

interface TxSuccess {
hash: string;
}

interface TxLoadRes {
load: boolean;
}

interface TokenInfo {
usd: number;
usd_24h_change: number;
}

interface InfoState {
denom: string;
coingecko_name: string;
enabled: boolean;
last_updated: string;
info: TokenInfo;
}

interface TokensInfoState {
error: string;
info: InfoState;
status: string;
}

interface SelectedNetwork {
chainName: string;
}

interface AllTokensInfoState {
error: string;
info: Record<string, InfoState>;
status: string;
}

interface CommonState {
errState: ErrorState;
txSuccess: TxSuccess;
txLoadRes: TxLoadRes;
tokensInfoState: TokensInfoState;
selectedNetwork: SelectedNetwork;
allTokensInfoState: AllTokensInfoState;
}

0 comments on commit ee2b387

Please sign in to comment.