|
|
|
// store/slice/authslice.ts |
|
|
|
import { |
|
createAsyncThunk, |
|
createSlice, |
|
PayloadAction, |
|
} from "@reduxjs/toolkit"; |
|
import { AxiosError, AxiosResponse } from "axios"; |
|
import { useRouter } from "next/router"; |
|
import authService from "../../services/auth.service"; |
|
import useAuthService from "../../hooks/useAuthService"; |
|
import { User } from "../../interfaces/user.interface"; |
|
import Cookies from "js-cookie"; |
|
|
|
const key = "user"; |
|
|
|
// Get user data from cookie |
|
const userValue = Cookies.get(key); |
|
let initialUser = null; |
|
|
|
try { |
|
if (userValue) { |
|
// Parse the JSON string from the cookie |
|
initialUser = JSON.parse(userValue); |
|
} |
|
} catch (error) { |
|
console.error("Error parsing user object from cookie:", error); |
|
} |
|
|
|
type RegisterAction = ReturnType<typeof Register>; |
|
|
|
const setUserInCookie = (userData: User) => { |
|
const jsonUserData = JSON.stringify(userData); |
|
Cookies.set(key, jsonUserData); |
|
}; |
|
|
|
const removeUserFromCookie = () => { |
|
Cookies.remove(key); |
|
}; |
|
|
|
interface AuthState { |
|
user: User | null; |
|
isError: boolean; |
|
isLoading: boolean; |
|
isSuccess: boolean; |
|
message: string; |
|
} |
|
export interface RegisterPayload { |
|
email: string; |
|
password1: string; |
|
password2: string; |
|
} |
|
|
|
const initialState: AuthState = { |
|
user: initialUser, |
|
isError: false, |
|
isLoading: false, |
|
isSuccess: false, |
|
message: "", |
|
}; |
|
|
|
export const Register = createAsyncThunk( |
|
"accounts/register", |
|
async (userData: RegisterPayload, thunkAPI) => { |
|
try { |
|
const { email, password1, password2} = userData; |
|
|
|
return await authService.register( |
|
email, |
|
password1, |
|
password2 |
|
); |
|
} catch (error: any) { |
|
const message = |
|
(error.response && |
|
error.response.data && |
|
error.response.data.message) || |
|
error.message || |
|
error.toString(); |
|
return thunkAPI.rejectWithValue(message); |
|
} |
|
} |
|
); |
|
|
|
export const login = createAsyncThunk( |
|
"accounts/login", |
|
async (userData: { email: string; password: string }, thunkAPI) => { |
|
try { |
|
const { email, password } = userData; |
|
|
|
const response = await authService.login(email, password); |
|
const user = response.data.user; |
|
|
|
return user; |
|
} catch (error: any) { |
|
const message = |
|
(error.response && |
|
error.response.data && |
|
error.response.data.message) || |
|
error.message || |
|
error.toString(); |
|
|
|
return thunkAPI.rejectWithValue(message); |
|
} |
|
} |
|
); |
|
|
|
export const logout = createAsyncThunk("accounts/logout", async () => { |
|
authService.logout(); |
|
}); |
|
|
|
|
|
export const authSlice = createSlice({ |
|
name: "auth", |
|
initialState, |
|
reducers: { |
|
reset: (state) => { |
|
state.isLoading = false; |
|
state.isError = false; |
|
state.isSuccess = false; |
|
state.message = ""; |
|
}, |
|
setUser: (state, action: PayloadAction<User | null>) => { |
|
state.user = action.payload; |
|
}, |
|
}, |
|
extraReducers: (builder) => { |
|
builder |
|
.addCase(Register.pending, (state) => { |
|
state.isLoading = true; |
|
}) |
|
.addCase(Register.fulfilled, (state, action) => { |
|
state.isLoading = false; |
|
state.isSuccess = true; |
|
state.user = action.payload; |
|
}) |
|
.addCase(Register.rejected, (state, action) => { |
|
state.isLoading = false; |
|
state.isError = true; |
|
state.message = action.payload as string; |
|
state.user = null; |
|
}) |
|
.addCase(login.pending, (state) => { |
|
state.isLoading = true; |
|
}) |
|
.addCase(login.fulfilled, (state, action) => { |
|
state.isLoading = false; |
|
state.isSuccess = true; |
|
state.user = action.payload; |
|
}) |
|
.addCase(login.rejected, (state, action) => { |
|
state.isLoading = false; |
|
state.isError = true; |
|
state.message = action.payload as string; |
|
state.user = null; |
|
}) |
|
.addCase(logout.fulfilled, (state) => { |
|
state.user = null; |
|
}) |
|
}, |
|
}); |
|
|
|
export const { reset, setUser } = authSlice.actions; |
|
export const selectUser = (state: { auth: AuthState }) => state.auth.user; |
|
export default authSlice.reducer; |
|
|
|
|