77 */
88
99import React , { useState , useEffect , useCallback , useMemo } from 'react' ;
10- import type { AuthUser , AuthClient , AuthProviderConfig } from './types' ;
10+ import type { AuthUser , AuthClient , AuthProviderConfig , PreviewModeOptions } from './types' ;
1111import { AuthCtx , type AuthContextValue } from './AuthContext' ;
1212import { createAuthClient } from './createAuthClient' ;
1313
@@ -20,6 +20,12 @@ export interface AuthProviderProps extends AuthProviderConfig {
2020 * @default true
2121 */
2222 enabled ?: boolean ;
23+ /**
24+ * Preview mode configuration.
25+ * When provided, the auth provider auto-logs in a simulated user and bypasses
26+ * login/registration screens. Useful for marketplace demos and app showcases.
27+ */
28+ previewMode ?: PreviewModeOptions ;
2329}
2430
2531/**
@@ -41,12 +47,19 @@ export interface AuthProviderProps extends AuthProviderConfig {
4147 * <App />
4248 * </AuthProvider>
4349 * ```
50+ * @example With preview mode (marketplace demo)
51+ * ```tsx
52+ * <AuthProvider authUrl="/api/auth" previewMode={{ simulatedRole: 'admin', bannerMessage: 'Demo mode' }}>
53+ * <App />
54+ * </AuthProvider>
55+ * ```
4456 */
4557export function AuthProvider ( {
4658 authUrl,
4759 client : externalClient ,
4860 onAuthStateChange,
4961 enabled = true ,
62+ previewMode,
5063 children,
5164} : AuthProviderProps ) {
5265 const client = useMemo < AuthClient > (
@@ -59,13 +72,38 @@ export function AuthProvider({
5972 const [ isLoading , setIsLoading ] = useState ( true ) ;
6073 const [ error , setError ] = useState < Error | null > ( null ) ;
6174
62- // If auth is disabled, automatically set as authenticated with a guest user
63- const isAuthenticated = enabled
75+ // Determine if we're in preview mode
76+ const isPreviewMode = previewMode != null ;
77+
78+ // If auth is disabled or in preview mode, automatically set as authenticated
79+ const isAuthenticated = ( enabled && ! isPreviewMode )
6480 ? user !== null && session !== null
6581 : true ;
6682
67- // Load session on mount (only if auth is enabled)
83+ // Load session on mount (only if auth is enabled and not in preview mode )
6884 useEffect ( ( ) => {
85+ if ( isPreviewMode ) {
86+ // Preview mode: simulate a user based on previewMode config
87+ const role = previewMode . simulatedRole ?? 'admin' ;
88+ const name = previewMode . simulatedUserName ?? 'Preview User' ;
89+ const expiresInSeconds = previewMode . expiresInSeconds ?? 0 ;
90+ setUser ( {
91+ id : 'preview-user' ,
92+ email : 'preview@preview.local' ,
93+ name,
94+ role,
95+ roles : [ role ] ,
96+ } ) ;
97+ setSession ( {
98+ token : 'preview-token' ,
99+ expiresAt : expiresInSeconds > 0
100+ ? new Date ( Date . now ( ) + expiresInSeconds * 1000 )
101+ : new Date ( Date . now ( ) + 365 * 24 * 60 * 60 * 1000 ) ,
102+ } ) ;
103+ setIsLoading ( false ) ;
104+ return ;
105+ }
106+
69107 if ( ! enabled ) {
70108 // When auth is disabled, set a guest user and mark as loaded
71109 setUser ( {
@@ -103,7 +141,7 @@ export function AuthProvider({
103141
104142 loadSession ( ) ;
105143 return ( ) => { cancelled = true ; } ;
106- } , [ client , enabled ] ) ;
144+ } , [ client , enabled , isPreviewMode , previewMode ] ) ;
107145
108146 // Notify on auth state changes
109147 useEffect ( ( ) => {
@@ -218,14 +256,16 @@ export function AuthProvider({
218256 isAuthenticated,
219257 isLoading,
220258 error,
259+ isPreviewMode,
260+ previewMode : isPreviewMode ? previewMode : null ,
221261 signIn,
222262 signUp,
223263 signOut,
224264 updateUser,
225265 forgotPassword,
226266 resetPassword,
227267 } ) ,
228- [ user , session , isAuthenticated , isLoading , error , signIn , signUp , signOut , updateUser , forgotPassword , resetPassword ] ,
268+ [ user , session , isAuthenticated , isLoading , error , isPreviewMode , previewMode , signIn , signUp , signOut , updateUser , forgotPassword , resetPassword ] ,
229269 ) ;
230270
231271 return < AuthCtx . Provider value = { value } > { children } </ AuthCtx . Provider > ;
0 commit comments