132 lines
3.9 KiB
TypeScript
132 lines
3.9 KiB
TypeScript
import { createContext, useContext, useReducer, useEffect } from 'react';
|
|
import { AuthState, User } from '../types';
|
|
|
|
interface AuthContextType extends AuthState {
|
|
login: (email: string, password: string) => Promise<boolean>;
|
|
logout: () => void;
|
|
hasPermission: (permission: number) => boolean;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
|
|
|
type AuthAction =
|
|
| { type: 'LOGIN_SUCCESS'; payload: { user: User; token: string } }
|
|
| { type: 'LOGOUT' }
|
|
| { type: 'RESTORE_SESSION'; payload: { user: User; token: string } };
|
|
|
|
const authReducer = (state: AuthState, action: AuthAction): AuthState => {
|
|
switch (action.type) {
|
|
case 'LOGIN_SUCCESS':
|
|
return {
|
|
isAuthenticated: true,
|
|
user: action.payload.user,
|
|
permissions: action.payload.user.permissions,
|
|
token: action.payload.token,
|
|
};
|
|
case 'LOGOUT':
|
|
return {
|
|
isAuthenticated: false,
|
|
user: null,
|
|
permissions: [],
|
|
token: null,
|
|
};
|
|
case 'RESTORE_SESSION':
|
|
return {
|
|
isAuthenticated: true,
|
|
user: action.payload.user,
|
|
permissions: action.payload.user.permissions,
|
|
token: action.payload.token,
|
|
};
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
const initialState: AuthState = {
|
|
isAuthenticated: false,
|
|
user: null,
|
|
permissions: [],
|
|
token: null,
|
|
};
|
|
|
|
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|
const [state, dispatch] = useReducer(authReducer, initialState);
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem('admin_token');
|
|
const userStr = localStorage.getItem('admin_user');
|
|
|
|
if (token && userStr) {
|
|
try {
|
|
const user = JSON.parse(userStr);
|
|
dispatch({ type: 'RESTORE_SESSION', payload: { user, token } });
|
|
} catch (error) {
|
|
localStorage.removeItem('admin_token');
|
|
localStorage.removeItem('admin_user');
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
const login = async (email: string, password: string): Promise<boolean> => {
|
|
try {
|
|
const mockUser: User = {
|
|
id: '1',
|
|
name: 'مدیر کل',
|
|
email: email,
|
|
role: 'admin',
|
|
permissions: [1, 2, 3, 4, 5, 10, 15, 20, 22, 25, 30],
|
|
status: 'active',
|
|
createdAt: new Date().toISOString(),
|
|
lastLogin: new Date().toISOString(),
|
|
};
|
|
|
|
const mockToken = 'mock-jwt-token-' + Date.now();
|
|
|
|
if (email === 'admin@test.com' && password === 'admin123') {
|
|
localStorage.setItem('admin_token', mockToken);
|
|
localStorage.setItem('admin_user', JSON.stringify(mockUser));
|
|
|
|
dispatch({
|
|
type: 'LOGIN_SUCCESS',
|
|
payload: { user: mockUser, token: mockToken }
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
const logout = () => {
|
|
localStorage.removeItem('admin_token');
|
|
localStorage.removeItem('admin_user');
|
|
dispatch({ type: 'LOGOUT' });
|
|
};
|
|
|
|
const hasPermission = (permission: number): boolean => {
|
|
return state.permissions.includes(permission);
|
|
};
|
|
|
|
return (
|
|
<AuthContext.Provider value={{
|
|
...state,
|
|
login,
|
|
logout,
|
|
hasPermission,
|
|
}}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useAuth = () => {
|
|
const context = useContext(AuthContext);
|
|
if (context === undefined) {
|
|
throw new Error('useAuth must be used within an AuthProvider');
|
|
}
|
|
return context;
|
|
};
|