149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import { createReducer, createAction, PayloadAction } from '@reduxjs/toolkit';
|
|
import { PartnerProfile, PartnerLocation } from '@app-types/index';
|
|
import {
|
|
getProfileThunk,
|
|
updateProfileThunk,
|
|
loginWithPhone,
|
|
verifyOtp,
|
|
} from './thunk';
|
|
import { LoginResponse, User } from '@interfaces';
|
|
import { getDashboard } from '@features/screens/onboardingCompleteScreen/thunk';
|
|
|
|
export interface AuthState {
|
|
isAuthenticated: boolean;
|
|
loginData: LoginResponse | null;
|
|
user: User | null;
|
|
accessToken: string | null;
|
|
refreshToken: string | null;
|
|
isNewUser: boolean | null;
|
|
hasCompletedOnboarding: boolean;
|
|
isOnline: boolean;
|
|
token: string | null;
|
|
partnerId: string | null;
|
|
partnerProfile: PartnerProfile | null;
|
|
requestId: string | null;
|
|
loading: boolean;
|
|
error: string | null;
|
|
}
|
|
|
|
const initialState: AuthState = {
|
|
isAuthenticated: false,
|
|
user: null,
|
|
accessToken: null,
|
|
refreshToken: null,
|
|
isNewUser: null,
|
|
hasCompletedOnboarding: false,
|
|
isOnline: false,
|
|
token: null,
|
|
partnerId: null,
|
|
partnerProfile: null,
|
|
requestId: null,
|
|
loading: false,
|
|
error: null,
|
|
loginData: null,
|
|
};
|
|
|
|
export const setAuthenticated = createAction<{
|
|
token: string;
|
|
partnerId: string;
|
|
}>('auth/setAuthenticated');
|
|
export const setRequestId = createAction<string>('auth/setRequestId');
|
|
export const setOnboardingComplete = createAction('auth/setOnboardingComplete');
|
|
export const setOnlineStatus = createAction<boolean>('auth/setOnlineStatus');
|
|
export const setProfile = createAction<PartnerProfile>('auth/setProfile');
|
|
export const setLocation = createAction<PartnerLocation>('auth/setLocation');
|
|
export const logout = createAction('auth/logout');
|
|
|
|
export const authReducer = createReducer(initialState, builder => {
|
|
builder
|
|
// Sync Actions
|
|
.addCase(setAuthenticated, (state, action) => {
|
|
state.isAuthenticated = true;
|
|
state.token = action.payload.token;
|
|
state.partnerId = action.payload.partnerId;
|
|
})
|
|
.addCase(setRequestId, (state, action) => {
|
|
state.requestId = action.payload;
|
|
})
|
|
.addCase(setOnboardingComplete, state => {
|
|
state.hasCompletedOnboarding = true;
|
|
})
|
|
.addCase(setOnlineStatus, (state, action) => {
|
|
state.isOnline = action.payload;
|
|
})
|
|
.addCase(setProfile, (state, action) => {
|
|
state.partnerProfile = action.payload;
|
|
})
|
|
.addCase(setLocation, (state, action) => {
|
|
if (state.partnerProfile) {
|
|
state.partnerProfile.location = action.payload;
|
|
}
|
|
})
|
|
.addCase(logout, () => initialState)
|
|
// Async Thunks
|
|
// Login
|
|
.addCase(loginWithPhone.pending, state => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(loginWithPhone.fulfilled, (state, action) => {
|
|
state.loginData = action.payload;
|
|
state.loading = false;
|
|
state.error = null;
|
|
})
|
|
.addCase(loginWithPhone.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.payload as string;
|
|
})
|
|
// Verify OTP
|
|
.addCase(verifyOtp.pending, state => {
|
|
state.loading = 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.loading = false;
|
|
state.error = null;
|
|
})
|
|
.addCase(verifyOtp.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.payload as string;
|
|
})
|
|
.addCase(getProfileThunk.pending, state => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(getProfileThunk.fulfilled, (state, action) => {
|
|
state.loading = false;
|
|
state.partnerProfile = action.payload;
|
|
})
|
|
.addCase(getProfileThunk.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.payload as string;
|
|
})
|
|
.addCase(updateProfileThunk.pending, state => {
|
|
state.loading = true;
|
|
state.error = null;
|
|
})
|
|
.addCase(updateProfileThunk.fulfilled, (state, action) => {
|
|
state.loading = false;
|
|
state.partnerProfile = action.payload;
|
|
})
|
|
.addCase(updateProfileThunk.rejected, (state, action) => {
|
|
state.loading = false;
|
|
state.error = action.payload as string;
|
|
})
|
|
// When dashboard is fetched, sync user.status so rootNavigator
|
|
// automatically swaps from OnBoardingStack → AppStack
|
|
.addCase(getDashboard.fulfilled, (state, action) => {
|
|
const serverStatus = action.payload?.deliveryPartner?.user?.status;
|
|
if (state.user && serverStatus) {
|
|
state.user.status = serverStatus as User['status'];
|
|
}
|
|
});
|
|
});
|