Spaces:
Sleeping
Sleeping
File size: 2,088 Bytes
3a19693 7758205 3a19693 7758205 3a19693 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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)
}
|