4 changed files with 91 additions and 8 deletions
-
31web/components/dashboard/UserStats.tsx
-
10web/services/statsService.ts
-
56web/store/statsSlice.ts
-
2web/store/store.ts
@ -0,0 +1,10 @@ |
|||
import httpClient from '../lib/httpClient' |
|||
|
|||
class StatsService { |
|||
async getStats() { |
|||
const res = await httpClient.get(`/gateway/stats`) |
|||
return res.data.data |
|||
} |
|||
} |
|||
|
|||
export const statsService = new StatsService() |
|||
@ -0,0 +1,56 @@ |
|||
import { createAsyncThunk, createSlice, isAnyOf } from '@reduxjs/toolkit' |
|||
import type { PayloadAction } from '@reduxjs/toolkit' |
|||
import { createStandaloneToast } from '@chakra-ui/react' |
|||
import { RootState } from './store' |
|||
import { statsService } from '../services/statsService' |
|||
|
|||
const { toast } = createStandaloneToast() |
|||
|
|||
const initialState = { |
|||
loading: false, |
|||
data: { |
|||
totalApiKeyCount: 0, |
|||
totalDeviceCount: 0, |
|||
totalSMSCount: 0, |
|||
}, |
|||
} |
|||
|
|||
export const fetchStats = createAsyncThunk( |
|||
'gateway/fetchStats', |
|||
async (_, { rejectWithValue }) => { |
|||
try { |
|||
const res = await statsService.getStats() |
|||
return res |
|||
} catch (e) { |
|||
toast({ |
|||
title: e.response.data.error || 'Failed to Fetch stats', |
|||
status: 'error', |
|||
}) |
|||
return rejectWithValue(e.response.data) |
|||
} |
|||
} |
|||
) |
|||
|
|||
export const statsSlice = createSlice({ |
|||
name: 'stats', |
|||
initialState, |
|||
reducers: {}, |
|||
extraReducers: (builder) => { |
|||
builder |
|||
.addCase(fetchStats.fulfilled, (state, action: PayloadAction<any>) => { |
|||
state.loading = false |
|||
state.data = action.payload |
|||
}) |
|||
.addCase(fetchStats.rejected, (state) => { |
|||
state.loading = false |
|||
}) |
|||
.addMatcher(isAnyOf(fetchStats.pending), (state) => { |
|||
state.loading = true |
|||
}) |
|||
}, |
|||
}) |
|||
|
|||
export const selectStatsLoading = (state: RootState) => state.stats.loading |
|||
export const selectStatsData = (state: RootState) => state.stats.data |
|||
|
|||
export default statsSlice.reducer |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue