feat(auth): implement role-based dashboard redirect
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import type { PayloadAction } from "@reduxjs/toolkit";
|
||||
import { loginWithEmail, logout, getCurrentUser } from "../../services/authService";
|
||||
import { fetchUserData } from "../../services/firestoreService";
|
||||
import type { User } from "firebase/auth";
|
||||
|
||||
export interface AuthUser {
|
||||
@@ -8,7 +9,7 @@ export interface AuthUser {
|
||||
email: string | null;
|
||||
displayName: string | null;
|
||||
photoURL: string | null;
|
||||
role?: string;
|
||||
userRole?: "admin" | "client" | "vendor";
|
||||
}
|
||||
|
||||
interface AuthState {
|
||||
@@ -27,6 +28,7 @@ const initialState: AuthState = {
|
||||
|
||||
/**
|
||||
* Async thunk for user login
|
||||
* Fetches user data including role from Firestore after authentication
|
||||
*/
|
||||
export const loginUser = createAsyncThunk(
|
||||
"auth/loginUser",
|
||||
@@ -38,11 +40,25 @@ export const loginUser = createAsyncThunk(
|
||||
}
|
||||
|
||||
const firebaseUser = result.user as User;
|
||||
|
||||
// Fetch user role from Firestore
|
||||
let userRole: "admin" | "client" | "vendor" = "client";
|
||||
try {
|
||||
const userData = await fetchUserData(firebaseUser.uid);
|
||||
if (userData) {
|
||||
userRole = userData.userRole;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch user role:", error);
|
||||
// Continue with default role on error
|
||||
}
|
||||
|
||||
return {
|
||||
uid: firebaseUser.uid,
|
||||
email: firebaseUser.email,
|
||||
displayName: firebaseUser.displayName,
|
||||
photoURL: firebaseUser.photoURL,
|
||||
userRole: userRole,
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -62,16 +78,30 @@ export const logoutUser = createAsyncThunk("auth/logoutUser", async (_, { reject
|
||||
|
||||
/**
|
||||
* Async thunk to check if user is already logged in
|
||||
* Fetches user role from Firestore on app initialization
|
||||
*/
|
||||
export const checkAuthStatus = createAsyncThunk("auth/checkAuthStatus", async () => {
|
||||
export const checkAuthStatus = createAsyncThunk("auth/checkAuthStatus", async (_, { rejectWithValue }) => {
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
if (currentUser) {
|
||||
// Fetch user role from Firestore
|
||||
let userRole: "admin" | "client" | "vendor" = "client";
|
||||
try {
|
||||
const userData = await fetchUserData(currentUser.uid);
|
||||
if (userData) {
|
||||
userRole = userData.userRole;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch user role:", error);
|
||||
// Continue with default role on error
|
||||
}
|
||||
|
||||
return {
|
||||
uid: currentUser.uid,
|
||||
email: currentUser.email,
|
||||
displayName: currentUser.displayName,
|
||||
photoURL: currentUser.photoURL,
|
||||
userRole: userRole,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,9 +115,9 @@ const authSlice = createSlice({
|
||||
clearError: (state) => {
|
||||
state.error = null;
|
||||
},
|
||||
setRole: (state, action: PayloadAction<string>) => {
|
||||
setUserRole: (state, action: PayloadAction<"admin" | "client" | "vendor">) => {
|
||||
if (state.user) {
|
||||
state.user.role = action.payload;
|
||||
state.user.userRole = action.payload;
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -137,5 +167,5 @@ const authSlice = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const { clearError, setRole } = authSlice.actions;
|
||||
export const { clearError, setUserRole } = authSlice.actions;
|
||||
export default authSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user