@djangocfg/layouts 2.1.101 → 2.1.103

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 (49) hide show
  1. package/dist/AIChatWidget-LUPM7S2O.mjs +1644 -0
  2. package/dist/AIChatWidget-LUPM7S2O.mjs.map +1 -0
  3. package/dist/AIChatWidget-O23TJJ7C.mjs +3 -0
  4. package/dist/AIChatWidget-O23TJJ7C.mjs.map +1 -0
  5. package/dist/chunk-53YKWR6F.mjs +6 -0
  6. package/dist/chunk-53YKWR6F.mjs.map +1 -0
  7. package/dist/chunk-EI7TDN2G.mjs +1652 -0
  8. package/dist/chunk-EI7TDN2G.mjs.map +1 -0
  9. package/dist/components.cjs +925 -0
  10. package/dist/components.cjs.map +1 -0
  11. package/dist/components.d.mts +583 -0
  12. package/dist/components.d.ts +583 -0
  13. package/dist/components.mjs +879 -0
  14. package/dist/components.mjs.map +1 -0
  15. package/dist/index.cjs +7573 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.mts +2376 -0
  18. package/dist/index.d.ts +2376 -0
  19. package/dist/index.mjs +5673 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/layouts.cjs +6530 -0
  22. package/dist/layouts.cjs.map +1 -0
  23. package/dist/layouts.d.mts +748 -0
  24. package/dist/layouts.d.ts +748 -0
  25. package/dist/layouts.mjs +4741 -0
  26. package/dist/layouts.mjs.map +1 -0
  27. package/dist/pages.cjs +178 -0
  28. package/dist/pages.cjs.map +1 -0
  29. package/dist/pages.d.mts +57 -0
  30. package/dist/pages.d.ts +57 -0
  31. package/dist/pages.mjs +168 -0
  32. package/dist/pages.mjs.map +1 -0
  33. package/dist/snippets.cjs +3793 -0
  34. package/dist/snippets.cjs.map +1 -0
  35. package/dist/snippets.d.mts +1192 -0
  36. package/dist/snippets.d.ts +1192 -0
  37. package/dist/snippets.mjs +3738 -0
  38. package/dist/snippets.mjs.map +1 -0
  39. package/dist/utils.cjs +34 -0
  40. package/dist/utils.cjs.map +1 -0
  41. package/dist/utils.d.mts +40 -0
  42. package/dist/utils.d.ts +40 -0
  43. package/dist/utils.mjs +25 -0
  44. package/dist/utils.mjs.map +1 -0
  45. package/package.json +38 -47
  46. package/src/components/errors/ErrorsTracker/components/ErrorButtons.tsx +2 -1
  47. package/src/layouts/ProfileLayout/ProfileLayout.tsx +507 -86
  48. package/src/layouts/ProfileLayout/components/DeleteAccountSection.tsx +2 -2
  49. package/src/snippets/AuthDialog/useAuthDialog.ts +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/snippets/Breadcrumbs.tsx","../src/snippets/AuthDialog/AuthDialog.tsx","../src/snippets/AuthDialog/events.ts","../src/snippets/AuthDialog/useAuthDialog.ts","../src/snippets/Analytics/useAnalytics.ts","../src/snippets/Analytics/AnalyticsProvider.tsx","../src/snippets/Analytics/events.ts","../src/snippets/McpChat/config.ts","../src/snippets/McpChat/context/ChatContext.tsx","../src/snippets/McpChat/hooks/useAIChat.ts","../src/snippets/McpChat/context/AIChatContext.tsx","../src/snippets/McpChat/hooks/useChatLayout.ts","../src/snippets/McpChat/components/MessageBubble.tsx","../src/snippets/McpChat/components/ChatMessages.tsx","../src/snippets/McpChat/components/MessageInput.tsx","../src/snippets/McpChat/components/ChatPanel.tsx","../src/snippets/McpChat/components/ChatSidebar.tsx","../src/snippets/McpChat/components/ChatWidget.tsx","../src/snippets/McpChat/components/AIChatWidget.tsx","../src/snippets/McpChat/hooks/useMcpChat.ts","../src/snippets/McpChat/components/AskAIButton.tsx","../src/snippets/PWAInstall/utils/localStorage.ts","../src/snippets/PWAInstall/utils/logger.ts","../src/snippets/PWAInstall/utils/platform.ts","../src/snippets/PWAInstall/hooks/useInstallPrompt.ts","../src/snippets/PWAInstall/context/InstallContext.tsx","../src/snippets/PWAInstall/components/DesktopGuide.tsx","../src/snippets/PWAInstall/components/IOSGuideDrawer.tsx","../src/snippets/PWAInstall/components/IOSGuideModal.tsx","../src/snippets/PWAInstall/components/IOSGuide.tsx","../src/snippets/PWAInstall/components/A2HSHint.tsx","../src/snippets/PWAInstall/hooks/useIsPWA.ts","../src/snippets/PushNotifications/utils/logger.ts","../src/snippets/PushNotifications/utils/platform.ts","../src/snippets/PushNotifications/utils/vapid.ts","../src/snippets/PushNotifications/hooks/usePushNotifications.ts","../src/snippets/PushNotifications/hooks/useDjangoPush.ts","../src/snippets/PushNotifications/context/DjangoPushContext.tsx","../src/snippets/PushNotifications/utils/localStorage.ts","../src/snippets/PushNotifications/components/PushPrompt.tsx","../src/snippets/PushNotifications/config.ts"],"names":["useState","useCfgRouter","useEventListener","jsx","Dialog","jsxs","DialogContent","DialogHeader","DialogTitle","Button","LogIn","useCallback","events","ReactGA","usePathname","useAuth","useEffect","Fragment","createContext","useRef","useLocalStorage","useIsMobile","uuidv4","useMemo","error","useContext","React","Avatar","AvatarImage","AvatarFallback","User","Bot","Card","CardContent","MarkdownMessage","Loader2","Badge","ExternalLink","forwardRef","useImperativeHandle","MessageSquare","StopCircle","Send","CardHeader","RotateCcw","PanelRight","X","CardFooter","GripVertical","PanelRightClose","Portal","MessageCircle","Zap","consola","nav","useBrowserDetect","useDeviceDetect","ArrowDownToLine","Plus","Check","Menu","Search","Monitor","steps","DialogDescription","DialogFooter","ArrowUpRight","ArrowDown","CheckCircle","StepCard","Drawer","DrawerContent","DrawerHeader","DrawerTitle","Share","DrawerDescription","ChevronRight","Download","cn","isDebugEnabled","pwaLogger","isStandalone","apiWebPush","toast","STORAGE_KEYS","isDismissedRecentlyHelper","DEFAULT_RESET_DAYS","Bell"],"mappings":"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","file":"snippets.cjs","sourcesContent":["\"use client\";\nimport { ChevronRight, Home } from 'lucide-react';\nimport Link from 'next/link';\nimport { usePathname } from 'next/navigation';\nimport React from 'react';\n\nexport interface BreadcrumbItem {\n path: string;\n label: string;\n isActive: boolean;\n}\n\ninterface BreadcrumbsProps {\n items?: BreadcrumbItem[];\n className?: string;\n}\n\nconst Breadcrumbs: React.FC<BreadcrumbsProps> = ({ items, className = \"\" }) => {\n const pathname = usePathname();\n \n // Use provided items or generate from pathname\n const breadcrumbs = items || generateBreadcrumbsFromPath(pathname);\n\n if (breadcrumbs.length <= 1) {\n return null;\n }\n\n return (\n <nav className={`flex items-center space-x-2 text-sm ${className}`} aria-label=\"Breadcrumb\">\n <ol className=\"flex items-center space-x-2\">\n {breadcrumbs.map((item: BreadcrumbItem, index: number) => (\n <li key={item.path} className=\"flex items-center\">\n {index > 0 && (\n <ChevronRight className=\"w-4 h-4 text-gray-400 mx-2\" />\n )}\n \n {item.isActive ? (\n <span className=\"text-gray-900 dark:text-white font-medium flex items-center gap-1\">\n {index === 0 && <Home className=\"w-4 h-4\" />}\n {item.label}\n </span>\n ) : (\n <Link\n href={item.path}\n className=\"text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 \n transition-colors duration-200 flex items-center gap-1 hover:underline\"\n >\n {index === 0 && <Home className=\"w-4 h-4\" />}\n {item.label}\n </Link>\n )}\n </li>\n ))}\n </ol>\n </nav>\n );\n};\n\n// Helper function to generate breadcrumbs from pathname\nfunction generateBreadcrumbsFromPath(pathname: string): BreadcrumbItem[] {\n const segments = pathname.split('/').filter(Boolean);\n const breadcrumbs: BreadcrumbItem[] = [\n { path: '/', label: 'Home', isActive: pathname === '/' }\n ];\n\n let currentPath = '';\n segments.forEach((segment, index) => {\n currentPath += `/${segment}`;\n breadcrumbs.push({\n path: currentPath,\n label: segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' '),\n isActive: index === segments.length - 1\n });\n });\n\n return breadcrumbs;\n}\n\nexport default Breadcrumbs;\nexport { generateBreadcrumbsFromPath };","'use client';\n\nimport { LogIn } from 'lucide-react';\nimport React, { useState } from 'react';\n\nimport {\n Button, Dialog, DialogContent, DialogHeader, DialogTitle\n} from '@djangocfg/ui-nextjs/components';\nimport { useCfgRouter, useEventListener } from '@djangocfg/ui-nextjs/hooks';\n\n// Re-export events for backwards compatibility\nexport const DIALOG_EVENTS = {\n OPEN_AUTH_DIALOG: 'OPEN_AUTH_DIALOG',\n CLOSE_AUTH_DIALOG: 'CLOSE_AUTH_DIALOG',\n AUTH_SUCCESS: 'AUTH_SUCCESS',\n AUTH_FAILURE: 'AUTH_FAILURE',\n} as const;\n\ninterface AuthDialogProps {\n onAuthRequired?: () => void;\n authPath?: string;\n}\n\nexport const AuthDialog: React.FC<AuthDialogProps> = ({\n onAuthRequired,\n authPath = '/auth'\n}) => {\n const [open, setOpen] = useState(false);\n const [message, setMessage] = useState<string>('Please sign in to continue');\n const router = useCfgRouter();\n\n // Listen for open auth dialog event\n useEventListener(DIALOG_EVENTS.OPEN_AUTH_DIALOG, (payload: any) => {\n if (payload?.message) {\n setMessage(payload.message);\n }\n setOpen(true);\n });\n\n // Listen for close auth dialog event\n useEventListener(DIALOG_EVENTS.CLOSE_AUTH_DIALOG, () => {\n setOpen(false);\n });\n\n const handleClose = () => {\n setMessage('Please sign in to continue');\n setOpen(false);\n };\n\n const handleGoToAuth = () => {\n // Save current URL for redirect after successful auth\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('redirectAfterAuth', window.location.pathname);\n }\n\n if (onAuthRequired) {\n onAuthRequired();\n } else {\n router.push(authPath);\n }\n\n handleClose();\n };\n\n return (\n <Dialog open={open} onOpenChange={handleClose}>\n <DialogContent className=\"max-w-sm\">\n <DialogHeader>\n <DialogTitle>Authentication Required</DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">{message}</p>\n\n <Button onClick={handleGoToAuth} className=\"w-full\">\n <LogIn className=\"h-4 w-4 mr-2\" />\n Go to Sign In\n </Button>\n </div>\n </DialogContent>\n </Dialog>\n );\n};\n","export const AUTH_EVENTS = {\n OPEN_AUTH_DIALOG: 'OPEN_AUTH_DIALOG',\n CLOSE_AUTH_DIALOG: 'CLOSE_AUTH_DIALOG',\n AUTH_SUCCESS: 'AUTH_SUCCESS',\n AUTH_FAILURE: 'AUTH_FAILURE',\n} as const;\n\nexport type AuthEventType = typeof AUTH_EVENTS[keyof typeof AUTH_EVENTS];\n\nexport interface OpenAuthDialogPayload {\n message?: string;\n redirectUrl?: string;\n}\n\nexport interface AuthSuccessPayload {\n user?: any;\n}\n\nexport interface AuthFailurePayload {\n error?: string;\n}\n","\"use client\"\n\nimport { useCallback } from 'react';\n\nimport { events } from '@djangocfg/ui-core/hooks';\n\nimport { AUTH_EVENTS, OpenAuthDialogPayload} from './events';\n\n/**\n * Hook to control auth dialog from anywhere in the app\n */\nexport function useAuthDialog() {\n const openAuthDialog = useCallback((options?: OpenAuthDialogPayload) => {\n events.publish({\n type: AUTH_EVENTS.OPEN_AUTH_DIALOG,\n payload: options,\n });\n }, []);\n\n const closeAuthDialog = useCallback(() => {\n events.publish({\n type: AUTH_EVENTS.CLOSE_AUTH_DIALOG,\n });\n }, []);\n\n return {\n openAuthDialog,\n closeAuthDialog,\n };\n}\n","/**\n * useAnalytics Hook\n *\n * Provides Google Analytics tracking via react-ga4\n * Automatically tracks page views on route changes\n * Only works in production mode\n */\n\n'use client';\n\nimport { usePathname } from 'next/navigation';\nimport { useEffect } from 'react';\nimport ReactGA from 'react-ga4';\n\nimport { useAuth } from '@djangocfg/api/auth';\n\n// Check if we're in production\nconst isProduction = process.env.NODE_ENV === 'production';\n\n// Tracking state\nlet isInitialized = false;\nlet currentTrackingId: string | undefined;\n\n/**\n * Analytics utility object for standalone usage (outside React components)\n *\n * @example\n * ```ts\n * import { Analytics } from '@djangocfg/layouts';\n *\n * // In an event handler or utility function\n * Analytics.event('button_click', { category: 'engagement', label: 'signup' });\n * ```\n */\nexport const Analytics = {\n /**\n * Initialize Google Analytics (called automatically by useAnalytics hook)\n */\n init: (trackingId: string) => {\n if (!isProduction || !trackingId || isInitialized) return;\n ReactGA.initialize(trackingId);\n isInitialized = true;\n currentTrackingId = trackingId;\n },\n\n /**\n * Check if Analytics is enabled and initialized\n */\n isEnabled: () => isProduction && isInitialized,\n\n /**\n * Track a page view\n */\n pageview: (path: string) => {\n if (!Analytics.isEnabled()) return;\n ReactGA.send({ hitType: 'pageview', page: path });\n },\n\n /**\n * Track a custom event\n * @param name - Event name (action)\n * @param params - Optional event parameters\n */\n event: (name: string, params: Record<string, any> = {}) => {\n if (!Analytics.isEnabled()) return;\n ReactGA.event(name, params);\n },\n\n /**\n * Set user ID for tracking\n */\n setUser: (userId: string) => {\n if (!Analytics.isEnabled()) return;\n ReactGA.set({ user_id: userId });\n },\n\n /**\n * Set custom dimensions/metrics\n */\n set: (fieldsObject: Record<string, any>) => {\n if (!Analytics.isEnabled()) return;\n ReactGA.set(fieldsObject);\n },\n};\n\n/**\n * Hook for Google Analytics tracking via react-ga4\n *\n * Automatically initializes GA and tracks page views on route changes\n * Only works in production mode (NODE_ENV === 'production')\n *\n * @example\n * ```tsx\n * // Just call the hook - it auto-tracks pageviews\n * useAnalytics();\n *\n * // Or use the returned methods for custom tracking\n * const { event, isEnabled } = useAnalytics();\n * event('button_click', { category: 'engagement', label: 'signup' });\n * ```\n */\nexport function useAnalytics(trackingIdProp?: string) {\n const pathname = usePathname();\n const { user, isAuthenticated } = useAuth();\n\n // Use trackingId from prop (passed from AppLayout)\n const trackingId = trackingIdProp;\n const isEnabled = isProduction && Boolean(trackingId);\n\n // Initialize GA4\n useEffect(() => {\n if (!isEnabled || !trackingId) return;\n Analytics.init(trackingId);\n }, [isEnabled, trackingId]);\n\n // Auto-set user ID when authenticated\n useEffect(() => {\n if (!isEnabled || !isAuthenticated || !user?.id) return;\n Analytics.setUser(String(user.id));\n }, [isEnabled, isAuthenticated, user?.id]);\n\n // Auto-track page views on route change (App Router)\n useEffect(() => {\n if (!isEnabled || typeof window === 'undefined') return;\n\n // Track page view when pathname changes\n const url = pathname + (window.location.search || '');\n Analytics.pageview(url);\n }, [pathname, isEnabled]);\n\n return {\n isEnabled,\n trackingId,\n pageview: Analytics.pageview,\n event: Analytics.event,\n setUser: Analytics.setUser,\n set: Analytics.set,\n };\n}\n\nexport default useAnalytics;\n","/**\n * AnalyticsProvider Component\n *\n * Initializes Google Analytics and auto-tracks pageviews.\n * Can work standalone with trackingId prop, or use AppContext if available.\n */\n\n'use client';\n\nimport { ReactNode } from 'react';\n\nimport { useAnalytics } from './useAnalytics';\n\ninterface AnalyticsProviderProps {\n children: ReactNode;\n /** Google Analytics tracking ID (optional if using AppContext) */\n trackingId?: string;\n}\n\n/**\n * Analytics Provider that initializes tracking\n * Automatically:\n * - Initializes GA4 with tracking ID from prop or config\n * - Sets user ID when authenticated\n * - Tracks page views on route changes\n */\nexport function AnalyticsProvider({ children, trackingId }: AnalyticsProviderProps) {\n // If trackingId is provided as prop, use it directly\n // Otherwise, useAnalytics will try to get it from AppContext\n useAnalytics(trackingId);\n return <>{children}</>;\n}\n\nexport default AnalyticsProvider;\n","/**\n * Analytics Events Constants\n *\n * Predefined event names and categories for consistent tracking\n * across the entire application.\n */\n\n/**\n * Event Categories\n */\nexport const AnalyticsCategory = {\n AUTH: 'auth',\n ERROR: 'error',\n NAVIGATION: 'navigation',\n ENGAGEMENT: 'engagement',\n USER: 'user',\n} as const;\n\n/**\n * Predefined Event Names\n */\nexport const AnalyticsEvent = {\n // Auth Events\n AUTH_OTP_REQUEST: 'auth_otp_request',\n AUTH_OTP_VERIFY_SUCCESS: 'auth_otp_verify_success',\n AUTH_OTP_VERIFY_FAIL: 'auth_otp_verify_fail',\n AUTH_LOGIN_SUCCESS: 'auth_login_success',\n AUTH_LOGOUT: 'auth_logout',\n AUTH_SESSION_EXPIRED: 'auth_session_expired',\n AUTH_TOKEN_REFRESH: 'auth_token_refresh',\n AUTH_TOKEN_REFRESH_FAIL: 'auth_token_refresh_fail',\n\n // OAuth Events\n AUTH_OAUTH_START: 'auth_oauth_start',\n AUTH_OAUTH_SUCCESS: 'auth_oauth_success',\n AUTH_OAUTH_FAIL: 'auth_oauth_fail',\n\n // Error Events\n ERROR_BOUNDARY: 'error_boundary',\n ERROR_API: 'error_api',\n ERROR_VALIDATION: 'error_validation',\n ERROR_NETWORK: 'error_network',\n\n // Navigation Events\n NAV_ADMIN_ENTER: 'nav_admin_enter',\n NAV_DASHBOARD_ENTER: 'nav_dashboard_enter',\n NAV_PAGE_VIEW: 'nav_page_view',\n\n // Engagement Events\n THEME_CHANGE: 'theme_change',\n SIDEBAR_TOGGLE: 'sidebar_toggle',\n MOBILE_MENU_OPEN: 'mobile_menu_open',\n\n // User Events\n USER_PROFILE_VIEW: 'user_profile_view',\n USER_PROFILE_UPDATE: 'user_profile_update',\n} as const;\n\nexport type AnalyticsCategoryType = typeof AnalyticsCategory[keyof typeof AnalyticsCategory];\nexport type AnalyticsEventType = typeof AnalyticsEvent[keyof typeof AnalyticsEvent];\n","/**\n * McpChat configuration\n * Environment-aware configuration for MCP server endpoints\n */\n\n// Hosts\nconst PROD_HOST = 'https://mcp.djangocfg.com';\nconst DEV_HOST = 'http://localhost:3002';\n\n/**\n * Get host based on auto-detect flag\n * @param autoDetect - If true, auto-detect based on NODE_ENV. If false, always use PROD_HOST\n */\nfunction getHost(autoDetect: boolean = false): string {\n if (autoDetect && process.env.NODE_ENV === 'development') {\n return DEV_HOST;\n }\n return PROD_HOST;\n}\n\n/**\n * Get MCP Server endpoints\n * @param autoDetect - If true, auto-detect environment. If false (default), always use production\n */\nexport function getMcpEndpoints(autoDetect: boolean = false) {\n const HOST = getHost(autoDetect);\n return {\n /** Base URL */\n baseUrl: HOST,\n /** Chat API endpoint */\n chat: `${HOST}/api/chat`,\n /** Search API endpoint */\n search: `${HOST}/api/search`,\n /** Conversations API endpoint */\n conversations: `${HOST}/api/conversations`,\n /** Health check endpoint */\n health: `${HOST}/health`,\n /** MCP protocol endpoint (Streamable HTTP) */\n mcp: `${HOST}/mcp`,\n /** SSE endpoint for legacy clients */\n sse: `${HOST}/mcp/sse`,\n };\n}\n\n/**\n * MCP Server endpoints (always production by default)\n */\nexport const mcpEndpoints = getMcpEndpoints(false);\n\n// Export defaults for backwards compatibility\nexport const DEFAULT_CHAT_API_ENDPOINT = PROD_HOST + '/api/chat';\nexport const DEFAULT_MCP_BASE_URL = PROD_HOST;\n\n/**\n * Chat sidebar layout configuration\n */\nexport const sidebarConfig = {\n /** Minimum sidebar width in pixels */\n minWidth: 320,\n /** Maximum sidebar width in pixels */\n maxWidth: 600,\n /** Default sidebar width in pixels */\n defaultWidth: 400,\n /** Z-index for chat elements */\n zIndex: 300,\n /** Animation duration in milliseconds */\n animationDuration: 200,\n};\n\n/**\n * Chat FAB (Floating Action Button) configuration\n */\nexport const fabConfig = {\n /** Bottom offset in pixels */\n bottom: 24,\n /** Right offset in pixels */\n right: 24,\n /** Size of FAB button in pixels */\n size: 56,\n};\n\n/**\n * LocalStorage keys for chat state persistence\n */\nexport const storageKeys = {\n /** Display mode (closed, floating, sidebar) */\n mode: 'djangocfg-chat-mode',\n /** User ID for conversation tracking */\n userId: 'djangocfg-chat-user-id',\n /** Chat messages history */\n messages: 'djangocfg-chat-messages',\n /** Sidebar width */\n sidebarWidth: 'djangocfg-chat-sidebar-width',\n};\n","'use client';\n\nimport React, {\n createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState\n} from 'react';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { useIsMobile, useLocalStorage } from '@djangocfg/ui-nextjs/hooks';\n\nimport { storageKeys } from '../config';\n\nimport type { AIChatMessage, ChatApiResponse, AIChatSource, ChatWidgetConfig, ChatDisplayMode } from '../types';\nconst MAX_STORED_MESSAGES = 50;\n\nfunction generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Serialized message format for localStorage\n */\ninterface SerializedMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: string; // ISO string\n sources?: AIChatSource[];\n}\n\n/**\n * Chat context state\n */\nexport interface ChatContextState {\n /** All chat messages */\n messages: AIChatMessage[];\n /** Whether a request is in progress */\n isLoading: boolean;\n /** Last error if any */\n error: Error | null;\n /** Whether chat panel is open */\n isOpen: boolean;\n /** Whether chat is minimized */\n isMinimized: boolean;\n /** Configuration */\n config: ChatWidgetConfig;\n /** Current display mode */\n displayMode: ChatDisplayMode;\n /** Is on mobile device */\n isMobile: boolean;\n /** User ID for this session */\n userId: string;\n}\n\n/**\n * Chat context actions\n */\nexport interface ChatContextActions {\n /** Send a message */\n sendMessage: (content: string) => Promise<void>;\n /** Clear all messages */\n clearMessages: () => void;\n /** Open chat panel */\n openChat: () => void;\n /** Close chat panel */\n closeChat: () => void;\n /** Toggle chat panel */\n toggleChat: () => void;\n /** Minimize/restore chat */\n toggleMinimize: () => void;\n /** Set display mode */\n setDisplayMode: (mode: ChatDisplayMode) => void;\n}\n\nexport type ChatContextValue = ChatContextState & ChatContextActions;\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\n/**\n * Chat provider props\n */\nexport interface ChatProviderProps {\n children: ReactNode;\n /** API endpoint for chat */\n apiEndpoint?: string;\n /** Widget configuration */\n config?: Partial<ChatWidgetConfig>;\n /** Callback on error */\n onError?: (error: Error) => void;\n}\n\n/**\n * Chat provider component\n */\nexport function ChatProvider({\n children,\n apiEndpoint = '/api/chat',\n config: userConfig = {},\n onError,\n}: ChatProviderProps) {\n const [messages, setMessages] = useState<AIChatMessage[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isMinimized, setIsMinimized] = useState(false);\n const isHydratedRef = useRef(false);\n const mobileResetRef = useRef(false);\n\n // Display mode with localStorage persistence\n const [storedMode, setStoredMode] = useLocalStorage<ChatDisplayMode>(storageKeys.mode, 'closed');\n\n // User ID with localStorage persistence\n const [userId, setUserId] = useLocalStorage<string>(storageKeys.userId, '');\n\n // Messages storage (serialized)\n const [storedMessages, setStoredMessages] = useLocalStorage<SerializedMessage[]>(storageKeys.messages, []);\n\n const isMobile = useIsMobile();\n\n // On mobile, always start closed on page load (don't restore state)\n useEffect(() => {\n if (isMobile && !mobileResetRef.current && storedMode !== 'closed') {\n mobileResetRef.current = true;\n setStoredMode('closed');\n }\n }, [isMobile, storedMode, setStoredMode]);\n\n // Generate user ID if not exists\n useEffect(() => {\n if (!userId) {\n setUserId(uuidv4());\n }\n }, [userId, setUserId]);\n\n // Load messages from localStorage on mount (once)\n useEffect(() => {\n if (isHydratedRef.current) return;\n isHydratedRef.current = true;\n\n if (storedMessages.length > 0) {\n const hydratedMessages: AIChatMessage[] = storedMessages.map((msg) => ({\n ...msg,\n timestamp: new Date(msg.timestamp),\n }));\n setMessages(hydratedMessages);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [storedMessages]); // Depend on storedMessages to wait for localStorage\n\n // Save messages to localStorage when they change\n useEffect(() => {\n if (!isHydratedRef.current) return;\n\n const toStore: SerializedMessage[] = messages.slice(-MAX_STORED_MESSAGES).map((msg) => ({\n id: msg.id,\n role: msg.role,\n content: msg.content,\n timestamp: msg.timestamp.toISOString(),\n sources: msg.sources,\n }));\n setStoredMessages(toStore);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n // On mobile, sidebar mode is not available - fallback to floating\n const displayMode: ChatDisplayMode = useMemo(() => {\n if (isMobile && storedMode === 'sidebar') {\n return 'floating';\n }\n return storedMode;\n }, [isMobile, storedMode]);\n\n // Derived state: isOpen is true when not in 'closed' mode\n const isOpen = displayMode !== 'closed';\n\n const config: ChatWidgetConfig = useMemo(\n () => ({\n apiEndpoint,\n title: 'DjangoCFG AI',\n placeholder: 'Ask about DjangoCFG...',\n greeting:\n \"Hi! I'm your DjangoCFG documentation assistant. Ask me anything about configuration, features, or how to use the library.\",\n position: 'bottom-right',\n variant: 'default',\n ...userConfig,\n }),\n [apiEndpoint, userConfig]\n );\n\n const sendMessage = useCallback(\n async (content: string) => {\n if (!content.trim() || isLoading) return;\n\n const userMessage: AIChatMessage = {\n id: generateMessageId(),\n role: 'user',\n content: content.trim(),\n timestamp: new Date(),\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setError(null);\n\n try {\n const response = await fetch(config.apiEndpoint || apiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n query: content,\n userId: userId || undefined,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status}`);\n }\n\n const data: ChatApiResponse = await response.json();\n\n if (!data.success) {\n throw new Error(data.error || 'Failed to get response');\n }\n\n const sources: AIChatSource[] =\n data.results?.map((r) => ({\n title: r.chunk.title,\n path: r.chunk.path,\n url: r.chunk.url,\n section: r.chunk.section,\n score: r.score,\n })) || [];\n\n const assistantMessage: AIChatMessage = {\n id: generateMessageId(),\n role: 'assistant',\n content: data.answer || 'I found some relevant documentation.',\n timestamp: new Date(),\n sources,\n };\n\n setMessages((prev) => [...prev, assistantMessage]);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error');\n setError(error);\n onError?.(error);\n\n const errorMessage: AIChatMessage = {\n id: generateMessageId(),\n role: 'assistant',\n content: `Sorry, I encountered an error: ${error.message}. Please try again.`,\n timestamp: new Date(),\n };\n\n setMessages((prev) => [...prev, errorMessage]);\n } finally {\n setIsLoading(false);\n }\n },\n [apiEndpoint, config.apiEndpoint, isLoading, onError, userId]\n );\n\n const clearMessages = useCallback(() => {\n setMessages([]);\n setStoredMessages([]);\n setError(null);\n }, [setStoredMessages]);\n\n const openChat = useCallback(() => {\n setStoredMode('floating');\n setIsMinimized(false);\n }, [setStoredMode]);\n\n const closeChat = useCallback(() => {\n setStoredMode('closed');\n setIsMinimized(false);\n }, [setStoredMode]);\n\n const toggleChat = useCallback(() => {\n if (displayMode === 'closed') {\n setStoredMode('floating');\n setIsMinimized(false);\n } else {\n setStoredMode('closed');\n }\n }, [displayMode, setStoredMode]);\n\n const toggleMinimize = useCallback(() => {\n setIsMinimized((prev) => !prev);\n }, []);\n\n const setDisplayMode = useCallback(\n (mode: ChatDisplayMode) => {\n // On mobile, sidebar is not available\n if (isMobile && mode === 'sidebar') {\n setStoredMode('floating');\n } else {\n setStoredMode(mode);\n }\n setIsMinimized(false);\n },\n [isMobile, setStoredMode]\n );\n\n const value = useMemo<ChatContextValue>(\n () => ({\n messages,\n isLoading,\n error,\n isOpen,\n isMinimized,\n config,\n displayMode,\n isMobile,\n userId: userId || '',\n sendMessage,\n clearMessages,\n openChat,\n closeChat,\n toggleChat,\n toggleMinimize,\n setDisplayMode,\n }),\n [\n messages,\n isLoading,\n error,\n isOpen,\n isMinimized,\n config,\n displayMode,\n isMobile,\n userId,\n sendMessage,\n clearMessages,\n openChat,\n closeChat,\n toggleChat,\n toggleMinimize,\n setDisplayMode,\n ]\n );\n\n return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;\n}\n\n/**\n * Hook to access chat context\n */\nexport function useChatContext(): ChatContextValue {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error('useChatContext must be used within a ChatProvider');\n }\n return context;\n}\n\n/**\n * Hook to check if chat context is available\n */\nexport function useChatContextOptional(): ChatContextValue | null {\n return useContext(ChatContext);\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport {\n type AIChatMessage, type AIChatSource, mcpEndpoints, type UseAIChatOptions, type UseAIChatReturn\n} from '../types';\n\nfunction generateId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nfunction generateThreadId(): string {\n return `thread_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nfunction generateUserId(): string {\n return `user_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nconst STORAGE_KEY = 'djangocfg_chat';\n\n/**\n * Get or create persistent chat IDs from localStorage\n */\nfunction getPersistedIds(): { threadId: string; userId: string } {\n if (typeof window === 'undefined') {\n return { threadId: generateThreadId(), userId: generateUserId() };\n }\n\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const data = JSON.parse(stored);\n if (data.threadId && data.userId) {\n return data;\n }\n }\n } catch {\n // Ignore parse errors\n }\n\n // Generate new IDs and persist\n const ids = { threadId: generateThreadId(), userId: generateUserId() };\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(ids));\n } catch {\n // Ignore storage errors\n }\n return ids;\n}\n\n/**\n * Update persisted thread ID (after clear)\n */\nfunction persistThreadId(threadId: string, userId: string): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({ threadId, userId }));\n } catch {\n // Ignore storage errors\n }\n}\n\n/**\n * Save message to server\n */\nasync function saveMessageToServer(threadId: string, userId: string, message: AIChatMessage): Promise<void> {\n try {\n await fetch(`${mcpEndpoints.conversations}/${threadId}/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n userId,\n message: {\n id: message.id,\n role: message.role,\n content: message.content,\n timestamp: message.timestamp.getTime(),\n sources: message.sources,\n },\n }),\n });\n } catch (error) {\n console.warn('[Chat] Failed to save message to server:', error);\n }\n}\n\n/**\n * Load conversation from server\n */\nasync function loadConversationFromServer(threadId: string): Promise<AIChatMessage[] | null> {\n try {\n const response = await fetch(`${mcpEndpoints.conversations}/${threadId}`);\n \n // If conversation not found (404), return null to signal reset needed\n if (response.status === 404) return null;\n \n if (!response.ok) return [];\n\n const data = await response.json();\n if (!data.messages || !Array.isArray(data.messages)) return [];\n\n return data.messages.map((m: {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: number;\n sources?: AIChatSource[];\n }) => ({\n id: m.id,\n role: m.role,\n content: m.content,\n timestamp: new Date(m.timestamp),\n sources: m.sources,\n }));\n } catch (error) {\n console.warn('[Chat] Failed to load conversation from server:', error);\n return [];\n }\n}\n\n/**\n * Delete conversation from server\n */\nasync function deleteConversationFromServer(threadId: string): Promise<void> {\n try {\n await fetch(`${mcpEndpoints.conversations}/${threadId}`, {\n method: 'DELETE',\n });\n } catch (error) {\n console.warn('[Chat] Failed to delete conversation from server:', error);\n }\n}\n\n/**\n * AI Chat hook with streaming support and server-side history\n * All persistence is handled through API endpoints - no localStorage\n */\nexport function useAIChat(options: UseAIChatOptions): UseAIChatReturn {\n const {\n apiEndpoint = mcpEndpoints.chat,\n initialMessages = [],\n onError,\n enableStreaming = true,\n threadId: initialThreadId,\n userId: initialUserId,\n } = options;\n\n const [messages, setMessages] = useState<AIChatMessage[]>(initialMessages);\n const [isLoadingHistory, setIsLoadingHistory] = useState(true);\n\n // Get persisted IDs from localStorage (or generate new ones)\n const persistedIds = useRef<{ threadId: string; userId: string } | null>(null);\n if (persistedIds.current === null && typeof window !== 'undefined') {\n persistedIds.current = getPersistedIds();\n }\n\n const [threadId, setThreadId] = useState<string>(() =>\n initialThreadId || persistedIds.current?.threadId || generateThreadId()\n );\n const [userId] = useState<string>(() =>\n initialUserId || persistedIds.current?.userId || generateUserId()\n );\n\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n // Load conversation from server on mount (always try to restore from persisted threadId)\n useEffect(() => {\n if (typeof window === 'undefined') {\n setIsLoadingHistory(false);\n return;\n }\n\n const loadHistory = async () => {\n const serverMessages = await loadConversationFromServer(threadId);\n \n // If server returned null (404), session is expired/invalid\n if (serverMessages === null) {\n console.log('[Chat] Session expired or invalid, starting new session');\n const newThreadId = generateThreadId();\n setThreadId(newThreadId);\n persistThreadId(newThreadId, userId);\n setMessages([]); // Ensure empty state\n } else if (serverMessages.length > 0) {\n setMessages(serverMessages);\n }\n \n setIsLoadingHistory(false);\n };\n loadHistory();\n }, [threadId, userId]);\n\n /**\n * Send message with streaming support\n */\n const sendMessage = useCallback(\n async (content: string) => {\n if (!content.trim() || isLoading) return;\n\n // Abort any previous request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n abortControllerRef.current = new AbortController();\n\n // Add user message\n const userMessage: AIChatMessage = {\n id: generateId(),\n role: 'user',\n content: content.trim(),\n timestamp: new Date(),\n };\n\n // Add placeholder for assistant message\n const assistantMessageId = generateId();\n const assistantMessage: AIChatMessage = {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date(),\n isStreaming: true,\n };\n\n setMessages((prev) => [...prev, userMessage, assistantMessage]);\n setIsLoading(true);\n setError(null);\n\n // Save user message to server\n saveMessageToServer(threadId, userId, userMessage);\n\n try {\n // Build messages array from history + current message (for OpenAI format)\n const chatMessages = [\n ...messages\n .filter((m) => m.role !== 'system')\n .slice(-10) // Keep last 10 messages for context\n .map((m) => ({\n role: m.role as 'user' | 'assistant',\n content: m.content,\n })),\n { role: 'user' as const, content },\n ];\n\n const response = await fetch(apiEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n messages: chatMessages,\n stream: enableStreaming,\n }),\n signal: abortControllerRef.current.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error: ${response.status}`);\n }\n\n if (enableStreaming && response.headers.get('content-type')?.includes('text/event-stream')) {\n // Handle streaming response\n await handleStreamingResponse(response, assistantMessageId);\n } else {\n // Handle non-streaming response\n const data = await response.json();\n\n if (!data.success) {\n throw new Error(data.error || 'Failed to get response');\n }\n\n // Update thread ID if returned\n if (data.threadId && data.threadId !== threadId) {\n setThreadId(data.threadId);\n }\n\n // Extract sources\n const sources: AIChatSource[] =\n data.sources?.map((s: { title: string; path: string; url?: string; section?: string; score?: number }) => ({\n title: s.title,\n path: s.path,\n url: s.url,\n section: s.section,\n score: s.score,\n })) || [];\n\n const finalContent = data.content || 'I found some relevant documentation.';\n\n // Update assistant message\n setMessages((prev) =>\n prev.map((m) =>\n m.id === assistantMessageId\n ? {\n ...m,\n content: finalContent,\n sources,\n isStreaming: false,\n }\n : m\n )\n );\n\n // Save assistant message to server\n saveMessageToServer(threadId, userId, {\n id: assistantMessageId,\n role: 'assistant',\n content: finalContent,\n timestamp: new Date(),\n sources,\n });\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // Request was aborted, remove the assistant message\n setMessages((prev) => prev.filter((m) => m.id !== assistantMessageId));\n return;\n }\n\n const error = err instanceof Error ? err : new Error('Unknown error');\n setError(error);\n onError?.(error);\n\n // Update assistant message with error\n setMessages((prev) =>\n prev.map((m) =>\n m.id === assistantMessageId\n ? {\n ...m,\n content: `Sorry, I encountered an error: ${error.message}. Please try again.`,\n isStreaming: false,\n }\n : m\n )\n );\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n },\n [apiEndpoint, isLoading, messages, threadId, userId, enableStreaming, onError]\n );\n\n /**\n * Handle streaming SSE response\n */\n const handleStreamingResponse = async (response: Response, messageId: string) => {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('No response body');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let fullContent = '';\n const sources: AIChatSource[] = [];\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete events\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6);\n\n if (data === '[DONE]') {\n // Stream complete\n setMessages((prev) =>\n prev.map((m) =>\n m.id === messageId\n ? {\n ...m,\n content: fullContent,\n sources,\n isStreaming: false,\n }\n : m\n )\n );\n\n // Save final assistant message to server\n saveMessageToServer(threadId, userId, {\n id: messageId,\n role: 'assistant',\n content: fullContent,\n timestamp: new Date(),\n sources,\n });\n return;\n }\n\n try {\n const parsed = JSON.parse(data);\n\n if (parsed.type === 'text' && parsed.content) {\n fullContent += parsed.content;\n // Update message with current content\n setMessages((prev) =>\n prev.map((m) =>\n m.id === messageId\n ? {\n ...m,\n content: fullContent,\n isStreaming: true,\n }\n : m\n )\n );\n } else if (parsed.type === 'source' && parsed.source) {\n sources.push({\n title: parsed.source.title,\n path: parsed.source.path,\n url: parsed.source.url,\n section: parsed.source.section,\n score: parsed.source.score,\n });\n } else if (parsed.type === 'done') {\n // Update with final usage info if needed\n setMessages((prev) =>\n prev.map((m) =>\n m.id === messageId\n ? {\n ...m,\n content: fullContent,\n sources,\n isStreaming: false,\n }\n : m\n )\n );\n\n // Save final assistant message to server\n saveMessageToServer(threadId, userId, {\n id: messageId,\n role: 'assistant',\n content: fullContent,\n timestamp: new Date(),\n sources,\n });\n } else if (parsed.type === 'error') {\n throw new Error(parsed.error || 'Stream error');\n }\n } catch {\n // Ignore parse errors for individual events\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n };\n\n /**\n * Clear all messages and start new conversation\n */\n const clearMessages = useCallback(async () => {\n // Abort any ongoing request\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n // Delete conversation from server\n await deleteConversationFromServer(threadId);\n\n setMessages([]);\n setError(null);\n\n // Generate new thread ID for fresh conversation and persist it\n const newThreadId = generateThreadId();\n setThreadId(newThreadId);\n persistThreadId(newThreadId, userId);\n }, [threadId, userId]);\n\n /**\n * Stop current streaming response\n */\n const stopStreaming = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n return {\n messages,\n isLoading: isLoading || isLoadingHistory,\n error,\n threadId,\n userId,\n sendMessage,\n clearMessages,\n stopStreaming,\n };\n}\n","'use client';\n\nimport {\n createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState\n} from 'react';\n\nimport { useIsMobile, useLocalStorage } from '@djangocfg/ui-nextjs/hooks';\n\nimport { useAIChat } from '../hooks/useAIChat';\nimport { AIChatMessage, ChatDisplayMode, ChatWidgetConfig, mcpEndpoints} from '../types';\n\nconst STORAGE_KEY_MODE = 'djangocfg-ai-chat-mode';\n\n/**\n * AI Chat context state\n */\nexport interface AIChatContextState {\n /** All chat messages */\n messages: AIChatMessage[];\n /** Whether a request is in progress */\n isLoading: boolean;\n /** Last error if any */\n error: Error | null;\n /** Whether chat panel is open */\n isOpen: boolean;\n /** Whether chat is minimized */\n isMinimized: boolean;\n /** Configuration */\n config: ChatWidgetConfig;\n /** Current display mode */\n displayMode: ChatDisplayMode;\n /** Is on mobile device */\n isMobile: boolean;\n /** Thread ID for conversation */\n threadId: string;\n /** User ID for conversation */\n userId: string;\n}\n\n/**\n * AI Chat context actions\n */\nexport interface AIChatContextActions {\n /** Send a message */\n sendMessage: (content: string) => Promise<void>;\n /** Clear all messages */\n clearMessages: () => void;\n /** Open chat panel */\n openChat: () => void;\n /** Close chat panel */\n closeChat: () => void;\n /** Toggle chat panel */\n toggleChat: () => void;\n /** Minimize/restore chat */\n toggleMinimize: () => void;\n /** Set display mode */\n setDisplayMode: (mode: ChatDisplayMode) => void;\n /** Stop streaming response */\n stopStreaming: () => void;\n}\n\nexport type AIChatContextValue = AIChatContextState & AIChatContextActions;\n\nconst AIChatContext = createContext<AIChatContextValue | null>(null);\n\n/**\n * AI Chat provider props\n */\nexport interface AIChatProviderProps {\n children: ReactNode;\n /** API endpoint for AI chat (default: /api/ai/chat) */\n apiEndpoint?: string;\n /** Widget configuration */\n config?: Partial<ChatWidgetConfig>;\n /** Callback on error */\n onError?: (error: Error) => void;\n /** Enable streaming (default: true) */\n enableStreaming?: boolean;\n}\n\n/**\n * AI Chat provider component\n * Uses useAIChat hook with server-side persistence\n */\nexport function AIChatProvider({\n children,\n apiEndpoint = mcpEndpoints.chat,\n config: userConfig = {},\n onError,\n enableStreaming = true,\n}: AIChatProviderProps) {\n // Use AI chat hook\n const {\n messages,\n isLoading,\n error,\n threadId,\n userId,\n sendMessage: sendAIMessage,\n clearMessages: clearAIMessages,\n stopStreaming,\n } = useAIChat({\n apiEndpoint,\n onError,\n enableStreaming,\n });\n\n const [isMinimized, setIsMinimized] = useState(false);\n\n // Display mode with localStorage persistence\n const [storedMode, setStoredMode] = useLocalStorage<ChatDisplayMode>(STORAGE_KEY_MODE, 'closed');\n\n const isMobile = useIsMobile();\n\n // On mobile, sidebar mode is not available - fallback to floating\n const displayMode: ChatDisplayMode = useMemo(() => {\n if (isMobile && storedMode === 'sidebar') {\n return 'floating';\n }\n return storedMode;\n }, [isMobile, storedMode]);\n\n // Derived state: isOpen is true when not in 'closed' mode\n const isOpen = displayMode !== 'closed';\n\n // Track isOpen in a ref for event handler\n const isOpenRef = useRef(isOpen);\n useEffect(() => {\n isOpenRef.current = isOpen;\n }, [isOpen]);\n\n // Track last active mode (non-closed) to restore when reopening\n const lastActiveModeRef = useRef<Exclude<ChatDisplayMode, 'closed'>>('floating');\n useEffect(() => {\n if (displayMode !== 'closed') {\n lastActiveModeRef.current = displayMode;\n }\n }, [displayMode]);\n\n const config: ChatWidgetConfig = useMemo(\n () => ({\n apiEndpoint,\n title: 'DjangoCFG AI',\n placeholder: 'Ask about DjangoCFG...',\n greeting:\n \"Hi! I'm your DjangoCFG AI assistant powered by GPT. Ask me anything about configuration, features, or how to use the library.\",\n position: 'bottom-right',\n variant: 'default',\n ...userConfig,\n }),\n [apiEndpoint, userConfig]\n );\n\n const sendMessage = useCallback(\n async (content: string) => {\n await sendAIMessage(content);\n },\n [sendAIMessage]\n );\n\n const clearMessages = useCallback(() => {\n clearAIMessages();\n }, [clearAIMessages]);\n\n const openChat = useCallback(() => {\n // Restore last active mode instead of always opening in floating\n setStoredMode(lastActiveModeRef.current);\n setIsMinimized(false);\n }, [setStoredMode]);\n\n const closeChat = useCallback(() => {\n setStoredMode('closed');\n setIsMinimized(false);\n }, [setStoredMode]);\n\n const toggleChat = useCallback(() => {\n if (displayMode === 'closed') {\n setStoredMode('floating');\n setIsMinimized(false);\n } else {\n setStoredMode('closed');\n }\n }, [displayMode, setStoredMode]);\n\n const toggleMinimize = useCallback(() => {\n setIsMinimized((prev) => !prev);\n }, []);\n\n const setDisplayMode = useCallback(\n (mode: ChatDisplayMode) => {\n // On mobile, sidebar is not available\n if (isMobile && mode === 'sidebar') {\n setStoredMode('floating');\n } else {\n setStoredMode(mode);\n }\n setIsMinimized(false);\n },\n [isMobile, setStoredMode]\n );\n\n const value = useMemo<AIChatContextValue>(\n () => ({\n messages,\n isLoading,\n error,\n isOpen,\n isMinimized,\n config,\n displayMode,\n isMobile,\n threadId,\n userId,\n sendMessage,\n clearMessages,\n openChat,\n closeChat,\n toggleChat,\n toggleMinimize,\n setDisplayMode,\n stopStreaming,\n }),\n [\n messages,\n isLoading,\n error,\n isOpen,\n isMinimized,\n config,\n displayMode,\n isMobile,\n threadId,\n userId,\n sendMessage,\n clearMessages,\n openChat,\n closeChat,\n toggleChat,\n toggleMinimize,\n setDisplayMode,\n stopStreaming,\n ]\n );\n\n // =============================================================================\n // Global Chat Event Listener\n // =============================================================================\n\n /**\n * Listen for mcp:chat:send events from useMcpChat hook\n * This allows any component to trigger chat from anywhere in the app\n */\n useEffect(() => {\n // Register chat as available\n if (typeof window !== 'undefined') {\n (window as any).__MCP_CHAT_AVAILABLE__ = true;\n }\n\n const handleChatEvent = (event: Event) => {\n const customEvent = event as CustomEvent<import('../types').McpChatEventDetail>;\n const { message, context, autoSend = true, displayMode: requestedMode } = customEvent.detail;\n\n // Send confirmation that event was handled\n window.dispatchEvent(new CustomEvent('mcp:chat:handled'));\n\n // Format message with context if provided\n let fullMessage = message;\n if (context) {\n if (context.type) {\n fullMessage = `[${context.type.toUpperCase()}] ${message}`;\n }\n if (context.data) {\n fullMessage += `\\n\\n**Context:**\\n\\`\\`\\`json\\n${JSON.stringify(context.data, null, 2)}\\n\\`\\`\\``;\n }\n if (context.source) {\n fullMessage += `\\n\\n_Source: ${context.source}_`;\n }\n }\n\n // Open chat in requested mode, or keep current mode if already open\n if (requestedMode) {\n setDisplayMode(requestedMode);\n } else if (!isOpenRef.current) {\n // Only open if chat is currently closed\n openChat();\n }\n // If already open, keep current mode\n\n // Auto-send message if requested\n if (autoSend) {\n // Small delay to ensure chat is open and ready\n setTimeout(() => {\n sendMessage(fullMessage);\n }, 100);\n }\n };\n\n window.addEventListener('mcp:chat:send', handleChatEvent);\n\n return () => {\n window.removeEventListener('mcp:chat:send', handleChatEvent);\n if (typeof window !== 'undefined') {\n (window as any).__MCP_CHAT_AVAILABLE__ = false;\n }\n };\n }, [sendMessage, setDisplayMode, openChat]);\n\n return <AIChatContext.Provider value={value}>{children}</AIChatContext.Provider>;\n}\n\n/**\n * Hook to access AI chat context\n */\nexport function useAIChatContext(): AIChatContextValue {\n const context = useContext(AIChatContext);\n if (!context) {\n throw new Error('useAIChatContext must be used within an AIChatProvider');\n }\n return context;\n}\n\n/**\n * Hook to check if AI chat context is available\n */\nexport function useAIChatContextOptional(): AIChatContextValue | null {\n return useContext(AIChatContext);\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useLocalStorage } from '@djangocfg/ui-nextjs/hooks';\n\nimport { fabConfig, sidebarConfig, storageKeys } from '../config';\n\nimport type { ChatDisplayMode } from '../types';\n// Re-export for convenience\nexport const MIN_SIDEBAR_WIDTH = sidebarConfig.minWidth;\nexport const MAX_SIDEBAR_WIDTH = sidebarConfig.maxWidth;\nexport const DEFAULT_SIDEBAR_WIDTH = sidebarConfig.defaultWidth;\n\n/**\n * Configuration for chat layout management\n */\nexport interface ChatLayoutConfig {\n /** Initial width of sidebar in pixels */\n initialWidth?: number;\n /** Animation duration in ms */\n animationDuration?: number;\n /** Element to push (defaults to body) */\n pushTarget?: 'body' | 'main' | string;\n}\n\n/**\n * Return type for useChatLayout hook\n */\nexport interface UseChatLayoutReturn {\n /** Current sidebar width */\n sidebarWidth: number;\n /** Apply layout changes for mode */\n applyLayout: (mode: ChatDisplayMode) => void;\n /** Reset layout to default */\n resetLayout: () => void;\n /** Update sidebar width (for resize) */\n updateWidth: (width: number) => void;\n /** Start resize operation */\n startResize: (e: React.MouseEvent) => void;\n /** Whether currently resizing */\n isResizing: boolean;\n /** Get CSS for sidebar container */\n getSidebarStyles: () => React.CSSProperties;\n /** Get CSS for floating container */\n getFloatingStyles: (position: 'bottom-right' | 'bottom-left') => React.CSSProperties;\n /** Get CSS for FAB button */\n getFabStyles: (position: 'bottom-right' | 'bottom-left') => React.CSSProperties;\n}\n\nconst DEFAULT_CONFIG: Required<ChatLayoutConfig> = {\n initialWidth: sidebarConfig.defaultWidth,\n animationDuration: sidebarConfig.animationDuration,\n pushTarget: 'body',\n};\n\n/** Stored original styles for fixed elements */\ninterface FixedElementOriginalStyles {\n element: HTMLElement;\n right: string;\n transition: string;\n}\n\n/**\n * Hook for managing chat layout embedding modes\n *\n * Handles:\n * - Sidebar mode: pushes content left by adding margin to target element\n * AND automatically adjusts all position:fixed elements with right:0\n * - Floating mode: positions chat at bottom-right/left\n * - Closed mode: just shows FAB button\n *\n * @example\n * ```tsx\n * const { applyLayout, getSidebarStyles, getFloatingStyles } = useChatLayout({\n * sidebarWidth: 400,\n * });\n *\n * useEffect(() => {\n * applyLayout(displayMode);\n * }, [displayMode]);\n * ```\n */\nexport function useChatLayout(config?: ChatLayoutConfig): UseChatLayoutReturn {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n const { initialWidth, animationDuration, pushTarget } = mergedConfig;\n\n // Sidebar width with localStorage persistence\n const [storedWidth, setStoredWidth] = useLocalStorage<number>(storageKeys.sidebarWidth, initialWidth);\n\n // Clamp stored width to valid range\n const sidebarWidth = Math.max(MIN_SIDEBAR_WIDTH, Math.min(MAX_SIDEBAR_WIDTH, storedWidth));\n const sidebarWidthRef = useRef(sidebarWidth);\n\n // Resizing state (runtime only, not persisted)\n const [isResizing, setIsResizing] = useState(false);\n\n // Keep ref in sync\n useEffect(() => {\n sidebarWidthRef.current = sidebarWidth;\n }, [sidebarWidth]);\n\n // Store original styles for cleanup\n const originalStylesRef = useRef<{\n marginRight?: string;\n overflowX?: string;\n transition?: string;\n } | null>(null);\n\n // Store original styles for fixed elements\n const fixedElementsRef = useRef<FixedElementOriginalStyles[]>([]);\n\n // Current mode for cleanup\n const currentModeRef = useRef<ChatDisplayMode>('closed');\n\n /**\n * Get the target element to push\n */\n const getTargetElement = useCallback((): HTMLElement | null => {\n if (typeof window === 'undefined') return null;\n\n if (pushTarget === 'body') {\n return document.body;\n } else if (pushTarget === 'main') {\n return document.querySelector('main');\n } else {\n return document.querySelector(pushTarget);\n }\n }, [pushTarget]);\n\n /**\n * Find all fixed/sticky elements that need right adjustment\n */\n const getFixedElements = useCallback((): HTMLElement[] => {\n if (typeof window === 'undefined') return [];\n\n const elements: HTMLElement[] = [];\n const allElements = document.querySelectorAll('*');\n\n allElements.forEach((el) => {\n if (!(el instanceof HTMLElement)) return;\n // Skip chat sidebar itself\n if (el.closest('[data-chat-sidebar-panel]')) return;\n\n const style = window.getComputedStyle(el);\n const position = style.position;\n const right = style.right;\n\n // Check for fixed/sticky elements with right: 0\n if ((position === 'fixed' || position === 'sticky') && right === '0px') {\n elements.push(el);\n }\n });\n\n return elements;\n }, []);\n\n /**\n * Save original styles before modification\n */\n const saveOriginalStyles = useCallback((element: HTMLElement) => {\n if (!originalStylesRef.current) {\n originalStylesRef.current = {\n marginRight: element.style.marginRight,\n overflowX: element.style.overflowX,\n transition: element.style.transition,\n };\n }\n }, []);\n\n /**\n * Restore original styles\n */\n const restoreOriginalStyles = useCallback((element: HTMLElement) => {\n if (originalStylesRef.current) {\n element.style.marginRight = originalStylesRef.current.marginRight || '';\n element.style.overflowX = originalStylesRef.current.overflowX || '';\n element.style.transition = originalStylesRef.current.transition || '';\n element.removeAttribute('data-chat-sidebar');\n originalStylesRef.current = null;\n }\n }, []);\n\n /**\n * Adjust fixed elements for sidebar\n */\n const adjustFixedElements = useCallback(\n (open: boolean) => {\n const currentWidth = sidebarWidthRef.current;\n if (open) {\n // Save and adjust fixed elements\n const fixedElements = getFixedElements();\n fixedElementsRef.current = fixedElements.map((el) => ({\n element: el,\n right: el.style.right,\n transition: el.style.transition,\n }));\n\n fixedElements.forEach((el) => {\n el.style.transition = `right ${animationDuration}ms ease`;\n el.style.right = `${currentWidth}px`;\n });\n } else {\n // Restore fixed elements\n fixedElementsRef.current.forEach(({ element, right, transition }) => {\n element.style.transition = `right ${animationDuration}ms ease`;\n element.style.right = '0px';\n\n // Restore original after animation\n setTimeout(() => {\n element.style.right = right;\n element.style.transition = transition;\n }, animationDuration);\n });\n fixedElementsRef.current = [];\n }\n },\n [getFixedElements, animationDuration]\n );\n\n /**\n * Apply sidebar mode layout\n */\n const applySidebarLayout = useCallback(() => {\n const target = getTargetElement();\n if (!target) return;\n\n const currentWidth = sidebarWidthRef.current;\n\n saveOriginalStyles(target);\n\n // Add smooth transition\n target.style.transition = `margin-right ${animationDuration}ms ease`;\n target.style.marginRight = `${currentWidth}px`;\n target.style.overflowX = 'hidden';\n target.setAttribute('data-chat-sidebar', 'open');\n\n // Adjust fixed elements (header, etc.)\n adjustFixedElements(true);\n\n currentModeRef.current = 'sidebar';\n }, [getTargetElement, saveOriginalStyles, animationDuration, adjustFixedElements]);\n\n /**\n * Apply floating/closed mode layout (reset sidebar push)\n */\n const applyDefaultLayout = useCallback(\n (mode: ChatDisplayMode) => {\n const target = getTargetElement();\n if (!target) return;\n\n // Only restore if we were in sidebar mode\n if (currentModeRef.current === 'sidebar') {\n // Add transition for smooth animation\n target.style.transition = `margin-right ${animationDuration}ms ease`;\n target.style.marginRight = '0px';\n\n // Restore fixed elements\n adjustFixedElements(false);\n\n // Remove styles after animation completes\n setTimeout(() => {\n restoreOriginalStyles(target);\n }, animationDuration);\n }\n\n currentModeRef.current = mode;\n },\n [getTargetElement, restoreOriginalStyles, animationDuration, adjustFixedElements]\n );\n\n /**\n * Apply layout changes for given mode\n */\n const applyLayout = useCallback(\n (mode: ChatDisplayMode) => {\n if (mode === 'sidebar') {\n applySidebarLayout();\n } else {\n applyDefaultLayout(mode);\n }\n },\n [applySidebarLayout, applyDefaultLayout]\n );\n\n /**\n * Reset layout to default (cleanup)\n */\n const resetLayout = useCallback(() => {\n const target = getTargetElement();\n if (target && originalStylesRef.current) {\n restoreOriginalStyles(target);\n }\n // Restore fixed elements immediately on cleanup\n fixedElementsRef.current.forEach(({ element, right, transition }) => {\n element.style.right = right;\n element.style.transition = transition;\n });\n fixedElementsRef.current = [];\n currentModeRef.current = 'closed';\n }, [getTargetElement, restoreOriginalStyles]);\n\n /**\n * Update width during resize (no animation)\n */\n const updateWidthImmediate = useCallback(\n (newWidth: number) => {\n const clampedWidth = Math.max(MIN_SIDEBAR_WIDTH, Math.min(MAX_SIDEBAR_WIDTH, newWidth));\n\n // Update body margin\n const target = getTargetElement();\n if (target && currentModeRef.current === 'sidebar') {\n target.style.transition = 'none';\n target.style.marginRight = `${clampedWidth}px`;\n }\n\n // Update fixed elements\n fixedElementsRef.current.forEach(({ element }) => {\n element.style.transition = 'none';\n element.style.right = `${clampedWidth}px`;\n });\n\n return clampedWidth;\n },\n [getTargetElement]\n );\n\n /**\n * Update sidebar width (for resize)\n */\n const updateWidth = useCallback(\n (newWidth: number) => {\n const clampedWidth = updateWidthImmediate(newWidth);\n setStoredWidth(clampedWidth);\n },\n [updateWidthImmediate, setStoredWidth]\n );\n\n /**\n * Start resize operation\n */\n const startResize = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n setIsResizing(true);\n\n const startX = e.clientX;\n const startWidth = sidebarWidthRef.current;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n // Calculate new width (dragging left increases width)\n const deltaX = startX - moveEvent.clientX;\n const newWidth = startWidth + deltaX;\n const clampedWidth = Math.max(MIN_SIDEBAR_WIDTH, Math.min(MAX_SIDEBAR_WIDTH, newWidth));\n\n // Update DOM immediately for smooth feel\n updateWidthImmediate(clampedWidth);\n sidebarWidthRef.current = clampedWidth;\n\n // Also update React state so sidebar visually resizes\n setStoredWidth(clampedWidth);\n };\n\n const handleMouseUp = () => {\n setIsResizing(false);\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n },\n [updateWidthImmediate, setStoredWidth]\n );\n\n /**\n * Get CSS styles for sidebar container\n */\n const getSidebarStyles = useCallback((): React.CSSProperties => {\n return {\n position: 'fixed',\n top: 0,\n right: 0,\n bottom: 0,\n width: `${sidebarWidth}px`,\n zIndex: sidebarConfig.zIndex,\n };\n }, [sidebarWidth]);\n\n /**\n * Get CSS styles for floating container\n */\n const getFloatingStyles = useCallback(\n (position: 'bottom-right' | 'bottom-left'): React.CSSProperties => {\n return {\n position: 'fixed',\n zIndex: sidebarConfig.zIndex - 50,\n bottom: fabConfig.bottom,\n ...(position === 'bottom-right' ? { right: fabConfig.right } : { left: fabConfig.right }),\n };\n },\n []\n );\n\n /**\n * Get CSS styles for FAB button\n */\n const getFabStyles = useCallback(\n (position: 'bottom-right' | 'bottom-left'): React.CSSProperties => {\n return {\n position: 'fixed',\n zIndex: sidebarConfig.zIndex - 50,\n bottom: fabConfig.bottom,\n ...(position === 'bottom-right' ? { right: fabConfig.right } : { left: fabConfig.right }),\n };\n },\n []\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n resetLayout();\n };\n }, [resetLayout]);\n\n return {\n sidebarWidth,\n applyLayout,\n resetLayout,\n updateWidth,\n startResize,\n isResizing,\n getSidebarStyles,\n getFloatingStyles,\n getFabStyles,\n };\n}\n","'use client';\n\nimport { Bot, ExternalLink, Loader2, User } from 'lucide-react';\nimport React from 'react';\n\nimport { useAuth } from '@djangocfg/api/auth';\nimport {\n Avatar, AvatarFallback, AvatarImage, Badge, Card, CardContent\n} from '@djangocfg/ui-nextjs';\nimport { MarkdownMessage } from '@djangocfg/ui-tools';\n\nimport type { AIChatMessage } from '../types';\n\nexport interface MessageBubbleProps {\n message: AIChatMessage;\n isCompact?: boolean;\n}\n\nfunction formatTime(date: Date): string {\n return date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport const MessageBubble = React.memo<MessageBubbleProps>(\n ({ message, isCompact = false }) => {\n const isUser = message.role === 'user';\n const isAssistant = message.role === 'assistant';\n const { user, isAuthenticated } = useAuth();\n\n // Prepare user data BEFORE render\n const showUserAvatar = isUser && isAuthenticated && user;\n const userAvatar = user?.avatar || '';\n const userDisplayName = user?.display_username || user?.email || 'User';\n const userInitial = userDisplayName.charAt(0).toUpperCase();\n const avatarSize = isCompact ? '28px' : '36px';\n const iconSize = isCompact ? 'h-3.5 w-3.5' : 'h-4 w-4';\n\n return (\n <div\n className={`flex gap-3 animate-in fade-in slide-in-from-bottom-2 duration-300 max-w-full overflow-hidden ${\n isUser ? 'flex-row-reverse' : ''\n }`}\n >\n {/* Avatar */}\n {showUserAvatar ? (\n // Authenticated user avatar\n <Avatar className=\"flex-shrink-0\" style={{ width: avatarSize, height: avatarSize }}>\n <AvatarImage src={userAvatar} alt={userDisplayName} />\n <AvatarFallback className=\"bg-primary text-primary-foreground text-xs\">\n {userInitial}\n </AvatarFallback>\n </Avatar>\n ) : isUser ? (\n // Guest user icon\n <div\n className=\"flex-shrink-0 rounded-full flex items-center justify-center bg-primary text-primary-foreground\"\n style={{ width: avatarSize, height: avatarSize }}\n >\n <User className={iconSize} />\n </div>\n ) : (\n // Bot icon\n <div\n className=\"flex-shrink-0 rounded-full flex items-center justify-center bg-muted text-muted-foreground\"\n style={{ width: avatarSize, height: avatarSize }}\n >\n <Bot className={iconSize} />\n </div>\n )}\n\n {/* Message Content */}\n <div className={`flex-1 min-w-0 ${isUser ? 'max-w-[80%] ml-auto' : 'max-w-[85%]'}`}>\n {/* Header */}\n <div className={`flex items-baseline gap-2 mb-1 ${isUser ? 'justify-end' : ''}`}>\n <span className={`font-medium ${isCompact ? 'text-xs' : 'text-sm'}`}>\n {isUser ? userDisplayName : 'DjangoCFG AI'}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {formatTime(message.timestamp)}\n </span>\n </div>\n\n {/* Message Bubble */}\n <Card\n className={`transition-all duration-200 ${\n isUser\n ? 'bg-primary text-primary-foreground ml-auto'\n : 'bg-muted'\n }`}\n >\n <CardContent className={isCompact ? 'p-2' : 'p-3'}>\n {/* Message Text */}\n <div className={`${isCompact ? 'text-xs' : 'text-sm'} overflow-hidden`} style={{ overflowWrap: 'anywhere', wordBreak: 'break-word' }}>\n {/* Always render markdown for immediate code block highlighting */}\n <MarkdownMessage\n content={message.content}\n isUser={isUser}\n isCompact={isCompact}\n />\n {/* Show spinner during streaming */}\n {message.isStreaming && (\n <Loader2 className=\"inline-block ml-1 h-3 w-3 animate-spin\" />\n )}\n </div>\n\n {/* Sources */}\n {isAssistant && message.sources && message.sources.length > 0 && (\n <div className=\"mt-3 pt-2 border-t border-border/50\">\n <p className=\"text-xs text-muted-foreground mb-1.5\">Related docs:</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {message.sources.slice(0, 3).map((source, idx) => (\n <a\n key={idx}\n href={source.url || source.path}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-block\"\n >\n <Badge\n variant=\"outline\"\n className=\"text-xs gap-1 hover:bg-primary/10 transition-colors cursor-pointer\"\n >\n {source.title}\n {source.section && ` - ${source.section}`}\n <ExternalLink className=\"h-2.5 w-2.5\" />\n </Badge>\n </a>\n ))}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n </div>\n );\n }\n);\n\nMessageBubble.displayName = 'MessageBubble';\n","'use client';\n\nimport { Bot, MessageSquare, StopCircle } from 'lucide-react';\nimport React, { forwardRef, useImperativeHandle, useRef } from 'react';\n\nimport { Button } from '@djangocfg/ui-nextjs';\n\nimport { MessageBubble } from './MessageBubble';\n\nimport type { AIChatMessage } from '../types';\n\n/**\n * ChatMessages imperative handle\n */\nexport interface ChatMessagesHandle {\n scrollToBottom: (instant?: boolean) => void;\n scrollToLastMessage: (instant?: boolean) => void;\n}\n\nexport interface ChatMessagesProps {\n /** Messages to display */\n messages: AIChatMessage[];\n /** Whether loading/streaming is in progress */\n isLoading: boolean;\n /** Greeting to show when no messages */\n greeting?: string;\n /** Callback to stop streaming */\n onStopStreaming?: () => void;\n /** Use compact layout (smaller bubbles) */\n isCompact?: boolean;\n /** Use larger icon for greeting (sidebar mode) */\n largeGreetingIcon?: boolean;\n /** Custom greeting icon */\n greetingIcon?: 'bot' | 'message';\n /** Custom greeting title */\n greetingTitle?: string;\n}\n\n/**\n * ChatMessages - Shared component for displaying chat messages\n *\n * Uses flex-col-reverse for natural bottom scroll behavior:\n * - Scroll position 0 = visual bottom\n * - New content naturally stays at bottom\n * - No complex JS scroll management needed\n */\nexport const ChatMessages = forwardRef<ChatMessagesHandle, ChatMessagesProps>(\n (\n {\n messages,\n isLoading,\n greeting,\n onStopStreaming,\n isCompact = false,\n largeGreetingIcon = false,\n greetingIcon = 'bot',\n greetingTitle,\n },\n ref\n ) => {\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n\n // Expose scroll methods via ref (for compatibility)\n useImperativeHandle(ref, () => ({\n scrollToBottom: () => {\n // With flex-col-reverse, scroll to top = visual bottom\n scrollContainerRef.current?.scrollTo({ top: 0, behavior: 'smooth' });\n },\n scrollToLastMessage: () => {\n scrollContainerRef.current?.scrollTo({ top: 0, behavior: 'smooth' });\n },\n }), []);\n\n // No manual scroll effects needed - flex-col-reverse handles it naturally\n\n const GreetingIcon = greetingIcon === 'message' ? MessageSquare : Bot;\n const iconSize = largeGreetingIcon ? { container: '64px', icon: 'h-8 w-8' } : { container: '48px', icon: 'h-6 w-6' };\n const padding = largeGreetingIcon ? 'py-12' : 'py-8';\n\n return (\n <div ref={scrollContainerRef} className=\"h-full w-full overflow-y-auto flex flex-col-reverse\">\n <div className={`${isCompact ? 'p-3' : 'p-4'} space-y-4 max-w-full overflow-x-hidden`}>\n {/* Greeting */}\n {messages.length === 0 && greeting && (\n <div className={`text-center ${padding}`}>\n <div\n className=\"mx-auto mb-4 rounded-full bg-primary/10 flex items-center justify-center\"\n style={{ width: iconSize.container, height: iconSize.container }}\n >\n <GreetingIcon className={`${iconSize.icon} text-primary`} />\n </div>\n {greetingTitle && (\n <h4 className=\"font-medium mb-2\">{greetingTitle}</h4>\n )}\n <p className={`text-sm text-muted-foreground ${largeGreetingIcon ? 'max-w-[300px]' : 'max-w-[280px]'} mx-auto`}>\n {greeting}\n </p>\n </div>\n )}\n\n {/* Messages */}\n {messages.map((message) => (\n <div key={message.id} data-message-bubble>\n <MessageBubble message={message} isCompact={isCompact} />\n </div>\n ))}\n\n {/* Loading indicator with stop button */}\n {isLoading && messages.length > 0 && (\n <div className=\"flex items-center justify-between text-muted-foreground text-sm\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-1\">\n <span className=\"animate-bounce\" style={{ animationDelay: '0ms' }}>.</span>\n <span className=\"animate-bounce\" style={{ animationDelay: '150ms' }}>.</span>\n <span className=\"animate-bounce\" style={{ animationDelay: '300ms' }}>.</span>\n </div>\n <span>Generating response...</span>\n </div>\n {onStopStreaming && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onStopStreaming}\n className=\"h-6 px-2 text-xs\"\n >\n <StopCircle className=\"h-3 w-3 mr-1\" />\n Stop\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n }\n);\n\nChatMessages.displayName = 'ChatMessages';\n","'use client';\n\nimport { Loader2, Send } from 'lucide-react';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '@djangocfg/ui-nextjs';\n\nexport interface AIMessageInputProps {\n onSend: (message: string) => void;\n disabled?: boolean;\n isLoading?: boolean;\n placeholder?: string;\n maxRows?: number;\n}\n\nexport const AIMessageInput = React.memo<AIMessageInputProps>(\n ({\n onSend,\n disabled = false,\n isLoading = false,\n placeholder = 'Ask about DjangoCFG...',\n maxRows = 5,\n }) => {\n const [value, setValue] = useState('');\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Auto-resize textarea\n const adjustHeight = useCallback(() => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n\n // Reset height to auto to get the correct scrollHeight\n textarea.style.height = 'auto';\n\n // Calculate line height and max height\n const lineHeight = 24; // ~1.5rem\n const minHeight = 44; // Single line height with padding\n const maxHeight = lineHeight * maxRows + 20; // padding\n\n // Set new height\n const newHeight = Math.min(Math.max(textarea.scrollHeight, minHeight), maxHeight);\n textarea.style.height = `${newHeight}px`;\n }, [maxRows]);\n\n // Adjust height when value changes\n useEffect(() => {\n adjustHeight();\n }, [value, adjustHeight]);\n\n const handleSubmit = useCallback(\n (e?: React.FormEvent) => {\n e?.preventDefault();\n\n const trimmed = value.trim();\n if (!trimmed || disabled || isLoading) return;\n\n onSend(trimmed);\n setValue('');\n\n // Reset height after sending\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n textareaRef.current?.focus();\n },\n [value, disabled, isLoading, onSend]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const canSend = value.trim().length > 0 && !disabled && !isLoading;\n\n return (\n <form onSubmit={handleSubmit} className=\"w-full\">\n <div\n className=\"relative flex items-end rounded-2xl border border-input bg-background transition-colors focus-within:ring-1 focus-within:ring-ring focus-within:border-ring\"\n style={{ minHeight: '44px' }}\n >\n {/* Textarea */}\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || isLoading}\n rows={1}\n className=\"flex-1 resize-none bg-transparent px-4 py-3 text-sm placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 pr-12\"\n style={{\n minHeight: '44px',\n maxHeight: `${24 * maxRows + 20}px`,\n lineHeight: '1.5rem',\n }}\n autoComplete=\"off\"\n />\n\n {/* Send Button - positioned inside, bottom right */}\n <div\n className=\"absolute flex items-center justify-center\"\n style={{\n right: '6px',\n bottom: '6px',\n }}\n >\n <Button\n type=\"submit\"\n size=\"icon\"\n disabled={!canSend}\n className=\"h-8 w-8 rounded-full transition-all\"\n style={{\n opacity: canSend ? 1 : 0.5,\n }}\n >\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n </div>\n\n {/* Helper text */}\n <p className=\"mt-1.5 text-xs text-muted-foreground text-center\">\n Press Enter to send, Shift+Enter for new line\n </p>\n </form>\n );\n }\n);\n\nAIMessageInput.displayName = 'AIMessageInput';\n","'use client';\n\nimport { Bot, PanelRight, RotateCcw, X } from 'lucide-react';\nimport React from 'react';\n\nimport { Button, Card, CardContent, CardFooter, CardHeader } from '@djangocfg/ui-nextjs';\n\nimport { useAIChatContext } from '../context/AIChatContext';\nimport { ChatMessages } from './ChatMessages';\nimport { AIMessageInput } from './MessageInput';\n\nexport const ChatPanel = React.memo(() => {\n const {\n messages,\n isLoading,\n config,\n isMobile,\n sendMessage,\n closeChat,\n setDisplayMode,\n stopStreaming,\n clearMessages,\n } = useAIChatContext();\n\n // Mobile: fullscreen, Desktop: floating panel\n const panelStyles: React.CSSProperties = isMobile\n ? {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n width: '100%',\n height: '100%',\n maxHeight: '100dvh',\n borderRadius: 0,\n display: 'flex',\n flexDirection: 'column',\n margin: 0,\n border: 'none',\n }\n : {\n width: '380px',\n height: '520px',\n maxHeight: 'calc(100vh - 100px)',\n };\n\n return (\n <Card\n className={`flex flex-col ${isMobile ? 'rounded-none border-0 shadow-none' : 'shadow-2xl border-border/50'}`}\n style={panelStyles}\n >\n {/* Header */}\n <CardHeader className=\"flex flex-row items-center justify-between p-3 border-b\">\n <div className=\"flex items-center gap-2\">\n <div\n className=\"rounded-full bg-primary/10 flex items-center justify-center\"\n style={{ width: '32px', height: '32px' }}\n >\n <Bot className=\"h-4 w-4 text-primary\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-sm\">{config.title || 'DjangoCFG AI'}</h3>\n <p className=\"text-xs text-muted-foreground\">AI Assistant</p>\n </div>\n </div>\n <div className=\"flex gap-1\">\n {messages.length > 0 && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={clearMessages}\n title=\"New chat\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n )}\n {/* Sidebar mode button - only on desktop */}\n {!isMobile && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setDisplayMode('sidebar')}\n title=\"Switch to sidebar mode\"\n >\n <PanelRight className=\"h-4 w-4\" />\n </Button>\n )}\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" onClick={closeChat} title=\"Close\">\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </CardHeader>\n\n {/* Messages */}\n <CardContent className=\"flex-1 p-0 overflow-hidden\">\n <ChatMessages\n messages={messages}\n isLoading={isLoading}\n greeting={config.greeting}\n onStopStreaming={stopStreaming}\n isCompact\n greetingIcon=\"bot\"\n />\n </CardContent>\n\n {/* Input */}\n <CardFooter className=\"p-3 border-t\">\n <AIMessageInput\n onSend={sendMessage}\n isLoading={isLoading}\n placeholder={config.placeholder}\n />\n </CardFooter>\n </Card>\n );\n});\n\nChatPanel.displayName = 'ChatPanel';\n","'use client';\n\nimport { Bot, GripVertical, PanelRightClose, RotateCcw, X } from 'lucide-react';\nimport React, { useEffect } from 'react';\n\nimport { Button } from '@djangocfg/ui-nextjs';\n\nimport { useAIChatContext } from '../context/AIChatContext';\nimport { useChatLayout } from '../hooks/useChatLayout';\nimport { ChatMessages } from './ChatMessages';\nimport { AIMessageInput } from './MessageInput';\n\nexport interface ChatSidebarProps {\n /** Width of resize handle in pixels (default: 12) */\n resizeHandleWidth?: number;\n /** Show grip icon in resize handle (default: true) */\n showResizeIcon?: boolean;\n /** Custom class for resize handle */\n resizeHandleClassName?: string;\n}\n\nexport const ChatSidebar = React.memo<ChatSidebarProps>(({\n resizeHandleWidth = 12,\n showResizeIcon = true,\n resizeHandleClassName,\n}) => {\n const {\n messages,\n isLoading,\n config,\n sendMessage,\n closeChat,\n setDisplayMode,\n stopStreaming,\n clearMessages,\n } = useAIChatContext();\n\n // Use the layout hook for content pushing and resizing\n const { applyLayout, getSidebarStyles, startResize, isResizing } = useChatLayout();\n\n // Apply sidebar layout on mount, reset on unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n applyLayout('sidebar');\n return () => {\n applyLayout('closed');\n };\n }, []);\n\n const sidebarStyles = getSidebarStyles();\n\n return (\n <div\n className=\"flex bg-background\"\n style={sidebarStyles}\n data-chat-sidebar-panel\n >\n {/* Resize handle */}\n <div\n className={`\n flex items-center justify-center cursor-ew-resize\n border-l border-border transition-colors select-none flex-shrink-0\n ${isResizing ? 'bg-primary/20' : 'bg-muted/30 hover:bg-muted/50'}\n ${resizeHandleClassName || ''}\n `}\n style={{ width: resizeHandleWidth }}\n onMouseDown={startResize}\n title=\"Drag to resize\"\n >\n {showResizeIcon && (\n <GripVertical className={`h-4 w-4 ${isResizing ? 'text-primary' : 'text-muted-foreground/50'}`} />\n )}\n </div>\n\n {/* Main sidebar content */}\n <div className=\"flex flex-col flex-1 min-w-0\">\n {/* Header - uses CSS variable for navbar height consistency */}\n <div\n className=\"flex items-center justify-between px-4 border-b border-border bg-muted/30\"\n style={{ height: 'var(--nextra-navbar-height, 64px)', minHeight: 'var(--nextra-navbar-height, 64px)' }}\n >\n <div className=\"flex items-center gap-2\">\n <div\n className=\"rounded-full bg-primary/10 flex items-center justify-center\"\n style={{ width: '32px', height: '32px' }}\n >\n <Bot className=\"h-4 w-4 text-primary\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-sm\">{config.title || 'DjangoCFG AI'}</h3>\n <p className=\"text-xs text-muted-foreground\">AI Assistant</p>\n </div>\n </div>\n <div className=\"flex gap-1\">\n {messages.length > 0 && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={clearMessages}\n title=\"New chat\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setDisplayMode('floating')}\n title=\"Switch to floating mode\"\n >\n <PanelRightClose className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" onClick={closeChat} title=\"Close chat\">\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"flex-1 overflow-hidden\">\n <ChatMessages\n messages={messages}\n isLoading={isLoading}\n greeting={config.greeting}\n onStopStreaming={stopStreaming}\n isCompact={false}\n largeGreetingIcon\n greetingIcon=\"message\"\n greetingTitle=\"How can I help?\"\n />\n </div>\n\n {/* Input */}\n <div className=\"p-4 border-t border-border bg-muted/30\">\n <AIMessageInput onSend={sendMessage} isLoading={isLoading} placeholder={config.placeholder} />\n </div>\n </div>\n </div>\n );\n});\n\nChatSidebar.displayName = 'ChatSidebar';\n","'use client';\n\nimport { MessageCircle } from 'lucide-react';\nimport React from 'react';\n\nimport { Button, Portal } from '@djangocfg/ui-nextjs';\n\nimport { ChatProvider, useChatContext, useChatContextOptional } from '../context';\nimport { useChatLayout } from '../hooks/useChatLayout';\nimport { ChatPanel } from './ChatPanel';\nimport { ChatSidebar } from './ChatSidebar';\n\nimport type { ChatWidgetConfig } from '../types';\n\nexport interface ChatWidgetProps extends ChatWidgetConfig {\n /** Custom class name for the container */\n className?: string;\n}\n\n/**\n * Internal chat widget that uses context\n */\nconst ChatWidgetInternal: React.FC<{ className?: string }> = ({ className }) => {\n const { config, displayMode, openChat, isMobile } = useChatContext();\n\n // Use layout hook for consistent positioning\n const { getFabStyles, getFloatingStyles } = useChatLayout();\n\n const position = config.position || 'bottom-right';\n const fabStyles = getFabStyles(position);\n const floatingStyles = getFloatingStyles(position);\n\n // Mobile fullscreen styles for floating mode\n // Using inset: 0 with height: 100dvh for proper mobile viewport handling\n const mobileFullscreenStyles: React.CSSProperties = {\n position: 'fixed',\n inset: 0,\n height: '100dvh',\n width: '100vw',\n zIndex: 400, // Higher z-index for mobile overlay\n overflow: 'hidden',\n };\n\n // Mode: closed - just show FAB\n if (displayMode === 'closed') {\n return (\n <Portal>\n <div style={fabStyles} className={className || ''}>\n <Button\n onClick={openChat}\n className=\"rounded-full shadow-lg hover:shadow-xl transition-shadow\"\n style={{ width: '56px', height: '56px' }}\n >\n <MessageCircle className=\"h-6 w-6\" />\n </Button>\n </div>\n </Portal>\n );\n }\n\n // Mode: sidebar - full-height panel on the right (desktop only)\n if (displayMode === 'sidebar') {\n return (\n <Portal>\n <ChatSidebar />\n </Portal>\n );\n }\n\n // Mode: floating - fullscreen on mobile, floating panel on desktop\n return (\n <Portal>\n <div style={isMobile ? mobileFullscreenStyles : floatingStyles} className={className || ''}>\n <ChatPanel />\n </div>\n </Portal>\n );\n};\n\n/**\n * ChatWidget component\n *\n * Can be used in two ways:\n * 1. Standalone (wraps itself in ChatProvider)\n * 2. Inside a ChatProvider (uses context directly)\n */\nexport const ChatWidget: React.FC<ChatWidgetProps> = ({\n apiEndpoint = '/api/chat',\n title = 'DjangoCFG AI',\n placeholder = 'Ask about DjangoCFG...',\n greeting = \"Hi! I'm your DjangoCFG documentation assistant. Ask me anything about configuration, features, or how to use the library.\",\n position = 'bottom-right',\n variant = 'default',\n className,\n}) => {\n // Check if we're inside a ChatProvider\n const existingContext = useChatContextOptional();\n\n // If already in context, use internal widget directly\n if (existingContext) {\n return <ChatWidgetInternal className={className} />;\n }\n\n // Otherwise, wrap in provider\n return (\n <ChatProvider\n apiEndpoint={apiEndpoint}\n config={{ title, placeholder, greeting, position, variant }}\n >\n <ChatWidgetInternal className={className} />\n </ChatProvider>\n );\n};\n\nChatWidget.displayName = 'ChatWidget';\n","'use client';\n\nimport { Zap } from 'lucide-react';\nimport React from 'react';\n\nimport { Button, Portal } from '@djangocfg/ui-nextjs';\n\nimport {\n AIChatProvider, useAIChatContext, useAIChatContextOptional\n} from '../context/AIChatContext';\nimport { useChatLayout } from '../hooks/useChatLayout';\nimport { ChatWidgetConfig, getMcpEndpoints} from '../types';\nimport { ChatPanel } from './ChatPanel';\nimport { ChatSidebar } from './ChatSidebar';\n\n// CSS for game-quality multi-layer animated border with smooth color flow\nconst fabAnimationStyles = `\n@keyframes rotate-gradient {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n@keyframes rotate-gradient-reverse {\n 0% { transform: rotate(360deg); }\n 100% { transform: rotate(0deg); }\n}\n\n@keyframes color-shift-glow {\n 0%, 100% {\n box-shadow:\n 0 0 20px rgba(251, 191, 36, 0.5),\n 0 0 40px rgba(168, 85, 247, 0.3),\n 0 0 60px rgba(20, 184, 166, 0.2);\n }\n 33% {\n box-shadow:\n 0 0 20px rgba(168, 85, 247, 0.5),\n 0 0 40px rgba(20, 184, 166, 0.3),\n 0 0 60px rgba(251, 191, 36, 0.2);\n }\n 66% {\n box-shadow:\n 0 0 20px rgba(20, 184, 166, 0.5),\n 0 0 40px rgba(236, 72, 153, 0.3),\n 0 0 60px rgba(168, 85, 247, 0.2);\n }\n}\n\n@keyframes icon-pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n filter: drop-shadow(0 0 4px rgba(251, 191, 36, 0.7));\n }\n 50% {\n opacity: 0.85;\n transform: scale(1.15);\n filter: drop-shadow(0 0 12px rgba(251, 191, 36, 1));\n }\n}\n\n@keyframes border-pulse {\n 0%, 100% {\n opacity: 1;\n filter: blur(0px);\n }\n 50% {\n opacity: 0.85;\n filter: blur(0.5px);\n }\n}\n\n@keyframes inner-glow-pulse {\n 0%, 100% {\n box-shadow:\n inset 0 0 15px rgba(251, 191, 36, 0.3),\n inset 0 0 25px rgba(168, 85, 247, 0.2);\n }\n 50% {\n box-shadow:\n inset 0 0 20px rgba(168, 85, 247, 0.35),\n inset 0 0 30px rgba(20, 184, 166, 0.25);\n }\n}\n\n@keyframes fab-entrance {\n 0% {\n transform: scale(0);\n }\n 50% {\n transform: scale(1.08);\n }\n 70% {\n transform: scale(0.98);\n }\n 85% {\n transform: scale(1.02);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes fab-glow-entrance {\n 0% {\n box-shadow: 0 0 0 rgba(251, 191, 36, 0);\n }\n 40% {\n box-shadow:\n 0 0 25px rgba(251, 191, 36, 0.6),\n 0 0 50px rgba(168, 85, 247, 0.4),\n 0 0 75px rgba(20, 184, 166, 0.25);\n }\n 100% {\n box-shadow:\n 0 0 20px rgba(251, 191, 36, 0.5),\n 0 0 40px rgba(168, 85, 247, 0.3),\n 0 0 60px rgba(20, 184, 166, 0.2);\n }\n}\n`;\n\nexport interface AIChatWidgetProps extends ChatWidgetConfig {\n /** Custom class name for the container */\n className?: string;\n /** Enable streaming responses (default: true) */\n enableStreaming?: boolean;\n}\n\n/**\n * Internal AI chat widget that uses context\n */\nconst AIChatWidgetInternal = React.memo<{ className?: string }>(({ className }) => {\n const { config, displayMode, openChat, isMobile } = useAIChatContext();\n\n // Use layout hook for consistent positioning\n const { getFabStyles, getFloatingStyles } = useChatLayout();\n\n const position = config.position || 'bottom-right';\n const fabStyles = getFabStyles(position);\n const floatingStyles = getFloatingStyles(position);\n\n // Mode: closed - just show FAB with game-quality multi-layer animated border\n if (displayMode === 'closed') {\n return (\n <Portal>\n <style>{fabAnimationStyles}</style>\n <div style={fabStyles} className={className || ''}>\n {/* Outer glow container with entrance and color-shifting animations */}\n <div\n className=\"relative rounded-full\"\n style={{\n width: '68px',\n height: '68px',\n overflow: 'hidden',\n animation: 'fab-entrance 0.6s cubic-bezier(0.34, 1.45, 0.64, 1) 0s 1 normal forwards, fab-glow-entrance 0.8s ease-out 0s 1 normal forwards, color-shift-glow 8s ease-in-out 0.6s infinite',\n }}\n >\n {/* Border container - multiple layers for depth */}\n <div\n className=\"absolute rounded-full\"\n style={{\n inset: '0',\n overflow: 'hidden',\n }}\n >\n {/* Layer 1: Base smooth gradient with more color stops */}\n <div\n className=\"absolute rounded-full\"\n style={{\n inset: '0',\n background: `conic-gradient(\n from 0deg,\n rgba(251, 191, 36, 1) 0%,\n rgba(251, 191, 36, 0.7) 8%,\n rgba(251, 191, 36, 0) 15%,\n rgba(168, 85, 247, 0) 20%,\n rgba(168, 85, 247, 0.7) 28%,\n rgba(168, 85, 247, 1) 35%,\n rgba(168, 85, 247, 0.7) 42%,\n rgba(168, 85, 247, 0) 50%,\n rgba(20, 184, 166, 0) 55%,\n rgba(20, 184, 166, 0.7) 63%,\n rgba(20, 184, 166, 1) 70%,\n rgba(20, 184, 166, 0.7) 77%,\n rgba(20, 184, 166, 0) 85%,\n rgba(236, 72, 153, 0) 88%,\n rgba(236, 72, 153, 0.7) 93%,\n rgba(236, 72, 153, 1) 97%,\n rgba(251, 191, 36, 1) 100%\n )`,\n animation: 'rotate-gradient 7s linear infinite, border-pulse 4s ease-in-out infinite',\n filter: 'blur(1px)',\n opacity: 0.95,\n }}\n />\n\n {/* Layer 2: Secondary gradient (counter-clockwise) - stronger */}\n <div\n className=\"absolute rounded-full\"\n style={{\n inset: '1px',\n background: `conic-gradient(\n from 180deg,\n rgba(168, 85, 247, 0.85) 0%,\n rgba(168, 85, 247, 0.5) 10%,\n rgba(168, 85, 247, 0) 20%,\n rgba(20, 184, 166, 0) 30%,\n rgba(20, 184, 166, 0.5) 40%,\n rgba(20, 184, 166, 0.85) 50%,\n rgba(20, 184, 166, 0.5) 60%,\n rgba(20, 184, 166, 0) 70%,\n rgba(251, 191, 36, 0) 75%,\n rgba(251, 191, 36, 0.5) 85%,\n rgba(251, 191, 36, 0.85) 95%,\n rgba(168, 85, 247, 0.85) 100%\n )`,\n animation: 'rotate-gradient-reverse 9s linear infinite',\n filter: 'blur(0.75px)',\n opacity: 0.75,\n }}\n />\n\n {/* Inner mask with glowing edge */}\n <div\n className=\"absolute rounded-full bg-background\"\n style={{\n inset: '4px',\n animation: 'inner-glow-pulse 5s ease-in-out infinite',\n }}\n />\n\n {/* Main FAB button */}\n <Button\n onClick={openChat}\n variant=\"ghost\"\n className=\"absolute rounded-full hover:scale-105 transition-all duration-300 bg-background/80 hover:bg-background/95 border-0 backdrop-blur-sm\"\n style={{\n inset: '2.5px',\n width: 'auto',\n height: 'auto',\n }}\n >\n <Zap\n className=\"h-6 w-6\"\n style={{\n animation: 'icon-pulse 2.5s ease-in-out infinite',\n color: '#fbbf24',\n fill: '#fbbf24',\n }}\n />\n </Button>\n </div>\n </div>\n </div>\n </Portal>\n );\n }\n\n // Mode: sidebar - full-height panel on the right (desktop only)\n if (displayMode === 'sidebar') {\n return (\n <Portal>\n <ChatSidebar />\n </Portal>\n );\n }\n\n // Mode: floating - fullscreen on mobile (via Portal), floating panel on desktop\n if (isMobile) {\n return (\n <Portal>\n <div\n className=\"z-[400] overflow-hidden\"\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n width: '100vw',\n height: '100dvh',\n }}\n >\n <ChatPanel />\n </div>\n </Portal>\n );\n }\n\n return (\n <Portal>\n <div style={floatingStyles} className={className || ''}>\n <ChatPanel />\n </div>\n </Portal>\n );\n});\n\nAIChatWidgetInternal.displayName = 'AIChatWidgetInternal';\n\n/**\n * AI Chat Widget component\n *\n * AI-powered documentation assistant with streaming support.\n * Uses Mastra agent backend for intelligent responses.\n *\n * Can be used in two ways:\n * 1. Standalone (wraps itself in AIChatProvider)\n * 2. Inside an AIChatProvider (uses context directly)\n *\n * @example\n * ```tsx\n * // Standalone usage (always uses production API)\n * <AIChatWidget />\n *\n * // Auto-detect environment (dev/prod)\n * <AIChatWidget autoDetectEnvironment={true} />\n *\n * // With provider for custom control\n * <AIChatProvider apiEndpoint=\"/api/ai/chat\">\n * <MyApp />\n * <AIChatWidget />\n * </AIChatProvider>\n * ```\n */\nexport const AIChatWidget: React.FC<AIChatWidgetProps> = ({\n apiEndpoint,\n title = 'DjangoCFG AI',\n placeholder = 'Ask about DjangoCFG...',\n greeting = \"Hi! I'm your DjangoCFG AI assistant powered by GPT. Ask me anything about configuration, features, or how to use the library.\",\n position = 'bottom-right',\n variant = 'default',\n className,\n enableStreaming = true,\n autoDetectEnvironment = false,\n}) => {\n // Check if we're inside an AIChatProvider\n const existingContext = useAIChatContextOptional();\n\n // If already in context, use internal widget directly\n if (existingContext) {\n return <AIChatWidgetInternal className={className} />;\n }\n\n // Determine API endpoint: use provided, or get from config based on autoDetect\n const finalApiEndpoint = apiEndpoint || getMcpEndpoints(autoDetectEnvironment).chat;\n\n // Otherwise, wrap in provider\n return (\n <AIChatProvider\n apiEndpoint={finalApiEndpoint}\n config={{ title, placeholder, greeting, position, variant, autoDetectEnvironment }}\n enableStreaming={enableStreaming}\n >\n <AIChatWidgetInternal className={className} />\n </AIChatProvider>\n );\n};\n\nAIChatWidget.displayName = 'AIChatWidget';\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport type { McpChatEventDetail, UseMcpChatReturn } from '../types';\n\n/**\n * Hook to send messages to MCP Chat from anywhere in the app\n *\n * @example\n * ```tsx\n * function ErrorBoundary({ error }) {\n * const { sendToChat } = useMcpChat();\n *\n * const explainError = () => {\n * sendToChat({\n * message: `Explain this error: ${error.message}`,\n * context: {\n * type: 'error',\n * data: { error: error.stack },\n * source: 'ErrorBoundary'\n * }\n * });\n * };\n *\n * return <button onClick={explainError}>Explain Error</button>;\n * }\n * ```\n */\nexport function useMcpChat(): UseMcpChatReturn {\n /**\n * Send message to chat via CustomEvent\n */\n const sendToChat = useCallback((detail: McpChatEventDetail) => {\n if (typeof window === 'undefined') {\n console.error('[useMcpChat] Cannot send message: window is not available');\n return;\n }\n\n // Create custom event\n const event = new CustomEvent('mcp:chat:send', {\n detail,\n bubbles: true,\n });\n\n // Set up handler confirmation listener\n let handled = false;\n const handleConfirmation = () => {\n handled = true;\n };\n\n window.addEventListener('mcp:chat:handled', handleConfirmation, { once: true });\n\n // Dispatch event\n window.dispatchEvent(event);\n\n // Check if event was handled\n setTimeout(() => {\n window.removeEventListener('mcp:chat:handled', handleConfirmation);\n\n if (!handled) {\n const errorMessage = 'AI Chat is not available. Please make sure the chat component is loaded.';\n console.error('[useMcpChat]', errorMessage);\n\n // Import consola dynamically if available\n if (typeof window !== 'undefined' && (window as any).consola) {\n (window as any).consola.error('[useMcpChat] Chat not available');\n }\n\n // Show user-friendly alert\n alert(errorMessage);\n }\n }, 100);\n }, []);\n\n /**\n * Check if chat is available\n */\n const isChatAvailable = useCallback(() => {\n if (typeof window === 'undefined') return false;\n\n // Check if chat registered itself\n return (window as any).__MCP_CHAT_AVAILABLE__ === true;\n }, []);\n\n return {\n sendToChat,\n isChatAvailable,\n };\n}\n","'use client';\n\nimport { Bot } from 'lucide-react';\n\nimport { Button, ButtonProps} from '@djangocfg/ui-nextjs';\n\nimport { useMcpChat } from '../hooks/useMcpChat';\n\nimport type { McpChatEventDetail } from '../types';\n\nexport interface AskAIButtonProps extends Omit<ButtonProps, 'onClick'> {\n /** Message to send to AI */\n message: string;\n /** Additional context data */\n contextData?: Record<string, any>;\n /** Source component name */\n source?: string;\n /** Auto-send message (default: true) */\n autoSend?: boolean;\n /** Show icon (default: true) */\n showIcon?: boolean;\n /** Callback after sending */\n onSent?: () => void;\n}\n\n/**\n * Universal AI chat trigger button\n *\n * @example Basic usage\n * ```tsx\n * <AskAIButton message=\"Explain this feature\">\n * Explain this\n * </AskAIButton>\n * ```\n *\n * @example With context\n * ```tsx\n * <AskAIButton\n * message=\"Why is this failing?\"\n * contextData={{ error: error.stack }}\n * source=\"ErrorBoundary\"\n * >\n * Ask AI\n * </AskAIButton>\n * ```\n */\nexport function AskAIButton({\n message,\n contextData,\n source,\n autoSend = true,\n showIcon = true,\n onSent,\n children = 'Ask AI',\n variant = 'outline',\n size = 'default',\n className,\n ...buttonProps\n}: AskAIButtonProps) {\n const { sendToChat } = useMcpChat();\n\n const handleClick = () => {\n const detail: McpChatEventDetail = {\n message,\n autoSend,\n // No displayMode - chat will use remembered mode automatically\n };\n\n if (contextData || source) {\n detail.context = {\n data: contextData,\n source,\n };\n }\n\n sendToChat(detail);\n onSent?.();\n };\n\n return (\n <Button\n onClick={handleClick}\n variant={variant}\n size={size}\n className={className}\n {...buttonProps}\n >\n {showIcon && <Bot className=\"h-4 w-4 mr-2\" />}\n {children}\n </Button>\n );\n}\n","/**\n * LocalStorage utilities for PWA install state persistence\n */\n\nimport type { IOSGuideState } from '../types';\n\n/**\n * Storage keys\n */\nexport const STORAGE_KEYS = {\n IOS_GUIDE_DISMISSED: 'pwa_ios_guide_dismissed_at',\n APP_INSTALLED: 'pwa_app_installed',\n A2HS_DISMISSED: 'pwa_a2hs_dismissed_at',\n} as const;\n\n/**\n * Check if iOS guide was dismissed recently\n * @param resetDays Number of days before re-showing (default: 7)\n */\nexport function isDismissedRecently(resetDays: number = 7): boolean {\n if (typeof window === 'undefined') return false;\n\n try {\n const dismissed = localStorage.getItem(STORAGE_KEYS.IOS_GUIDE_DISMISSED);\n if (!dismissed) return false;\n\n const dismissedAt = parseInt(dismissed, 10);\n const now = Date.now();\n const daysSinceDismissed = (now - dismissedAt) / (1000 * 60 * 60 * 24);\n\n return daysSinceDismissed < resetDays;\n } catch {\n return false;\n }\n}\n\n/**\n * Mark iOS guide as dismissed\n */\nexport function markIOSGuideDismissed(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.setItem(STORAGE_KEYS.IOS_GUIDE_DISMISSED, Date.now().toString());\n } catch {\n // Fail silently if localStorage is not available\n }\n}\n\n/**\n * Clear iOS guide dismissal\n */\nexport function clearIOSGuideDismissal(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.removeItem(STORAGE_KEYS.IOS_GUIDE_DISMISSED);\n } catch {\n // Fail silently\n }\n}\n\n/**\n * Get iOS guide state\n */\nexport function getIOSGuideState(resetDays: number = 7): IOSGuideState {\n if (typeof window === 'undefined') {\n return {\n dismissed: false,\n dismissedAt: null,\n shouldShow: false,\n };\n }\n\n try {\n const dismissed = localStorage.getItem(STORAGE_KEYS.IOS_GUIDE_DISMISSED);\n if (!dismissed) {\n return {\n dismissed: false,\n dismissedAt: null,\n shouldShow: true,\n };\n }\n\n const dismissedAt = parseInt(dismissed, 10);\n const now = Date.now();\n const daysSinceDismissed = (now - dismissedAt) / (1000 * 60 * 60 * 24);\n\n return {\n dismissed: true,\n dismissedAt,\n shouldShow: daysSinceDismissed >= resetDays,\n };\n } catch {\n return {\n dismissed: false,\n dismissedAt: null,\n shouldShow: false,\n };\n }\n}\n\n/**\n * Mark app as installed\n */\nexport function markAppInstalled(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.setItem(STORAGE_KEYS.APP_INSTALLED, 'true');\n // Clear dismissal state when app is installed\n clearIOSGuideDismissal();\n } catch {\n // Fail silently\n }\n}\n\n/**\n * Check if app is marked as installed\n */\nexport function isAppInstalled(): boolean {\n if (typeof window === 'undefined') return false;\n\n try {\n return localStorage.getItem(STORAGE_KEYS.APP_INSTALLED) === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * Check if A2HS hint was dismissed recently\n * @param resetDays Number of days before re-showing (default: 3)\n */\nexport function isA2HSDismissedRecently(resetDays: number = 3): boolean {\n return isDismissedRecentlyHelper(resetDays, STORAGE_KEYS.A2HS_DISMISSED);\n}\n\n/**\n * Mark A2HS hint as dismissed\n */\nexport function markA2HSDismissed(): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(STORAGE_KEYS.A2HS_DISMISSED, Date.now().toString());\n } catch {\n // Fail silently\n }\n}\n\n/**\n * Helper: Check if a key was dismissed recently\n * @internal\n */\nfunction isDismissedRecentlyHelper(resetDays: number, key: string): boolean {\n if (typeof window === 'undefined') return false;\n try {\n const dismissed = localStorage.getItem(key);\n if (!dismissed) return false;\n const dismissedAt = parseInt(dismissed, 10);\n const daysSince = (Date.now() - dismissedAt) / (1000 * 60 * 60 * 24);\n return daysSince < resetDays;\n } catch {\n return false;\n }\n}\n\n/**\n * Clear all PWA install data\n */\nexport function clearAllPWAInstallData(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.removeItem(STORAGE_KEYS.IOS_GUIDE_DISMISSED);\n localStorage.removeItem(STORAGE_KEYS.APP_INSTALLED);\n localStorage.removeItem(STORAGE_KEYS.A2HS_DISMISSED);\n } catch {\n // Fail silently\n }\n}\n","/**\n * PWA Logger with Conditional Logging\n *\n * Provides logging utilities that respect environment and debug settings:\n * - In production: Only errors are logged\n * - In development: All levels are logged\n * - Debug mode: Can be enabled in production via localStorage\n *\n * @example\n * ```typescript\n * import { pwaLogger } from '../utils/logger';\n *\n * pwaLogger.info('Info message'); // Only in dev\n * pwaLogger.warn('Warning message'); // Only in dev\n * pwaLogger.error('Error message'); // Always logged\n * pwaLogger.debug('Debug message'); // Only when debug enabled\n * ```\n *\n * Enable debug mode in production:\n * ```typescript\n * import { enablePWADebug } from '../utils/logger';\n * enablePWADebug();\n * // or in console:\n * localStorage.setItem('pwa_debug', 'true');\n * ```\n */\n\nimport { consola } from 'consola';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\n/**\n * Check if debug mode is enabled via localStorage\n */\nfunction isDebugEnabled(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return localStorage.getItem('pwa_debug') === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * PWA Logger instance with conditional logging\n */\nexport const pwaLogger = {\n /**\n * Info level logging\n * Only logs in development or when debug is enabled\n */\n info: (...args: Parameters<typeof consola.info>): void => {\n if (isDevelopment || isDebugEnabled()) {\n consola.info(...args);\n }\n },\n\n /**\n * Warning level logging\n * Only logs in development or when debug is enabled\n */\n warn: (...args: Parameters<typeof consola.warn>): void => {\n if (isDevelopment || isDebugEnabled()) {\n consola.warn(...args);\n }\n },\n\n /**\n * Error level logging\n * Always logs (production + development)\n */\n error: (...args: Parameters<typeof consola.error>): void => {\n consola.error(...args);\n },\n\n /**\n * Debug level logging\n * Only logs when debug is explicitly enabled\n */\n debug: (...args: Parameters<typeof consola.debug>): void => {\n if (isDebugEnabled()) {\n consola.debug(...args);\n }\n },\n\n /**\n * Success level logging\n * Only logs in development or when debug is enabled\n */\n success: (...args: Parameters<typeof consola.success>): void => {\n if (isDevelopment || isDebugEnabled()) {\n consola.success(...args);\n }\n },\n};\n\n/**\n * Enable debug mode\n *\n * This allows seeing debug logs in production.\n * Call this function or set localStorage manually:\n * `localStorage.setItem('pwa_debug', 'true')`\n *\n * @example\n * ```typescript\n * import { enablePWADebug } from '@djangocfg/layouts/snippets';\n * enablePWADebug();\n * // Reload page to see debug logs\n * ```\n */\nexport function enablePWADebug(): void {\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem('pwa_debug', 'true');\n consola.info('[PWA] Debug mode enabled. Reload page to see debug logs.');\n } catch (e) {\n consola.error('[PWA] Failed to enable debug mode:', e);\n }\n }\n}\n\n/**\n * Disable debug mode\n *\n * @example\n * ```typescript\n * import { disablePWADebug } from '@djangocfg/layouts/snippets';\n * disablePWADebug();\n * ```\n */\nexport function disablePWADebug(): void {\n if (typeof window !== 'undefined') {\n try {\n localStorage.removeItem('pwa_debug');\n consola.info('[PWA] Debug mode disabled.');\n } catch (e) {\n consola.error('[PWA] Failed to disable debug mode:', e);\n }\n }\n}\n\n/**\n * Check if debug mode is currently active\n *\n * @returns true if debug mode is enabled\n */\nexport function isPWADebugEnabled(): boolean {\n return isDebugEnabled();\n}\n","/**\n * Platform Detection Utilities\n *\n * Centralized utilities for detecting PWA state, platform, and capabilities.\n * Used by hooks to avoid code duplication.\n */\n\n/**\n * Check if running as PWA (standalone mode)\n *\n * Checks if the app is running in standalone mode (added to home screen).\n * This is the primary indicator that a PWA has been installed.\n *\n * @returns true if app is running in standalone mode\n *\n * @example\n * ```typescript\n * if (isStandalone()) {\n * console.log('Running as PWA');\n * }\n * ```\n */\nexport function isStandalone(): boolean {\n if (typeof window === 'undefined') return false;\n\n // Fallback for older browsers without matchMedia\n if (!window.matchMedia) {\n // Use legacy iOS check only\n const nav = navigator as Navigator & { standalone?: boolean };\n return nav.standalone === true;\n }\n\n // Check display-mode media query (modern approach)\n const isStandaloneDisplay = window.matchMedia('(display-mode: standalone)').matches;\n\n // Legacy iOS check (navigator.standalone)\n const nav = navigator as Navigator & { standalone?: boolean };\n const isStandaloneNavigator = nav.standalone === true;\n\n return isStandaloneDisplay || isStandaloneNavigator;\n}\n\n/**\n * Check if device is mobile\n *\n * @returns true if device is mobile (iOS, Android, etc.)\n */\nexport function isMobileDevice(): boolean {\n if (typeof window === 'undefined') return false;\n return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\n}\n\n/**\n * Check if web app manifest exists and is valid\n *\n * @returns true if manifest link exists in document head\n */\nexport function hasValidManifest(): boolean {\n if (typeof document === 'undefined') return false;\n const manifestLink = document.querySelector('link[rel=\"manifest\"]');\n return !!manifestLink;\n}\n\n/**\n * Reliable check for PWA mode with edge case handling\n *\n * This function provides additional validation for desktop browsers\n * to avoid false positives (e.g., Safari macOS \"Add to Dock\").\n *\n * For mobile devices, standard standalone check is sufficient.\n * For desktop, additionally validates that a manifest exists.\n *\n * @returns true if app is running as a genuine PWA\n *\n * @example\n * ```typescript\n * // Use this for more reliable detection\n * if (isStandaloneReliable()) {\n * console.log('Definitely running as PWA');\n * }\n * ```\n */\nexport function isStandaloneReliable(): boolean {\n const standalone = isStandalone();\n if (!standalone) return false;\n\n // For mobile devices, standalone check is sufficient\n if (isMobileDevice()) return true;\n\n // For desktop browsers, additionally check for valid manifest\n // This prevents false positives like Safari macOS \"Add to Dock\"\n return hasValidManifest();\n}\n\n/**\n * Get display mode from media query\n *\n * @returns Current display mode: 'standalone', 'fullscreen', 'minimal-ui', or 'browser'\n */\nexport function getDisplayMode(): 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser' {\n if (typeof window === 'undefined') return 'browser';\n\n if (!window.matchMedia) return 'browser';\n\n const modes: Array<'standalone' | 'fullscreen' | 'minimal-ui'> = [\n 'fullscreen',\n 'standalone',\n 'minimal-ui',\n ];\n\n for (const mode of modes) {\n if (window.matchMedia(`(display-mode: ${mode})`).matches) {\n return mode;\n }\n }\n\n return 'browser';\n}\n\n/**\n * Create a media query listener for display-mode changes\n *\n * @param callback - Function to call when display mode changes\n * @returns Cleanup function to remove listener\n *\n * @example\n * ```typescript\n * const cleanup = onDisplayModeChange((isStandalone) => {\n * console.log('Display mode changed:', isStandalone);\n * });\n *\n * // Later: cleanup();\n * ```\n */\nexport function onDisplayModeChange(callback: (isStandalone: boolean) => void): () => void {\n if (typeof window === 'undefined' || !window.matchMedia) {\n return () => {}; // No-op cleanup\n }\n\n const mediaQuery = window.matchMedia('(display-mode: standalone)');\n\n const handleChange = (e: MediaQueryListEvent) => {\n callback(e.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleChange);\n };\n}\n","'use client';\n\n/**\n * PWA Install Prompt Hook\n *\n * Manages beforeinstallprompt event and installation state\n * Uses existing hooks from @djangocfg/ui-nextjs for platform detection\n */\n\nimport { useEffect, useState } from 'react';\n\nimport { useBrowserDetect, useDeviceDetect } from '@djangocfg/ui-nextjs';\n\nimport { markAppInstalled } from '../utils/localStorage';\nimport { pwaLogger } from '../utils/logger';\nimport { isStandalone, onDisplayModeChange } from '../utils/platform';\n\nimport type { BeforeInstallPromptEvent, InstallPromptState, InstallOutcome } from '../types';\nexport function useInstallPrompt() {\n const browser = useBrowserDetect();\n const device = useDeviceDetect();\n\n const [state, setState] = useState<InstallPromptState>(() => {\n if (typeof window === 'undefined') {\n return {\n isIOS: false,\n isAndroid: false,\n isSafari: false,\n isChrome: false,\n isInstalled: false,\n canPrompt: false,\n deferredPrompt: null,\n };\n }\n\n // Real Safari = Safari && NOT Chromium (avoid Arc, Brave on iOS)\n const isSafari = browser.isSafari && !browser.isChromium;\n\n return {\n isIOS: device.isIOS,\n isAndroid: device.isAndroid,\n isSafari,\n isChrome: browser.isChrome || browser.isChromium,\n isInstalled: isStandalone(),\n canPrompt: false,\n deferredPrompt: null,\n };\n });\n\n // Update state when platform info changes\n useEffect(() => {\n const isSafari = browser.isSafari && !browser.isChromium;\n\n setState((prev) => ({\n ...prev,\n isIOS: device.isIOS,\n isAndroid: device.isAndroid,\n isSafari,\n isChrome: browser.isChrome || browser.isChromium,\n isInstalled: isStandalone(),\n }));\n }, [browser, device]);\n\n // Listen for beforeinstallprompt event (Android Chrome only)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleBeforeInstallPrompt = (e: Event) => {\n // Prevent the default browser install prompt\n e.preventDefault();\n\n const event = e as BeforeInstallPromptEvent;\n\n setState((prev) => ({\n ...prev,\n canPrompt: true,\n deferredPrompt: event,\n }));\n };\n\n window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);\n\n return () => {\n window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);\n };\n }, []);\n\n // Listen for appinstalled event (Android Chrome)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleAppInstalled = () => {\n setState((prev) => ({\n ...prev,\n canPrompt: false,\n deferredPrompt: null,\n isInstalled: true,\n }));\n\n // Mark as installed in localStorage\n markAppInstalled();\n };\n\n window.addEventListener('appinstalled', handleAppInstalled);\n\n return () => {\n window.removeEventListener('appinstalled', handleAppInstalled);\n };\n }, []);\n\n // Check for display-mode changes (user adds to home screen)\n useEffect(() => {\n const cleanup = onDisplayModeChange((isStandaloneMode) => {\n if (isStandaloneMode) {\n setState((prev) => ({\n ...prev,\n isInstalled: true,\n canPrompt: false,\n deferredPrompt: null,\n }));\n\n markAppInstalled();\n }\n });\n\n return cleanup;\n }, []);\n\n /**\n * Trigger Android native install prompt\n */\n const promptInstall = async (): Promise<InstallOutcome> => {\n if (!state.deferredPrompt) {\n pwaLogger.warn('[PWA Install] No deferred prompt available');\n return null;\n }\n\n try {\n // Show the native prompt\n await state.deferredPrompt.prompt();\n\n // Wait for user response\n const { outcome } = await state.deferredPrompt.userChoice;\n\n pwaLogger.info('[PWA Install] User choice:', outcome);\n\n // Clear the deferred prompt\n setState((prev) => ({\n ...prev,\n deferredPrompt: null,\n canPrompt: false,\n }));\n\n return outcome;\n } catch (error) {\n pwaLogger.error('[PWA Install] Error showing install prompt:', error);\n return null;\n }\n };\n\n return {\n ...state,\n promptInstall,\n // Expose full browser info\n browser,\n device,\n };\n}\n","'use client';\n\n/**\n * PWA Install Context\n *\n * Minimal global state for PWA installation\n * No tracking, no metrics, no engagement — just install state\n */\n\nimport React, { createContext, ReactNode, useContext } from 'react';\n\nimport { useInstallPrompt } from '../hooks/useInstallPrompt';\n\nimport type { InstallOutcome } from '../types';\nexport interface PwaContextValue {\n // Platform\n isIOS: boolean;\n isAndroid: boolean;\n isDesktop: boolean;\n\n // Browsers\n isSafari: boolean;\n isChrome: boolean;\n isFirefox: boolean;\n isEdge: boolean;\n isOpera: boolean;\n isBrave: boolean;\n isArc: boolean;\n isVivaldi: boolean;\n isYandex: boolean;\n isSamsungBrowser: boolean;\n isUCBrowser: boolean;\n isChromium: boolean; // Any Chromium-based browser\n browserName: string;\n\n // State\n isInstalled: boolean;\n canPrompt: boolean;\n\n // Actions\n install: () => Promise<InstallOutcome>;\n}\n\nconst PwaContext = createContext<PwaContextValue | undefined>(undefined);\n\nexport interface PwaConfig {\n enabled?: boolean;\n}\n\nexport function PwaProvider({ children, ...config }: PwaConfig & { children: ReactNode }) {\n // If not enabled, acts as a simple pass-through\n if (config.enabled === false) {\n return <>{children}</>;\n }\n\n const prompt = useInstallPrompt();\n\n const value: PwaContextValue = {\n // Platform\n isIOS: prompt.isIOS,\n isAndroid: prompt.isAndroid,\n isDesktop: !prompt.isIOS && !prompt.isAndroid,\n\n // Browsers (from useBrowserDetect)\n isSafari: prompt.browser.isSafari && !prompt.browser.isChromium, // Real Safari only\n isChrome: prompt.browser.isChrome,\n isFirefox: prompt.browser.isFirefox,\n isEdge: prompt.browser.isEdge,\n isOpera: prompt.browser.isOpera,\n isBrave: prompt.browser.isBrave,\n isArc: prompt.browser.isArc,\n isVivaldi: prompt.browser.isVivaldi,\n isYandex: prompt.browser.isYandex,\n isSamsungBrowser: prompt.browser.isSamsungBrowser,\n isUCBrowser: prompt.browser.isUCBrowser,\n isChromium: prompt.browser.isChromium,\n browserName: prompt.browser.browserName,\n\n // State\n isInstalled: prompt.isInstalled,\n canPrompt: prompt.canPrompt,\n\n // Actions\n install: prompt.promptInstall,\n };\n\n return <PwaContext.Provider value={value}>{children}</PwaContext.Provider>;\n}\n\n/**\n * Use install context\n * Must be used within <PwaProvider>\n */\nexport function useInstall(): PwaContextValue {\n const context = useContext(PwaContext);\n\n if (context === undefined) {\n throw new Error('useInstall must be used within <PwaProvider>');\n }\n\n return context;\n}\n","'use client';\n\n/**\n * Desktop Installation Guide Modal\n *\n * Visual step-by-step guide for installing PWA on desktop browsers\n * Uses platform detection from InstallContext\n * Supports: Chrome, Edge, Brave, Arc, Vivaldi, Opera, Yandex, Firefox, Safari\n */\n\nimport { ArrowDownToLine, Check, Menu, Monitor, Plus, Search } from 'lucide-react';\nimport React, { useMemo } from 'react';\n\nimport {\n Button, Card, CardContent, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader,\n DialogTitle\n} from '@djangocfg/ui-nextjs';\n\nimport { useInstall } from '../context/InstallContext';\n\nimport type { IOSGuideModalProps, InstallStep } from '../types';\ntype BrowserCategory = 'chromium' | 'firefox' | 'safari' | 'unknown';\n\nfunction getBrowserCategory(browser: {\n isChromium: boolean;\n isFirefox: boolean;\n isSafari: boolean;\n}): BrowserCategory {\n if (browser.isChromium) return 'chromium';\n if (browser.isFirefox) return 'firefox';\n if (browser.isSafari) return 'safari';\n return 'unknown';\n}\n\nfunction getBrowserSteps(category: BrowserCategory, browserName: string): InstallStep[] {\n switch (category) {\n case 'chromium':\n // Chrome, Edge, Brave, Arc, Vivaldi, Opera, Yandex, etc.\n return [\n {\n number: 1,\n title: 'Find Install Icon',\n icon: ArrowDownToLine,\n description: 'Look for install icon in address bar (right side)',\n },\n {\n number: 2,\n title: 'Click Install',\n icon: Plus,\n description: 'Click the icon and select \"Install\"',\n },\n {\n number: 3,\n title: 'Confirm',\n icon: Check,\n description: 'Click \"Install\" in the popup dialog',\n },\n ];\n\n case 'firefox':\n return [\n {\n number: 1,\n title: 'Open Menu',\n icon: Menu,\n description: 'Click the menu button (three lines)',\n },\n {\n number: 2,\n title: 'Find Install Option',\n icon: Search,\n description: 'Look for \"Install\" or \"Add to Home Screen\"',\n },\n {\n number: 3,\n title: 'Confirm',\n icon: Check,\n description: 'Follow the installation prompts',\n },\n ];\n\n case 'safari':\n return [\n {\n number: 1,\n title: 'Limited Support',\n icon: Monitor,\n description: 'Safari on macOS has limited PWA support',\n },\n {\n number: 2,\n title: 'Use Chromium Browser',\n icon: ArrowDownToLine,\n description: 'Consider using Chrome, Edge, or Brave for full PWA experience',\n },\n ];\n\n default:\n return [\n {\n number: 1,\n title: 'Check Address Bar',\n icon: ArrowDownToLine,\n description: 'Look for an install or download icon',\n },\n {\n number: 2,\n title: 'Or Use Menu',\n icon: Menu,\n description: 'Check browser menu for install option',\n },\n {\n number: 3,\n title: 'Confirm',\n icon: Check,\n description: 'Follow the installation prompts',\n },\n ];\n }\n}\n\nfunction StepCard({ step }: { step: InstallStep }) {\n return (\n <Card className=\"border border-border\">\n <CardContent className=\"p-4\">\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex items-center justify-center rounded-full bg-primary text-primary-foreground flex-shrink-0\"\n style={{ width: '32px', height: '32px' }}\n >\n <span className=\"text-sm font-semibold\">{step.number}</span>\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <step.icon className=\"w-5 h-5 text-primary\" />\n <h3 className=\"font-semibold text-foreground\">{step.title}</h3>\n </div>\n <p className=\"text-sm text-muted-foreground\">{step.description}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport function DesktopGuide({ onDismiss, open = true }: IOSGuideModalProps) {\n const {\n browserName,\n isChromium,\n isFirefox,\n isSafari,\n isEdge,\n isBrave,\n isArc,\n isVivaldi,\n isOpera,\n isYandex,\n } = useInstall();\n\n const category = useMemo(\n () => getBrowserCategory({ isChromium, isFirefox, isSafari }),\n [isChromium, isFirefox, isSafari]\n );\n\n const steps = useMemo(() => getBrowserSteps(category, browserName), [category, browserName]);\n\n // Get specific browser display name with emoji\n const displayName = useMemo(() => {\n if (isEdge) return 'Edge';\n if (isBrave) return 'Brave';\n if (isArc) return 'Arc';\n if (isVivaldi) return 'Vivaldi';\n if (isOpera) return 'Opera';\n if (isYandex) return 'Yandex Browser';\n return browserName;\n }, [browserName, isEdge, isBrave, isArc, isVivaldi, isOpera, isYandex]);\n\n return (\n <Dialog open={open} onOpenChange={(isOpen) => !isOpen && onDismiss()}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader className=\"text-left\">\n <DialogTitle className=\"flex items-center gap-2\">\n <Monitor className=\"w-5 h-5 text-primary\" />\n Install App on Desktop\n </DialogTitle>\n <DialogDescription className=\"text-left\">\n {isSafari\n ? 'Safari on macOS has limited PWA support. For the best experience, use Chrome, Edge, or Brave.'\n : `Install this app on ${displayName} for quick access from your desktop`\n }\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-3 py-4\">\n {steps.map((step) => (\n <StepCard key={step.number} step={step} />\n ))}\n </div>\n\n {category === 'chromium' && (\n <div className=\"p-3 bg-muted/30 rounded-lg text-xs text-muted-foreground\">\n 💡 Tip: You can also right-click the page and look for \"Install\" option in {displayName}\n </div>\n )}\n\n {category === 'firefox' && (\n <div className=\"p-3 bg-amber-500/10 rounded-lg text-xs text-amber-700 dark:text-amber-400\">\n ℹ️ Note: Firefox has limited PWA support. Some features may not work as expected.\n </div>\n )}\n\n <DialogFooter>\n <Button onClick={onDismiss} variant=\"default\" className=\"w-full\">\n <Check className=\"w-4 h-4 mr-2\" />\n Got It\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","'use client';\n\n/**\n * iOS Installation Guide Drawer (Mobile-Optimized)\n *\n * Bottom drawer with swipe gestures for iOS installation guide\n * Better UX for mobile devices\n */\n\nimport { ArrowDown, ArrowUpRight, Check, CheckCircle, Share } from 'lucide-react';\nimport React from 'react';\n\nimport {\n Button, Card, CardContent, Drawer, DrawerContent, DrawerDescription, DrawerHeader, DrawerTitle\n} from '@djangocfg/ui-nextjs';\n\nimport type { IOSGuideModalProps, InstallStep } from '../types';\n\nconst steps: InstallStep[] = [\n {\n number: 1,\n title: 'Tap Share',\n icon: ArrowUpRight,\n description: 'At the bottom of Safari',\n },\n {\n number: 2,\n title: 'Scroll & Tap',\n icon: ArrowDown,\n description: '\"Add to Home Screen\"',\n },\n {\n number: 3,\n title: 'Confirm',\n icon: CheckCircle,\n description: 'Tap \"Add\" in top-right',\n },\n];\n\nfunction StepCard({ step }: { step: InstallStep }) {\n return (\n <Card className=\"border border-border\">\n <CardContent className=\"p-4\">\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex items-center justify-center rounded-full bg-primary text-primary-foreground flex-shrink-0\"\n style={{ width: '32px', height: '32px' }}\n >\n <span className=\"text-sm font-semibold\">{step.number}</span>\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <step.icon className=\"w-5 h-5 text-primary\" />\n <h3 className=\"font-semibold text-foreground\">{step.title}</h3>\n </div>\n <p className=\"text-sm text-muted-foreground\">{step.description}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport function IOSGuideDrawer({ onDismiss, open = true }: IOSGuideModalProps) {\n return (\n <Drawer open={open} onOpenChange={(isOpen) => !isOpen && onDismiss()}>\n <DrawerContent>\n <DrawerHeader className=\"text-left\">\n <DrawerTitle className=\"flex items-center gap-2\">\n <Share className=\"w-5 h-5 text-primary\" />\n Add to Home Screen\n </DrawerTitle>\n <DrawerDescription className=\"text-left\">\n Install this app on your iPhone for quick access and a better experience\n </DrawerDescription>\n </DrawerHeader>\n\n <div className=\"space-y-3 p-4\">\n {steps.map((step) => (\n <StepCard key={step.number} step={step} />\n ))}\n </div>\n\n <div className=\"p-4 pt-0\">\n <Button onClick={onDismiss} variant=\"default\" className=\"w-full\">\n <Check className=\"w-4 h-4 mr-2\" />\n Got It\n </Button>\n </div>\n </DrawerContent>\n </Drawer>\n );\n}\n","'use client';\n\n/**\n * iOS Installation Guide Modal\n *\n * Visual step-by-step guide for adding PWA to home screen on iOS Safari\n */\n\nimport { ArrowDown, ArrowUpRight, Check, CheckCircle, Share } from 'lucide-react';\nimport React from 'react';\n\nimport {\n Button, Card, CardContent, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader,\n DialogTitle\n} from '@djangocfg/ui-nextjs';\n\nimport type { IOSGuideModalProps, InstallStep } from '../types';\n\nconst steps: InstallStep[] = [\n {\n number: 1,\n title: 'Tap Share',\n icon: ArrowUpRight,\n description: 'At the bottom of Safari',\n },\n {\n number: 2,\n title: 'Scroll & Tap',\n icon: ArrowDown,\n description: '\"Add to Home Screen\"',\n },\n {\n number: 3,\n title: 'Confirm',\n icon: CheckCircle,\n description: 'Tap \"Add\" in top-right',\n },\n];\n\nfunction StepCard({ step }: { step: InstallStep }) {\n return (\n <Card className=\"border border-border\">\n <CardContent className=\"p-4\">\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex items-center justify-center rounded-full bg-primary text-primary-foreground flex-shrink-0\"\n style={{ width: '32px', height: '32px' }}\n >\n <span className=\"text-sm font-semibold\">{step.number}</span>\n </div>\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <step.icon className=\"w-5 h-5 text-primary\" />\n <h3 className=\"font-semibold text-foreground\">{step.title}</h3>\n </div>\n <p className=\"text-sm text-muted-foreground\">{step.description}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport function IOSGuideModal({ onDismiss, open = true }: IOSGuideModalProps) {\n return (\n <Dialog open={open} onOpenChange={(isOpen) => !isOpen && onDismiss()}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader className=\"text-left\">\n <DialogTitle className=\"flex items-center gap-2\">\n <Share className=\"w-5 h-5 text-primary\" />\n Add to Home Screen\n </DialogTitle>\n <DialogDescription className=\"text-left\">\n Install this app on your iPhone for quick access and a better experience\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-3 py-4\">\n {steps.map((step) => (\n <StepCard key={step.number} step={step} />\n ))}\n </div>\n\n <DialogFooter>\n <Button onClick={onDismiss} variant=\"default\" className=\"w-full\">\n <Check className=\"w-4 h-4 mr-2\" />\n Got It\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","'use client';\n\n/**\n * iOS Installation Guide (Adaptive)\n *\n * Automatically uses:\n * - Drawer on mobile (better swipe UX)\n * - Dialog on desktop/tablet\n */\n\nimport React from 'react';\n\nimport { useIsMobile } from '@djangocfg/ui-nextjs/hooks';\n\nimport { IOSGuideDrawer } from './IOSGuideDrawer';\nimport { IOSGuideModal } from './IOSGuideModal';\n\nimport type { IOSGuideModalProps } from '../types';\n\nexport function IOSGuide(props: IOSGuideModalProps) {\n const isMobile = useIsMobile(); // Viewport < 768px\n\n // Use drawer on mobile, dialog on desktop\n if (isMobile) {\n return <IOSGuideDrawer {...props} />;\n }\n\n return <IOSGuideModal {...props} />;\n}\n","'use client';\n\n/**\n * PWA Install Hint (Unified for iOS & Android)\n *\n * Inline, non-blocking hint that shows at the bottom of the screen\n * - iOS Safari: Opens visual guide on click\n * - Android Chrome: Triggers native install prompt on click\n * - Unified UX: Same position, same style, same behavior\n *\n * Auto-resets after 3 days (configurable)\n */\n\nimport { ChevronRight, Download, Share, X } from 'lucide-react';\nimport React, { useEffect, useState } from 'react';\n\nimport { Button } from '@djangocfg/ui-nextjs';\nimport { cn } from '@djangocfg/ui-core/lib';\n\nimport { useInstall } from '../context/InstallContext';\nimport { isA2HSDismissedRecently, markA2HSDismissed } from '../utils/localStorage';\nimport { pwaLogger } from '../utils/logger';\nimport { DesktopGuide } from './DesktopGuide';\nimport { IOSGuide } from './IOSGuide';\n\nconst DEFAULT_RESET_DAYS = 3;\n\ninterface A2HSHintProps {\n /**\n * Additional class names for the container\n */\n className?: string;\n\n /**\n * Number of days before re-showing dismissed hint\n * @default 3\n * Set to null to never reset (show once forever)\n */\n resetAfterDays?: number | null;\n\n /**\n * Delay before showing hint (ms)\n * @default 3000\n */\n delayMs?: number;\n\n /**\n * Demo mode - shows hint on all platforms with appropriate guides\n * Production: only iOS Safari & Android Chrome\n * Demo: shows on desktop too with desktop install guide\n * @default false\n */\n demo?: boolean;\n\n /**\n * App logo URL to display in hint\n * If not provided, uses Share icon\n */\n logo?: string;\n}\n\nexport function A2HSHint({\n className,\n resetAfterDays = DEFAULT_RESET_DAYS,\n delayMs = 3000,\n demo = false,\n logo,\n}: A2HSHintProps = {}) {\n const { isIOS, isDesktop, isInstalled, canPrompt, install } = useInstall();\n const [show, setShow] = useState(false);\n const [showGuide, setShowGuide] = useState(false);\n const [installing, setInstalling] = useState(false);\n\n // Determine if should show hint\n // Production: iOS (all browsers support PWA via Share) & Android Chrome with native prompt\n // Demo: show on all platforms (desktop, iOS, Android)\n const shouldShow = demo\n ? !isInstalled // Demo: show on all platforms if not installed\n : !isInstalled && (isIOS || canPrompt); // Production: iOS (all browsers) or Android with prompt\n\n useEffect(() => {\n if (!shouldShow) return;\n\n // Check if previously dismissed (skip localStorage check in demo mode)\n if (!demo && typeof window !== 'undefined') {\n // If resetAfterDays is null, never reset (check with very large number)\n if (resetAfterDays === null) {\n if (isA2HSDismissedRecently(Number.MAX_SAFE_INTEGER)) {\n return; // Dismissed forever\n }\n } else if (isA2HSDismissedRecently(resetAfterDays)) {\n return; // Still within reset period\n }\n }\n\n // Show after delay (user is already engaged)\n const timer = setTimeout(() => setShow(true), delayMs);\n return () => clearTimeout(timer);\n }, [shouldShow, resetAfterDays, delayMs, demo]);\n\n const handleDismiss = () => {\n setShow(false);\n // Don't save to localStorage if demo mode (dev testing)\n if (!demo) {\n markA2HSDismissed();\n }\n };\n\n const handleGuideDismiss = () => {\n setShowGuide(false);\n // In demo mode, keep hint visible after guide is dismissed\n // In production mode, dismiss both guide and hint\n if (!demo) {\n handleDismiss();\n }\n };\n\n const handleClick = async () => {\n // iOS (all browsers support PWA via Share menu)\n // iOS or Desktop: Open visual guide\n if (isIOS || isDesktop) {\n setShowGuide(true);\n } else if (canPrompt) {\n // Android: Trigger native install prompt\n setInstalling(true);\n try {\n await install();\n // If install succeeds, dismiss hint\n handleDismiss();\n } catch (error) {\n pwaLogger.error('[A2HSHint] Install error:', error);\n } finally {\n setInstalling(false);\n }\n }\n };\n\n if (!show) return null;\n\n // Determine which guide/action to show\n let title: string;\n let subtitle: React.ReactNode;\n\n if (isIOS) {\n title = 'Add to Home Screen';\n subtitle = <>Tap to learn how <ChevronRight className=\"w-3 h-3\" /></>;\n } else if (isDesktop) {\n title = 'Install App';\n subtitle = <>Click to see desktop guide <ChevronRight className=\"w-3 h-3\" /></>;\n } else {\n // Android or other mobile with native prompt\n title = 'Install App';\n subtitle = <>Tap to install <Download className=\"w-3 h-3\" /></>;\n }\n\n return (\n <>\n <div className={cn(\n \"fixed bottom-4 left-4 right-4 z-50 animate-in slide-in-from-bottom-4 duration-300\",\n demo && \"relative inset-auto z-auto\", // Demo mode: remove fixed positioning\n className\n )}>\n {/* Make entire card clickable */}\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleClick();\n }\n }}\n className={cn(\n \"w-full bg-zinc-900 border border-zinc-700 rounded-lg p-4 shadow-lg cursor-pointer hover:bg-zinc-800 transition-colors\",\n installing && \"opacity-70 cursor-not-allowed\"\n )}\n aria-disabled={installing}\n >\n <div className=\"flex items-center gap-3\">\n {/* App logo or icon */}\n <div className=\"flex-shrink-0\">\n {logo ? (\n <img src={logo} alt=\"App logo\" className=\"w-10 h-10 rounded-lg\" />\n ) : (\n <Share className=\"w-5 h-5 text-blue-400\" />\n )}\n </div>\n\n {/* Content - now just displays, clicking anywhere triggers action */}\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-white mb-1\">{title}</p>\n <p className=\"text-xs text-zinc-400 flex items-center gap-1\">\n {installing ? 'Installing...' : subtitle}\n </p>\n </div>\n\n {/* Close button - prevent event bubbling */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss();\n }}\n className=\"flex-shrink-0 p-1 hover:bg-zinc-700 rounded transition-colors\"\n aria-label=\"Dismiss\"\n >\n <X className=\"w-4 h-4 text-zinc-400\" />\n </button>\n </div>\n </div>\n </div>\n\n {/* Show appropriate guide based on platform */}\n {isIOS && (\n <IOSGuide open={showGuide} onDismiss={handleGuideDismiss} />\n )}\n\n {/* Desktop guide */}\n {isDesktop && (\n <DesktopGuide open={showGuide} onDismiss={handleGuideDismiss} />\n )}\n </>\n );\n}\n","'use client';\n\n/**\n * Hook to detect if app is running as PWA\n *\n * Checks if the app is running in standalone mode (added to home screen).\n * Results are cached in sessionStorage for fast initialization across page loads.\n *\n * @example\n * ```typescript\n * // Basic usage (standard check)\n * const isPWA = useIsPWA();\n *\n * // Reliable check (with manifest validation for desktop)\n * const isPWA = useIsPWA({ reliable: true });\n * ```\n */\n\nimport { useEffect, useState } from 'react';\n\nimport { isStandalone, isStandaloneReliable, onDisplayModeChange } from '../utils/platform';\n\nconst CACHE_KEY = 'pwa_is_standalone';\n\n/**\n * Options for useIsPWA hook\n */\nexport interface UseIsPWAOptions {\n /**\n * Use reliable check with additional validation for desktop browsers\n * This prevents false positives on Safari macOS \"Add to Dock\"\n * @default false\n */\n reliable?: boolean;\n}\n\n/**\n * Hook to detect if app is running as PWA (standalone mode)\n *\n * @param options - Configuration options\n * @returns true if app is running as PWA\n */\nexport function useIsPWA(options?: UseIsPWAOptions): boolean {\n const checkFunction = options?.reliable ? isStandaloneReliable : isStandalone;\n\n const [isPWA, setIsPWA] = useState<boolean>(() => {\n // Try to restore from cache for fast initialization\n if (typeof window !== 'undefined') {\n try {\n const cached = sessionStorage.getItem(CACHE_KEY);\n if (cached !== null) {\n return cached === 'true';\n }\n } catch {\n // Ignore sessionStorage errors (e.g., in incognito mode)\n }\n }\n\n // Initial check\n return checkFunction();\n });\n\n useEffect(() => {\n // Check after mount (may differ from SSR)\n const isStandaloneMode = checkFunction();\n setIsPWA(isStandaloneMode);\n\n // Update cache\n if (typeof window !== 'undefined') {\n try {\n sessionStorage.setItem(CACHE_KEY, String(isStandaloneMode));\n } catch {\n // Ignore sessionStorage errors\n }\n }\n\n // Listen for display-mode changes\n const cleanup = onDisplayModeChange((newValue) => {\n setIsPWA(newValue);\n\n // Update cache\n if (typeof window !== 'undefined') {\n try {\n sessionStorage.setItem(CACHE_KEY, String(newValue));\n } catch {\n // Ignore sessionStorage errors\n }\n }\n });\n\n return cleanup;\n }, [checkFunction]);\n\n return isPWA;\n}\n\n/**\n * Clear isPWA cache\n *\n * Useful for testing or when you want to force a re-check\n *\n * @example\n * ```typescript\n * import { clearIsPWACache } from '@djangocfg/layouts/snippets';\n * clearIsPWACache();\n * window.location.reload();\n * ```\n */\nexport function clearIsPWACache(): void {\n if (typeof window === 'undefined') return;\n try {\n sessionStorage.removeItem(CACHE_KEY);\n } catch {\n // Ignore sessionStorage errors\n }\n}\n","/**\n * PWA Logger with Conditional Logging\n *\n * Provides logging utilities that respect environment and debug settings:\n * - In production: Only errors are logged\n * - In development: All levels are logged\n * - Debug mode: Can be enabled in production via localStorage\n *\n * @example\n * ```typescript\n * import { pwaLogger } from '../utils/logger';\n *\n * pwaLogger.info('Info message'); // Only in dev\n * pwaLogger.warn('Warning message'); // Only in dev\n * pwaLogger.error('Error message'); // Always logged\n * pwaLogger.debug('Debug message'); // Only when debug enabled\n * ```\n *\n * Enable debug mode in production:\n * ```typescript\n * import { enablePWADebug } from '../utils/logger';\n * enablePWADebug();\n * // or in console:\n * localStorage.setItem('pwa_debug', 'true');\n * ```\n */\n\nimport { consola } from 'consola';\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\n/**\n * Check if debug mode is enabled via localStorage\n */\nfunction isDebugEnabled(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return localStorage.getItem('pwa_debug') === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * PWA Logger instance with conditional logging\n */\nexport const pwaLogger = {\n /**\n * Info level logging\n * Only logs in development or when debug is enabled\n */\n info: (...args: Parameters<typeof consola.info>): void => {\n if (isDevelopment || isDebugEnabled()) {\n consola.info(...args);\n }\n },\n\n /**\n * Warning level logging\n * Only logs in development or when debug is enabled\n */\n warn: (...args: Parameters<typeof consola.warn>): void => {\n if (isDevelopment || isDebugEnabled()) {\n consola.warn(...args);\n }\n },\n\n /**\n * Error level logging\n * Always logs (production + development)\n */\n error: (...args: Parameters<typeof consola.error>): void => {\n consola.error(...args);\n },\n\n /**\n * Debug level logging\n * Only logs when debug is explicitly enabled\n */\n debug: (...args: Parameters<typeof consola.debug>): void => {\n if (isDebugEnabled()) {\n consola.debug(...args);\n }\n },\n\n /**\n * Success level logging\n * Only logs in development or when debug is enabled\n */\n success: (...args: Parameters<typeof consola.success>): void => {\n if (isDevelopment || isDebugEnabled()) {\n consola.success(...args);\n }\n },\n};\n\n/**\n * Enable debug mode\n *\n * This allows seeing debug logs in production.\n * Call this function or set localStorage manually:\n * `localStorage.setItem('pwa_debug', 'true')`\n *\n * @example\n * ```typescript\n * import { enablePWADebug } from '@djangocfg/layouts/snippets';\n * enablePWADebug();\n * // Reload page to see debug logs\n * ```\n */\nexport function enablePWADebug(): void {\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem('pwa_debug', 'true');\n consola.info('[PWA] Debug mode enabled. Reload page to see debug logs.');\n } catch (e) {\n consola.error('[PWA] Failed to enable debug mode:', e);\n }\n }\n}\n\n/**\n * Disable debug mode\n *\n * @example\n * ```typescript\n * import { disablePWADebug } from '@djangocfg/layouts/snippets';\n * disablePWADebug();\n * ```\n */\nexport function disablePWADebug(): void {\n if (typeof window !== 'undefined') {\n try {\n localStorage.removeItem('pwa_debug');\n consola.info('[PWA] Debug mode disabled.');\n } catch (e) {\n consola.error('[PWA] Failed to disable debug mode:', e);\n }\n }\n}\n\n/**\n * Check if debug mode is currently active\n *\n * @returns true if debug mode is enabled\n */\nexport function isPWADebugEnabled(): boolean {\n return isDebugEnabled();\n}\n","/**\n * Platform Detection Utilities\n *\n * Centralized utilities for detecting PWA state, platform, and capabilities.\n * Used by hooks to avoid code duplication.\n */\n\n// ============================================================================\n// Browser Push Support Detection\n// ============================================================================\n\n/**\n * List of browsers/contexts known to NOT support Web Push Notifications\n */\nexport interface BrowserPushSupport {\n isSupported: boolean;\n browserName: string;\n reason?: string;\n}\n\n/**\n * Check if the current browser supports Web Push Notifications\n *\n * This checks for browsers that are known to NOT support push notifications:\n * - Opera Mini (no service worker support)\n * - Internet Explorer (deprecated, no Push API)\n * - UC Browser (unreliable push support)\n * - In-App browsers (Facebook, Instagram, TikTok, Snapchat, WeChat, etc.)\n * - Generic WebViews\n *\n * Note: Comet (Perplexity) is Chromium-based and DOES support push notifications.\n *\n * @returns Object with isSupported flag, browserName, and optional reason\n *\n * @example\n * ```typescript\n * const { isSupported, browserName, reason } = checkBrowserPushSupport();\n * if (!isSupported) {\n * console.log(`Push not supported in ${browserName}: ${reason}`);\n * }\n * ```\n */\nexport function checkBrowserPushSupport(): BrowserPushSupport {\n if (typeof window === 'undefined') {\n return { isSupported: false, browserName: 'unknown', reason: 'Server-side rendering' };\n }\n\n const ua = window.navigator.userAgent.toLowerCase();\n\n // ============================================================================\n // In-App Browsers (WebViews) - typically do NOT support push\n // ============================================================================\n\n // Facebook In-App Browser\n if (ua.includes('fban') || ua.includes('fbav') || ua.includes('fb_iab')) {\n return { isSupported: false, browserName: 'Facebook In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Instagram In-App Browser\n if (ua.includes('instagram')) {\n return { isSupported: false, browserName: 'Instagram In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // TikTok In-App Browser\n if (ua.includes('tiktok') || ua.includes('bytedancewebview') || ua.includes('bytelocale')) {\n return { isSupported: false, browserName: 'TikTok In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Snapchat In-App Browser\n if (ua.includes('snapchat')) {\n return { isSupported: false, browserName: 'Snapchat In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // WeChat In-App Browser\n if (ua.includes('micromessenger')) {\n return { isSupported: false, browserName: 'WeChat In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Threads In-App Browser (Meta's app - codename Barcelona)\n if (ua.includes('barcelona')) {\n return { isSupported: false, browserName: 'Threads In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Pinterest In-App Browser\n if (ua.includes('pinterest')) {\n return { isSupported: false, browserName: 'Pinterest In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Telegram In-App Browser\n if (ua.includes('telegram')) {\n return { isSupported: false, browserName: 'Telegram In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Line In-App Browser\n if (ua.includes('line/')) {\n return { isSupported: false, browserName: 'Line In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // KakaoTalk In-App Browser\n if (ua.includes('kakaotalk')) {\n return { isSupported: false, browserName: 'KakaoTalk In-App', reason: 'In-app browsers do not support push notifications' };\n }\n\n // Note: Twitter and LinkedIn In-App on Android use Chrome WebView and DO support push\n // We don't block them here\n const isIOSDevice = ua.includes('iphone') || ua.includes('ipad') || ua.includes('ipod');\n\n // LinkedIn In-App on iOS - no push\n if (ua.includes('linkedinapp') && isIOSDevice) {\n return { isSupported: false, browserName: 'LinkedIn In-App', reason: 'LinkedIn In-App on iOS does not support push notifications' };\n }\n\n // Twitter In-App on iOS - no push\n if (ua.includes('twitter') && isIOSDevice) {\n return { isSupported: false, browserName: 'Twitter In-App', reason: 'Twitter In-App on iOS does not support push notifications' };\n }\n\n // ============================================================================\n // Browsers without Push Support\n // ============================================================================\n\n // Note: Comet Browser (Perplexity) is Chromium-based and DOES support push\n\n // Opera Mini\n if (ua.includes('opera mini') || ua.includes('opios')) {\n return { isSupported: false, browserName: 'Opera Mini', reason: 'Opera Mini does not support service workers' };\n }\n\n // Internet Explorer\n if (ua.includes('msie') || ua.includes('trident/')) {\n return { isSupported: false, browserName: 'Internet Explorer', reason: 'Internet Explorer does not support Push API' };\n }\n\n // UC Browser (unreliable support)\n if (ua.includes('ucbrowser') || ua.includes('uc browser')) {\n return { isSupported: false, browserName: 'UC Browser', reason: 'UC Browser has unreliable push notification support' };\n }\n\n // ============================================================================\n // Generic WebView Detection\n // ============================================================================\n\n const isWebView = ua.includes('wv)') ||\n ua.includes('webview') ||\n ua.includes('; wv') ||\n (ua.includes('iphone') && !ua.includes('safari')) ||\n (ua.includes('ipad') && !ua.includes('safari'));\n\n if (isWebView) {\n return { isSupported: false, browserName: 'WebView', reason: 'WebViews do not support push notifications' };\n }\n\n // ============================================================================\n // Determine Browser Name for supported browsers\n // ============================================================================\n\n let browserName = 'unknown';\n\n if (ua.includes('comet') || ua.includes('perplexity')) browserName = 'Comet';\n else if (ua.includes('edg/') || ua.includes('edge/')) browserName = 'Edge';\n else if ((window.navigator as any).brave) browserName = 'Brave';\n else if (ua.includes('arc/')) browserName = 'Arc';\n else if (ua.includes('vivaldi')) browserName = 'Vivaldi';\n else if (ua.includes('yabrowser')) browserName = 'Yandex';\n else if (ua.includes('samsungbrowser')) browserName = 'Samsung Internet';\n else if (ua.includes('opr/') || ua.includes('opera')) browserName = 'Opera';\n else if (ua.includes('firefox')) browserName = 'Firefox';\n else if (ua.includes('chrome')) browserName = 'Chrome';\n else if (ua.includes('safari') && ua.includes('version/')) browserName = 'Safari';\n\n return { isSupported: true, browserName };\n}\n\n/**\n * Quick check if push notifications are supported by the browser\n *\n * @returns true if browser supports push notifications\n */\nexport function isBrowserPushSupported(): boolean {\n return checkBrowserPushSupport().isSupported;\n}\n\n/**\n * Check if running as PWA (standalone mode)\n *\n * Checks if the app is running in standalone mode (added to home screen).\n * This is the primary indicator that a PWA has been installed.\n *\n * @returns true if app is running in standalone mode\n *\n * @example\n * ```typescript\n * if (isStandalone()) {\n * console.log('Running as PWA');\n * }\n * ```\n */\nexport function isStandalone(): boolean {\n if (typeof window === 'undefined') return false;\n\n // Fallback for older browsers without matchMedia\n if (!window.matchMedia) {\n // Use legacy iOS check only\n const nav = navigator as Navigator & { standalone?: boolean };\n return nav.standalone === true;\n }\n\n // Check display-mode media query (modern approach)\n const isStandaloneDisplay = window.matchMedia('(display-mode: standalone)').matches;\n\n // Legacy iOS check (navigator.standalone)\n const nav = navigator as Navigator & { standalone?: boolean };\n const isStandaloneNavigator = nav.standalone === true;\n\n return isStandaloneDisplay || isStandaloneNavigator;\n}\n\n/**\n * Check if device is mobile\n *\n * @returns true if device is mobile (iOS, Android, etc.)\n */\nexport function isMobileDevice(): boolean {\n if (typeof window === 'undefined') return false;\n return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\n}\n\n/**\n * Check if web app manifest exists and is valid\n *\n * @returns true if manifest link exists in document head\n */\nexport function hasValidManifest(): boolean {\n if (typeof document === 'undefined') return false;\n const manifestLink = document.querySelector('link[rel=\"manifest\"]');\n return !!manifestLink;\n}\n\n/**\n * Reliable check for PWA mode with edge case handling\n *\n * This function provides additional validation for desktop browsers\n * to avoid false positives (e.g., Safari macOS \"Add to Dock\").\n *\n * For mobile devices, standard standalone check is sufficient.\n * For desktop, additionally validates that a manifest exists.\n *\n * @returns true if app is running as a genuine PWA\n *\n * @example\n * ```typescript\n * // Use this for more reliable detection\n * if (isStandaloneReliable()) {\n * console.log('Definitely running as PWA');\n * }\n * ```\n */\nexport function isStandaloneReliable(): boolean {\n const standalone = isStandalone();\n if (!standalone) return false;\n\n // For mobile devices, standalone check is sufficient\n if (isMobileDevice()) return true;\n\n // For desktop browsers, additionally check for valid manifest\n // This prevents false positives like Safari macOS \"Add to Dock\"\n return hasValidManifest();\n}\n\n/**\n * Get display mode from media query\n *\n * @returns Current display mode: 'standalone', 'fullscreen', 'minimal-ui', or 'browser'\n */\nexport function getDisplayMode(): 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser' {\n if (typeof window === 'undefined') return 'browser';\n\n if (!window.matchMedia) return 'browser';\n\n const modes: Array<'standalone' | 'fullscreen' | 'minimal-ui'> = [\n 'fullscreen',\n 'standalone',\n 'minimal-ui',\n ];\n\n for (const mode of modes) {\n if (window.matchMedia(`(display-mode: ${mode})`).matches) {\n return mode;\n }\n }\n\n return 'browser';\n}\n\n/**\n * Create a media query listener for display-mode changes\n *\n * @param callback - Function to call when display mode changes\n * @returns Cleanup function to remove listener\n *\n * @example\n * ```typescript\n * const cleanup = onDisplayModeChange((isStandalone) => {\n * console.log('Display mode changed:', isStandalone);\n * });\n *\n * // Later: cleanup();\n * ```\n */\nexport function onDisplayModeChange(callback: (isStandalone: boolean) => void): () => void {\n if (typeof window === 'undefined' || !window.matchMedia) {\n return () => {}; // No-op cleanup\n }\n\n const mediaQuery = window.matchMedia('(display-mode: standalone)');\n\n const handleChange = (e: MediaQueryListEvent) => {\n callback(e.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleChange);\n };\n}\n","/**\n * VAPID Key Utilities\n *\n * Provides validation and conversion utilities for VAPID public keys\n * used in push notification subscriptions.\n *\n * VAPID keys must be:\n * - Base64url encoded\n * - 65 bytes after decoding (P-256 uncompressed public key)\n * - Start with 0x04 (uncompressed point indicator)\n */\n\n/**\n * Custom error class for VAPID key validation failures\n */\nexport class VapidKeyError extends Error {\n constructor(\n message: string,\n public readonly code: VapidKeyErrorCode\n ) {\n super(message);\n this.name = 'VapidKeyError';\n }\n}\n\n/**\n * Error codes for VAPID key validation\n */\nexport type VapidKeyErrorCode =\n | 'VAPID_EMPTY'\n | 'VAPID_INVALID_TYPE'\n | 'VAPID_INVALID_BASE64'\n | 'VAPID_INVALID_LENGTH'\n | 'VAPID_INVALID_FORMAT';\n\n/**\n * Convert base64url VAPID public key to Uint8Array\n *\n * Validates and converts a VAPID public key from base64url format\n * to Uint8Array for use with PushManager.subscribe().\n *\n * @param base64String - VAPID public key in base64url format\n * @returns Uint8Array ready for pushManager.subscribe()\n * @throws VapidKeyError if key is invalid\n *\n * @example\n * ```typescript\n * try {\n * const key = urlBase64ToUint8Array(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY);\n * await registration.pushManager.subscribe({\n * userVisibleOnly: true,\n * applicationServerKey: key,\n * });\n * } catch (e) {\n * if (e instanceof VapidKeyError) {\n * console.error('Invalid VAPID key:', e.message, e.code);\n * }\n * }\n * ```\n */\nexport function urlBase64ToUint8Array(base64String: string): Uint8Array {\n // 1. Validate input\n if (!base64String) {\n throw new VapidKeyError('VAPID public key is required', 'VAPID_EMPTY');\n }\n\n if (typeof base64String !== 'string') {\n throw new VapidKeyError('VAPID public key must be a string', 'VAPID_INVALID_TYPE');\n }\n\n // 2. Convert base64url to base64\n // base64url uses '-' and '_' instead of '+' and '/'\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');\n\n // 3. Decode base64\n let rawData: string;\n try {\n rawData = window.atob(base64);\n } catch (e) {\n throw new VapidKeyError(\n `Invalid base64url format: ${e instanceof Error ? e.message : String(e)}`,\n 'VAPID_INVALID_BASE64'\n );\n }\n\n // 4. Convert to Uint8Array\n const outputArray = new Uint8Array(rawData.length);\n for (let i = 0; i < rawData.length; i++) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n\n // 5. Validate length (P-256 uncompressed = 65 bytes)\n // Format: 0x04 (1 byte) + X coordinate (32 bytes) + Y coordinate (32 bytes)\n if (outputArray.length !== 65) {\n throw new VapidKeyError(\n `Invalid key length: expected 65 bytes (P-256 uncompressed), got ${outputArray.length} bytes`,\n 'VAPID_INVALID_LENGTH'\n );\n }\n\n // 6. Validate format (must start with 0x04 for uncompressed P-256 point)\n if (outputArray[0] !== 0x04) {\n throw new VapidKeyError(\n `Invalid key format: must start with 0x04 (uncompressed P-256 point), got 0x${outputArray[0]\n .toString(16)\n .padStart(2, '0')}`,\n 'VAPID_INVALID_FORMAT'\n );\n }\n\n return outputArray;\n}\n\n/**\n * Validate VAPID key without conversion\n *\n * Checks if a VAPID key is valid without converting it.\n * Useful for validation before attempting subscription.\n *\n * @param base64String - VAPID public key to validate\n * @returns true if key is valid\n *\n * @example\n * ```typescript\n * if (isValidVapidKey(vapidKey)) {\n * // Proceed with subscription\n * } else {\n * console.error('Invalid VAPID key configuration');\n * }\n * ```\n */\nexport function isValidVapidKey(base64String: string): boolean {\n try {\n urlBase64ToUint8Array(base64String);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get VAPID key information for debugging\n *\n * Returns detailed information about a VAPID key for troubleshooting.\n *\n * @param base64String - VAPID public key to inspect\n * @returns Key information object\n *\n * @example\n * ```typescript\n * const info = getVapidKeyInfo(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY);\n * console.log('VAPID Key Info:', info);\n * // {\n * // valid: true,\n * // length: 65,\n * // firstByte: '0x04',\n * // format: 'P-256 uncompressed'\n * // }\n * ```\n */\nexport function getVapidKeyInfo(base64String: string): {\n valid: boolean;\n length?: number;\n firstByte?: string;\n format?: string;\n error?: string;\n errorCode?: VapidKeyErrorCode;\n} {\n try {\n const key = urlBase64ToUint8Array(base64String);\n return {\n valid: true,\n length: key.length,\n firstByte: `0x${key[0].toString(16).padStart(2, '0')}`,\n format: key[0] === 0x04 ? 'P-256 uncompressed' : 'Unknown',\n };\n } catch (e) {\n if (e instanceof VapidKeyError) {\n return {\n valid: false,\n error: e.message,\n errorCode: e.code,\n };\n }\n return {\n valid: false,\n error: String(e),\n };\n }\n}\n\n/**\n * Safe VAPID key conversion with error handling\n *\n * Attempts to convert a VAPID key with detailed error logging.\n * Returns null on failure instead of throwing.\n *\n * @param base64String - VAPID public key\n * @param onError - Optional error callback\n * @returns Uint8Array or null if conversion fails\n *\n * @example\n * ```typescript\n * const key = safeUrlBase64ToUint8Array(vapidKey, (error) => {\n * console.error('VAPID conversion failed:', error.message, error.code);\n * });\n *\n * if (key) {\n * // Use key for subscription\n * }\n * ```\n */\nexport function safeUrlBase64ToUint8Array(\n base64String: string,\n onError?: (error: VapidKeyError) => void\n): Uint8Array | null {\n try {\n return urlBase64ToUint8Array(base64String);\n } catch (e) {\n if (e instanceof VapidKeyError) {\n onError?.(e);\n }\n return null;\n }\n}\n","'use client';\n\n/**\n * Push Notifications Hook\n *\n * Manages push notification subscription state\n * Integrates with @djangocfg/nextjs/pwa\n */\n\nimport { useEffect, useState } from 'react';\n\nimport { pwaLogger } from '../utils/logger';\nimport { checkBrowserPushSupport } from '../utils/platform';\nimport { urlBase64ToUint8Array, VapidKeyError } from '../utils/vapid';\n\nimport type { PushNotificationState, PushNotificationOptions } from '../types';\nexport function usePushNotifications(options?: PushNotificationOptions) {\n const [state, setState] = useState<PushNotificationState>({\n isSupported: false,\n permission: 'default',\n isSubscribed: false,\n subscription: null,\n });\n\n // Check if push notifications are supported\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n // Check browser-level support first (blocks unsupported browsers like Comet, Opera Mini, etc.)\n const browserSupport = checkBrowserPushSupport();\n\n if (!browserSupport.isSupported) {\n pwaLogger.info(`[usePushNotifications] Browser does not support push: ${browserSupport.browserName} - ${browserSupport.reason}`);\n setState((prev) => ({\n ...prev,\n isSupported: false,\n permission: 'denied',\n }));\n return;\n }\n\n // Check API-level support\n const isSupported = 'serviceWorker' in navigator && 'PushManager' in window && 'Notification' in window;\n\n setState((prev) => ({\n ...prev,\n isSupported,\n permission: isSupported ? Notification.permission : 'denied',\n }));\n\n // Check existing subscription\n if (isSupported) {\n navigator.serviceWorker.ready\n .then((registration) => registration.pushManager.getSubscription())\n .then((subscription) => {\n setState((prev) => ({\n ...prev,\n isSubscribed: !!subscription,\n subscription,\n }));\n })\n .catch((error) => {\n pwaLogger.error('[usePushNotifications] Failed to get subscription:', error);\n });\n }\n }, []);\n\n /**\n * Subscribe to push notifications\n * @returns subscription on success, null on failure\n */\n const subscribe = async (): Promise<PushSubscription | null> => {\n if (!state.isSupported) {\n pwaLogger.warn('[usePushNotifications] Push notifications not supported');\n return null;\n }\n\n if (!options?.vapidPublicKey) {\n pwaLogger.error('[usePushNotifications] VAPID public key required');\n return null;\n }\n\n try {\n // Pre-flight check: Test network connectivity\n pwaLogger.debug('[usePushNotifications] Running pre-flight checks...');\n\n // Check if we're online\n if (!navigator.onLine) {\n pwaLogger.error('[usePushNotifications] No internet connection');\n throw new Error('No internet connection. Please check your network and try again.');\n }\n\n // Request permission\n const permission = await Notification.requestPermission();\n setState((prev) => ({ ...prev, permission }));\n\n if (permission !== 'granted') {\n pwaLogger.warn('[usePushNotifications] Permission not granted:', permission);\n return null;\n }\n\n // Subscribe to push\n const registration = await navigator.serviceWorker.ready;\n\n // Convert and validate VAPID key\n let applicationServerKey: Uint8Array;\n try {\n pwaLogger.debug('[usePushNotifications] Converting VAPID key...');\n applicationServerKey = urlBase64ToUint8Array(options.vapidPublicKey);\n pwaLogger.info('[usePushNotifications] VAPID key validated successfully');\n } catch (e) {\n if (e instanceof VapidKeyError) {\n pwaLogger.error(`[usePushNotifications] Invalid VAPID key: ${e.message} (code: ${e.code})`);\n } else {\n pwaLogger.error('[usePushNotifications] Failed to convert VAPID key:', e);\n }\n return null;\n }\n\n // Diagnostic logging (only in debug mode)\n pwaLogger.debug('[usePushNotifications] Service Worker state:', {\n controller: navigator.serviceWorker.controller ? 'active' : 'none',\n registrationActive: registration.active ? 'yes' : 'no',\n permission: Notification.permission,\n });\n\n // Check for existing subscription and unsubscribe\n const existingSub = await registration.pushManager.getSubscription();\n if (existingSub) {\n pwaLogger.debug('[usePushNotifications] Unsubscribing from existing subscription...');\n await existingSub.unsubscribe();\n }\n\n // Prepare subscription options\n const subscribeOptions = {\n userVisibleOnly: true,\n applicationServerKey: applicationServerKey as unknown as BufferSource,\n };\n\n pwaLogger.debug('[usePushNotifications] Subscribing with VAPID key...');\n\n // Attempt subscribe\n const subscription = await registration.pushManager.subscribe(subscribeOptions);\n\n // Send subscription to server (legacy endpoint support)\n if (options.subscribeEndpoint) {\n await fetch(options.subscribeEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(subscription),\n });\n }\n\n setState((prev) => ({\n ...prev,\n isSubscribed: true,\n subscription,\n }));\n\n pwaLogger.success('[usePushNotifications] Successfully subscribed to push notifications');\n return subscription;\n } catch (error: any) {\n pwaLogger.error('[usePushNotifications] Subscribe failed:', error);\n\n // Specific diagnostic for push service errors\n if (error.name === 'AbortError' || error.message?.includes('push service error')) {\n pwaLogger.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n pwaLogger.error('❌ PUSH SERVICE ERROR - Cannot connect to FCM');\n pwaLogger.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n pwaLogger.error('');\n pwaLogger.error('🔍 This is NOT a code bug - it\\'s a network/security block.');\n pwaLogger.error('');\n pwaLogger.error('✅ Quick Fixes (try in order):');\n pwaLogger.error(' 1. Disable VPN/Proxy and refresh page');\n pwaLogger.error(' 2. Open Incognito window (Cmd+Shift+N)');\n pwaLogger.error(' 3. Try different browser (Safari, Firefox)');\n pwaLogger.error(' 4. Use mobile hotspot instead of WiFi');\n pwaLogger.error('');\n pwaLogger.error('🔧 Technical Details:');\n pwaLogger.error(' • Browser tries to connect to FCM (ports 5228-5230)');\n pwaLogger.error(' • VPN/Firewall/Privacy settings may block these ports');\n pwaLogger.error(' • Check browser console for \"AbortError\" details');\n pwaLogger.error('');\n pwaLogger.error('📚 Learn more: https://web.dev/push-notifications-overview/');\n pwaLogger.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n } else if (error.message?.includes('No internet connection')) {\n pwaLogger.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n pwaLogger.error('❌ NO INTERNET CONNECTION');\n pwaLogger.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');\n pwaLogger.error('Please check your network connection and try again.');\n } else {\n pwaLogger.error('Unknown error:', error.name, error.message);\n }\n\n return null;\n }\n };\n\n const unsubscribe = async (): Promise<boolean> => {\n if (!state.subscription) {\n pwaLogger.warn('[usePushNotifications] No active subscription to unsubscribe');\n return false;\n }\n\n try {\n await state.subscription.unsubscribe();\n setState((prev) => ({\n ...prev,\n isSubscribed: false,\n subscription: null,\n }));\n pwaLogger.info('[usePushNotifications] Successfully unsubscribed from push notifications');\n return true;\n } catch (error) {\n pwaLogger.error('[usePushNotifications] Unsubscribe failed:', error);\n return false;\n }\n };\n\n return {\n ...state,\n subscribe,\n unsubscribe,\n };\n}\n","'use client';\n\n/**\n * Django Push Notifications Hook\n *\n * Integrates usePushNotifications with Django-CFG backend API.\n * Uses generated TypeScript client from @djangocfg/api for type-safe integration.\n * Requires authentication - opens AuthDialog if user is not logged in.\n *\n * Architecture:\n * - usePushNotifications: handles all browser Push API operations\n * - useDjangoPush: adds Django backend sync on top\n *\n * @example\n * ```tsx\n * import { useDjangoPush } from '@djangocfg/layouts/snippets';\n *\n * function NotificationsButton() {\n * const { subscribe, unsubscribe, isSubscribed } = useDjangoPush({\n * vapidPublicKey: 'YOUR_VAPID_KEY'\n * });\n *\n * return (\n * <button onClick={isSubscribed ? unsubscribe : subscribe}>\n * {isSubscribed ? 'Unsubscribe' : 'Subscribe'}\n * </button>\n * );\n * }\n * ```\n */\n\nimport { useCallback, useState } from 'react';\nimport { toast } from '@djangocfg/ui-core/hooks';\n\n// Auth\nimport { useAuth } from '@djangocfg/api/auth';\n// Import Django API client\n// @ts-ignore - optional peer dependency\nimport { apiWebPush } from '@djangocfg/api/clients';\n\nimport { useAuthDialog } from '../../AuthDialog';\nimport { pwaLogger } from '../utils/logger';\nimport { usePushNotifications } from './usePushNotifications';\n\nimport type { PushNotificationOptions } from '../types';\n\ninterface UseDjangoPushOptions extends PushNotificationOptions {\n /**\n * Callback when subscription created\n */\n onSubscribed?: (subscription: PushSubscription) => void;\n\n /**\n * Callback when subscription failed\n */\n onSubscribeError?: (error: Error) => void;\n\n /**\n * Callback when unsubscribed\n */\n onUnsubscribed?: () => void;\n}\n\ninterface UseDjangoPushReturn {\n // State (from usePushNotifications)\n isSupported: boolean;\n permission: NotificationPermission;\n isSubscribed: boolean;\n subscription: PushSubscription | null;\n\n // Local state\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n subscribe: () => Promise<boolean>;\n unsubscribe: () => Promise<boolean>;\n sendTestPush: (message: { title: string; body: string; url?: string }) => Promise<boolean>;\n}\n\n/**\n * Hook for Django-CFG push notifications integration\n */\nexport function useDjangoPush(options: UseDjangoPushOptions): UseDjangoPushReturn {\n const { onSubscribed, onSubscribeError, onUnsubscribed, ...pushOptions } = options;\n\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Auth check\n const { isAuthenticated } = useAuth();\n const { openAuthDialog } = useAuthDialog();\n\n // Use base push notifications hook (handles all browser API)\n const pushNotifications = usePushNotifications(pushOptions);\n\n /**\n * Subscribe to push notifications and save to Django backend\n */\n const subscribe = useCallback(async (): Promise<boolean> => {\n // Auth check - require login for push subscriptions\n if (!isAuthenticated) {\n openAuthDialog({\n message: 'Please sign in to enable push notifications',\n });\n return false;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n // Step 1: Browser subscription via usePushNotifications\n const subscription = await pushNotifications.subscribe();\n\n if (!subscription) {\n // Permission denied or other browser error\n const err = new Error('Browser subscription failed');\n setError(err);\n onSubscribeError?.(err);\n return false;\n }\n\n pwaLogger.info('[useDjangoPush] Browser subscription created');\n\n // Step 2: Save to Django backend\n const result = await apiWebPush.web_push.webpushSubscribeCreate({\n endpoint: subscription.endpoint,\n keys: {\n p256dh: arrayBufferToBase64(subscription.getKey('p256dh')),\n auth: arrayBufferToBase64(subscription.getKey('auth')),\n },\n });\n\n pwaLogger.info('[useDjangoPush] Subscription saved to Django:', result);\n\n onSubscribed?.(subscription);\n toast.success('Push notifications enabled');\n return true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n pwaLogger.error('[useDjangoPush] Subscribe failed:', error);\n setError(error);\n onSubscribeError?.(error);\n\n toast.error('Subscription Failed', {\n description: 'Could not save subscription to server. Please try again.',\n duration: 5000,\n });\n\n return false;\n } finally {\n setIsLoading(false);\n }\n }, [isAuthenticated, openAuthDialog, pushNotifications.subscribe, onSubscribed, onSubscribeError]);\n\n /**\n * Unsubscribe from push notifications\n */\n const unsubscribe = useCallback(async (): Promise<boolean> => {\n setIsLoading(true);\n setError(null);\n\n try {\n // Unsubscribe via usePushNotifications (handles browser API)\n const success = await pushNotifications.unsubscribe();\n\n if (!success) {\n return false;\n }\n\n pwaLogger.info('[useDjangoPush] Browser unsubscribed');\n\n // Note: Django backend auto-cleans up inactive subscriptions\n // when push delivery fails (410 Gone response)\n\n onUnsubscribed?.();\n toast.success('Push notifications disabled');\n return true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n pwaLogger.error('[useDjangoPush] Unsubscribe failed:', error);\n setError(error);\n return false;\n } finally {\n setIsLoading(false);\n }\n }, [pushNotifications.unsubscribe, onUnsubscribed]);\n\n /**\n * Send test push notification\n */\n const sendTestPush = useCallback(\n async (message: { title: string; body: string; url?: string }): Promise<boolean> => {\n if (!pushNotifications.isSubscribed) {\n const err = new Error('Not subscribed');\n setError(err);\n return false;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await apiWebPush.web_push.webpushSendCreate({\n title: message.title,\n body: message.body,\n url: message.url || '/',\n icon: '/icon.png',\n });\n\n pwaLogger.info('[useDjangoPush] Test push sent:', result);\n return result.success;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n pwaLogger.error('[useDjangoPush] Send test push failed:', error);\n setError(error);\n return false;\n } finally {\n setIsLoading(false);\n }\n },\n [pushNotifications.isSubscribed]\n );\n\n return {\n // State from usePushNotifications\n isSupported: pushNotifications.isSupported,\n permission: pushNotifications.permission,\n isSubscribed: pushNotifications.isSubscribed,\n subscription: pushNotifications.subscription,\n\n // Local state\n isLoading,\n error,\n\n // Actions\n subscribe,\n unsubscribe,\n sendTestPush,\n };\n}\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Convert ArrayBuffer to base64 string\n */\nfunction arrayBufferToBase64(buffer: ArrayBuffer | null): string {\n if (!buffer) return '';\n\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return window.btoa(binary);\n}\n","'use client';\n\n/**\n * Django Push Context\n *\n * Provider for Django-CFG push notifications integration.\n * Wraps useDjangoPush hook in React context for easy consumption.\n *\n * @example\n * ```tsx\n * import { DjangoPushProvider, useDjangoPushContext } from '@djangocfg/layouts/PWA';\n *\n * // In layout\n * <DjangoPushProvider vapidPublicKey={process.env.NEXT_PUBLIC_VAPID_KEY}>\n * {children}\n * </DjangoPushProvider>\n *\n * // In component\n * function NotifyButton() {\n * const { subscribe, isSubscribed } = useDjangoPushContext();\n * return <button onClick={subscribe}>Subscribe</button>;\n * }\n * ```\n */\n\nimport React, { createContext, useCallback, useContext, useEffect, useState } from 'react';\n\nimport { useDjangoPush } from '../hooks/useDjangoPush';\nimport { pwaLogger } from '../utils/logger';\n\nimport type { PushNotificationOptions } from '../types';\n\nexport interface PushMessage {\n id: string;\n title: string;\n body: string;\n icon?: string;\n badge?: string;\n tag?: string;\n timestamp: number;\n data?: Record<string, unknown>;\n}\n\ninterface DjangoPushContextValue {\n // State\n isSupported: boolean;\n permission: NotificationPermission;\n isSubscribed: boolean;\n subscription: PushSubscription | null;\n isLoading: boolean;\n error: Error | null;\n\n // Push history\n pushes: PushMessage[];\n\n // Actions\n subscribe: () => Promise<boolean>;\n unsubscribe: () => Promise<boolean>;\n sendTestPush: (message: { title: string; body: string; url?: string }) => Promise<boolean>;\n sendPush: (message: Omit<PushMessage, 'id' | 'timestamp'>) => Promise<void>;\n clearPushes: () => void;\n removePush: (id: string) => void;\n}\n\nconst DjangoPushContext = createContext<DjangoPushContextValue | undefined>(undefined);\n\ninterface DjangoPushProviderProps extends PushNotificationOptions {\n children: React.ReactNode;\n\n /**\n * Auto-subscribe on mount if permission granted\n * @default false\n */\n autoSubscribe?: boolean;\n\n /**\n * Callback when subscription created\n */\n onSubscribed?: (subscription: PushSubscription) => void;\n\n /**\n * Callback when subscription failed\n */\n onSubscribeError?: (error: Error) => void;\n\n /**\n * Callback when unsubscribed\n */\n onUnsubscribed?: () => void;\n}\n\n/**\n * Provider for Django push notifications\n */\nexport function DjangoPushProvider({\n children,\n vapidPublicKey,\n autoSubscribe = false,\n onSubscribed,\n onSubscribeError,\n onUnsubscribed,\n}: DjangoPushProviderProps) {\n const djangoPush = useDjangoPush({\n vapidPublicKey,\n onSubscribed,\n onSubscribeError,\n onUnsubscribed,\n });\n\n // Auto-subscribe on mount if permission already granted\n useEffect(() => {\n if (\n autoSubscribe &&\n djangoPush.isSupported &&\n djangoPush.permission === 'granted' &&\n !djangoPush.isSubscribed &&\n !djangoPush.isLoading\n ) {\n pwaLogger.info('[DjangoPushProvider] Auto-subscribing (permission already granted)');\n djangoPush.subscribe();\n }\n }, [autoSubscribe, djangoPush.isSupported, djangoPush.permission, djangoPush.isSubscribed, djangoPush.isLoading]);\n\n const [pushes, setPushes] = useState<PushMessage[]>([]);\n\n // Listen for push messages from service worker\n useEffect(() => {\n if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {\n return;\n }\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data && event.data.type === 'PUSH_RECEIVED') {\n const push: PushMessage = {\n id: crypto.randomUUID(),\n timestamp: Date.now(),\n ...event.data.notification,\n };\n\n setPushes(prev => [push, ...prev]);\n pwaLogger.info('[DjangoPushProvider] Push received:', push);\n }\n };\n\n navigator.serviceWorker.addEventListener('message', handleMessage);\n return () => navigator.serviceWorker.removeEventListener('message', handleMessage);\n }, []);\n\n const sendPush = useCallback(\n async (message: Omit<PushMessage, 'id' | 'timestamp'>) => {\n await djangoPush.sendTestPush({\n title: message.title,\n body: message.body,\n url: message.data?.url as string | undefined,\n });\n },\n [djangoPush]\n );\n\n const clearPushes = useCallback(() => {\n setPushes([]);\n pwaLogger.info('[DjangoPushProvider] Push history cleared');\n }, []);\n\n const removePush = useCallback((id: string) => {\n setPushes(prev => prev.filter(p => p.id !== id));\n pwaLogger.info('[DjangoPushProvider] Push removed:', id);\n }, []);\n\n const value: DjangoPushContextValue = {\n ...djangoPush,\n pushes,\n sendPush,\n clearPushes,\n removePush,\n };\n\n return <DjangoPushContext.Provider value={value}>{children}</DjangoPushContext.Provider>;\n}\n\n/**\n * Hook to access Django push context\n */\nexport function useDjangoPushContext(): DjangoPushContextValue {\n const context = useContext(DjangoPushContext);\n\n if (context === undefined) {\n throw new Error('useDjangoPushContext must be used within DjangoPushProvider');\n }\n\n return context;\n}\n","/**\n * LocalStorage utilities for Push Notifications state persistence\n */\n\n/**\n * Storage keys\n */\nexport const STORAGE_KEYS = {\n PUSH_DISMISSED: 'pwa_push_dismissed_at',\n} as const;\n\n/**\n * Check if push prompt was dismissed recently\n * @param resetDays Number of days before re-showing (default: 7)\n */\nexport function isPushDismissedRecently(resetDays: number = 7): boolean {\n return isDismissedRecentlyHelper(resetDays, STORAGE_KEYS.PUSH_DISMISSED);\n}\n\n/**\n * Mark push prompt as dismissed\n */\nexport function markPushDismissed(): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(STORAGE_KEYS.PUSH_DISMISSED, Date.now().toString());\n } catch {\n // Fail silently\n }\n}\n\n/**\n * Helper: Check if a key was dismissed recently\n * @internal\n */\nfunction isDismissedRecentlyHelper(resetDays: number, key: string): boolean {\n if (typeof window === 'undefined') return false;\n try {\n const dismissed = localStorage.getItem(key);\n if (!dismissed) return false;\n const dismissedAt = parseInt(dismissed, 10);\n const daysSince = (Date.now() - dismissedAt) / (1000 * 60 * 60 * 24);\n return daysSince < resetDays;\n } catch {\n return false;\n }\n}\n\n/**\n * Clear all push notification data\n */\nexport function clearAllPushData(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.removeItem(STORAGE_KEYS.PUSH_DISMISSED);\n } catch {\n // Fail silently\n }\n}\n","'use client';\n\n/**\n * Push Notification Prompt\n *\n * Shows after PWA is installed to request push notification permission\n * Auto-dismisses after user action or timeout\n */\n\nimport { Bell, X } from 'lucide-react';\nimport React, { useEffect, useState } from 'react';\n\nimport { useAuth } from '@djangocfg/api/auth';\nimport { Button } from '@djangocfg/ui-nextjs';\n\nimport { usePushNotifications } from '../hooks/usePushNotifications';\nimport { isPushDismissedRecently, markPushDismissed } from '../utils/localStorage';\nimport { pwaLogger } from '../utils/logger';\nimport { isStandalone } from '../utils/platform';\n\nimport type { PushNotificationOptions } from '../types';\n\nconst DEFAULT_RESET_DAYS = 7;\n\ninterface PushPromptProps extends PushNotificationOptions {\n /**\n * Only show if PWA is installed\n * @default true\n */\n requirePWA?: boolean;\n\n /**\n * Delay before showing prompt (ms)\n * @default 5000\n */\n delayMs?: number;\n\n /**\n * Number of days before re-showing dismissed prompt\n * @default 7\n */\n resetAfterDays?: number;\n\n /**\n * Callback when push is enabled\n */\n onEnabled?: () => void;\n\n /**\n * Callback when push is dismissed\n */\n onDismissed?: () => void;\n}\n\nexport function PushPrompt({\n vapidPublicKey,\n subscribeEndpoint = '/api/push/subscribe',\n requirePWA = true,\n delayMs = 5000,\n resetAfterDays = DEFAULT_RESET_DAYS,\n onEnabled,\n onDismissed,\n}: PushPromptProps) {\n const { isAuthenticated, isLoading: isAuthLoading } = useAuth();\n const { isSupported, permission, isSubscribed, subscribe } = usePushNotifications({\n vapidPublicKey,\n subscribeEndpoint,\n });\n\n const [show, setShow] = useState(false);\n const [enabling, setEnabling] = useState(false);\n\n // Check if should show\n useEffect(() => {\n // Wait for auth to complete, don't show for unauthenticated users\n if (isAuthLoading || !isAuthenticated) {\n return;\n }\n\n if (!isSupported || isSubscribed || permission === 'denied') {\n return;\n }\n\n // Check if PWA is installed (standalone mode)\n if (requirePWA && !isStandalone()) {\n return;\n }\n\n // Check if previously dismissed\n if (typeof window !== 'undefined') {\n if (isPushDismissedRecently(resetAfterDays)) {\n return; // Still within reset period\n }\n }\n\n // Show after delay\n const timer = setTimeout(() => setShow(true), delayMs);\n return () => clearTimeout(timer);\n }, [isAuthLoading, isAuthenticated, isSupported, isSubscribed, permission, requirePWA, resetAfterDays, delayMs]);\n\n const handleEnable = async () => {\n setEnabling(true);\n try {\n const success = await subscribe();\n if (success) {\n setShow(false);\n onEnabled?.();\n }\n } catch (error) {\n pwaLogger.error('[PushPrompt] Enable failed:', error);\n } finally {\n setEnabling(false);\n }\n };\n\n const handleDismiss = () => {\n setShow(false);\n markPushDismissed();\n onDismissed?.();\n };\n\n if (!show) return null;\n\n return (\n <div className=\"fixed bottom-4 left-4 right-4 z-50 animate-in slide-in-from-bottom-4 duration-300\">\n <div className=\"bg-zinc-900 border border-zinc-700 rounded-lg p-4 shadow-lg\">\n <div className=\"flex items-start gap-3\">\n {/* Icon */}\n <div className=\"flex-shrink-0\">\n <Bell className=\"w-5 h-5 text-blue-400\" />\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-white mb-1\">Enable notifications</p>\n <p className=\"text-xs text-zinc-400 mb-3\">\n Stay updated with important updates and alerts\n </p>\n\n {/* Actions */}\n <div className=\"flex gap-2\">\n <Button\n onClick={handleEnable}\n loading={enabling}\n size=\"sm\"\n variant=\"default\"\n >\n Enable\n </Button>\n <Button\n onClick={handleDismiss}\n size=\"sm\"\n variant=\"ghost\"\n >\n Not now\n </Button>\n </div>\n </div>\n\n {/* Close button */}\n <Button\n onClick={handleDismiss}\n size=\"sm\"\n variant=\"ghost\"\n className=\"flex-shrink-0 p-1\"\n aria-label=\"Dismiss\"\n >\n <X className=\"w-4 h-4\" />\n </Button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Push Notifications Configuration\n *\n * Centralized constants for push notifications functionality.\n *\n * SECURITY NOTE:\n * - VAPID_PRIVATE_KEY should NEVER be in frontend code\n * - Private keys must only exist in backend/API routes\n * - Frontend only needs the public key (NEXT_PUBLIC_* env vars)\n * - VAPID_MAILTO should also remain on backend only\n */\n\n// Default VAPID public key (safe to expose in frontend)\nexport const DEFAULT_VAPID_PUBLIC_KEY = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY || '';\n\n// NOTE: VAPID private key and mailto should only exist in:\n// - Backend environment variables (not NEXT_PUBLIC_*)\n// - API route handlers (app/api/push/*)\n// - Service worker generation scripts\n// NEVER import or use private keys in frontend code\n"]}