@skylabs-digital/react-identity-access 1.0.0 → 1.1.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/CHANGELOG.md +32 -0
- package/README.md +8 -8
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +1017 -972
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/AppProvider.d.ts +1 -17
- package/dist/providers/AppProvider.d.ts.map +1 -1
- package/dist/providers/AuthProvider.d.ts.map +1 -1
- package/dist/providers/FeatureFlagProvider.d.ts.map +1 -1
- package/dist/providers/SubscriptionProvider.d.ts.map +1 -1
- package/dist/providers/TenantProvider.d.ts +25 -3
- package/dist/providers/TenantProvider.d.ts.map +1 -1
- package/package.json +5 -2
package/dist/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/services/HttpService.ts","../src/services/TenantApiService.ts","../src/services/AppApiService.ts","../src/providers/AppProvider.tsx","../src/services/SessionManager.ts","../src/services/AuthApiService.ts","../src/services/RoleApiService.ts","../src/services/UserApiService.ts","../src/providers/AuthProvider.tsx","../src/services/FeatureFlagApiService.ts","../src/providers/FeatureFlagProvider.tsx","../src/services/SubscriptionApiService.ts","../src/providers/SubscriptionProvider.tsx","../src/providers/TenantProvider.tsx","../src/types/api.ts","../src/components/Protected.tsx","../src/components/ProtectedRoute.tsx","../src/components/SubscriptionGuard.tsx","../src/components/FeatureFlag.tsx","../src/components/LoginForm.tsx","../src/components/SignupForm.tsx","../src/components/PasswordRecoveryForm.tsx","../src/services/PermissionApiService.ts","../src/services/SubscriptionPlanApiService.ts","../src/services/HealthApiService.ts","../src/utils/mappers.ts"],"sourcesContent":["export interface RequestOptions {\n headers?: Record<string, string>;\n timeout?: number;\n skipAuth?: boolean; // Skip automatic auth header injection\n skipRetry?: boolean; // Skip automatic retry on 401\n}\n\nexport class HttpService {\n private baseUrl: string;\n private timeout: number;\n private sessionManager?: any; // SessionManager instance\n\n constructor(baseUrl: string, timeout = 10000) {\n this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.timeout = timeout;\n }\n\n setSessionManager(sessionManager: any): void {\n this.sessionManager = sessionManager;\n }\n\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n private async request<T>(\n method: string,\n endpoint: string,\n data?: any,\n options?: RequestOptions\n ): Promise<T> {\n return this.executeRequest<T>(method, endpoint, data, options, false);\n }\n\n private async executeRequest<T>(\n method: string,\n endpoint: string,\n data?: any,\n options?: RequestOptions,\n isRetry = false\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;\n const requestTimeout = options?.timeout || this.timeout;\n\n // Inject auth headers automatically unless skipAuth is true\n let requestHeaders = {\n 'Content-Type': 'application/json',\n ...options?.headers,\n };\n\n if (!options?.skipAuth && this.sessionManager) {\n try {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n requestHeaders = { ...requestHeaders, ...authHeaders };\n } catch (error) {\n // If auth header injection fails, continue without auth\n console.warn('Failed to inject auth headers:', error);\n }\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), requestTimeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: data ? JSON.stringify(data) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle 401 Unauthorized with automatic retry\n if (response.status === 401 && !options?.skipRetry && !isRetry && this.sessionManager) {\n try {\n // Force token refresh by clearing current tokens and getting new auth headers\n const tokens = this.sessionManager.getTokens();\n if (tokens?.refreshToken) {\n // Trigger refresh through getAuthHeaders with expired token\n await this.sessionManager.getAuthHeaders();\n\n // Retry the original request\n return this.executeRequest<T>(method, endpoint, data, options, true);\n }\n } catch {\n // If refresh fails, throw the original 401 error\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Handle empty responses\n const contentType = response.headers.get('content-type');\n if (!contentType || !contentType.includes('application/json')) {\n return {} as T;\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timeout after ${requestTimeout}ms`);\n }\n\n throw error;\n }\n }\n\n async get<T>(endpoint: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', endpoint, undefined, options);\n }\n\n async post<T>(endpoint: string, data: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', endpoint, data, options);\n }\n\n async put<T>(endpoint: string, data: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', endpoint, data, options);\n }\n\n async delete<T>(endpoint: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', endpoint, undefined, options);\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Tenant,\n CreateTenantRequest,\n PublicTenantInfo,\n TenantSettings,\n UpdateTenantSettingsRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class TenantApiService {\n constructor(\n private httpService: HttpService,\n private appId: string,\n private sessionManager?: SessionManager\n ) {}\n\n async createTenant(request: CreateTenantRequest): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Tenant>>('/tenants/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getTenants(params?: PaginationParams): Promise<{ tenants: Tenant[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/tenants/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Tenant[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n tenants: response.data,\n meta: response.meta,\n };\n }\n\n async getTenantById(id: string): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Tenant>>(`/tenants/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateTenant(id: string, request: Partial<CreateTenantRequest>): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Tenant>>(`/tenants/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async adminUpdateTenant(id: string, request: Partial<CreateTenantRequest>): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Tenant>>(\n `/tenants/${id}/admin-update`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n // Public endpoint - no auth required\n async getPublicTenantInfo(slug: string): Promise<PublicTenantInfo> {\n const response = await this.httpService.get<ApiResponse<PublicTenantInfo>>(\n `/tenants/${this.appId}/${slug}/public`\n );\n return response.data;\n }\n\n // Settings endpoints\n async getTenantSettings(id: string): Promise<TenantSettings> {\n const response = await this.httpService.get<ApiResponse<TenantSettings>>(\n `/tenants/${id}/settings`\n );\n return response.data;\n }\n\n async updateTenantSettings(\n id: string,\n request: UpdateTenantSettingsRequest\n ): Promise<TenantSettings> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<TenantSettings>>(\n `/tenants/${id}/settings`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n ApiResponse,\n App,\n CreateAppRequest,\n PublicAppInfo,\n PaginationParams,\n} from '../types/api';\n\nexport class AppApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager: SessionManager\n ) {}\n\n async createApp(request: CreateAppRequest): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<App>>('/apps/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getApps(params?: PaginationParams): Promise<{ apps: App[]; meta: any }> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/apps/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<App[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n apps: response.data,\n meta: response.meta,\n };\n }\n\n async getAppById(id: string): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<App>>(`/apps/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateApp(id: string, request: Partial<CreateAppRequest>): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<App>>(`/apps/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getPublicAppInfo(id: string): Promise<PublicAppInfo> {\n const response = await this.httpService.get<ApiResponse<PublicAppInfo>>(`/apps/${id}/public`);\n return response.data;\n }\n\n async setDefaultSubscriptionPlan(appId: string, planId: string): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<App>>(\n `/apps/${appId}/default-subscription-plan`,\n { planId },\n { headers: authHeaders }\n );\n return response.data;\n }\n\n async updateSettingsSchema(appId: string, schema: any, defaultSettings: any): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<App>>(\n `/apps/${appId}/settings-schema`,\n { schema, defaultSettings },\n { headers: authHeaders }\n );\n return response.data;\n }\n\n async exportConfig(appId: string): Promise<any> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<any>>(`/apps/${appId}/export-config`, {\n headers: authHeaders,\n });\n return response.data;\n }\n}\n","import {\n createContext,\n useContext,\n useMemo,\n ReactNode,\n useState,\n useEffect,\n useCallback,\n} from 'react';\nimport { HttpService } from '../services/HttpService';\nimport { TenantApiService } from '../services/TenantApiService';\nimport { AppApiService } from '../services/AppApiService';\nimport type { PublicTenantInfo, PublicAppInfo } from '../types/api';\n\nexport interface AppConfig {\n baseUrl: string;\n appId: string;\n // Tenant configuration\n tenantMode?: 'subdomain' | 'selector' | 'fixed';\n fixedTenantSlug?: string; // Required when tenantMode is 'fixed'\n selectorParam?: string; // Default: 'tenant', used when tenantMode is 'selector'\n // SSR support\n initialTenant?: PublicTenantInfo;\n // Fallbacks\n loadingFallback?: ReactNode;\n errorFallback?: ReactNode | ((error: Error, retry: () => void) => ReactNode);\n}\n\ninterface AppContextValue {\n appId: string;\n baseUrl: string;\n // Tenant info\n tenant: PublicTenantInfo | null;\n tenantSlug: string | null;\n isTenantLoading: boolean;\n tenantError: Error | null;\n retryTenant: () => void;\n // App info with settings schema\n appInfo: PublicAppInfo | null;\n isAppLoading: boolean;\n appError: Error | null;\n retryApp: () => void;\n}\n\nconst AppContext = createContext<AppContextValue | null>(null);\n\ninterface AppProviderProps {\n config: AppConfig;\n children: ReactNode;\n}\n\n// Default loading component\nconst DefaultLoadingFallback = () => (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontFamily: 'system-ui, sans-serif',\n }}\n >\n <div>Loading application...</div>\n </div>\n);\n\n// Default error component\nconst DefaultErrorFallback = ({ error, retry }: { error: Error; retry: () => void }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontFamily: 'system-ui, sans-serif',\n textAlign: 'center',\n padding: '20px',\n }}\n >\n <h2 style={{ color: '#dc3545', marginBottom: '16px' }}>Application Error</h2>\n <p style={{ color: '#6c757d', marginBottom: '24px' }}>\n {error.message || 'Unable to load application'}\n </p>\n <button\n onClick={retry}\n style={{\n padding: '8px 16px',\n backgroundColor: '#007bff',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Retry\n </button>\n </div>\n);\n\nexport function AppProvider({ config, children }: AppProviderProps) {\n const [tenant, setTenant] = useState<PublicTenantInfo | null>(config.initialTenant || null);\n const [isTenantLoading, setIsTenantLoading] = useState(!config.initialTenant);\n const [tenantError, setTenantError] = useState<Error | null>(null);\n\n // App info state\n const [appInfo, setAppInfo] = useState<PublicAppInfo | null>(null);\n const [isAppLoading, setIsAppLoading] = useState(true);\n const [appError, setAppError] = useState<Error | null>(null);\n\n // Detect tenant slug from URL or config with localStorage fallback\n const detectTenantSlug = useCallback((): string | null => {\n const tenantMode = config.tenantMode || 'fixed';\n const storageKey = `tenant`;\n\n if (tenantMode === 'fixed') {\n return config.fixedTenantSlug || null;\n }\n\n if (typeof window === 'undefined') return null;\n\n if (tenantMode === 'subdomain') {\n const hostname = window.location.hostname;\n const parts = hostname.split('.');\n\n // Extract subdomain (assuming format: subdomain.domain.com)\n if (parts.length >= 3) {\n const subdomain = parts[0];\n // Save to localStorage for persistence\n localStorage.setItem(storageKey, subdomain);\n return subdomain;\n }\n\n // Fallback to localStorage if no subdomain found\n return localStorage.getItem(storageKey);\n } else {\n // tenantMode === 'selector'\n const urlParams = new URLSearchParams(window.location.search);\n const urlTenant = urlParams.get(config.selectorParam || 'tenant');\n\n if (urlTenant) {\n // Save to localStorage when found in URL\n localStorage.setItem(storageKey, urlTenant);\n return urlTenant;\n }\n\n // Fallback to localStorage if not in URL\n return localStorage.getItem(storageKey);\n }\n }, [config.tenantMode, config.fixedTenantSlug, config.selectorParam]);\n\n const tenantSlug = useMemo(() => detectTenantSlug(), [detectTenantSlug]);\n\n const contextValue = useMemo(() => {\n // Retry function for tenant loading\n const retryTenant = () => {\n if (tenantSlug) {\n loadTenant(tenantSlug);\n }\n };\n\n // Retry function for app loading\n const retryApp = () => {\n loadApp();\n };\n\n return {\n appId: config.appId,\n baseUrl: config.baseUrl,\n // Tenant info\n tenant,\n tenantSlug,\n isTenantLoading,\n tenantError,\n retryTenant,\n // App info\n appInfo,\n isAppLoading,\n appError,\n retryApp,\n };\n }, [config, tenant, tenantSlug, isTenantLoading, tenantError, appInfo, isAppLoading, appError]);\n\n // Load app info\n const loadApp = useCallback(async () => {\n try {\n setIsAppLoading(true);\n setAppError(null);\n\n const httpService = new HttpService(config.baseUrl);\n const appApi = new AppApiService(httpService, {} as any); // SessionManager not needed for public endpoint\n const appData = await appApi.getPublicAppInfo(config.appId);\n setAppInfo(appData);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load app information');\n setAppError(error);\n setAppInfo(null);\n } finally {\n setIsAppLoading(false);\n }\n }, [config.baseUrl, config.appId]);\n\n // Load tenant info\n const loadTenant = useCallback(\n async (slug: string) => {\n try {\n setIsTenantLoading(true);\n setTenantError(null);\n\n const httpService = new HttpService(config.baseUrl);\n const tenantApi = new TenantApiService(httpService, config.appId);\n const tenantInfo = await tenantApi.getPublicTenantInfo(slug);\n setTenant(tenantInfo);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load tenant information');\n setTenantError(error);\n setTenant(null);\n } finally {\n setIsTenantLoading(false);\n }\n },\n [config.baseUrl, config.appId]\n );\n\n // Load app info on mount\n useEffect(() => {\n loadApp();\n }, [loadApp]);\n\n // Load tenant on mount (if not SSR)\n useEffect(() => {\n if (!config.initialTenant && tenantSlug) {\n loadTenant(tenantSlug);\n } else if (!config.initialTenant && !tenantSlug && config.tenantMode !== 'fixed') {\n const mode = config.tenantMode || 'fixed';\n setTenantError(\n new Error(`No tenant ${mode === 'subdomain' ? 'subdomain' : 'parameter'} found`)\n );\n setIsTenantLoading(false);\n } else if (config.tenantMode === 'fixed' && !config.fixedTenantSlug) {\n setTenantError(new Error('Fixed tenant mode requires fixedTenantSlug configuration'));\n setIsTenantLoading(false);\n }\n }, [config.initialTenant, tenantSlug, loadTenant, config.tenantMode, config.fixedTenantSlug]);\n\n // Show loading fallback\n if (isTenantLoading) {\n return <>{config.loadingFallback || <DefaultLoadingFallback />}</>;\n }\n\n // Show error fallback\n if (tenantError) {\n const ErrorComponent =\n typeof config.errorFallback === 'function'\n ? config.errorFallback(tenantError, () => loadTenant(tenantSlug || ''))\n : config.errorFallback || (\n <DefaultErrorFallback error={tenantError} retry={() => loadTenant(tenantSlug || '')} />\n );\n\n return <>{ErrorComponent}</>;\n }\n\n // Show children only when we have tenant info (or when tenant is not required)\n if (!tenant && config.tenantMode !== 'fixed') {\n return (\n <DefaultErrorFallback\n error={new Error('No tenant information available')}\n retry={() => loadTenant(tenantSlug || '')}\n />\n );\n }\n\n return <AppContext.Provider value={contextValue}>{children}</AppContext.Provider>;\n}\n\nexport function useApp(): AppContextValue {\n const context = useContext(AppContext);\n if (!context) {\n throw new Error('useApp must be used within an AppProvider');\n }\n return context;\n}\n\n// Backward compatibility\nexport const useApi = useApp;\n\n// Tenant hook\nexport function useTenant() {\n const { tenant, tenantSlug, isTenantLoading, tenantError, retryTenant } = useApp();\n return {\n tenant,\n tenantSlug,\n isLoading: isTenantLoading,\n error: tenantError,\n retry: retryTenant,\n };\n}\n","export interface TokenData {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n expiresIn?: number;\n tokenType?: string;\n}\n\nexport interface TokenStorage {\n get(): any;\n set(data: any): void;\n clear(): void;\n}\n\nexport interface SessionConfig {\n storageKey?: string;\n autoRefresh?: boolean;\n refreshThreshold?: number;\n onRefreshFailed?: () => void;\n tokenStorage?: TokenStorage;\n baseUrl?: string; // Base URL for API calls\n}\n\nexport class SessionManager {\n private storageKey: string;\n private autoRefresh: boolean;\n private refreshThreshold: number;\n private baseUrl: string;\n private onRefreshFailed?: () => void;\n private tokenStorage: TokenStorage;\n\n // Refresh queue management\n private refreshPromise: Promise<void> | null = null;\n private refreshQueue: Array<{\n resolve: (headers: Record<string, string>) => void;\n reject: (error: Error) => void;\n }> = [];\n\n constructor(config: SessionConfig = {}) {\n this.storageKey = config.storageKey || 'auth_tokens';\n this.autoRefresh = config.autoRefresh ?? true;\n this.refreshThreshold = config.refreshThreshold || 300000; // 5 minutes\n this.onRefreshFailed = config.onRefreshFailed;\n this.baseUrl = config.baseUrl || '';\n\n // Use provided tokenStorage or create default localStorage implementation\n this.tokenStorage = config.tokenStorage || {\n get: () => {\n try {\n const stored = localStorage.getItem(this.storageKey);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n },\n set: (data: any) => {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(data));\n } catch {\n // Handle storage errors silently\n }\n },\n clear: () => {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // Handle storage errors silently\n }\n },\n };\n }\n\n setTokens(tokens: TokenData): void {\n // Convert expiresIn to expiresAt if needed\n const tokenData: TokenData = {\n ...tokens,\n expiresAt:\n tokens.expiresAt || (tokens.expiresIn ? Date.now() + tokens.expiresIn * 1000 : undefined),\n };\n\n this.tokenStorage.set(tokenData);\n }\n\n getTokens(): TokenData | null {\n return this.tokenStorage.get();\n }\n\n clearTokens(): void {\n this.tokenStorage.clear();\n }\n\n isTokenExpired(token?: TokenData): boolean {\n const tokens = token || this.getTokens();\n if (!tokens?.expiresAt) return false;\n\n return Date.now() >= tokens.expiresAt;\n }\n\n shouldRefreshToken(token?: TokenData): boolean {\n const tokens = token || this.getTokens();\n if (!tokens?.expiresAt || !this.autoRefresh) return false;\n\n return Date.now() >= tokens.expiresAt - this.refreshThreshold;\n }\n\n getAccessToken(): string | null {\n const tokens = this.getTokens();\n return tokens?.accessToken || null;\n }\n\n async getAuthHeaders(): Promise<Record<string, string>> {\n const tokens = this.getTokens();\n\n // No tokens available\n if (!tokens?.accessToken) {\n return {};\n }\n\n // Token is valid and doesn't need refresh yet, return headers immediately\n if (!this.shouldRefreshToken(tokens)) {\n return {\n Authorization: `Bearer ${tokens.accessToken}`,\n };\n }\n\n // Token needs refresh\n if (!tokens.refreshToken) {\n // No refresh token available, clear session and return empty headers\n this.clearSession();\n if (this.onRefreshFailed) {\n this.onRefreshFailed();\n }\n return {};\n }\n\n // If refresh is already in progress, queue this request\n if (this.refreshPromise) {\n return new Promise((resolve, reject) => {\n this.refreshQueue.push({ resolve, reject });\n });\n }\n\n // Start refresh process\n this.refreshPromise = this.performTokenRefresh(tokens.refreshToken);\n\n try {\n await this.refreshPromise;\n\n // Refresh successful, process queue\n const newTokens = this.getTokens();\n const headers: Record<string, string> = newTokens?.accessToken\n ? { Authorization: `Bearer ${newTokens.accessToken}` }\n : {};\n\n // Resolve all queued requests\n this.refreshQueue.forEach(({ resolve }) => resolve(headers));\n this.refreshQueue = [];\n\n return headers;\n } catch (error) {\n // Refresh failed, reject all queued requests\n const refreshError = error instanceof Error ? error : new Error('Token refresh failed');\n\n this.refreshQueue.forEach(({ reject }) => reject(refreshError));\n this.refreshQueue = [];\n\n // Clear session and notify\n this.clearSession();\n if (this.onRefreshFailed) {\n this.onRefreshFailed();\n }\n\n return {};\n } finally {\n this.refreshPromise = null;\n }\n }\n\n private async performTokenRefresh(refreshToken: string): Promise<void> {\n if (!this.baseUrl) {\n throw new Error('Base URL not configured for token refresh');\n }\n\n const url = `${this.baseUrl}/auth/refresh`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n refreshToken,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Token refresh failed: ${response.status} ${response.statusText}`);\n }\n\n const refreshResponse = await response.json();\n\n this.setTokens({\n accessToken: refreshResponse.accessToken,\n refreshToken: refreshResponse.refreshToken || refreshToken,\n expiresIn: refreshResponse.expiresIn,\n });\n }\n\n setUser(user: any): void {\n // Store user data alongside tokens\n const currentData = this.tokenStorage.get() || {};\n this.tokenStorage.set({ ...currentData, user });\n }\n\n getUser(): any | null {\n const data = this.tokenStorage.get();\n return data?.user || null;\n }\n\n clearUser(): void {\n const currentData = this.tokenStorage.get() || {};\n delete currentData.user;\n this.tokenStorage.set(currentData);\n }\n\n clearSession(): void {\n this.clearTokens();\n this.clearUser();\n }\n\n hasValidSession(): boolean {\n const tokens = this.getTokens();\n return tokens !== null && !this.isTokenExpired(tokens);\n }\n}\n","import { HttpService } from './HttpService';\nimport type {\n LoginRequest,\n LoginResponse,\n SignupRequest,\n ChangePasswordRequest,\n RefreshTokenRequest,\n RefreshTokenResponse,\n ApiResponse,\n User,\n} from '../types/api';\n\nexport class AuthApiService {\n constructor(private httpService: HttpService) {}\n\n // Public endpoints - no auth required\n async login(request: LoginRequest): Promise<LoginResponse> {\n const response = await this.httpService.post<LoginResponse>('/auth/login', request);\n console.log(response);\n return response;\n }\n\n async signup(request: SignupRequest): Promise<User> {\n const response = await this.httpService.post<User>('/auth/signup', request);\n return response;\n }\n\n async signupTenantAdmin(request: {\n email: string;\n name: string;\n password: string;\n tenantName: string;\n appId: string;\n }): Promise<{ user: User; tenant: any }> {\n const response = await this.httpService.post<{ user: User; tenant: any }>(\n '/auth/signup/tenant-admin',\n request\n );\n return response;\n }\n\n async refreshToken(request: RefreshTokenRequest): Promise<RefreshTokenResponse> {\n const response = await this.httpService.post<RefreshTokenResponse>('/auth/refresh', request);\n return response;\n }\n\n async requestPasswordReset(request: { email: string; tenantId: string }): Promise<void> {\n await this.httpService.post<void>('/auth/password-reset/request', request);\n }\n\n async confirmPasswordReset(request: { token: string; newPassword: string }): Promise<void> {\n await this.httpService.post<void>('/auth/password-reset/confirm', request);\n }\n\n // Protected endpoints - auth required\n async changePassword(\n request: ChangePasswordRequest,\n authHeaders: Record<string, string>\n ): Promise<void> {\n await this.httpService.post<ApiResponse<null>>('/auth/change-password', request, {\n headers: authHeaders,\n });\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Role,\n CreateRoleRequest,\n AssignRoleRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class RoleApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createRole(request: CreateRoleRequest): Promise<Role> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Role>>('/roles/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getRoleById(id: string): Promise<Role> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Role>>(`/roles/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateRole(id: string, request: Partial<CreateRoleRequest>): Promise<Role> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Role>>(`/roles/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async deleteRole(id: string): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/roles/${id}`, {\n headers: authHeaders,\n });\n }\n\n // Public endpoint - no auth required\n async getRolesByApp(\n appId: string,\n params?: PaginationParams\n ): Promise<{ roles: Role[]; meta: any }> {\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/roles/app/${appId}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Role[]>>(url);\n\n return {\n roles: response.data,\n meta: response.meta,\n };\n }\n\n async assignRole(roleId: string, request: AssignRoleRequest): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.post<ApiResponse<null>>(`/roles/${roleId}/assign`, request, {\n headers: authHeaders,\n });\n }\n\n async revokeRole(roleId: string, request: AssignRoleRequest): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.post<ApiResponse<null>>(`/roles/${roleId}/revoke`, request, {\n headers: authHeaders,\n });\n }\n\n async getUserRoles(\n userId: string,\n params?: PaginationParams\n ): Promise<{ roles: Role[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/roles/user/${userId}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Role[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n roles: response.data,\n meta: response.meta,\n };\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type { User, CreateUserRequest, ApiResponse, PaginationParams } from '../types/api';\n\nexport class UserApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager: SessionManager\n ) {}\n\n async createUser(request: CreateUserRequest): Promise<User> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<User>>('/users/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getUsers(params?: PaginationParams): Promise<{ users: User[]; meta: any }> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/users/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<User[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n users: response.data,\n meta: response.meta,\n };\n }\n\n async getUserById(id: string): Promise<User> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<User>>(`/users/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateUser(id: string, request: Partial<CreateUserRequest>): Promise<User> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<User>>(`/users/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async deleteUser(id: string): Promise<void> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/users/${id}`, {\n headers: authHeaders,\n });\n }\n}\n","import { createContext, useContext, ReactNode, useMemo, useState, useEffect } from 'react';\nimport { SessionManager } from '../services/SessionManager';\nimport { AuthApiService } from '../services/AuthApiService';\nimport { RoleApiService } from '../services/RoleApiService';\nimport { UserApiService } from '../services/UserApiService';\nimport { HttpService } from '../services/HttpService';\nimport { useApp } from './AppProvider';\nimport type { Role, Permission, User } from '../types/api';\n\nexport interface AuthConfig {\n onRefreshFailed?: () => void;\n initialRoles?: Role[]; // For SSR injection\n}\n\nexport interface AuthContextValue {\n sessionManager: SessionManager;\n authenticatedHttpService: HttpService; // Authenticated HttpService for protected endpoints\n // Auth methods\n login: (email: string, password: string, tenantId: string) => Promise<any>;\n signup: (email: string, name: string, password: string, tenantId: string) => Promise<any>;\n signupTenantAdmin: (\n email: string,\n name: string,\n password: string,\n tenantName: string\n ) => Promise<any>;\n changePassword: (currentPassword: string, newPassword: string) => Promise<void>;\n requestPasswordReset: (email: string, tenantId: string) => Promise<void>;\n confirmPasswordReset: (token: string, newPassword: string) => Promise<void>;\n refreshToken: () => Promise<void>;\n logout: () => void;\n // Session methods\n setTokens: (tokens: { accessToken: string; refreshToken: string; expiresIn: number }) => void;\n hasValidSession: () => boolean;\n clearSession: () => void;\n // User data\n currentUser: User | null;\n isUserLoading: boolean;\n userError: Error | null;\n refreshUser: () => Promise<void>;\n // Role and Permission methods\n userRole: Role | null;\n userPermissions: string[];\n availableRoles: Role[];\n rolesLoading: boolean;\n hasPermission: (permission: string | Permission) => boolean;\n hasAnyPermission: (permissions: (string | Permission)[]) => boolean;\n hasAllPermissions: (permissions: (string | Permission)[]) => boolean;\n getUserPermissionStrings: () => string[];\n refreshRoles: () => Promise<void>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\ninterface AuthProviderProps {\n config?: AuthConfig;\n children: ReactNode;\n}\n\nexport function AuthProvider({ config = {}, children }: AuthProviderProps) {\n const { appId, tenantSlug, baseUrl } = useApp();\n const [availableRoles, setAvailableRoles] = useState<Role[]>(config.initialRoles || []);\n const [rolesLoading, setRolesLoading] = useState(!config.initialRoles);\n const [currentUser, setCurrentUser] = useState<User | null>(null);\n const [isUserLoading, setIsUserLoading] = useState(false);\n const [userError, setUserError] = useState<Error | null>(null);\n\n // Create services with stable references\n const sessionManager = useMemo(() => {\n const storageKey = tenantSlug ? `auth_tokens_${tenantSlug}` : 'auth_tokens';\n const tokenStorage = {\n get: () => {\n try {\n const stored = localStorage.getItem(storageKey);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n },\n set: (tokens: any) => {\n try {\n localStorage.setItem(storageKey, JSON.stringify(tokens));\n } catch {\n // Handle storage errors silently\n }\n },\n clear: () => {\n try {\n localStorage.removeItem(storageKey);\n } catch {\n // Handle storage errors silently\n }\n },\n };\n\n return new SessionManager({\n onRefreshFailed: config.onRefreshFailed,\n tokenStorage,\n baseUrl: baseUrl,\n });\n }, [tenantSlug, baseUrl, config.onRefreshFailed]);\n\n const authenticatedHttpService = useMemo(() => {\n const service = new HttpService(baseUrl);\n service.setSessionManager(sessionManager);\n return service;\n }, [baseUrl, sessionManager]);\n\n const authApiService = useMemo(() => {\n return new AuthApiService(new HttpService(baseUrl));\n }, [baseUrl]);\n\n const userApiService = useMemo(() => {\n return new UserApiService(authenticatedHttpService, sessionManager);\n }, [authenticatedHttpService, sessionManager]);\n\n const roleApiService = useMemo(() => {\n return new RoleApiService(new HttpService(baseUrl));\n }, [baseUrl]);\n\n // Calculate derived values with useMemo to prevent recalculation\n const user = useMemo(() => {\n return currentUser || sessionManager.getUser();\n }, [currentUser, sessionManager]);\n\n const userRole = useMemo(() => {\n return user?.roleId ? availableRoles.find(role => role.id === user.roleId) || null : null;\n }, [user, availableRoles]);\n\n const userPermissions = useMemo(() => {\n const permissions = userRole?.permissions || [];\n // Permissions from API are already strings in 'resource.action' format\n return permissions;\n }, [userRole]);\n\n // Debug log only when userPermissions actually changes\n useEffect(() => {\n console.log('AuthProvider - userPermissions changed:', userPermissions);\n }, [userPermissions]);\n\n const contextValue = useMemo(() => {\n // Load user data from API\n const loadUserData = async () => {\n try {\n setIsUserLoading(true);\n setUserError(null);\n\n const user = sessionManager.getUser();\n if (!user?.id) {\n throw new Error('No user ID available in session');\n }\n\n const userData = await userApiService.getUserById(user.id);\n setCurrentUser(userData);\n sessionManager.setUser(userData); // Update session with fresh data\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load user data');\n setUserError(error);\n console.error('Failed to load user data:', error);\n } finally {\n setIsUserLoading(false);\n }\n };\n\n const refreshUser = async () => {\n await loadUserData();\n };\n\n // Auth methods\n const login = async (email: string, password: string, tenantId: string) => {\n const loginResponse = await authApiService.login({\n email,\n password,\n tenantId,\n });\n\n sessionManager.setTokens({\n accessToken: loginResponse.accessToken,\n refreshToken: loginResponse.refreshToken,\n expiresIn: loginResponse.expiresIn,\n });\n\n // Store user data if available in the response\n if (loginResponse.user) {\n sessionManager.setUser(loginResponse.user);\n setCurrentUser(loginResponse.user);\n\n // Load complete user data from API after login\n try {\n await loadUserData();\n } catch (error) {\n console.warn('Failed to load complete user data after login:', error);\n }\n }\n\n return loginResponse;\n };\n\n const signup = async (email: string, name: string, password: string, tenantId: string) => {\n const signupResponse = await authApiService.signup({ email, name, password, tenantId });\n return signupResponse;\n };\n\n const signupTenantAdmin = async (\n email: string,\n name: string,\n password: string,\n tenantName: string\n ) => {\n const signupResponse = await authApiService.signupTenantAdmin({\n email,\n name,\n password,\n tenantName,\n appId,\n });\n return signupResponse;\n };\n\n const changePassword = async (currentPassword: string, newPassword: string) => {\n const authHeaders = await sessionManager.getAuthHeaders();\n await authApiService.changePassword({ currentPassword, newPassword }, authHeaders);\n };\n\n const requestPasswordReset = async (email: string, tenantId: string) => {\n await authApiService.requestPasswordReset({ email, tenantId });\n };\n\n const confirmPasswordReset = async (token: string, newPassword: string) => {\n await authApiService.confirmPasswordReset({ token, newPassword });\n };\n\n const refreshToken = async () => {\n const tokens = sessionManager.getTokens();\n if (!tokens?.refreshToken) {\n throw new Error('No refresh token available');\n }\n\n const refreshResponse = await authApiService.refreshToken({\n refreshToken: tokens.refreshToken,\n });\n\n sessionManager.setTokens({\n accessToken: refreshResponse.accessToken,\n refreshToken: refreshResponse.refreshToken || tokens.refreshToken,\n expiresIn: refreshResponse.expiresIn,\n });\n };\n\n const logout = () => {\n sessionManager.clearSession();\n setCurrentUser(null);\n setUserError(null);\n };\n\n const setTokens = (tokens: {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n }) => {\n sessionManager.setTokens(tokens);\n };\n\n const hasValidSession = () => {\n return sessionManager.hasValidSession();\n };\n\n const clearSession = () => {\n sessionManager.clearSession();\n setCurrentUser(null);\n setUserError(null);\n };\n\n // Role and Permission methods\n const fetchRoles = async () => {\n if (!appId) return;\n\n try {\n setRolesLoading(true);\n const { roles } = await roleApiService.getRolesByApp(appId);\n setAvailableRoles(roles);\n } catch (error) {\n console.error('Failed to fetch roles:', error);\n } finally {\n setRolesLoading(false);\n }\n };\n\n const refreshRoles = async () => {\n await fetchRoles();\n };\n\n // Helper functions for permission checks\n const hasPermission = (permission: string | Permission): boolean => {\n if (!userPermissions || userPermissions.length === 0) {\n return false;\n }\n\n if (typeof permission === 'string') {\n // userPermissions is now an array of strings in 'resource.action' format\n return userPermissions.includes(permission);\n }\n\n // For Permission objects, convert to string and check\n const permissionString = `${permission.resource}.${permission.action}`;\n return userPermissions.includes(permissionString);\n };\n\n const hasAnyPermission = (permissions: (string | Permission)[]): boolean => {\n return permissions.some(permission => hasPermission(permission));\n };\n\n const hasAllPermissions = (permissions: (string | Permission)[]): boolean => {\n return permissions.every(permission => hasPermission(permission));\n };\n\n // Utility function to get all user permissions in resource.action format\n const getUserPermissionStrings = (): string[] => {\n if (!userPermissions) return [];\n // userPermissions is already an array of strings\n return userPermissions;\n };\n\n return {\n sessionManager,\n authenticatedHttpService,\n login,\n signup,\n signupTenantAdmin,\n changePassword,\n requestPasswordReset,\n confirmPasswordReset,\n refreshToken,\n logout,\n setTokens,\n hasValidSession,\n clearSession,\n currentUser,\n isUserLoading,\n userError,\n refreshUser,\n userRole,\n userPermissions,\n availableRoles,\n rolesLoading,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n getUserPermissionStrings,\n refreshRoles,\n };\n }, [\n sessionManager,\n authenticatedHttpService,\n authApiService,\n userApiService,\n roleApiService,\n appId,\n availableRoles,\n currentUser,\n isUserLoading,\n userError,\n userRole,\n userPermissions,\n ]);\n\n // Fetch roles on mount if not provided via SSR\n useEffect(() => {\n if (!config.initialRoles && appId) {\n const fetchRoles = async () => {\n try {\n setRolesLoading(true);\n const internalHttpService = new HttpService(baseUrl);\n const roleApiService = new RoleApiService(internalHttpService);\n const { roles } = await roleApiService.getRolesByApp(appId);\n setAvailableRoles(roles);\n } catch (error) {\n console.error('Failed to fetch roles:', error);\n } finally {\n setRolesLoading(false);\n }\n };\n\n fetchRoles();\n }\n }, [appId, baseUrl, config.initialRoles]);\n\n // Initialize user data from session on mount\n useEffect(() => {\n const user = sessionManager.getUser();\n if (user && sessionManager.hasValidSession()) {\n setCurrentUser(user);\n }\n }, [sessionManager]);\n\n return <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n ApiResponse,\n FeatureFlagItem,\n FeatureFlagValueResponse,\n FeatureFlag,\n CreateFeatureFlagRequest,\n PaginationParams,\n} from '../types/api';\n\nexport class FeatureFlagApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createFeatureFlag(request: CreateFeatureFlagRequest): Promise<FeatureFlag> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<FeatureFlag>>(\n '/feature-flags/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getFeatureFlags(\n params?: PaginationParams\n ): Promise<{ featureFlags: FeatureFlag[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/feature-flags/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<FeatureFlag[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n featureFlags: response.data,\n meta: response.meta,\n };\n }\n\n async getFeatureFlagById(id: string): Promise<FeatureFlag> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<FeatureFlag>>(`/feature-flags/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateFeatureFlag(\n id: string,\n request: Partial<CreateFeatureFlagRequest>\n ): Promise<FeatureFlag> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<FeatureFlag>>(\n `/feature-flags/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async deleteFeatureFlag(id: string): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/feature-flags/${id}`, {\n headers: authHeaders,\n });\n }\n\n // Public endpoint - no auth required\n async getTenantFeatureFlags(tenantId: string, appId: string): Promise<FeatureFlagItem[]> {\n if (!tenantId || !appId) {\n throw new Error('Tenant ID and App ID are required');\n }\n\n const queryParams = new URLSearchParams();\n queryParams.append('tenantId', tenantId);\n queryParams.append('appId', appId);\n\n const url = `/tenant-feature-flags${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<FeatureFlagItem[]>>(url, {\n headers: { 'X-Tenant-ID': tenantId },\n });\n\n return response.data;\n }\n\n // Public endpoint - no auth required\n async getTenantFeatureFlag(\n flagKey: string,\n tenantId: string,\n appId: string\n ): Promise<FeatureFlagValueResponse> {\n if (!flagKey || !tenantId || !appId) {\n throw new Error('Flag Key, Tenant ID and App ID are required');\n }\n\n const queryParams = new URLSearchParams();\n queryParams.append('tenantId', tenantId);\n queryParams.append('appId', appId);\n\n const url = `/tenant-feature-flags/${flagKey}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<FeatureFlagValueResponse>>(url, {\n headers: { 'X-Tenant-ID': tenantId },\n });\n\n return response.data;\n }\n}\n","import { createContext, useContext, ReactNode, useMemo, useState, useEffect } from 'react';\nimport { FeatureFlagApiService } from '../services/FeatureFlagApiService';\nimport { HttpService } from '../services/HttpService';\nimport { useApp } from './AppProvider';\nimport type { FeatureFlagItem } from '../types/api';\n\nexport interface FeatureFlagConfig {\n refreshInterval?: number; // in milliseconds, default 5 minutes\n onError?: (error: Error) => void;\n}\n\nexport interface FeatureFlagContextValue {\n featureFlags: FeatureFlagItem[];\n loading: boolean;\n error: string | null;\n isEnabled: (flagName: string) => boolean;\n getFlag: (flagName: string) => FeatureFlagItem | undefined;\n refresh: () => Promise<void>;\n}\n\nconst FeatureFlagContext = createContext<FeatureFlagContextValue | null>(null);\n\ninterface FeatureFlagProviderProps {\n config?: FeatureFlagConfig;\n children: ReactNode;\n}\n\nexport function FeatureFlagProvider({ config = {}, children }: FeatureFlagProviderProps) {\n const { tenant, baseUrl, appId } = useApp();\n const [featureFlags, setFeatureFlags] = useState<FeatureFlagItem[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const featureFlagService = useMemo(() => {\n const httpService = new HttpService(baseUrl);\n return new FeatureFlagApiService(httpService);\n }, [baseUrl]);\n\n const fetchFeatureFlags = async () => {\n if (!tenant?.id) {\n setFeatureFlags([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await featureFlagService.getTenantFeatureFlags(tenant.id, appId);\n setFeatureFlags(response);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to fetch feature flags';\n setError(errorMessage);\n if (config.onError) {\n config.onError(err instanceof Error ? err : new Error(errorMessage));\n }\n } finally {\n setLoading(false);\n }\n };\n\n // Initial fetch and setup refresh interval\n useEffect(() => {\n fetchFeatureFlags();\n\n const refreshInterval = config.refreshInterval || 5 * 60 * 1000; // 5 minutes default\n const interval = setInterval(fetchFeatureFlags, refreshInterval);\n\n return () => clearInterval(interval);\n }, [tenant?.id, config.refreshInterval]);\n\n const contextValue = useMemo(() => {\n const isEnabled = (flagKey: string): boolean => {\n const flag = featureFlags.find(f => f.key === flagKey);\n return flag?.value === true;\n };\n\n const getFlag = (flagKey: string): FeatureFlagItem | undefined => {\n return featureFlags.find(f => f.key === flagKey);\n };\n\n const getFlagState = (flagKey: string): 'enabled' | 'disabled' | 'not_found' => {\n const flag = featureFlags.find(f => f.key === flagKey);\n if (!flag) return 'not_found';\n return flag.value ? 'enabled' : 'disabled';\n };\n\n const refresh = async () => {\n await fetchFeatureFlags();\n };\n\n return {\n featureFlags,\n loading,\n error,\n isEnabled,\n getFlag,\n getFlagState,\n refresh,\n };\n }, [featureFlags, loading, error]);\n\n return <FeatureFlagContext.Provider value={contextValue}>{children}</FeatureFlagContext.Provider>;\n}\n\nexport function useFeatureFlags(): FeatureFlagContextValue {\n const context = useContext(FeatureFlagContext);\n if (!context) {\n throw new Error('useFeatureFlags must be used within a FeatureFlagProvider');\n }\n return context;\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Subscription,\n CreateSubscriptionRequest,\n ApiResponse,\n TenantSubscriptionFeatures,\n} from '../types/api';\n\nexport class SubscriptionApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createSubscription(request: CreateSubscriptionRequest): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Subscription>>(\n '/subscriptions/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getSubscriptionById(id: string): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Subscription>>(\n `/subscriptions/subscriptions/${id}`,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async updateSubscription(\n id: string,\n request: Partial<CreateSubscriptionRequest>\n ): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Subscription>>(\n `/subscriptions/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async changeSubscriptionPlan(subscriptionId: string, planId: string): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Subscription>>(\n `/subscriptions/${subscriptionId}/plan`,\n { planId },\n { headers: authHeaders }\n );\n return response.data;\n }\n\n // Public endpoint - no auth required\n async getTenantSubscriptionFeatures(tenantId: string): Promise<TenantSubscriptionFeatures> {\n const response = await this.httpService.get<ApiResponse<TenantSubscriptionFeatures>>(\n `/subscriptions/tenants/${tenantId}/subscription-features`\n );\n return response.data;\n }\n\n async processPayment(subscriptionId: string, paymentData: any): Promise<any> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<any>>(\n `/subscriptions/${subscriptionId}/process-payment`,\n paymentData,\n { headers: authHeaders }\n );\n return response.data;\n }\n}\n","import { createContext, useContext, ReactNode, useMemo, useState, useEffect } from 'react';\nimport { SubscriptionApiService } from '../services/SubscriptionApiService';\nimport { HttpService } from '../services/HttpService';\nimport { useApp } from './AppProvider';\nimport type { TenantSubscriptionFeatures, PlanFeature } from '../types/api';\n\nexport interface SubscriptionConfig {\n refreshInterval?: number; // in milliseconds, default 10 minutes\n onError?: (error: Error) => void;\n}\n\nexport interface SubscriptionContextValue {\n subscription: TenantSubscriptionFeatures | null;\n features: PlanFeature[];\n loading: boolean;\n error: string | null;\n isFeatureEnabled: (featureKey: string) => boolean;\n getFeature: (featureKey: string) => PlanFeature | undefined;\n getFeatureValue: <T = any>(featureKey: string, defaultValue?: T) => T;\n hasAllowedPlan: (allowedPlans: string[]) => boolean;\n refresh: () => Promise<void>;\n}\n\nexport interface SubscriptionProviderProps {\n config?: SubscriptionConfig;\n children: ReactNode;\n}\n\nconst SubscriptionContext = createContext<SubscriptionContextValue | undefined>(undefined);\n\nexport function SubscriptionProvider({ config = {}, children }: SubscriptionProviderProps) {\n const { tenant, baseUrl } = useApp();\n const [subscription, setSubscription] = useState<TenantSubscriptionFeatures | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Create subscription service\n const subscriptionService = useMemo(() => {\n const httpService = new HttpService(baseUrl);\n return new SubscriptionApiService(httpService);\n }, [baseUrl]);\n\n const fetchSubscription = async () => {\n if (!tenant?.id) {\n setSubscription(null);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await subscriptionService.getTenantSubscriptionFeatures(tenant.id);\n setSubscription(response);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to fetch subscription';\n setError(errorMessage);\n if (config.onError) {\n config.onError(err instanceof Error ? err : new Error(errorMessage));\n }\n } finally {\n setLoading(false);\n }\n };\n\n // Fetch subscription on mount and when tenant changes\n useEffect(() => {\n fetchSubscription();\n\n // Set up refresh interval if configured\n if (!config.refreshInterval) return;\n\n const refreshInterval = config.refreshInterval || 10 * 60 * 1000; // 10 minutes default\n const interval = setInterval(fetchSubscription, refreshInterval);\n\n return () => clearInterval(interval);\n }, [tenant?.id, config.refreshInterval]);\n\n const contextValue = useMemo(() => {\n const features = subscription?.features || [];\n\n const isFeatureEnabled = (featureKey: string): boolean => {\n const feature = features.find(f => f.key === featureKey);\n if (!feature) return false;\n\n // Handle different feature types\n if (feature.type === 'BOOLEAN' || feature.type === 'boolean') {\n return feature.value === true;\n }\n\n // For non-boolean features, consider them enabled if they have a truthy value\n return Boolean(feature.value);\n };\n\n const getFeature = (featureKey: string): PlanFeature | undefined => {\n return features.find(f => f.key === featureKey);\n };\n\n const getFeatureValue = <T = any,>(featureKey: string, defaultValue?: T): T => {\n const feature = features.find(f => f.key === featureKey);\n return feature ? feature.value : (defaultValue as T);\n };\n\n const hasAllowedPlan = (allowedPlans: string[]): boolean => {\n if (!subscription || !subscription.isActive) return false;\n\n // Check if current plan is in the allowed plans array\n return allowedPlans.includes(subscription.planId);\n };\n\n const refresh = async () => {\n await fetchSubscription();\n };\n\n return {\n subscription,\n features,\n loading,\n error,\n isFeatureEnabled,\n getFeature,\n getFeatureValue,\n hasAllowedPlan,\n refresh,\n };\n }, [subscription, loading, error]);\n\n return (\n <SubscriptionContext.Provider value={contextValue}>{children}</SubscriptionContext.Provider>\n );\n}\n\nexport function useSubscription(): SubscriptionContextValue {\n const context = useContext(SubscriptionContext);\n if (context === undefined) {\n throw new Error('useSubscription must be used within a SubscriptionProvider');\n }\n return context;\n}\n","import {\n createContext,\n useContext,\n useMemo,\n ReactNode,\n useState,\n useEffect,\n useCallback,\n} from 'react';\nimport { useApp } from './AppProvider';\nimport { useAuth } from './AuthProvider';\nimport { HttpService } from '../services/HttpService';\nimport { TenantApiService } from '../services/TenantApiService';\nimport type { TenantSettings, UpdateTenantSettingsRequest, JSONSchema } from '../types/api';\n\ninterface TenantContextValue {\n // Settings\n settings: TenantSettings | null;\n settingsSchema: JSONSchema | null;\n isSettingsLoading: boolean;\n settingsError: Error | null;\n // Actions\n updateSettings: (settings: TenantSettings) => Promise<void>;\n refreshSettings: () => void;\n // Validation\n validateSettings: (settings: TenantSettings) => { isValid: boolean; errors: string[] };\n}\n\nconst TenantContext = createContext<TenantContextValue | null>(null);\n\ninterface TenantProviderProps {\n children: ReactNode;\n}\n\nexport function TenantProvider({ children }: TenantProviderProps) {\n const { baseUrl, tenant, appInfo } = useApp();\n const { sessionManager } = useAuth();\n\n const [settings, setSettings] = useState<TenantSettings | null>(null);\n const [isSettingsLoading, setIsSettingsLoading] = useState(false);\n const [settingsError, setSettingsError] = useState<Error | null>(null);\n\n // Get settings schema from app info\n const settingsSchema = appInfo?.settingsSchema || null;\n\n // Load tenant settings\n const loadSettings = useCallback(async () => {\n if (!tenant?.id) return;\n\n try {\n setIsSettingsLoading(true);\n setSettingsError(null);\n\n const httpService = new HttpService(baseUrl);\n const tenantApi = new TenantApiService(httpService, tenant.appId);\n const tenantSettings = await tenantApi.getTenantSettings(tenant.id);\n setSettings(tenantSettings);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load tenant settings');\n setSettingsError(error);\n setSettings(null);\n } finally {\n setIsSettingsLoading(false);\n }\n }, [baseUrl, tenant]);\n\n // Update tenant settings\n const updateSettings = useCallback(\n async (newSettings: TenantSettings) => {\n if (!tenant?.id || !sessionManager) {\n throw new Error('Tenant ID and authentication required to update settings');\n }\n\n try {\n setIsSettingsLoading(true);\n setSettingsError(null);\n\n const httpService = new HttpService(baseUrl);\n const tenantApi = new TenantApiService(httpService, tenant.appId, sessionManager);\n\n const request: UpdateTenantSettingsRequest = { settings: newSettings };\n const updatedSettings = await tenantApi.updateTenantSettings(tenant.id, request);\n setSettings(updatedSettings);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update tenant settings');\n setSettingsError(error);\n throw error;\n } finally {\n setIsSettingsLoading(false);\n }\n },\n [baseUrl, tenant, sessionManager]\n );\n\n // Refresh settings\n const refreshSettings = useCallback(() => {\n loadSettings();\n }, [loadSettings]);\n\n // Validate settings against schema\n const validateSettings = useCallback(\n (settingsToValidate: TenantSettings) => {\n if (!settingsSchema) {\n return { isValid: true, errors: [] };\n }\n\n const errors: string[] = [];\n\n try {\n // If settingsSchema has properties, validate against them\n if (settingsSchema.properties) {\n Object.entries(settingsSchema.properties).forEach(([key, fieldSchema]) => {\n const value = settingsToValidate[key];\n\n // Check required fields\n if (settingsSchema.required?.includes(key) && (value === undefined || value === null)) {\n errors.push(`Field '${key}' is required`);\n return;\n }\n\n // Skip validation if value is not provided and not required\n if (value === undefined || value === null) return;\n\n // Type validation using JSONSchema\n if (fieldSchema.type) {\n const expectedType = fieldSchema.type;\n const actualType = typeof value;\n\n if (expectedType === 'string' && actualType !== 'string') {\n errors.push(`Field '${key}' must be a string`);\n } else if (\n (expectedType === 'number' || expectedType === 'integer') &&\n actualType !== 'number'\n ) {\n errors.push(`Field '${key}' must be a number`);\n } else if (expectedType === 'boolean' && actualType !== 'boolean') {\n errors.push(`Field '${key}' must be a boolean`);\n } else if (expectedType === 'array' && !Array.isArray(value)) {\n errors.push(`Field '${key}' must be an array`);\n }\n }\n\n // String length validation\n if (\n fieldSchema.minLength !== undefined &&\n typeof value === 'string' &&\n value.length < fieldSchema.minLength\n ) {\n errors.push(\n `Field '${key}' must be at least ${fieldSchema.minLength} characters long`\n );\n }\n if (\n fieldSchema.maxLength !== undefined &&\n typeof value === 'string' &&\n value.length > fieldSchema.maxLength\n ) {\n errors.push(\n `Field '${key}' must be no more than ${fieldSchema.maxLength} characters long`\n );\n }\n\n // Number range validation\n if (\n fieldSchema.minimum !== undefined &&\n typeof value === 'number' &&\n value < fieldSchema.minimum\n ) {\n errors.push(`Field '${key}' must be at least ${fieldSchema.minimum}`);\n }\n if (\n fieldSchema.maximum !== undefined &&\n typeof value === 'number' &&\n value > fieldSchema.maximum\n ) {\n errors.push(`Field '${key}' must be no more than ${fieldSchema.maximum}`);\n }\n\n // Pattern validation for strings\n if (fieldSchema.pattern && typeof value === 'string') {\n const regex = new RegExp(fieldSchema.pattern);\n if (!regex.test(value)) {\n errors.push(`Field '${key}' does not match the required pattern`);\n }\n }\n\n // Enum validation\n if (fieldSchema.enum && !fieldSchema.enum.includes(value)) {\n errors.push(`Field '${key}' must be one of: ${fieldSchema.enum.join(', ')}`);\n }\n });\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n } catch {\n return {\n isValid: false,\n errors: ['Invalid settings schema or validation error'],\n };\n }\n },\n [settingsSchema]\n );\n\n // Load settings when tenant changes\n useEffect(() => {\n if (tenant?.id) {\n loadSettings();\n } else {\n setSettings(null);\n setSettingsError(null);\n setIsSettingsLoading(false);\n }\n }, [tenant?.id, loadSettings]);\n\n const contextValue = useMemo(\n () => ({\n // Settings\n settings,\n settingsSchema,\n isSettingsLoading,\n settingsError,\n // Actions\n updateSettings,\n refreshSettings,\n // Validation\n validateSettings,\n }),\n [\n settings,\n settingsSchema,\n isSettingsLoading,\n settingsError,\n updateSettings,\n refreshSettings,\n validateSettings,\n ]\n );\n\n return <TenantContext.Provider value={contextValue}>{children}</TenantContext.Provider>;\n}\n\nexport function useTenantSettings(): TenantContextValue {\n const context = useContext(TenantContext);\n if (!context) {\n throw new Error('useTenantSettings must be used within a TenantProvider');\n }\n return context;\n}\n\n// Convenience hook for just the settings\nexport function useSettings() {\n const {\n settings,\n settingsSchema,\n isSettingsLoading,\n settingsError,\n updateSettings,\n validateSettings,\n } = useTenantSettings();\n return {\n settings,\n settingsSchema,\n isLoading: isSettingsLoading,\n error: settingsError,\n updateSettings,\n validateSettings,\n };\n}\n","// Common API Response Types\nexport interface ApiResponse<T> {\n success: boolean;\n message?: string;\n data: T;\n meta?: PaginationMeta;\n}\n\nexport interface ApiError {\n success: false;\n error: {\n code: string;\n };\n message: string;\n type?: 'AUTH' | 'VALIDATION' | 'BUSINESS' | 'SYSTEM';\n}\n\nexport interface PaginationMeta {\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n hasNext: boolean;\n hasPrev: boolean;\n}\n\n// User Types\nexport enum UserType {\n SUPERUSER = 'SUPERUSER',\n TENANT_ADMIN = 'TENANT_ADMIN',\n USER = 'USER',\n}\n\nexport interface User {\n id: string;\n email: string;\n name: string;\n isActive: boolean;\n userType: UserType;\n tenantId: string;\n roleId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateUserRequest {\n email: string;\n name: string;\n password: string;\n tenantId: string;\n userType?: string;\n roleId?: string;\n}\n\n// Auth Types\nexport interface LoginRequest {\n email: string;\n password: string;\n tenantId: string;\n}\n\nexport interface LoginResponse {\n user: User;\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\nexport interface SignupRequest {\n email: string;\n name: string;\n password: string;\n tenantId: string;\n}\n\nexport interface ChangePasswordRequest {\n currentPassword: string;\n newPassword: string;\n}\n\nexport interface RefreshTokenRequest {\n refreshToken: string;\n}\n\nexport interface RefreshTokenResponse {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n// Role Types\nexport interface Role {\n id: string;\n name: string;\n description: string | null;\n appId: string;\n permissions: string[]; // API returns permissions as strings in 'resource.action' format\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateRoleRequest {\n name: string;\n description?: string;\n appId: string;\n permissionIds: string[];\n}\n\nexport interface AssignRoleRequest {\n userId: string;\n}\n\n// Permission Types\nexport interface Permission {\n id: string;\n name: string;\n description: string | null;\n resource: string;\n action: string;\n appId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatePermissionRequest {\n name: string;\n description?: string;\n resource: string;\n action: string;\n appId?: string;\n}\n\n// App Types\nexport interface App {\n id: string;\n name: string;\n description: string | null;\n securityLevel: 'ADMIN' | 'USER';\n isActive: boolean;\n autoApproveTenants: boolean;\n defaultSubscriptionPlanId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface JSONSchema {\n $schema?: string;\n $id?: string;\n title?: string;\n description?: string;\n type?: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';\n properties?: { [key: string]: JSONSchema };\n items?: JSONSchema;\n required?: string[];\n enum?: unknown[];\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n default?: unknown;\n placeholder?: string;\n additionalProperties?: boolean | JSONSchema;\n}\n\nexport interface PublicAppInfo {\n id: string;\n name: string;\n description: string | null;\n settingsSchema: JSONSchema | null;\n}\n\nexport interface CreateAppRequest {\n name: string;\n description?: string;\n securityLevel?: 'ADMIN' | 'USER';\n}\n\n// Tenant Types\nexport interface Tenant {\n id: string;\n name: string;\n domain: string | null;\n isActive: boolean;\n appId: string;\n settings: Record<string, any>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateTenantRequest {\n name: string;\n domain?: string;\n appId: string;\n settings?: Record<string, any>;\n}\n\nexport interface PublicTenantInfo {\n id: string;\n name: string;\n domain: string | null;\n appId: string;\n}\n\nexport interface TenantSettings {\n [key: string]: any;\n}\n\nexport interface UpdateTenantSettingsRequest {\n settings: TenantSettings;\n}\n\n// Subscription Types\nexport interface Subscription {\n id: string;\n tenantId: string;\n planId: string;\n status: 'ACTIVE' | 'INACTIVE' | 'PENDING' | 'CANCELLED';\n startDate: string;\n endDate: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateSubscriptionRequest {\n tenantId: string;\n planId: string;\n startDate?: string;\n endDate?: string;\n}\n\n// Subscription Plan Types\nexport interface SubscriptionPlan {\n id: string;\n name: string;\n description: string | null;\n price: number;\n currency: string;\n billingCycle: 'MONTHLY' | 'YEARLY';\n appId: string;\n features: SubscriptionFeature[];\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SubscriptionFeature {\n id: string;\n name: string;\n description: string | null;\n featureType: 'BOOLEAN' | 'NUMERIC' | 'TEXT';\n value: any;\n planId: string;\n}\n\nexport interface CreateSubscriptionPlanRequest {\n name: string;\n description?: string;\n price: number;\n currency: string;\n billingCycle: 'MONTHLY' | 'YEARLY';\n appId: string;\n features: CreateSubscriptionFeatureRequest[];\n}\n\nexport interface CreateSubscriptionFeatureRequest {\n name: string;\n description?: string;\n featureType: 'BOOLEAN' | 'NUMERIC' | 'TEXT';\n value: any;\n}\n\n// Feature Flag Types\nexport interface FeatureFlag {\n id: string;\n name: string;\n description: string | null;\n isActive: boolean;\n appId: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateFeatureFlagRequest {\n name: string;\n description?: string;\n appId: string;\n}\n\n// Feature Flag API Response Types\nexport interface FeatureFlagItem {\n featureFlagId: string;\n key: string;\n name: string;\n value: boolean;\n isOverridden: boolean;\n}\n\nexport interface FeatureFlagValueResponse {\n key: string;\n value: boolean;\n}\n\n// Subscription Feature Types\nexport interface PlanFeature {\n key: string;\n name: string;\n type: 'BOOLEAN' | 'NUMBER' | 'STRING' | 'boolean' | 'number' | 'string';\n value: any;\n description?: string;\n}\n\nexport interface TenantSubscriptionFeatures {\n tenantId: string;\n planId: string;\n planName: string;\n subscriptionStatus: string;\n features: PlanFeature[];\n isActive: boolean;\n}\n\n// Common Query Parameters\nexport interface PaginationParams {\n page?: number;\n limit?: number;\n sortBy?: string;\n sortOrder?: 'ASC' | 'DESC';\n}\n","import { ReactNode } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { UserType, Permission } from '../types/api';\n\nexport interface ProtectedProps {\n children: ReactNode;\n fallback?: ReactNode;\n minUserType?: UserType;\n requiredPermissions?: (string | Permission)[];\n requireAllPermissions?: boolean; // If true, user must have ALL permissions. If false, user needs ANY permission\n}\n\nconst DefaultFallback = () => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '20px',\n backgroundColor: '#f8f9fa',\n border: '1px solid #dee2e6',\n borderRadius: '6px',\n textAlign: 'center',\n margin: '20px 0',\n }}\n >\n <div style={{ fontSize: '2rem', marginBottom: '10px' }}>🔒</div>\n <h3 style={{ color: '#495057', marginBottom: '10px' }}>Access Required</h3>\n <p style={{ color: '#6c757d', fontSize: '14px', marginBottom: '15px' }}>\n You need to be signed in to view this content.\n </p>\n <button\n style={{\n padding: '8px 16px',\n backgroundColor: '#007bff',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontSize: '14px',\n }}\n onClick={() => (window.location.href = '/login')}\n >\n Sign In\n </button>\n </div>\n);\n\nconst InsufficientPermissionsFallback = ({\n userType,\n minUserType,\n missingPermissions,\n}: {\n userType?: UserType;\n minUserType?: UserType;\n missingPermissions?: string[];\n}) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '20px',\n backgroundColor: '#fff3cd',\n border: '1px solid #ffeaa7',\n borderRadius: '6px',\n textAlign: 'center',\n margin: '20px 0',\n }}\n >\n <div style={{ fontSize: '2rem', marginBottom: '10px' }}>⚠️</div>\n <h3 style={{ color: '#856404', marginBottom: '10px' }}>Insufficient Permissions</h3>\n {minUserType && userType ? (\n <>\n <p style={{ color: '#856404', fontSize: '14px', marginBottom: '10px' }}>\n This content requires <strong>{minUserType}</strong> access level or higher.\n </p>\n <p style={{ color: '#6c757d', fontSize: '12px' }}>\n Your current access level: <strong>{userType}</strong>\n </p>\n </>\n ) : (\n <>\n <p style={{ color: '#856404', fontSize: '14px', marginBottom: '10px' }}>\n You don't have the required permissions to view this content.\n </p>\n {missingPermissions && missingPermissions.length > 0 && (\n <p style={{ color: '#6c757d', fontSize: '12px' }}>\n Required permissions: <strong>{missingPermissions.join(', ')}</strong>\n </p>\n )}\n </>\n )}\n </div>\n);\n\n// Helper function to check if user type meets minimum requirement\nconst hasMinimumUserType = (userType: UserType, minUserType: UserType): boolean => {\n const hierarchy = {\n [UserType.USER]: 1,\n [UserType.TENANT_ADMIN]: 2,\n [UserType.SUPERUSER]: 3,\n };\n\n return hierarchy[userType] >= hierarchy[minUserType];\n};\n\nexport function Protected({\n children,\n fallback,\n minUserType,\n requiredPermissions,\n requireAllPermissions = false,\n}: ProtectedProps) {\n const { hasValidSession, sessionManager, hasPermission, hasAnyPermission, hasAllPermissions } =\n useAuth();\n\n // Check if user has a valid session\n if (!hasValidSession()) {\n return <>{fallback || <DefaultFallback />}</>;\n }\n\n const user = sessionManager.getUser();\n\n if (!user) {\n // User session exists but no user data - show fallback\n return <>{fallback || <DefaultFallback />}</>;\n }\n\n // Check user type permissions if specified\n if (minUserType && !hasMinimumUserType(user.userType, minUserType)) {\n return <InsufficientPermissionsFallback userType={user.userType} minUserType={minUserType} />;\n }\n\n // Check specific permissions if specified\n if (requiredPermissions && requiredPermissions.length > 0) {\n const hasRequiredPermissions = requireAllPermissions\n ? hasAllPermissions(requiredPermissions)\n : hasAnyPermission(requiredPermissions);\n\n if (!hasRequiredPermissions) {\n // Get missing permissions for better error message\n const missingPermissions = requiredPermissions\n .filter(permission => !hasPermission(permission))\n .map(permission => (typeof permission === 'string' ? permission : permission.name));\n\n return <InsufficientPermissionsFallback missingPermissions={missingPermissions} />;\n }\n }\n\n // User is authenticated and has sufficient permissions\n return <>{children}</>;\n}\n","import { ReactNode } from 'react';\nimport { Navigate, useLocation } from 'react-router';\nimport { useAuth } from '../providers/AuthProvider';\nimport { UserType, Permission } from '../types/api';\n\nexport interface ProtectedRouteProps {\n children: ReactNode;\n redirectTo?: string;\n minUserType?: UserType;\n requiredPermissions?: (string | Permission)[];\n requireAllPermissions?: boolean; // If true, user must have ALL permissions. If false, user needs ANY permission\n fallback?: ReactNode;\n}\n\nconst DefaultFallback = ({ redirectPath }: { redirectPath: string }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '100vh',\n padding: '2rem',\n backgroundColor: '#f9fafb',\n textAlign: 'center',\n }}\n >\n <div\n style={{\n backgroundColor: '#ffffff',\n padding: '2rem',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n maxWidth: '400px',\n }}\n >\n <div style={{ fontSize: '3rem', marginBottom: '1rem' }}>🔒</div>\n <h2 style={{ color: '#374151', marginBottom: '1rem' }}>Access Required</h2>\n <p style={{ color: '#6b7280', marginBottom: '1.5rem' }}>\n You need to be signed in to access this page.\n </p>\n <p style={{ fontSize: '0.875rem', color: '#9ca3af' }}>Redirecting to {redirectPath}...</p>\n </div>\n </div>\n);\n\nconst InsufficientPermissionsFallback = ({\n userType,\n minUserType,\n missingPermissions,\n}: {\n userType?: UserType;\n minUserType?: UserType;\n missingPermissions?: string[];\n}) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '100vh',\n padding: '2rem',\n backgroundColor: '#f9fafb',\n textAlign: 'center',\n }}\n >\n <div\n style={{\n backgroundColor: '#ffffff',\n padding: '2rem',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n maxWidth: '400px',\n }}\n >\n <div style={{ fontSize: '3rem', marginBottom: '1rem' }}>⚠️</div>\n <h2 style={{ color: '#374151', marginBottom: '1rem' }}>Insufficient Permissions</h2>\n {minUserType && userType ? (\n <>\n <p style={{ color: '#6b7280', marginBottom: '1rem' }}>\n This page requires <strong>{minUserType}</strong> access level or higher.\n </p>\n <p style={{ color: '#9ca3af', fontSize: '0.875rem' }}>\n Your current access level: <strong>{userType}</strong>\n </p>\n </>\n ) : (\n <>\n <p style={{ color: '#6b7280', marginBottom: '1rem' }}>\n You don't have the required permissions to access this page.\n </p>\n {missingPermissions && missingPermissions.length > 0 && (\n <p style={{ color: '#9ca3af', fontSize: '0.875rem' }}>\n Required permissions: <strong>{missingPermissions.join(', ')}</strong>\n </p>\n )}\n </>\n )}\n </div>\n </div>\n);\n\n// Helper function to check if user type meets minimum requirement\nconst hasMinimumUserType = (userType: UserType, minUserType: UserType): boolean => {\n const hierarchy = {\n [UserType.USER]: 1,\n [UserType.TENANT_ADMIN]: 2,\n [UserType.SUPERUSER]: 3,\n };\n\n return hierarchy[userType] >= hierarchy[minUserType];\n};\n\nexport function ProtectedRoute({\n children,\n redirectTo = '/login',\n minUserType,\n requiredPermissions,\n requireAllPermissions = false,\n fallback,\n}: ProtectedRouteProps) {\n const { hasValidSession, sessionManager, hasPermission, hasAnyPermission, hasAllPermissions } =\n useAuth();\n const location = useLocation();\n\n // Check if user has a valid session\n if (!hasValidSession()) {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n return (\n <>\n <DefaultFallback redirectPath={redirectTo} />\n <Navigate to={redirectTo} state={{ from: location.pathname }} replace />\n </>\n );\n }\n\n const user = sessionManager.getUser();\n\n if (!user) {\n // User session exists but no user data - redirect to login\n return <Navigate to={redirectTo} state={{ from: location.pathname }} replace />;\n }\n\n // Check user type permissions if specified\n if (minUserType && !hasMinimumUserType(user.userType, minUserType)) {\n return <InsufficientPermissionsFallback userType={user.userType} minUserType={minUserType} />;\n }\n\n // Check specific permissions if specified\n if (requiredPermissions && requiredPermissions.length > 0) {\n const hasRequiredPermissions = requireAllPermissions\n ? hasAllPermissions(requiredPermissions)\n : hasAnyPermission(requiredPermissions);\n\n if (!hasRequiredPermissions) {\n // Get missing permissions for better error message\n const missingPermissions = requiredPermissions\n .filter(permission => !hasPermission(permission))\n .map(permission => (typeof permission === 'string' ? permission : permission.name));\n\n return <InsufficientPermissionsFallback missingPermissions={missingPermissions} />;\n }\n }\n\n // User is authenticated and has sufficient permissions\n return <>{children}</>;\n}\n","import { ReactNode } from 'react';\nimport { useSubscription } from '../providers/SubscriptionProvider';\n\nexport interface SubscriptionGuardProps {\n children: ReactNode;\n fallback?: ReactNode;\n allowedPlans?: string[];\n requiredFeature?: string;\n}\n\nconst DefaultFallback = () => (\n <div\n style={{\n padding: '2rem',\n textAlign: 'center',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '8px',\n color: '#dc2626',\n }}\n >\n <h3 style={{ margin: '0 0 1rem 0' }}>🔒 Subscription Required</h3>\n <p style={{ margin: 0 }}>\n This feature requires a higher subscription plan. Please upgrade your plan to access this\n content.\n </p>\n </div>\n);\n\nexport function SubscriptionGuard({\n children,\n fallback = <DefaultFallback />,\n allowedPlans,\n requiredFeature,\n}: SubscriptionGuardProps) {\n const { subscription, hasAllowedPlan, isFeatureEnabled, loading } = useSubscription();\n\n // Show loading state\n if (loading) {\n return (\n <div\n style={{\n padding: '2rem',\n textAlign: 'center',\n color: '#6b7280',\n }}\n >\n Loading subscription...\n </div>\n );\n }\n\n // No subscription data available\n if (!subscription) {\n return <>{fallback}</>;\n }\n\n // Check if subscription is active\n if (!subscription.isActive) {\n return <>{fallback}</>;\n }\n\n // Check allowed plans requirement\n if (allowedPlans && allowedPlans.length > 0 && !hasAllowedPlan(allowedPlans)) {\n return <>{fallback}</>;\n }\n\n // Check required feature\n if (requiredFeature && !isFeatureEnabled(requiredFeature)) {\n return <>{fallback}</>;\n }\n\n // All checks passed, render children\n return <>{children}</>;\n}\n","import { ReactNode } from 'react';\nimport { useFeatureFlags } from '../providers/FeatureFlagProvider';\n\ninterface FeatureFlagProps {\n name: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\nconst DefaultFallback = ({ flagName }: { flagName: string }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '15px',\n backgroundColor: '#f8f9fa',\n border: '1px solid #dee2e6',\n borderRadius: '6px',\n textAlign: 'center',\n fontFamily: 'system-ui, sans-serif',\n color: '#6c757d',\n }}\n >\n <div style={{ fontSize: '24px', marginBottom: '8px' }}>🚧</div>\n <div style={{ fontSize: '14px', fontWeight: '500', marginBottom: '4px' }}>\n Feature Not Available\n </div>\n <div style={{ fontSize: '12px', opacity: 0.7 }}>Feature flag \"{flagName}\" is disabled</div>\n </div>\n);\n\nexport function FeatureFlag({ name, children, fallback }: FeatureFlagProps) {\n const { isEnabled, loading } = useFeatureFlags();\n\n // Show loading state while fetching feature flags\n if (loading) {\n return (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '10px',\n color: '#6c757d',\n fontSize: '14px',\n }}\n >\n Loading feature flags...\n </div>\n );\n }\n\n console.log(name, isEnabled(name));\n // Show children if feature flag is enabled\n if (isEnabled(name)) {\n return <>{children}</>;\n }\n\n // Show fallback if provided, otherwise show default fallback\n return <>{fallback || <DefaultFallback flagName={name} />}</>;\n}\n","import React, { useState } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { useApp } from '../providers/AppProvider';\n\nexport interface LoginFormCopy {\n title?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n passwordLabel?: string;\n passwordPlaceholder?: string;\n submitButton?: string;\n forgotPasswordLink?: string;\n signupLink?: string;\n signupText?: string;\n errorMessage?: string;\n loadingText?: string;\n}\n\nexport interface LoginFormStyles {\n container?: React.CSSProperties;\n title?: React.CSSProperties;\n form?: React.CSSProperties;\n fieldGroup?: React.CSSProperties;\n label?: React.CSSProperties;\n input?: React.CSSProperties;\n inputError?: React.CSSProperties;\n inputContainer?: React.CSSProperties;\n passwordToggle?: React.CSSProperties;\n button?: React.CSSProperties;\n buttonDisabled?: React.CSSProperties;\n buttonLoading?: React.CSSProperties;\n errorText?: React.CSSProperties;\n linkContainer?: React.CSSProperties;\n link?: React.CSSProperties;\n divider?: React.CSSProperties;\n}\n\nexport interface LoginFormIcons {\n showPassword?: React.ReactNode;\n hidePassword?: React.ReactNode;\n}\n\nexport interface LoginFormProps {\n copy?: LoginFormCopy;\n styles?: LoginFormStyles;\n icons?: LoginFormIcons;\n onSuccess?: (data: any) => void;\n onError?: (error: string) => void;\n onForgotPassword?: () => void;\n onSignupClick?: () => void;\n showForgotPassword?: boolean;\n showSignupLink?: boolean;\n className?: string;\n}\n\n// Default SVG icons for password toggle\nconst EyeIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ flexShrink: 0 }}\n >\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n);\n\nconst EyeOffIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ flexShrink: 0 }}\n >\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\" />\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n </svg>\n);\n\nconst defaultIcons: Required<LoginFormIcons> = {\n showPassword: <EyeIcon />,\n hidePassword: <EyeOffIcon />,\n};\n\nconst defaultCopy: Required<LoginFormCopy> = {\n title: 'Sign In',\n emailLabel: 'Email',\n emailPlaceholder: 'Enter your email',\n passwordLabel: 'Password',\n passwordPlaceholder: 'Enter your password',\n submitButton: 'Sign In',\n forgotPasswordLink: 'Forgot your password?',\n signupLink: 'Sign up here',\n signupText: \"Don't have an account?\",\n errorMessage: 'Invalid email or password',\n loadingText: 'Signing in...',\n};\n\nconst defaultStyles: Required<LoginFormStyles> = {\n container: {\n maxWidth: '400px',\n width: '100%',\n margin: '0 auto',\n padding: '2rem',\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 'bold',\n textAlign: 'center',\n marginBottom: '1.5rem',\n color: '#333333',\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n },\n fieldGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.75rem',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n fontSize: '1rem',\n transition: 'border-color 0.15s ease-in-out',\n outline: 'none',\n width: '100%',\n },\n inputError: {\n borderColor: '#ef4444',\n boxShadow: '0 0 0 3px rgba(239, 68, 68, 0.1)',\n },\n inputContainer: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n },\n passwordToggle: {\n position: 'absolute',\n right: '0.75rem',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '0.25rem',\n color: '#6b7280',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n borderRadius: '4px',\n transition: 'background-color 0.15s ease-in-out',\n },\n button: {\n padding: '0.75rem 1rem',\n backgroundColor: '#3b82f6',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n fontSize: '1rem',\n fontWeight: '500',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n marginTop: '0.5rem',\n },\n buttonDisabled: {\n backgroundColor: '#9ca3af',\n cursor: 'not-allowed',\n },\n buttonLoading: {\n backgroundColor: '#6b7280',\n },\n errorText: {\n color: '#ef4444',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n linkContainer: {\n textAlign: 'center',\n marginTop: '1rem',\n },\n link: {\n color: '#3b82f6',\n textDecoration: 'none',\n fontSize: '0.875rem',\n cursor: 'pointer',\n },\n divider: {\n margin: '0.5rem 0',\n color: '#6b7280',\n fontSize: '0.875rem',\n },\n};\n\nexport function LoginForm({\n copy = {},\n styles = {},\n icons = {},\n onSuccess,\n onError,\n onForgotPassword,\n onSignupClick,\n showForgotPassword = true,\n showSignupLink = true,\n className,\n}: LoginFormProps) {\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [showPassword, setShowPassword] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [fieldErrors, setFieldErrors] = useState<{ email?: boolean; password?: boolean }>({});\n\n const { login } = useAuth();\n const { tenant } = useApp();\n\n const mergedCopy = { ...defaultCopy, ...copy };\n const mergedStyles = { ...defaultStyles, ...styles };\n const mergedIcons = { ...defaultIcons, ...icons };\n\n const validateForm = () => {\n const errors: { email?: boolean; password?: boolean } = {};\n\n if (!email.trim()) errors.email = true;\n if (!password.trim()) errors.password = true;\n\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateForm()) return;\n if (!tenant?.id) {\n setError('Tenant not found');\n return;\n }\n\n setLoading(true);\n setError('');\n\n try {\n const result = await login(email, password, tenant.id);\n onSuccess?.(result);\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const getInputStyle = (field: 'email' | 'password') => ({\n ...mergedStyles.input,\n ...(fieldErrors[field] ? mergedStyles.inputError : {}),\n });\n\n const getButtonStyle = () => ({\n ...mergedStyles.button,\n ...(loading ? mergedStyles.buttonLoading : {}),\n ...(!email || !password || loading ? mergedStyles.buttonDisabled : {}),\n });\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.title}</h2>\n\n <form onSubmit={handleSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.emailLabel}</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={e => {\n setEmail(e.target.value);\n if (fieldErrors.email) {\n setFieldErrors(prev => ({ ...prev, email: false }));\n }\n }}\n placeholder={mergedCopy.emailPlaceholder}\n style={getInputStyle('email')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.passwordLabel}</label>\n <div style={mergedStyles.inputContainer}>\n <input\n id=\"password\"\n name=\"password\"\n type={showPassword ? 'text' : 'password'}\n value={password}\n onChange={e => {\n setPassword(e.target.value);\n if (fieldErrors.password) {\n setFieldErrors(prev => ({ ...prev, password: false }));\n }\n }}\n placeholder={mergedCopy.passwordPlaceholder}\n style={{\n ...getInputStyle('password'),\n paddingRight: '2.5rem', // Make room for the icon\n }}\n disabled={loading}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n style={mergedStyles.passwordToggle}\n disabled={loading}\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n >\n {showPassword ? mergedIcons.hidePassword : mergedIcons.showPassword}\n </button>\n </div>\n </div>\n\n <button type=\"submit\" disabled={!email || !password || loading} style={getButtonStyle()}>\n {loading ? mergedCopy.loadingText : mergedCopy.submitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n </form>\n\n {(showForgotPassword || showSignupLink) && (\n <div style={mergedStyles.linkContainer}>\n {showForgotPassword && (\n <a onClick={onForgotPassword} style={mergedStyles.link}>\n {mergedCopy.forgotPasswordLink}\n </a>\n )}\n\n {showForgotPassword && showSignupLink && <div style={mergedStyles.divider}>•</div>}\n\n {showSignupLink && (\n <div>\n <span style={mergedStyles.divider}>{mergedCopy.signupText} </span>\n <a onClick={onSignupClick} style={mergedStyles.link}>\n {mergedCopy.signupLink}\n </a>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { useApp } from '../providers/AppProvider';\n\nexport interface SignupFormCopy {\n title?: string;\n nameLabel?: string;\n namePlaceholder?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n passwordLabel?: string;\n passwordPlaceholder?: string;\n confirmPasswordLabel?: string;\n confirmPasswordPlaceholder?: string;\n tenantNameLabel?: string;\n tenantNamePlaceholder?: string;\n submitButton?: string;\n loginLink?: string;\n loginText?: string;\n errorMessage?: string;\n loadingText?: string;\n passwordMismatchError?: string;\n isAdminLabel?: string;\n isAdminDescription?: string;\n}\n\nexport interface SignupFormStyles {\n container?: React.CSSProperties;\n title?: React.CSSProperties;\n form?: React.CSSProperties;\n fieldGroup?: React.CSSProperties;\n label?: React.CSSProperties;\n input?: React.CSSProperties;\n inputError?: React.CSSProperties;\n checkbox?: React.CSSProperties;\n checkboxContainer?: React.CSSProperties;\n checkboxLabel?: React.CSSProperties;\n button?: React.CSSProperties;\n buttonDisabled?: React.CSSProperties;\n buttonLoading?: React.CSSProperties;\n errorText?: React.CSSProperties;\n linkContainer?: React.CSSProperties;\n link?: React.CSSProperties;\n divider?: React.CSSProperties;\n}\n\nexport type SignupType = 'user' | 'tenant';\n\nexport interface SignupFormProps {\n copy?: SignupFormCopy;\n styles?: SignupFormStyles;\n signupType?: SignupType;\n onSuccess?: (data: any) => void;\n onError?: (error: string) => void;\n onLoginClick?: () => void;\n showLoginLink?: boolean;\n className?: string;\n}\n\nconst defaultCopy: Required<SignupFormCopy> = {\n title: 'Create Account',\n nameLabel: 'Full Name',\n namePlaceholder: 'Enter your full name',\n emailLabel: 'Email',\n emailPlaceholder: 'Enter your email',\n passwordLabel: 'Password',\n passwordPlaceholder: 'Enter your password',\n confirmPasswordLabel: 'Confirm Password',\n confirmPasswordPlaceholder: 'Confirm your password',\n tenantNameLabel: 'Organization Name',\n tenantNamePlaceholder: 'Enter your organization name',\n submitButton: 'Create Account',\n loginLink: 'Sign in here',\n loginText: 'Already have an account?',\n errorMessage: 'Failed to create account',\n loadingText: 'Creating account...',\n passwordMismatchError: 'Passwords do not match',\n isAdminLabel: 'Create new organization',\n isAdminDescription: 'Check this if you want to create a new organization',\n};\n\nconst defaultStyles: Required<SignupFormStyles> = {\n container: {\n maxWidth: '400px',\n width: '100%',\n margin: '0 auto',\n padding: '2rem',\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 'bold',\n textAlign: 'center',\n marginBottom: '1.5rem',\n color: '#333333',\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n },\n fieldGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.75rem',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n fontSize: '1rem',\n transition: 'border-color 0.15s ease-in-out',\n outline: 'none',\n },\n inputError: {\n borderColor: '#ef4444',\n boxShadow: '0 0 0 3px rgba(239, 68, 68, 0.1)',\n },\n checkbox: {\n marginRight: '0.5rem',\n },\n checkboxContainer: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '0.5rem',\n padding: '0.5rem 0',\n },\n checkboxLabel: {\n fontSize: '0.875rem',\n color: '#374151',\n lineHeight: '1.4',\n },\n button: {\n padding: '0.75rem 1rem',\n backgroundColor: '#10b981',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n fontSize: '1rem',\n fontWeight: '500',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n marginTop: '0.5rem',\n },\n buttonDisabled: {\n backgroundColor: '#9ca3af',\n cursor: 'not-allowed',\n },\n buttonLoading: {\n backgroundColor: '#6b7280',\n },\n errorText: {\n color: '#ef4444',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n linkContainer: {\n textAlign: 'center',\n marginTop: '1rem',\n },\n link: {\n color: '#3b82f6',\n textDecoration: 'none',\n fontSize: '0.875rem',\n cursor: 'pointer',\n },\n divider: {\n margin: '0.5rem 0',\n color: '#6b7280',\n fontSize: '0.875rem',\n },\n};\n\nexport function SignupForm({\n copy = {},\n styles = {},\n signupType = 'user',\n onSuccess,\n onError,\n onLoginClick,\n showLoginLink = true,\n className,\n}: SignupFormProps) {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [tenantName, setTenantName] = useState('');\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [fieldErrors, setFieldErrors] = useState<{\n name?: boolean;\n email?: boolean;\n password?: boolean;\n confirmPassword?: boolean;\n tenantName?: boolean;\n }>({});\n\n const { signup, signupTenantAdmin } = useAuth();\n const { tenant } = useApp();\n\n const mergedCopy = { ...defaultCopy, ...copy };\n const mergedStyles = { ...defaultStyles, ...styles };\n\n const validateForm = () => {\n const errors: {\n name?: boolean;\n email?: boolean;\n password?: boolean;\n confirmPassword?: boolean;\n tenantName?: boolean;\n } = {};\n\n if (!name.trim()) errors.name = true;\n if (!email.trim()) errors.email = true;\n if (!password.trim()) errors.password = true;\n if (!confirmPassword.trim()) errors.confirmPassword = true;\n if (signupType === 'tenant' && !tenantName.trim()) errors.tenantName = true;\n\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateForm()) return;\n\n if (password !== confirmPassword) {\n setError(mergedCopy.passwordMismatchError);\n setFieldErrors({ confirmPassword: true });\n return;\n }\n\n if (signupType === 'user' && !tenant?.id) {\n setError('Tenant not found');\n return;\n }\n\n setLoading(true);\n setError('');\n\n try {\n let result;\n if (signupType === 'tenant') {\n result = await signupTenantAdmin(email, name, password, tenantName);\n } else {\n result = await signup(email, name, password, tenant!.id);\n }\n onSuccess?.(result);\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const getInputStyle = (field: keyof typeof fieldErrors) => ({\n ...mergedStyles.input,\n ...(fieldErrors[field] ? mergedStyles.inputError : {}),\n });\n\n const getButtonStyle = () => ({\n ...mergedStyles.button,\n ...(loading ? mergedStyles.buttonLoading : {}),\n ...(!name ||\n !email ||\n !password ||\n !confirmPassword ||\n loading ||\n (signupType === 'tenant' && !tenantName)\n ? mergedStyles.buttonDisabled\n : {}),\n });\n\n const isFormValid =\n name && email && password && confirmPassword && (signupType === 'user' || tenantName);\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.title}</h2>\n\n <form onSubmit={handleSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.nameLabel}</label>\n <input\n id=\"name\"\n name=\"name\"\n type=\"text\"\n value={name}\n onChange={e => {\n setName(e.target.value);\n if (fieldErrors.name) {\n setFieldErrors(prev => ({ ...prev, name: false }));\n }\n }}\n placeholder={mergedCopy.namePlaceholder}\n style={getInputStyle('name')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.emailLabel}</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={e => {\n setEmail(e.target.value);\n if (fieldErrors.email) {\n setFieldErrors(prev => ({ ...prev, email: false }));\n }\n }}\n placeholder={mergedCopy.emailPlaceholder}\n style={getInputStyle('email')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.passwordLabel}</label>\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n value={password}\n onChange={e => {\n setPassword(e.target.value);\n if (fieldErrors.password) {\n setFieldErrors(prev => ({ ...prev, password: false }));\n }\n }}\n placeholder={mergedCopy.passwordPlaceholder}\n style={getInputStyle('password')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.confirmPasswordLabel}</label>\n <input\n id=\"confirmPassword\"\n name=\"confirmPassword\"\n type=\"password\"\n value={confirmPassword}\n onChange={e => {\n setConfirmPassword(e.target.value);\n if (fieldErrors.confirmPassword) {\n setFieldErrors(prev => ({ ...prev, confirmPassword: false }));\n }\n if (error === mergedCopy.passwordMismatchError) {\n setError('');\n }\n }}\n placeholder={mergedCopy.confirmPasswordPlaceholder}\n style={getInputStyle('confirmPassword')}\n disabled={loading}\n />\n </div>\n\n {signupType === 'tenant' && (\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.tenantNameLabel}</label>\n <input\n id=\"tenantName\"\n name=\"tenantName\"\n type=\"text\"\n value={tenantName}\n onChange={e => {\n setTenantName(e.target.value);\n if (fieldErrors.tenantName) {\n setFieldErrors(prev => ({ ...prev, tenantName: false }));\n }\n }}\n placeholder={mergedCopy.tenantNamePlaceholder}\n style={getInputStyle('tenantName')}\n disabled={loading}\n />\n </div>\n )}\n\n <button type=\"submit\" disabled={!isFormValid || loading} style={getButtonStyle()}>\n {loading ? mergedCopy.loadingText : mergedCopy.submitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n </form>\n\n {showLoginLink && (\n <div style={mergedStyles.linkContainer}>\n <span style={mergedStyles.divider}>{mergedCopy.loginText} </span>\n <a onClick={onLoginClick} style={mergedStyles.link}>\n {mergedCopy.loginLink}\n </a>\n </div>\n )}\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { useApp } from '../providers/AppProvider';\n\nexport interface PasswordRecoveryFormCopy {\n title?: string;\n subtitle?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n submitButton?: string;\n backToLoginLink?: string;\n successMessage?: string;\n errorMessage?: string;\n loadingText?: string;\n // Reset form copy\n resetTitle?: string;\n resetSubtitle?: string;\n tokenLabel?: string;\n tokenPlaceholder?: string;\n newPasswordLabel?: string;\n newPasswordPlaceholder?: string;\n confirmPasswordLabel?: string;\n confirmPasswordPlaceholder?: string;\n resetSubmitButton?: string;\n resetLoadingText?: string;\n resetSuccessMessage?: string;\n passwordMismatchError?: string;\n}\n\nexport interface PasswordRecoveryFormStyles {\n container?: React.CSSProperties;\n title?: React.CSSProperties;\n subtitle?: React.CSSProperties;\n form?: React.CSSProperties;\n fieldGroup?: React.CSSProperties;\n label?: React.CSSProperties;\n input?: React.CSSProperties;\n inputError?: React.CSSProperties;\n button?: React.CSSProperties;\n buttonDisabled?: React.CSSProperties;\n buttonLoading?: React.CSSProperties;\n errorText?: React.CSSProperties;\n successText?: React.CSSProperties;\n linkContainer?: React.CSSProperties;\n link?: React.CSSProperties;\n}\n\nexport interface PasswordRecoveryFormProps {\n copy?: PasswordRecoveryFormCopy;\n styles?: PasswordRecoveryFormStyles;\n mode?: 'request' | 'reset';\n token?: string;\n onSuccess?: (data?: any) => void;\n onError?: (error: string) => void;\n onBackToLogin?: () => void;\n onModeChange?: (mode: 'request' | 'reset') => void;\n className?: string;\n}\n\nconst defaultCopy: Required<PasswordRecoveryFormCopy> = {\n title: 'Reset Password',\n subtitle: \"Enter your email address and we'll send you a link to reset your password.\",\n emailLabel: 'Email',\n emailPlaceholder: 'Enter your email',\n submitButton: 'Send Reset Link',\n backToLoginLink: 'Back to Sign In',\n successMessage: 'Password reset link sent! Check your email.',\n errorMessage: 'Failed to send reset link',\n loadingText: 'Sending...',\n resetTitle: 'Set New Password',\n resetSubtitle: 'Enter your reset token and new password.',\n tokenLabel: 'Reset Token',\n tokenPlaceholder: 'Enter reset token from email',\n newPasswordLabel: 'New Password',\n newPasswordPlaceholder: 'Enter new password',\n confirmPasswordLabel: 'Confirm Password',\n confirmPasswordPlaceholder: 'Confirm new password',\n resetSubmitButton: 'Reset Password',\n resetLoadingText: 'Resetting...',\n resetSuccessMessage: 'Password reset successfully!',\n passwordMismatchError: 'Passwords do not match',\n};\n\nconst defaultStyles: Required<PasswordRecoveryFormStyles> = {\n container: {\n maxWidth: '400px',\n margin: '0 auto',\n padding: '2rem',\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 'bold',\n textAlign: 'center',\n marginBottom: '0.5rem',\n color: '#333333',\n },\n subtitle: {\n fontSize: '0.875rem',\n textAlign: 'center',\n marginBottom: '1.5rem',\n color: '#6b7280',\n lineHeight: '1.4',\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n },\n fieldGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.75rem',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n fontSize: '1rem',\n transition: 'border-color 0.15s ease-in-out',\n outline: 'none',\n },\n inputError: {\n borderColor: '#ef4444',\n boxShadow: '0 0 0 3px rgba(239, 68, 68, 0.1)',\n },\n button: {\n padding: '0.75rem 1rem',\n backgroundColor: '#f59e0b',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n fontSize: '1rem',\n fontWeight: '500',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n marginTop: '0.5rem',\n },\n buttonDisabled: {\n backgroundColor: '#9ca3af',\n cursor: 'not-allowed',\n },\n buttonLoading: {\n backgroundColor: '#6b7280',\n },\n errorText: {\n color: '#ef4444',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n successText: {\n color: '#10b981',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n linkContainer: {\n textAlign: 'center',\n marginTop: '1rem',\n },\n link: {\n color: '#3b82f6',\n textDecoration: 'none',\n fontSize: '0.875rem',\n cursor: 'pointer',\n },\n};\n\nexport function PasswordRecoveryForm({\n copy = {},\n styles = {},\n mode = 'request',\n token: initialToken = '',\n onSuccess,\n onError,\n onBackToLogin,\n onModeChange,\n className,\n}: PasswordRecoveryFormProps) {\n const [email, setEmail] = useState('');\n const [token, setToken] = useState(initialToken);\n const [newPassword, setNewPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [success, setSuccess] = useState('');\n const [fieldErrors, setFieldErrors] = useState<{\n email?: boolean;\n token?: boolean;\n newPassword?: boolean;\n confirmPassword?: boolean;\n }>({});\n\n const { requestPasswordReset, confirmPasswordReset } = useAuth();\n const { tenant } = useApp();\n\n const mergedCopy = { ...defaultCopy, ...copy };\n const mergedStyles = { ...defaultStyles, ...styles };\n\n const validateRequestForm = () => {\n const errors: { email?: boolean } = {};\n if (!email.trim()) errors.email = true;\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const validateResetForm = () => {\n const errors: { token?: boolean; newPassword?: boolean; confirmPassword?: boolean } = {};\n if (!token.trim()) errors.token = true;\n if (!newPassword.trim()) errors.newPassword = true;\n if (!confirmPassword.trim()) errors.confirmPassword = true;\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const handleRequestSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateRequestForm()) return;\n if (!tenant?.id) {\n setError('Tenant not found');\n return;\n }\n\n setLoading(true);\n setError('');\n setSuccess('');\n\n try {\n await requestPasswordReset(email, tenant.id);\n setSuccess(mergedCopy.successMessage);\n onSuccess?.();\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const handleResetSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateResetForm()) return;\n\n if (newPassword !== confirmPassword) {\n setError(mergedCopy.passwordMismatchError);\n setFieldErrors({ confirmPassword: true });\n return;\n }\n\n setLoading(true);\n setError('');\n setSuccess('');\n\n try {\n await confirmPasswordReset(token, newPassword);\n setSuccess(mergedCopy.resetSuccessMessage);\n onSuccess?.();\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const getInputStyle = (field: keyof typeof fieldErrors) => ({\n ...mergedStyles.input,\n ...(fieldErrors[field] ? mergedStyles.inputError : {}),\n });\n\n const getButtonStyle = () => ({\n ...mergedStyles.button,\n ...(loading ? mergedStyles.buttonLoading : {}),\n });\n\n if (mode === 'reset') {\n const isFormValid = token && newPassword && confirmPassword;\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.resetTitle}</h2>\n <p style={mergedStyles.subtitle}>{mergedCopy.resetSubtitle}</p>\n\n <form onSubmit={handleResetSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.tokenLabel}</label>\n <input\n type=\"text\"\n value={token}\n onChange={e => {\n setToken(e.target.value);\n if (fieldErrors.token) {\n setFieldErrors(prev => ({ ...prev, token: false }));\n }\n }}\n placeholder={mergedCopy.tokenPlaceholder}\n style={getInputStyle('token')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.newPasswordLabel}</label>\n <input\n type=\"password\"\n value={newPassword}\n onChange={e => {\n setNewPassword(e.target.value);\n if (fieldErrors.newPassword) {\n setFieldErrors(prev => ({ ...prev, newPassword: false }));\n }\n }}\n placeholder={mergedCopy.newPasswordPlaceholder}\n style={getInputStyle('newPassword')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.confirmPasswordLabel}</label>\n <input\n type=\"password\"\n value={confirmPassword}\n onChange={e => {\n setConfirmPassword(e.target.value);\n if (fieldErrors.confirmPassword) {\n setFieldErrors(prev => ({ ...prev, confirmPassword: false }));\n }\n if (error === mergedCopy.passwordMismatchError) {\n setError('');\n }\n }}\n placeholder={mergedCopy.confirmPasswordPlaceholder}\n style={getInputStyle('confirmPassword')}\n disabled={loading}\n />\n </div>\n\n <button\n type=\"submit\"\n disabled={!isFormValid || loading}\n style={{\n ...getButtonStyle(),\n ...(!isFormValid || loading ? mergedStyles.buttonDisabled : {}),\n }}\n >\n {loading ? mergedCopy.resetLoadingText : mergedCopy.resetSubmitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n {success && <div style={mergedStyles.successText}>{success}</div>}\n </form>\n\n <div style={mergedStyles.linkContainer}>\n <a onClick={onBackToLogin} style={mergedStyles.link}>\n {mergedCopy.backToLoginLink}\n </a>\n {onModeChange && (\n <>\n <span style={{ margin: '0 0.5rem', color: '#6b7280' }}>•</span>\n <a onClick={() => onModeChange('request')} style={mergedStyles.link}>\n Request New Link\n </a>\n </>\n )}\n </div>\n </div>\n );\n }\n\n // Request mode\n const isFormValid = email;\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.title}</h2>\n <p style={mergedStyles.subtitle}>{mergedCopy.subtitle}</p>\n\n <form onSubmit={handleRequestSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.emailLabel}</label>\n <input\n type=\"email\"\n value={email}\n onChange={e => {\n setEmail(e.target.value);\n if (fieldErrors.email) {\n setFieldErrors(prev => ({ ...prev, email: false }));\n }\n }}\n placeholder={mergedCopy.emailPlaceholder}\n style={getInputStyle('email')}\n disabled={loading}\n />\n </div>\n\n <button\n type=\"submit\"\n disabled={!isFormValid || loading}\n style={{\n ...getButtonStyle(),\n ...(!isFormValid || loading ? mergedStyles.buttonDisabled : {}),\n }}\n >\n {loading ? mergedCopy.loadingText : mergedCopy.submitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n {success && <div style={mergedStyles.successText}>{success}</div>}\n </form>\n\n <div style={mergedStyles.linkContainer}>\n <a onClick={onBackToLogin} style={mergedStyles.link}>\n {mergedCopy.backToLoginLink}\n </a>\n {onModeChange && (\n <>\n <span style={{ margin: '0 0.5rem', color: '#6b7280' }}>•</span>\n <a onClick={() => onModeChange('reset')} style={mergedStyles.link}>\n I have a token\n </a>\n </>\n )}\n </div>\n </div>\n );\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Permission,\n CreatePermissionRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class PermissionApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createPermission(request: CreatePermissionRequest): Promise<Permission> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Permission>>(\n '/permissions/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getPermissions(\n params?: PaginationParams\n ): Promise<{ permissions: Permission[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/permissions/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Permission[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n permissions: response.data,\n meta: response.meta,\n };\n }\n\n async getPermissionById(id: string): Promise<Permission> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Permission>>(`/permissions/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updatePermission(\n id: string,\n request: Partial<CreatePermissionRequest>\n ): Promise<Permission> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Permission>>(\n `/permissions/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async deletePermission(id: string): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/permissions/${id}`, {\n headers: authHeaders,\n });\n }\n\n // Public endpoint - no auth required\n async getAppPermissions(\n appId: string,\n params?: PaginationParams\n ): Promise<{ permissions: Permission[]; meta: any }> {\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/permissions/apps/${appId}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Permission[]>>(url);\n\n return {\n permissions: response.data,\n meta: response.meta,\n };\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n SubscriptionPlan,\n CreateSubscriptionPlanRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class SubscriptionPlanApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager: SessionManager\n ) {}\n\n async createSubscriptionPlan(request: CreateSubscriptionPlanRequest): Promise<SubscriptionPlan> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<SubscriptionPlan>>(\n '/subscription-plans/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getSubscriptionPlans(\n params?: PaginationParams & { appId?: string }\n ): Promise<{ plans: SubscriptionPlan[]; meta: any }> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n if (params?.appId) queryParams.append('appId', params.appId);\n\n const url = `/subscription-plans/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<SubscriptionPlan[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n plans: response.data,\n meta: response.meta,\n };\n }\n\n async getSubscriptionPlanById(id: string): Promise<SubscriptionPlan> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<SubscriptionPlan>>(\n `/subscription-plans/${id}`,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async updateSubscriptionPlan(\n id: string,\n request: Partial<CreateSubscriptionPlanRequest>\n ): Promise<SubscriptionPlan> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<SubscriptionPlan>>(\n `/subscription-plans/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async deleteSubscriptionPlan(id: string): Promise<void> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/subscription-plans/${id}`, {\n headers: authHeaders,\n });\n }\n}\n","import { HttpService } from './HttpService';\n\nexport class HealthApiService {\n constructor(private httpService: HttpService) {}\n\n // Public endpoint - no auth required\n async checkHealth(): Promise<{ status: string }> {\n return await this.httpService.get<{ status: string }>('/health');\n }\n}\n","// Data transformation utilities for API responses\n\nexport class ApiMappers {\n // Date string to Date object\n static toDate(dateString: string): Date {\n return new Date(dateString);\n }\n\n // Date object to ISO string\n static toISOString(date: Date): string {\n return date.toISOString();\n }\n\n // Transform API response pagination meta\n static transformPaginationMeta(meta: any) {\n return {\n total: meta.total || 0,\n page: meta.page || 1,\n limit: meta.limit || 100,\n totalPages: meta.totalPages || 1,\n hasNext: meta.hasNext || false,\n hasPrev: meta.hasPrev || false,\n };\n }\n\n // Transform user data for display\n static transformUser(user: any) {\n return {\n ...user,\n createdAt: this.toDate(user.createdAt),\n updatedAt: this.toDate(user.updatedAt),\n displayName: user.name,\n isActiveUser: user.isActive,\n };\n }\n\n // Transform role data for display\n static transformRole(role: any) {\n return {\n ...role,\n createdAt: this.toDate(role.createdAt),\n updatedAt: this.toDate(role.updatedAt),\n permissionCount: role.permissions?.length || 0,\n };\n }\n\n // Transform tenant data for display\n static transformTenant(tenant: any) {\n return {\n ...tenant,\n createdAt: this.toDate(tenant.createdAt),\n updatedAt: this.toDate(tenant.updatedAt),\n displayName: tenant.name,\n hasCustomDomain: !!tenant.domain,\n };\n }\n\n // Transform subscription data for display\n static transformSubscription(subscription: any) {\n return {\n ...subscription,\n createdAt: this.toDate(subscription.createdAt),\n updatedAt: this.toDate(subscription.updatedAt),\n startDate: this.toDate(subscription.startDate),\n endDate: subscription.endDate ? this.toDate(subscription.endDate) : null,\n isActive: subscription.status === 'ACTIVE',\n isExpired: subscription.endDate ? new Date(subscription.endDate) < new Date() : false,\n };\n }\n\n // Transform app data for display\n static transformApp(app: any) {\n return {\n ...app,\n createdAt: this.toDate(app.createdAt),\n updatedAt: this.toDate(app.updatedAt),\n isAdminLevel: app.securityLevel === 'ADMIN',\n hasDefaultPlan: !!app.defaultSubscriptionPlanId,\n };\n }\n\n // Transform feature flag data for display\n static transformFeatureFlag(featureFlag: any) {\n return {\n ...featureFlag,\n createdAt: this.toDate(featureFlag.createdAt),\n updatedAt: this.toDate(featureFlag.updatedAt),\n isEnabled: featureFlag.isActive,\n };\n }\n\n // Transform permission data for display\n static transformPermission(permission: any) {\n return {\n ...permission,\n createdAt: this.toDate(permission.createdAt),\n updatedAt: this.toDate(permission.updatedAt),\n fullName: `${permission.resource}:${permission.action}`,\n isSystemLevel: !permission.appId,\n };\n }\n\n // Transform subscription plan data for display\n static transformSubscriptionPlan(plan: any) {\n return {\n ...plan,\n createdAt: this.toDate(plan.createdAt),\n updatedAt: this.toDate(plan.updatedAt),\n displayPrice: `${plan.currency} ${plan.price}`,\n isMonthly: plan.billingCycle === 'MONTHLY',\n featureCount: plan.features?.length || 0,\n };\n }\n\n // Transform error response\n static transformError(error: any) {\n return {\n code: error.error?.code || 'UNKNOWN_ERROR',\n message: error.message || 'An unexpected error occurred',\n type: error.type || 'SYSTEM',\n isAuthError: error.type === 'AUTH',\n isValidationError: error.type === 'VALIDATION',\n };\n }\n\n // Transform query parameters for API calls\n static transformQueryParams(params: any): URLSearchParams {\n const searchParams = new URLSearchParams();\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== '') {\n searchParams.append(key, String(value));\n }\n });\n\n return searchParams;\n }\n}\n"],"names":["HttpService","baseUrl","timeout","sessionManager","method","endpoint","data","options","isRetry","url","requestTimeout","requestHeaders","authHeaders","error","controller","timeoutId","response","tokens","contentType","TenantApiService","httpService","appId","request","params","queryParams","id","slug","AppApiService","planId","schema","defaultSettings","AppContext","createContext","DefaultLoadingFallback","jsx","DefaultErrorFallback","retry","jsxs","AppProvider","config","children","tenant","setTenant","useState","isTenantLoading","setIsTenantLoading","tenantError","setTenantError","appInfo","setAppInfo","isAppLoading","setIsAppLoading","appError","setAppError","detectTenantSlug","useCallback","tenantMode","storageKey","parts","subdomain","urlTenant","tenantSlug","useMemo","contextValue","retryTenant","loadTenant","retryApp","loadApp","appData","err","tenantInfo","useEffect","mode","Fragment","ErrorComponent","useApp","context","useContext","useApi","useTenant","SessionManager","stored","tokenData","token","resolve","reject","newTokens","headers","refreshError","refreshToken","refreshResponse","user","currentData","AuthApiService","RoleApiService","roleId","userId","UserApiService","AuthContext","AuthProvider","availableRoles","setAvailableRoles","rolesLoading","setRolesLoading","currentUser","setCurrentUser","isUserLoading","setIsUserLoading","userError","setUserError","tokenStorage","authenticatedHttpService","service","authApiService","userApiService","roleApiService","userRole","role","userPermissions","loadUserData","userData","refreshUser","login","email","password","tenantId","loginResponse","signup","name","signupTenantAdmin","tenantName","changePassword","currentPassword","newPassword","requestPasswordReset","confirmPasswordReset","logout","setTokens","hasValidSession","clearSession","fetchRoles","roles","refreshRoles","hasPermission","permission","permissionString","permissions","internalHttpService","useAuth","FeatureFlagApiService","flagKey","FeatureFlagContext","FeatureFlagProvider","featureFlags","setFeatureFlags","loading","setLoading","setError","featureFlagService","fetchFeatureFlags","errorMessage","refreshInterval","interval","flag","f","useFeatureFlags","SubscriptionApiService","subscriptionId","paymentData","SubscriptionContext","SubscriptionProvider","subscription","setSubscription","subscriptionService","fetchSubscription","features","featureKey","feature","defaultValue","allowedPlans","useSubscription","TenantContext","TenantProvider","settings","setSettings","isSettingsLoading","setIsSettingsLoading","settingsError","setSettingsError","settingsSchema","loadSettings","tenantSettings","updateSettings","newSettings","tenantApi","updatedSettings","refreshSettings","validateSettings","settingsToValidate","errors","key","fieldSchema","value","_a","expectedType","actualType","useTenantSettings","useSettings","UserType","DefaultFallback","InsufficientPermissionsFallback","userType","minUserType","missingPermissions","hasMinimumUserType","hierarchy","Protected","fallback","requiredPermissions","requireAllPermissions","hasAnyPermission","hasAllPermissions","redirectPath","ProtectedRoute","redirectTo","location","useLocation","Navigate","SubscriptionGuard","requiredFeature","hasAllowedPlan","isFeatureEnabled","flagName","FeatureFlag","isEnabled","EyeIcon","EyeOffIcon","defaultIcons","defaultCopy","defaultStyles","LoginForm","copy","styles","icons","onSuccess","onError","onForgotPassword","onSignupClick","showForgotPassword","showSignupLink","className","setEmail","setPassword","showPassword","setShowPassword","fieldErrors","setFieldErrors","mergedCopy","mergedStyles","mergedIcons","validateForm","handleSubmit","e","result","getInputStyle","field","getButtonStyle","prev","SignupForm","signupType","onLoginClick","showLoginLink","setName","confirmPassword","setConfirmPassword","setTenantName","isFormValid","PasswordRecoveryForm","initialToken","onBackToLogin","onModeChange","setToken","setNewPassword","success","setSuccess","validateRequestForm","validateResetForm","handleRequestSubmit","handleResetSubmit","PermissionApiService","SubscriptionPlanApiService","HealthApiService","ApiMappers","dateString","date","meta","app","featureFlag","plan","searchParams"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/services/HttpService.ts","../src/services/AppApiService.ts","../src/providers/AppProvider.tsx","../src/services/SessionManager.ts","../src/services/AuthApiService.ts","../src/services/RoleApiService.ts","../src/services/UserApiService.ts","../src/services/TenantApiService.ts","../src/providers/TenantProvider.tsx","../src/providers/AuthProvider.tsx","../src/services/FeatureFlagApiService.ts","../src/providers/FeatureFlagProvider.tsx","../src/services/SubscriptionApiService.ts","../src/providers/SubscriptionProvider.tsx","../src/types/api.ts","../src/components/Protected.tsx","../src/components/ProtectedRoute.tsx","../src/components/SubscriptionGuard.tsx","../src/components/FeatureFlag.tsx","../src/components/LoginForm.tsx","../src/components/SignupForm.tsx","../src/components/PasswordRecoveryForm.tsx","../src/services/PermissionApiService.ts","../src/services/SubscriptionPlanApiService.ts","../src/services/HealthApiService.ts","../src/utils/mappers.ts"],"sourcesContent":["export interface RequestOptions {\n headers?: Record<string, string>;\n timeout?: number;\n skipAuth?: boolean; // Skip automatic auth header injection\n skipRetry?: boolean; // Skip automatic retry on 401\n}\n\nexport class HttpService {\n private baseUrl: string;\n private timeout: number;\n private sessionManager?: any; // SessionManager instance\n\n constructor(baseUrl: string, timeout = 10000) {\n this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.timeout = timeout;\n }\n\n setSessionManager(sessionManager: any): void {\n this.sessionManager = sessionManager;\n }\n\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n private async request<T>(\n method: string,\n endpoint: string,\n data?: any,\n options?: RequestOptions\n ): Promise<T> {\n return this.executeRequest<T>(method, endpoint, data, options, false);\n }\n\n private async executeRequest<T>(\n method: string,\n endpoint: string,\n data?: any,\n options?: RequestOptions,\n isRetry = false\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;\n const requestTimeout = options?.timeout || this.timeout;\n\n // Inject auth headers automatically unless skipAuth is true\n let requestHeaders = {\n 'Content-Type': 'application/json',\n ...options?.headers,\n };\n\n if (!options?.skipAuth && this.sessionManager) {\n try {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n requestHeaders = { ...requestHeaders, ...authHeaders };\n } catch (error) {\n // If auth header injection fails, continue without auth\n console.warn('Failed to inject auth headers:', error);\n }\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), requestTimeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: data ? JSON.stringify(data) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Handle 401 Unauthorized with automatic retry\n if (response.status === 401 && !options?.skipRetry && !isRetry && this.sessionManager) {\n try {\n // Force token refresh by clearing current tokens and getting new auth headers\n const tokens = this.sessionManager.getTokens();\n if (tokens?.refreshToken) {\n // Trigger refresh through getAuthHeaders with expired token\n await this.sessionManager.getAuthHeaders();\n\n // Retry the original request\n return this.executeRequest<T>(method, endpoint, data, options, true);\n }\n } catch {\n // If refresh fails, throw the original 401 error\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Handle empty responses\n const contentType = response.headers.get('content-type');\n if (!contentType || !contentType.includes('application/json')) {\n return {} as T;\n }\n\n return await response.json();\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timeout after ${requestTimeout}ms`);\n }\n\n throw error;\n }\n }\n\n async get<T>(endpoint: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', endpoint, undefined, options);\n }\n\n async post<T>(endpoint: string, data: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', endpoint, data, options);\n }\n\n async put<T>(endpoint: string, data: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', endpoint, data, options);\n }\n\n async delete<T>(endpoint: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', endpoint, undefined, options);\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n ApiResponse,\n App,\n CreateAppRequest,\n PublicAppInfo,\n PaginationParams,\n} from '../types/api';\n\nexport class AppApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager: SessionManager\n ) {}\n\n async createApp(request: CreateAppRequest): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<App>>('/apps/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getApps(params?: PaginationParams): Promise<{ apps: App[]; meta: any }> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/apps/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<App[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n apps: response.data,\n meta: response.meta,\n };\n }\n\n async getAppById(id: string): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<App>>(`/apps/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateApp(id: string, request: Partial<CreateAppRequest>): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<App>>(`/apps/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getPublicAppInfo(id: string): Promise<PublicAppInfo> {\n const response = await this.httpService.get<ApiResponse<PublicAppInfo>>(`/apps/${id}/public`);\n return response.data;\n }\n\n async setDefaultSubscriptionPlan(appId: string, planId: string): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<App>>(\n `/apps/${appId}/default-subscription-plan`,\n { planId },\n { headers: authHeaders }\n );\n return response.data;\n }\n\n async updateSettingsSchema(appId: string, schema: any, defaultSettings: any): Promise<App> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<App>>(\n `/apps/${appId}/settings-schema`,\n { schema, defaultSettings },\n { headers: authHeaders }\n );\n return response.data;\n }\n\n async exportConfig(appId: string): Promise<any> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<any>>(`/apps/${appId}/export-config`, {\n headers: authHeaders,\n });\n return response.data;\n }\n}\n","import {\n createContext,\n useContext,\n useMemo,\n ReactNode,\n useState,\n useEffect,\n useCallback,\n} from 'react';\nimport { HttpService } from '../services/HttpService';\nimport { AppApiService } from '../services/AppApiService';\nimport type { PublicAppInfo } from '../types/api';\n\nexport interface AppConfig {\n baseUrl: string;\n appId: string;\n // Fallbacks\n loadingFallback?: ReactNode;\n errorFallback?: ReactNode | ((error: Error, retry: () => void) => ReactNode);\n}\n\ninterface AppContextValue {\n appId: string;\n baseUrl: string;\n // App info with settings schema\n appInfo: PublicAppInfo | null;\n isAppLoading: boolean;\n appError: Error | null;\n retryApp: () => void;\n}\n\nconst AppContext = createContext<AppContextValue | null>(null);\n\ninterface AppProviderProps {\n config: AppConfig;\n children: ReactNode;\n}\n\n// Default loading component\nconst DefaultLoadingFallback = () => (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontFamily: 'system-ui, sans-serif',\n }}\n >\n <div>Loading application...</div>\n </div>\n);\n\n// Default error component\nconst DefaultErrorFallback = ({ error, retry }: { error: Error; retry: () => void }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontFamily: 'system-ui, sans-serif',\n textAlign: 'center',\n padding: '20px',\n }}\n >\n <h2 style={{ color: '#dc3545', marginBottom: '16px' }}>Application Error</h2>\n <p style={{ color: '#6c757d', marginBottom: '24px' }}>\n {error.message || 'Unable to load application'}\n </p>\n <button\n onClick={retry}\n style={{\n padding: '8px 16px',\n backgroundColor: '#007bff',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Retry\n </button>\n </div>\n);\n\nexport function AppProvider({ config, children }: AppProviderProps) {\n // App info state\n const [appInfo, setAppInfo] = useState<PublicAppInfo | null>(null);\n const [isAppLoading, setIsAppLoading] = useState(true);\n const [appError, setAppError] = useState<Error | null>(null);\n\n\n const contextValue = useMemo(() => {\n // Retry function for app loading\n const retryApp = () => {\n loadApp();\n };\n\n return {\n appId: config.appId,\n baseUrl: config.baseUrl,\n // App info\n appInfo,\n isAppLoading,\n appError,\n retryApp,\n };\n }, [config, appInfo, isAppLoading, appError]);\n\n // Load app info\n const loadApp = useCallback(async () => {\n try {\n setIsAppLoading(true);\n setAppError(null);\n\n const httpService = new HttpService(config.baseUrl);\n const appApi = new AppApiService(httpService, {} as any); // SessionManager not needed for public endpoint\n const appData = await appApi.getPublicAppInfo(config.appId);\n setAppInfo(appData);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load app information');\n setAppError(error);\n setAppInfo(null);\n } finally {\n setIsAppLoading(false);\n }\n }, [config.baseUrl, config.appId]);\n\n\n // Load app info on mount\n useEffect(() => {\n loadApp();\n }, [loadApp]);\n\n\n // Show loading fallback for app info\n if (isAppLoading) {\n return <>{config.loadingFallback || <DefaultLoadingFallback />}</>;\n }\n\n // Show error fallback for app info\n if (appError) {\n const ErrorComponent =\n typeof config.errorFallback === 'function'\n ? config.errorFallback(appError, () => loadApp())\n : config.errorFallback || (\n <DefaultErrorFallback error={appError} retry={() => loadApp()} />\n );\n\n return <>{ErrorComponent}</>;\n }\n\n return <AppContext.Provider value={contextValue}>{children}</AppContext.Provider>;\n}\n\nexport function useApp(): AppContextValue {\n const context = useContext(AppContext);\n if (!context) {\n throw new Error('useApp must be used within an AppProvider');\n }\n return context;\n}\n\n// Backward compatibility\nexport const useApi = useApp;\n\n","export interface TokenData {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n expiresIn?: number;\n tokenType?: string;\n}\n\nexport interface TokenStorage {\n get(): any;\n set(data: any): void;\n clear(): void;\n}\n\nexport interface SessionConfig {\n storageKey?: string;\n autoRefresh?: boolean;\n refreshThreshold?: number;\n onRefreshFailed?: () => void;\n tokenStorage?: TokenStorage;\n baseUrl?: string; // Base URL for API calls\n}\n\nexport class SessionManager {\n private storageKey: string;\n private autoRefresh: boolean;\n private refreshThreshold: number;\n private baseUrl: string;\n private onRefreshFailed?: () => void;\n private tokenStorage: TokenStorage;\n\n // Refresh queue management\n private refreshPromise: Promise<void> | null = null;\n private refreshQueue: Array<{\n resolve: (headers: Record<string, string>) => void;\n reject: (error: Error) => void;\n }> = [];\n\n constructor(config: SessionConfig = {}) {\n this.storageKey = config.storageKey || 'auth_tokens';\n this.autoRefresh = config.autoRefresh ?? true;\n this.refreshThreshold = config.refreshThreshold || 300000; // 5 minutes\n this.onRefreshFailed = config.onRefreshFailed;\n this.baseUrl = config.baseUrl || '';\n\n // Use provided tokenStorage or create default localStorage implementation\n this.tokenStorage = config.tokenStorage || {\n get: () => {\n try {\n const stored = localStorage.getItem(this.storageKey);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n },\n set: (data: any) => {\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(data));\n } catch {\n // Handle storage errors silently\n }\n },\n clear: () => {\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // Handle storage errors silently\n }\n },\n };\n }\n\n setTokens(tokens: TokenData): void {\n // Convert expiresIn to expiresAt if needed\n const tokenData: TokenData = {\n ...tokens,\n expiresAt:\n tokens.expiresAt || (tokens.expiresIn ? Date.now() + tokens.expiresIn * 1000 : undefined),\n };\n\n this.tokenStorage.set(tokenData);\n }\n\n getTokens(): TokenData | null {\n return this.tokenStorage.get();\n }\n\n clearTokens(): void {\n this.tokenStorage.clear();\n }\n\n isTokenExpired(token?: TokenData): boolean {\n const tokens = token || this.getTokens();\n if (!tokens?.expiresAt) return false;\n\n return Date.now() >= tokens.expiresAt;\n }\n\n shouldRefreshToken(token?: TokenData): boolean {\n const tokens = token || this.getTokens();\n if (!tokens?.expiresAt || !this.autoRefresh) return false;\n\n return Date.now() >= tokens.expiresAt - this.refreshThreshold;\n }\n\n getAccessToken(): string | null {\n const tokens = this.getTokens();\n return tokens?.accessToken || null;\n }\n\n async getAuthHeaders(): Promise<Record<string, string>> {\n const tokens = this.getTokens();\n\n // No tokens available\n if (!tokens?.accessToken) {\n return {};\n }\n\n // Token is valid and doesn't need refresh yet, return headers immediately\n if (!this.shouldRefreshToken(tokens)) {\n return {\n Authorization: `Bearer ${tokens.accessToken}`,\n };\n }\n\n // Token needs refresh\n if (!tokens.refreshToken) {\n // No refresh token available, clear session and return empty headers\n this.clearSession();\n if (this.onRefreshFailed) {\n this.onRefreshFailed();\n }\n return {};\n }\n\n // If refresh is already in progress, queue this request\n if (this.refreshPromise) {\n return new Promise((resolve, reject) => {\n this.refreshQueue.push({ resolve, reject });\n });\n }\n\n // Start refresh process\n this.refreshPromise = this.performTokenRefresh(tokens.refreshToken);\n\n try {\n await this.refreshPromise;\n\n // Refresh successful, process queue\n const newTokens = this.getTokens();\n const headers: Record<string, string> = newTokens?.accessToken\n ? { Authorization: `Bearer ${newTokens.accessToken}` }\n : {};\n\n // Resolve all queued requests\n this.refreshQueue.forEach(({ resolve }) => resolve(headers));\n this.refreshQueue = [];\n\n return headers;\n } catch (error) {\n // Refresh failed, reject all queued requests\n const refreshError = error instanceof Error ? error : new Error('Token refresh failed');\n\n this.refreshQueue.forEach(({ reject }) => reject(refreshError));\n this.refreshQueue = [];\n\n // Clear session and notify\n this.clearSession();\n if (this.onRefreshFailed) {\n this.onRefreshFailed();\n }\n\n return {};\n } finally {\n this.refreshPromise = null;\n }\n }\n\n private async performTokenRefresh(refreshToken: string): Promise<void> {\n if (!this.baseUrl) {\n throw new Error('Base URL not configured for token refresh');\n }\n\n const url = `${this.baseUrl}/auth/refresh`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n refreshToken,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Token refresh failed: ${response.status} ${response.statusText}`);\n }\n\n const refreshResponse = await response.json();\n\n this.setTokens({\n accessToken: refreshResponse.accessToken,\n refreshToken: refreshResponse.refreshToken || refreshToken,\n expiresIn: refreshResponse.expiresIn,\n });\n }\n\n setUser(user: any): void {\n // Store user data alongside tokens\n const currentData = this.tokenStorage.get() || {};\n this.tokenStorage.set({ ...currentData, user });\n }\n\n getUser(): any | null {\n const data = this.tokenStorage.get();\n return data?.user || null;\n }\n\n clearUser(): void {\n const currentData = this.tokenStorage.get() || {};\n delete currentData.user;\n this.tokenStorage.set(currentData);\n }\n\n clearSession(): void {\n this.clearTokens();\n this.clearUser();\n }\n\n hasValidSession(): boolean {\n const tokens = this.getTokens();\n return tokens !== null && !this.isTokenExpired(tokens);\n }\n}\n","import { HttpService } from './HttpService';\nimport type {\n LoginRequest,\n LoginResponse,\n SignupRequest,\n ChangePasswordRequest,\n RefreshTokenRequest,\n RefreshTokenResponse,\n ApiResponse,\n User,\n} from '../types/api';\n\nexport class AuthApiService {\n constructor(private httpService: HttpService) {}\n\n // Public endpoints - no auth required\n async login(request: LoginRequest): Promise<LoginResponse> {\n const response = await this.httpService.post<LoginResponse>('/auth/login', request);\n console.log(response);\n return response;\n }\n\n async signup(request: SignupRequest): Promise<User> {\n const response = await this.httpService.post<User>('/auth/signup', request);\n return response;\n }\n\n async signupTenantAdmin(request: {\n email: string;\n name: string;\n password: string;\n tenantName: string;\n appId: string;\n }): Promise<{ user: User; tenant: any }> {\n const response = await this.httpService.post<{ user: User; tenant: any }>(\n '/auth/signup/tenant-admin',\n request\n );\n return response;\n }\n\n async refreshToken(request: RefreshTokenRequest): Promise<RefreshTokenResponse> {\n const response = await this.httpService.post<RefreshTokenResponse>('/auth/refresh', request);\n return response;\n }\n\n async requestPasswordReset(request: { email: string; tenantId: string }): Promise<void> {\n await this.httpService.post<void>('/auth/password-reset/request', request);\n }\n\n async confirmPasswordReset(request: { token: string; newPassword: string }): Promise<void> {\n await this.httpService.post<void>('/auth/password-reset/confirm', request);\n }\n\n // Protected endpoints - auth required\n async changePassword(\n request: ChangePasswordRequest,\n authHeaders: Record<string, string>\n ): Promise<void> {\n await this.httpService.post<ApiResponse<null>>('/auth/change-password', request, {\n headers: authHeaders,\n });\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Role,\n CreateRoleRequest,\n AssignRoleRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class RoleApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createRole(request: CreateRoleRequest): Promise<Role> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Role>>('/roles/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getRoleById(id: string): Promise<Role> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Role>>(`/roles/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateRole(id: string, request: Partial<CreateRoleRequest>): Promise<Role> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Role>>(`/roles/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async deleteRole(id: string): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/roles/${id}`, {\n headers: authHeaders,\n });\n }\n\n // Public endpoint - no auth required\n async getRolesByApp(\n appId: string,\n params?: PaginationParams\n ): Promise<{ roles: Role[]; meta: any }> {\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/roles/app/${appId}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Role[]>>(url);\n\n return {\n roles: response.data,\n meta: response.meta,\n };\n }\n\n async assignRole(roleId: string, request: AssignRoleRequest): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.post<ApiResponse<null>>(`/roles/${roleId}/assign`, request, {\n headers: authHeaders,\n });\n }\n\n async revokeRole(roleId: string, request: AssignRoleRequest): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.post<ApiResponse<null>>(`/roles/${roleId}/revoke`, request, {\n headers: authHeaders,\n });\n }\n\n async getUserRoles(\n userId: string,\n params?: PaginationParams\n ): Promise<{ roles: Role[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/roles/user/${userId}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Role[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n roles: response.data,\n meta: response.meta,\n };\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type { User, CreateUserRequest, ApiResponse, PaginationParams } from '../types/api';\n\nexport class UserApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager: SessionManager\n ) {}\n\n async createUser(request: CreateUserRequest): Promise<User> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<User>>('/users/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getUsers(params?: PaginationParams): Promise<{ users: User[]; meta: any }> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/users/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<User[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n users: response.data,\n meta: response.meta,\n };\n }\n\n async getUserById(id: string): Promise<User> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<User>>(`/users/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateUser(id: string, request: Partial<CreateUserRequest>): Promise<User> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<User>>(`/users/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async deleteUser(id: string): Promise<void> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/users/${id}`, {\n headers: authHeaders,\n });\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Tenant,\n CreateTenantRequest,\n PublicTenantInfo,\n TenantSettings,\n UpdateTenantSettingsRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class TenantApiService {\n constructor(\n private httpService: HttpService,\n private appId: string,\n private sessionManager?: SessionManager\n ) {}\n\n async createTenant(request: CreateTenantRequest): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Tenant>>('/tenants/', request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async getTenants(params?: PaginationParams): Promise<{ tenants: Tenant[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/tenants/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Tenant[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n tenants: response.data,\n meta: response.meta,\n };\n }\n\n async getTenantById(id: string): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Tenant>>(`/tenants/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateTenant(id: string, request: Partial<CreateTenantRequest>): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Tenant>>(`/tenants/${id}`, request, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async adminUpdateTenant(id: string, request: Partial<CreateTenantRequest>): Promise<Tenant> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Tenant>>(\n `/tenants/${id}/admin-update`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n // Public endpoint - no auth required\n async getPublicTenantInfo(slug: string): Promise<PublicTenantInfo> {\n const response = await this.httpService.get<ApiResponse<PublicTenantInfo>>(\n `/tenants/${this.appId}/${slug}/public`\n );\n return response.data;\n }\n\n // Settings endpoints\n async getTenantSettings(id: string): Promise<TenantSettings> {\n const response = await this.httpService.get<ApiResponse<TenantSettings>>(\n `/tenants/${id}/settings`\n );\n return response.data;\n }\n\n async updateTenantSettings(\n id: string,\n request: UpdateTenantSettingsRequest\n ): Promise<TenantSettings> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<TenantSettings>>(\n `/tenants/${id}/settings`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n}\n","import {\n createContext,\n useContext,\n useMemo,\n ReactNode,\n useState,\n useEffect,\n useCallback,\n} from 'react';\nimport { useApp } from './AppProvider';\nimport { useAuth } from './AuthProvider';\nimport { HttpService } from '../services/HttpService';\nimport { TenantApiService } from '../services/TenantApiService';\nimport type { TenantSettings, UpdateTenantSettingsRequest, JSONSchema, PublicTenantInfo } from '../types/api';\n\nexport interface TenantConfig {\n // Tenant configuration\n tenantMode?: 'subdomain' | 'selector' | 'fixed' | 'optional';\n fixedTenantSlug?: string; // Required when tenantMode is 'fixed'\n selectorParam?: string; // Default: 'tenant', used when tenantMode is 'selector'\n // SSR support\n initialTenant?: PublicTenantInfo;\n // Fallbacks\n loadingFallback?: ReactNode;\n errorFallback?: ReactNode | ((error: Error, retry: () => void) => ReactNode);\n}\n\ninterface TenantContextValue {\n // Tenant info\n tenant: PublicTenantInfo | null;\n tenantSlug: string | null;\n isTenantLoading: boolean;\n tenantError: Error | null;\n retryTenant: () => void;\n // Settings\n settings: TenantSettings | null;\n settingsSchema: JSONSchema | null;\n isSettingsLoading: boolean;\n settingsError: Error | null;\n // Actions\n updateSettings: (settings: TenantSettings) => Promise<void>;\n refreshSettings: () => void;\n // Validation\n validateSettings: (settings: TenantSettings) => { isValid: boolean; errors: string[] };\n}\n\nconst TenantContext = createContext<TenantContextValue | null>(null);\n\ninterface TenantProviderProps {\n config: TenantConfig;\n children: ReactNode;\n}\n\n// Default loading component\nconst DefaultLoadingFallback = () => (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontFamily: 'system-ui, sans-serif',\n }}\n >\n <div>Loading tenant...</div>\n </div>\n);\n\n// Default error component\nconst DefaultErrorFallback = ({ error, retry }: { error: Error; retry: () => void }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n fontFamily: 'system-ui, sans-serif',\n textAlign: 'center',\n padding: '20px',\n }}\n >\n <h2 style={{ color: '#dc3545', marginBottom: '16px' }}>Tenant Error</h2>\n <p style={{ color: '#6c757d', marginBottom: '24px' }}>\n {error.message || 'Unable to load tenant'}\n </p>\n <button\n onClick={retry}\n style={{\n padding: '8px 16px',\n backgroundColor: '#007bff',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n >\n Retry\n </button>\n </div>\n);\n\nexport function TenantProvider({ config, children }: TenantProviderProps) {\n const { baseUrl, appInfo, appId } = useApp();\n const auth = useAuth();\n const sessionManager = auth?.sessionManager;\n\n // Tenant state\n const [tenant, setTenant] = useState<PublicTenantInfo | null>(config.initialTenant || null);\n const [isTenantLoading, setIsTenantLoading] = useState(!config.initialTenant);\n const [tenantError, setTenantError] = useState<Error | null>(null);\n\n // Settings state\n const [settings, setSettings] = useState<TenantSettings | null>(null);\n const [isSettingsLoading, setIsSettingsLoading] = useState(false);\n const [settingsError, setSettingsError] = useState<Error | null>(null);\n\n // Detect tenant slug from URL or config with localStorage fallback\n const detectTenantSlug = useCallback((): string | null => {\n const tenantMode = config.tenantMode || 'optional';\n const storageKey = `tenant`;\n\n if (tenantMode === 'fixed') {\n return config.fixedTenantSlug || null;\n }\n\n if (typeof window === 'undefined') return null;\n\n if (tenantMode === 'subdomain') {\n const hostname = window.location.hostname;\n const parts = hostname.split('.');\n\n // Extract subdomain (assuming format: subdomain.domain.com)\n if (parts.length >= 3) {\n const subdomain = parts[0];\n // Save to localStorage for persistence\n localStorage.setItem(storageKey, subdomain);\n return subdomain;\n }\n\n // Fallback to localStorage if no subdomain found\n return localStorage.getItem(storageKey);\n } else if (tenantMode === 'selector') {\n // tenantMode === 'selector'\n const urlParams = new URLSearchParams(window.location.search);\n const urlTenant = urlParams.get(config.selectorParam || 'tenant');\n\n if (urlTenant) {\n // Save to localStorage when found in URL\n localStorage.setItem(storageKey, urlTenant);\n return urlTenant;\n }\n\n // Fallback to localStorage if not in URL\n return localStorage.getItem(storageKey);\n }\n\n // For 'optional' mode, return null (no tenant required)\n return null;\n }, [config.tenantMode, config.fixedTenantSlug, config.selectorParam]);\n\n const tenantSlug = useMemo(() => detectTenantSlug(), [detectTenantSlug]);\n\n // Get settings schema from app info\n const settingsSchema = appInfo?.settingsSchema || null;\n\n // Load tenant info\n const loadTenant = useCallback(\n async (slug: string) => {\n try {\n setIsTenantLoading(true);\n setTenantError(null);\n\n const httpService = new HttpService(baseUrl);\n const tenantApi = new TenantApiService(httpService, appId);\n const tenantInfo = await tenantApi.getPublicTenantInfo(slug);\n setTenant(tenantInfo);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load tenant information');\n setTenantError(error);\n setTenant(null);\n } finally {\n setIsTenantLoading(false);\n }\n },\n [baseUrl, appId]\n );\n\n // Load tenant settings\n const loadSettings = useCallback(async () => {\n if (!tenant?.id) return;\n\n try {\n setIsSettingsLoading(true);\n setSettingsError(null);\n\n const httpService = new HttpService(baseUrl);\n const tenantApi = new TenantApiService(httpService, tenant.appId);\n const tenantSettings = await tenantApi.getTenantSettings(tenant.id);\n setSettings(tenantSettings);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load tenant settings');\n setSettingsError(error);\n setSettings(null);\n } finally {\n setIsSettingsLoading(false);\n }\n }, [baseUrl, tenant]);\n\n // Update tenant settings\n const updateSettings = useCallback(\n async (newSettings: TenantSettings) => {\n if (!tenant?.id || !sessionManager) {\n throw new Error('Tenant ID and authentication required to update settings');\n }\n\n try {\n setIsSettingsLoading(true);\n setSettingsError(null);\n\n const httpService = new HttpService(baseUrl);\n const tenantApi = new TenantApiService(httpService, tenant.appId, sessionManager);\n\n const request: UpdateTenantSettingsRequest = { settings: newSettings };\n const updatedSettings = await tenantApi.updateTenantSettings(tenant.id, request);\n setSettings(updatedSettings);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update tenant settings');\n setSettingsError(error);\n throw error;\n } finally {\n setIsSettingsLoading(false);\n }\n },\n [baseUrl, tenant, sessionManager]\n );\n\n // Refresh settings\n const refreshSettings = useCallback(() => {\n loadSettings();\n }, [loadSettings]);\n\n // Validate settings against schema\n const validateSettings = useCallback(\n (settingsToValidate: TenantSettings) => {\n if (!settingsSchema) {\n return { isValid: true, errors: [] };\n }\n\n const errors: string[] = [];\n\n try {\n // If settingsSchema has properties, validate against them\n if (settingsSchema.properties) {\n Object.entries(settingsSchema.properties).forEach(([key, fieldSchema]) => {\n const value = settingsToValidate[key];\n\n // Check required fields\n if (settingsSchema.required?.includes(key) && (value === undefined || value === null)) {\n errors.push(`Field '${key}' is required`);\n return;\n }\n\n // Skip validation if value is not provided and not required\n if (value === undefined || value === null) return;\n\n // Type validation using JSONSchema\n if (fieldSchema.type) {\n const expectedType = fieldSchema.type;\n const actualType = typeof value;\n\n if (expectedType === 'string' && actualType !== 'string') {\n errors.push(`Field '${key}' must be a string`);\n } else if (\n (expectedType === 'number' || expectedType === 'integer') &&\n actualType !== 'number'\n ) {\n errors.push(`Field '${key}' must be a number`);\n } else if (expectedType === 'boolean' && actualType !== 'boolean') {\n errors.push(`Field '${key}' must be a boolean`);\n } else if (expectedType === 'array' && !Array.isArray(value)) {\n errors.push(`Field '${key}' must be an array`);\n }\n }\n\n // String length validation\n if (\n fieldSchema.minLength !== undefined &&\n typeof value === 'string' &&\n value.length < fieldSchema.minLength\n ) {\n errors.push(\n `Field '${key}' must be at least ${fieldSchema.minLength} characters long`\n );\n }\n if (\n fieldSchema.maxLength !== undefined &&\n typeof value === 'string' &&\n value.length > fieldSchema.maxLength\n ) {\n errors.push(\n `Field '${key}' must be no more than ${fieldSchema.maxLength} characters long`\n );\n }\n\n // Number range validation\n if (\n fieldSchema.minimum !== undefined &&\n typeof value === 'number' &&\n value < fieldSchema.minimum\n ) {\n errors.push(`Field '${key}' must be at least ${fieldSchema.minimum}`);\n }\n if (\n fieldSchema.maximum !== undefined &&\n typeof value === 'number' &&\n value > fieldSchema.maximum\n ) {\n errors.push(`Field '${key}' must be no more than ${fieldSchema.maximum}`);\n }\n\n // Pattern validation for strings\n if (fieldSchema.pattern && typeof value === 'string') {\n const regex = new RegExp(fieldSchema.pattern);\n if (!regex.test(value)) {\n errors.push(`Field '${key}' does not match the required pattern`);\n }\n }\n\n // Enum validation\n if (fieldSchema.enum && !fieldSchema.enum.includes(value)) {\n errors.push(`Field '${key}' must be one of: ${fieldSchema.enum.join(', ')}`);\n }\n });\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n } catch {\n return {\n isValid: false,\n errors: ['Invalid settings schema or validation error'],\n };\n }\n },\n [settingsSchema]\n );\n\n // Load tenant on mount (if not SSR)\n useEffect(() => {\n const tenantMode = config.tenantMode || 'optional';\n \n if (!config.initialTenant && tenantSlug) {\n loadTenant(tenantSlug);\n } else if (!config.initialTenant && !tenantSlug && tenantMode === 'fixed') {\n setTenantError(new Error('Fixed tenant mode requires fixedTenantSlug configuration'));\n setIsTenantLoading(false);\n } else if (!config.initialTenant && !tenantSlug && (tenantMode === 'subdomain' || tenantMode === 'selector')) {\n setTenantError(\n new Error(`No tenant ${tenantMode === 'subdomain' ? 'subdomain' : 'parameter'} found`)\n );\n setIsTenantLoading(false);\n } else if (!config.initialTenant && !tenantSlug && tenantMode === 'optional') {\n // No tenant required, allow access to root\n setTenant(null);\n setTenantError(null);\n setIsTenantLoading(false);\n }\n }, [config.initialTenant, tenantSlug, loadTenant, config.tenantMode, config.fixedTenantSlug]);\n\n // Load settings when tenant changes\n useEffect(() => {\n if (tenant?.id) {\n loadSettings();\n } else {\n setSettings(null);\n setSettingsError(null);\n setIsSettingsLoading(false);\n }\n }, [tenant?.id, loadSettings]);\n\n const contextValue = useMemo(() => {\n // Retry function for tenant loading\n const retryTenant = () => {\n if (tenantSlug) {\n loadTenant(tenantSlug);\n }\n };\n\n return {\n // Tenant info\n tenant,\n tenantSlug,\n isTenantLoading,\n tenantError,\n retryTenant,\n // Settings\n settings,\n settingsSchema,\n isSettingsLoading,\n settingsError,\n // Actions\n updateSettings,\n refreshSettings,\n // Validation\n validateSettings,\n };\n }, [\n tenant,\n tenantSlug,\n isTenantLoading,\n tenantError,\n settings,\n settingsSchema,\n isSettingsLoading,\n settingsError,\n updateSettings,\n refreshSettings,\n validateSettings,\n ]);\n\n // Show loading fallback\n if (isTenantLoading) {\n return <>{config.loadingFallback || <DefaultLoadingFallback />}</>;\n }\n\n // Show error fallback (only if tenant is required)\n if (tenantError && config.tenantMode !== 'optional') {\n const ErrorComponent =\n typeof config.errorFallback === 'function'\n ? config.errorFallback(tenantError, () => loadTenant(tenantSlug || ''))\n : config.errorFallback || (\n <DefaultErrorFallback error={tenantError} retry={() => loadTenant(tenantSlug || '')} />\n );\n\n return <>{ErrorComponent}</>;\n }\n\n return <TenantContext.Provider value={contextValue}>{children}</TenantContext.Provider>;\n}\n\nexport function useTenant(): TenantContextValue {\n const context = useContext(TenantContext);\n if (!context) {\n throw new Error('useTenant must be used within a TenantProvider');\n }\n return context;\n}\n\n// Backward compatibility\nexport const useTenantSettings = useTenant;\n\n// Convenience hook for just the settings\nexport function useSettings() {\n const {\n settings,\n settingsSchema,\n isSettingsLoading,\n settingsError,\n updateSettings,\n validateSettings,\n } = useTenant();\n return {\n settings,\n settingsSchema,\n isLoading: isSettingsLoading,\n error: settingsError,\n updateSettings,\n validateSettings,\n };\n}\n\n// Convenience hook for just tenant info\nexport function useTenantInfo() {\n const { tenant, tenantSlug, isTenantLoading, tenantError, retryTenant } = useTenant();\n return {\n tenant,\n tenantSlug,\n isLoading: isTenantLoading,\n error: tenantError,\n retry: retryTenant,\n };\n}\n","import { createContext, useContext, ReactNode, useMemo, useState, useEffect } from 'react';\nimport { SessionManager } from '../services/SessionManager';\nimport { AuthApiService } from '../services/AuthApiService';\nimport { RoleApiService } from '../services/RoleApiService';\nimport { UserApiService } from '../services/UserApiService';\nimport { HttpService } from '../services/HttpService';\nimport { useApp } from './AppProvider';\nimport { useTenantInfo } from './TenantProvider';\nimport type { Role, Permission, User } from '../types/api';\n\nexport interface AuthConfig {\n onRefreshFailed?: () => void;\n initialRoles?: Role[]; // For SSR injection\n}\n\nexport interface AuthContextValue {\n sessionManager: SessionManager;\n authenticatedHttpService: HttpService; // Authenticated HttpService for protected endpoints\n // Auth methods\n login: (email: string, password: string, tenantId: string) => Promise<any>;\n signup: (email: string, name: string, password: string, tenantId: string) => Promise<any>;\n signupTenantAdmin: (\n email: string,\n name: string,\n password: string,\n tenantName: string\n ) => Promise<any>;\n changePassword: (currentPassword: string, newPassword: string) => Promise<void>;\n requestPasswordReset: (email: string, tenantId: string) => Promise<void>;\n confirmPasswordReset: (token: string, newPassword: string) => Promise<void>;\n refreshToken: () => Promise<void>;\n logout: () => void;\n // Session methods\n setTokens: (tokens: { accessToken: string; refreshToken: string; expiresIn: number }) => void;\n hasValidSession: () => boolean;\n clearSession: () => void;\n // User data\n currentUser: User | null;\n isUserLoading: boolean;\n userError: Error | null;\n refreshUser: () => Promise<void>;\n // Role and Permission methods\n userRole: Role | null;\n userPermissions: string[];\n availableRoles: Role[];\n rolesLoading: boolean;\n hasPermission: (permission: string | Permission) => boolean;\n hasAnyPermission: (permissions: (string | Permission)[]) => boolean;\n hasAllPermissions: (permissions: (string | Permission)[]) => boolean;\n getUserPermissionStrings: () => string[];\n refreshRoles: () => Promise<void>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\ninterface AuthProviderProps {\n config?: AuthConfig;\n children: ReactNode;\n}\n\nexport function AuthProvider({ config = {}, children }: AuthProviderProps) {\n const { appId, baseUrl } = useApp();\n const tenantInfo = useTenantInfo();\n const tenantSlug = tenantInfo?.tenantSlug || null;\n const [availableRoles, setAvailableRoles] = useState<Role[]>(config.initialRoles || []);\n const [rolesLoading, setRolesLoading] = useState(!config.initialRoles);\n const [currentUser, setCurrentUser] = useState<User | null>(null);\n const [isUserLoading, setIsUserLoading] = useState(false);\n const [userError, setUserError] = useState<Error | null>(null);\n\n // Create services with stable references\n const sessionManager = useMemo(() => {\n const storageKey = tenantSlug ? `auth_tokens_${tenantSlug}` : 'auth_tokens';\n const tokenStorage = {\n get: () => {\n try {\n const stored = localStorage.getItem(storageKey);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n },\n set: (tokens: any) => {\n try {\n localStorage.setItem(storageKey, JSON.stringify(tokens));\n } catch {\n // Handle storage errors silently\n }\n },\n clear: () => {\n try {\n localStorage.removeItem(storageKey);\n } catch {\n // Handle storage errors silently\n }\n },\n };\n\n return new SessionManager({\n onRefreshFailed: config.onRefreshFailed,\n tokenStorage,\n baseUrl: baseUrl,\n });\n }, [tenantSlug, baseUrl, config.onRefreshFailed]);\n\n const authenticatedHttpService = useMemo(() => {\n const service = new HttpService(baseUrl);\n service.setSessionManager(sessionManager);\n return service;\n }, [baseUrl, sessionManager]);\n\n const authApiService = useMemo(() => {\n return new AuthApiService(new HttpService(baseUrl));\n }, [baseUrl]);\n\n const userApiService = useMemo(() => {\n return new UserApiService(authenticatedHttpService, sessionManager);\n }, [authenticatedHttpService, sessionManager]);\n\n const roleApiService = useMemo(() => {\n return new RoleApiService(new HttpService(baseUrl));\n }, [baseUrl]);\n\n // Calculate derived values with useMemo to prevent recalculation\n const user = useMemo(() => {\n return currentUser || sessionManager.getUser();\n }, [currentUser, sessionManager]);\n\n const userRole = useMemo(() => {\n return user?.roleId ? availableRoles.find(role => role.id === user.roleId) || null : null;\n }, [user, availableRoles]);\n\n const userPermissions = useMemo(() => {\n const permissions = userRole?.permissions || [];\n // Permissions from API are already strings in 'resource.action' format\n return permissions;\n }, [userRole]);\n\n // Debug log only when userPermissions actually changes\n useEffect(() => {\n console.log('AuthProvider - userPermissions changed:', userPermissions);\n }, [userPermissions]);\n\n const contextValue = useMemo(() => {\n // Load user data from API\n const loadUserData = async () => {\n try {\n setIsUserLoading(true);\n setUserError(null);\n\n const user = sessionManager.getUser();\n if (!user?.id) {\n throw new Error('No user ID available in session');\n }\n\n const userData = await userApiService.getUserById(user.id);\n setCurrentUser(userData);\n sessionManager.setUser(userData); // Update session with fresh data\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to load user data');\n setUserError(error);\n console.error('Failed to load user data:', error);\n } finally {\n setIsUserLoading(false);\n }\n };\n\n const refreshUser = async () => {\n await loadUserData();\n };\n\n // Auth methods\n const login = async (email: string, password: string, tenantId: string) => {\n const loginResponse = await authApiService.login({\n email,\n password,\n tenantId,\n });\n\n sessionManager.setTokens({\n accessToken: loginResponse.accessToken,\n refreshToken: loginResponse.refreshToken,\n expiresIn: loginResponse.expiresIn,\n });\n\n // Store user data if available in the response\n if (loginResponse.user) {\n sessionManager.setUser(loginResponse.user);\n setCurrentUser(loginResponse.user);\n\n // Load complete user data from API after login\n try {\n await loadUserData();\n } catch (error) {\n console.warn('Failed to load complete user data after login:', error);\n }\n }\n\n return loginResponse;\n };\n\n const signup = async (email: string, name: string, password: string, tenantId: string) => {\n const signupResponse = await authApiService.signup({ email, name, password, tenantId });\n return signupResponse;\n };\n\n const signupTenantAdmin = async (\n email: string,\n name: string,\n password: string,\n tenantName: string\n ) => {\n const signupResponse = await authApiService.signupTenantAdmin({\n email,\n name,\n password,\n tenantName,\n appId,\n });\n return signupResponse;\n };\n\n const changePassword = async (currentPassword: string, newPassword: string) => {\n const authHeaders = await sessionManager.getAuthHeaders();\n await authApiService.changePassword({ currentPassword, newPassword }, authHeaders);\n };\n\n const requestPasswordReset = async (email: string, tenantId: string) => {\n await authApiService.requestPasswordReset({ email, tenantId });\n };\n\n const confirmPasswordReset = async (token: string, newPassword: string) => {\n await authApiService.confirmPasswordReset({ token, newPassword });\n };\n\n const refreshToken = async () => {\n const tokens = sessionManager.getTokens();\n if (!tokens?.refreshToken) {\n throw new Error('No refresh token available');\n }\n\n const refreshResponse = await authApiService.refreshToken({\n refreshToken: tokens.refreshToken,\n });\n\n sessionManager.setTokens({\n accessToken: refreshResponse.accessToken,\n refreshToken: refreshResponse.refreshToken || tokens.refreshToken,\n expiresIn: refreshResponse.expiresIn,\n });\n };\n\n const logout = () => {\n sessionManager.clearSession();\n setCurrentUser(null);\n setUserError(null);\n };\n\n const setTokens = (tokens: {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n }) => {\n sessionManager.setTokens(tokens);\n };\n\n const hasValidSession = () => {\n return sessionManager.hasValidSession();\n };\n\n const clearSession = () => {\n sessionManager.clearSession();\n setCurrentUser(null);\n setUserError(null);\n };\n\n // Role and Permission methods\n const fetchRoles = async () => {\n if (!appId) return;\n\n try {\n setRolesLoading(true);\n const { roles } = await roleApiService.getRolesByApp(appId);\n setAvailableRoles(roles);\n } catch (error) {\n console.error('Failed to fetch roles:', error);\n } finally {\n setRolesLoading(false);\n }\n };\n\n const refreshRoles = async () => {\n await fetchRoles();\n };\n\n // Helper functions for permission checks\n const hasPermission = (permission: string | Permission): boolean => {\n if (!userPermissions || userPermissions.length === 0) {\n return false;\n }\n\n if (typeof permission === 'string') {\n // userPermissions is now an array of strings in 'resource.action' format\n return userPermissions.includes(permission);\n }\n\n // For Permission objects, convert to string and check\n const permissionString = `${permission.resource}.${permission.action}`;\n return userPermissions.includes(permissionString);\n };\n\n const hasAnyPermission = (permissions: (string | Permission)[]): boolean => {\n return permissions.some(permission => hasPermission(permission));\n };\n\n const hasAllPermissions = (permissions: (string | Permission)[]): boolean => {\n return permissions.every(permission => hasPermission(permission));\n };\n\n // Utility function to get all user permissions in resource.action format\n const getUserPermissionStrings = (): string[] => {\n if (!userPermissions) return [];\n // userPermissions is already an array of strings\n return userPermissions;\n };\n\n return {\n sessionManager,\n authenticatedHttpService,\n login,\n signup,\n signupTenantAdmin,\n changePassword,\n requestPasswordReset,\n confirmPasswordReset,\n refreshToken,\n logout,\n setTokens,\n hasValidSession,\n clearSession,\n currentUser,\n isUserLoading,\n userError,\n refreshUser,\n userRole,\n userPermissions,\n availableRoles,\n rolesLoading,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n getUserPermissionStrings,\n refreshRoles,\n };\n }, [\n sessionManager,\n authenticatedHttpService,\n authApiService,\n userApiService,\n roleApiService,\n appId,\n availableRoles,\n currentUser,\n isUserLoading,\n userError,\n userRole,\n userPermissions,\n ]);\n\n // Fetch roles on mount if not provided via SSR\n useEffect(() => {\n if (!config.initialRoles && appId) {\n const fetchRoles = async () => {\n try {\n setRolesLoading(true);\n const internalHttpService = new HttpService(baseUrl);\n const roleApiService = new RoleApiService(internalHttpService);\n const { roles } = await roleApiService.getRolesByApp(appId);\n setAvailableRoles(roles);\n } catch (error) {\n console.error('Failed to fetch roles:', error);\n } finally {\n setRolesLoading(false);\n }\n };\n\n fetchRoles();\n }\n }, [appId, baseUrl, config.initialRoles]);\n\n // Initialize user data from session on mount\n useEffect(() => {\n const user = sessionManager.getUser();\n if (user && sessionManager.hasValidSession()) {\n setCurrentUser(user);\n }\n }, [sessionManager]);\n\n return <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n ApiResponse,\n FeatureFlagItem,\n FeatureFlagValueResponse,\n FeatureFlag,\n CreateFeatureFlagRequest,\n PaginationParams,\n} from '../types/api';\n\nexport class FeatureFlagApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createFeatureFlag(request: CreateFeatureFlagRequest): Promise<FeatureFlag> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<FeatureFlag>>(\n '/feature-flags/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getFeatureFlags(\n params?: PaginationParams\n ): Promise<{ featureFlags: FeatureFlag[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/feature-flags/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<FeatureFlag[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n featureFlags: response.data,\n meta: response.meta,\n };\n }\n\n async getFeatureFlagById(id: string): Promise<FeatureFlag> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<FeatureFlag>>(`/feature-flags/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updateFeatureFlag(\n id: string,\n request: Partial<CreateFeatureFlagRequest>\n ): Promise<FeatureFlag> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<FeatureFlag>>(\n `/feature-flags/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async deleteFeatureFlag(id: string): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/feature-flags/${id}`, {\n headers: authHeaders,\n });\n }\n\n // Public endpoint - no auth required\n async getTenantFeatureFlags(tenantId: string, appId: string): Promise<FeatureFlagItem[]> {\n if (!tenantId || !appId) {\n throw new Error('Tenant ID and App ID are required');\n }\n\n const queryParams = new URLSearchParams();\n queryParams.append('tenantId', tenantId);\n queryParams.append('appId', appId);\n\n const url = `/tenant-feature-flags${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<FeatureFlagItem[]>>(url, {\n headers: { 'X-Tenant-ID': tenantId },\n });\n\n return response.data;\n }\n\n // Public endpoint - no auth required\n async getTenantFeatureFlag(\n flagKey: string,\n tenantId: string,\n appId: string\n ): Promise<FeatureFlagValueResponse> {\n if (!flagKey || !tenantId || !appId) {\n throw new Error('Flag Key, Tenant ID and App ID are required');\n }\n\n const queryParams = new URLSearchParams();\n queryParams.append('tenantId', tenantId);\n queryParams.append('appId', appId);\n\n const url = `/tenant-feature-flags/${flagKey}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<FeatureFlagValueResponse>>(url, {\n headers: { 'X-Tenant-ID': tenantId },\n });\n\n return response.data;\n }\n}\n","import { createContext, useContext, ReactNode, useMemo, useState, useEffect } from 'react';\nimport { FeatureFlagApiService } from '../services/FeatureFlagApiService';\nimport { HttpService } from '../services/HttpService';\nimport { useApp } from './AppProvider';\nimport { useTenantInfo } from './TenantProvider';\nimport type { FeatureFlagItem } from '../types/api';\n\nexport interface FeatureFlagConfig {\n refreshInterval?: number; // in milliseconds, default 5 minutes\n onError?: (error: Error) => void;\n}\n\nexport interface FeatureFlagContextValue {\n featureFlags: FeatureFlagItem[];\n loading: boolean;\n error: string | null;\n isEnabled: (flagName: string) => boolean;\n getFlag: (flagName: string) => FeatureFlagItem | undefined;\n refresh: () => Promise<void>;\n}\n\nconst FeatureFlagContext = createContext<FeatureFlagContextValue | null>(null);\n\ninterface FeatureFlagProviderProps {\n config?: FeatureFlagConfig;\n children: ReactNode;\n}\n\nexport function FeatureFlagProvider({ config = {}, children }: FeatureFlagProviderProps) {\n const { baseUrl, appId } = useApp();\n const { tenant } = useTenantInfo();\n const [featureFlags, setFeatureFlags] = useState<FeatureFlagItem[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const featureFlagService = useMemo(() => {\n const httpService = new HttpService(baseUrl);\n return new FeatureFlagApiService(httpService);\n }, [baseUrl]);\n\n const fetchFeatureFlags = async () => {\n if (!tenant?.id) {\n setFeatureFlags([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await featureFlagService.getTenantFeatureFlags(tenant.id, appId);\n setFeatureFlags(response);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to fetch feature flags';\n setError(errorMessage);\n if (config.onError) {\n config.onError(err instanceof Error ? err : new Error(errorMessage));\n }\n } finally {\n setLoading(false);\n }\n };\n\n // Initial fetch and setup refresh interval\n useEffect(() => {\n fetchFeatureFlags();\n\n const refreshInterval = config.refreshInterval || 5 * 60 * 1000; // 5 minutes default\n const interval = setInterval(fetchFeatureFlags, refreshInterval);\n\n return () => clearInterval(interval);\n }, [tenant?.id, config.refreshInterval]);\n\n const contextValue = useMemo(() => {\n const isEnabled = (flagKey: string): boolean => {\n const flag = featureFlags.find(f => f.key === flagKey);\n return flag?.value === true;\n };\n\n const getFlag = (flagKey: string): FeatureFlagItem | undefined => {\n return featureFlags.find(f => f.key === flagKey);\n };\n\n const getFlagState = (flagKey: string): 'enabled' | 'disabled' | 'not_found' => {\n const flag = featureFlags.find(f => f.key === flagKey);\n if (!flag) return 'not_found';\n return flag.value ? 'enabled' : 'disabled';\n };\n\n const refresh = async () => {\n await fetchFeatureFlags();\n };\n\n return {\n featureFlags,\n loading,\n error,\n isEnabled,\n getFlag,\n getFlagState,\n refresh,\n };\n }, [featureFlags, loading, error]);\n\n return <FeatureFlagContext.Provider value={contextValue}>{children}</FeatureFlagContext.Provider>;\n}\n\nexport function useFeatureFlags(): FeatureFlagContextValue {\n const context = useContext(FeatureFlagContext);\n if (!context) {\n throw new Error('useFeatureFlags must be used within a FeatureFlagProvider');\n }\n return context;\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Subscription,\n CreateSubscriptionRequest,\n ApiResponse,\n TenantSubscriptionFeatures,\n} from '../types/api';\n\nexport class SubscriptionApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createSubscription(request: CreateSubscriptionRequest): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Subscription>>(\n '/subscriptions/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getSubscriptionById(id: string): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Subscription>>(\n `/subscriptions/subscriptions/${id}`,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async updateSubscription(\n id: string,\n request: Partial<CreateSubscriptionRequest>\n ): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Subscription>>(\n `/subscriptions/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async changeSubscriptionPlan(subscriptionId: string, planId: string): Promise<Subscription> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Subscription>>(\n `/subscriptions/${subscriptionId}/plan`,\n { planId },\n { headers: authHeaders }\n );\n return response.data;\n }\n\n // Public endpoint - no auth required\n async getTenantSubscriptionFeatures(tenantId: string): Promise<TenantSubscriptionFeatures> {\n const response = await this.httpService.get<ApiResponse<TenantSubscriptionFeatures>>(\n `/subscriptions/tenants/${tenantId}/subscription-features`\n );\n return response.data;\n }\n\n async processPayment(subscriptionId: string, paymentData: any): Promise<any> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<any>>(\n `/subscriptions/${subscriptionId}/process-payment`,\n paymentData,\n { headers: authHeaders }\n );\n return response.data;\n }\n}\n","import { createContext, useContext, ReactNode, useMemo, useState, useEffect } from 'react';\nimport { SubscriptionApiService } from '../services/SubscriptionApiService';\nimport { HttpService } from '../services/HttpService';\nimport { useApp } from './AppProvider';\nimport { useTenantInfo } from './TenantProvider';\nimport type { TenantSubscriptionFeatures, PlanFeature } from '../types/api';\n\nexport interface SubscriptionConfig {\n refreshInterval?: number; // in milliseconds, default 10 minutes\n onError?: (error: Error) => void;\n}\n\nexport interface SubscriptionContextValue {\n subscription: TenantSubscriptionFeatures | null;\n features: PlanFeature[];\n loading: boolean;\n error: string | null;\n isFeatureEnabled: (featureKey: string) => boolean;\n getFeature: (featureKey: string) => PlanFeature | undefined;\n getFeatureValue: <T = any>(featureKey: string, defaultValue?: T) => T;\n hasAllowedPlan: (allowedPlans: string[]) => boolean;\n refresh: () => Promise<void>;\n}\n\nexport interface SubscriptionProviderProps {\n config?: SubscriptionConfig;\n children: ReactNode;\n}\n\nconst SubscriptionContext = createContext<SubscriptionContextValue | undefined>(undefined);\n\nexport function SubscriptionProvider({ config = {}, children }: SubscriptionProviderProps) {\n const { baseUrl } = useApp();\n const { tenant } = useTenantInfo();\n const [subscription, setSubscription] = useState<TenantSubscriptionFeatures | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Create subscription service\n const subscriptionService = useMemo(() => {\n const httpService = new HttpService(baseUrl);\n return new SubscriptionApiService(httpService);\n }, [baseUrl]);\n\n const fetchSubscription = async () => {\n if (!tenant?.id) {\n setSubscription(null);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await subscriptionService.getTenantSubscriptionFeatures(tenant.id);\n setSubscription(response);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to fetch subscription';\n setError(errorMessage);\n if (config.onError) {\n config.onError(err instanceof Error ? err : new Error(errorMessage));\n }\n } finally {\n setLoading(false);\n }\n };\n\n // Fetch subscription on mount and when tenant changes\n useEffect(() => {\n fetchSubscription();\n\n // Set up refresh interval if configured\n if (!config.refreshInterval) return;\n\n const refreshInterval = config.refreshInterval || 10 * 60 * 1000; // 10 minutes default\n const interval = setInterval(fetchSubscription, refreshInterval);\n\n return () => clearInterval(interval);\n }, [tenant?.id, config.refreshInterval]);\n\n const contextValue = useMemo(() => {\n const features = subscription?.features || [];\n\n const isFeatureEnabled = (featureKey: string): boolean => {\n const feature = features.find(f => f.key === featureKey);\n if (!feature) return false;\n\n // Handle different feature types\n if (feature.type === 'BOOLEAN' || feature.type === 'boolean') {\n return feature.value === true;\n }\n\n // For non-boolean features, consider them enabled if they have a truthy value\n return Boolean(feature.value);\n };\n\n const getFeature = (featureKey: string): PlanFeature | undefined => {\n return features.find(f => f.key === featureKey);\n };\n\n const getFeatureValue = <T = any,>(featureKey: string, defaultValue?: T): T => {\n const feature = features.find(f => f.key === featureKey);\n return feature ? feature.value : (defaultValue as T);\n };\n\n const hasAllowedPlan = (allowedPlans: string[]): boolean => {\n if (!subscription || !subscription.isActive) return false;\n\n // Check if current plan is in the allowed plans array\n return allowedPlans.includes(subscription.planId);\n };\n\n const refresh = async () => {\n await fetchSubscription();\n };\n\n return {\n subscription,\n features,\n loading,\n error,\n isFeatureEnabled,\n getFeature,\n getFeatureValue,\n hasAllowedPlan,\n refresh,\n };\n }, [subscription, loading, error]);\n\n return (\n <SubscriptionContext.Provider value={contextValue}>{children}</SubscriptionContext.Provider>\n );\n}\n\nexport function useSubscription(): SubscriptionContextValue {\n const context = useContext(SubscriptionContext);\n if (context === undefined) {\n throw new Error('useSubscription must be used within a SubscriptionProvider');\n }\n return context;\n}\n","// Common API Response Types\nexport interface ApiResponse<T> {\n success: boolean;\n message?: string;\n data: T;\n meta?: PaginationMeta;\n}\n\nexport interface ApiError {\n success: false;\n error: {\n code: string;\n };\n message: string;\n type?: 'AUTH' | 'VALIDATION' | 'BUSINESS' | 'SYSTEM';\n}\n\nexport interface PaginationMeta {\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n hasNext: boolean;\n hasPrev: boolean;\n}\n\n// User Types\nexport enum UserType {\n SUPERUSER = 'SUPERUSER',\n TENANT_ADMIN = 'TENANT_ADMIN',\n USER = 'USER',\n}\n\nexport interface User {\n id: string;\n email: string;\n name: string;\n isActive: boolean;\n userType: UserType;\n tenantId: string;\n roleId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateUserRequest {\n email: string;\n name: string;\n password: string;\n tenantId: string;\n userType?: string;\n roleId?: string;\n}\n\n// Auth Types\nexport interface LoginRequest {\n email: string;\n password: string;\n tenantId: string;\n}\n\nexport interface LoginResponse {\n user: User;\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\nexport interface SignupRequest {\n email: string;\n name: string;\n password: string;\n tenantId: string;\n}\n\nexport interface ChangePasswordRequest {\n currentPassword: string;\n newPassword: string;\n}\n\nexport interface RefreshTokenRequest {\n refreshToken: string;\n}\n\nexport interface RefreshTokenResponse {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n// Role Types\nexport interface Role {\n id: string;\n name: string;\n description: string | null;\n appId: string;\n permissions: string[]; // API returns permissions as strings in 'resource.action' format\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateRoleRequest {\n name: string;\n description?: string;\n appId: string;\n permissionIds: string[];\n}\n\nexport interface AssignRoleRequest {\n userId: string;\n}\n\n// Permission Types\nexport interface Permission {\n id: string;\n name: string;\n description: string | null;\n resource: string;\n action: string;\n appId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreatePermissionRequest {\n name: string;\n description?: string;\n resource: string;\n action: string;\n appId?: string;\n}\n\n// App Types\nexport interface App {\n id: string;\n name: string;\n description: string | null;\n securityLevel: 'ADMIN' | 'USER';\n isActive: boolean;\n autoApproveTenants: boolean;\n defaultSubscriptionPlanId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface JSONSchema {\n $schema?: string;\n $id?: string;\n title?: string;\n description?: string;\n type?: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';\n properties?: { [key: string]: JSONSchema };\n items?: JSONSchema;\n required?: string[];\n enum?: unknown[];\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n default?: unknown;\n placeholder?: string;\n additionalProperties?: boolean | JSONSchema;\n}\n\nexport interface PublicAppInfo {\n id: string;\n name: string;\n description: string | null;\n settingsSchema: JSONSchema | null;\n}\n\nexport interface CreateAppRequest {\n name: string;\n description?: string;\n securityLevel?: 'ADMIN' | 'USER';\n}\n\n// Tenant Types\nexport interface Tenant {\n id: string;\n name: string;\n domain: string | null;\n isActive: boolean;\n appId: string;\n settings: Record<string, any>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateTenantRequest {\n name: string;\n domain?: string;\n appId: string;\n settings?: Record<string, any>;\n}\n\nexport interface PublicTenantInfo {\n id: string;\n name: string;\n domain: string | null;\n appId: string;\n}\n\nexport interface TenantSettings {\n [key: string]: any;\n}\n\nexport interface UpdateTenantSettingsRequest {\n settings: TenantSettings;\n}\n\n// Subscription Types\nexport interface Subscription {\n id: string;\n tenantId: string;\n planId: string;\n status: 'ACTIVE' | 'INACTIVE' | 'PENDING' | 'CANCELLED';\n startDate: string;\n endDate: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateSubscriptionRequest {\n tenantId: string;\n planId: string;\n startDate?: string;\n endDate?: string;\n}\n\n// Subscription Plan Types\nexport interface SubscriptionPlan {\n id: string;\n name: string;\n description: string | null;\n price: number;\n currency: string;\n billingCycle: 'MONTHLY' | 'YEARLY';\n appId: string;\n features: SubscriptionFeature[];\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SubscriptionFeature {\n id: string;\n name: string;\n description: string | null;\n featureType: 'BOOLEAN' | 'NUMERIC' | 'TEXT';\n value: any;\n planId: string;\n}\n\nexport interface CreateSubscriptionPlanRequest {\n name: string;\n description?: string;\n price: number;\n currency: string;\n billingCycle: 'MONTHLY' | 'YEARLY';\n appId: string;\n features: CreateSubscriptionFeatureRequest[];\n}\n\nexport interface CreateSubscriptionFeatureRequest {\n name: string;\n description?: string;\n featureType: 'BOOLEAN' | 'NUMERIC' | 'TEXT';\n value: any;\n}\n\n// Feature Flag Types\nexport interface FeatureFlag {\n id: string;\n name: string;\n description: string | null;\n isActive: boolean;\n appId: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateFeatureFlagRequest {\n name: string;\n description?: string;\n appId: string;\n}\n\n// Feature Flag API Response Types\nexport interface FeatureFlagItem {\n featureFlagId: string;\n key: string;\n name: string;\n value: boolean;\n isOverridden: boolean;\n}\n\nexport interface FeatureFlagValueResponse {\n key: string;\n value: boolean;\n}\n\n// Subscription Feature Types\nexport interface PlanFeature {\n key: string;\n name: string;\n type: 'BOOLEAN' | 'NUMBER' | 'STRING' | 'boolean' | 'number' | 'string';\n value: any;\n description?: string;\n}\n\nexport interface TenantSubscriptionFeatures {\n tenantId: string;\n planId: string;\n planName: string;\n subscriptionStatus: string;\n features: PlanFeature[];\n isActive: boolean;\n}\n\n// Common Query Parameters\nexport interface PaginationParams {\n page?: number;\n limit?: number;\n sortBy?: string;\n sortOrder?: 'ASC' | 'DESC';\n}\n","import { ReactNode } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { UserType, Permission } from '../types/api';\n\nexport interface ProtectedProps {\n children: ReactNode;\n fallback?: ReactNode;\n minUserType?: UserType;\n requiredPermissions?: (string | Permission)[];\n requireAllPermissions?: boolean; // If true, user must have ALL permissions. If false, user needs ANY permission\n}\n\nconst DefaultFallback = () => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '20px',\n backgroundColor: '#f8f9fa',\n border: '1px solid #dee2e6',\n borderRadius: '6px',\n textAlign: 'center',\n margin: '20px 0',\n }}\n >\n <div style={{ fontSize: '2rem', marginBottom: '10px' }}>🔒</div>\n <h3 style={{ color: '#495057', marginBottom: '10px' }}>Access Required</h3>\n <p style={{ color: '#6c757d', fontSize: '14px', marginBottom: '15px' }}>\n You need to be signed in to view this content.\n </p>\n <button\n style={{\n padding: '8px 16px',\n backgroundColor: '#007bff',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontSize: '14px',\n }}\n onClick={() => (window.location.href = '/login')}\n >\n Sign In\n </button>\n </div>\n);\n\nconst InsufficientPermissionsFallback = ({\n userType,\n minUserType,\n missingPermissions,\n}: {\n userType?: UserType;\n minUserType?: UserType;\n missingPermissions?: string[];\n}) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '20px',\n backgroundColor: '#fff3cd',\n border: '1px solid #ffeaa7',\n borderRadius: '6px',\n textAlign: 'center',\n margin: '20px 0',\n }}\n >\n <div style={{ fontSize: '2rem', marginBottom: '10px' }}>⚠️</div>\n <h3 style={{ color: '#856404', marginBottom: '10px' }}>Insufficient Permissions</h3>\n {minUserType && userType ? (\n <>\n <p style={{ color: '#856404', fontSize: '14px', marginBottom: '10px' }}>\n This content requires <strong>{minUserType}</strong> access level or higher.\n </p>\n <p style={{ color: '#6c757d', fontSize: '12px' }}>\n Your current access level: <strong>{userType}</strong>\n </p>\n </>\n ) : (\n <>\n <p style={{ color: '#856404', fontSize: '14px', marginBottom: '10px' }}>\n You don't have the required permissions to view this content.\n </p>\n {missingPermissions && missingPermissions.length > 0 && (\n <p style={{ color: '#6c757d', fontSize: '12px' }}>\n Required permissions: <strong>{missingPermissions.join(', ')}</strong>\n </p>\n )}\n </>\n )}\n </div>\n);\n\n// Helper function to check if user type meets minimum requirement\nconst hasMinimumUserType = (userType: UserType, minUserType: UserType): boolean => {\n const hierarchy = {\n [UserType.USER]: 1,\n [UserType.TENANT_ADMIN]: 2,\n [UserType.SUPERUSER]: 3,\n };\n\n return hierarchy[userType] >= hierarchy[minUserType];\n};\n\nexport function Protected({\n children,\n fallback,\n minUserType,\n requiredPermissions,\n requireAllPermissions = false,\n}: ProtectedProps) {\n const { hasValidSession, sessionManager, hasPermission, hasAnyPermission, hasAllPermissions } =\n useAuth();\n\n // Check if user has a valid session\n if (!hasValidSession()) {\n return <>{fallback || <DefaultFallback />}</>;\n }\n\n const user = sessionManager.getUser();\n\n if (!user) {\n // User session exists but no user data - show fallback\n return <>{fallback || <DefaultFallback />}</>;\n }\n\n // Check user type permissions if specified\n if (minUserType && !hasMinimumUserType(user.userType, minUserType)) {\n return <InsufficientPermissionsFallback userType={user.userType} minUserType={minUserType} />;\n }\n\n // Check specific permissions if specified\n if (requiredPermissions && requiredPermissions.length > 0) {\n const hasRequiredPermissions = requireAllPermissions\n ? hasAllPermissions(requiredPermissions)\n : hasAnyPermission(requiredPermissions);\n\n if (!hasRequiredPermissions) {\n // Get missing permissions for better error message\n const missingPermissions = requiredPermissions\n .filter(permission => !hasPermission(permission))\n .map(permission => (typeof permission === 'string' ? permission : permission.name));\n\n return <InsufficientPermissionsFallback missingPermissions={missingPermissions} />;\n }\n }\n\n // User is authenticated and has sufficient permissions\n return <>{children}</>;\n}\n","import { ReactNode } from 'react';\nimport { Navigate, useLocation } from 'react-router';\nimport { useAuth } from '../providers/AuthProvider';\nimport { UserType, Permission } from '../types/api';\n\nexport interface ProtectedRouteProps {\n children: ReactNode;\n redirectTo?: string;\n minUserType?: UserType;\n requiredPermissions?: (string | Permission)[];\n requireAllPermissions?: boolean; // If true, user must have ALL permissions. If false, user needs ANY permission\n fallback?: ReactNode;\n}\n\nconst DefaultFallback = ({ redirectPath }: { redirectPath: string }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '100vh',\n padding: '2rem',\n backgroundColor: '#f9fafb',\n textAlign: 'center',\n }}\n >\n <div\n style={{\n backgroundColor: '#ffffff',\n padding: '2rem',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n maxWidth: '400px',\n }}\n >\n <div style={{ fontSize: '3rem', marginBottom: '1rem' }}>🔒</div>\n <h2 style={{ color: '#374151', marginBottom: '1rem' }}>Access Required</h2>\n <p style={{ color: '#6b7280', marginBottom: '1.5rem' }}>\n You need to be signed in to access this page.\n </p>\n <p style={{ fontSize: '0.875rem', color: '#9ca3af' }}>Redirecting to {redirectPath}...</p>\n </div>\n </div>\n);\n\nconst InsufficientPermissionsFallback = ({\n userType,\n minUserType,\n missingPermissions,\n}: {\n userType?: UserType;\n minUserType?: UserType;\n missingPermissions?: string[];\n}) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '100vh',\n padding: '2rem',\n backgroundColor: '#f9fafb',\n textAlign: 'center',\n }}\n >\n <div\n style={{\n backgroundColor: '#ffffff',\n padding: '2rem',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n maxWidth: '400px',\n }}\n >\n <div style={{ fontSize: '3rem', marginBottom: '1rem' }}>⚠️</div>\n <h2 style={{ color: '#374151', marginBottom: '1rem' }}>Insufficient Permissions</h2>\n {minUserType && userType ? (\n <>\n <p style={{ color: '#6b7280', marginBottom: '1rem' }}>\n This page requires <strong>{minUserType}</strong> access level or higher.\n </p>\n <p style={{ color: '#9ca3af', fontSize: '0.875rem' }}>\n Your current access level: <strong>{userType}</strong>\n </p>\n </>\n ) : (\n <>\n <p style={{ color: '#6b7280', marginBottom: '1rem' }}>\n You don't have the required permissions to access this page.\n </p>\n {missingPermissions && missingPermissions.length > 0 && (\n <p style={{ color: '#9ca3af', fontSize: '0.875rem' }}>\n Required permissions: <strong>{missingPermissions.join(', ')}</strong>\n </p>\n )}\n </>\n )}\n </div>\n </div>\n);\n\n// Helper function to check if user type meets minimum requirement\nconst hasMinimumUserType = (userType: UserType, minUserType: UserType): boolean => {\n const hierarchy = {\n [UserType.USER]: 1,\n [UserType.TENANT_ADMIN]: 2,\n [UserType.SUPERUSER]: 3,\n };\n\n return hierarchy[userType] >= hierarchy[minUserType];\n};\n\nexport function ProtectedRoute({\n children,\n redirectTo = '/login',\n minUserType,\n requiredPermissions,\n requireAllPermissions = false,\n fallback,\n}: ProtectedRouteProps) {\n const { hasValidSession, sessionManager, hasPermission, hasAnyPermission, hasAllPermissions } =\n useAuth();\n const location = useLocation();\n\n // Check if user has a valid session\n if (!hasValidSession()) {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n return (\n <>\n <DefaultFallback redirectPath={redirectTo} />\n <Navigate to={redirectTo} state={{ from: location.pathname }} replace />\n </>\n );\n }\n\n const user = sessionManager.getUser();\n\n if (!user) {\n // User session exists but no user data - redirect to login\n return <Navigate to={redirectTo} state={{ from: location.pathname }} replace />;\n }\n\n // Check user type permissions if specified\n if (minUserType && !hasMinimumUserType(user.userType, minUserType)) {\n return <InsufficientPermissionsFallback userType={user.userType} minUserType={minUserType} />;\n }\n\n // Check specific permissions if specified\n if (requiredPermissions && requiredPermissions.length > 0) {\n const hasRequiredPermissions = requireAllPermissions\n ? hasAllPermissions(requiredPermissions)\n : hasAnyPermission(requiredPermissions);\n\n if (!hasRequiredPermissions) {\n // Get missing permissions for better error message\n const missingPermissions = requiredPermissions\n .filter(permission => !hasPermission(permission))\n .map(permission => (typeof permission === 'string' ? permission : permission.name));\n\n return <InsufficientPermissionsFallback missingPermissions={missingPermissions} />;\n }\n }\n\n // User is authenticated and has sufficient permissions\n return <>{children}</>;\n}\n","import { ReactNode } from 'react';\nimport { useSubscription } from '../providers/SubscriptionProvider';\n\nexport interface SubscriptionGuardProps {\n children: ReactNode;\n fallback?: ReactNode;\n allowedPlans?: string[];\n requiredFeature?: string;\n}\n\nconst DefaultFallback = () => (\n <div\n style={{\n padding: '2rem',\n textAlign: 'center',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '8px',\n color: '#dc2626',\n }}\n >\n <h3 style={{ margin: '0 0 1rem 0' }}>🔒 Subscription Required</h3>\n <p style={{ margin: 0 }}>\n This feature requires a higher subscription plan. Please upgrade your plan to access this\n content.\n </p>\n </div>\n);\n\nexport function SubscriptionGuard({\n children,\n fallback = <DefaultFallback />,\n allowedPlans,\n requiredFeature,\n}: SubscriptionGuardProps) {\n const { subscription, hasAllowedPlan, isFeatureEnabled, loading } = useSubscription();\n\n // Show loading state\n if (loading) {\n return (\n <div\n style={{\n padding: '2rem',\n textAlign: 'center',\n color: '#6b7280',\n }}\n >\n Loading subscription...\n </div>\n );\n }\n\n // No subscription data available\n if (!subscription) {\n return <>{fallback}</>;\n }\n\n // Check if subscription is active\n if (!subscription.isActive) {\n return <>{fallback}</>;\n }\n\n // Check allowed plans requirement\n if (allowedPlans && allowedPlans.length > 0 && !hasAllowedPlan(allowedPlans)) {\n return <>{fallback}</>;\n }\n\n // Check required feature\n if (requiredFeature && !isFeatureEnabled(requiredFeature)) {\n return <>{fallback}</>;\n }\n\n // All checks passed, render children\n return <>{children}</>;\n}\n","import { ReactNode } from 'react';\nimport { useFeatureFlags } from '../providers/FeatureFlagProvider';\n\ninterface FeatureFlagProps {\n name: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\nconst DefaultFallback = ({ flagName }: { flagName: string }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '15px',\n backgroundColor: '#f8f9fa',\n border: '1px solid #dee2e6',\n borderRadius: '6px',\n textAlign: 'center',\n fontFamily: 'system-ui, sans-serif',\n color: '#6c757d',\n }}\n >\n <div style={{ fontSize: '24px', marginBottom: '8px' }}>🚧</div>\n <div style={{ fontSize: '14px', fontWeight: '500', marginBottom: '4px' }}>\n Feature Not Available\n </div>\n <div style={{ fontSize: '12px', opacity: 0.7 }}>Feature flag \"{flagName}\" is disabled</div>\n </div>\n);\n\nexport function FeatureFlag({ name, children, fallback }: FeatureFlagProps) {\n const { isEnabled, loading } = useFeatureFlags();\n\n // Show loading state while fetching feature flags\n if (loading) {\n return (\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '10px',\n color: '#6c757d',\n fontSize: '14px',\n }}\n >\n Loading feature flags...\n </div>\n );\n }\n\n console.log(name, isEnabled(name));\n // Show children if feature flag is enabled\n if (isEnabled(name)) {\n return <>{children}</>;\n }\n\n // Show fallback if provided, otherwise show default fallback\n return <>{fallback || <DefaultFallback flagName={name} />}</>;\n}\n","import React, { useState } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { useTenantInfo } from '../providers/TenantProvider';\n\nexport interface LoginFormCopy {\n title?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n passwordLabel?: string;\n passwordPlaceholder?: string;\n submitButton?: string;\n forgotPasswordLink?: string;\n signupLink?: string;\n signupText?: string;\n errorMessage?: string;\n loadingText?: string;\n}\n\nexport interface LoginFormStyles {\n container?: React.CSSProperties;\n title?: React.CSSProperties;\n form?: React.CSSProperties;\n fieldGroup?: React.CSSProperties;\n label?: React.CSSProperties;\n input?: React.CSSProperties;\n inputError?: React.CSSProperties;\n inputContainer?: React.CSSProperties;\n passwordToggle?: React.CSSProperties;\n button?: React.CSSProperties;\n buttonDisabled?: React.CSSProperties;\n buttonLoading?: React.CSSProperties;\n errorText?: React.CSSProperties;\n linkContainer?: React.CSSProperties;\n link?: React.CSSProperties;\n divider?: React.CSSProperties;\n}\n\nexport interface LoginFormIcons {\n showPassword?: React.ReactNode;\n hidePassword?: React.ReactNode;\n}\n\nexport interface LoginFormProps {\n copy?: LoginFormCopy;\n styles?: LoginFormStyles;\n icons?: LoginFormIcons;\n onSuccess?: (data: any) => void;\n onError?: (error: string) => void;\n onForgotPassword?: () => void;\n onSignupClick?: () => void;\n showForgotPassword?: boolean;\n showSignupLink?: boolean;\n className?: string;\n}\n\n// Default SVG icons for password toggle\nconst EyeIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ flexShrink: 0 }}\n >\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n);\n\nconst EyeOffIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ flexShrink: 0 }}\n >\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\" />\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n </svg>\n);\n\nconst defaultIcons: Required<LoginFormIcons> = {\n showPassword: <EyeIcon />,\n hidePassword: <EyeOffIcon />,\n};\n\nconst defaultCopy: Required<LoginFormCopy> = {\n title: 'Sign In',\n emailLabel: 'Email',\n emailPlaceholder: 'Enter your email',\n passwordLabel: 'Password',\n passwordPlaceholder: 'Enter your password',\n submitButton: 'Sign In',\n forgotPasswordLink: 'Forgot your password?',\n signupLink: 'Sign up here',\n signupText: \"Don't have an account?\",\n errorMessage: 'Invalid email or password',\n loadingText: 'Signing in...',\n};\n\nconst defaultStyles: Required<LoginFormStyles> = {\n container: {\n maxWidth: '400px',\n width: '100%',\n margin: '0 auto',\n padding: '2rem',\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 'bold',\n textAlign: 'center',\n marginBottom: '1.5rem',\n color: '#333333',\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n },\n fieldGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.75rem',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n fontSize: '1rem',\n transition: 'border-color 0.15s ease-in-out',\n outline: 'none',\n width: '100%',\n },\n inputError: {\n borderColor: '#ef4444',\n boxShadow: '0 0 0 3px rgba(239, 68, 68, 0.1)',\n },\n inputContainer: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n },\n passwordToggle: {\n position: 'absolute',\n right: '0.75rem',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: '0.25rem',\n color: '#6b7280',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n borderRadius: '4px',\n transition: 'background-color 0.15s ease-in-out',\n },\n button: {\n padding: '0.75rem 1rem',\n backgroundColor: '#3b82f6',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n fontSize: '1rem',\n fontWeight: '500',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n marginTop: '0.5rem',\n },\n buttonDisabled: {\n backgroundColor: '#9ca3af',\n cursor: 'not-allowed',\n },\n buttonLoading: {\n backgroundColor: '#6b7280',\n },\n errorText: {\n color: '#ef4444',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n linkContainer: {\n textAlign: 'center',\n marginTop: '1rem',\n },\n link: {\n color: '#3b82f6',\n textDecoration: 'none',\n fontSize: '0.875rem',\n cursor: 'pointer',\n },\n divider: {\n margin: '0.5rem 0',\n color: '#6b7280',\n fontSize: '0.875rem',\n },\n};\n\nexport function LoginForm({\n copy = {},\n styles = {},\n icons = {},\n onSuccess,\n onError,\n onForgotPassword,\n onSignupClick,\n showForgotPassword = true,\n showSignupLink = true,\n className,\n}: LoginFormProps) {\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [showPassword, setShowPassword] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [fieldErrors, setFieldErrors] = useState<{ email?: boolean; password?: boolean }>({});\n\n const { login } = useAuth();\n const { tenant } = useTenantInfo();\n\n const mergedCopy = { ...defaultCopy, ...copy };\n const mergedStyles = { ...defaultStyles, ...styles };\n const mergedIcons = { ...defaultIcons, ...icons };\n\n const validateForm = () => {\n const errors: { email?: boolean; password?: boolean } = {};\n\n if (!email.trim()) errors.email = true;\n if (!password.trim()) errors.password = true;\n\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateForm()) return;\n if (!tenant?.id) {\n setError('Tenant not found');\n return;\n }\n\n setLoading(true);\n setError('');\n\n try {\n const result = await login(email, password, tenant.id);\n onSuccess?.(result);\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const getInputStyle = (field: 'email' | 'password') => ({\n ...mergedStyles.input,\n ...(fieldErrors[field] ? mergedStyles.inputError : {}),\n });\n\n const getButtonStyle = () => ({\n ...mergedStyles.button,\n ...(loading ? mergedStyles.buttonLoading : {}),\n ...(!email || !password || loading ? mergedStyles.buttonDisabled : {}),\n });\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.title}</h2>\n\n <form onSubmit={handleSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.emailLabel}</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={e => {\n setEmail(e.target.value);\n if (fieldErrors.email) {\n setFieldErrors(prev => ({ ...prev, email: false }));\n }\n }}\n placeholder={mergedCopy.emailPlaceholder}\n style={getInputStyle('email')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.passwordLabel}</label>\n <div style={mergedStyles.inputContainer}>\n <input\n id=\"password\"\n name=\"password\"\n type={showPassword ? 'text' : 'password'}\n value={password}\n onChange={e => {\n setPassword(e.target.value);\n if (fieldErrors.password) {\n setFieldErrors(prev => ({ ...prev, password: false }));\n }\n }}\n placeholder={mergedCopy.passwordPlaceholder}\n style={{\n ...getInputStyle('password'),\n paddingRight: '2.5rem', // Make room for the icon\n }}\n disabled={loading}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword(!showPassword)}\n style={mergedStyles.passwordToggle}\n disabled={loading}\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n >\n {showPassword ? mergedIcons.hidePassword : mergedIcons.showPassword}\n </button>\n </div>\n </div>\n\n <button type=\"submit\" disabled={!email || !password || loading} style={getButtonStyle()}>\n {loading ? mergedCopy.loadingText : mergedCopy.submitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n </form>\n\n {(showForgotPassword || showSignupLink) && (\n <div style={mergedStyles.linkContainer}>\n {showForgotPassword && (\n <a onClick={onForgotPassword} style={mergedStyles.link}>\n {mergedCopy.forgotPasswordLink}\n </a>\n )}\n\n {showForgotPassword && showSignupLink && <div style={mergedStyles.divider}>•</div>}\n\n {showSignupLink && (\n <div>\n <span style={mergedStyles.divider}>{mergedCopy.signupText} </span>\n <a onClick={onSignupClick} style={mergedStyles.link}>\n {mergedCopy.signupLink}\n </a>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { useTenantInfo } from '../providers/TenantProvider';\n\nexport interface SignupFormCopy {\n title?: string;\n nameLabel?: string;\n namePlaceholder?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n passwordLabel?: string;\n passwordPlaceholder?: string;\n confirmPasswordLabel?: string;\n confirmPasswordPlaceholder?: string;\n tenantNameLabel?: string;\n tenantNamePlaceholder?: string;\n submitButton?: string;\n loginLink?: string;\n loginText?: string;\n errorMessage?: string;\n loadingText?: string;\n passwordMismatchError?: string;\n isAdminLabel?: string;\n isAdminDescription?: string;\n}\n\nexport interface SignupFormStyles {\n container?: React.CSSProperties;\n title?: React.CSSProperties;\n form?: React.CSSProperties;\n fieldGroup?: React.CSSProperties;\n label?: React.CSSProperties;\n input?: React.CSSProperties;\n inputError?: React.CSSProperties;\n checkbox?: React.CSSProperties;\n checkboxContainer?: React.CSSProperties;\n checkboxLabel?: React.CSSProperties;\n button?: React.CSSProperties;\n buttonDisabled?: React.CSSProperties;\n buttonLoading?: React.CSSProperties;\n errorText?: React.CSSProperties;\n linkContainer?: React.CSSProperties;\n link?: React.CSSProperties;\n divider?: React.CSSProperties;\n}\n\nexport type SignupType = 'user' | 'tenant';\n\nexport interface SignupFormProps {\n copy?: SignupFormCopy;\n styles?: SignupFormStyles;\n signupType?: SignupType;\n onSuccess?: (data: any) => void;\n onError?: (error: string) => void;\n onLoginClick?: () => void;\n showLoginLink?: boolean;\n className?: string;\n}\n\nconst defaultCopy: Required<SignupFormCopy> = {\n title: 'Create Account',\n nameLabel: 'Full Name',\n namePlaceholder: 'Enter your full name',\n emailLabel: 'Email',\n emailPlaceholder: 'Enter your email',\n passwordLabel: 'Password',\n passwordPlaceholder: 'Enter your password',\n confirmPasswordLabel: 'Confirm Password',\n confirmPasswordPlaceholder: 'Confirm your password',\n tenantNameLabel: 'Organization Name',\n tenantNamePlaceholder: 'Enter your organization name',\n submitButton: 'Create Account',\n loginLink: 'Sign in here',\n loginText: 'Already have an account?',\n errorMessage: 'Failed to create account',\n loadingText: 'Creating account...',\n passwordMismatchError: 'Passwords do not match',\n isAdminLabel: 'Create new organization',\n isAdminDescription: 'Check this if you want to create a new organization',\n};\n\nconst defaultStyles: Required<SignupFormStyles> = {\n container: {\n maxWidth: '400px',\n width: '100%',\n margin: '0 auto',\n padding: '2rem',\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 'bold',\n textAlign: 'center',\n marginBottom: '1.5rem',\n color: '#333333',\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n },\n fieldGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.75rem',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n fontSize: '1rem',\n transition: 'border-color 0.15s ease-in-out',\n outline: 'none',\n },\n inputError: {\n borderColor: '#ef4444',\n boxShadow: '0 0 0 3px rgba(239, 68, 68, 0.1)',\n },\n checkbox: {\n marginRight: '0.5rem',\n },\n checkboxContainer: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '0.5rem',\n padding: '0.5rem 0',\n },\n checkboxLabel: {\n fontSize: '0.875rem',\n color: '#374151',\n lineHeight: '1.4',\n },\n button: {\n padding: '0.75rem 1rem',\n backgroundColor: '#10b981',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n fontSize: '1rem',\n fontWeight: '500',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n marginTop: '0.5rem',\n },\n buttonDisabled: {\n backgroundColor: '#9ca3af',\n cursor: 'not-allowed',\n },\n buttonLoading: {\n backgroundColor: '#6b7280',\n },\n errorText: {\n color: '#ef4444',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n linkContainer: {\n textAlign: 'center',\n marginTop: '1rem',\n },\n link: {\n color: '#3b82f6',\n textDecoration: 'none',\n fontSize: '0.875rem',\n cursor: 'pointer',\n },\n divider: {\n margin: '0.5rem 0',\n color: '#6b7280',\n fontSize: '0.875rem',\n },\n};\n\nexport function SignupForm({\n copy = {},\n styles = {},\n signupType = 'user',\n onSuccess,\n onError,\n onLoginClick,\n showLoginLink = true,\n className,\n}: SignupFormProps) {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [tenantName, setTenantName] = useState('');\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [fieldErrors, setFieldErrors] = useState<{\n name?: boolean;\n email?: boolean;\n password?: boolean;\n confirmPassword?: boolean;\n tenantName?: boolean;\n }>({});\n\n const { signup, signupTenantAdmin } = useAuth();\n const { tenant } = useTenantInfo();\n\n const mergedCopy = { ...defaultCopy, ...copy };\n const mergedStyles = { ...defaultStyles, ...styles };\n\n const validateForm = () => {\n const errors: {\n name?: boolean;\n email?: boolean;\n password?: boolean;\n confirmPassword?: boolean;\n tenantName?: boolean;\n } = {};\n\n if (!name.trim()) errors.name = true;\n if (!email.trim()) errors.email = true;\n if (!password.trim()) errors.password = true;\n if (!confirmPassword.trim()) errors.confirmPassword = true;\n if (signupType === 'tenant' && !tenantName.trim()) errors.tenantName = true;\n\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateForm()) return;\n\n if (password !== confirmPassword) {\n setError(mergedCopy.passwordMismatchError);\n setFieldErrors({ confirmPassword: true });\n return;\n }\n\n if (signupType === 'user' && !tenant?.id) {\n setError('Tenant not found');\n return;\n }\n\n setLoading(true);\n setError('');\n\n try {\n let result;\n if (signupType === 'tenant') {\n result = await signupTenantAdmin(email, name, password, tenantName);\n } else {\n result = await signup(email, name, password, tenant!.id);\n }\n onSuccess?.(result);\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const getInputStyle = (field: keyof typeof fieldErrors) => ({\n ...mergedStyles.input,\n ...(fieldErrors[field] ? mergedStyles.inputError : {}),\n });\n\n const getButtonStyle = () => ({\n ...mergedStyles.button,\n ...(loading ? mergedStyles.buttonLoading : {}),\n ...(!name ||\n !email ||\n !password ||\n !confirmPassword ||\n loading ||\n (signupType === 'tenant' && !tenantName)\n ? mergedStyles.buttonDisabled\n : {}),\n });\n\n const isFormValid =\n name && email && password && confirmPassword && (signupType === 'user' || tenantName);\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.title}</h2>\n\n <form onSubmit={handleSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.nameLabel}</label>\n <input\n id=\"name\"\n name=\"name\"\n type=\"text\"\n value={name}\n onChange={e => {\n setName(e.target.value);\n if (fieldErrors.name) {\n setFieldErrors(prev => ({ ...prev, name: false }));\n }\n }}\n placeholder={mergedCopy.namePlaceholder}\n style={getInputStyle('name')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.emailLabel}</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={e => {\n setEmail(e.target.value);\n if (fieldErrors.email) {\n setFieldErrors(prev => ({ ...prev, email: false }));\n }\n }}\n placeholder={mergedCopy.emailPlaceholder}\n style={getInputStyle('email')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.passwordLabel}</label>\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n value={password}\n onChange={e => {\n setPassword(e.target.value);\n if (fieldErrors.password) {\n setFieldErrors(prev => ({ ...prev, password: false }));\n }\n }}\n placeholder={mergedCopy.passwordPlaceholder}\n style={getInputStyle('password')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.confirmPasswordLabel}</label>\n <input\n id=\"confirmPassword\"\n name=\"confirmPassword\"\n type=\"password\"\n value={confirmPassword}\n onChange={e => {\n setConfirmPassword(e.target.value);\n if (fieldErrors.confirmPassword) {\n setFieldErrors(prev => ({ ...prev, confirmPassword: false }));\n }\n if (error === mergedCopy.passwordMismatchError) {\n setError('');\n }\n }}\n placeholder={mergedCopy.confirmPasswordPlaceholder}\n style={getInputStyle('confirmPassword')}\n disabled={loading}\n />\n </div>\n\n {signupType === 'tenant' && (\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.tenantNameLabel}</label>\n <input\n id=\"tenantName\"\n name=\"tenantName\"\n type=\"text\"\n value={tenantName}\n onChange={e => {\n setTenantName(e.target.value);\n if (fieldErrors.tenantName) {\n setFieldErrors(prev => ({ ...prev, tenantName: false }));\n }\n }}\n placeholder={mergedCopy.tenantNamePlaceholder}\n style={getInputStyle('tenantName')}\n disabled={loading}\n />\n </div>\n )}\n\n <button type=\"submit\" disabled={!isFormValid || loading} style={getButtonStyle()}>\n {loading ? mergedCopy.loadingText : mergedCopy.submitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n </form>\n\n {showLoginLink && (\n <div style={mergedStyles.linkContainer}>\n <span style={mergedStyles.divider}>{mergedCopy.loginText} </span>\n <a onClick={onLoginClick} style={mergedStyles.link}>\n {mergedCopy.loginLink}\n </a>\n </div>\n )}\n </div>\n );\n}\n","import React, { useState } from 'react';\nimport { useAuth } from '../providers/AuthProvider';\nimport { useTenantInfo } from '../providers/TenantProvider';\n\nexport interface PasswordRecoveryFormCopy {\n title?: string;\n subtitle?: string;\n emailLabel?: string;\n emailPlaceholder?: string;\n submitButton?: string;\n backToLoginLink?: string;\n successMessage?: string;\n errorMessage?: string;\n loadingText?: string;\n // Reset form copy\n resetTitle?: string;\n resetSubtitle?: string;\n tokenLabel?: string;\n tokenPlaceholder?: string;\n newPasswordLabel?: string;\n newPasswordPlaceholder?: string;\n confirmPasswordLabel?: string;\n confirmPasswordPlaceholder?: string;\n resetSubmitButton?: string;\n resetLoadingText?: string;\n resetSuccessMessage?: string;\n passwordMismatchError?: string;\n}\n\nexport interface PasswordRecoveryFormStyles {\n container?: React.CSSProperties;\n title?: React.CSSProperties;\n subtitle?: React.CSSProperties;\n form?: React.CSSProperties;\n fieldGroup?: React.CSSProperties;\n label?: React.CSSProperties;\n input?: React.CSSProperties;\n inputError?: React.CSSProperties;\n button?: React.CSSProperties;\n buttonDisabled?: React.CSSProperties;\n buttonLoading?: React.CSSProperties;\n errorText?: React.CSSProperties;\n successText?: React.CSSProperties;\n linkContainer?: React.CSSProperties;\n link?: React.CSSProperties;\n}\n\nexport interface PasswordRecoveryFormProps {\n copy?: PasswordRecoveryFormCopy;\n styles?: PasswordRecoveryFormStyles;\n mode?: 'request' | 'reset';\n token?: string;\n onSuccess?: (data?: any) => void;\n onError?: (error: string) => void;\n onBackToLogin?: () => void;\n onModeChange?: (mode: 'request' | 'reset') => void;\n className?: string;\n}\n\nconst defaultCopy: Required<PasswordRecoveryFormCopy> = {\n title: 'Reset Password',\n subtitle: \"Enter your email address and we'll send you a link to reset your password.\",\n emailLabel: 'Email',\n emailPlaceholder: 'Enter your email',\n submitButton: 'Send Reset Link',\n backToLoginLink: 'Back to Sign In',\n successMessage: 'Password reset link sent! Check your email.',\n errorMessage: 'Failed to send reset link',\n loadingText: 'Sending...',\n resetTitle: 'Set New Password',\n resetSubtitle: 'Enter your reset token and new password.',\n tokenLabel: 'Reset Token',\n tokenPlaceholder: 'Enter reset token from email',\n newPasswordLabel: 'New Password',\n newPasswordPlaceholder: 'Enter new password',\n confirmPasswordLabel: 'Confirm Password',\n confirmPasswordPlaceholder: 'Confirm new password',\n resetSubmitButton: 'Reset Password',\n resetLoadingText: 'Resetting...',\n resetSuccessMessage: 'Password reset successfully!',\n passwordMismatchError: 'Passwords do not match',\n};\n\nconst defaultStyles: Required<PasswordRecoveryFormStyles> = {\n container: {\n maxWidth: '400px',\n margin: '0 auto',\n padding: '2rem',\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.1)',\n },\n title: {\n fontSize: '1.5rem',\n fontWeight: 'bold',\n textAlign: 'center',\n marginBottom: '0.5rem',\n color: '#333333',\n },\n subtitle: {\n fontSize: '0.875rem',\n textAlign: 'center',\n marginBottom: '1.5rem',\n color: '#6b7280',\n lineHeight: '1.4',\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n },\n fieldGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n },\n label: {\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#374151',\n },\n input: {\n padding: '0.75rem',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n fontSize: '1rem',\n transition: 'border-color 0.15s ease-in-out',\n outline: 'none',\n },\n inputError: {\n borderColor: '#ef4444',\n boxShadow: '0 0 0 3px rgba(239, 68, 68, 0.1)',\n },\n button: {\n padding: '0.75rem 1rem',\n backgroundColor: '#f59e0b',\n color: 'white',\n border: 'none',\n borderRadius: '6px',\n fontSize: '1rem',\n fontWeight: '500',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n marginTop: '0.5rem',\n },\n buttonDisabled: {\n backgroundColor: '#9ca3af',\n cursor: 'not-allowed',\n },\n buttonLoading: {\n backgroundColor: '#6b7280',\n },\n errorText: {\n color: '#ef4444',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n successText: {\n color: '#10b981',\n fontSize: '0.875rem',\n textAlign: 'center',\n marginTop: '0.5rem',\n },\n linkContainer: {\n textAlign: 'center',\n marginTop: '1rem',\n },\n link: {\n color: '#3b82f6',\n textDecoration: 'none',\n fontSize: '0.875rem',\n cursor: 'pointer',\n },\n};\n\nexport function PasswordRecoveryForm({\n copy = {},\n styles = {},\n mode = 'request',\n token: initialToken = '',\n onSuccess,\n onError,\n onBackToLogin,\n onModeChange,\n className,\n}: PasswordRecoveryFormProps) {\n const [email, setEmail] = useState('');\n const [token, setToken] = useState(initialToken);\n const [newPassword, setNewPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [success, setSuccess] = useState('');\n const [fieldErrors, setFieldErrors] = useState<{\n email?: boolean;\n token?: boolean;\n newPassword?: boolean;\n confirmPassword?: boolean;\n }>({});\n\n const { requestPasswordReset, confirmPasswordReset } = useAuth();\n const { tenant } = useTenantInfo();\n\n const mergedCopy = { ...defaultCopy, ...copy };\n const mergedStyles = { ...defaultStyles, ...styles };\n\n const validateRequestForm = () => {\n const errors: { email?: boolean } = {};\n if (!email.trim()) errors.email = true;\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const validateResetForm = () => {\n const errors: { token?: boolean; newPassword?: boolean; confirmPassword?: boolean } = {};\n if (!token.trim()) errors.token = true;\n if (!newPassword.trim()) errors.newPassword = true;\n if (!confirmPassword.trim()) errors.confirmPassword = true;\n setFieldErrors(errors);\n return Object.keys(errors).length === 0;\n };\n\n const handleRequestSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateRequestForm()) return;\n if (!tenant?.id) {\n setError('Tenant not found');\n return;\n }\n\n setLoading(true);\n setError('');\n setSuccess('');\n\n try {\n await requestPasswordReset(email, tenant.id);\n setSuccess(mergedCopy.successMessage);\n onSuccess?.();\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const handleResetSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validateResetForm()) return;\n\n if (newPassword !== confirmPassword) {\n setError(mergedCopy.passwordMismatchError);\n setFieldErrors({ confirmPassword: true });\n return;\n }\n\n setLoading(true);\n setError('');\n setSuccess('');\n\n try {\n await confirmPasswordReset(token, newPassword);\n setSuccess(mergedCopy.resetSuccessMessage);\n onSuccess?.();\n } catch (err: any) {\n const errorMessage = err.message || mergedCopy.errorMessage;\n setError(errorMessage);\n onError?.(errorMessage);\n } finally {\n setLoading(false);\n }\n };\n\n const getInputStyle = (field: keyof typeof fieldErrors) => ({\n ...mergedStyles.input,\n ...(fieldErrors[field] ? mergedStyles.inputError : {}),\n });\n\n const getButtonStyle = () => ({\n ...mergedStyles.button,\n ...(loading ? mergedStyles.buttonLoading : {}),\n });\n\n if (mode === 'reset') {\n const isFormValid = token && newPassword && confirmPassword;\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.resetTitle}</h2>\n <p style={mergedStyles.subtitle}>{mergedCopy.resetSubtitle}</p>\n\n <form onSubmit={handleResetSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.tokenLabel}</label>\n <input\n type=\"text\"\n value={token}\n onChange={e => {\n setToken(e.target.value);\n if (fieldErrors.token) {\n setFieldErrors(prev => ({ ...prev, token: false }));\n }\n }}\n placeholder={mergedCopy.tokenPlaceholder}\n style={getInputStyle('token')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.newPasswordLabel}</label>\n <input\n type=\"password\"\n value={newPassword}\n onChange={e => {\n setNewPassword(e.target.value);\n if (fieldErrors.newPassword) {\n setFieldErrors(prev => ({ ...prev, newPassword: false }));\n }\n }}\n placeholder={mergedCopy.newPasswordPlaceholder}\n style={getInputStyle('newPassword')}\n disabled={loading}\n />\n </div>\n\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.confirmPasswordLabel}</label>\n <input\n type=\"password\"\n value={confirmPassword}\n onChange={e => {\n setConfirmPassword(e.target.value);\n if (fieldErrors.confirmPassword) {\n setFieldErrors(prev => ({ ...prev, confirmPassword: false }));\n }\n if (error === mergedCopy.passwordMismatchError) {\n setError('');\n }\n }}\n placeholder={mergedCopy.confirmPasswordPlaceholder}\n style={getInputStyle('confirmPassword')}\n disabled={loading}\n />\n </div>\n\n <button\n type=\"submit\"\n disabled={!isFormValid || loading}\n style={{\n ...getButtonStyle(),\n ...(!isFormValid || loading ? mergedStyles.buttonDisabled : {}),\n }}\n >\n {loading ? mergedCopy.resetLoadingText : mergedCopy.resetSubmitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n {success && <div style={mergedStyles.successText}>{success}</div>}\n </form>\n\n <div style={mergedStyles.linkContainer}>\n <a onClick={onBackToLogin} style={mergedStyles.link}>\n {mergedCopy.backToLoginLink}\n </a>\n {onModeChange && (\n <>\n <span style={{ margin: '0 0.5rem', color: '#6b7280' }}>•</span>\n <a onClick={() => onModeChange('request')} style={mergedStyles.link}>\n Request New Link\n </a>\n </>\n )}\n </div>\n </div>\n );\n }\n\n // Request mode\n const isFormValid = email;\n\n return (\n <div className={className} style={mergedStyles.container}>\n <h2 style={mergedStyles.title}>{mergedCopy.title}</h2>\n <p style={mergedStyles.subtitle}>{mergedCopy.subtitle}</p>\n\n <form onSubmit={handleRequestSubmit} style={mergedStyles.form}>\n <div style={mergedStyles.fieldGroup}>\n <label style={mergedStyles.label}>{mergedCopy.emailLabel}</label>\n <input\n type=\"email\"\n value={email}\n onChange={e => {\n setEmail(e.target.value);\n if (fieldErrors.email) {\n setFieldErrors(prev => ({ ...prev, email: false }));\n }\n }}\n placeholder={mergedCopy.emailPlaceholder}\n style={getInputStyle('email')}\n disabled={loading}\n />\n </div>\n\n <button\n type=\"submit\"\n disabled={!isFormValid || loading}\n style={{\n ...getButtonStyle(),\n ...(!isFormValid || loading ? mergedStyles.buttonDisabled : {}),\n }}\n >\n {loading ? mergedCopy.loadingText : mergedCopy.submitButton}\n </button>\n\n {error && <div style={mergedStyles.errorText}>{error}</div>}\n {success && <div style={mergedStyles.successText}>{success}</div>}\n </form>\n\n <div style={mergedStyles.linkContainer}>\n <a onClick={onBackToLogin} style={mergedStyles.link}>\n {mergedCopy.backToLoginLink}\n </a>\n {onModeChange && (\n <>\n <span style={{ margin: '0 0.5rem', color: '#6b7280' }}>•</span>\n <a onClick={() => onModeChange('reset')} style={mergedStyles.link}>\n I have a token\n </a>\n </>\n )}\n </div>\n </div>\n );\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n Permission,\n CreatePermissionRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class PermissionApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager?: SessionManager\n ) {}\n\n async createPermission(request: CreatePermissionRequest): Promise<Permission> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<Permission>>(\n '/permissions/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getPermissions(\n params?: PaginationParams\n ): Promise<{ permissions: Permission[]; meta: any }> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/permissions/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Permission[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n permissions: response.data,\n meta: response.meta,\n };\n }\n\n async getPermissionById(id: string): Promise<Permission> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<Permission>>(`/permissions/${id}`, {\n headers: authHeaders,\n });\n return response.data;\n }\n\n async updatePermission(\n id: string,\n request: Partial<CreatePermissionRequest>\n ): Promise<Permission> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<Permission>>(\n `/permissions/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async deletePermission(id: string): Promise<void> {\n if (!this.sessionManager) {\n throw new Error('SessionManager is required for private endpoints');\n }\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/permissions/${id}`, {\n headers: authHeaders,\n });\n }\n\n // Public endpoint - no auth required\n async getAppPermissions(\n appId: string,\n params?: PaginationParams\n ): Promise<{ permissions: Permission[]; meta: any }> {\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n\n const url = `/permissions/apps/${appId}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<Permission[]>>(url);\n\n return {\n permissions: response.data,\n meta: response.meta,\n };\n }\n}\n","import { HttpService } from './HttpService';\nimport { SessionManager } from './SessionManager';\nimport type {\n SubscriptionPlan,\n CreateSubscriptionPlanRequest,\n ApiResponse,\n PaginationParams,\n} from '../types/api';\n\nexport class SubscriptionPlanApiService {\n constructor(\n private httpService: HttpService,\n private sessionManager: SessionManager\n ) {}\n\n async createSubscriptionPlan(request: CreateSubscriptionPlanRequest): Promise<SubscriptionPlan> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.post<ApiResponse<SubscriptionPlan>>(\n '/subscription-plans/',\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async getSubscriptionPlans(\n params?: PaginationParams & { appId?: string }\n ): Promise<{ plans: SubscriptionPlan[]; meta: any }> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const queryParams = new URLSearchParams();\n\n if (params?.page) queryParams.append('page', params.page.toString());\n if (params?.limit) queryParams.append('limit', params.limit.toString());\n if (params?.sortBy) queryParams.append('sortBy', params.sortBy);\n if (params?.sortOrder) queryParams.append('sortOrder', params.sortOrder);\n if (params?.appId) queryParams.append('appId', params.appId);\n\n const url = `/subscription-plans/${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.httpService.get<ApiResponse<SubscriptionPlan[]>>(url, {\n headers: authHeaders,\n });\n\n return {\n plans: response.data,\n meta: response.meta,\n };\n }\n\n async getSubscriptionPlanById(id: string): Promise<SubscriptionPlan> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.get<ApiResponse<SubscriptionPlan>>(\n `/subscription-plans/${id}`,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async updateSubscriptionPlan(\n id: string,\n request: Partial<CreateSubscriptionPlanRequest>\n ): Promise<SubscriptionPlan> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n const response = await this.httpService.put<ApiResponse<SubscriptionPlan>>(\n `/subscription-plans/${id}`,\n request,\n {\n headers: authHeaders,\n }\n );\n return response.data;\n }\n\n async deleteSubscriptionPlan(id: string): Promise<void> {\n const authHeaders = await this.sessionManager.getAuthHeaders();\n await this.httpService.delete<void>(`/subscription-plans/${id}`, {\n headers: authHeaders,\n });\n }\n}\n","import { HttpService } from './HttpService';\n\nexport class HealthApiService {\n constructor(private httpService: HttpService) {}\n\n // Public endpoint - no auth required\n async checkHealth(): Promise<{ status: string }> {\n return await this.httpService.get<{ status: string }>('/health');\n }\n}\n","// Data transformation utilities for API responses\n\nexport class ApiMappers {\n // Date string to Date object\n static toDate(dateString: string): Date {\n return new Date(dateString);\n }\n\n // Date object to ISO string\n static toISOString(date: Date): string {\n return date.toISOString();\n }\n\n // Transform API response pagination meta\n static transformPaginationMeta(meta: any) {\n return {\n total: meta.total || 0,\n page: meta.page || 1,\n limit: meta.limit || 100,\n totalPages: meta.totalPages || 1,\n hasNext: meta.hasNext || false,\n hasPrev: meta.hasPrev || false,\n };\n }\n\n // Transform user data for display\n static transformUser(user: any) {\n return {\n ...user,\n createdAt: this.toDate(user.createdAt),\n updatedAt: this.toDate(user.updatedAt),\n displayName: user.name,\n isActiveUser: user.isActive,\n };\n }\n\n // Transform role data for display\n static transformRole(role: any) {\n return {\n ...role,\n createdAt: this.toDate(role.createdAt),\n updatedAt: this.toDate(role.updatedAt),\n permissionCount: role.permissions?.length || 0,\n };\n }\n\n // Transform tenant data for display\n static transformTenant(tenant: any) {\n return {\n ...tenant,\n createdAt: this.toDate(tenant.createdAt),\n updatedAt: this.toDate(tenant.updatedAt),\n displayName: tenant.name,\n hasCustomDomain: !!tenant.domain,\n };\n }\n\n // Transform subscription data for display\n static transformSubscription(subscription: any) {\n return {\n ...subscription,\n createdAt: this.toDate(subscription.createdAt),\n updatedAt: this.toDate(subscription.updatedAt),\n startDate: this.toDate(subscription.startDate),\n endDate: subscription.endDate ? this.toDate(subscription.endDate) : null,\n isActive: subscription.status === 'ACTIVE',\n isExpired: subscription.endDate ? new Date(subscription.endDate) < new Date() : false,\n };\n }\n\n // Transform app data for display\n static transformApp(app: any) {\n return {\n ...app,\n createdAt: this.toDate(app.createdAt),\n updatedAt: this.toDate(app.updatedAt),\n isAdminLevel: app.securityLevel === 'ADMIN',\n hasDefaultPlan: !!app.defaultSubscriptionPlanId,\n };\n }\n\n // Transform feature flag data for display\n static transformFeatureFlag(featureFlag: any) {\n return {\n ...featureFlag,\n createdAt: this.toDate(featureFlag.createdAt),\n updatedAt: this.toDate(featureFlag.updatedAt),\n isEnabled: featureFlag.isActive,\n };\n }\n\n // Transform permission data for display\n static transformPermission(permission: any) {\n return {\n ...permission,\n createdAt: this.toDate(permission.createdAt),\n updatedAt: this.toDate(permission.updatedAt),\n fullName: `${permission.resource}:${permission.action}`,\n isSystemLevel: !permission.appId,\n };\n }\n\n // Transform subscription plan data for display\n static transformSubscriptionPlan(plan: any) {\n return {\n ...plan,\n createdAt: this.toDate(plan.createdAt),\n updatedAt: this.toDate(plan.updatedAt),\n displayPrice: `${plan.currency} ${plan.price}`,\n isMonthly: plan.billingCycle === 'MONTHLY',\n featureCount: plan.features?.length || 0,\n };\n }\n\n // Transform error response\n static transformError(error: any) {\n return {\n code: error.error?.code || 'UNKNOWN_ERROR',\n message: error.message || 'An unexpected error occurred',\n type: error.type || 'SYSTEM',\n isAuthError: error.type === 'AUTH',\n isValidationError: error.type === 'VALIDATION',\n };\n }\n\n // Transform query parameters for API calls\n static transformQueryParams(params: any): URLSearchParams {\n const searchParams = new URLSearchParams();\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== '') {\n searchParams.append(key, String(value));\n }\n });\n\n return searchParams;\n }\n}\n"],"names":["HttpService","baseUrl","timeout","sessionManager","method","endpoint","data","options","isRetry","url","requestTimeout","requestHeaders","authHeaders","error","controller","timeoutId","response","tokens","contentType","AppApiService","httpService","request","params","queryParams","id","appId","planId","schema","defaultSettings","AppContext","createContext","DefaultLoadingFallback","jsx","DefaultErrorFallback","retry","jsxs","AppProvider","config","children","appInfo","setAppInfo","useState","isAppLoading","setIsAppLoading","appError","setAppError","contextValue","useMemo","retryApp","loadApp","useCallback","appData","err","useEffect","Fragment","ErrorComponent","useApp","context","useContext","useApi","SessionManager","stored","tokenData","token","resolve","reject","newTokens","headers","refreshError","refreshToken","refreshResponse","user","currentData","AuthApiService","RoleApiService","roleId","userId","UserApiService","TenantApiService","slug","TenantContext","TenantProvider","auth","useAuth","tenant","setTenant","isTenantLoading","setIsTenantLoading","tenantError","setTenantError","settings","setSettings","isSettingsLoading","setIsSettingsLoading","settingsError","setSettingsError","detectTenantSlug","tenantMode","storageKey","parts","subdomain","urlTenant","tenantSlug","settingsSchema","loadTenant","tenantInfo","loadSettings","tenantSettings","updateSettings","newSettings","tenantApi","updatedSettings","refreshSettings","validateSettings","settingsToValidate","errors","key","fieldSchema","value","_a","expectedType","actualType","useTenant","useTenantSettings","useSettings","useTenantInfo","retryTenant","AuthContext","AuthProvider","availableRoles","setAvailableRoles","rolesLoading","setRolesLoading","currentUser","setCurrentUser","isUserLoading","setIsUserLoading","userError","setUserError","tokenStorage","authenticatedHttpService","service","authApiService","userApiService","roleApiService","userRole","role","userPermissions","loadUserData","userData","refreshUser","login","email","password","tenantId","loginResponse","signup","name","signupTenantAdmin","tenantName","changePassword","currentPassword","newPassword","requestPasswordReset","confirmPasswordReset","logout","setTokens","hasValidSession","clearSession","fetchRoles","roles","refreshRoles","hasPermission","permission","permissionString","permissions","internalHttpService","FeatureFlagApiService","flagKey","FeatureFlagContext","FeatureFlagProvider","featureFlags","setFeatureFlags","loading","setLoading","setError","featureFlagService","fetchFeatureFlags","errorMessage","refreshInterval","interval","flag","f","useFeatureFlags","SubscriptionApiService","subscriptionId","paymentData","SubscriptionContext","SubscriptionProvider","subscription","setSubscription","subscriptionService","fetchSubscription","features","featureKey","feature","defaultValue","allowedPlans","useSubscription","UserType","DefaultFallback","InsufficientPermissionsFallback","userType","minUserType","missingPermissions","hasMinimumUserType","hierarchy","Protected","fallback","requiredPermissions","requireAllPermissions","hasAnyPermission","hasAllPermissions","redirectPath","ProtectedRoute","redirectTo","location","useLocation","Navigate","SubscriptionGuard","requiredFeature","hasAllowedPlan","isFeatureEnabled","flagName","FeatureFlag","isEnabled","EyeIcon","EyeOffIcon","defaultIcons","defaultCopy","defaultStyles","LoginForm","copy","styles","icons","onSuccess","onError","onForgotPassword","onSignupClick","showForgotPassword","showSignupLink","className","setEmail","setPassword","showPassword","setShowPassword","fieldErrors","setFieldErrors","mergedCopy","mergedStyles","mergedIcons","validateForm","handleSubmit","e","result","getInputStyle","field","getButtonStyle","prev","SignupForm","signupType","onLoginClick","showLoginLink","setName","confirmPassword","setConfirmPassword","setTenantName","isFormValid","PasswordRecoveryForm","mode","initialToken","onBackToLogin","onModeChange","setToken","setNewPassword","success","setSuccess","validateRequestForm","validateResetForm","handleRequestSubmit","handleResetSubmit","PermissionApiService","SubscriptionPlanApiService","HealthApiService","ApiMappers","dateString","date","meta","app","featureFlag","plan","searchParams"],"mappings":"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"}
|