import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; import { resellerDashboardService, ResellerDashboardStats, ResellerCustomer, ResellerProduct, ResellerSale, ResellerReceipt, ResellerPayment, ResellerRecentActivity } from '../../services/resellerDashboardService'; export interface ResellerDashboardState { stats: ResellerDashboardStats; customers: ResellerCustomer[]; products: ResellerProduct[]; sales: ResellerSale[]; receipts: ResellerReceipt[]; payments: ResellerPayment[]; recentActivities: ResellerRecentActivity[]; isLoading: boolean; error: string | null; } const initialState: ResellerDashboardState = { stats: { totalRevenue: 0, activeCustomers: 0, totalProducts: 0, commissionRate: 0, monthlyGrowth: 0, currency: 'USD', commissionEarned: 0, averageDealSize: 0, conversionRate: 0, }, customers: [], products: [], sales: [], receipts: [], payments: [], recentActivities: [], isLoading: false, error: null, }; // Async thunks export const fetchDashboardStats = createAsyncThunk( 'resellerDashboard/fetchStats', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getDashboardStats(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const fetchCustomers = createAsyncThunk( 'resellerDashboard/fetchCustomers', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getCustomers(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const fetchProducts = createAsyncThunk( 'resellerDashboard/fetchProducts', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getProducts(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const fetchSales = createAsyncThunk( 'resellerDashboard/fetchSales', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getSales(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const fetchReceipts = createAsyncThunk( 'resellerDashboard/fetchReceipts', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getReceipts(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const fetchPayments = createAsyncThunk( 'resellerDashboard/fetchPayments', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getPayments(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const fetchRecentActivities = createAsyncThunk( 'resellerDashboard/fetchRecentActivities', async (_, { rejectWithValue }) => { try { return await resellerDashboardService.getRecentActivities(); } catch (error: any) { return rejectWithValue(error.message); } } ); export const addCustomer = createAsyncThunk( 'resellerDashboard/addCustomer', async (customerData: Partial, { rejectWithValue }) => { try { return await resellerDashboardService.addCustomer(customerData); } catch (error: any) { return rejectWithValue(error.message); } } ); export const createSale = createAsyncThunk( 'resellerDashboard/createSale', async (saleData: Partial, { rejectWithValue }) => { try { return await resellerDashboardService.createSale(saleData); } catch (error: any) { return rejectWithValue(error.message); } } ); const resellerDashboardSlice = createSlice({ name: 'resellerDashboard', initialState, reducers: { setLoading: (state, action: PayloadAction) => { state.isLoading = action.payload; }, setError: (state, action: PayloadAction) => { state.error = action.payload; }, updateStats: (state, action: PayloadAction>) => { state.stats = { ...state.stats, ...action.payload }; }, addRecentActivity: (state, action: PayloadAction) => { state.recentActivities.unshift(action.payload); if (state.recentActivities.length > 20) { state.recentActivities = state.recentActivities.slice(0, 20); } }, updateCustomer: (state, action: PayloadAction) => { const index = state.customers.findIndex(c => c.id === action.payload.id); if (index !== -1) { state.customers[index] = action.payload; } }, removeCustomer: (state, action: PayloadAction) => { state.customers = state.customers.filter(c => c.id !== action.payload); }, addSale: (state, action: PayloadAction) => { state.sales.unshift(action.payload); if (state.sales.length > 100) { state.sales = state.sales.slice(0, 100); } }, addReceipt: (state, action: PayloadAction) => { state.receipts.unshift(action.payload); if (state.receipts.length > 100) { state.receipts = state.receipts.slice(0, 100); } }, addPayment: (state, action: PayloadAction) => { state.payments.unshift(action.payload); if (state.payments.length > 100) { state.payments = state.payments.slice(0, 100); } }, }, extraReducers: (builder) => { builder // Dashboard Stats .addCase(fetchDashboardStats.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchDashboardStats.fulfilled, (state, action) => { state.isLoading = false; state.stats = action.payload; }) .addCase(fetchDashboardStats.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Customers .addCase(fetchCustomers.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchCustomers.fulfilled, (state, action) => { state.isLoading = false; state.customers = action.payload; }) .addCase(fetchCustomers.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Products .addCase(fetchProducts.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchProducts.fulfilled, (state, action) => { state.isLoading = false; state.products = action.payload; }) .addCase(fetchProducts.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Sales .addCase(fetchSales.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchSales.fulfilled, (state, action) => { state.isLoading = false; state.sales = action.payload; }) .addCase(fetchSales.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Receipts .addCase(fetchReceipts.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchReceipts.fulfilled, (state, action) => { state.isLoading = false; state.receipts = action.payload; }) .addCase(fetchReceipts.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Payments .addCase(fetchPayments.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchPayments.fulfilled, (state, action) => { state.isLoading = false; state.payments = action.payload; }) .addCase(fetchPayments.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Recent Activities .addCase(fetchRecentActivities.pending, (state) => { state.isLoading = true; state.error = null; }) .addCase(fetchRecentActivities.fulfilled, (state, action) => { state.isLoading = false; state.recentActivities = action.payload; }) .addCase(fetchRecentActivities.rejected, (state, action) => { state.isLoading = false; state.error = action.payload as string; }) // Add Customer .addCase(addCustomer.fulfilled, (state, action) => { state.customers.unshift(action.payload); state.stats.activeCustomers += 1; }) // Create Sale .addCase(createSale.fulfilled, (state, action) => { state.sales.unshift(action.payload); state.stats.totalRevenue += action.payload.amount; state.stats.commissionEarned += action.payload.commission; }); }, }); export const { setLoading, setError, updateStats, addRecentActivity, updateCustomer, removeCustomer, addSale, addReceipt, addPayment, } = resellerDashboardSlice.actions; export default resellerDashboardSlice.reducer;