221 lines
6.1 KiB
TypeScript
221 lines
6.1 KiB
TypeScript
// type PayloadAction<T> = {
|
|
// type: string;
|
|
// payload: T;
|
|
// }
|
|
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import * as SecureStore from "expo-secure-store";
|
|
import urls, { STORAGE_KEYS, MESSAGES } from "../constants/config";
|
|
import { AUTH_STATUSES, StatusType } from "../constants/types";
|
|
|
|
interface AuthState {
|
|
phone: string | null;
|
|
otpId: number | null;
|
|
isLoggedIn: boolean;
|
|
status: StatusType;
|
|
sendOTPError: string | null;
|
|
verifyOTPError: string | null;
|
|
generalError: string | null;
|
|
}
|
|
|
|
interface SendOTPResponse {
|
|
status: boolean;
|
|
message: string;
|
|
data: {
|
|
otpId: number;
|
|
};
|
|
}
|
|
|
|
interface VerifyOTPResponse {
|
|
status: boolean;
|
|
message: string;
|
|
token: string;
|
|
refreshToken: string;
|
|
}
|
|
|
|
interface SendOTPParams {
|
|
phone: string | null;
|
|
}
|
|
|
|
interface VerifyOTPParams {
|
|
phone: string | null;
|
|
otp: string | null;
|
|
otpId: number | null;
|
|
}
|
|
|
|
const initialState: AuthState = {
|
|
phone: null,
|
|
otpId: null,
|
|
isLoggedIn: false,
|
|
status: AUTH_STATUSES.IDLE,
|
|
sendOTPError: null,
|
|
verifyOTPError: null,
|
|
generalError: null,
|
|
};
|
|
|
|
//async thunk to send otp
|
|
export const sendOTP = createAsyncThunk<SendOTPResponse, SendOTPParams>(
|
|
"auth/sendOTP",
|
|
async (params, { rejectWithValue }) => {
|
|
try {
|
|
console.log(urls.BASE_URL, "BASE_URL");
|
|
// const response = await axios.post<SendOTPResponse>(
|
|
// `${urls.BASE_URL}/send-otp`,
|
|
// params
|
|
// );
|
|
// return response.data;
|
|
return {
|
|
status: true,
|
|
message: "Done",
|
|
data: {
|
|
otpId: 22,
|
|
},
|
|
};
|
|
// if (!response.data.status) throw new Error(response.data.message);
|
|
} catch (error: any) {
|
|
return rejectWithValue(error.response?.data?.message || error.message);
|
|
}
|
|
}
|
|
);
|
|
|
|
export const verifyOTP = createAsyncThunk<VerifyOTPResponse, VerifyOTPParams>(
|
|
"auth/verifyOTP",
|
|
async (params, { rejectWithValue }) => {
|
|
try {
|
|
return {
|
|
status: true,
|
|
message: "Done",
|
|
token: "token",
|
|
refreshToken: "refreshToken",
|
|
};
|
|
// const response = await axios.post<VerifyOTPResponse>(
|
|
// `${urls.BASE_URL}/verify-otp`,
|
|
// params
|
|
// );
|
|
// if (!response.data.status) throw new Error(response.data.message);
|
|
|
|
// // Store tokens
|
|
// await AsyncStorage.setItem(STORAGE_KEYS.AUTH_TOKEN, response.data.token);
|
|
// await SecureStore.setItemAsync(
|
|
// STORAGE_KEYS.REFRESH_TOKEN,
|
|
// response.data.refreshToken
|
|
// );
|
|
|
|
// return response.data;
|
|
} catch (error: any) {
|
|
return rejectWithValue(MESSAGES.AUTHENTICATION.VERIFICATION_FAILED);
|
|
}
|
|
}
|
|
);
|
|
|
|
export const logout = createAsyncThunk(
|
|
"auth/logout",
|
|
async (_, { dispatch }) => {
|
|
await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN);
|
|
await SecureStore.deleteItemAsync(STORAGE_KEYS.REFRESH_TOKEN);
|
|
dispatch(authSlice.actions.logout());
|
|
}
|
|
);
|
|
|
|
const authSlice = createSlice({
|
|
name: "auth",
|
|
initialState,
|
|
reducers: {
|
|
loginRequest: (state) => {
|
|
state.status = AUTH_STATUSES.LOADING;
|
|
},
|
|
loginSuccess: (state, action) => {
|
|
state.status = AUTH_STATUSES.SUCCESS;
|
|
state.isLoggedIn = true; // Set logged-in state to true
|
|
},
|
|
setIsLoggedIn: (state, action) => {
|
|
state.isLoggedIn = action.payload;
|
|
},
|
|
loginFailure: (state, action: PayloadAction<string>) => {
|
|
state.status = AUTH_STATUSES.FAILED;
|
|
state.generalError = action.payload;
|
|
},
|
|
logout: (state) => {
|
|
state.isLoggedIn = false;
|
|
},
|
|
clearSendOTPError: (state) => {
|
|
state.sendOTPError = null;
|
|
},
|
|
clearVerifyOTPError: (state) => {
|
|
state.verifyOTPError = null;
|
|
},
|
|
clearAllErrors: (state) => {
|
|
state.sendOTPError = null;
|
|
state.verifyOTPError = null;
|
|
state.generalError = null;
|
|
},
|
|
},
|
|
extraReducers: (builder) => {
|
|
builder
|
|
.addCase(sendOTP.pending, (state) => {
|
|
state.status = AUTH_STATUSES.LOADING;
|
|
state.sendOTPError = null;
|
|
})
|
|
.addCase(sendOTP.fulfilled, (state, action) => {
|
|
state.status = AUTH_STATUSES.SUCCESS;
|
|
state.otpId = action.payload.data.otpId;
|
|
state.phone = action.meta.arg.phone;
|
|
state.sendOTPError = null;
|
|
})
|
|
.addCase(sendOTP.rejected, (state, action) => {
|
|
state.status = AUTH_STATUSES.FAILED;
|
|
state.sendOTPError = action.error.message || "Failed to send OTP";
|
|
})
|
|
.addCase(verifyOTP.pending, (state) => {
|
|
state.status = AUTH_STATUSES.LOADING;
|
|
state.verifyOTPError = null;
|
|
})
|
|
.addCase(verifyOTP.fulfilled, (state, action) => {
|
|
state.status = AUTH_STATUSES.SUCCESS;
|
|
state.isLoggedIn = true;
|
|
state.verifyOTPError = null;
|
|
const token = action.payload.token;
|
|
AsyncStorage.setItem(STORAGE_KEYS.AUTH_TOKEN, token).catch((error) => {
|
|
console.log("Error storing token", error);
|
|
});
|
|
|
|
const refreshToken = action.payload.refreshToken;
|
|
SecureStore.setItemAsync(
|
|
STORAGE_KEYS.REFRESH_TOKEN,
|
|
refreshToken
|
|
).catch((error) => {
|
|
console.log("Error storing refresh token", error);
|
|
});
|
|
})
|
|
.addCase(verifyOTP.rejected, (state, action) => {
|
|
state.status = AUTH_STATUSES.FAILED;
|
|
state.verifyOTPError = action.error.message || "Failed to verify OTP";
|
|
})
|
|
.addCase(logout.pending, (state) => {
|
|
state.status = AUTH_STATUSES.LOADING;
|
|
})
|
|
.addCase(logout.fulfilled, (state) => {
|
|
state.otpId = null;
|
|
state.isLoggedIn = false;
|
|
state.status = AUTH_STATUSES.IDLE;
|
|
state.verifyOTPError = null;
|
|
state.generalError = null;
|
|
state.sendOTPError = null;
|
|
state.phone = null;
|
|
})
|
|
.addCase(logout.rejected, (state, action) => {
|
|
state.status = AUTH_STATUSES.FAILED;
|
|
state.generalError = action.error.message || "Failed to log out";
|
|
});
|
|
},
|
|
});
|
|
|
|
export const {
|
|
logout: localLogout,
|
|
clearSendOTPError,
|
|
clearVerifyOTPError,
|
|
clearAllErrors,
|
|
} = authSlice.actions;
|
|
|
|
export default authSlice.reducer;
|