@djangocfg/layouts 2.1.37 → 2.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +204 -18
  2. package/package.json +5 -5
  3. package/src/components/errors/index.ts +9 -0
  4. package/src/components/errors/types.ts +38 -0
  5. package/src/layouts/AppLayout/AppLayout.tsx +33 -45
  6. package/src/layouts/AppLayout/BaseApp.tsx +104 -33
  7. package/src/layouts/AuthLayout/AuthContext.tsx +7 -1
  8. package/src/layouts/AuthLayout/OAuthProviders.tsx +1 -10
  9. package/src/layouts/AuthLayout/OTPForm.tsx +1 -0
  10. package/src/layouts/PrivateLayout/PrivateLayout.tsx +1 -1
  11. package/src/layouts/PublicLayout/PublicLayout.tsx +1 -1
  12. package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +1 -1
  13. package/src/layouts/PublicLayout/components/PublicNavigation.tsx +1 -1
  14. package/src/layouts/_components/UserMenu.tsx +1 -1
  15. package/src/layouts/index.ts +1 -1
  16. package/src/layouts/types/index.ts +47 -0
  17. package/src/layouts/types/layout.types.ts +61 -0
  18. package/src/layouts/types/providers.types.ts +65 -0
  19. package/src/layouts/types/ui.types.ts +103 -0
  20. package/src/snippets/Analytics/index.ts +1 -0
  21. package/src/snippets/Analytics/types.ts +10 -0
  22. package/src/snippets/PWAInstall/@docs/README.md +92 -0
  23. package/src/snippets/PWAInstall/README.md +185 -0
  24. package/src/snippets/{PWA → PWAInstall}/components/A2HSHint.tsx +85 -84
  25. package/src/snippets/PWAInstall/components/DesktopGuide.tsx +229 -0
  26. package/src/snippets/PWAInstall/context/InstallContext.tsx +102 -0
  27. package/src/snippets/{PWA → PWAInstall}/hooks/useInstallPrompt.ts +3 -0
  28. package/src/snippets/{PWA → PWAInstall}/index.ts +12 -31
  29. package/src/snippets/{PWA → PWAInstall}/types/components.ts +0 -6
  30. package/src/snippets/PWAInstall/types/config.ts +22 -0
  31. package/src/snippets/{PWA → PWAInstall}/types/index.ts +4 -4
  32. package/src/snippets/{PWA → PWAInstall}/utils/localStorage.ts +1 -23
  33. package/src/snippets/PushNotifications/@docs/README.md +191 -0
  34. package/src/snippets/PushNotifications/@docs/guides/django-integration.md +648 -0
  35. package/src/snippets/PushNotifications/@docs/guides/service-worker.md +467 -0
  36. package/src/snippets/PushNotifications/@docs/guides/vapid-setup.md +352 -0
  37. package/src/snippets/PushNotifications/README.md +328 -0
  38. package/src/snippets/{PWA → PushNotifications}/config.ts +2 -2
  39. package/src/snippets/PushNotifications/context/DjangoPushContext.tsx +190 -0
  40. package/src/snippets/{PWA → PushNotifications}/hooks/useDjangoPush.ts +63 -81
  41. package/src/snippets/{PWA → PushNotifications}/hooks/usePushNotifications.ts +12 -8
  42. package/src/snippets/PushNotifications/index.ts +87 -0
  43. package/src/snippets/PushNotifications/types/config.ts +28 -0
  44. package/src/snippets/PushNotifications/types/index.ts +9 -0
  45. package/src/snippets/PushNotifications/utils/localStorage.ts +60 -0
  46. package/src/snippets/PushNotifications/utils/logger.ts +149 -0
  47. package/src/snippets/PushNotifications/utils/platform.ts +151 -0
  48. package/src/snippets/index.ts +37 -12
  49. package/src/layouts/shared/index.ts +0 -21
  50. package/src/layouts/shared/types.ts +0 -247
  51. package/src/snippets/PWA/@refactoring/ARCHITECTURE_ANALYSIS.md +0 -1179
  52. package/src/snippets/PWA/@refactoring/EXECUTIVE_SUMMARY.md +0 -271
  53. package/src/snippets/PWA/@refactoring/README.md +0 -204
  54. package/src/snippets/PWA/@refactoring/REFACTORING_PROPOSALS.md +0 -1109
  55. package/src/snippets/PWA/@refactoring2/COMPARISON-WITH-NEXTJS.md +0 -718
  56. package/src/snippets/PWA/@refactoring2/P1-FIXES-COMPLETED.md +0 -188
  57. package/src/snippets/PWA/@refactoring2/POST-P0-ANALYSIS.md +0 -362
  58. package/src/snippets/PWA/@refactoring2/README.md +0 -85
  59. package/src/snippets/PWA/@refactoring2/RECOMMENDATIONS.md +0 -1321
  60. package/src/snippets/PWA/@refactoring2/REMAINING-ISSUES.md +0 -557
  61. package/src/snippets/PWA/README.md +0 -387
  62. package/src/snippets/PWA/context/DjangoPushContext.tsx +0 -105
  63. package/src/snippets/PWA/context/InstallContext.tsx +0 -118
  64. package/src/snippets/PWA/context/PushContext.tsx +0 -156
  65. /package/src/layouts/{shared → types}/README.md +0 -0
  66. /package/src/snippets/{PWA/@docs/research.md → PWAInstall/@docs/research/ios-android-install-flows.md} +0 -0
  67. /package/src/snippets/{PWA → PWAInstall}/components/IOSGuide.tsx +0 -0
  68. /package/src/snippets/{PWA → PWAInstall}/components/IOSGuideDrawer.tsx +0 -0
  69. /package/src/snippets/{PWA → PWAInstall}/components/IOSGuideModal.tsx +0 -0
  70. /package/src/snippets/{PWA → PWAInstall}/hooks/useIsPWA.ts +0 -0
  71. /package/src/snippets/{PWA → PWAInstall}/types/install.ts +0 -0
  72. /package/src/snippets/{PWA → PWAInstall}/types/platform.ts +0 -0
  73. /package/src/snippets/{PWA → PWAInstall}/utils/logger.ts +0 -0
  74. /package/src/snippets/{PWA → PWAInstall}/utils/platform.ts +0 -0
  75. /package/src/snippets/{PWA → PushNotifications}/components/PushPrompt.tsx +0 -0
  76. /package/src/snippets/{PWA → PushNotifications}/types/push.ts +0 -0
  77. /package/src/snippets/{PWA → PushNotifications}/utils/vapid.ts +0 -0
@@ -1,156 +0,0 @@
1
- 'use client';
2
-
3
- import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
4
- import { usePushNotifications } from '../hooks/usePushNotifications';
5
- import { pwaLogger } from '../utils/logger';
6
- import type { PushNotificationOptions } from '../types';
7
-
8
- const ICON_URL = 'https://djangocfg.com/static/logos/192x192.png';
9
-
10
- export interface PushMessage {
11
- id: string;
12
- title: string;
13
- body: string;
14
- icon?: string;
15
- badge?: string;
16
- tag?: string;
17
- timestamp: number;
18
- data?: Record<string, unknown>;
19
- }
20
-
21
- export interface PushContextValue {
22
- // Push state
23
- isSupported: boolean;
24
- permission: NotificationPermission;
25
- isSubscribed: boolean;
26
- subscription: PushSubscription | null;
27
-
28
- // Accumulated pushes
29
- pushes: PushMessage[];
30
-
31
- // Actions
32
- subscribe: () => Promise<boolean>;
33
- unsubscribe: () => Promise<boolean>;
34
- sendPush: (message: Omit<PushMessage, 'id' | 'timestamp'>) => Promise<void>;
35
- clearPushes: () => void;
36
- removePush: (id: string) => void;
37
- }
38
-
39
- const PushContext = createContext<PushContextValue | undefined>(undefined);
40
-
41
- interface PushProviderProps {
42
- children: React.ReactNode;
43
- vapidPublicKey?: string;
44
- subscribeEndpoint?: string;
45
- sendEndpoint?: string;
46
- onPushReceived?: (push: PushMessage) => void;
47
- }
48
-
49
- export function PushProvider({
50
- children,
51
- vapidPublicKey = '',
52
- subscribeEndpoint = '/api/push/subscribe',
53
- sendEndpoint = '/api/push/send',
54
- onPushReceived,
55
- }: PushProviderProps) {
56
- const pushNotifications = usePushNotifications({
57
- vapidPublicKey,
58
- subscribeEndpoint,
59
- });
60
-
61
- const [pushes, setPushes] = useState<PushMessage[]>([]);
62
-
63
- // Listen for push messages from service worker
64
- useEffect(() => {
65
- if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {
66
- return;
67
- }
68
-
69
- const handleMessage = (event: MessageEvent) => {
70
- if (event.data && event.data.type === 'PUSH_RECEIVED') {
71
- const push: PushMessage = {
72
- id: crypto.randomUUID(),
73
- timestamp: Date.now(),
74
- ...event.data.notification,
75
- };
76
-
77
- setPushes(prev => [push, ...prev]);
78
- onPushReceived?.(push);
79
- }
80
- };
81
-
82
- navigator.serviceWorker.addEventListener('message', handleMessage);
83
-
84
- return () => {
85
- navigator.serviceWorker.removeEventListener('message', handleMessage);
86
- };
87
- }, [onPushReceived]);
88
-
89
- const sendPush = useCallback(async (message: Omit<PushMessage, 'id' | 'timestamp'>) => {
90
- if (!pushNotifications.isSubscribed) {
91
- throw new Error('Not subscribed to push notifications');
92
- }
93
-
94
- // In real app, this calls your backend API to send actual push
95
- try {
96
- // Send to server
97
- await fetch(sendEndpoint, {
98
- method: 'POST',
99
- headers: { 'Content-Type': 'application/json' },
100
- body: JSON.stringify({
101
- subscription: pushNotifications.subscription,
102
- notification: message,
103
- }),
104
- });
105
-
106
- // Optimistic update for UI
107
- const push: PushMessage = {
108
- ...message,
109
- id: crypto.randomUUID(),
110
- timestamp: Date.now(),
111
- };
112
-
113
- setPushes(prev => [push, ...prev]);
114
- } catch (error) {
115
- pwaLogger.error('[PushContext] Failed to send push:', error);
116
- throw error;
117
- }
118
- }, [pushNotifications.isSubscribed, pushNotifications.subscription, sendEndpoint]);
119
-
120
- const clearPushes = useCallback(() => {
121
- setPushes([]);
122
- }, []);
123
-
124
- const removePush = useCallback((id: string) => {
125
- setPushes(prev => prev.filter(p => p.id !== id));
126
- }, []);
127
-
128
- const value: PushContextValue = {
129
- isSupported: pushNotifications.isSupported,
130
- permission: pushNotifications.permission,
131
- isSubscribed: pushNotifications.isSubscribed,
132
- subscription: pushNotifications.subscription,
133
- pushes,
134
- subscribe: pushNotifications.subscribe,
135
- unsubscribe: pushNotifications.unsubscribe,
136
- sendPush,
137
- clearPushes,
138
- removePush,
139
- };
140
-
141
- return <PushContext.Provider value={value}>{children}</PushContext.Provider>;
142
- }
143
-
144
- /**
145
- * Use push notifications context
146
- * Must be used within <PushProvider>
147
- */
148
- export function usePush(): PushContextValue {
149
- const context = useContext(PushContext);
150
-
151
- if (context === undefined) {
152
- throw new Error('usePush must be used within <PushProvider>');
153
- }
154
-
155
- return context;
156
- }
File without changes