@djangocfg/layouts 2.1.37 → 2.1.38

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.
Files changed (77) hide show
  1. package/README.md +204 -18
  2. package/package.json +5 -5
  3. package/src/components/errors/index.ts +9 -0
  4. package/src/components/errors/types.ts +38 -0
  5. package/src/layouts/AppLayout/AppLayout.tsx +33 -45
  6. package/src/layouts/AppLayout/BaseApp.tsx +104 -33
  7. package/src/layouts/AuthLayout/AuthContext.tsx +7 -1
  8. package/src/layouts/AuthLayout/OAuthProviders.tsx +1 -10
  9. package/src/layouts/AuthLayout/OTPForm.tsx +1 -0
  10. package/src/layouts/PrivateLayout/PrivateLayout.tsx +1 -1
  11. package/src/layouts/PublicLayout/PublicLayout.tsx +1 -1
  12. package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +1 -1
  13. package/src/layouts/PublicLayout/components/PublicNavigation.tsx +1 -1
  14. package/src/layouts/_components/UserMenu.tsx +1 -1
  15. package/src/layouts/index.ts +1 -1
  16. package/src/layouts/types/index.ts +47 -0
  17. package/src/layouts/types/layout.types.ts +61 -0
  18. package/src/layouts/types/providers.types.ts +65 -0
  19. package/src/layouts/types/ui.types.ts +103 -0
  20. package/src/snippets/Analytics/index.ts +1 -0
  21. package/src/snippets/Analytics/types.ts +10 -0
  22. package/src/snippets/PWAInstall/@docs/README.md +92 -0
  23. package/src/snippets/PWAInstall/README.md +185 -0
  24. package/src/snippets/{PWA → PWAInstall}/components/A2HSHint.tsx +85 -84
  25. package/src/snippets/PWAInstall/components/DesktopGuide.tsx +229 -0
  26. package/src/snippets/PWAInstall/context/InstallContext.tsx +102 -0
  27. package/src/snippets/{PWA → PWAInstall}/hooks/useInstallPrompt.ts +3 -0
  28. package/src/snippets/{PWA → PWAInstall}/index.ts +12 -31
  29. package/src/snippets/{PWA → PWAInstall}/types/components.ts +0 -6
  30. package/src/snippets/PWAInstall/types/config.ts +22 -0
  31. package/src/snippets/{PWA → PWAInstall}/types/index.ts +4 -4
  32. package/src/snippets/{PWA → PWAInstall}/utils/localStorage.ts +1 -23
  33. package/src/snippets/PushNotifications/@docs/README.md +191 -0
  34. package/src/snippets/PushNotifications/@docs/guides/django-integration.md +648 -0
  35. package/src/snippets/PushNotifications/@docs/guides/service-worker.md +467 -0
  36. package/src/snippets/PushNotifications/@docs/guides/vapid-setup.md +352 -0
  37. package/src/snippets/PushNotifications/README.md +328 -0
  38. package/src/snippets/{PWA → PushNotifications}/config.ts +2 -2
  39. package/src/snippets/PushNotifications/context/DjangoPushContext.tsx +190 -0
  40. package/src/snippets/{PWA → PushNotifications}/hooks/useDjangoPush.ts +63 -81
  41. package/src/snippets/{PWA → PushNotifications}/hooks/usePushNotifications.ts +12 -8
  42. package/src/snippets/PushNotifications/index.ts +87 -0
  43. package/src/snippets/PushNotifications/types/config.ts +28 -0
  44. package/src/snippets/PushNotifications/types/index.ts +9 -0
  45. package/src/snippets/PushNotifications/utils/localStorage.ts +60 -0
  46. package/src/snippets/PushNotifications/utils/logger.ts +149 -0
  47. package/src/snippets/PushNotifications/utils/platform.ts +151 -0
  48. package/src/snippets/index.ts +37 -12
  49. package/src/layouts/shared/index.ts +0 -21
  50. package/src/layouts/shared/types.ts +0 -247
  51. package/src/snippets/PWA/@refactoring/ARCHITECTURE_ANALYSIS.md +0 -1179
  52. package/src/snippets/PWA/@refactoring/EXECUTIVE_SUMMARY.md +0 -271
  53. package/src/snippets/PWA/@refactoring/README.md +0 -204
  54. package/src/snippets/PWA/@refactoring/REFACTORING_PROPOSALS.md +0 -1109
  55. package/src/snippets/PWA/@refactoring2/COMPARISON-WITH-NEXTJS.md +0 -718
  56. package/src/snippets/PWA/@refactoring2/P1-FIXES-COMPLETED.md +0 -188
  57. package/src/snippets/PWA/@refactoring2/POST-P0-ANALYSIS.md +0 -362
  58. package/src/snippets/PWA/@refactoring2/README.md +0 -85
  59. package/src/snippets/PWA/@refactoring2/RECOMMENDATIONS.md +0 -1321
  60. package/src/snippets/PWA/@refactoring2/REMAINING-ISSUES.md +0 -557
  61. package/src/snippets/PWA/README.md +0 -387
  62. package/src/snippets/PWA/context/DjangoPushContext.tsx +0 -105
  63. package/src/snippets/PWA/context/InstallContext.tsx +0 -118
  64. package/src/snippets/PWA/context/PushContext.tsx +0 -156
  65. /package/src/layouts/{shared → types}/README.md +0 -0
  66. /package/src/snippets/{PWA/@docs/research.md → PWAInstall/@docs/research/ios-android-install-flows.md} +0 -0
  67. /package/src/snippets/{PWA → PWAInstall}/components/IOSGuide.tsx +0 -0
  68. /package/src/snippets/{PWA → PWAInstall}/components/IOSGuideDrawer.tsx +0 -0
  69. /package/src/snippets/{PWA → PWAInstall}/components/IOSGuideModal.tsx +0 -0
  70. /package/src/snippets/{PWA → PWAInstall}/hooks/useIsPWA.ts +0 -0
  71. /package/src/snippets/{PWA → PWAInstall}/types/install.ts +0 -0
  72. /package/src/snippets/{PWA → PWAInstall}/types/platform.ts +0 -0
  73. /package/src/snippets/{PWA → PWAInstall}/utils/logger.ts +0 -0
  74. /package/src/snippets/{PWA → PWAInstall}/utils/platform.ts +0 -0
  75. /package/src/snippets/{PWA → PushNotifications}/components/PushPrompt.tsx +0 -0
  76. /package/src/snippets/{PWA → PushNotifications}/types/push.ts +0 -0
  77. /package/src/snippets/{PWA → PushNotifications}/utils/vapid.ts +0 -0
@@ -6,7 +6,11 @@
6
6
  * - TooltipProvider (tooltip positioning)
7
7
  * - SWRConfig (data fetching)
8
8
  * - AuthProvider (authentication context)
9
- * - PwaProvider (PWA context, optional)
9
+ * - AuthDialog (global auth prompt dialog)
10
+ * - AnalyticsProvider (Google Analytics, optional)
11
+ * - CentrifugoProvider (WebSocket real-time, optional)
12
+ * - PwaProvider (PWA installation, optional)
13
+ * - DjangoPushProvider (Django web push integration, optional)
10
14
  * - ErrorTrackingProvider (error handling)
11
15
  * - ErrorBoundary (React error boundary, enabled by default)
12
16
  * - MCP Chat Widget (optional, lazy loaded)
@@ -15,11 +19,17 @@
15
19
  * ```tsx
16
20
  * import { BaseApp } from '@djangocfg/layouts';
17
21
  *
18
- * // With PWA and MCP Chat enabled
22
+ * // With PWA Install and Push Notifications
19
23
  * <BaseApp
20
24
  * theme={{ defaultTheme: 'system' }}
21
25
  * auth={{ loginPath: '/auth/login' }}
22
- * pwa={{ enabled: true }}
26
+ * analytics={{ googleTrackingId: 'G-XXXXXXXXXX' }}
27
+ * pwaInstall={{ enabled: true, logo: '/logo192.png' }}
28
+ * pushNotifications={{
29
+ * enabled: true,
30
+ * vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_KEY,
31
+ * requirePWA: true
32
+ * }}
23
33
  * mcpChat={{ enabled: true, autoDetectEnvironment: true }}
24
34
  * >
25
35
  * {children}
@@ -37,13 +47,18 @@
37
47
  import { ReactNode } from 'react';
38
48
  import dynamic from 'next/dynamic';
39
49
  import { SWRConfig } from 'swr';
40
- import { ThemeProvider, Toaster, TooltipProvider } from '@djangocfg/ui-nextjs';
50
+ import { ThemeProvider, SonnerToaster, TooltipProvider } from '@djangocfg/ui-nextjs';
41
51
  import { AuthProvider } from '@djangocfg/api/auth';
52
+ import { CentrifugoProvider } from '@djangocfg/centrifugo';
53
+ import { getCentrifugoAuthTokenRetrieve } from '@djangocfg/api';
42
54
  import { ErrorTrackingProvider } from '../../components/errors/ErrorsTracker';
43
55
  import { ErrorBoundary } from '../../components/errors/ErrorBoundary';
44
56
  import { PageProgress } from '../../components/core/PageProgress';
45
- import { PwaProvider } from '../../snippets/PWA';
46
- import type { BaseLayoutProps } from '../shared/types';
57
+ import { AnalyticsProvider } from '../../snippets/Analytics';
58
+ import { PwaProvider, A2HSHint } from '../../snippets/PWAInstall';
59
+ import { DjangoPushProvider, PushPrompt } from '../../snippets/PushNotifications';
60
+ import { AuthDialog } from '../../snippets/AuthDialog';
61
+ import type { BaseLayoutProps } from '../types/layout.types';
47
62
 
48
63
  // Lazy load MCP Chat Widget with dynamic import
49
64
  const AIChatWidget = dynamic(
@@ -57,22 +72,38 @@ export type BaseAppProps = BaseLayoutProps;
57
72
  /**
58
73
  * BaseApp - Core providers wrapper for any React/Next.js app
59
74
  *
60
- * Includes: ThemeProvider, TooltipProvider, SWRConfig, AuthProvider, ErrorTrackingProvider, ErrorBoundary (optional), MCP Chat (optional)
75
+ * Includes: ThemeProvider, TooltipProvider, SWRConfig, AuthProvider, AnalyticsProvider,
76
+ * CentrifugoProvider, PwaProvider, PushProvider, ErrorTrackingProvider,
77
+ * ErrorBoundary (optional), MCP Chat (optional)
61
78
  * Also renders global Toaster and PageProgress components
62
79
  */
63
80
  export function BaseApp({
64
81
  children,
65
82
  theme,
66
83
  auth,
84
+ analytics,
85
+ centrifugo,
67
86
  errorTracking,
68
87
  errorBoundary,
69
88
  swr,
70
89
  mcpChat,
71
- pwa,
90
+ pwaInstall,
91
+ pushNotifications,
72
92
  }: BaseAppProps) {
73
93
  // ErrorBoundary is enabled by default
74
94
  const enableErrorBoundary = errorBoundary?.enabled !== false;
75
95
 
96
+ // Check if PWA Install is enabled
97
+ const pwaInstallEnabled = pwaInstall?.enabled !== false;
98
+ const showInstallHint = pwaInstallEnabled && pwaInstall?.showInstallHint !== false;
99
+
100
+ // Check if Push Notifications is enabled
101
+ const pushEnabled = pushNotifications?.enabled !== false && !!pushNotifications?.vapidPublicKey;
102
+
103
+ // Centrifugo configuration
104
+ const centrifugoUrl = centrifugo?.url || process.env.NEXT_PUBLIC_CENTRIFUGO_URL;
105
+ const centrifugoEnabled = centrifugo?.enabled !== false;
106
+
76
107
  const content = (
77
108
  <ThemeProvider
78
109
  defaultTheme={theme?.defaultTheme || 'system'}
@@ -87,33 +118,73 @@ export function BaseApp({
87
118
  }}
88
119
  >
89
120
  <AuthProvider config={auth}>
90
- <PwaProvider {...pwa}>
91
- <ErrorTrackingProvider
92
- validation={errorTracking?.validation}
93
- cors={errorTracking?.cors}
94
- network={errorTracking?.network}
95
- onError={errorTracking?.onError}
121
+ <AnalyticsProvider trackingId={analytics?.googleTrackingId}>
122
+ <CentrifugoProvider
123
+ enabled={centrifugoEnabled}
124
+ autoConnect={centrifugoEnabled && centrifugo?.autoConnect}
125
+ url={centrifugoUrl}
126
+ onTokenRefresh={async () => {
127
+ const response = await getCentrifugoAuthTokenRetrieve();
128
+ return response.token;
129
+ }}
96
130
  >
97
- {children}
98
- <PageProgress />
99
- <Toaster />
131
+ <PwaProvider enabled={pwaInstallEnabled}>
132
+ <DjangoPushProvider
133
+ vapidPublicKey={pushNotifications?.vapidPublicKey || ''}
134
+ autoSubscribe={pushNotifications?.autoSubscribe}
135
+ >
136
+ <ErrorTrackingProvider
137
+ validation={errorTracking?.validation}
138
+ cors={errorTracking?.cors}
139
+ network={errorTracking?.network}
140
+ onError={errorTracking?.onError}
141
+ >
142
+ {children}
143
+ <PageProgress />
144
+ <SonnerToaster />
145
+
146
+ {/* PWA Install Hint */}
147
+ {showInstallHint && (
148
+ <A2HSHint
149
+ resetAfterDays={pwaInstall?.resetAfterDays}
150
+ delayMs={pwaInstall?.delayMs}
151
+ logo={pwaInstall?.logo}
152
+ />
153
+ )}
154
+
155
+ {/* Push Notifications Prompt */}
156
+ {pushEnabled && (
157
+ <PushPrompt
158
+ vapidPublicKey={pushNotifications!.vapidPublicKey}
159
+ subscribeEndpoint={pushNotifications?.subscribeEndpoint}
160
+ requirePWA={pushNotifications?.requirePWA ?? true}
161
+ delayMs={pushNotifications?.delayMs}
162
+ resetAfterDays={pushNotifications?.resetAfterDays}
163
+ />
164
+ )}
165
+
166
+ {/* MCP Chat Widget - lazy loaded */}
167
+ {mcpChat?.enabled && (
168
+ <AIChatWidget
169
+ apiEndpoint={mcpChat.apiEndpoint}
170
+ title={mcpChat.title}
171
+ placeholder={mcpChat.placeholder}
172
+ greeting={mcpChat.greeting}
173
+ position={mcpChat.position}
174
+ variant={mcpChat.variant}
175
+ enableStreaming={mcpChat.enableStreaming}
176
+ autoDetectEnvironment={mcpChat.autoDetectEnvironment}
177
+ className={mcpChat.className}
178
+ />
179
+ )}
100
180
 
101
- {/* MCP Chat Widget - lazy loaded */}
102
- {mcpChat?.enabled && (
103
- <AIChatWidget
104
- apiEndpoint={mcpChat.apiEndpoint}
105
- title={mcpChat.title}
106
- placeholder={mcpChat.placeholder}
107
- greeting={mcpChat.greeting}
108
- position={mcpChat.position}
109
- variant={mcpChat.variant}
110
- enableStreaming={mcpChat.enableStreaming}
111
- autoDetectEnvironment={mcpChat.autoDetectEnvironment}
112
- className={mcpChat.className}
113
- />
114
- )}
115
- </ErrorTrackingProvider>
116
- </PwaProvider>
181
+ {/* Auth Dialog - global auth prompt */}
182
+ <AuthDialog authPath={auth?.routes?.auth} />
183
+ </ErrorTrackingProvider>
184
+ </DjangoPushProvider>
185
+ </PwaProvider>
186
+ </CentrifugoProvider>
187
+ </AnalyticsProvider>
117
188
  </AuthProvider>
118
189
  </SWRConfig>
119
190
  </TooltipProvider>
@@ -16,18 +16,24 @@ export const AuthProvider: React.FC<AuthProps> = ({
16
16
  privacyUrl,
17
17
  enablePhoneAuth = false, // Default to false for backward compatibility
18
18
  enableGithubAuth = false, // Default to false for backward compatibility
19
+ redirectUrl, // URL to redirect after successful OTP auth
19
20
  onIdentifierSuccess,
20
21
  onOTPSuccess,
21
22
  onError,
22
23
  }) => {
23
24
  const sourceUrl = sourceUrlProp || (typeof window !== 'undefined' ? window.location.origin : '');
24
25
 
25
- // Use the auth form hook with required sourceUrl
26
+ // Require terms acceptance only if terms or privacy URL is provided
27
+ const requireTermsAcceptance = Boolean(termsUrl || privacyUrl);
28
+
29
+ // Use the auth form hook with required sourceUrl and redirectUrl
26
30
  const authForm = useAuthForm({
27
31
  onIdentifierSuccess,
28
32
  onOTPSuccess,
29
33
  onError,
30
34
  sourceUrl,
35
+ redirectUrl,
36
+ requireTermsAcceptance,
31
37
  });
32
38
 
33
39
  const value: AuthContextType = {
@@ -15,11 +15,10 @@ import { useAuthContext } from './AuthContext';
15
15
  * Handles the OAuth flow initiation.
16
16
  */
17
17
  export const OAuthProviders: React.FC = () => {
18
- const { enableGithubAuth, sourceUrl, error: contextError, setError } = useAuthContext();
18
+ const { enableGithubAuth, sourceUrl, setError } = useAuthContext();
19
19
 
20
20
  const {
21
21
  isLoading: isGithubLoading,
22
- error: githubError,
23
22
  startGithubAuth,
24
23
  } = useGithubAuth({
25
24
  sourceUrl,
@@ -33,8 +32,6 @@ export const OAuthProviders: React.FC = () => {
33
32
  return null;
34
33
  }
35
34
 
36
- const error = githubError || contextError;
37
-
38
35
  return (
39
36
  <div className="space-y-4">
40
37
  {/* Divider */}
@@ -74,12 +71,6 @@ export const OAuthProviders: React.FC = () => {
74
71
  )}
75
72
  </div>
76
73
 
77
- {/* Error Message */}
78
- {error && (
79
- <div className="text-sm text-destructive bg-destructive/10 p-3 rounded-md border border-destructive/20">
80
- {error}
81
- </div>
82
- )}
83
74
  </div>
84
75
  );
85
76
  };
@@ -79,6 +79,7 @@ export const OTPForm: React.FC = () => {
79
79
  onChange={setOtp}
80
80
  disabled={isLoading}
81
81
  autoFocus={true}
82
+ autoSubmit={true}
82
83
  size="lg"
83
84
  />
84
85
  </div>
@@ -51,7 +51,7 @@ import { SidebarProvider, SidebarInset, Preloader, ButtonLink } from '@djangocfg
51
51
  import { useAuth } from '@djangocfg/api/auth';
52
52
  import { PrivateSidebar, PrivateHeader, PrivateContent } from './components';
53
53
  import type { LucideIcon as LucideIconType } from 'lucide-react';
54
- import { UserMenuConfig } from '../shared/types';
54
+ import { UserMenuConfig } from '../types';
55
55
 
56
56
  export interface SidebarItem {
57
57
  label: string;
@@ -30,7 +30,7 @@
30
30
 
31
31
  import { ReactNode, useState, useEffect } from 'react';
32
32
  import { usePathname } from 'next/navigation';
33
- import type { NavigationItem, UserMenuConfig } from '../shared/types';
33
+ import type { NavigationItem, UserMenuConfig } from '../types';
34
34
  import {
35
35
  PublicNavigation,
36
36
  PublicMobileDrawer,
@@ -20,7 +20,7 @@ import {
20
20
  import { ThemeToggle } from '@djangocfg/ui-nextjs/theme';
21
21
  import { useAuth } from '@djangocfg/api/auth';
22
22
  import { UserMenu } from '../../_components/UserMenu';
23
- import type { NavigationItem, UserMenuConfig } from '../../shared/types';
23
+ import type { NavigationItem, UserMenuConfig } from '../../types';
24
24
 
25
25
  interface PublicMobileDrawerProps {
26
26
  isOpen: boolean;
@@ -15,7 +15,7 @@ import { cn } from '@djangocfg/ui-nextjs/lib';
15
15
  import { useIsMobile } from '@djangocfg/ui-nextjs/hooks';
16
16
  import { useAuth } from '@djangocfg/api/auth';
17
17
  import { UserMenu } from '../../_components/UserMenu';
18
- import type { NavigationItem, UserMenuConfig } from '../../shared/types';
18
+ import type { NavigationItem, UserMenuConfig } from '../../types';
19
19
 
20
20
  interface PublicNavigationProps {
21
21
  logo?: string;
@@ -47,7 +47,7 @@ import {
47
47
  Button,
48
48
  } from '@djangocfg/ui-nextjs/components';
49
49
  import { useAuth } from '@djangocfg/api/auth';
50
- import type { UserMenuGroup } from '../shared/types';
50
+ import type { UserMenuGroup } from '../types';
51
51
 
52
52
  export interface UserMenuProps {
53
53
  /** Display variant */
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  // Shared types (universal type system)
9
- export * from './shared';
9
+ export * from './types';
10
10
 
11
11
  // Smart layout router
12
12
  export * from './AppLayout';
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Shared Layout Types - Central Export
3
+ *
4
+ * This is the main entry point for all layout types.
5
+ * Types are organized by category and imported from their source modules.
6
+ */
7
+
8
+ // ============================================================================
9
+ // Provider Configuration Types
10
+ // ============================================================================
11
+
12
+ // Local provider configs
13
+ export type { ThemeConfig, SWRConfigOptions, McpChatConfig, CentrifugoConfig } from './providers.types';
14
+
15
+ // External provider configs (re-export for convenience)
16
+ export type { AnalyticsConfig } from '../../snippets/Analytics/types';
17
+ export type { PwaInstallConfig } from '../../snippets/PWAInstall/types';
18
+ export type { PushNotificationsConfig } from '../../snippets/PushNotifications/types';
19
+ export type {
20
+ ErrorBoundaryConfig,
21
+ ErrorTrackingConfig,
22
+ ValidationErrorConfig,
23
+ CORSErrorConfig,
24
+ NetworkErrorConfig,
25
+ } from '../../components/errors/types';
26
+
27
+ // ============================================================================
28
+ // UI Component Types
29
+ // ============================================================================
30
+
31
+ export type {
32
+ NavigationItem,
33
+ NavigationSection,
34
+ FooterLink,
35
+ FooterMenuSection,
36
+ FooterSocialLinks,
37
+ FooterConfig,
38
+ UserMenuItem,
39
+ UserMenuGroup,
40
+ UserMenuConfig,
41
+ } from './ui.types';
42
+
43
+ // ============================================================================
44
+ // Layout Types
45
+ // ============================================================================
46
+
47
+ export type { BaseLayoutProps } from './layout.types';
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Base Layout Types
3
+ *
4
+ * Core layout configuration that combines all provider configs
5
+ */
6
+
7
+ import type { ReactNode } from 'react';
8
+ import type { AuthConfig } from '@djangocfg/api/auth';
9
+
10
+ // Import provider configs from their modules
11
+ import type { AnalyticsConfig } from '../../snippets/Analytics/types';
12
+ import type { PwaInstallConfig } from '../../snippets/PWAInstall/types';
13
+ import type { PushNotificationsConfig } from '../../snippets/PushNotifications/types';
14
+ import type { ErrorBoundaryConfig, ErrorTrackingConfig } from '../../components/errors/types';
15
+
16
+ // Import local provider configs
17
+ import type { ThemeConfig, SWRConfigOptions, McpChatConfig, CentrifugoConfig } from './providers.types';
18
+
19
+ // ============================================================================
20
+ // Base Layout Props
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Base Layout Props
25
+ *
26
+ * Core configuration for BaseApp component.
27
+ * All provider configs are imported from their respective modules.
28
+ */
29
+ export interface BaseLayoutProps {
30
+ children: ReactNode;
31
+
32
+ /** Theme configuration */
33
+ theme?: ThemeConfig;
34
+
35
+ /** Auth configuration */
36
+ auth?: AuthConfig;
37
+
38
+ /** Analytics configuration (from snippets/Analytics) */
39
+ analytics?: AnalyticsConfig;
40
+
41
+ /** Centrifugo configuration */
42
+ centrifugo?: CentrifugoConfig;
43
+
44
+ /** Error tracking configuration (from components/errors) */
45
+ errorTracking?: ErrorTrackingConfig;
46
+
47
+ /** SWR configuration */
48
+ swr?: SWRConfigOptions;
49
+
50
+ /** Error boundary configuration (from components/errors, enabled by default) */
51
+ errorBoundary?: ErrorBoundaryConfig;
52
+
53
+ /** MCP chat configuration */
54
+ mcpChat?: McpChatConfig;
55
+
56
+ /** PWA Install configuration (from snippets/PWAInstall) */
57
+ pwaInstall?: PwaInstallConfig;
58
+
59
+ /** Push Notifications configuration (from snippets/PushNotifications) */
60
+ pushNotifications?: PushNotificationsConfig;
61
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Provider Configuration Types
3
+ *
4
+ * Configuration types for layout providers (theme, SWR, MCP chat, Centrifugo)
5
+ * Note: Analytics, PWA, Push, and Error types are defined in their respective modules
6
+ */
7
+
8
+ // ============================================================================
9
+ // Theme Configuration
10
+ // ============================================================================
11
+
12
+ export interface ThemeConfig {
13
+ defaultTheme?: 'light' | 'dark' | 'system';
14
+ storageKey?: string;
15
+ }
16
+
17
+ // ============================================================================
18
+ // SWR Configuration
19
+ // ============================================================================
20
+
21
+ export interface SWRConfigOptions {
22
+ revalidateOnFocus?: boolean;
23
+ revalidateOnReconnect?: boolean;
24
+ dedupingInterval?: number;
25
+ }
26
+
27
+ // ============================================================================
28
+ // MCP Chat Configuration
29
+ // ============================================================================
30
+
31
+ export interface McpChatConfig {
32
+ /** Enable MCP chat widget */
33
+ enabled?: boolean;
34
+ /** API endpoint for chat */
35
+ apiEndpoint?: string;
36
+ /** Chat widget title */
37
+ title?: string;
38
+ /** Input placeholder */
39
+ placeholder?: string;
40
+ /** Greeting message */
41
+ greeting?: string;
42
+ /** Widget position */
43
+ position?: 'bottom-right' | 'bottom-left';
44
+ /** Widget variant */
45
+ variant?: 'default' | 'minimal';
46
+ /** Enable streaming responses */
47
+ enableStreaming?: boolean;
48
+ /** Auto-detect environment (dev/prod) */
49
+ autoDetectEnvironment?: boolean;
50
+ /** Custom class name */
51
+ className?: string;
52
+ }
53
+
54
+ // ============================================================================
55
+ // Centrifugo Configuration
56
+ // ============================================================================
57
+
58
+ export interface CentrifugoConfig {
59
+ /** Enable Centrifugo (default: true) */
60
+ enabled?: boolean;
61
+ /** Auto-connect on mount (default: false) */
62
+ autoConnect?: boolean;
63
+ /** Centrifugo server URL */
64
+ url?: string;
65
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * UI Component Types
3
+ *
4
+ * Types for layout UI components (navigation, footer, user menu)
5
+ */
6
+
7
+ import type { LucideIcon } from 'lucide-react';
8
+
9
+ // ============================================================================
10
+ // Navigation Types
11
+ // ============================================================================
12
+
13
+ export interface NavigationItem {
14
+ label: string;
15
+ href: string;
16
+ icon?: LucideIcon | string;
17
+ badge?: string | number;
18
+ external?: boolean;
19
+ }
20
+
21
+ export interface NavigationSection {
22
+ title?: string;
23
+ items: NavigationItem[];
24
+ }
25
+
26
+ // ============================================================================
27
+ // Footer Types
28
+ // ============================================================================
29
+
30
+ export interface FooterLink {
31
+ label: string;
32
+ path: string;
33
+ external?: boolean;
34
+ }
35
+
36
+ export interface FooterMenuSection {
37
+ title: string;
38
+ items: FooterLink[];
39
+ }
40
+
41
+ export interface FooterSocialLinks {
42
+ github?: string;
43
+ linkedin?: string;
44
+ twitter?: string;
45
+ telegram?: string;
46
+ youtube?: string;
47
+ facebook?: string;
48
+ instagram?: string;
49
+ whatsapp?: string;
50
+ email?: string;
51
+ }
52
+
53
+ export interface FooterConfig {
54
+ siteName?: string;
55
+ description?: string;
56
+ logo?: string;
57
+ badge?: {
58
+ icon: LucideIcon;
59
+ text: string;
60
+ };
61
+ socialLinks?: FooterSocialLinks;
62
+ links?: FooterLink[];
63
+ menuSections?: FooterMenuSection[];
64
+ copyright?: string;
65
+ credits?: {
66
+ text: string;
67
+ url?: string;
68
+ };
69
+ variant?: 'full' | 'simple';
70
+ }
71
+
72
+ // ============================================================================
73
+ // User Menu Types
74
+ // ============================================================================
75
+
76
+ export interface UserMenuItem {
77
+ /** Menu item label */
78
+ label: string;
79
+ /** Link href (optional if onClick is provided) */
80
+ href?: string;
81
+ /** Icon component */
82
+ icon?: LucideIcon;
83
+ /** Visual variant */
84
+ variant?: 'default' | 'destructive';
85
+ /** Click handler (optional if href is provided) */
86
+ onClick?: () => void;
87
+ /** Open link in new tab */
88
+ external?: boolean;
89
+ }
90
+
91
+ export interface UserMenuGroup {
92
+ /** Optional group title (renders DropdownMenuLabel) */
93
+ title?: string;
94
+ /** Menu items in this group */
95
+ items: UserMenuItem[];
96
+ }
97
+
98
+ export interface UserMenuConfig {
99
+ /** Menu groups for authenticated users */
100
+ groups?: UserMenuGroup[];
101
+ /** Auth page path (for sign in button) */
102
+ authPath?: string;
103
+ }
@@ -8,3 +8,4 @@ export { useAnalytics, Analytics } from './useAnalytics';
8
8
  export { AnalyticsProvider } from './AnalyticsProvider';
9
9
  export { AnalyticsEvent, AnalyticsCategory } from './events';
10
10
  export type { AnalyticsEventType, AnalyticsCategoryType } from './events';
11
+ export type { AnalyticsConfig } from './types';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Analytics Configuration Types
3
+ *
4
+ * Configuration for Google Analytics integration
5
+ */
6
+
7
+ export interface AnalyticsConfig {
8
+ /** Google Analytics tracking ID (e.g., 'G-XXXXXXXXXX') */
9
+ googleTrackingId?: string;
10
+ }