@insforge/react 0.1.6 → 0.2.0

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.
package/README.md CHANGED
@@ -1,18 +1,22 @@
1
1
  # @insforge/react
2
2
 
3
- **Complete authentication solution for React applications.** Framework-agnostic components with full business logic included.
3
+ **Complete authentication solution for React applications.** Production-ready components with full business logic included.
4
4
 
5
5
  ## Why @insforge/react?
6
6
 
7
- ✅ **Complete Package** - Not just UI, includes SDK integration, providers, and hooks
8
- ✅ **Framework Agnostic** - Works with Next.js, Vite, Remix, or any React framework
9
- ✅ **5-Minute Setup** - Provider + Components = done
7
+ ✅ **5-Minute Setup** - One provider + one line of router config = done
8
+ ✅ **Built-in Auth UI** - Use deployed auth pages (like Next.js middleware)
9
+ ✅ **Framework Agnostic** - Works with any React framework
10
10
  ✅ **Full TypeScript** - Complete type safety out of the box
11
- ✅ **Customizable** - Every component supports appearance props and text customization
11
+ ✅ **Fully Customizable** - Deep styling control when you need it
12
12
 
13
- **Need just UI?** All components are exported separately for maximum flexibility.
13
+ ---
14
+
15
+ ## Quick Start
14
16
 
15
- ## Installation
17
+ Get authentication working in your React app in 5 minutes.
18
+
19
+ ### 1. Install
16
20
 
17
21
  ```bash
18
22
  npm install @insforge/react
@@ -22,443 +26,328 @@ yarn add @insforge/react
22
26
  pnpm add @insforge/react
23
27
  ```
24
28
 
25
- Dependencies automatically include `@insforge/sdk` for authentication logic.
26
-
27
- ---
28
-
29
- ## Quick Start
29
+ ### 2. Setup Provider
30
30
 
31
- ### 1. Setup Provider
32
-
33
- Wrap your app with `InsforgeProvider` in the root:
31
+ Wrap your app with `InsforgeProvider`:
34
32
 
35
33
  ```tsx
36
- // React / Vite
34
+ // src/main.tsx (Vite) or src/index.tsx (CRA)
35
+ import { StrictMode } from 'react';
36
+ import { createRoot } from 'react-dom/client';
37
37
  import { InsforgeProvider } from '@insforge/react';
38
38
  import '@insforge/react/styles.css';
39
+ import App from './App';
39
40
 
40
- function App() {
41
- return (
41
+ createRoot(document.getElementById('root')!).render(
42
+ <StrictMode>
42
43
  <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
43
- {/* Your app */}
44
+ <App />
44
45
  </InsforgeProvider>
45
- );
46
- }
47
- ```
48
-
49
- ```tsx
50
- // Next.js App Router
51
- 'use client';
52
- import { InsforgeProvider } from '@insforge/react';
53
- import '@insforge/react/styles.css';
54
-
55
- export default function RootLayout({ children }) {
56
- return (
57
- <html>
58
- <body>
59
- <InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL}>
60
- {children}
61
- </InsforgeProvider>
62
- </body>
63
- </html>
64
- );
65
- }
46
+ </StrictMode>
47
+ );
66
48
  ```
67
49
 
68
- **Props:**
69
- - `baseUrl` (required): Your Insforge backend URL
70
- - `onAuthChange` (optional): Callback when auth state changes
71
- - `syncTokenToCookie` (optional): Custom function to sync token to cookies (for Next.js SSR)
72
- - `clearCookie` (optional): Custom function to clear cookie on sign out
73
-
74
- ### 2. Use Pre-built Components
75
-
76
- The easiest way to add authentication:
50
+ ### 3. Configure Router (Built-in Auth)
77
51
 
78
52
  ```tsx
79
- 'use client'; // for Next.js
80
- import { SignIn, SignUp } from '@insforge/react';
81
-
82
- // Sign In Page
83
- export default function SignInPage() {
84
- return (
85
- <div className="min-h-screen flex items-center justify-center bg-gray-50">
86
- <SignIn
87
- afterSignInUrl="/dashboard"
88
- signUpUrl="/sign-up"
89
- />
90
- </div>
91
- );
92
- }
53
+ // src/App.tsx
54
+ import { createBrowserRouter, RouterProvider } from 'react-router-dom';
55
+ import { getInsforgeRoutes } from '@insforge/react/router';
56
+ import Home from './pages/Home';
57
+ import Dashboard from './pages/Dashboard';
58
+
59
+ const router = createBrowserRouter([
60
+ { path: '/', element: <Home /> },
61
+
62
+ ...getInsforgeRoutes({
63
+ baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
64
+ builtInAuth: true
65
+ }),
66
+
67
+ { path: '/dashboard', element: <Dashboard /> }
68
+ ]);
93
69
 
94
- // Sign Up Page
95
- export default function SignUpPage() {
96
- return (
97
- <div className="min-h-screen flex items-center justify-center bg-gray-50">
98
- <SignUp
99
- afterSignUpUrl="/dashboard"
100
- signInUrl="/sign-in"
101
- />
102
- </div>
103
- );
70
+ export default function App() {
71
+ return <RouterProvider router={router} />;
104
72
  }
105
73
  ```
106
74
 
107
- ### 3. Create Callback Page (for OAuth)
108
-
109
- Handle OAuth redirects:
110
-
111
- ```tsx
112
- 'use client'; // for Next.js
113
- import { InsforgeCallback } from '@insforge/react';
114
-
115
- export default function CallbackPage() {
116
- return <InsforgeCallback />;
117
- }
118
- ```
75
+ **What this does:**
76
+ - Visiting `/sign-in` → Redirects to `your-project.insforge.app/auth/sign-in`
77
+ - Visiting `/sign-up` → Redirects to `your-project.insforge.app/auth/sign-up`
78
+ - After auth → Redirects back to `/auth/callback` → Goes to dashboard
119
79
 
120
- ### 4. Use Hooks & Components
80
+ ### 4. Add Auth UI to Your Pages
121
81
 
122
82
  ```tsx
123
- 'use client'; // for Next.js
124
- import { SignedIn, SignedOut, UserButton, useAuth, useUser } from '@insforge/react';
83
+ // src/pages/Home.tsx
84
+ import { SignedIn, SignedOut, UserButton } from '@insforge/react';
125
85
 
126
86
  export default function Home() {
127
- const { isSignedIn } = useAuth();
128
- const { user } = useUser();
129
-
130
87
  return (
131
88
  <div>
132
- <SignedOut>
133
- <a href="/sign-in">Sign In</a>
134
- </SignedOut>
135
-
136
- <SignedIn>
137
- <UserButton afterSignOutUrl="/" />
138
- <h1>Welcome, {user?.email}!</h1>
139
- </SignedIn>
89
+ <nav>
90
+ <SignedOut>
91
+ <a href="/sign-in">Sign In</a>
92
+ </SignedOut>
93
+
94
+ <SignedIn>
95
+ <UserButton afterSignOutUrl="/" />
96
+ </SignedIn>
97
+ </nav>
98
+
99
+ <h1>Welcome to My App!</h1>
140
100
  </div>
141
101
  );
142
102
  }
143
103
  ```
144
104
 
145
- **That's it!** 🎉 Your React app now has production-ready authentication.
146
-
147
- ---
148
-
149
- ## How It Works
150
-
151
- ```
152
- 1. User visits Sign In page → Renders <SignIn> component
153
-
154
- 2. User enters credentials → Component calls SDK methods
155
-
156
- 3. SDK communicates with backend → Returns auth token
157
-
158
- 4. Provider updates auth state → Components re-render
159
-
160
- 5. User sees authenticated UI → Redirect to dashboard
161
- ```
162
-
163
- **Architecture:**
164
- - **InsforgeProvider**: Manages authentication state globally
165
- - **SDK Integration**: All auth operations go through `@insforge/sdk`
166
- - **React Context**: Provides auth state to all child components
167
- - **Hooks**: Easy access to auth methods and user data
105
+ **That's it!** 🎉 You now have production-ready authentication.
168
106
 
169
107
  ---
170
108
 
171
- ## Complete Components (with Business Logic)
109
+ ## Router Configuration Options
172
110
 
173
- These components include full authentication logic:
111
+ ### Built-in Auth (Recommended)
174
112
 
175
- ### `<SignIn />`
176
-
177
- Complete sign-in component with email/password and OAuth:
113
+ Uses your deployed Insforge auth pages:
178
114
 
179
115
  ```tsx
180
- import { SignIn } from '@insforge/react';
181
- import { useNavigate } from 'react-router-dom';
182
-
183
- function SignInPage() {
184
- const navigate = useNavigate();
185
-
186
- return (
187
- <SignIn
188
- afterSignInUrl="/dashboard"
189
- signUpUrl="/sign-up"
190
- forgotPasswordUrl="/forgot-password"
191
- onSuccess={(user, accessToken) => {
192
- console.log('Signed in:', user);
193
- }}
194
- onError={(error) => {
195
- console.error('Error:', error);
196
- }}
197
- onRedirect={(url) => navigate(url)}
198
- // Customization
199
- title="Welcome Back"
200
- subtitle="Sign in to continue"
201
- appearance={{
202
- containerClassName: "shadow-xl",
203
- buttonClassName: "bg-blue-600"
204
- }}
205
- />
206
- );
207
- }
116
+ ...getInsforgeRoutes({
117
+ baseUrl: 'https://your-project.insforge.app',
118
+ builtInAuth: true, // Default
119
+ paths: {
120
+ signIn: '/sign-in', // Custom path (optional)
121
+ signUp: '/sign-up',
122
+ verifyEmail: '/verify-email',
123
+ forgotPassword: '/forgot-password',
124
+ resetPassword: '/reset-password',
125
+ callback: '/auth/callback'
126
+ }
127
+ })
208
128
  ```
209
129
 
210
- **Key Features:**
211
- - Email/password authentication
212
- - OAuth provider buttons (auto-detected from backend)
213
- - Password visibility toggle
214
- - Error handling
215
- - Loading states
216
- - Customizable text and styling
217
-
218
- ### `<SignUp />`
130
+ ### Custom UI Components
219
131
 
220
- Complete sign-up component with password strength validation:
132
+ Use package components with your own styling:
221
133
 
222
134
  ```tsx
223
- import { SignUp } from '@insforge/react';
135
+ import { SignIn, SignUp } from '@insforge/react';
224
136
 
225
- function SignUpPage() {
226
- return (
227
- <SignUp
228
- afterSignUpUrl="/onboarding"
229
- signInUrl="/sign-in"
230
- onSuccess={(user, accessToken) => {
231
- // Track sign-up event
232
- analytics.track('user_signed_up', { userId: user.id });
233
- }}
234
- />
235
- );
236
- }
137
+ const router = createBrowserRouter([
138
+ { path: '/', element: <Home /> },
139
+
140
+ // Still need callback route for OAuth
141
+ ...getInsforgeRoutes({
142
+ baseUrl: import.meta.env.VITE_INSFORGE_BASE_URL,
143
+ builtInAuth: false // Don't redirect to deployed UI
144
+ }),
145
+
146
+ // Use package components
147
+ { path: '/sign-in', element: <SignIn afterSignInUrl="/dashboard" /> },
148
+ { path: '/sign-up', element: <SignUp afterSignUpUrl="/dashboard" /> }
149
+ ]);
237
150
  ```
238
151
 
239
- **Key Features:**
240
- - Email/password registration
241
- - Real-time password strength indicator
242
- - OAuth provider buttons
243
- - Form validation
244
- - Customizable requirements
152
+ ### Fully Custom UI
245
153
 
246
- ### `<UserButton />`
247
-
248
- User profile dropdown with sign-out:
154
+ Build your own auth pages from scratch:
249
155
 
250
156
  ```tsx
251
- import { UserButton } from '@insforge/react';
157
+ import { useAuth } from '@insforge/react';
252
158
 
253
- function Header() {
254
- return (
255
- <header>
256
- <nav>
257
- {/* Your navigation */}
258
- </nav>
259
- <UserButton
260
- afterSignOutUrl="/"
261
- mode="detailed" // or "simple"
262
- appearance={{
263
- buttonClassName: "hover:bg-gray-100",
264
- nameClassName: "text-gray-900",
265
- emailClassName: "text-gray-600"
266
- }}
267
- />
268
- </header>
269
- );
159
+ function CustomSignIn() {
160
+ const { signIn } = useAuth();
161
+
162
+ const handleSubmit = async (e) => {
163
+ e.preventDefault();
164
+ await signIn(email, password);
165
+ navigate('/dashboard');
166
+ };
167
+
168
+ return <form onSubmit={handleSubmit}>...</form>;
270
169
  }
271
170
  ```
272
171
 
273
- **Modes:**
274
- - `detailed`: Shows avatar + name + email
275
- - `simple`: Shows avatar only
276
-
277
- ### `<Protect />`
278
-
279
- Protected content with conditional rendering:
280
-
281
- ```tsx
282
- import { Protect } from '@insforge/react';
283
-
284
- function Dashboard() {
285
- return (
286
- <div>
287
- <h1>Dashboard</h1>
288
-
289
- {/* Simple protection */}
290
- <Protect redirectTo="/sign-in">
291
- <UserContent />
292
- </Protect>
293
-
294
- {/* Role-based protection */}
295
- <Protect
296
- redirectTo="/unauthorized"
297
- condition={(user) => user.role === 'admin'}
298
- >
299
- <AdminPanel />
300
- </Protect>
301
- </div>
302
- );
303
- }
304
- ```
172
+ ---
305
173
 
306
- ### `<SignedIn>` / `<SignedOut>`
174
+ ## Core Features
307
175
 
308
- Conditional rendering based on auth state:
176
+ ### Components
309
177
 
310
- ```tsx
311
- import { SignedIn, SignedOut } from '@insforge/react';
178
+ **Pre-built with Business Logic:**
179
+ - `<SignIn />` - Complete sign-in with email/password & OAuth
180
+ - `<SignUp />` - Registration with password validation
181
+ - `<UserButton />` - User dropdown with sign-out
182
+ - `<Protect />` - Route protection wrapper
183
+ - `<SignedIn>` / `<SignedOut>` - Conditional rendering
184
+ - `<InsforgeCallback />` - OAuth callback handler
312
185
 
313
- function NavBar() {
314
- return (
315
- <nav>
316
- <SignedOut>
317
- <a href="/sign-in">Sign In</a>
318
- <a href="/sign-up">Sign Up</a>
319
- </SignedOut>
320
-
321
- <SignedIn>
322
- <a href="/dashboard">Dashboard</a>
323
- <UserButton />
324
- </SignedIn>
325
- </nav>
326
- );
327
- }
328
- ```
186
+ **Form Components (Pure UI):**
187
+ - `<SignInForm />` - Sign-in UI without logic
188
+ - `<SignUpForm />` - Sign-up UI without logic
189
+ - `<ForgotPasswordForm />` - Password reset request
190
+ - `<ResetPasswordForm />` - Password reset with token
191
+ - `<VerifyEmailStatus />` - Email verification status
329
192
 
330
- ### `<InsforgeCallback />`
193
+ **Atomic Components (13 total):**
194
+ - `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, etc.
331
195
 
332
- OAuth callback handler (3 lines instead of 70+):
196
+ ### Hooks
333
197
 
334
198
  ```tsx
335
- 'use client';
336
- import { InsforgeCallback } from '@insforge/react';
337
-
338
- export default function CallbackPage() {
339
- return <InsforgeCallback redirectTo="/dashboard" />;
340
- }
199
+ const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
200
+ const { user, updateUser, isLoaded } = useUser();
201
+ const { oauthProviders, emailConfig, isLoaded } = usePublicAuthConfig();
341
202
  ```
342
203
 
343
204
  ---
344
205
 
345
- ## Hooks
206
+ ## Customization
346
207
 
347
- ### `useAuth()`
208
+ ### Basic Styling
348
209
 
349
- Access authentication methods:
210
+ All components support `appearance` props:
350
211
 
351
212
  ```tsx
352
- import { useAuth } from '@insforge/react';
353
-
354
- function LoginButton() {
355
- const { signIn, signUp, signOut, isSignedIn, isLoaded } = useAuth();
356
-
357
- const handleSignIn = async () => {
358
- try {
359
- await signIn('user@example.com', 'password');
360
- // Redirect or update UI
361
- } catch (error) {
362
- console.error('Sign in failed:', error);
363
- }
364
- };
365
-
366
- if (!isLoaded) return <div>Loading...</div>;
367
-
368
- return (
369
- <button onClick={isSignedIn ? signOut : handleSignIn}>
370
- {isSignedIn ? 'Sign Out' : 'Sign In'}
371
- </button>
372
- );
373
- }
213
+ <SignIn
214
+ appearance={{
215
+ container: "max-w-lg",
216
+ card: "bg-white shadow-2xl",
217
+ button: "bg-blue-600 hover:bg-blue-700"
218
+ }}
219
+ />
374
220
  ```
375
221
 
376
- **Returns:**
377
- - `signIn(email, password)` - Sign in with email/password
378
- - `signUp(email, password)` - Sign up new user
379
- - `signOut()` - Sign out current user
380
- - `isSignedIn` - Boolean auth state
381
- - `isLoaded` - Boolean loading state
222
+ ### Deep Customization (Hierarchical Appearance)
382
223
 
383
- ### `useUser()`
384
-
385
- Access user data:
224
+ Style nested components through hierarchical structure:
386
225
 
387
226
  ```tsx
388
- import { useUser } from '@insforge/react';
227
+ <SignIn
228
+ appearance={{
229
+ card: "bg-gradient-to-br from-blue-50 to-white shadow-2xl",
230
+ header: {
231
+ title: "text-3xl font-bold text-purple-900",
232
+ subtitle: "text-purple-600"
233
+ },
234
+ form: {
235
+ emailField: {
236
+ label: "text-gray-800 font-semibold",
237
+ input: "border-purple-300 focus:border-purple-500 rounded-lg"
238
+ },
239
+ passwordField: {
240
+ input: "border-purple-300 focus:border-purple-500 rounded-lg",
241
+ forgotPasswordLink: "text-purple-600 hover:text-purple-800"
242
+ }
243
+ },
244
+ button: "bg-purple-600 hover:bg-purple-700 rounded-lg h-12",
245
+ link: {
246
+ text: "text-gray-600",
247
+ link: "text-purple-600 hover:text-purple-800 font-semibold"
248
+ },
249
+ oauth: {
250
+ button: "border-2 hover:bg-gray-50 rounded-xl"
251
+ }
252
+ }}
253
+ />
254
+ ```
389
255
 
390
- function UserProfile() {
391
- const { user, isLoaded, updateUser } = useUser();
256
+ #### Complete Appearance Structure
392
257
 
393
- if (!isLoaded) return <div>Loading...</div>;
394
- if (!user) return <div>Not signed in</div>;
258
+ **SignIn / SignUp Components:**
395
259
 
396
- const handleUpdate = async () => {
397
- await updateUser({ name: 'New Name' });
260
+ ```typescript
261
+ appearance?: {
262
+ container?: string; // Outermost wrapper
263
+ card?: string; // Inner card box
264
+ header?: {
265
+ container?: string; // Header wrapper
266
+ title?: string; // Title text
267
+ subtitle?: string; // Subtitle text
268
+ };
269
+ errorBanner?: string; // Error message banner
270
+ form?: {
271
+ container?: string; // Form wrapper
272
+ emailField?: {
273
+ container?: string; // Email field wrapper
274
+ label?: string; // Email label
275
+ input?: string; // Email input
276
+ };
277
+ passwordField?: {
278
+ container?: string; // Password field wrapper
279
+ label?: string; // Password label
280
+ input?: string; // Password input
281
+ forgotPasswordLink?: string; // Forgot password link (SignIn only)
282
+ strengthIndicator?: { // Password strength (SignUp only)
283
+ container?: string;
284
+ requirement?: string;
285
+ };
286
+ };
287
+ };
288
+ button?: string; // Submit button
289
+ link?: {
290
+ container?: string; // Link section wrapper
291
+ text?: string; // Link description text
292
+ link?: string; // Actual link element
293
+ };
294
+ divider?: string; // "or" divider
295
+ oauth?: {
296
+ container?: string; // OAuth buttons wrapper
297
+ button?: string; // Individual OAuth button
398
298
  };
399
-
400
- return (
401
- <div>
402
- <p>Email: {user.email}</p>
403
- <p>Name: {user.name}</p>
404
- <img src={user.avatarUrl} alt="Avatar" />
405
- <button onClick={handleUpdate}>Update Name</button>
406
- </div>
407
- );
408
299
  }
409
300
  ```
410
301
 
411
- **Returns:**
412
- - `user` - User object with id, email, name, avatarUrl
413
- - `isLoaded` - Boolean loading state
414
- - `updateUser(data)` - Update user profile
415
- - `setUser(user)` - Manually set user state
416
-
417
- ### `usePublicAuthConfig()`
302
+ ### Text Customization
418
303
 
419
- Get OAuth providers and password requirements:
304
+ All text is customizable:
420
305
 
421
306
  ```tsx
422
- import { usePublicAuthConfig } from '@insforge/react';
423
-
424
- function SignInPage() {
425
- const { oauthProviders, emailConfig, isLoaded } = usePublicAuthConfig();
426
-
427
- if (!isLoaded) return <div>Loading...</div>;
428
-
429
- return (
430
- <div>
431
- <p>Available OAuth: {oauthProviders.join(', ')}</p>
432
- <p>Password min length: {emailConfig?.passwordMinLength}</p>
433
- </div>
434
- );
435
- }
307
+ <SignIn
308
+ title="Welcome Back!"
309
+ subtitle="We're happy to see you again"
310
+ emailLabel="Your Email Address"
311
+ emailPlaceholder="you@company.com"
312
+ passwordLabel="Your Password"
313
+ submitButtonText="Login Now"
314
+ loadingButtonText="Signing you in..."
315
+ signUpText="New to our platform?"
316
+ signUpLinkText="Create an account"
317
+ dividerText="or continue with"
318
+ />
436
319
  ```
437
320
 
438
- **⚠️ Important:** Only use this hook in SignIn/SignUp components to avoid unnecessary API calls.
439
-
440
321
  ---
441
322
 
442
- ## UI Form Components (Pure UI)
443
-
444
- Build custom auth flows with pre-built forms:
323
+ ## Advanced Usage
445
324
 
446
- ### `<SignInForm />`
325
+ ### Complete Component with Custom Logic
447
326
 
448
327
  ```tsx
449
- import { SignInForm } from '@insforge/react';
328
+ import { SignInForm, useAuth } from '@insforge/react';
450
329
  import { useState } from 'react';
451
330
 
452
331
  function CustomSignIn() {
332
+ const { signIn } = useAuth();
453
333
  const [email, setEmail] = useState('');
454
334
  const [password, setPassword] = useState('');
455
335
  const [error, setError] = useState('');
456
336
  const [loading, setLoading] = useState(false);
457
337
 
458
- const handleSubmit = async (e) => {
338
+ const handleSubmit = async (e: React.FormEvent) => {
459
339
  e.preventDefault();
460
340
  setLoading(true);
461
- // Your auth logic
341
+ setError('');
342
+
343
+ try {
344
+ await signIn(email, password);
345
+ // Custom success logic
346
+ } catch (err) {
347
+ setError(err.message);
348
+ } finally {
349
+ setLoading(false);
350
+ }
462
351
  };
463
352
 
464
353
  return (
@@ -471,23 +360,15 @@ function CustomSignIn() {
471
360
  error={error}
472
361
  loading={loading}
473
362
  availableProviders={['google', 'github']}
474
- onOAuthClick={(provider) => handleOAuth(provider)}
363
+ onOAuthClick={(provider) => {
364
+ // Custom OAuth logic
365
+ }}
475
366
  />
476
367
  );
477
368
  }
478
369
  ```
479
370
 
480
- **Other Form Components:**
481
- - `<SignUpForm />` - Sign up with password strength
482
- - `<ForgotPasswordForm />` - Request password reset
483
- - `<ResetPasswordForm />` - Reset password with token
484
- - `<VerifyEmailStatus />` - Email verification status
485
-
486
- ---
487
-
488
- ## Atomic Components (Maximum Flexibility)
489
-
490
- Build completely custom UIs:
371
+ ### Build from Atomic Components
491
372
 
492
373
  ```tsx
493
374
  import {
@@ -564,143 +445,29 @@ function CompletelyCustomAuth() {
564
445
  }
565
446
  ```
566
447
 
567
- **Available Atomic Components:**
568
- - `AuthContainer` - Main wrapper with branding
569
- - `AuthHeader` - Title and subtitle
570
- - `AuthErrorBanner` - Error messages
571
- - `AuthFormField` - Standard input
572
- - `AuthPasswordField` - Password with toggle
573
- - `AuthPasswordStrengthIndicator` - Password checklist
574
- - `AuthSubmitButton` - Loading button
575
- - `AuthLink` - Navigation link
576
- - `AuthDivider` - Visual separator
577
- - `AuthOAuthButton` - Single OAuth button
578
- - `AuthOAuthProviders` - OAuth grid
579
- - `AuthVerificationCodeInput` - 6-digit OTP
580
- - `AuthBranding` - Insforge branding
581
-
582
- ---
583
-
584
- ## Customization
585
-
586
- ### Appearance Props
587
-
588
- All components support Tailwind className overrides:
589
-
590
- ```tsx
591
- <SignIn
592
- appearance={{
593
- containerClassName: "shadow-2xl max-w-lg",
594
- cardClassName: "bg-gradient-to-br from-blue-50 to-white",
595
- formClassName: "space-y-6",
596
- buttonClassName: "bg-blue-600 hover:bg-blue-700 h-12"
597
- }}
598
- />
599
-
600
- <UserButton
601
- appearance={{
602
- buttonClassName: "hover:bg-gray-100 rounded-full",
603
- nameClassName: "text-gray-900 font-semibold",
604
- emailClassName: "text-gray-500",
605
- dropdownClassName: "shadow-xl"
606
- }}
607
- />
608
- ```
609
-
610
- ### Text Customization
611
-
612
- All text is customizable:
613
-
614
- ```tsx
615
- <SignIn
616
- title="Welcome Back!"
617
- subtitle="We're happy to see you again"
618
- emailLabel="Your Email Address"
619
- emailPlaceholder="you@company.com"
620
- passwordLabel="Your Password"
621
- submitButtonText="Login Now"
622
- loadingButtonText="Signing you in..."
623
- signUpText="New to our platform?"
624
- signUpLinkText="Create an account"
625
- dividerText="or continue with"
626
- />
627
- ```
628
-
629
- ---
630
-
631
- ## Framework Integration
632
-
633
- ### Next.js (App Router)
448
+ ### Route Protection
634
449
 
635
450
  ```tsx
636
- // app/layout.tsx
637
- 'use client';
638
- import { InsforgeProvider } from '@insforge/react';
639
- import '@insforge/react/styles.css';
451
+ import { Protect } from '@insforge/react';
640
452
 
641
- export default function RootLayout({ children }) {
453
+ function Dashboard() {
642
454
  return (
643
- <html>
644
- <body>
645
- <InsforgeProvider
646
- baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL}
647
- syncTokenToCookie={async (token) => {
648
- await fetch('/api/auth', {
649
- method: 'POST',
650
- body: JSON.stringify({ token })
651
- });
652
- return true;
653
- }}
654
- clearCookie={async () => {
655
- await fetch('/api/auth', { method: 'DELETE' });
656
- }}
657
- >
658
- {children}
659
- </InsforgeProvider>
660
- </body>
661
- </html>
662
- );
663
- }
664
- ```
665
-
666
- ### Vite / React
667
-
668
- ```tsx
669
- // src/main.tsx
670
- import { StrictMode } from 'react';
671
- import { createRoot } from 'react-dom/client';
672
- import { BrowserRouter } from 'react-router-dom';
673
- import { InsforgeProvider } from '@insforge/react';
674
- import '@insforge/react/styles.css';
675
- import App from './App';
676
-
677
- createRoot(document.getElementById('root')!).render(
678
- <StrictMode>
679
- <BrowserRouter>
680
- <InsforgeProvider baseUrl={import.meta.env.VITE_INSFORGE_BASE_URL}>
681
- <App />
682
- </InsforgeProvider>
683
- </BrowserRouter>
684
- </StrictMode>
685
- );
686
- ```
687
-
688
- ### Remix
689
-
690
- ```tsx
691
- // app/root.tsx
692
- import { InsforgeProvider } from '@insforge/react';
693
- import '@insforge/react/styles.css';
455
+ <div>
456
+ <h1>Dashboard</h1>
457
+
458
+ {/* Simple protection */}
459
+ <Protect redirectTo="/sign-in">
460
+ <UserContent />
461
+ </Protect>
694
462
 
695
- export default function App() {
696
- return (
697
- <html>
698
- <body>
699
- <InsforgeProvider baseUrl={process.env.INSFORGE_BASE_URL}>
700
- <Outlet />
701
- </InsforgeProvider>
702
- </body>
703
- </html>
463
+ {/* Role-based protection */}
464
+ <Protect
465
+ redirectTo="/unauthorized"
466
+ condition={(user) => user.role === 'admin'}
467
+ >
468
+ <AdminPanel />
469
+ </Protect>
470
+ </div>
704
471
  );
705
472
  }
706
473
  ```
@@ -716,6 +483,8 @@ import type {
716
483
  InsforgeUser,
717
484
  SignInProps,
718
485
  SignUpProps,
486
+ SignInAppearance,
487
+ SignUpAppearance,
719
488
  UserButtonProps,
720
489
  ProtectProps,
721
490
  ConditionalProps,
@@ -726,74 +495,12 @@ import type {
726
495
  OAuthProvider,
727
496
  EmailAuthConfig,
728
497
  InsforgeProviderProps,
498
+ GetInsforgeRoutesConfig,
729
499
  } from '@insforge/react';
730
500
  ```
731
501
 
732
502
  ---
733
503
 
734
- ## API Reference
735
-
736
- ### InsforgeProvider Props
737
-
738
- ```tsx
739
- interface InsforgeProviderProps {
740
- baseUrl: string; // Insforge backend URL
741
- onAuthChange?: (user: InsforgeUser | null) => void; // Auth state callback
742
- syncTokenToCookie?: (token: string) => Promise<boolean>; // Custom cookie sync
743
- clearCookie?: () => Promise<void>; // Custom cookie clear
744
- }
745
- ```
746
-
747
- ### SignIn / SignUp Props
748
-
749
- ```tsx
750
- interface SignInProps {
751
- afterSignInUrl?: string; // Redirect after sign in
752
- signUpUrl?: string; // Link to sign up page
753
- forgotPasswordUrl?: string; // Link to forgot password
754
- onSuccess?: (user, token) => void; // Success callback
755
- onError?: (error: Error) => void; // Error callback
756
- onRedirect?: (url: string) => void; // Custom redirect handler
757
- title?: string; // Custom title
758
- subtitle?: string; // Custom subtitle
759
- appearance?: { // Custom styling
760
- containerClassName?: string;
761
- cardClassName?: string;
762
- formClassName?: string;
763
- buttonClassName?: string;
764
- };
765
- // ... more text customization props
766
- }
767
- ```
768
-
769
- ### InsforgeCallback Props
770
-
771
- ```tsx
772
- interface InsforgeCallbackProps {
773
- redirectTo?: string; // Custom redirect destination
774
- onSuccess?: () => void; // Success callback
775
- onError?: (error: string) => void; // Error callback
776
- loadingComponent?: ReactNode; // Custom loading UI
777
- onRedirect?: (url: string) => void; // Custom redirect handler
778
- }
779
- ```
780
-
781
- ---
782
-
783
- ## Validation Utilities
784
-
785
- ```tsx
786
- import { emailSchema, cn } from '@insforge/react';
787
-
788
- // Validate email with Zod
789
- const result = emailSchema.safeParse('user@example.com');
790
-
791
- // Merge Tailwind classes
792
- const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
793
- ```
794
-
795
- ---
796
-
797
504
  ## OAuth Providers
798
505
 
799
506
  Built-in support for 10+ OAuth providers:
@@ -813,28 +520,37 @@ Providers are auto-detected from your backend configuration.
813
520
 
814
521
  ---
815
522
 
816
- ## Why @insforge/react?
523
+ ## Validation Utilities
817
524
 
818
- **vs. Building Custom Auth:**
819
- - ⚡️ 5 minutes vs 2+ days of development
820
- - 🔒 Production-ready security built-in
821
- - 🎨 Customizable when needed, works out of the box
822
- - 🚀 No framework lock-in
525
+ ```tsx
526
+ import { emailSchema, cn } from '@insforge/react/lib';
823
527
 
824
- **vs. Other Auth Libraries:**
825
- - 📦 Complete package (not just UI)
826
- - 🎯 Framework agnostic (works everywhere)
827
- - 🤖 SDK-first approach (consistent API)
828
- - 💰 Self-hosted (no vendor lock-in)
528
+ // Validate email with Zod
529
+ const result = emailSchema.safeParse('user@example.com');
829
530
 
830
- ---
531
+ // Merge Tailwind classes
532
+ const className = cn('px-4 py-2', 'bg-blue-500', conditionalClass);
533
+ ```
831
534
 
832
- ## Examples
535
+ ---
833
536
 
834
- Check out example integrations:
835
- - [Next.js App Router](./examples/nextjs)
836
- - [Vite + React Router](./examples/vite)
837
- - [Remix](./examples/remix)
537
+ ## Available Atomic Components
538
+
539
+ Low-level building blocks for complete customization:
540
+
541
+ - `<AuthBranding />` - Insforge branding footer
542
+ - `<AuthContainer />` - Main container wrapper
543
+ - `<AuthHeader />` - Title and subtitle display
544
+ - `<AuthErrorBanner />` - Error message display
545
+ - `<AuthFormField />` - Standard input field
546
+ - `<AuthPasswordField />` - Password input with features
547
+ - `<AuthPasswordStrengthIndicator />` - Password checklist
548
+ - `<AuthSubmitButton />` - Submit button with states
549
+ - `<AuthLink />` - Call-to-action link
550
+ - `<AuthDivider />` - Visual separator
551
+ - `<AuthOAuthButton />` - Single OAuth provider button
552
+ - `<AuthOAuthProviders />` - Smart OAuth grid
553
+ - `<AuthVerificationCodeInput />` - 6-digit OTP input
838
554
 
839
555
  ---
840
556