113 lines
2.7 KiB
TypeScript
113 lines
2.7 KiB
TypeScript
// src/context/BackendContext.tsx
|
|
'use client'
|
|
|
|
import type React from 'react'
|
|
import {
|
|
type ReactNode,
|
|
createContext,
|
|
useContext,
|
|
useEffect,
|
|
useState,
|
|
useCallback
|
|
} from 'react'
|
|
|
|
const BACKEND_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'
|
|
|
|
/**
|
|
* @interface BackendContextType
|
|
* @description Defines the structure of the BackendContext value.
|
|
*/
|
|
interface BackendContextType {
|
|
// Connection status
|
|
isBackendConnected: boolean
|
|
isLoading: boolean
|
|
|
|
// Actions
|
|
checkBackendConnection: () => Promise<void>
|
|
refreshStatus: () => Promise<void>
|
|
}
|
|
|
|
/**
|
|
* @const BackendContext
|
|
* @description Creates a context for managing backend connection.
|
|
*/
|
|
const BackendContext = createContext<BackendContextType | undefined>(undefined)
|
|
|
|
/**
|
|
* @component BackendProvider
|
|
* @description Provides the BackendContext to its children.
|
|
*/
|
|
export const BackendProvider: React.FC<{ children: ReactNode }> = ({
|
|
children
|
|
}) => {
|
|
// State
|
|
const [isBackendConnected, setIsBackendConnected] = useState(false)
|
|
const [isLoading, setIsLoading] = useState(true)
|
|
|
|
// Check backend connection
|
|
const checkBackendConnection = useCallback(async (): Promise<void> => {
|
|
try {
|
|
const response = await fetch(`${BACKEND_URL}/auth/session`, {
|
|
method: 'GET',
|
|
credentials: 'include',
|
|
})
|
|
|
|
const connected = response.ok
|
|
setIsBackendConnected(connected)
|
|
|
|
if (connected) {
|
|
console.log('✅ Backend connected')
|
|
} else {
|
|
console.log('❌ Backend not connected')
|
|
}
|
|
|
|
// Don't return anything - function returns Promise<void>
|
|
} catch (error) {
|
|
console.error('Error checking backend connection:', error)
|
|
setIsBackendConnected(false)
|
|
// Don't return anything - function returns Promise<void>
|
|
}
|
|
}, [])
|
|
|
|
// Refresh backend status
|
|
const refreshStatus = useCallback(async () => {
|
|
setIsLoading(true)
|
|
try {
|
|
await checkBackendConnection()
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}, [checkBackendConnection])
|
|
|
|
// Initialize on mount
|
|
useEffect(() => {
|
|
refreshStatus()
|
|
}, [refreshStatus])
|
|
|
|
return (
|
|
<BackendContext.Provider
|
|
value={{
|
|
isBackendConnected,
|
|
isLoading,
|
|
checkBackendConnection,
|
|
refreshStatus
|
|
}}
|
|
>
|
|
{children}
|
|
</BackendContext.Provider>
|
|
)
|
|
}
|
|
|
|
/**
|
|
* @function useBackend
|
|
* @description A hook that provides access to the BackendContext.
|
|
* @returns {BackendContextType} The backend context value.
|
|
* @throws {Error} If used outside of a BackendProvider.
|
|
*/
|
|
export const useBackend = () => {
|
|
const context = useContext(BackendContext)
|
|
if (context === undefined) {
|
|
throw new Error('useBackend must be used within a BackendProvider')
|
|
}
|
|
return context
|
|
} |