Init working UI
This commit is contained in:
89
src/context/AuthContext.tsx
Normal file
89
src/context/AuthContext.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect, createContext, useContext, ReactNode } from 'react';
|
||||
import { API_BASE_URL } from '@/constants/api';
|
||||
import { UserDetails, UserRoles, ErrorResponse, AuthContextType } from '@/types'; // Import types
|
||||
|
||||
export const AuthContext = createContext<AuthContextType | null>(null);
|
||||
|
||||
interface AuthProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
||||
const [token, setToken] = useState<string | null>(null);
|
||||
const [user, setUser] = useState<UserDetails | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
const storedToken = localStorage.getItem('jwt_token');
|
||||
const storedUser = localStorage.getItem('user_data');
|
||||
if (storedToken && storedUser) {
|
||||
setToken(storedToken);
|
||||
try {
|
||||
setUser(JSON.parse(storedUser));
|
||||
} catch (error) {
|
||||
console.error("Failed to parse stored user data:", error);
|
||||
localStorage.removeItem('user_data');
|
||||
}
|
||||
}
|
||||
setLoading(false);
|
||||
}, []);
|
||||
|
||||
const login = async (username: string, password: string): Promise<boolean> => {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password }),
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
setToken(data.access_token);
|
||||
const tempUser: UserDetails = { id: data.user_id || 'some-id', username: data.username, role: data.role || UserRoles.USER };
|
||||
setUser(tempUser);
|
||||
localStorage.setItem('jwt_token', data.access_token);
|
||||
localStorage.setItem('user_data', JSON.stringify(tempUser));
|
||||
return true;
|
||||
} else {
|
||||
const errorData = data as ErrorResponse;
|
||||
console.error('Login failed:', errorData.message || errorData.detail || response.statusText);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Network error during login:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
setToken(null);
|
||||
setUser(null);
|
||||
localStorage.removeItem('jwt_token');
|
||||
localStorage.removeItem('user_data');
|
||||
};
|
||||
|
||||
const hasPermission = (requiredRole: UserRoles): boolean => {
|
||||
if (!user || !user.role) return false;
|
||||
const roleOrder: Record<UserRoles, number> = {
|
||||
[UserRoles.USER]: 0,
|
||||
[UserRoles.MOD]: 1,
|
||||
[UserRoles.ADMIN]: 2
|
||||
};
|
||||
return roleOrder[user.role] >= roleOrder[requiredRole];
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ token, user, loading, login, logout, hasPermission }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAuth = (): AuthContextType => {
|
||||
const context = useContext(AuthContext);
|
||||
if (context === null) {
|
||||
throw new Error("useAuth must be used within an AuthProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user