@djangocfg/layouts 2.1.42 → 2.1.43

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 (67) hide show
  1. package/package.json +7 -6
  2. package/src/components/RedirectPage/RedirectPage.tsx +2 -1
  3. package/src/components/core/ClientOnly.tsx +2 -1
  4. package/src/components/core/LucideIcon.tsx +3 -2
  5. package/src/components/core/Suspense.tsx +1 -1
  6. package/src/components/errors/ErrorBoundary.tsx +1 -1
  7. package/src/components/errors/ErrorLayout.tsx +2 -0
  8. package/src/components/errors/ErrorsTracker/components/ErrorButtons.tsx +6 -6
  9. package/src/components/errors/ErrorsTracker/components/ErrorToast.tsx +4 -3
  10. package/src/components/errors/ErrorsTracker/providers/ErrorTrackingProvider.tsx +10 -9
  11. package/src/layouts/AdminLayout/AdminLayout.tsx +2 -1
  12. package/src/layouts/AppLayout/AppLayout.tsx +4 -2
  13. package/src/layouts/AppLayout/BaseApp.tsx +10 -7
  14. package/src/layouts/AuthLayout/AuthHelp.tsx +1 -1
  15. package/src/layouts/AuthLayout/AuthLayout.tsx +2 -2
  16. package/src/layouts/AuthLayout/IdentifierForm.tsx +4 -16
  17. package/src/layouts/AuthLayout/OAuthCallback.tsx +5 -4
  18. package/src/layouts/AuthLayout/OAuthProviders.tsx +2 -2
  19. package/src/layouts/AuthLayout/OTPForm.tsx +3 -9
  20. package/src/layouts/PrivateLayout/PrivateLayout.tsx +7 -3
  21. package/src/layouts/PrivateLayout/components/PrivateContent.tsx +1 -0
  22. package/src/layouts/PrivateLayout/components/PrivateHeader.tsx +6 -7
  23. package/src/layouts/PrivateLayout/components/PrivateSidebar.tsx +6 -12
  24. package/src/layouts/ProfileLayout/ProfileLayout.tsx +4 -13
  25. package/src/layouts/ProfileLayout/components/AvatarSection.tsx +7 -3
  26. package/src/layouts/ProfileLayout/components/ProfileForm.tsx +8 -18
  27. package/src/layouts/PublicLayout/PublicLayout.tsx +4 -6
  28. package/src/layouts/PublicLayout/components/PublicFooter/FooterBottom.tsx +3 -1
  29. package/src/layouts/PublicLayout/components/PublicFooter/FooterMenuSections.tsx +2 -1
  30. package/src/layouts/PublicLayout/components/PublicFooter/FooterProjectInfo.tsx +3 -1
  31. package/src/layouts/PublicLayout/components/PublicFooter/FooterSocialLinks.tsx +3 -10
  32. package/src/layouts/PublicLayout/components/PublicFooter/PublicFooter.tsx +6 -3
  33. package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +7 -9
  34. package/src/layouts/PublicLayout/components/PublicNavigation.tsx +8 -5
  35. package/src/layouts/_components/UserMenu.tsx +8 -14
  36. package/src/pages/legal/LegalPage.tsx +3 -6
  37. package/src/pages/legal/pages.tsx +2 -6
  38. package/src/snippets/Analytics/AnalyticsProvider.tsx +1 -0
  39. package/src/snippets/Analytics/useAnalytics.ts +2 -1
  40. package/src/snippets/AuthDialog/AuthDialog.tsx +2 -6
  41. package/src/snippets/AuthDialog/useAuthDialog.ts +2 -1
  42. package/src/snippets/Breadcrumbs.tsx +4 -4
  43. package/src/snippets/McpChat/components/AIChatWidget.tsx +8 -4
  44. package/src/snippets/McpChat/components/AskAIButton.tsx +4 -1
  45. package/src/snippets/McpChat/components/ChatMessages.tsx +5 -2
  46. package/src/snippets/McpChat/components/ChatPanel.tsx +5 -3
  47. package/src/snippets/McpChat/components/ChatSidebar.tsx +5 -3
  48. package/src/snippets/McpChat/components/ChatWidget.tsx +6 -3
  49. package/src/snippets/McpChat/components/MessageBubble.tsx +6 -2
  50. package/src/snippets/McpChat/components/MessageInput.tsx +3 -2
  51. package/src/snippets/McpChat/context/AIChatContext.tsx +7 -3
  52. package/src/snippets/McpChat/context/ChatContext.tsx +7 -3
  53. package/src/snippets/McpChat/hooks/useAIChat.ts +5 -2
  54. package/src/snippets/McpChat/hooks/useChatLayout.ts +5 -3
  55. package/src/snippets/McpChat/hooks/useMcpChat.ts +1 -0
  56. package/src/snippets/PWAInstall/components/A2HSHint.tsx +6 -5
  57. package/src/snippets/PWAInstall/components/DesktopGuide.tsx +4 -11
  58. package/src/snippets/PWAInstall/components/IOSGuide.tsx +1 -1
  59. package/src/snippets/PWAInstall/components/IOSGuideDrawer.tsx +2 -9
  60. package/src/snippets/PWAInstall/components/IOSGuideModal.tsx +3 -10
  61. package/src/snippets/PWAInstall/context/InstallContext.tsx +2 -2
  62. package/src/snippets/PWAInstall/hooks/useInstallPrompt.ts +3 -2
  63. package/src/snippets/PWAInstall/hooks/useIsPWA.ts +2 -1
  64. package/src/snippets/PushNotifications/components/PushPrompt.tsx +5 -3
  65. package/src/snippets/PushNotifications/context/DjangoPushContext.tsx +3 -1
  66. package/src/snippets/PushNotifications/hooks/useDjangoPush.ts +7 -6
  67. package/src/snippets/PushNotifications/hooks/usePushNotifications.ts +3 -2
@@ -6,20 +6,18 @@
6
6
 
7
7
  'use client';
8
8
 
9
- import React from 'react';
10
- import Link from 'next/link';
11
9
  import { X } from 'lucide-react';
10
+ import Link from 'next/link';
11
+ import React from 'react';
12
+
13
+ import { useAuth } from '@djangocfg/api/auth';
12
14
  import {
13
- Drawer,
14
- DrawerContent,
15
- DrawerHeader,
16
- DrawerTitle,
17
- DrawerClose,
18
- Button,
15
+ Button, Drawer, DrawerClose, DrawerContent, DrawerHeader, DrawerTitle
19
16
  } from '@djangocfg/ui-nextjs/components';
20
17
  import { ThemeToggle } from '@djangocfg/ui-nextjs/theme';
21
- import { useAuth } from '@djangocfg/api/auth';
18
+
22
19
  import { UserMenu } from '../../_components/UserMenu';
20
+
23
21
  import type { NavigationItem, UserMenuConfig } from '../../types';
24
22
 
25
23
  interface PublicMobileDrawerProps {
@@ -6,15 +6,18 @@
6
6
 
7
7
  'use client';
8
8
 
9
- import React from 'react';
10
- import Link from 'next/link';
11
9
  import { Menu } from 'lucide-react';
10
+ import Link from 'next/link';
11
+ import React from 'react';
12
+
13
+ import { useAuth } from '@djangocfg/api/auth';
12
14
  import { Button } from '@djangocfg/ui-nextjs/components';
13
- import { ThemeToggle } from '@djangocfg/ui-nextjs/theme';
14
- import { cn } from '@djangocfg/ui-nextjs/lib';
15
15
  import { useIsMobile } from '@djangocfg/ui-nextjs/hooks';
16
- import { useAuth } from '@djangocfg/api/auth';
16
+ import { cn } from '@djangocfg/ui-nextjs/lib';
17
+ import { ThemeToggle } from '@djangocfg/ui-nextjs/theme';
18
+
17
19
  import { UserMenu } from '../../_components/UserMenu';
20
+
18
21
  import type { NavigationItem, UserMenuConfig } from '../../types';
19
22
 
20
23
  interface PublicNavigationProps {
@@ -30,23 +30,17 @@
30
30
 
31
31
  'use client';
32
32
 
33
- import React from 'react';
34
- import Link from 'next/link';
35
33
  import { LogOut } from 'lucide-react';
34
+ import Link from 'next/link';
35
+ import React from 'react';
36
+
37
+ import { useAuth } from '@djangocfg/api/auth';
36
38
  import {
37
- DropdownMenu,
38
- DropdownMenuContent,
39
- DropdownMenuGroup,
40
- DropdownMenuItem,
41
- DropdownMenuLabel,
42
- DropdownMenuSeparator,
43
- DropdownMenuTrigger,
44
- Avatar,
45
- AvatarFallback,
46
- AvatarImage,
47
- Button,
39
+ Avatar, AvatarFallback, AvatarImage, Button, DropdownMenu, DropdownMenuContent,
40
+ DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator,
41
+ DropdownMenuTrigger
48
42
  } from '@djangocfg/ui-nextjs/components';
49
- import { useAuth } from '@djangocfg/api/auth';
43
+
50
44
  import type { UserMenuGroup } from '../types';
51
45
 
52
46
  export interface UserMenuProps {
@@ -18,12 +18,9 @@
18
18
  'use client';
19
19
 
20
20
  import React from 'react';
21
- import {
22
- Card,
23
- CardHeader,
24
- CardTitle,
25
- CardContent,
26
- } from '@djangocfg/ui-nextjs/components';
21
+
22
+ import { Card, CardContent, CardHeader, CardTitle } from '@djangocfg/ui-nextjs/components';
23
+
27
24
  import type { LegalPageConfig } from './types';
28
25
 
29
26
  export interface LegalPageProps {
@@ -15,13 +15,9 @@
15
15
 
16
16
  'use client';
17
17
 
18
+ import { cookiesConfig, privacyConfig, securityConfig, termsConfig } from './configs';
18
19
  import { LegalPage } from './LegalPage';
19
- import {
20
- privacyConfig,
21
- termsConfig,
22
- cookiesConfig,
23
- securityConfig,
24
- } from './configs';
20
+
25
21
  import type { LegalPageConfig } from './types';
26
22
 
27
23
  export interface LegalPageComponentProps {
@@ -8,6 +8,7 @@
8
8
  'use client';
9
9
 
10
10
  import { ReactNode } from 'react';
11
+
11
12
  import { useAnalytics } from './useAnalytics';
12
13
 
13
14
  interface AnalyticsProviderProps {
@@ -8,9 +8,10 @@
8
8
 
9
9
  'use client';
10
10
 
11
- import { useEffect } from 'react';
12
11
  import { usePathname } from 'next/navigation';
12
+ import { useEffect } from 'react';
13
13
  import ReactGA from 'react-ga4';
14
+
14
15
  import { useAuth } from '@djangocfg/api/auth';
15
16
 
16
17
  // Check if we're in production
@@ -4,13 +4,9 @@ import { LogIn } from 'lucide-react';
4
4
  import React, { useState } from 'react';
5
5
 
6
6
  import {
7
- Button,
8
- Dialog,
9
- DialogContent,
10
- DialogHeader,
11
- DialogTitle,
7
+ Button, Dialog, DialogContent, DialogHeader, DialogTitle
12
8
  } from '@djangocfg/ui-nextjs/components';
13
- import { useEventListener, useCfgRouter } from '@djangocfg/ui-nextjs/hooks';
9
+ import { useCfgRouter, useEventListener } from '@djangocfg/ui-nextjs/hooks';
14
10
 
15
11
  // Re-export events for backwards compatibility
16
12
  export const DIALOG_EVENTS = {
@@ -2,9 +2,10 @@
2
2
 
3
3
  import { useCallback } from 'react';
4
4
 
5
- import { AUTH_EVENTS, type OpenAuthDialogPayload } from './events';
6
5
  import { events } from '@djangocfg/ui-nextjs';
7
6
 
7
+ import { AUTH_EVENTS, OpenAuthDialogPayload} from './events';
8
+
8
9
  /**
9
10
  * Hook to control auth dialog from anywhere in the app
10
11
  */
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import React from "react";
3
- import Link from "next/link";
4
- import { usePathname } from "next/navigation";
5
- import { ChevronRight, Home } from "lucide-react";
2
+ import { ChevronRight, Home } from 'lucide-react';
3
+ import Link from 'next/link';
4
+ import { usePathname } from 'next/navigation';
5
+ import React from 'react';
6
6
 
7
7
  export interface BreadcrumbItem {
8
8
  path: string;
@@ -1,13 +1,17 @@
1
1
  'use client';
2
2
 
3
+ import { Zap } from 'lucide-react';
3
4
  import React from 'react';
5
+
4
6
  import { Button, Portal } from '@djangocfg/ui-nextjs';
5
- import { Zap } from 'lucide-react';
7
+
8
+ import {
9
+ AIChatProvider, useAIChatContext, useAIChatContextOptional
10
+ } from '../context/AIChatContext';
11
+ import { useChatLayout } from '../hooks/useChatLayout';
12
+ import { ChatWidgetConfig, getMcpEndpoints} from '../types';
6
13
  import { ChatPanel } from './ChatPanel';
7
14
  import { ChatSidebar } from './ChatSidebar';
8
- import { useAIChatContext, useAIChatContextOptional, AIChatProvider } from '../context/AIChatContext';
9
- import { useChatLayout } from '../hooks/useChatLayout';
10
- import { getMcpEndpoints, type ChatWidgetConfig } from '../types';
11
15
 
12
16
  // CSS for game-quality multi-layer animated border with smooth color flow
13
17
  const fabAnimationStyles = `
@@ -1,8 +1,11 @@
1
1
  'use client';
2
2
 
3
- import { Button, type ButtonProps } from '@djangocfg/ui-nextjs';
4
3
  import { Bot } from 'lucide-react';
4
+
5
+ import { Button, ButtonProps} from '@djangocfg/ui-nextjs';
6
+
5
7
  import { useMcpChat } from '../hooks/useMcpChat';
8
+
6
9
  import type { McpChatEventDetail } from '../types';
7
10
 
8
11
  export interface AskAIButtonProps extends Omit<ButtonProps, 'onClick'> {
@@ -1,9 +1,12 @@
1
1
  'use client';
2
2
 
3
- import React, { useRef, useEffect, useCallback, useImperativeHandle, forwardRef } from 'react';
4
- import { ScrollArea, Button, type ScrollAreaHandle } from '@djangocfg/ui-nextjs';
5
3
  import { Bot, MessageSquare, StopCircle } from 'lucide-react';
4
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
5
+
6
+ import { Button, ScrollArea, ScrollAreaHandle} from '@djangocfg/ui-nextjs';
7
+
6
8
  import { MessageBubble } from './MessageBubble';
9
+
7
10
  import type { AIChatMessage } from '../types';
8
11
 
9
12
  /**
@@ -1,11 +1,13 @@
1
1
  'use client';
2
2
 
3
+ import { Bot, PanelRight, RotateCcw, X } from 'lucide-react';
3
4
  import React from 'react';
4
- import { Card, CardHeader, CardContent, CardFooter, Button } from '@djangocfg/ui-nextjs';
5
- import { X, PanelRight, Bot, RotateCcw } from 'lucide-react';
5
+
6
+ import { Button, Card, CardContent, CardFooter, CardHeader } from '@djangocfg/ui-nextjs';
7
+
8
+ import { useAIChatContext } from '../context/AIChatContext';
6
9
  import { ChatMessages } from './ChatMessages';
7
10
  import { AIMessageInput } from './MessageInput';
8
- import { useAIChatContext } from '../context/AIChatContext';
9
11
 
10
12
  export const ChatPanel = React.memo(() => {
11
13
  const {
@@ -1,12 +1,14 @@
1
1
  'use client';
2
2
 
3
+ import { Bot, GripVertical, PanelRightClose, RotateCcw, X } from 'lucide-react';
3
4
  import React, { useEffect } from 'react';
5
+
4
6
  import { Button } from '@djangocfg/ui-nextjs';
5
- import { X, PanelRightClose, Bot, GripVertical, RotateCcw } from 'lucide-react';
7
+
8
+ import { useAIChatContext } from '../context/AIChatContext';
9
+ import { useChatLayout } from '../hooks/useChatLayout';
6
10
  import { ChatMessages } from './ChatMessages';
7
11
  import { AIMessageInput } from './MessageInput';
8
- import { useChatLayout } from '../hooks/useChatLayout';
9
- import { useAIChatContext } from '../context/AIChatContext';
10
12
 
11
13
  export interface ChatSidebarProps {
12
14
  /** Width of resize handle in pixels (default: 12) */
@@ -1,12 +1,15 @@
1
1
  'use client';
2
2
 
3
+ import { MessageCircle } from 'lucide-react';
3
4
  import React from 'react';
5
+
4
6
  import { Button, Portal } from '@djangocfg/ui-nextjs';
5
- import { MessageCircle } from 'lucide-react';
7
+
8
+ import { ChatProvider, useChatContext, useChatContextOptional } from '../context';
9
+ import { useChatLayout } from '../hooks/useChatLayout';
6
10
  import { ChatPanel } from './ChatPanel';
7
11
  import { ChatSidebar } from './ChatSidebar';
8
- import { useChatContext, useChatContextOptional, ChatProvider } from '../context';
9
- import { useChatLayout } from '../hooks/useChatLayout';
12
+
10
13
  import type { ChatWidgetConfig } from '../types';
11
14
 
12
15
  export interface ChatWidgetProps extends ChatWidgetConfig {
@@ -1,9 +1,13 @@
1
1
  'use client';
2
2
 
3
+ import { Bot, ExternalLink, Loader2, User } from 'lucide-react';
3
4
  import React from 'react';
4
- import { Card, CardContent, Badge, MarkdownMessage, Avatar, AvatarImage, AvatarFallback } from '@djangocfg/ui-nextjs';
5
- import { User, Bot, ExternalLink, Loader2 } from 'lucide-react';
5
+
6
6
  import { useAuth } from '@djangocfg/api/auth';
7
+ import {
8
+ Avatar, AvatarFallback, AvatarImage, Badge, Card, CardContent, MarkdownMessage
9
+ } from '@djangocfg/ui-nextjs';
10
+
7
11
  import type { AIChatMessage } from '../types';
8
12
 
9
13
  export interface MessageBubbleProps {
@@ -1,8 +1,9 @@
1
1
  'use client';
2
2
 
3
- import React, { useState, useRef, useCallback, useEffect } from 'react';
3
+ import { Loader2, Send } from 'lucide-react';
4
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
5
+
4
6
  import { Button } from '@djangocfg/ui-nextjs';
5
- import { Send, Loader2 } from 'lucide-react';
6
7
 
7
8
  export interface AIMessageInputProps {
8
9
  onSend: (message: string) => void;
@@ -1,9 +1,13 @@
1
1
  'use client';
2
2
 
3
- import { createContext, useContext, useState, useCallback, useMemo, useEffect, useRef, type ReactNode } from 'react';
4
- import { useLocalStorage, useIsMobile } from '@djangocfg/ui-nextjs/hooks';
3
+ import {
4
+ createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState
5
+ } from 'react';
6
+
7
+ import { useIsMobile, useLocalStorage } from '@djangocfg/ui-nextjs/hooks';
8
+
5
9
  import { useAIChat } from '../hooks/useAIChat';
6
- import { mcpEndpoints, type AIChatMessage, type ChatWidgetConfig, type ChatDisplayMode } from '../types';
10
+ import { AIChatMessage, ChatDisplayMode, ChatWidgetConfig, mcpEndpoints} from '../types';
7
11
 
8
12
  const STORAGE_KEY_MODE = 'djangocfg-ai-chat-mode';
9
13
 
@@ -1,11 +1,15 @@
1
1
  'use client';
2
2
 
3
- import React, { createContext, useContext, useState, useCallback, useMemo, useEffect, useRef, type ReactNode } from 'react';
4
- import { useLocalStorage, useIsMobile } from '@djangocfg/ui-nextjs/hooks';
3
+ import React, {
4
+ createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState
5
+ } from 'react';
5
6
  import { v4 as uuidv4 } from 'uuid';
6
- import type { AIChatMessage, ChatApiResponse, AIChatSource, ChatWidgetConfig, ChatDisplayMode } from '../types';
7
+
8
+ import { useIsMobile, useLocalStorage } from '@djangocfg/ui-nextjs/hooks';
9
+
7
10
  import { storageKeys } from '../config';
8
11
 
12
+ import type { AIChatMessage, ChatApiResponse, AIChatSource, ChatWidgetConfig, ChatDisplayMode } from '../types';
9
13
  const MAX_STORED_MESSAGES = 50;
10
14
 
11
15
  function generateMessageId(): string {
@@ -1,7 +1,10 @@
1
1
  'use client';
2
2
 
3
- import { useState, useCallback, useRef, useEffect } from 'react';
4
- import { mcpEndpoints, type AIChatMessage, type AIChatSource, type UseAIChatOptions, type UseAIChatReturn } from '../types';
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
+
5
+ import {
6
+ type AIChatMessage, type AIChatSource, mcpEndpoints, type UseAIChatOptions, type UseAIChatReturn
7
+ } from '../types';
5
8
 
6
9
  function generateId(): string {
7
10
  return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
@@ -1,10 +1,12 @@
1
1
  'use client';
2
2
 
3
- import { useEffect, useCallback, useRef, useState } from 'react';
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
+
4
5
  import { useLocalStorage } from '@djangocfg/ui-nextjs/hooks';
5
- import type { ChatDisplayMode } from '../types';
6
- import { sidebarConfig, fabConfig, storageKeys } from '../config';
7
6
 
7
+ import { fabConfig, sidebarConfig, storageKeys } from '../config';
8
+
9
+ import type { ChatDisplayMode } from '../types';
8
10
  // Re-export for convenience
9
11
  export const MIN_SIDEBAR_WIDTH = sidebarConfig.minWidth;
10
12
  export const MAX_SIDEBAR_WIDTH = sidebarConfig.maxWidth;
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useCallback } from 'react';
4
+
4
5
  import type { McpChatEventDetail, UseMcpChatReturn } from '../types';
5
6
 
6
7
  /**
@@ -11,16 +11,17 @@
11
11
  * Auto-resets after 3 days (configurable)
12
12
  */
13
13
 
14
- import React, { useState, useEffect } from 'react';
15
- import { Share, X, ChevronRight, Download } from 'lucide-react';
14
+ import { ChevronRight, Download, Share, X } from 'lucide-react';
15
+ import React, { useEffect, useState } from 'react';
16
+
16
17
  import { Button } from '@djangocfg/ui-nextjs';
17
18
  import { cn } from '@djangocfg/ui-nextjs/lib';
18
19
 
19
20
  import { useInstall } from '../context/InstallContext';
20
- import { IOSGuide } from './IOSGuide';
21
- import { DesktopGuide } from './DesktopGuide';
21
+ import { isA2HSDismissedRecently, markA2HSDismissed } from '../utils/localStorage';
22
22
  import { pwaLogger } from '../utils/logger';
23
- import { markA2HSDismissed, isA2HSDismissedRecently } from '../utils/localStorage';
23
+ import { DesktopGuide } from './DesktopGuide';
24
+ import { IOSGuide } from './IOSGuide';
24
25
 
25
26
  const DEFAULT_RESET_DAYS = 3;
26
27
 
@@ -8,24 +8,17 @@
8
8
  * Supports: Chrome, Edge, Brave, Arc, Vivaldi, Opera, Yandex, Firefox, Safari
9
9
  */
10
10
 
11
+ import { ArrowDownToLine, Check, Menu, Monitor, Plus, Search } from 'lucide-react';
11
12
  import React, { useMemo } from 'react';
12
- import { Monitor, Check, ArrowDownToLine, Menu, Search, Plus } from 'lucide-react';
13
13
 
14
14
  import {
15
- Dialog,
16
- DialogContent,
17
- DialogDescription,
18
- DialogFooter,
19
- DialogHeader,
20
- DialogTitle,
21
- Button,
22
- Card,
23
- CardContent,
15
+ Button, Card, CardContent, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader,
16
+ DialogTitle
24
17
  } from '@djangocfg/ui-nextjs';
25
18
 
26
- import type { IOSGuideModalProps, InstallStep } from '../types';
27
19
  import { useInstall } from '../context/InstallContext';
28
20
 
21
+ import type { IOSGuideModalProps, InstallStep } from '../types';
29
22
  type BrowserCategory = 'chromium' | 'firefox' | 'safari' | 'unknown';
30
23
 
31
24
  function getBrowserCategory(browser: {
@@ -12,8 +12,8 @@ import React from 'react';
12
12
 
13
13
  import { useIsMobile } from '@djangocfg/ui-nextjs/hooks';
14
14
 
15
- import { IOSGuideModal } from './IOSGuideModal';
16
15
  import { IOSGuideDrawer } from './IOSGuideDrawer';
16
+ import { IOSGuideModal } from './IOSGuideModal';
17
17
 
18
18
  import type { IOSGuideModalProps } from '../types';
19
19
 
@@ -7,18 +7,11 @@
7
7
  * Better UX for mobile devices
8
8
  */
9
9
 
10
+ import { ArrowDown, ArrowUpRight, Check, CheckCircle, Share } from 'lucide-react';
10
11
  import React from 'react';
11
- import { Share, Check, ArrowUpRight, ArrowDown, CheckCircle } from 'lucide-react';
12
12
 
13
13
  import {
14
- Drawer,
15
- DrawerContent,
16
- DrawerDescription,
17
- DrawerHeader,
18
- DrawerTitle,
19
- Button,
20
- Card,
21
- CardContent,
14
+ Button, Card, CardContent, Drawer, DrawerContent, DrawerDescription, DrawerHeader, DrawerTitle
22
15
  } from '@djangocfg/ui-nextjs';
23
16
 
24
17
  import type { IOSGuideModalProps, InstallStep } from '../types';
@@ -6,19 +6,12 @@
6
6
  * Visual step-by-step guide for adding PWA to home screen on iOS Safari
7
7
  */
8
8
 
9
+ import { ArrowDown, ArrowUpRight, Check, CheckCircle, Share } from 'lucide-react';
9
10
  import React from 'react';
10
- import { Share, Check, ArrowUpRight, ArrowDown, CheckCircle } from 'lucide-react';
11
11
 
12
12
  import {
13
- Dialog,
14
- DialogContent,
15
- DialogDescription,
16
- DialogFooter,
17
- DialogHeader,
18
- DialogTitle,
19
- Button,
20
- Card,
21
- CardContent,
13
+ Button, Card, CardContent, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader,
14
+ DialogTitle
22
15
  } from '@djangocfg/ui-nextjs';
23
16
 
24
17
  import type { IOSGuideModalProps, InstallStep } from '../types';
@@ -7,11 +7,11 @@
7
7
  * No tracking, no metrics, no engagement — just install state
8
8
  */
9
9
 
10
- import React, { createContext, useContext, ReactNode } from 'react';
10
+ import React, { createContext, ReactNode, useContext } from 'react';
11
11
 
12
- import type { InstallOutcome } from '../types';
13
12
  import { useInstallPrompt } from '../hooks/useInstallPrompt';
14
13
 
14
+ import type { InstallOutcome } from '../types';
15
15
  export interface PwaContextValue {
16
16
  // Platform
17
17
  isIOS: boolean;
@@ -8,13 +8,14 @@
8
8
  */
9
9
 
10
10
  import { useEffect, useState } from 'react';
11
+
11
12
  import { useBrowserDetect, useDeviceDetect } from '@djangocfg/ui-nextjs';
12
13
 
13
- import type { BeforeInstallPromptEvent, InstallPromptState, InstallOutcome } from '../types';
14
14
  import { markAppInstalled } from '../utils/localStorage';
15
- import { isStandalone, onDisplayModeChange } from '../utils/platform';
16
15
  import { pwaLogger } from '../utils/logger';
16
+ import { isStandalone, onDisplayModeChange } from '../utils/platform';
17
17
 
18
+ import type { BeforeInstallPromptEvent, InstallPromptState, InstallOutcome } from '../types';
18
19
  export function useInstallPrompt() {
19
20
  const browser = useBrowserDetect();
20
21
  const device = useDeviceDetect();
@@ -16,7 +16,8 @@
16
16
  * ```
17
17
  */
18
18
 
19
- import { useState, useEffect } from 'react';
19
+ import { useEffect, useState } from 'react';
20
+
20
21
  import { isStandalone, isStandaloneReliable, onDisplayModeChange } from '../utils/platform';
21
22
 
22
23
  const CACHE_KEY = 'pwa_is_standalone';
@@ -7,14 +7,16 @@
7
7
  * Auto-dismisses after user action or timeout
8
8
  */
9
9
 
10
- import React, { useState, useEffect } from 'react';
11
10
  import { Bell, X } from 'lucide-react';
11
+ import React, { useEffect, useState } from 'react';
12
+
12
13
  import { Button } from '@djangocfg/ui-nextjs';
13
14
 
14
15
  import { usePushNotifications } from '../hooks/usePushNotifications';
15
- import { isStandalone } from '../utils/platform';
16
+ import { isPushDismissedRecently, markPushDismissed } from '../utils/localStorage';
16
17
  import { pwaLogger } from '../utils/logger';
17
- import { markPushDismissed, isPushDismissedRecently } from '../utils/localStorage';
18
+ import { isStandalone } from '../utils/platform';
19
+
18
20
  import type { PushNotificationOptions } from '../types';
19
21
 
20
22
  const DEFAULT_RESET_DAYS = 7;
@@ -23,9 +23,11 @@
23
23
  * ```
24
24
  */
25
25
 
26
- import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
26
+ import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
27
+
27
28
  import { useDjangoPush } from '../hooks/useDjangoPush';
28
29
  import { pwaLogger } from '../utils/logger';
30
+
29
31
  import type { PushNotificationOptions } from '../types';
30
32
 
31
33
  export interface PushMessage {
@@ -29,20 +29,21 @@
29
29
  * ```
30
30
  */
31
31
 
32
- import { useState, useCallback } from 'react';
32
+ import { useCallback, useState } from 'react';
33
33
  import { toast } from 'sonner';
34
- import { usePushNotifications } from './usePushNotifications';
35
- import { pwaLogger } from '../utils/logger';
36
- import type { PushNotificationOptions } from '../types';
37
34
 
38
35
  // Auth
39
36
  import { useAuth } from '@djangocfg/api/auth';
40
- import { useAuthDialog } from '../../AuthDialog';
41
-
42
37
  // Import Django API client
43
38
  // @ts-ignore - optional peer dependency
44
39
  import { apiWebPush } from '@djangocfg/api/clients';
45
40
 
41
+ import { useAuthDialog } from '../../AuthDialog';
42
+ import { pwaLogger } from '../utils/logger';
43
+ import { usePushNotifications } from './usePushNotifications';
44
+
45
+ import type { PushNotificationOptions } from '../types';
46
+
46
47
  interface UseDjangoPushOptions extends PushNotificationOptions {
47
48
  /**
48
49
  * Callback when subscription created
@@ -7,11 +7,12 @@
7
7
  * Integrates with @djangocfg/nextjs/pwa
8
8
  */
9
9
 
10
- import { useState, useEffect } from 'react';
11
- import type { PushNotificationState, PushNotificationOptions } from '../types';
10
+ import { useEffect, useState } from 'react';
11
+
12
12
  import { pwaLogger } from '../utils/logger';
13
13
  import { urlBase64ToUint8Array, VapidKeyError } from '../utils/vapid';
14
14
 
15
+ import type { PushNotificationState, PushNotificationOptions } from '../types';
15
16
  export function usePushNotifications(options?: PushNotificationOptions) {
16
17
  const [state, setState] = useState<PushNotificationState>({
17
18
  isSupported: false,