fediversion/frontend/contexts/auth-context.tsx
fullsizemalt b4cddf41ea feat: Initialize Fediversion multi-band platform
- Fork elmeg-demo codebase for multi-band support
- Add data importer infrastructure with base class
- Create band-specific importers:
  - phish.py: Phish.net API v5
  - grateful_dead.py: Grateful Stats API
  - setlistfm.py: Dead & Company, Billy Strings (Setlist.fm)
- Add spec-kit configuration for Gemini
- Update README with supported bands and architecture
2025-12-28 12:39:28 -08:00

90 lines
2.4 KiB
TypeScript

"use client"
import React, { createContext, useContext, useState, useEffect, useCallback } from "react"
import { getApiUrl } from "@/lib/api-config"
interface User {
id: number
email: string
is_active: boolean
is_superuser: boolean
role: string
}
interface AuthContextType {
user: User | null
token: string | null
loading: boolean
login: (token: string) => Promise<void>
logout: () => void
}
const AuthContext = createContext<AuthContextType>({
user: null,
token: null,
loading: true,
login: async () => { },
logout: () => { },
})
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [token, setToken] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const fetchUser = useCallback(async (authToken: string): Promise<boolean> => {
const res = await fetch(`${getApiUrl()}/auth/users/me`, {
headers: {
Authorization: `Bearer ${authToken}`
}
})
if (res.ok) {
const userData = await res.json()
setUser(userData)
return true
} else if (res.status === 401 || res.status === 403) {
// Token expired or invalid - handle silently
return false
} else {
// Unexpected error
console.warn("Auth check failed with status:", res.status)
return false
}
}, [])
useEffect(() => {
const initAuth = async () => {
const storedToken = localStorage.getItem("token")
if (storedToken) {
setToken(storedToken)
const success = await fetchUser(storedToken)
if (!success) {
localStorage.removeItem("token")
setToken(null)
}
}
setLoading(false)
}
initAuth()
}, [fetchUser])
const login = async (newToken: string) => {
localStorage.setItem("token", newToken)
setToken(newToken)
await fetchUser(newToken)
}
const logout = () => {
localStorage.removeItem("token")
setToken(null)
setUser(null)
}
return (
<AuthContext.Provider value={{ user, token, loading, login, logout }}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => useContext(AuthContext)