import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; const AuthContext = createContext(null); export function AuthProvider({ children }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Check if user is authenticated on mount const checkAuth = useCallback(async () => { try { const response = await fetch(`${API_BASE}/auth/me`, { credentials: 'include' }); if (response.ok) { const data = await response.json(); setUser(data.user); } else { setUser(null); } } catch (err) { console.error('Auth check error:', err); setUser(null); } finally { setLoading(false); } }, []); useEffect(() => { checkAuth(); }, [checkAuth]); // Login function const login = async (username, password) => { setError(null); try { const response = await fetch(`${API_BASE}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ username, password }) }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Login failed'); } setUser(data.user); return { success: true }; } catch (err) { setError(err.message); return { success: false, error: err.message }; } }; // Logout function const logout = async () => { try { await fetch(`${API_BASE}/auth/logout`, { method: 'POST', credentials: 'include' }); } catch (err) { console.error('Logout error:', err); } setUser(null); }; // Check if user has a specific role const hasRole = (...roles) => { return user && roles.includes(user.role); }; // Check if user can perform write operations (editor or admin) const canWrite = () => hasRole('editor', 'admin'); // Check if user is admin const isAdmin = () => hasRole('admin'); const value = { user, loading, error, login, logout, checkAuth, hasRole, canWrite, isAdmin, isAuthenticated: !!user }; return ( {children} ); } export function useAuth() { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }