diff --git a/web/components/dashboard/UserStats.tsx b/web/components/dashboard/UserStats.tsx
index 380d078..08ef988 100644
--- a/web/components/dashboard/UserStats.tsx
+++ b/web/components/dashboard/UserStats.tsx
@@ -1,15 +1,27 @@
import { Box, SimpleGrid, chakra } from '@chakra-ui/react'
-import React from 'react'
+import React, { useEffect } from 'react'
import { useSelector } from 'react-redux'
-import { selectApiKeyList } from '../../store/apiKeySlice'
import { selectAuthUser } from '../../store/authSlice'
-import { selectDeviceList } from '../../store/deviceSlice'
import UserStatsCard from './UserStatsCard'
+import {
+ fetchStats,
+ selectStatsData,
+ selectStatsLoading,
+} from '../../store/statsSlice'
+import { useAppDispatch, useAppSelector } from '../../store/hooks'
const UserStats = () => {
const authUser = useSelector(selectAuthUser)
- const deviceList = useSelector(selectDeviceList)
- const apiKeyList = useSelector(selectApiKeyList)
+
+ const { totalApiKeyCount, totalDeviceCount, totalSMSCount } =
+ useAppSelector(selectStatsData)
+ const statsLoading = useAppSelector(selectStatsLoading)
+
+ const dispatch = useAppDispatch()
+
+ useEffect(() => {
+ dispatch(fetchStats())
+ }, [dispatch])
return (
<>
@@ -26,13 +38,16 @@ const UserStats = () => {
+
-
diff --git a/web/services/statsService.ts b/web/services/statsService.ts
new file mode 100644
index 0000000..b83c763
--- /dev/null
+++ b/web/services/statsService.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()
diff --git a/web/store/statsSlice.ts b/web/store/statsSlice.ts
new file mode 100644
index 0000000..896044f
--- /dev/null
+++ b/web/store/statsSlice.ts
@@ -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) => {
+ 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
diff --git a/web/store/store.ts b/web/store/store.ts
index 94f0589..1581172 100644
--- a/web/store/store.ts
+++ b/web/store/store.ts
@@ -2,12 +2,14 @@ import { configureStore } from '@reduxjs/toolkit'
import apiKeyReducer from './apiKeySlice'
import authReducer from './authSlice'
import deviceReducer from './deviceSlice'
+import statsReducer from './statsSlice'
export const store = configureStore({
reducer: {
auth: authReducer,
apiKey: apiKeyReducer,
device: deviceReducer,
+ stats: statsReducer,
},
})