123df671f5
Reviewed-on: #5 Co-authored-by: David Gwilliam <dhgwilliam@gmail.com> Co-committed-by: David Gwilliam <dhgwilliam@gmail.com>
88 lines
2.4 KiB
TypeScript
88 lines
2.4 KiB
TypeScript
"use client"
|
|
|
|
import { createContext, useContext, useEffect, useState } from "react"
|
|
import { authClient } from "@/lib/auth-client"
|
|
|
|
interface SessionContextType {
|
|
session: { user: any; session: any } | null
|
|
loading: boolean
|
|
refreshSession: () => Promise<void>
|
|
}
|
|
|
|
const SessionContext = createContext<SessionContextType | undefined>(undefined)
|
|
|
|
export function SessionProvider({ children }: { children: React.ReactNode }) {
|
|
const [session, setSession] = useState<{ user: any; session: any } | null>(null)
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
const refreshSession = async () => {
|
|
setLoading(true)
|
|
try {
|
|
const result = await authClient.getSession()
|
|
if (result.data) {
|
|
setSession(result.data)
|
|
} else {
|
|
setSession(null)
|
|
}
|
|
} catch {
|
|
setSession(null)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
// Initial session fetch - only run once on mount
|
|
useEffect(() => {
|
|
refreshSession()
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [])
|
|
|
|
// Listen for session changes from Better Auth
|
|
useEffect(() => {
|
|
// Better Auth dispatches custom events when session changes
|
|
const handleSessionChange = (event: Event) => {
|
|
// Check if this is a session change event
|
|
const customEvent = event as CustomEvent
|
|
if (customEvent.detail?.session !== undefined) {
|
|
// Session was updated
|
|
if (customEvent.detail.session) {
|
|
setSession(customEvent.detail.session)
|
|
} else {
|
|
setSession(null)
|
|
}
|
|
} else {
|
|
// Fallback: refresh session from server
|
|
refreshSession()
|
|
}
|
|
}
|
|
|
|
// Listen for Better Auth's session change events
|
|
window.addEventListener('better-auth:session', handleSessionChange as EventListener)
|
|
|
|
// Also listen for storage events for cross-tab communication
|
|
window.addEventListener('storage', (e) => {
|
|
if (e.key === 'better-auth.session_token') {
|
|
refreshSession()
|
|
}
|
|
})
|
|
|
|
return () => {
|
|
window.removeEventListener('better-auth:session', handleSessionChange as EventListener)
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<SessionContext.Provider value={{ session, loading, refreshSession }}>
|
|
{children}
|
|
</SessionContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useSession() {
|
|
const context = useContext(SessionContext)
|
|
if (!context) {
|
|
throw new Error("useSession must be used within SessionProvider")
|
|
}
|
|
return context
|
|
}
|