@djangocfg/layouts 2.1.103 → 2.1.104
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/package.json +33 -37
- package/src/components/RedirectPage/RedirectPage.tsx +2 -2
- package/src/components/core/ClientOnly.tsx +1 -1
- package/src/components/errors/ErrorLayout.tsx +1 -1
- package/src/components/errors/ErrorsTracker/components/ErrorButtons.tsx +1 -1
- package/src/components/index.ts +2 -0
- package/src/index.ts +2 -0
- package/src/layouts/AuthLayout/components/AuthHelp.tsx +1 -1
- package/src/layouts/AuthLayout/components/AuthSuccess.tsx +1 -1
- package/src/layouts/AuthLayout/components/IdentifierForm.tsx +1 -1
- package/src/layouts/AuthLayout/components/OTPForm.tsx +1 -1
- package/src/layouts/AuthLayout/components/TwoFactorForm.tsx +1 -1
- package/src/layouts/AuthLayout/components/TwoFactorSetup.tsx +1 -1
- package/src/layouts/AuthLayout/components/oauth/OAuthCallback.tsx +1 -1
- package/src/layouts/AuthLayout/components/oauth/OAuthProviders.tsx +1 -1
- package/src/layouts/PrivateLayout/PrivateLayout.tsx +3 -2
- package/src/layouts/PrivateLayout/components/PrivateHeader.tsx +2 -2
- package/src/layouts/ProfileLayout/ProfileLayout.tsx +1 -1
- package/src/layouts/ProfileLayout/__tests__/TwoFactorSection.test.tsx +1 -1
- package/src/layouts/ProfileLayout/components/AvatarSection.tsx +1 -1
- package/src/layouts/ProfileLayout/components/DeleteAccountSection.tsx +1 -1
- package/src/layouts/ProfileLayout/components/ProfileForm.tsx +1 -1
- package/src/layouts/ProfileLayout/components/TwoFactorSection.tsx +1 -1
- package/src/layouts/PublicLayout/components/PublicFooter/PublicFooter.tsx +1 -1
- package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +1 -1
- package/src/layouts/PublicLayout/components/PublicNavigation.tsx +2 -2
- package/src/layouts/_components/UserMenu.tsx +1 -1
- package/src/layouts/index.ts +2 -0
- package/src/pages/index.ts +2 -0
- package/src/pages/legal/LegalPage.tsx +1 -1
- package/src/snippets/AuthDialog/AuthDialog.tsx +3 -2
- package/src/snippets/McpChat/components/AIChatWidget.tsx +1 -1
- package/src/snippets/McpChat/components/AskAIButton.tsx +1 -1
- package/src/snippets/McpChat/components/ChatMessages.tsx +1 -1
- package/src/snippets/McpChat/components/ChatPanel.tsx +1 -1
- package/src/snippets/McpChat/components/ChatSidebar.tsx +1 -1
- package/src/snippets/McpChat/components/ChatWidget.tsx +1 -1
- package/src/snippets/McpChat/components/MessageBubble.tsx +1 -1
- package/src/snippets/McpChat/components/MessageInput.tsx +1 -1
- package/src/snippets/McpChat/context/AIChatContext.tsx +1 -1
- package/src/snippets/McpChat/context/ChatContext.tsx +1 -1
- package/src/snippets/McpChat/hooks/useChatLayout.ts +1 -1
- package/src/snippets/PWAInstall/components/A2HSHint.tsx +0 -1
- package/src/snippets/PWAInstall/components/DesktopGuide.tsx +1 -1
- package/src/snippets/PWAInstall/components/IOSGuide.tsx +1 -1
- package/src/snippets/PWAInstall/components/IOSGuideDrawer.tsx +1 -1
- package/src/snippets/PWAInstall/components/IOSGuideModal.tsx +1 -1
- package/src/snippets/PWAInstall/hooks/useInstallPrompt.ts +2 -2
- package/src/snippets/PushNotifications/components/PushPrompt.tsx +1 -1
- package/src/snippets/index.ts +1 -0
- package/dist/AIChatWidget-LUPM7S2O.mjs +0 -1644
- package/dist/AIChatWidget-LUPM7S2O.mjs.map +0 -1
- package/dist/AIChatWidget-O23TJJ7C.mjs +0 -3
- package/dist/AIChatWidget-O23TJJ7C.mjs.map +0 -1
- package/dist/chunk-53YKWR6F.mjs +0 -6
- package/dist/chunk-53YKWR6F.mjs.map +0 -1
- package/dist/chunk-EI7TDN2G.mjs +0 -1652
- package/dist/chunk-EI7TDN2G.mjs.map +0 -1
- package/dist/components.cjs +0 -925
- package/dist/components.cjs.map +0 -1
- package/dist/components.d.mts +0 -583
- package/dist/components.d.ts +0 -583
- package/dist/components.mjs +0 -879
- package/dist/components.mjs.map +0 -1
- package/dist/index.cjs +0 -7573
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.mts +0 -2376
- package/dist/index.d.ts +0 -2376
- package/dist/index.mjs +0 -5673
- package/dist/index.mjs.map +0 -1
- package/dist/layouts.cjs +0 -6530
- package/dist/layouts.cjs.map +0 -1
- package/dist/layouts.d.mts +0 -748
- package/dist/layouts.d.ts +0 -748
- package/dist/layouts.mjs +0 -4741
- package/dist/layouts.mjs.map +0 -1
- package/dist/pages.cjs +0 -178
- package/dist/pages.cjs.map +0 -1
- package/dist/pages.d.mts +0 -57
- package/dist/pages.d.ts +0 -57
- package/dist/pages.mjs +0 -168
- package/dist/pages.mjs.map +0 -1
- package/dist/snippets.cjs +0 -3793
- package/dist/snippets.cjs.map +0 -1
- package/dist/snippets.d.mts +0 -1192
- package/dist/snippets.d.ts +0 -1192
- package/dist/snippets.mjs +0 -3738
- package/dist/snippets.mjs.map +0 -1
- package/dist/utils.cjs +0 -34
- package/dist/utils.cjs.map +0 -1
- package/dist/utils.d.mts +0 -40
- package/dist/utils.d.ts +0 -40
- package/dist/utils.mjs +0 -25
- package/dist/utils.mjs.map +0 -1
package/dist/snippets.d.ts
DELETED
|
@@ -1,1192 +0,0 @@
|
|
|
1
|
-
import React$1, { ReactNode } from 'react';
|
|
2
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import { ButtonProps } from '@djangocfg/ui-nextjs';
|
|
4
|
-
|
|
5
|
-
interface BreadcrumbItem {
|
|
6
|
-
path: string;
|
|
7
|
-
label: string;
|
|
8
|
-
isActive: boolean;
|
|
9
|
-
}
|
|
10
|
-
declare function generateBreadcrumbsFromPath(pathname: string): BreadcrumbItem[];
|
|
11
|
-
|
|
12
|
-
declare const DIALOG_EVENTS: {
|
|
13
|
-
readonly OPEN_AUTH_DIALOG: "OPEN_AUTH_DIALOG";
|
|
14
|
-
readonly CLOSE_AUTH_DIALOG: "CLOSE_AUTH_DIALOG";
|
|
15
|
-
readonly AUTH_SUCCESS: "AUTH_SUCCESS";
|
|
16
|
-
readonly AUTH_FAILURE: "AUTH_FAILURE";
|
|
17
|
-
};
|
|
18
|
-
interface AuthDialogProps {
|
|
19
|
-
onAuthRequired?: () => void;
|
|
20
|
-
authPath?: string;
|
|
21
|
-
}
|
|
22
|
-
declare const AuthDialog: React$1.FC<AuthDialogProps>;
|
|
23
|
-
|
|
24
|
-
declare const AUTH_EVENTS: {
|
|
25
|
-
readonly OPEN_AUTH_DIALOG: "OPEN_AUTH_DIALOG";
|
|
26
|
-
readonly CLOSE_AUTH_DIALOG: "CLOSE_AUTH_DIALOG";
|
|
27
|
-
readonly AUTH_SUCCESS: "AUTH_SUCCESS";
|
|
28
|
-
readonly AUTH_FAILURE: "AUTH_FAILURE";
|
|
29
|
-
};
|
|
30
|
-
type AuthEventType = typeof AUTH_EVENTS[keyof typeof AUTH_EVENTS];
|
|
31
|
-
interface OpenAuthDialogPayload {
|
|
32
|
-
message?: string;
|
|
33
|
-
redirectUrl?: string;
|
|
34
|
-
}
|
|
35
|
-
interface AuthSuccessPayload {
|
|
36
|
-
user?: any;
|
|
37
|
-
}
|
|
38
|
-
interface AuthFailurePayload {
|
|
39
|
-
error?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Hook to control auth dialog from anywhere in the app
|
|
44
|
-
*/
|
|
45
|
-
declare function useAuthDialog(): {
|
|
46
|
-
openAuthDialog: (options?: OpenAuthDialogPayload) => void;
|
|
47
|
-
closeAuthDialog: () => void;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* useAnalytics Hook
|
|
52
|
-
*
|
|
53
|
-
* Provides Google Analytics tracking via react-ga4
|
|
54
|
-
* Automatically tracks page views on route changes
|
|
55
|
-
* Only works in production mode
|
|
56
|
-
*/
|
|
57
|
-
/**
|
|
58
|
-
* Analytics utility object for standalone usage (outside React components)
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* import { Analytics } from '@djangocfg/layouts';
|
|
63
|
-
*
|
|
64
|
-
* // In an event handler or utility function
|
|
65
|
-
* Analytics.event('button_click', { category: 'engagement', label: 'signup' });
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
declare const Analytics: {
|
|
69
|
-
/**
|
|
70
|
-
* Initialize Google Analytics (called automatically by useAnalytics hook)
|
|
71
|
-
*/
|
|
72
|
-
init: (trackingId: string) => void;
|
|
73
|
-
/**
|
|
74
|
-
* Check if Analytics is enabled and initialized
|
|
75
|
-
*/
|
|
76
|
-
isEnabled: () => boolean;
|
|
77
|
-
/**
|
|
78
|
-
* Track a page view
|
|
79
|
-
*/
|
|
80
|
-
pageview: (path: string) => void;
|
|
81
|
-
/**
|
|
82
|
-
* Track a custom event
|
|
83
|
-
* @param name - Event name (action)
|
|
84
|
-
* @param params - Optional event parameters
|
|
85
|
-
*/
|
|
86
|
-
event: (name: string, params?: Record<string, any>) => void;
|
|
87
|
-
/**
|
|
88
|
-
* Set user ID for tracking
|
|
89
|
-
*/
|
|
90
|
-
setUser: (userId: string) => void;
|
|
91
|
-
/**
|
|
92
|
-
* Set custom dimensions/metrics
|
|
93
|
-
*/
|
|
94
|
-
set: (fieldsObject: Record<string, any>) => void;
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Hook for Google Analytics tracking via react-ga4
|
|
98
|
-
*
|
|
99
|
-
* Automatically initializes GA and tracks page views on route changes
|
|
100
|
-
* Only works in production mode (NODE_ENV === 'production')
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```tsx
|
|
104
|
-
* // Just call the hook - it auto-tracks pageviews
|
|
105
|
-
* useAnalytics();
|
|
106
|
-
*
|
|
107
|
-
* // Or use the returned methods for custom tracking
|
|
108
|
-
* const { event, isEnabled } = useAnalytics();
|
|
109
|
-
* event('button_click', { category: 'engagement', label: 'signup' });
|
|
110
|
-
* ```
|
|
111
|
-
*/
|
|
112
|
-
declare function useAnalytics(trackingIdProp?: string): {
|
|
113
|
-
isEnabled: boolean;
|
|
114
|
-
trackingId: string;
|
|
115
|
-
pageview: (path: string) => void;
|
|
116
|
-
event: (name: string, params?: Record<string, any>) => void;
|
|
117
|
-
setUser: (userId: string) => void;
|
|
118
|
-
set: (fieldsObject: Record<string, any>) => void;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
interface AnalyticsProviderProps {
|
|
122
|
-
children: ReactNode;
|
|
123
|
-
/** Google Analytics tracking ID (optional if using AppContext) */
|
|
124
|
-
trackingId?: string;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Analytics Provider that initializes tracking
|
|
128
|
-
* Automatically:
|
|
129
|
-
* - Initializes GA4 with tracking ID from prop or config
|
|
130
|
-
* - Sets user ID when authenticated
|
|
131
|
-
* - Tracks page views on route changes
|
|
132
|
-
*/
|
|
133
|
-
declare function AnalyticsProvider({ children, trackingId }: AnalyticsProviderProps): react_jsx_runtime.JSX.Element;
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Analytics Events Constants
|
|
137
|
-
*
|
|
138
|
-
* Predefined event names and categories for consistent tracking
|
|
139
|
-
* across the entire application.
|
|
140
|
-
*/
|
|
141
|
-
/**
|
|
142
|
-
* Event Categories
|
|
143
|
-
*/
|
|
144
|
-
declare const AnalyticsCategory: {
|
|
145
|
-
readonly AUTH: "auth";
|
|
146
|
-
readonly ERROR: "error";
|
|
147
|
-
readonly NAVIGATION: "navigation";
|
|
148
|
-
readonly ENGAGEMENT: "engagement";
|
|
149
|
-
readonly USER: "user";
|
|
150
|
-
};
|
|
151
|
-
/**
|
|
152
|
-
* Predefined Event Names
|
|
153
|
-
*/
|
|
154
|
-
declare const AnalyticsEvent: {
|
|
155
|
-
readonly AUTH_OTP_REQUEST: "auth_otp_request";
|
|
156
|
-
readonly AUTH_OTP_VERIFY_SUCCESS: "auth_otp_verify_success";
|
|
157
|
-
readonly AUTH_OTP_VERIFY_FAIL: "auth_otp_verify_fail";
|
|
158
|
-
readonly AUTH_LOGIN_SUCCESS: "auth_login_success";
|
|
159
|
-
readonly AUTH_LOGOUT: "auth_logout";
|
|
160
|
-
readonly AUTH_SESSION_EXPIRED: "auth_session_expired";
|
|
161
|
-
readonly AUTH_TOKEN_REFRESH: "auth_token_refresh";
|
|
162
|
-
readonly AUTH_TOKEN_REFRESH_FAIL: "auth_token_refresh_fail";
|
|
163
|
-
readonly AUTH_OAUTH_START: "auth_oauth_start";
|
|
164
|
-
readonly AUTH_OAUTH_SUCCESS: "auth_oauth_success";
|
|
165
|
-
readonly AUTH_OAUTH_FAIL: "auth_oauth_fail";
|
|
166
|
-
readonly ERROR_BOUNDARY: "error_boundary";
|
|
167
|
-
readonly ERROR_API: "error_api";
|
|
168
|
-
readonly ERROR_VALIDATION: "error_validation";
|
|
169
|
-
readonly ERROR_NETWORK: "error_network";
|
|
170
|
-
readonly NAV_ADMIN_ENTER: "nav_admin_enter";
|
|
171
|
-
readonly NAV_DASHBOARD_ENTER: "nav_dashboard_enter";
|
|
172
|
-
readonly NAV_PAGE_VIEW: "nav_page_view";
|
|
173
|
-
readonly THEME_CHANGE: "theme_change";
|
|
174
|
-
readonly SIDEBAR_TOGGLE: "sidebar_toggle";
|
|
175
|
-
readonly MOBILE_MENU_OPEN: "mobile_menu_open";
|
|
176
|
-
readonly USER_PROFILE_VIEW: "user_profile_view";
|
|
177
|
-
readonly USER_PROFILE_UPDATE: "user_profile_update";
|
|
178
|
-
};
|
|
179
|
-
type AnalyticsCategoryType = typeof AnalyticsCategory[keyof typeof AnalyticsCategory];
|
|
180
|
-
type AnalyticsEventType = typeof AnalyticsEvent[keyof typeof AnalyticsEvent];
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Analytics Configuration Types
|
|
184
|
-
*
|
|
185
|
-
* Configuration for Google Analytics integration
|
|
186
|
-
*/
|
|
187
|
-
interface AnalyticsConfig {
|
|
188
|
-
/** Google Analytics tracking ID (e.g., 'G-XXXXXXXXXX') */
|
|
189
|
-
googleTrackingId?: string;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Types for @djangocfg/mcp-chat
|
|
194
|
-
*/
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* AI Chat message role
|
|
198
|
-
*/
|
|
199
|
-
type AIMessageRole = 'user' | 'assistant' | 'system';
|
|
200
|
-
/**
|
|
201
|
-
* AI Chat message
|
|
202
|
-
*/
|
|
203
|
-
interface AIChatMessage {
|
|
204
|
-
id: string;
|
|
205
|
-
role: AIMessageRole;
|
|
206
|
-
content: string;
|
|
207
|
-
timestamp: Date;
|
|
208
|
-
/** Related documentation links */
|
|
209
|
-
sources?: AIChatSource[];
|
|
210
|
-
/** Is message still being generated */
|
|
211
|
-
isStreaming?: boolean;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* AI Documentation source reference
|
|
215
|
-
*/
|
|
216
|
-
interface AIChatSource {
|
|
217
|
-
title: string;
|
|
218
|
-
path: string;
|
|
219
|
-
url?: string;
|
|
220
|
-
section?: string;
|
|
221
|
-
score?: number;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Chat display mode
|
|
225
|
-
* - closed: Only FAB button visible
|
|
226
|
-
* - floating: Floating panel (default)
|
|
227
|
-
* - sidebar: Full-height sidebar on the right (desktop only)
|
|
228
|
-
*/
|
|
229
|
-
type ChatDisplayMode = 'closed' | 'floating' | 'sidebar';
|
|
230
|
-
/**
|
|
231
|
-
* Chat widget configuration
|
|
232
|
-
*/
|
|
233
|
-
interface ChatWidgetConfig {
|
|
234
|
-
/** API endpoint for chat (default: /api/chat) */
|
|
235
|
-
apiEndpoint?: string;
|
|
236
|
-
/** Widget title */
|
|
237
|
-
title?: string;
|
|
238
|
-
/** Placeholder text for input */
|
|
239
|
-
placeholder?: string;
|
|
240
|
-
/** Initial greeting message */
|
|
241
|
-
greeting?: string;
|
|
242
|
-
/** Position on screen */
|
|
243
|
-
position?: 'bottom-right' | 'bottom-left';
|
|
244
|
-
/** Theme variant */
|
|
245
|
-
variant?: 'default' | 'minimal';
|
|
246
|
-
/** Auto-detect environment (dev/prod) for API endpoint. If false (default), always uses production */
|
|
247
|
-
autoDetectEnvironment?: boolean;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* AI Chat API response
|
|
251
|
-
*/
|
|
252
|
-
interface AIChatApiResponse {
|
|
253
|
-
success: boolean;
|
|
254
|
-
content?: string;
|
|
255
|
-
sources?: Array<{
|
|
256
|
-
id?: string;
|
|
257
|
-
title: string;
|
|
258
|
-
path: string;
|
|
259
|
-
url?: string;
|
|
260
|
-
section?: string;
|
|
261
|
-
score?: number;
|
|
262
|
-
}>;
|
|
263
|
-
threadId?: string;
|
|
264
|
-
usage?: {
|
|
265
|
-
promptTokens: number;
|
|
266
|
-
completionTokens: number;
|
|
267
|
-
totalTokens: number;
|
|
268
|
-
};
|
|
269
|
-
error?: string;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* useAIChat hook options
|
|
273
|
-
*/
|
|
274
|
-
interface UseAIChatOptions {
|
|
275
|
-
/** API endpoint (default: /api/ai/chat) */
|
|
276
|
-
apiEndpoint?: string;
|
|
277
|
-
/** Initial messages */
|
|
278
|
-
initialMessages?: AIChatMessage[];
|
|
279
|
-
/** Callback on error */
|
|
280
|
-
onError?: (error: Error) => void;
|
|
281
|
-
/** Enable streaming responses (default: true) */
|
|
282
|
-
enableStreaming?: boolean;
|
|
283
|
-
/** Thread ID for conversation (generated if not provided) */
|
|
284
|
-
threadId?: string;
|
|
285
|
-
/** User ID for conversation (generated if not provided) */
|
|
286
|
-
userId?: string;
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* useAIChat hook return type
|
|
290
|
-
*/
|
|
291
|
-
interface UseAIChatReturn {
|
|
292
|
-
messages: AIChatMessage[];
|
|
293
|
-
isLoading: boolean;
|
|
294
|
-
error: Error | null;
|
|
295
|
-
threadId: string;
|
|
296
|
-
userId: string;
|
|
297
|
-
sendMessage: (content: string) => Promise<void>;
|
|
298
|
-
clearMessages: () => void;
|
|
299
|
-
stopStreaming: () => void;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Context type for chat messages triggered from different parts of the app
|
|
303
|
-
*/
|
|
304
|
-
type McpChatContextType = 'error' | 'question' | 'explain' | 'advice' | 'help' | 'custom';
|
|
305
|
-
/**
|
|
306
|
-
* Event detail for mcp:chat:send custom event
|
|
307
|
-
*/
|
|
308
|
-
interface McpChatEventDetail {
|
|
309
|
-
/** Message to send to chat */
|
|
310
|
-
message: string;
|
|
311
|
-
/** Optional context about the message */
|
|
312
|
-
context?: {
|
|
313
|
-
/** Type of context */
|
|
314
|
-
type?: McpChatContextType;
|
|
315
|
-
/** Additional data (error object, selected element, etc.) */
|
|
316
|
-
data?: Record<string, any>;
|
|
317
|
-
/** Source component/page that triggered the event */
|
|
318
|
-
source?: string;
|
|
319
|
-
};
|
|
320
|
-
/** Auto-send message after opening chat (default: true) */
|
|
321
|
-
autoSend?: boolean;
|
|
322
|
-
/** Open chat in specific mode (default: 'floating') */
|
|
323
|
-
displayMode?: ChatDisplayMode;
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* useMcpChat hook return type
|
|
327
|
-
*/
|
|
328
|
-
interface UseMcpChatReturn {
|
|
329
|
-
/** Send message to chat from anywhere in the app */
|
|
330
|
-
sendToChat: (detail: McpChatEventDetail) => void;
|
|
331
|
-
/** Check if chat is available */
|
|
332
|
-
isChatAvailable: () => boolean;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
interface AIChatWidgetProps extends ChatWidgetConfig {
|
|
336
|
-
/** Custom class name for the container */
|
|
337
|
-
className?: string;
|
|
338
|
-
/** Enable streaming responses (default: true) */
|
|
339
|
-
enableStreaming?: boolean;
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* AI Chat Widget component
|
|
343
|
-
*
|
|
344
|
-
* AI-powered documentation assistant with streaming support.
|
|
345
|
-
* Uses Mastra agent backend for intelligent responses.
|
|
346
|
-
*
|
|
347
|
-
* Can be used in two ways:
|
|
348
|
-
* 1. Standalone (wraps itself in AIChatProvider)
|
|
349
|
-
* 2. Inside an AIChatProvider (uses context directly)
|
|
350
|
-
*
|
|
351
|
-
* @example
|
|
352
|
-
* ```tsx
|
|
353
|
-
* // Standalone usage (always uses production API)
|
|
354
|
-
* <AIChatWidget />
|
|
355
|
-
*
|
|
356
|
-
* // Auto-detect environment (dev/prod)
|
|
357
|
-
* <AIChatWidget autoDetectEnvironment={true} />
|
|
358
|
-
*
|
|
359
|
-
* // With provider for custom control
|
|
360
|
-
* <AIChatProvider apiEndpoint="/api/ai/chat">
|
|
361
|
-
* <MyApp />
|
|
362
|
-
* <AIChatWidget />
|
|
363
|
-
* </AIChatProvider>
|
|
364
|
-
* ```
|
|
365
|
-
*/
|
|
366
|
-
declare const AIChatWidget: React$1.FC<AIChatWidgetProps>;
|
|
367
|
-
|
|
368
|
-
declare const ChatPanel: React$1.MemoExoticComponent<() => react_jsx_runtime.JSX.Element>;
|
|
369
|
-
|
|
370
|
-
interface MessageBubbleProps {
|
|
371
|
-
message: AIChatMessage;
|
|
372
|
-
isCompact?: boolean;
|
|
373
|
-
}
|
|
374
|
-
declare const MessageBubble: React$1.NamedExoticComponent<MessageBubbleProps>;
|
|
375
|
-
|
|
376
|
-
interface AIMessageInputProps {
|
|
377
|
-
onSend: (message: string) => void;
|
|
378
|
-
disabled?: boolean;
|
|
379
|
-
isLoading?: boolean;
|
|
380
|
-
placeholder?: string;
|
|
381
|
-
maxRows?: number;
|
|
382
|
-
}
|
|
383
|
-
declare const AIMessageInput: React$1.NamedExoticComponent<AIMessageInputProps>;
|
|
384
|
-
|
|
385
|
-
interface AskAIButtonProps extends Omit<ButtonProps, 'onClick'> {
|
|
386
|
-
/** Message to send to AI */
|
|
387
|
-
message: string;
|
|
388
|
-
/** Additional context data */
|
|
389
|
-
contextData?: Record<string, any>;
|
|
390
|
-
/** Source component name */
|
|
391
|
-
source?: string;
|
|
392
|
-
/** Auto-send message (default: true) */
|
|
393
|
-
autoSend?: boolean;
|
|
394
|
-
/** Show icon (default: true) */
|
|
395
|
-
showIcon?: boolean;
|
|
396
|
-
/** Callback after sending */
|
|
397
|
-
onSent?: () => void;
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Universal AI chat trigger button
|
|
401
|
-
*
|
|
402
|
-
* @example Basic usage
|
|
403
|
-
* ```tsx
|
|
404
|
-
* <AskAIButton message="Explain this feature">
|
|
405
|
-
* Explain this
|
|
406
|
-
* </AskAIButton>
|
|
407
|
-
* ```
|
|
408
|
-
*
|
|
409
|
-
* @example With context
|
|
410
|
-
* ```tsx
|
|
411
|
-
* <AskAIButton
|
|
412
|
-
* message="Why is this failing?"
|
|
413
|
-
* contextData={{ error: error.stack }}
|
|
414
|
-
* source="ErrorBoundary"
|
|
415
|
-
* >
|
|
416
|
-
* Ask AI
|
|
417
|
-
* </AskAIButton>
|
|
418
|
-
* ```
|
|
419
|
-
*/
|
|
420
|
-
declare function AskAIButton({ message, contextData, source, autoSend, showIcon, onSent, children, variant, size, className, ...buttonProps }: AskAIButtonProps): react_jsx_runtime.JSX.Element;
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* AI Chat context state
|
|
424
|
-
*/
|
|
425
|
-
interface AIChatContextState {
|
|
426
|
-
/** All chat messages */
|
|
427
|
-
messages: AIChatMessage[];
|
|
428
|
-
/** Whether a request is in progress */
|
|
429
|
-
isLoading: boolean;
|
|
430
|
-
/** Last error if any */
|
|
431
|
-
error: Error | null;
|
|
432
|
-
/** Whether chat panel is open */
|
|
433
|
-
isOpen: boolean;
|
|
434
|
-
/** Whether chat is minimized */
|
|
435
|
-
isMinimized: boolean;
|
|
436
|
-
/** Configuration */
|
|
437
|
-
config: ChatWidgetConfig;
|
|
438
|
-
/** Current display mode */
|
|
439
|
-
displayMode: ChatDisplayMode;
|
|
440
|
-
/** Is on mobile device */
|
|
441
|
-
isMobile: boolean;
|
|
442
|
-
/** Thread ID for conversation */
|
|
443
|
-
threadId: string;
|
|
444
|
-
/** User ID for conversation */
|
|
445
|
-
userId: string;
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* AI Chat context actions
|
|
449
|
-
*/
|
|
450
|
-
interface AIChatContextActions {
|
|
451
|
-
/** Send a message */
|
|
452
|
-
sendMessage: (content: string) => Promise<void>;
|
|
453
|
-
/** Clear all messages */
|
|
454
|
-
clearMessages: () => void;
|
|
455
|
-
/** Open chat panel */
|
|
456
|
-
openChat: () => void;
|
|
457
|
-
/** Close chat panel */
|
|
458
|
-
closeChat: () => void;
|
|
459
|
-
/** Toggle chat panel */
|
|
460
|
-
toggleChat: () => void;
|
|
461
|
-
/** Minimize/restore chat */
|
|
462
|
-
toggleMinimize: () => void;
|
|
463
|
-
/** Set display mode */
|
|
464
|
-
setDisplayMode: (mode: ChatDisplayMode) => void;
|
|
465
|
-
/** Stop streaming response */
|
|
466
|
-
stopStreaming: () => void;
|
|
467
|
-
}
|
|
468
|
-
type AIChatContextValue = AIChatContextState & AIChatContextActions;
|
|
469
|
-
/**
|
|
470
|
-
* AI Chat provider props
|
|
471
|
-
*/
|
|
472
|
-
interface AIChatProviderProps {
|
|
473
|
-
children: ReactNode;
|
|
474
|
-
/** API endpoint for AI chat (default: /api/ai/chat) */
|
|
475
|
-
apiEndpoint?: string;
|
|
476
|
-
/** Widget configuration */
|
|
477
|
-
config?: Partial<ChatWidgetConfig>;
|
|
478
|
-
/** Callback on error */
|
|
479
|
-
onError?: (error: Error) => void;
|
|
480
|
-
/** Enable streaming (default: true) */
|
|
481
|
-
enableStreaming?: boolean;
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* AI Chat provider component
|
|
485
|
-
* Uses useAIChat hook with server-side persistence
|
|
486
|
-
*/
|
|
487
|
-
declare function AIChatProvider({ children, apiEndpoint, config: userConfig, onError, enableStreaming, }: AIChatProviderProps): react_jsx_runtime.JSX.Element;
|
|
488
|
-
/**
|
|
489
|
-
* Hook to access AI chat context
|
|
490
|
-
*/
|
|
491
|
-
declare function useAIChatContext(): AIChatContextValue;
|
|
492
|
-
/**
|
|
493
|
-
* Hook to check if AI chat context is available
|
|
494
|
-
*/
|
|
495
|
-
declare function useAIChatContextOptional(): AIChatContextValue | null;
|
|
496
|
-
|
|
497
|
-
/**
|
|
498
|
-
* AI Chat hook with streaming support and server-side history
|
|
499
|
-
* All persistence is handled through API endpoints - no localStorage
|
|
500
|
-
*/
|
|
501
|
-
declare function useAIChat(options: UseAIChatOptions): UseAIChatReturn;
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Configuration for chat layout management
|
|
505
|
-
*/
|
|
506
|
-
interface ChatLayoutConfig {
|
|
507
|
-
/** Initial width of sidebar in pixels */
|
|
508
|
-
initialWidth?: number;
|
|
509
|
-
/** Animation duration in ms */
|
|
510
|
-
animationDuration?: number;
|
|
511
|
-
/** Element to push (defaults to body) */
|
|
512
|
-
pushTarget?: 'body' | 'main' | string;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Return type for useChatLayout hook
|
|
516
|
-
*/
|
|
517
|
-
interface UseChatLayoutReturn {
|
|
518
|
-
/** Current sidebar width */
|
|
519
|
-
sidebarWidth: number;
|
|
520
|
-
/** Apply layout changes for mode */
|
|
521
|
-
applyLayout: (mode: ChatDisplayMode) => void;
|
|
522
|
-
/** Reset layout to default */
|
|
523
|
-
resetLayout: () => void;
|
|
524
|
-
/** Update sidebar width (for resize) */
|
|
525
|
-
updateWidth: (width: number) => void;
|
|
526
|
-
/** Start resize operation */
|
|
527
|
-
startResize: (e: React.MouseEvent) => void;
|
|
528
|
-
/** Whether currently resizing */
|
|
529
|
-
isResizing: boolean;
|
|
530
|
-
/** Get CSS for sidebar container */
|
|
531
|
-
getSidebarStyles: () => React.CSSProperties;
|
|
532
|
-
/** Get CSS for floating container */
|
|
533
|
-
getFloatingStyles: (position: 'bottom-right' | 'bottom-left') => React.CSSProperties;
|
|
534
|
-
/** Get CSS for FAB button */
|
|
535
|
-
getFabStyles: (position: 'bottom-right' | 'bottom-left') => React.CSSProperties;
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Hook for managing chat layout embedding modes
|
|
539
|
-
*
|
|
540
|
-
* Handles:
|
|
541
|
-
* - Sidebar mode: pushes content left by adding margin to target element
|
|
542
|
-
* AND automatically adjusts all position:fixed elements with right:0
|
|
543
|
-
* - Floating mode: positions chat at bottom-right/left
|
|
544
|
-
* - Closed mode: just shows FAB button
|
|
545
|
-
*
|
|
546
|
-
* @example
|
|
547
|
-
* ```tsx
|
|
548
|
-
* const { applyLayout, getSidebarStyles, getFloatingStyles } = useChatLayout({
|
|
549
|
-
* sidebarWidth: 400,
|
|
550
|
-
* });
|
|
551
|
-
*
|
|
552
|
-
* useEffect(() => {
|
|
553
|
-
* applyLayout(displayMode);
|
|
554
|
-
* }, [displayMode]);
|
|
555
|
-
* ```
|
|
556
|
-
*/
|
|
557
|
-
declare function useChatLayout(config?: ChatLayoutConfig): UseChatLayoutReturn;
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Hook to send messages to MCP Chat from anywhere in the app
|
|
561
|
-
*
|
|
562
|
-
* @example
|
|
563
|
-
* ```tsx
|
|
564
|
-
* function ErrorBoundary({ error }) {
|
|
565
|
-
* const { sendToChat } = useMcpChat();
|
|
566
|
-
*
|
|
567
|
-
* const explainError = () => {
|
|
568
|
-
* sendToChat({
|
|
569
|
-
* message: `Explain this error: ${error.message}`,
|
|
570
|
-
* context: {
|
|
571
|
-
* type: 'error',
|
|
572
|
-
* data: { error: error.stack },
|
|
573
|
-
* source: 'ErrorBoundary'
|
|
574
|
-
* }
|
|
575
|
-
* });
|
|
576
|
-
* };
|
|
577
|
-
*
|
|
578
|
-
* return <button onClick={explainError}>Explain Error</button>;
|
|
579
|
-
* }
|
|
580
|
-
* ```
|
|
581
|
-
*/
|
|
582
|
-
declare function useMcpChat(): UseMcpChatReturn;
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Platform Detection Types
|
|
586
|
-
*/
|
|
587
|
-
/**
|
|
588
|
-
* Platform detection result
|
|
589
|
-
*/
|
|
590
|
-
interface PlatformInfo {
|
|
591
|
-
isIOS: boolean;
|
|
592
|
-
isAndroid: boolean;
|
|
593
|
-
isDesktop: boolean;
|
|
594
|
-
isSafari: boolean;
|
|
595
|
-
isChrome: boolean;
|
|
596
|
-
isEdge: boolean;
|
|
597
|
-
isFirefox: boolean;
|
|
598
|
-
isStandalone: boolean;
|
|
599
|
-
canPrompt: boolean;
|
|
600
|
-
shouldShowAndroidPrompt: boolean;
|
|
601
|
-
shouldShowIOSGuide: boolean;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* PWA Installation Types
|
|
606
|
-
*/
|
|
607
|
-
/**
|
|
608
|
-
* Install prompt state
|
|
609
|
-
*/
|
|
610
|
-
interface InstallPromptState {
|
|
611
|
-
isIOS: boolean;
|
|
612
|
-
isAndroid: boolean;
|
|
613
|
-
isSafari: boolean;
|
|
614
|
-
isChrome: boolean;
|
|
615
|
-
isInstalled: boolean;
|
|
616
|
-
canPrompt: boolean;
|
|
617
|
-
deferredPrompt: BeforeInstallPromptEvent | null;
|
|
618
|
-
}
|
|
619
|
-
/**
|
|
620
|
-
* BeforeInstallPrompt event (Android Chrome)
|
|
621
|
-
*/
|
|
622
|
-
interface BeforeInstallPromptEvent extends Event {
|
|
623
|
-
prompt: () => Promise<void>;
|
|
624
|
-
userChoice: Promise<{
|
|
625
|
-
outcome: 'accepted' | 'dismissed';
|
|
626
|
-
platform: string;
|
|
627
|
-
}>;
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* Install outcome
|
|
631
|
-
*/
|
|
632
|
-
type InstallOutcome = 'accepted' | 'dismissed' | null;
|
|
633
|
-
/**
|
|
634
|
-
* iOS guide dismissal state
|
|
635
|
-
*/
|
|
636
|
-
interface IOSGuideState {
|
|
637
|
-
dismissed: boolean;
|
|
638
|
-
dismissedAt: number | null;
|
|
639
|
-
shouldShow: boolean;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
/**
|
|
643
|
-
* Component Props Types
|
|
644
|
-
*/
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* Install context type
|
|
648
|
-
*/
|
|
649
|
-
interface InstallContextType {
|
|
650
|
-
platform: PlatformInfo;
|
|
651
|
-
isInstalled: boolean;
|
|
652
|
-
canPrompt: boolean;
|
|
653
|
-
showIOSGuide: boolean;
|
|
654
|
-
setShowIOSGuide: (show: boolean) => void;
|
|
655
|
-
promptInstall: () => Promise<InstallOutcome>;
|
|
656
|
-
dismissIOSGuide: () => void;
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Install manager props
|
|
660
|
-
*/
|
|
661
|
-
interface InstallManagerProps {
|
|
662
|
-
/**
|
|
663
|
-
* Delay before showing iOS guide (ms)
|
|
664
|
-
* @default 2000
|
|
665
|
-
*/
|
|
666
|
-
delayMs?: number;
|
|
667
|
-
/**
|
|
668
|
-
* Number of days before re-showing dismissed guide
|
|
669
|
-
* @default 7
|
|
670
|
-
*/
|
|
671
|
-
resetDays?: number;
|
|
672
|
-
/**
|
|
673
|
-
* Custom class name for install button
|
|
674
|
-
*/
|
|
675
|
-
buttonClassName?: string;
|
|
676
|
-
/**
|
|
677
|
-
* Custom button text
|
|
678
|
-
*/
|
|
679
|
-
buttonText?: string;
|
|
680
|
-
/**
|
|
681
|
-
* Force show install UI (ignores platform detection)
|
|
682
|
-
* Useful for testing on desktop in development
|
|
683
|
-
* @default false
|
|
684
|
-
*/
|
|
685
|
-
forceShow?: boolean;
|
|
686
|
-
/**
|
|
687
|
-
* Callback when install is successful
|
|
688
|
-
*/
|
|
689
|
-
onInstallSuccess?: () => void;
|
|
690
|
-
/**
|
|
691
|
-
* Callback when install is dismissed
|
|
692
|
-
*/
|
|
693
|
-
onInstallDismiss?: () => void;
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* Android install button props
|
|
697
|
-
*/
|
|
698
|
-
interface AndroidInstallButtonProps {
|
|
699
|
-
onInstall: () => Promise<InstallOutcome>;
|
|
700
|
-
className?: string;
|
|
701
|
-
text?: string;
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* iOS guide modal props
|
|
705
|
-
*/
|
|
706
|
-
interface IOSGuideModalProps {
|
|
707
|
-
onDismiss: () => void;
|
|
708
|
-
open?: boolean;
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Install step for iOS guide
|
|
712
|
-
*/
|
|
713
|
-
interface InstallStep {
|
|
714
|
-
number: number;
|
|
715
|
-
title: string;
|
|
716
|
-
icon: React.ComponentType<{
|
|
717
|
-
className?: string;
|
|
718
|
-
}>;
|
|
719
|
-
description: string;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
interface PwaContextValue {
|
|
723
|
-
isIOS: boolean;
|
|
724
|
-
isAndroid: boolean;
|
|
725
|
-
isDesktop: boolean;
|
|
726
|
-
isSafari: boolean;
|
|
727
|
-
isChrome: boolean;
|
|
728
|
-
isFirefox: boolean;
|
|
729
|
-
isEdge: boolean;
|
|
730
|
-
isOpera: boolean;
|
|
731
|
-
isBrave: boolean;
|
|
732
|
-
isArc: boolean;
|
|
733
|
-
isVivaldi: boolean;
|
|
734
|
-
isYandex: boolean;
|
|
735
|
-
isSamsungBrowser: boolean;
|
|
736
|
-
isUCBrowser: boolean;
|
|
737
|
-
isChromium: boolean;
|
|
738
|
-
browserName: string;
|
|
739
|
-
isInstalled: boolean;
|
|
740
|
-
canPrompt: boolean;
|
|
741
|
-
install: () => Promise<InstallOutcome>;
|
|
742
|
-
}
|
|
743
|
-
interface PwaConfig {
|
|
744
|
-
enabled?: boolean;
|
|
745
|
-
}
|
|
746
|
-
declare function PwaProvider({ children, ...config }: PwaConfig & {
|
|
747
|
-
children: ReactNode;
|
|
748
|
-
}): react_jsx_runtime.JSX.Element;
|
|
749
|
-
/**
|
|
750
|
-
* Use install context
|
|
751
|
-
* Must be used within <PwaProvider>
|
|
752
|
-
*/
|
|
753
|
-
declare function useInstall(): PwaContextValue;
|
|
754
|
-
|
|
755
|
-
interface A2HSHintProps {
|
|
756
|
-
/**
|
|
757
|
-
* Additional class names for the container
|
|
758
|
-
*/
|
|
759
|
-
className?: string;
|
|
760
|
-
/**
|
|
761
|
-
* Number of days before re-showing dismissed hint
|
|
762
|
-
* @default 3
|
|
763
|
-
* Set to null to never reset (show once forever)
|
|
764
|
-
*/
|
|
765
|
-
resetAfterDays?: number | null;
|
|
766
|
-
/**
|
|
767
|
-
* Delay before showing hint (ms)
|
|
768
|
-
* @default 3000
|
|
769
|
-
*/
|
|
770
|
-
delayMs?: number;
|
|
771
|
-
/**
|
|
772
|
-
* Demo mode - shows hint on all platforms with appropriate guides
|
|
773
|
-
* Production: only iOS Safari & Android Chrome
|
|
774
|
-
* Demo: shows on desktop too with desktop install guide
|
|
775
|
-
* @default false
|
|
776
|
-
*/
|
|
777
|
-
demo?: boolean;
|
|
778
|
-
/**
|
|
779
|
-
* App logo URL to display in hint
|
|
780
|
-
* If not provided, uses Share icon
|
|
781
|
-
*/
|
|
782
|
-
logo?: string;
|
|
783
|
-
}
|
|
784
|
-
declare function A2HSHint({ className, resetAfterDays, delayMs, demo, logo, }?: A2HSHintProps): react_jsx_runtime.JSX.Element;
|
|
785
|
-
|
|
786
|
-
declare function IOSGuide(props: IOSGuideModalProps): react_jsx_runtime.JSX.Element;
|
|
787
|
-
|
|
788
|
-
declare function DesktopGuide({ onDismiss, open }: IOSGuideModalProps): react_jsx_runtime.JSX.Element;
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* Options for useIsPWA hook
|
|
792
|
-
*/
|
|
793
|
-
interface UseIsPWAOptions {
|
|
794
|
-
/**
|
|
795
|
-
* Use reliable check with additional validation for desktop browsers
|
|
796
|
-
* This prevents false positives on Safari macOS "Add to Dock"
|
|
797
|
-
* @default false
|
|
798
|
-
*/
|
|
799
|
-
reliable?: boolean;
|
|
800
|
-
}
|
|
801
|
-
/**
|
|
802
|
-
* Hook to detect if app is running as PWA (standalone mode)
|
|
803
|
-
*
|
|
804
|
-
* @param options - Configuration options
|
|
805
|
-
* @returns true if app is running as PWA
|
|
806
|
-
*/
|
|
807
|
-
declare function useIsPWA(options?: UseIsPWAOptions): boolean;
|
|
808
|
-
/**
|
|
809
|
-
* Clear isPWA cache
|
|
810
|
-
*
|
|
811
|
-
* Useful for testing or when you want to force a re-check
|
|
812
|
-
*
|
|
813
|
-
* @example
|
|
814
|
-
* ```typescript
|
|
815
|
-
* import { clearIsPWACache } from '@djangocfg/layouts/snippets';
|
|
816
|
-
* clearIsPWACache();
|
|
817
|
-
* window.location.reload();
|
|
818
|
-
* ```
|
|
819
|
-
*/
|
|
820
|
-
declare function clearIsPWACache(): void;
|
|
821
|
-
|
|
822
|
-
/**
|
|
823
|
-
* Platform Detection Utilities
|
|
824
|
-
*
|
|
825
|
-
* Centralized utilities for detecting PWA state, platform, and capabilities.
|
|
826
|
-
* Used by hooks to avoid code duplication.
|
|
827
|
-
*/
|
|
828
|
-
/**
|
|
829
|
-
* Check if running as PWA (standalone mode)
|
|
830
|
-
*
|
|
831
|
-
* Checks if the app is running in standalone mode (added to home screen).
|
|
832
|
-
* This is the primary indicator that a PWA has been installed.
|
|
833
|
-
*
|
|
834
|
-
* @returns true if app is running in standalone mode
|
|
835
|
-
*
|
|
836
|
-
* @example
|
|
837
|
-
* ```typescript
|
|
838
|
-
* if (isStandalone()) {
|
|
839
|
-
* console.log('Running as PWA');
|
|
840
|
-
* }
|
|
841
|
-
* ```
|
|
842
|
-
*/
|
|
843
|
-
declare function isStandalone(): boolean;
|
|
844
|
-
/**
|
|
845
|
-
* Check if device is mobile
|
|
846
|
-
*
|
|
847
|
-
* @returns true if device is mobile (iOS, Android, etc.)
|
|
848
|
-
*/
|
|
849
|
-
declare function isMobileDevice(): boolean;
|
|
850
|
-
/**
|
|
851
|
-
* Check if web app manifest exists and is valid
|
|
852
|
-
*
|
|
853
|
-
* @returns true if manifest link exists in document head
|
|
854
|
-
*/
|
|
855
|
-
declare function hasValidManifest(): boolean;
|
|
856
|
-
/**
|
|
857
|
-
* Reliable check for PWA mode with edge case handling
|
|
858
|
-
*
|
|
859
|
-
* This function provides additional validation for desktop browsers
|
|
860
|
-
* to avoid false positives (e.g., Safari macOS "Add to Dock").
|
|
861
|
-
*
|
|
862
|
-
* For mobile devices, standard standalone check is sufficient.
|
|
863
|
-
* For desktop, additionally validates that a manifest exists.
|
|
864
|
-
*
|
|
865
|
-
* @returns true if app is running as a genuine PWA
|
|
866
|
-
*
|
|
867
|
-
* @example
|
|
868
|
-
* ```typescript
|
|
869
|
-
* // Use this for more reliable detection
|
|
870
|
-
* if (isStandaloneReliable()) {
|
|
871
|
-
* console.log('Definitely running as PWA');
|
|
872
|
-
* }
|
|
873
|
-
* ```
|
|
874
|
-
*/
|
|
875
|
-
declare function isStandaloneReliable(): boolean;
|
|
876
|
-
/**
|
|
877
|
-
* Get display mode from media query
|
|
878
|
-
*
|
|
879
|
-
* @returns Current display mode: 'standalone', 'fullscreen', 'minimal-ui', or 'browser'
|
|
880
|
-
*/
|
|
881
|
-
declare function getDisplayMode(): 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
|
|
882
|
-
/**
|
|
883
|
-
* Create a media query listener for display-mode changes
|
|
884
|
-
*
|
|
885
|
-
* @param callback - Function to call when display mode changes
|
|
886
|
-
* @returns Cleanup function to remove listener
|
|
887
|
-
*
|
|
888
|
-
* @example
|
|
889
|
-
* ```typescript
|
|
890
|
-
* const cleanup = onDisplayModeChange((isStandalone) => {
|
|
891
|
-
* console.log('Display mode changed:', isStandalone);
|
|
892
|
-
* });
|
|
893
|
-
*
|
|
894
|
-
* // Later: cleanup();
|
|
895
|
-
* ```
|
|
896
|
-
*/
|
|
897
|
-
declare function onDisplayModeChange(callback: (isStandalone: boolean) => void): () => void;
|
|
898
|
-
|
|
899
|
-
/**
|
|
900
|
-
* LocalStorage utilities for PWA install state persistence
|
|
901
|
-
*/
|
|
902
|
-
|
|
903
|
-
/**
|
|
904
|
-
* Clear all PWA install data
|
|
905
|
-
*/
|
|
906
|
-
declare function clearAllPWAInstallData(): void;
|
|
907
|
-
|
|
908
|
-
/**
|
|
909
|
-
* Push Notification Types
|
|
910
|
-
*/
|
|
911
|
-
/**
|
|
912
|
-
* Push notification state
|
|
913
|
-
*/
|
|
914
|
-
interface PushNotificationState {
|
|
915
|
-
isSupported: boolean;
|
|
916
|
-
permission: NotificationPermission;
|
|
917
|
-
isSubscribed: boolean;
|
|
918
|
-
subscription: PushSubscription | null;
|
|
919
|
-
}
|
|
920
|
-
/**
|
|
921
|
-
* Push notification options
|
|
922
|
-
*/
|
|
923
|
-
interface PushNotificationOptions {
|
|
924
|
-
vapidPublicKey: string;
|
|
925
|
-
subscribeEndpoint?: string;
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
interface PushMessage {
|
|
929
|
-
id: string;
|
|
930
|
-
title: string;
|
|
931
|
-
body: string;
|
|
932
|
-
icon?: string;
|
|
933
|
-
badge?: string;
|
|
934
|
-
tag?: string;
|
|
935
|
-
timestamp: number;
|
|
936
|
-
data?: Record<string, unknown>;
|
|
937
|
-
}
|
|
938
|
-
interface DjangoPushContextValue {
|
|
939
|
-
isSupported: boolean;
|
|
940
|
-
permission: NotificationPermission;
|
|
941
|
-
isSubscribed: boolean;
|
|
942
|
-
subscription: PushSubscription | null;
|
|
943
|
-
isLoading: boolean;
|
|
944
|
-
error: Error | null;
|
|
945
|
-
pushes: PushMessage[];
|
|
946
|
-
subscribe: () => Promise<boolean>;
|
|
947
|
-
unsubscribe: () => Promise<boolean>;
|
|
948
|
-
sendTestPush: (message: {
|
|
949
|
-
title: string;
|
|
950
|
-
body: string;
|
|
951
|
-
url?: string;
|
|
952
|
-
}) => Promise<boolean>;
|
|
953
|
-
sendPush: (message: Omit<PushMessage, 'id' | 'timestamp'>) => Promise<void>;
|
|
954
|
-
clearPushes: () => void;
|
|
955
|
-
removePush: (id: string) => void;
|
|
956
|
-
}
|
|
957
|
-
interface DjangoPushProviderProps extends PushNotificationOptions {
|
|
958
|
-
children: React$1.ReactNode;
|
|
959
|
-
/**
|
|
960
|
-
* Auto-subscribe on mount if permission granted
|
|
961
|
-
* @default false
|
|
962
|
-
*/
|
|
963
|
-
autoSubscribe?: boolean;
|
|
964
|
-
/**
|
|
965
|
-
* Callback when subscription created
|
|
966
|
-
*/
|
|
967
|
-
onSubscribed?: (subscription: PushSubscription) => void;
|
|
968
|
-
/**
|
|
969
|
-
* Callback when subscription failed
|
|
970
|
-
*/
|
|
971
|
-
onSubscribeError?: (error: Error) => void;
|
|
972
|
-
/**
|
|
973
|
-
* Callback when unsubscribed
|
|
974
|
-
*/
|
|
975
|
-
onUnsubscribed?: () => void;
|
|
976
|
-
}
|
|
977
|
-
/**
|
|
978
|
-
* Provider for Django push notifications
|
|
979
|
-
*/
|
|
980
|
-
declare function DjangoPushProvider({ children, vapidPublicKey, autoSubscribe, onSubscribed, onSubscribeError, onUnsubscribed, }: DjangoPushProviderProps): react_jsx_runtime.JSX.Element;
|
|
981
|
-
/**
|
|
982
|
-
* Hook to access Django push context
|
|
983
|
-
*/
|
|
984
|
-
declare function useDjangoPushContext(): DjangoPushContextValue;
|
|
985
|
-
|
|
986
|
-
interface PushPromptProps extends PushNotificationOptions {
|
|
987
|
-
/**
|
|
988
|
-
* Only show if PWA is installed
|
|
989
|
-
* @default true
|
|
990
|
-
*/
|
|
991
|
-
requirePWA?: boolean;
|
|
992
|
-
/**
|
|
993
|
-
* Delay before showing prompt (ms)
|
|
994
|
-
* @default 5000
|
|
995
|
-
*/
|
|
996
|
-
delayMs?: number;
|
|
997
|
-
/**
|
|
998
|
-
* Number of days before re-showing dismissed prompt
|
|
999
|
-
* @default 7
|
|
1000
|
-
*/
|
|
1001
|
-
resetAfterDays?: number;
|
|
1002
|
-
/**
|
|
1003
|
-
* Callback when push is enabled
|
|
1004
|
-
*/
|
|
1005
|
-
onEnabled?: () => void;
|
|
1006
|
-
/**
|
|
1007
|
-
* Callback when push is dismissed
|
|
1008
|
-
*/
|
|
1009
|
-
onDismissed?: () => void;
|
|
1010
|
-
}
|
|
1011
|
-
declare function PushPrompt({ vapidPublicKey, subscribeEndpoint, requirePWA, delayMs, resetAfterDays, onEnabled, onDismissed, }: PushPromptProps): react_jsx_runtime.JSX.Element;
|
|
1012
|
-
|
|
1013
|
-
declare function usePushNotifications(options?: PushNotificationOptions): {
|
|
1014
|
-
subscribe: () => Promise<PushSubscription | null>;
|
|
1015
|
-
unsubscribe: () => Promise<boolean>;
|
|
1016
|
-
isSupported: boolean;
|
|
1017
|
-
permission: NotificationPermission;
|
|
1018
|
-
isSubscribed: boolean;
|
|
1019
|
-
subscription: PushSubscription | null;
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
|
-
interface UseDjangoPushOptions extends PushNotificationOptions {
|
|
1023
|
-
/**
|
|
1024
|
-
* Callback when subscription created
|
|
1025
|
-
*/
|
|
1026
|
-
onSubscribed?: (subscription: PushSubscription) => void;
|
|
1027
|
-
/**
|
|
1028
|
-
* Callback when subscription failed
|
|
1029
|
-
*/
|
|
1030
|
-
onSubscribeError?: (error: Error) => void;
|
|
1031
|
-
/**
|
|
1032
|
-
* Callback when unsubscribed
|
|
1033
|
-
*/
|
|
1034
|
-
onUnsubscribed?: () => void;
|
|
1035
|
-
}
|
|
1036
|
-
interface UseDjangoPushReturn {
|
|
1037
|
-
isSupported: boolean;
|
|
1038
|
-
permission: NotificationPermission;
|
|
1039
|
-
isSubscribed: boolean;
|
|
1040
|
-
subscription: PushSubscription | null;
|
|
1041
|
-
isLoading: boolean;
|
|
1042
|
-
error: Error | null;
|
|
1043
|
-
subscribe: () => Promise<boolean>;
|
|
1044
|
-
unsubscribe: () => Promise<boolean>;
|
|
1045
|
-
sendTestPush: (message: {
|
|
1046
|
-
title: string;
|
|
1047
|
-
body: string;
|
|
1048
|
-
url?: string;
|
|
1049
|
-
}) => Promise<boolean>;
|
|
1050
|
-
}
|
|
1051
|
-
/**
|
|
1052
|
-
* Hook for Django-CFG push notifications integration
|
|
1053
|
-
*/
|
|
1054
|
-
declare function useDjangoPush(options: UseDjangoPushOptions): UseDjangoPushReturn;
|
|
1055
|
-
|
|
1056
|
-
/**
|
|
1057
|
-
* Push Notifications Configuration
|
|
1058
|
-
*
|
|
1059
|
-
* Centralized constants for push notifications functionality.
|
|
1060
|
-
*
|
|
1061
|
-
* SECURITY NOTE:
|
|
1062
|
-
* - VAPID_PRIVATE_KEY should NEVER be in frontend code
|
|
1063
|
-
* - Private keys must only exist in backend/API routes
|
|
1064
|
-
* - Frontend only needs the public key (NEXT_PUBLIC_* env vars)
|
|
1065
|
-
* - VAPID_MAILTO should also remain on backend only
|
|
1066
|
-
*/
|
|
1067
|
-
declare const DEFAULT_VAPID_PUBLIC_KEY: string;
|
|
1068
|
-
|
|
1069
|
-
/**
|
|
1070
|
-
* VAPID Key Utilities
|
|
1071
|
-
*
|
|
1072
|
-
* Provides validation and conversion utilities for VAPID public keys
|
|
1073
|
-
* used in push notification subscriptions.
|
|
1074
|
-
*
|
|
1075
|
-
* VAPID keys must be:
|
|
1076
|
-
* - Base64url encoded
|
|
1077
|
-
* - 65 bytes after decoding (P-256 uncompressed public key)
|
|
1078
|
-
* - Start with 0x04 (uncompressed point indicator)
|
|
1079
|
-
*/
|
|
1080
|
-
/**
|
|
1081
|
-
* Custom error class for VAPID key validation failures
|
|
1082
|
-
*/
|
|
1083
|
-
declare class VapidKeyError extends Error {
|
|
1084
|
-
readonly code: VapidKeyErrorCode;
|
|
1085
|
-
constructor(message: string, code: VapidKeyErrorCode);
|
|
1086
|
-
}
|
|
1087
|
-
/**
|
|
1088
|
-
* Error codes for VAPID key validation
|
|
1089
|
-
*/
|
|
1090
|
-
type VapidKeyErrorCode = 'VAPID_EMPTY' | 'VAPID_INVALID_TYPE' | 'VAPID_INVALID_BASE64' | 'VAPID_INVALID_LENGTH' | 'VAPID_INVALID_FORMAT';
|
|
1091
|
-
/**
|
|
1092
|
-
* Convert base64url VAPID public key to Uint8Array
|
|
1093
|
-
*
|
|
1094
|
-
* Validates and converts a VAPID public key from base64url format
|
|
1095
|
-
* to Uint8Array for use with PushManager.subscribe().
|
|
1096
|
-
*
|
|
1097
|
-
* @param base64String - VAPID public key in base64url format
|
|
1098
|
-
* @returns Uint8Array ready for pushManager.subscribe()
|
|
1099
|
-
* @throws VapidKeyError if key is invalid
|
|
1100
|
-
*
|
|
1101
|
-
* @example
|
|
1102
|
-
* ```typescript
|
|
1103
|
-
* try {
|
|
1104
|
-
* const key = urlBase64ToUint8Array(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY);
|
|
1105
|
-
* await registration.pushManager.subscribe({
|
|
1106
|
-
* userVisibleOnly: true,
|
|
1107
|
-
* applicationServerKey: key,
|
|
1108
|
-
* });
|
|
1109
|
-
* } catch (e) {
|
|
1110
|
-
* if (e instanceof VapidKeyError) {
|
|
1111
|
-
* console.error('Invalid VAPID key:', e.message, e.code);
|
|
1112
|
-
* }
|
|
1113
|
-
* }
|
|
1114
|
-
* ```
|
|
1115
|
-
*/
|
|
1116
|
-
declare function urlBase64ToUint8Array(base64String: string): Uint8Array;
|
|
1117
|
-
/**
|
|
1118
|
-
* Validate VAPID key without conversion
|
|
1119
|
-
*
|
|
1120
|
-
* Checks if a VAPID key is valid without converting it.
|
|
1121
|
-
* Useful for validation before attempting subscription.
|
|
1122
|
-
*
|
|
1123
|
-
* @param base64String - VAPID public key to validate
|
|
1124
|
-
* @returns true if key is valid
|
|
1125
|
-
*
|
|
1126
|
-
* @example
|
|
1127
|
-
* ```typescript
|
|
1128
|
-
* if (isValidVapidKey(vapidKey)) {
|
|
1129
|
-
* // Proceed with subscription
|
|
1130
|
-
* } else {
|
|
1131
|
-
* console.error('Invalid VAPID key configuration');
|
|
1132
|
-
* }
|
|
1133
|
-
* ```
|
|
1134
|
-
*/
|
|
1135
|
-
declare function isValidVapidKey(base64String: string): boolean;
|
|
1136
|
-
/**
|
|
1137
|
-
* Get VAPID key information for debugging
|
|
1138
|
-
*
|
|
1139
|
-
* Returns detailed information about a VAPID key for troubleshooting.
|
|
1140
|
-
*
|
|
1141
|
-
* @param base64String - VAPID public key to inspect
|
|
1142
|
-
* @returns Key information object
|
|
1143
|
-
*
|
|
1144
|
-
* @example
|
|
1145
|
-
* ```typescript
|
|
1146
|
-
* const info = getVapidKeyInfo(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY);
|
|
1147
|
-
* console.log('VAPID Key Info:', info);
|
|
1148
|
-
* // {
|
|
1149
|
-
* // valid: true,
|
|
1150
|
-
* // length: 65,
|
|
1151
|
-
* // firstByte: '0x04',
|
|
1152
|
-
* // format: 'P-256 uncompressed'
|
|
1153
|
-
* // }
|
|
1154
|
-
* ```
|
|
1155
|
-
*/
|
|
1156
|
-
declare function getVapidKeyInfo(base64String: string): {
|
|
1157
|
-
valid: boolean;
|
|
1158
|
-
length?: number;
|
|
1159
|
-
firstByte?: string;
|
|
1160
|
-
format?: string;
|
|
1161
|
-
error?: string;
|
|
1162
|
-
errorCode?: VapidKeyErrorCode;
|
|
1163
|
-
};
|
|
1164
|
-
/**
|
|
1165
|
-
* Safe VAPID key conversion with error handling
|
|
1166
|
-
*
|
|
1167
|
-
* Attempts to convert a VAPID key with detailed error logging.
|
|
1168
|
-
* Returns null on failure instead of throwing.
|
|
1169
|
-
*
|
|
1170
|
-
* @param base64String - VAPID public key
|
|
1171
|
-
* @param onError - Optional error callback
|
|
1172
|
-
* @returns Uint8Array or null if conversion fails
|
|
1173
|
-
*
|
|
1174
|
-
* @example
|
|
1175
|
-
* ```typescript
|
|
1176
|
-
* const key = safeUrlBase64ToUint8Array(vapidKey, (error) => {
|
|
1177
|
-
* console.error('VAPID conversion failed:', error.message, error.code);
|
|
1178
|
-
* });
|
|
1179
|
-
*
|
|
1180
|
-
* if (key) {
|
|
1181
|
-
* // Use key for subscription
|
|
1182
|
-
* }
|
|
1183
|
-
* ```
|
|
1184
|
-
*/
|
|
1185
|
-
declare function safeUrlBase64ToUint8Array(base64String: string, onError?: (error: VapidKeyError) => void): Uint8Array | null;
|
|
1186
|
-
|
|
1187
|
-
/**
|
|
1188
|
-
* Clear all push notification data
|
|
1189
|
-
*/
|
|
1190
|
-
declare function clearAllPushData(): void;
|
|
1191
|
-
|
|
1192
|
-
export { A2HSHint, type AIChatApiResponse, type AIChatContextActions, type AIChatContextState, type AIChatContextValue, type AIChatMessage, AIChatProvider, type AIChatProviderProps, type AIChatSource, AIChatWidget, type AIChatWidgetProps, AIMessageInput, type AIMessageInputProps, type AIMessageRole, AUTH_EVENTS, Analytics, AnalyticsCategory, type AnalyticsCategoryType, type AnalyticsConfig, AnalyticsEvent, type AnalyticsEventType, AnalyticsProvider, type AndroidInstallButtonProps, AskAIButton, type AskAIButtonProps, AuthDialog, type AuthEventType, type AuthFailurePayload, type AuthSuccessPayload, type BeforeInstallPromptEvent, type BreadcrumbItem, type ChatLayoutConfig, ChatPanel, type ChatWidgetConfig, DEFAULT_VAPID_PUBLIC_KEY, DIALOG_EVENTS, DesktopGuide, DjangoPushProvider, IOSGuide, type IOSGuideModalProps, type IOSGuideState, type InstallContextType, type InstallManagerProps, type InstallOutcome, type InstallPromptState, type InstallStep, type McpChatContextType, type McpChatEventDetail, MessageBubble, type MessageBubbleProps, type OpenAuthDialogPayload, type PlatformInfo, type PushMessage, type PushNotificationOptions, type PushNotificationState, PushPrompt, DjangoPushProvider as PushProvider, PwaProvider, type UseAIChatOptions, type UseAIChatReturn, type UseChatLayoutReturn, type UseIsPWAOptions, type UseMcpChatReturn, VapidKeyError, type VapidKeyErrorCode, clearAllPWAInstallData, clearAllPushData, clearIsPWACache, generateBreadcrumbsFromPath, getDisplayMode, getVapidKeyInfo, hasValidManifest, isMobileDevice, isStandalone, isStandaloneReliable, isValidVapidKey, onDisplayModeChange, safeUrlBase64ToUint8Array, urlBase64ToUint8Array, useAIChat, useAIChatContext, useAIChatContextOptional, useAnalytics, useAuthDialog, useChatLayout, useDjangoPush, useDjangoPushContext, useInstall, useIsPWA, useMcpChat, useDjangoPushContext as usePush, usePushNotifications };
|