42 lines
1.1 KiB
TypeScript
42 lines
1.1 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import { authApi } from '../api'
|
|
|
|
export interface User {
|
|
id: number
|
|
username: string
|
|
email: string
|
|
is_active: boolean
|
|
}
|
|
|
|
// Simple module-level state (no external lib needed)
|
|
let currentUser: User | null = null
|
|
let isLoading = true
|
|
let fetchPromise: Promise<void> | null = null
|
|
const listeners = new Set<() => void>()
|
|
|
|
export function useAuth() {
|
|
const [user, setUser] = useState<User | null>(currentUser)
|
|
const [loading, setLoading] = useState(isLoading)
|
|
|
|
useEffect(() => {
|
|
const update = () => { setUser(currentUser); setLoading(isLoading) }
|
|
listeners.add(update)
|
|
if (!fetchPromise) {
|
|
fetchPromise = authApi.me()
|
|
.then((res) => { currentUser = res.data })
|
|
.catch(() => { currentUser = null })
|
|
.finally(() => { isLoading = false; listeners.forEach((l) => l()) })
|
|
}
|
|
return () => { listeners.delete(update) }
|
|
}, [])
|
|
|
|
const logout = async () => {
|
|
await authApi.logout()
|
|
currentUser = null
|
|
listeners.forEach((l) => l())
|
|
window.location.href = '/login'
|
|
}
|
|
|
|
return { user, loading, logout }
|
|
}
|