@fluxbase/sdk-react 0.0.1-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,163 @@
1
+ # React Admin Hooks Examples
2
+
3
+ This directory contains complete, production-ready examples demonstrating the Fluxbase React admin hooks.
4
+
5
+ ## Examples
6
+
7
+ ### AdminDashboard.tsx
8
+
9
+ A complete admin dashboard application demonstrating all admin hooks in action.
10
+
11
+ **Features:**
12
+ - Admin authentication with protected routes
13
+ - User management with pagination and search
14
+ - Real-time statistics dashboard
15
+ - Modern UI with Tailwind CSS
16
+ - Full TypeScript support
17
+
18
+ **Hooks demonstrated:**
19
+ - `useAdminAuth()` - Authentication state management
20
+ - `useUsers()` - User CRUD operations with pagination
21
+ - `useAPIKeys()` - API key management
22
+ - `useWebhooks()` - Webhook configuration
23
+ - `useAppSettings()` - Application settings
24
+ - `useSystemSettings()` - System settings
25
+
26
+ **Run the example:**
27
+
28
+ ```bash
29
+ # Install dependencies
30
+ npm install @fluxbase/sdk @fluxbase/sdk-react @tanstack/react-query
31
+
32
+ # Copy AdminDashboard.tsx to your project
33
+ # Add Tailwind CSS to your project (optional, for styling)
34
+ ```
35
+
36
+ **Basic usage:**
37
+
38
+ ```tsx
39
+ import { createClient } from '@fluxbase/sdk'
40
+ import { FluxbaseProvider } from '@fluxbase/sdk-react'
41
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
42
+ import AdminDashboard from './AdminDashboard'
43
+
44
+ const client = createClient({ url: 'http://localhost:8080' })
45
+ const queryClient = new QueryClient()
46
+
47
+ function App() {
48
+ return (
49
+ <QueryClientProvider client={queryClient}>
50
+ <FluxbaseProvider client={client}>
51
+ <AdminDashboard />
52
+ </FluxbaseProvider>
53
+ </QueryClientProvider>
54
+ )
55
+ }
56
+ ```
57
+
58
+ ## Key Patterns
59
+
60
+ ### 1. Authentication Flow
61
+
62
+ ```tsx
63
+ const { isAuthenticated, isLoading, login, logout } = useAdminAuth({
64
+ autoCheck: true // Automatically check auth status on mount
65
+ })
66
+
67
+ if (isLoading) return <LoadingSpinner />
68
+ if (!isAuthenticated) return <LoginPage />
69
+ return <Dashboard />
70
+ ```
71
+
72
+ ### 2. Data Fetching with Pagination
73
+
74
+ ```tsx
75
+ const [page, setPage] = useState(0)
76
+ const limit = 20
77
+
78
+ const { users, total, isLoading } = useUsers({
79
+ autoFetch: true,
80
+ limit,
81
+ offset: page * limit
82
+ })
83
+ ```
84
+
85
+ ### 3. Search and Filters
86
+
87
+ ```tsx
88
+ const [searchEmail, setSearchEmail] = useState('')
89
+ const [roleFilter, setRoleFilter] = useState<'admin' | 'user' | ''>('')
90
+
91
+ const { users, refetch } = useUsers({
92
+ autoFetch: true,
93
+ email: searchEmail || undefined,
94
+ role: roleFilter || undefined
95
+ })
96
+
97
+ // Refetch when filters change
98
+ useEffect(() => {
99
+ refetch()
100
+ }, [searchEmail, roleFilter, refetch])
101
+ ```
102
+
103
+ ### 4. Optimistic Updates
104
+
105
+ All mutation functions automatically refetch data:
106
+
107
+ ```tsx
108
+ const { users, inviteUser, deleteUser } = useUsers({ autoFetch: true })
109
+
110
+ // These automatically refetch the user list after success
111
+ await inviteUser('new@example.com', 'user')
112
+ await deleteUser(userId)
113
+ // users state is now updated
114
+ ```
115
+
116
+ ### 5. Error Handling
117
+
118
+ ```tsx
119
+ const { data, error, isLoading, refetch } = useUsers({ autoFetch: true })
120
+
121
+ if (isLoading) return <LoadingSpinner />
122
+ if (error) return <ErrorMessage error={error} onRetry={refetch} />
123
+ return <DataDisplay data={data} />
124
+ ```
125
+
126
+ ## Styling
127
+
128
+ The example uses Tailwind CSS utility classes, but you can easily adapt it to your preferred styling solution:
129
+
130
+ - **CSS Modules**: Replace `className` with module imports
131
+ - **Styled Components**: Replace elements with styled components
132
+ - **Material-UI**: Use MUI components instead of native HTML
133
+ - **Chakra UI**: Use Chakra components for rapid development
134
+
135
+ ## TypeScript
136
+
137
+ All examples are fully typed. The hooks provide complete type safety:
138
+
139
+ ```tsx
140
+ import type { EnrichedUser, APIKey, Webhook } from '@fluxbase/sdk-react'
141
+
142
+ const { users }: { users: EnrichedUser[] } = useUsers({ autoFetch: true })
143
+ const { keys }: { keys: APIKey[] } = useAPIKeys({ autoFetch: true })
144
+ ```
145
+
146
+ ## Next Steps
147
+
148
+ 1. **Customize the UI** - Adapt the styling to match your design system
149
+ 2. **Add more features** - Implement API keys, webhooks, and settings tabs
150
+ 3. **Add validation** - Add form validation for user inputs
151
+ 4. **Add loading states** - Improve loading and error states
152
+ 5. **Add notifications** - Show success/error toasts for mutations
153
+ 6. **Add search** - Enhance search with debouncing and advanced filters
154
+
155
+ ## Documentation
156
+
157
+ - [Complete Admin Hooks Guide](../README-ADMIN.md) - Full API reference and examples
158
+ - [React Hooks Documentation](../../docs/docs/sdks/react-hooks.md) - Core hooks documentation
159
+ - [Admin API Documentation](../../docs/docs/sdk/admin.md) - Admin operations reference
160
+
161
+ ## License
162
+
163
+ MIT
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@fluxbase/sdk-react",
3
+ "version": "0.0.1-rc.2",
4
+ "description": "React hooks for Fluxbase SDK",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "docs": "typedoc",
19
+ "docs:watch": "typedoc --watch",
20
+ "type-check": "tsc --noEmit",
21
+ "format": "prettier --write src",
22
+ "format:check": "prettier --check src"
23
+ },
24
+ "keywords": [
25
+ "fluxbase",
26
+ "react",
27
+ "hooks",
28
+ "database",
29
+ "realtime"
30
+ ],
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/wayli-app/fluxbase"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "@fluxbase/sdk": "^0.1.0",
40
+ "@tanstack/react-query": "^5.0.0",
41
+ "react": "^18.0.0 || ^19.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@fluxbase/sdk": "file:../sdk",
45
+ "@tanstack/react-query": "^5.62.14",
46
+ "@types/react": "^19.0.0",
47
+ "prettier": "^3.4.2",
48
+ "tsup": "^8.3.5",
49
+ "typedoc": "^0.28.14",
50
+ "typescript": "^5.7.3"
51
+ }
52
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * React context for Fluxbase client
3
+ */
4
+
5
+ import { createContext, useContext, type ReactNode } from 'react'
6
+ import type { FluxbaseClient } from '@fluxbase/sdk'
7
+
8
+ const FluxbaseContext = createContext<FluxbaseClient | null>(null)
9
+
10
+ export interface FluxbaseProviderProps {
11
+ client: FluxbaseClient
12
+ children: ReactNode
13
+ }
14
+
15
+ /**
16
+ * Provider component to make Fluxbase client available throughout the app
17
+ */
18
+ export function FluxbaseProvider({ client, children }: FluxbaseProviderProps) {
19
+ return <FluxbaseContext.Provider value={client}>{children}</FluxbaseContext.Provider>
20
+ }
21
+
22
+ /**
23
+ * Hook to access the Fluxbase client from context
24
+ */
25
+ export function useFluxbaseClient(): FluxbaseClient {
26
+ const client = useContext(FluxbaseContext)
27
+
28
+ if (!client) {
29
+ throw new Error('useFluxbaseClient must be used within a FluxbaseProvider')
30
+ }
31
+
32
+ return client
33
+ }
package/src/index.ts ADDED
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Fluxbase React Hooks
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { createClient } from '@fluxbase/sdk'
7
+ * import { FluxbaseProvider, useAuth, useTable } from '@fluxbase/sdk-react'
8
+ * import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
9
+ *
10
+ * const client = createClient({ url: 'http://localhost:8080' })
11
+ * const queryClient = new QueryClient()
12
+ *
13
+ * function App() {
14
+ * return (
15
+ * <QueryClientProvider client={queryClient}>
16
+ * <FluxbaseProvider client={client}>
17
+ * <MyComponent />
18
+ * </FluxbaseProvider>
19
+ * </QueryClientProvider>
20
+ * )
21
+ * }
22
+ *
23
+ * function MyComponent() {
24
+ * const { user, signIn, signOut } = useAuth()
25
+ * const { data: products } = useTable('products', (q) => q.select('*').eq('active', true))
26
+ *
27
+ * return <div>...</div>
28
+ * }
29
+ * ```
30
+ */
31
+
32
+ // Context and provider
33
+ export { FluxbaseProvider, useFluxbaseClient } from './context'
34
+
35
+ // Auth hooks
36
+ export {
37
+ useAuth,
38
+ useUser,
39
+ useSession,
40
+ useSignIn,
41
+ useSignUp,
42
+ useSignOut,
43
+ useUpdateUser,
44
+ } from './use-auth'
45
+
46
+ // Database query hooks
47
+ export {
48
+ useFluxbaseQuery,
49
+ useTable,
50
+ useInsert,
51
+ useUpdate,
52
+ useUpsert,
53
+ useDelete,
54
+ } from './use-query'
55
+
56
+ // Realtime hooks
57
+ export {
58
+ useRealtime,
59
+ useTableSubscription,
60
+ useTableInserts,
61
+ useTableUpdates,
62
+ useTableDeletes,
63
+ } from './use-realtime'
64
+
65
+ // Storage hooks
66
+ export {
67
+ useStorageList,
68
+ useStorageUpload,
69
+ useStorageDownload,
70
+ useStorageDelete,
71
+ useStoragePublicUrl,
72
+ useStorageSignedUrl,
73
+ useStorageMove,
74
+ useStorageCopy,
75
+ useStorageBuckets,
76
+ useCreateBucket,
77
+ useDeleteBucket,
78
+ } from './use-storage'
79
+
80
+ // RPC hooks
81
+ export {
82
+ useRPC,
83
+ useRPCMutation,
84
+ useRPCBatch,
85
+ } from './use-rpc'
86
+
87
+ // Admin hooks
88
+ export { useAdminAuth } from './use-admin-auth'
89
+ export { useUsers } from './use-users'
90
+ export { useAPIKeys } from './use-api-keys'
91
+ export {
92
+ useWebhooks,
93
+ useAppSettings,
94
+ useSystemSettings,
95
+ } from './use-admin-hooks'
96
+
97
+ // Re-export types from SDK
98
+ export type {
99
+ FluxbaseClient,
100
+ AuthSession,
101
+ User,
102
+ SignInCredentials,
103
+ SignUpCredentials,
104
+ PostgrestResponse,
105
+ RealtimeChangePayload,
106
+ StorageObject,
107
+ AdminUser,
108
+ EnrichedUser,
109
+ APIKey,
110
+ Webhook,
111
+ AppSettings,
112
+ SystemSetting,
113
+ } from '@fluxbase/sdk'
@@ -0,0 +1,168 @@
1
+ import { useState, useEffect, useCallback } from 'react'
2
+ import { useFluxbaseClient } from './context'
3
+ import type { AdminAuthResponse } from '@fluxbase/sdk'
4
+
5
+ /**
6
+ * Simplified admin user type returned by authentication
7
+ */
8
+ export interface AdminUser {
9
+ id: string
10
+ email: string
11
+ role: string
12
+ }
13
+
14
+ export interface UseAdminAuthOptions {
15
+ /**
16
+ * Automatically check authentication status on mount
17
+ * @default true
18
+ */
19
+ autoCheck?: boolean
20
+ }
21
+
22
+ export interface UseAdminAuthReturn {
23
+ /**
24
+ * Current admin user if authenticated
25
+ */
26
+ user: AdminUser | null
27
+
28
+ /**
29
+ * Whether the admin is authenticated
30
+ */
31
+ isAuthenticated: boolean
32
+
33
+ /**
34
+ * Whether the authentication check is in progress
35
+ */
36
+ isLoading: boolean
37
+
38
+ /**
39
+ * Any error that occurred during authentication
40
+ */
41
+ error: Error | null
42
+
43
+ /**
44
+ * Login as admin
45
+ */
46
+ login: (email: string, password: string) => Promise<AdminAuthResponse>
47
+
48
+ /**
49
+ * Logout admin
50
+ */
51
+ logout: () => Promise<void>
52
+
53
+ /**
54
+ * Refresh admin user info
55
+ */
56
+ refresh: () => Promise<void>
57
+ }
58
+
59
+ /**
60
+ * Hook for admin authentication
61
+ *
62
+ * Manages admin login state, authentication checks, and user info.
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * function AdminLogin() {
67
+ * const { user, isAuthenticated, isLoading, login, logout } = useAdminAuth()
68
+ *
69
+ * const handleLogin = async (e: React.FormEvent) => {
70
+ * e.preventDefault()
71
+ * await login(email, password)
72
+ * }
73
+ *
74
+ * if (isLoading) return <div>Loading...</div>
75
+ * if (isAuthenticated) return <div>Welcome {user?.email}</div>
76
+ *
77
+ * return <form onSubmit={handleLogin}>...</form>
78
+ * }
79
+ * ```
80
+ */
81
+ export function useAdminAuth(options: UseAdminAuthOptions = {}): UseAdminAuthReturn {
82
+ const { autoCheck = true } = options
83
+ const client = useFluxbaseClient()
84
+
85
+ const [user, setUser] = useState<AdminUser | null>(null)
86
+ const [isLoading, setIsLoading] = useState(autoCheck)
87
+ const [error, setError] = useState<Error | null>(null)
88
+
89
+ /**
90
+ * Check current authentication status
91
+ */
92
+ const checkAuth = useCallback(async () => {
93
+ try {
94
+ setIsLoading(true)
95
+ setError(null)
96
+ const { user } = await client.admin.me()
97
+ setUser(user)
98
+ } catch (err) {
99
+ setUser(null)
100
+ setError(err as Error)
101
+ } finally {
102
+ setIsLoading(false)
103
+ }
104
+ }, [client])
105
+
106
+ /**
107
+ * Login as admin
108
+ */
109
+ const login = useCallback(
110
+ async (email: string, password: string): Promise<AdminAuthResponse> => {
111
+ try {
112
+ setIsLoading(true)
113
+ setError(null)
114
+ const response = await client.admin.login({ email, password })
115
+ setUser(response.user)
116
+ return response
117
+ } catch (err) {
118
+ setError(err as Error)
119
+ throw err
120
+ } finally {
121
+ setIsLoading(false)
122
+ }
123
+ },
124
+ [client]
125
+ )
126
+
127
+ /**
128
+ * Logout admin
129
+ */
130
+ const logout = useCallback(async (): Promise<void> => {
131
+ try {
132
+ setIsLoading(true)
133
+ setError(null)
134
+ // Clear user state
135
+ setUser(null)
136
+ // Note: Add logout endpoint call here when available
137
+ } catch (err) {
138
+ setError(err as Error)
139
+ throw err
140
+ } finally {
141
+ setIsLoading(false)
142
+ }
143
+ }, [])
144
+
145
+ /**
146
+ * Refresh admin user info
147
+ */
148
+ const refresh = useCallback(async (): Promise<void> => {
149
+ await checkAuth()
150
+ }, [checkAuth])
151
+
152
+ // Auto-check authentication on mount
153
+ useEffect(() => {
154
+ if (autoCheck) {
155
+ checkAuth()
156
+ }
157
+ }, [autoCheck, checkAuth])
158
+
159
+ return {
160
+ user,
161
+ isAuthenticated: user !== null,
162
+ isLoading,
163
+ error,
164
+ login,
165
+ logout,
166
+ refresh
167
+ }
168
+ }