@djangocfg/layouts 2.1.35 → 2.1.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/layouts/AppLayout/BaseApp.tsx +31 -25
- package/src/layouts/shared/types.ts +36 -0
- package/src/snippets/McpChat/context/ChatContext.tsx +9 -0
- package/src/snippets/PWA/@docs/research.md +576 -0
- package/src/snippets/PWA/@refactoring/ARCHITECTURE_ANALYSIS.md +1179 -0
- package/src/snippets/PWA/@refactoring/EXECUTIVE_SUMMARY.md +271 -0
- package/src/snippets/PWA/@refactoring/README.md +204 -0
- package/src/snippets/PWA/@refactoring/REFACTORING_PROPOSALS.md +1109 -0
- package/src/snippets/PWA/@refactoring2/COMPARISON-WITH-NEXTJS.md +718 -0
- package/src/snippets/PWA/@refactoring2/P1-FIXES-COMPLETED.md +188 -0
- package/src/snippets/PWA/@refactoring2/POST-P0-ANALYSIS.md +362 -0
- package/src/snippets/PWA/@refactoring2/README.md +85 -0
- package/src/snippets/PWA/@refactoring2/RECOMMENDATIONS.md +1321 -0
- package/src/snippets/PWA/@refactoring2/REMAINING-ISSUES.md +557 -0
- package/src/snippets/PWA/README.md +387 -0
- package/src/snippets/PWA/components/A2HSHint.tsx +226 -0
- package/src/snippets/PWA/components/IOSGuide.tsx +29 -0
- package/src/snippets/PWA/components/IOSGuideDrawer.tsx +101 -0
- package/src/snippets/PWA/components/IOSGuideModal.tsx +101 -0
- package/src/snippets/PWA/components/PushPrompt.tsx +165 -0
- package/src/snippets/PWA/config.ts +20 -0
- package/src/snippets/PWA/context/DjangoPushContext.tsx +105 -0
- package/src/snippets/PWA/context/InstallContext.tsx +118 -0
- package/src/snippets/PWA/context/PushContext.tsx +156 -0
- package/src/snippets/PWA/hooks/useDjangoPush.ts +277 -0
- package/src/snippets/PWA/hooks/useInstallPrompt.ts +164 -0
- package/src/snippets/PWA/hooks/useIsPWA.ts +115 -0
- package/src/snippets/PWA/hooks/usePushNotifications.ts +205 -0
- package/src/snippets/PWA/index.ts +95 -0
- package/src/snippets/PWA/types/components.ts +101 -0
- package/src/snippets/PWA/types/index.ts +26 -0
- package/src/snippets/PWA/types/install.ts +38 -0
- package/src/snippets/PWA/types/platform.ts +29 -0
- package/src/snippets/PWA/types/push.ts +21 -0
- package/src/snippets/PWA/utils/localStorage.ts +203 -0
- package/src/snippets/PWA/utils/logger.ts +149 -0
- package/src/snippets/PWA/utils/platform.ts +151 -0
- package/src/snippets/PWA/utils/vapid.ts +226 -0
- package/src/snippets/index.ts +30 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/layouts",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.37",
|
|
4
4
|
"description": "Simple, straightforward layout components for Next.js - import and use with props",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"layouts",
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
"check": "tsc --noEmit"
|
|
93
93
|
},
|
|
94
94
|
"peerDependencies": {
|
|
95
|
-
"@djangocfg/api": "^2.1.
|
|
96
|
-
"@djangocfg/centrifugo": "^2.1.
|
|
97
|
-
"@djangocfg/ui-nextjs": "^2.1.
|
|
95
|
+
"@djangocfg/api": "^2.1.37",
|
|
96
|
+
"@djangocfg/centrifugo": "^2.1.37",
|
|
97
|
+
"@djangocfg/ui-nextjs": "^2.1.37",
|
|
98
98
|
"@hookform/resolvers": "^5.2.0",
|
|
99
99
|
"consola": "^3.4.2",
|
|
100
100
|
"lucide-react": "^0.545.0",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"uuid": "^11.1.0"
|
|
115
115
|
},
|
|
116
116
|
"devDependencies": {
|
|
117
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
117
|
+
"@djangocfg/typescript-config": "^2.1.37",
|
|
118
118
|
"@types/node": "^24.7.2",
|
|
119
119
|
"@types/react": "^19.1.0",
|
|
120
120
|
"@types/react-dom": "^19.1.0",
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - TooltipProvider (tooltip positioning)
|
|
7
7
|
* - SWRConfig (data fetching)
|
|
8
8
|
* - AuthProvider (authentication context)
|
|
9
|
+
* - PwaProvider (PWA context, optional)
|
|
9
10
|
* - ErrorTrackingProvider (error handling)
|
|
10
11
|
* - ErrorBoundary (React error boundary, enabled by default)
|
|
11
12
|
* - MCP Chat Widget (optional, lazy loaded)
|
|
@@ -14,10 +15,11 @@
|
|
|
14
15
|
* ```tsx
|
|
15
16
|
* import { BaseApp } from '@djangocfg/layouts';
|
|
16
17
|
*
|
|
17
|
-
* // With MCP Chat enabled
|
|
18
|
+
* // With PWA and MCP Chat enabled
|
|
18
19
|
* <BaseApp
|
|
19
20
|
* theme={{ defaultTheme: 'system' }}
|
|
20
21
|
* auth={{ loginPath: '/auth/login' }}
|
|
22
|
+
* pwa={{ enabled: true }}
|
|
21
23
|
* mcpChat={{ enabled: true, autoDetectEnvironment: true }}
|
|
22
24
|
* >
|
|
23
25
|
* {children}
|
|
@@ -40,6 +42,7 @@ import { AuthProvider } from '@djangocfg/api/auth';
|
|
|
40
42
|
import { ErrorTrackingProvider } from '../../components/errors/ErrorsTracker';
|
|
41
43
|
import { ErrorBoundary } from '../../components/errors/ErrorBoundary';
|
|
42
44
|
import { PageProgress } from '../../components/core/PageProgress';
|
|
45
|
+
import { PwaProvider } from '../../snippets/PWA';
|
|
43
46
|
import type { BaseLayoutProps } from '../shared/types';
|
|
44
47
|
|
|
45
48
|
// Lazy load MCP Chat Widget with dynamic import
|
|
@@ -65,6 +68,7 @@ export function BaseApp({
|
|
|
65
68
|
errorBoundary,
|
|
66
69
|
swr,
|
|
67
70
|
mcpChat,
|
|
71
|
+
pwa,
|
|
68
72
|
}: BaseAppProps) {
|
|
69
73
|
// ErrorBoundary is enabled by default
|
|
70
74
|
const enableErrorBoundary = errorBoundary?.enabled !== false;
|
|
@@ -83,31 +87,33 @@ export function BaseApp({
|
|
|
83
87
|
}}
|
|
84
88
|
>
|
|
85
89
|
<AuthProvider config={auth}>
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
<PwaProvider {...pwa}>
|
|
91
|
+
<ErrorTrackingProvider
|
|
92
|
+
validation={errorTracking?.validation}
|
|
93
|
+
cors={errorTracking?.cors}
|
|
94
|
+
network={errorTracking?.network}
|
|
95
|
+
onError={errorTracking?.onError}
|
|
96
|
+
>
|
|
97
|
+
{children}
|
|
98
|
+
<PageProgress />
|
|
99
|
+
<Toaster />
|
|
95
100
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
101
|
+
{/* MCP Chat Widget - lazy loaded */}
|
|
102
|
+
{mcpChat?.enabled && (
|
|
103
|
+
<AIChatWidget
|
|
104
|
+
apiEndpoint={mcpChat.apiEndpoint}
|
|
105
|
+
title={mcpChat.title}
|
|
106
|
+
placeholder={mcpChat.placeholder}
|
|
107
|
+
greeting={mcpChat.greeting}
|
|
108
|
+
position={mcpChat.position}
|
|
109
|
+
variant={mcpChat.variant}
|
|
110
|
+
enableStreaming={mcpChat.enableStreaming}
|
|
111
|
+
autoDetectEnvironment={mcpChat.autoDetectEnvironment}
|
|
112
|
+
className={mcpChat.className}
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
115
|
+
</ErrorTrackingProvider>
|
|
116
|
+
</PwaProvider>
|
|
111
117
|
</AuthProvider>
|
|
112
118
|
</SWRConfig>
|
|
113
119
|
</TooltipProvider>
|
|
@@ -88,6 +88,39 @@ export interface McpChatConfig {
|
|
|
88
88
|
className?: string;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
// ============================================================================
|
|
92
|
+
// PWA Configuration
|
|
93
|
+
// ============================================================================
|
|
94
|
+
|
|
95
|
+
export interface PwaConfig {
|
|
96
|
+
/** Enable PWA provider and features */
|
|
97
|
+
enabled?: boolean;
|
|
98
|
+
|
|
99
|
+
/** Show A2HS hint (enabled by default when pwa.enabled is true) */
|
|
100
|
+
showInstallHint?: boolean;
|
|
101
|
+
|
|
102
|
+
/** Number of days before re-showing dismissed hint */
|
|
103
|
+
resetAfterDays?: number | null;
|
|
104
|
+
|
|
105
|
+
/** Delay before showing hint (ms) */
|
|
106
|
+
delayMs?: number;
|
|
107
|
+
|
|
108
|
+
/** App logo URL to display in hint */
|
|
109
|
+
logo?: string;
|
|
110
|
+
|
|
111
|
+
/** Push notifications configuration */
|
|
112
|
+
pushNotifications?: {
|
|
113
|
+
/** VAPID public key for push notifications */
|
|
114
|
+
vapidPublicKey: string;
|
|
115
|
+
/** API endpoint for subscription */
|
|
116
|
+
subscribeEndpoint?: string;
|
|
117
|
+
/** Delay before showing push prompt after PWA install (ms) */
|
|
118
|
+
delayMs?: number;
|
|
119
|
+
/** Number of days before re-showing dismissed push prompt */
|
|
120
|
+
resetAfterDays?: number;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
91
124
|
// ============================================================================
|
|
92
125
|
// Base Layout Props
|
|
93
126
|
// ============================================================================
|
|
@@ -112,6 +145,9 @@ export interface BaseLayoutProps {
|
|
|
112
145
|
|
|
113
146
|
/** MCP chat configuration */
|
|
114
147
|
mcpChat?: McpChatConfig;
|
|
148
|
+
|
|
149
|
+
/** PWA configuration */
|
|
150
|
+
pwa?: PwaConfig;
|
|
115
151
|
}
|
|
116
152
|
|
|
117
153
|
// ============================================================================
|
|
@@ -98,6 +98,7 @@ export function ChatProvider({
|
|
|
98
98
|
const [error, setError] = useState<Error | null>(null);
|
|
99
99
|
const [isMinimized, setIsMinimized] = useState(false);
|
|
100
100
|
const isHydratedRef = useRef(false);
|
|
101
|
+
const mobileResetRef = useRef(false);
|
|
101
102
|
|
|
102
103
|
// Display mode with localStorage persistence
|
|
103
104
|
const [storedMode, setStoredMode] = useLocalStorage<ChatDisplayMode>(storageKeys.mode, 'closed');
|
|
@@ -110,6 +111,14 @@ export function ChatProvider({
|
|
|
110
111
|
|
|
111
112
|
const isMobile = useIsMobile();
|
|
112
113
|
|
|
114
|
+
// On mobile, always start closed on page load (don't restore state)
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (isMobile && !mobileResetRef.current && storedMode !== 'closed') {
|
|
117
|
+
mobileResetRef.current = true;
|
|
118
|
+
setStoredMode('closed');
|
|
119
|
+
}
|
|
120
|
+
}, [isMobile, storedMode, setStoredMode]);
|
|
121
|
+
|
|
113
122
|
// Generate user ID if not exists
|
|
114
123
|
useEffect(() => {
|
|
115
124
|
if (!userId) {
|