Something went wrong. Try again.
Barazo default frontend barazo.forum
Something went wrong. Try again.
3.1 kB · 101 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102/** * Plugin context provider. * Fetches enabled plugins and their settings from the API on mount. * Exposes helpers to check plugin state and a refresh method for admin pages. */
'use client'
import { createContext, useCallback, useEffect, useMemo, useState } from 'react'import type { ReactNode } from 'react'import type { Plugin } from '@/lib/api/types'import { getPlugins } from '@/lib/api/client'import { useAuth } from '@/hooks/use-auth'import { loadBundledPlugins } from '@/lib/plugins/loader'
export interface PluginContextValue { /** List of all plugins (enabled and disabled) */ plugins: Plugin[] /** Check whether a plugin with the given name is enabled */ isPluginEnabled: (name: string) => boolean /** Get the settings for a plugin by name, or null if not found */ getPluginSettings: (name: string) => Record<string, unknown> | null /** Whether the plugin list is still loading */ isLoading: boolean /** Re-fetch the plugin list (call after admin changes) */ refreshPlugins: () => Promise<void>}
export const PluginContext = createContext<PluginContextValue | null>(null)
interface PluginProviderProps { children: ReactNode}
export function PluginProvider({ children }: PluginProviderProps) { const { getAccessToken, isLoading: authLoading } = useAuth() const [plugins, setPlugins] = useState<Plugin[]>([]) const [isLoading, setIsLoading] = useState(true)
const fetchPlugins = useCallback(async () => { const token = getAccessToken() if (!token) { // Unauthenticated: no plugin data available from API setPlugins([]) setIsLoading(false) return }
try { const response = await getPlugins(token) const enabledNames = response.plugins.filter((p) => p.enabled).map((p) => p.name) await loadBundledPlugins(enabledNames) setPlugins(response.plugins) } catch { // On error, keep existing plugins (or empty on first load) setPlugins((prev) => prev) } finally { setIsLoading(false) } }, [getAccessToken])
const refreshPlugins = useCallback(async () => { setIsLoading(true) await fetchPlugins() }, [fetchPlugins])
useEffect(() => { if (authLoading) return void fetchPlugins() }, [authLoading, fetchPlugins])
const isPluginEnabled = useCallback( (name: string): boolean => { const plugin = plugins.find((p) => p.name === name) return plugin?.enabled ?? false }, [plugins] )
const getPluginSettings = useCallback( (name: string): Record<string, unknown> | null => { const plugin = plugins.find((p) => p.name === name) if (!plugin) return null return { ...plugin.settings } }, [plugins] )
const value = useMemo<PluginContextValue>( () => ({ plugins, isPluginEnabled, getPluginSettings, isLoading, refreshPlugins, }), [plugins, isPluginEnabled, getPluginSettings, isLoading, refreshPlugins] )
return <PluginContext.Provider value={value}>{children}</PluginContext.Provider>}