108 lines
3.5 KiB
TypeScript

import { createAction, createReducer } from '@reduxjs/toolkit';
import { VerifyOtpResponse } from '../../../interfaces';
import { loginWithPhone, verifyOtp, logoutUser, updateProfile } from './thunk';
import { LoginResponse, User } from '@interfaces/auth';
// ─── Sync Actions ─────────────────────────────────────────────────────────────
export const completeOnboarding = createAction('auth/completeOnboarding');
// ─── State ───────────────────────────────────────────────────────────────────
export interface AuthState {
loginData: LoginResponse | null;
user: User | null;
accessToken: string | null;
refreshToken: string | null;
isNewUser: boolean | null;
error: string | null;
isLoading: boolean;
}
const initialState: AuthState = {
loginData: null,
user: null,
accessToken: null,
refreshToken: null,
isNewUser: null,
isLoading: false,
error: null,
};
// ─── Reducer ─────────────────────────────────────────────────────────────────
const authReducer = createReducer(initialState, builder => {
builder
// Login
.addCase(loginWithPhone.pending, state => {
state.isLoading = true;
state.error = null;
})
.addCase(loginWithPhone.fulfilled, (state, action) => {
state.loginData = action.payload;
state.isLoading = false;
state.error = null;
})
.addCase(loginWithPhone.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload as string;
})
// Verify OTP
.addCase(verifyOtp.pending, state => {
state.isLoading = true;
state.error = null;
})
.addCase(verifyOtp.fulfilled, (state, action) => {
const { user, accessToken, refreshToken, isNewUser } = action.payload;
state.user = user;
state.accessToken = accessToken;
state.refreshToken = refreshToken;
state.isNewUser = isNewUser;
state.isLoading = false;
state.error = null;
})
.addCase(verifyOtp.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload as string;
})
// Complete Onboarding — flips user.status so RootNavigator swaps to AppStack
.addCase(completeOnboarding, state => {
if (state.user) {
state.user = { ...state.user, status: 'ACTIVE' };
}
})
// Update Profile
.addCase(updateProfile.fulfilled, (state, action) => {
if (state.user && action.payload?.status) {
state.user = { ...state.user, status: action.payload.status };
}
state.isLoading = false;
state.error = null;
})
// Logout — clear all auth state
.addCase(logoutUser.fulfilled, state => {
state.user = null;
state.accessToken = null;
state.refreshToken = null;
state.loginData = null;
state.isNewUser = null;
state.isLoading = false;
state.error = null;
})
.addCase(logoutUser.rejected, state => {
// Even on failure, clear local auth state (tokens already cleared by thunk)
state.user = null;
state.accessToken = null;
state.refreshToken = null;
state.loginData = null;
state.isNewUser = null;
state.isLoading = false;
});
});
export default authReducer;