diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 04f5ecd..c909f0e 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -1,26 +1,37 @@ -import { createContext, useContext, useReducer, useEffect } from 'react'; -import { AuthState, AdminUser, Permission } from '../types/auth'; +import React, { createContext, useContext, useReducer, useEffect } from 'react'; +import { AuthState, AdminUser, Permission, LoginRequest } from '../types/auth'; import toast from 'react-hot-toast'; -interface AuthContextType extends AuthState { +interface AuthContextType { + isAuthenticated: boolean; + isLoading: boolean; + user: AdminUser | null; + permissions: Permission[]; + allPermissions: Permission[]; + token: string | null; + refreshToken: string | null; logout: () => void; + restoreSession: () => void; hasPermission: (permissionId: number) => boolean; hasPermissionByTitle: (title: string) => boolean; - restoreSession: () => void; } const AuthContext = createContext(undefined); type AuthAction = - | { type: 'LOGIN_SUCCESS'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } } + | { type: 'LOGIN'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } } | { type: 'LOGOUT' } - | { type: 'RESTORE_SESSION'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } }; + | { type: 'RESTORE_SESSION'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } } + | { type: 'SET_LOADING'; payload: boolean }; const authReducer = (state: AuthState, action: AuthAction): AuthState => { switch (action.type) { - case 'LOGIN_SUCCESS': + case 'LOGIN': + case 'RESTORE_SESSION': return { + ...state, isAuthenticated: true, + isLoading: false, user: action.payload.user, permissions: action.payload.permissions, allPermissions: action.payload.allPermissions, @@ -29,21 +40,19 @@ const authReducer = (state: AuthState, action: AuthAction): AuthState => { }; case 'LOGOUT': return { + ...state, isAuthenticated: false, + isLoading: false, user: null, permissions: [], allPermissions: [], token: null, refreshToken: null, }; - case 'RESTORE_SESSION': + case 'SET_LOADING': return { - isAuthenticated: true, - user: action.payload.user, - permissions: action.payload.permissions, - allPermissions: action.payload.allPermissions, - token: action.payload.token, - refreshToken: action.payload.refreshToken, + ...state, + isLoading: action.payload, }; default: return state; @@ -52,6 +61,7 @@ const authReducer = (state: AuthState, action: AuthAction): AuthState => { const initialState: AuthState = { isAuthenticated: false, + isLoading: true, user: null, permissions: [], allPermissions: [], @@ -63,6 +73,8 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [state, dispatch] = useReducer(authReducer, initialState); const restoreSession = () => { + dispatch({ type: 'SET_LOADING', payload: true }); + const token = localStorage.getItem('admin_token'); const refreshToken = localStorage.getItem('admin_refresh_token'); const userStr = localStorage.getItem('admin_user'); @@ -88,7 +100,10 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { localStorage.removeItem('admin_refresh_token'); localStorage.removeItem('admin_user'); localStorage.removeItem('admin_permissions'); + dispatch({ type: 'SET_LOADING', payload: false }); } + } else { + dispatch({ type: 'SET_LOADING', payload: false }); } }; @@ -127,9 +142,9 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { {children} diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 82a8c3f..48873b4 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -10,12 +10,12 @@ import { loginSchema, LoginFormData } from '../utils/validationSchemas'; import { useLogin } from './auth/core/_hooks'; export const Login = () => { - const { isAuthenticated, restoreSession } = useAuth(); + const { isAuthenticated, isLoading, restoreSession } = useAuth(); const navigate = useNavigate(); const [showPassword, setShowPassword] = useState(false); const [error, setError] = useState(''); - const { mutate: login, isPending: isLoading } = useLogin(); + const { mutate: login, isPending: isLoggingIn } = useLogin(); const { register, @@ -26,6 +26,17 @@ export const Login = () => { mode: 'onChange', }); + if (isLoading) { + return ( +
+
+
+

در حال بارگذاری...

+
+
+ ); + } + if (isAuthenticated) { return ; } @@ -113,7 +124,7 @@ export const Login = () => {