TAM / frontend /src /contexts /AuthContext.jsx
Claude
Fix login API path: remove hardcoded /api prefix for production
7758205 unverified
Raw
History Blame Contribute Delete
2.09 kB
import { createContext, useContext, useState, useEffect, useCallback } from 'react'
const AuthContext = createContext(null)
const TOKEN_KEY = 'leadgen_token'
const USER_KEY = 'leadgen_user'
export function AuthProvider({ children }) {
const [token, setToken] = useState(() => localStorage.getItem(TOKEN_KEY))
const [user, setUser] = useState(() => {
try { return JSON.parse(localStorage.getItem(USER_KEY)) } catch { return null }
})
const login = useCallback(async (username, password) => {
const form = new URLSearchParams()
form.append('username', username)
form.append('password', password)
const base = import.meta.env.DEV ? '/api' : ''
const res = await fetch(`${base}/auth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: form,
})
if (!res.ok) {
const err = await res.json().catch(() => ({}))
throw new Error(err.detail || 'Login failed')
}
const data = await res.json()
localStorage.setItem(TOKEN_KEY, data.access_token)
localStorage.setItem(USER_KEY, JSON.stringify(data.user))
setToken(data.access_token)
setUser(data.user)
return data.user
}, [])
const logout = useCallback(() => {
localStorage.removeItem(TOKEN_KEY)
localStorage.removeItem(USER_KEY)
setToken(null)
setUser(null)
}, [])
// Refresh user info from API on mount (validates token is still good)
useEffect(() => {
if (!token) return
const base = import.meta.env.DEV ? '/api' : ''
fetch(`${base}/auth/me`, { headers: { Authorization: `Bearer ${token}` } })
.then(r => {
if (r.status === 401) { logout(); return null }
return r.json()
})
.then(u => { if (u) { setUser(u); localStorage.setItem(USER_KEY, JSON.stringify(u)) } })
.catch(() => {})
}, [token, logout])
return (
<AuthContext.Provider value={{ token, user, login, logout, isAdmin: user?.is_admin }}>
{children}
</AuthContext.Provider>
)
}
export function useAuth() {
return useContext(AuthContext)
}