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; } } );