Cloudtopiaa_Reseller_Frontend/src/store/slices/authThunks.ts
2025-08-11 00:47:45 +05:30

211 lines
6.4 KiB
TypeScript

import { createAsyncThunk } from '@reduxjs/toolkit';
import { apiService, LoginRequest, RegisterRequest } from '../../services/api';
import { setLoading, setError, loginSuccess, logout, setTokens, setUser } from './authSlice';
export const loginUser = createAsyncThunk(
'auth/login',
async (credentials: LoginRequest, { dispatch }) => {
try {
dispatch(setLoading(true));
dispatch(setError(null));
const response = await apiService.login(credentials);
if (response.success && response.data) {
// Check if user account is blocked
const userStatus = response.data.user.status;
if (['inactive', 'pending', 'suspended'].includes(userStatus)) {
throw new Error(`Account access blocked. Status: ${userStatus}. Please contact your vendor administrator.`);
}
// Dispatch login success (tokens will be stored in the slice)
dispatch(loginSuccess({
user: response.data.user,
token: response.data.accessToken,
refreshToken: response.data.refreshToken,
sessionId: response.data.sessionId,
}));
return response.data;
} else {
throw new Error(response.message || 'Login failed');
}
} catch (error: any) {
const errorMessage = error.message || 'Login failed. Please try again.';
dispatch(setError(errorMessage));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const registerUser = createAsyncThunk(
'auth/register',
async (userData: RegisterRequest, { dispatch }) => {
try {
dispatch(setLoading(true));
dispatch(setError(null));
const response = await apiService.register(userData);
if (response.success) {
return response;
} else {
throw new Error(response.message || 'Registration failed');
}
} catch (error: any) {
const errorMessage = error.message || 'Registration failed. Please try again.';
dispatch(setError(errorMessage));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const verifyEmail = createAsyncThunk(
'auth/verifyEmail',
async ({ email, otp }: { email: string; otp: string }, { dispatch }) => {
try {
dispatch(setLoading(true));
dispatch(setError(null));
const response = await apiService.verifyEmail(email, otp);
if (response.success) {
return response;
} else {
throw new Error(response.message || 'Email verification failed');
}
} catch (error: any) {
const errorMessage = error.message || 'Email verification failed. Please try again.';
dispatch(setError(errorMessage));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const resendVerificationEmail = createAsyncThunk(
'auth/resendVerification',
async (email: string, { dispatch }) => {
try {
dispatch(setLoading(true));
dispatch(setError(null));
const response = await apiService.resendVerificationEmail(email);
if (response.success) {
return response;
} else {
throw new Error(response.message || 'Failed to resend verification email');
}
} catch (error: any) {
const errorMessage = error.message || 'Failed to resend verification email. Please try again.';
dispatch(setError(errorMessage));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const logoutUser = createAsyncThunk(
'auth/logout',
async (_, { dispatch, getState }) => {
try {
const state = getState() as any;
const sessionId = state.auth.sessionId;
if (sessionId) {
await apiService.logout(sessionId);
}
// Dispatch logout (localStorage will be cleared in the slice)
dispatch(logout());
} catch (error) {
console.error('Logout error:', error);
// Still logout locally even if API call fails
dispatch(logout());
}
}
);
export const getCurrentUser = createAsyncThunk(
'auth/getCurrentUser',
async (_, { dispatch }) => {
try {
dispatch(setLoading(true));
dispatch(setError(null));
const response = await apiService.getCurrentUser();
if (response.success) {
// Check if user account is blocked
const userStatus = response.data.status;
if (['inactive', 'pending', 'suspended'].includes(userStatus)) {
// Force logout if account is blocked
dispatch(logout());
throw new Error(`Account access blocked. Status: ${userStatus}. Please contact your vendor administrator.`);
}
dispatch(setUser(response.data));
return response.data;
} else {
throw new Error('Failed to get current user');
}
} catch (error: any) {
const errorMessage = error.message || 'Failed to get current user';
dispatch(setError(errorMessage));
throw error;
} finally {
dispatch(setLoading(false));
}
}
);
export const refreshUserToken = createAsyncThunk(
'auth/refreshToken',
async (_, { dispatch, getState }) => {
try {
const state = getState() as any;
const refreshToken = state.auth.refreshToken;
if (!refreshToken) {
throw new Error('No refresh token available');
}
const response = await apiService.refreshToken(refreshToken);
if (response.success && response.data) {
// Check if user account is blocked (if user data is included in refresh response)
if (response.data.user) {
const userStatus = response.data.user.status;
if (['inactive', 'pending', 'suspended'].includes(userStatus)) {
// Force logout if account is blocked
dispatch(logout());
throw new Error(`Account access blocked. Status: ${userStatus}. Please contact your vendor administrator.`);
}
}
// Update tokens in store (localStorage will be updated in the slice)
dispatch(setTokens({
token: response.data.accessToken,
refreshToken: response.data.refreshToken,
sessionId: response.data.sessionId,
}));
return response.data;
} else {
throw new Error(response.message || 'Token refresh failed');
}
} catch (error: any) {
console.error('Token refresh failed:', error);
// If refresh fails, logout the user
dispatch(logoutUser());
throw error;
}
}
);