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