import { createSlice, PayloadAction } from '@reduxjs/toolkit' import { Address } from 'viem' import { PortfolioTabs, FetchState, setActiveTab, resetPortfolioState, typeSearchInput, resetSearchState, } from './actions' import { fetchAndStorePortfolioBalances, fetchAndStoreSingleNetworkPortfolioBalances, fetchAndStoreSearchInputPortfolioBalances, } from './hooks' import { NetworkTokenBalances } from '@/utils/actions/fetchPortfolioBalances' export interface PortfolioState { activeTab: PortfolioTabs balances: NetworkTokenBalances poolTokenBalances: NetworkTokenBalances status: FetchState error?: string searchInput: string searchedBalances: { [index: Address]: NetworkTokenBalances } searchStatus: FetchState } export const initialState: PortfolioState = { activeTab: PortfolioTabs.PORTFOLIO, balances: {}, poolTokenBalances: {}, status: FetchState.IDLE, error: null, searchInput: '', searchedBalances: {}, searchStatus: FetchState.IDLE, } export const portfolioSlice = createSlice({ name: 'portfolio', initialState, reducers: {}, extraReducers: (builder) => { builder .addCase(setActiveTab, (state, action: PayloadAction) => { state.activeTab = action.payload }) .addCase(typeSearchInput, (state, { payload: { searchInput } }) => { state.searchInput = searchInput }) .addCase(fetchAndStorePortfolioBalances.pending, (state) => { state.status = FetchState.LOADING }) .addCase(fetchAndStorePortfolioBalances.fulfilled, (state, action) => { state.status = FetchState.VALID state.balances = action.payload.balances state.poolTokenBalances = action.payload.poolTokenBalances }) .addCase(fetchAndStorePortfolioBalances.rejected, (state, action) => { state.status = FetchState.INVALID state.error = action.error.message }) .addCase(fetchAndStoreSearchInputPortfolioBalances.pending, (state) => { state.searchStatus = FetchState.LOADING }) .addCase( fetchAndStoreSearchInputPortfolioBalances.fulfilled, (state, action) => { const { balances, address } = action.payload state.searchStatus = FetchState.VALID state.searchedBalances[address] = balances } ) .addCase( fetchAndStoreSearchInputPortfolioBalances.rejected, (state, action) => { state.searchStatus = FetchState.INVALID state.error = action.error.message } ) .addCase( fetchAndStoreSingleNetworkPortfolioBalances.fulfilled, (state, action) => { const { balances, poolTokenBalances } = action.payload Object.entries(balances).forEach(([chainId, tokenBalances]) => { state.balances[chainId] = [...tokenBalances] }) Object.entries(poolTokenBalances).forEach( ([chainId, tokenBalances]) => { state.poolTokenBalances[chainId] = [...tokenBalances] } ) } ) .addCase(resetSearchState, (state) => { state.searchedBalances = initialState.searchedBalances state.searchStatus = initialState.searchStatus }) .addCase(resetPortfolioState, (state) => { state.activeTab = initialState.activeTab state.balances = initialState.balances state.status = initialState.status state.error = initialState.error state.searchInput = initialState.searchInput state.searchedBalances = initialState.searchedBalances state.searchStatus = initialState.searchStatus state.poolTokenBalances = initialState.poolTokenBalances }) }, }) export default portfolioSlice.reducer