Cloudtopiaa_Reseller_Frontend/src/store/reseller/resellerDashboardSlice.ts
2025-08-11 18:04:34 +05:30

304 lines
9.0 KiB
TypeScript

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<ResellerCustomer>, { rejectWithValue }) => {
try {
return await resellerDashboardService.addCustomer(customerData);
} catch (error: any) {
return rejectWithValue(error.message);
}
}
);
export const createSale = createAsyncThunk(
'resellerDashboard/createSale',
async (saleData: Partial<ResellerSale>, { 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<boolean>) => {
state.isLoading = action.payload;
},
setError: (state, action: PayloadAction<string | null>) => {
state.error = action.payload;
},
updateStats: (state, action: PayloadAction<Partial<ResellerDashboardStats>>) => {
state.stats = { ...state.stats, ...action.payload };
},
addRecentActivity: (state, action: PayloadAction<ResellerRecentActivity>) => {
state.recentActivities.unshift(action.payload);
if (state.recentActivities.length > 20) {
state.recentActivities = state.recentActivities.slice(0, 20);
}
},
updateCustomer: (state, action: PayloadAction<ResellerCustomer>) => {
const index = state.customers.findIndex(c => c.id === action.payload.id);
if (index !== -1) {
state.customers[index] = action.payload;
}
},
removeCustomer: (state, action: PayloadAction<string>) => {
state.customers = state.customers.filter(c => c.id !== action.payload);
},
addSale: (state, action: PayloadAction<ResellerSale>) => {
state.sales.unshift(action.payload);
if (state.sales.length > 100) {
state.sales = state.sales.slice(0, 100);
}
},
addReceipt: (state, action: PayloadAction<ResellerReceipt>) => {
state.receipts.unshift(action.payload);
if (state.receipts.length > 100) {
state.receipts = state.receipts.slice(0, 100);
}
},
addPayment: (state, action: PayloadAction<ResellerPayment>) => {
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;