create-fluxstack 1.7.5 → 1.8.3

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 (154) hide show
  1. package/.dockerignore +82 -0
  2. package/.env.example +19 -0
  3. package/Dockerfile +70 -0
  4. package/README.md +6 -3
  5. package/app/client/SIMPLIFICATION.md +140 -0
  6. package/app/client/frontend-only.ts +1 -1
  7. package/app/client/src/App.tsx +148 -283
  8. package/app/client/src/index.css +5 -20
  9. package/app/client/src/lib/eden-api.ts +53 -220
  10. package/app/client/src/main.tsx +2 -3
  11. package/app/server/app.ts +20 -5
  12. package/app/server/backend-only.ts +15 -12
  13. package/app/server/controllers/users.controller.ts +57 -31
  14. package/app/server/index.ts +86 -96
  15. package/app/server/live/register-components.ts +18 -7
  16. package/app/server/routes/env-test.ts +110 -0
  17. package/app/server/routes/index.ts +1 -8
  18. package/app/server/routes/users.routes.ts +192 -91
  19. package/config/app.config.ts +2 -54
  20. package/config/client.config.ts +95 -0
  21. package/config/fluxstack.config.ts +2 -2
  22. package/config/index.ts +57 -22
  23. package/config/monitoring.config.ts +114 -0
  24. package/config/plugins.config.ts +80 -0
  25. package/config/runtime.config.ts +0 -17
  26. package/config/server.config.ts +50 -30
  27. package/core/build/bundler.ts +17 -16
  28. package/core/build/flux-plugins-generator.ts +34 -23
  29. package/core/build/index.ts +32 -31
  30. package/core/build/live-components-generator.ts +44 -30
  31. package/core/build/optimizer.ts +37 -17
  32. package/core/cli/command-registry.ts +4 -14
  33. package/core/cli/commands/plugin-deps.ts +8 -8
  34. package/core/cli/generators/component.ts +3 -3
  35. package/core/cli/generators/controller.ts +4 -4
  36. package/core/cli/generators/index.ts +8 -8
  37. package/core/cli/generators/interactive.ts +4 -4
  38. package/core/cli/generators/plugin.ts +3 -3
  39. package/core/cli/generators/prompts.ts +1 -1
  40. package/core/cli/generators/route.ts +27 -11
  41. package/core/cli/generators/service.ts +5 -5
  42. package/core/cli/generators/template-engine.ts +1 -1
  43. package/core/cli/generators/types.ts +1 -1
  44. package/core/cli/index.ts +158 -189
  45. package/core/cli/plugin-discovery.ts +3 -3
  46. package/core/client/hooks/index.ts +2 -2
  47. package/core/client/hooks/state-validator.ts +1 -1
  48. package/core/client/hooks/useAuth.ts +1 -1
  49. package/core/client/hooks/useChunkedUpload.ts +1 -1
  50. package/core/client/hooks/useHybridLiveComponent.ts +1 -1
  51. package/core/client/hooks/useWebSocket.ts +1 -1
  52. package/core/config/env.ts +5 -1
  53. package/core/config/runtime-config.ts +12 -10
  54. package/core/config/schema.ts +33 -2
  55. package/core/framework/server.ts +30 -14
  56. package/core/framework/types.ts +2 -2
  57. package/core/index.ts +31 -23
  58. package/core/live/ComponentRegistry.ts +1 -1
  59. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1 -1
  60. package/core/plugins/built-in/live-components/index.ts +1 -1
  61. package/core/plugins/built-in/monitoring/index.ts +65 -161
  62. package/core/plugins/built-in/static/index.ts +75 -277
  63. package/core/plugins/built-in/swagger/index.ts +301 -231
  64. package/core/plugins/built-in/vite/index.ts +342 -377
  65. package/core/plugins/config.ts +2 -2
  66. package/core/plugins/dependency-manager.ts +2 -2
  67. package/core/plugins/discovery.ts +1 -1
  68. package/core/plugins/executor.ts +2 -2
  69. package/core/plugins/manager.ts +19 -4
  70. package/core/plugins/module-resolver.ts +1 -1
  71. package/core/plugins/registry.ts +25 -21
  72. package/core/plugins/types.ts +147 -5
  73. package/core/server/backend-entry.ts +51 -0
  74. package/core/server/framework.ts +2 -2
  75. package/core/server/live/ComponentRegistry.ts +9 -26
  76. package/core/server/live/FileUploadManager.ts +1 -1
  77. package/core/server/live/auto-generated-components.ts +26 -0
  78. package/core/server/live/websocket-plugin.ts +211 -19
  79. package/core/server/middleware/errorHandling.ts +1 -1
  80. package/core/server/middleware/index.ts +4 -4
  81. package/core/server/plugins/database.ts +1 -2
  82. package/core/server/plugins/static-files-plugin.ts +259 -231
  83. package/core/server/plugins/swagger.ts +1 -1
  84. package/core/server/services/BaseService.ts +1 -1
  85. package/core/server/services/ServiceContainer.ts +1 -1
  86. package/core/server/services/index.ts +4 -4
  87. package/core/server/standalone.ts +16 -1
  88. package/core/testing/index.ts +1 -1
  89. package/core/testing/setup.ts +1 -1
  90. package/core/types/plugin.ts +6 -0
  91. package/core/utils/build-logger.ts +324 -0
  92. package/core/utils/config-schema.ts +2 -6
  93. package/core/utils/helpers.ts +14 -9
  94. package/core/utils/logger/startup-banner.ts +7 -33
  95. package/core/utils/regenerate-files.ts +69 -0
  96. package/core/utils/version.ts +6 -6
  97. package/create-fluxstack.ts +68 -25
  98. package/fluxstack.config.ts +138 -252
  99. package/package.json +3 -18
  100. package/plugins/crypto-auth/index.ts +52 -47
  101. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  102. package/plugins/crypto-auth/server/middlewares/helpers.ts +16 -1
  103. package/vitest.config.ts +17 -26
  104. package/app/client/src/App.css +0 -883
  105. package/app/client/src/components/ErrorBoundary.tsx +0 -107
  106. package/app/client/src/components/ErrorDisplay.css +0 -365
  107. package/app/client/src/components/ErrorDisplay.tsx +0 -258
  108. package/app/client/src/components/FluxStackConfig.tsx +0 -1321
  109. package/app/client/src/components/HybridLiveCounter.tsx +0 -140
  110. package/app/client/src/components/LiveClock.tsx +0 -286
  111. package/app/client/src/components/MainLayout.tsx +0 -388
  112. package/app/client/src/components/SidebarNavigation.tsx +0 -391
  113. package/app/client/src/components/StateDemo.tsx +0 -178
  114. package/app/client/src/components/SystemMonitor.tsx +0 -1044
  115. package/app/client/src/components/UserProfile.tsx +0 -809
  116. package/app/client/src/hooks/useAuth.ts +0 -39
  117. package/app/client/src/hooks/useNotifications.ts +0 -56
  118. package/app/client/src/lib/errors.ts +0 -340
  119. package/app/client/src/lib/hooks/useErrorHandler.ts +0 -258
  120. package/app/client/src/lib/index.ts +0 -45
  121. package/app/client/src/pages/ApiDocs.tsx +0 -182
  122. package/app/client/src/pages/CryptoAuthPage.tsx +0 -394
  123. package/app/client/src/pages/Demo.tsx +0 -174
  124. package/app/client/src/pages/HybridLive.tsx +0 -263
  125. package/app/client/src/pages/Overview.tsx +0 -155
  126. package/app/client/src/store/README.md +0 -43
  127. package/app/client/src/store/index.ts +0 -16
  128. package/app/client/src/store/slices/uiSlice.ts +0 -151
  129. package/app/client/src/store/slices/userSlice.ts +0 -161
  130. package/app/client/src/test/README.md +0 -257
  131. package/app/client/src/test/setup.ts +0 -70
  132. package/app/client/src/test/types.ts +0 -12
  133. package/app/server/live/CounterComponent.ts +0 -191
  134. package/app/server/live/FluxStackConfig.ts +0 -534
  135. package/app/server/live/SidebarNavigation.ts +0 -157
  136. package/app/server/live/SystemMonitor.ts +0 -595
  137. package/app/server/live/SystemMonitorIntegration.ts +0 -151
  138. package/app/server/live/UserProfileComponent.ts +0 -141
  139. package/app/server/middleware/auth.ts +0 -136
  140. package/app/server/middleware/errorHandling.ts +0 -252
  141. package/app/server/middleware/index.ts +0 -10
  142. package/app/server/middleware/rateLimit.ts +0 -193
  143. package/app/server/middleware/requestLogging.ts +0 -215
  144. package/app/server/middleware/validation.ts +0 -270
  145. package/app/server/routes/config.ts +0 -145
  146. package/app/server/routes/crypto-auth-demo.routes.ts +0 -167
  147. package/app/server/routes/example-with-crypto-auth.routes.ts +0 -235
  148. package/app/server/routes/exemplo-posts.routes.ts +0 -161
  149. package/app/server/routes/upload.ts +0 -92
  150. package/app/server/services/NotificationService.ts +0 -302
  151. package/app/server/services/UserService.ts +0 -222
  152. package/app/server/services/index.ts +0 -46
  153. package/app/server/types/index.ts +0 -1
  154. package/config/build.config.ts +0 -24
@@ -1,391 +0,0 @@
1
- // 🔥 Sidebar Navigation Component
2
-
3
- import { useHybridLiveComponent } from '@/core/client'
4
- import {
5
- FaHome,
6
- FaUser,
7
- FaCog,
8
- FaFolder,
9
- FaServer,
10
- FaBars,
11
- FaTimes,
12
- FaMoon,
13
- FaSun,
14
- FaBell,
15
- FaTools
16
- } from 'react-icons/fa'
17
-
18
- export interface SidebarNavigationState {
19
- currentPage: 'dashboard' | 'profile' | 'settings' | 'files' | 'analytics' | 'config'
20
- isCollapsed: boolean
21
- theme: 'light' | 'dark'
22
- notifications: {
23
- profile: number
24
- settings: number
25
- files: number
26
- analytics: number
27
- config: number
28
- }
29
- lastNavigation: number
30
- }
31
-
32
- const initialState: SidebarNavigationState = {
33
- currentPage: 'dashboard',
34
- isCollapsed: false,
35
- theme: 'light',
36
- notifications: {
37
- profile: 0,
38
- settings: 0,
39
- files: 0,
40
- analytics: 0,
41
- config: 0
42
- },
43
- lastNavigation: Date.now()
44
- }
45
-
46
- interface SidebarNavigationProps {
47
- onPageChange: (page: string) => void
48
- }
49
-
50
- export function SidebarNavigation({ onPageChange }: SidebarNavigationProps) {
51
- const { state, call, connected, status, error } = useHybridLiveComponent<SidebarNavigationState>(
52
- 'SidebarNavigation',
53
- initialState,
54
- { debug: true }
55
- )
56
-
57
- // Show loading state
58
- if (!connected || status !== 'synced') {
59
- const getStatusMessage = () => {
60
- switch (status) {
61
- case 'connecting':
62
- return '🔄 Conectando navegação...'
63
- case 'reconnecting':
64
- return '🔄 Reconectando menu...'
65
- case 'mounting':
66
- return '🚀 Carregando menu...'
67
- case 'loading':
68
- return '⏳ Carregando...'
69
- case 'error':
70
- return '❌ Erro na navegação'
71
- default:
72
- return '🔄 Preparando menu...'
73
- }
74
- }
75
-
76
- return (
77
- <div style={{
78
- width: '280px',
79
- height: '100vh',
80
- background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
81
- color: 'white',
82
- padding: '2rem',
83
- display: 'flex',
84
- flexDirection: 'column',
85
- alignItems: 'center',
86
- justifyContent: 'center',
87
- textAlign: 'center'
88
- }}>
89
- <FaBars size={32} style={{ marginBottom: '1rem' }} />
90
- <p>{getStatusMessage()}</p>
91
- {error && (
92
- <p style={{ fontSize: '0.9rem', marginTop: '0.5rem', opacity: 0.8 }}>
93
- {error}
94
- </p>
95
- )}
96
- </div>
97
- )
98
- }
99
-
100
- const isDark = state.theme === 'dark'
101
- const sidebarWidth = state.isCollapsed ? '80px' : '280px'
102
-
103
- const menuItems = [
104
- {
105
- id: 'dashboard',
106
- label: 'Dashboard',
107
- icon: FaHome,
108
- notifications: 0
109
- },
110
- {
111
- id: 'profile',
112
- label: 'Perfil',
113
- icon: FaUser,
114
- notifications: state.notifications.profile
115
- },
116
- {
117
- id: 'settings',
118
- label: 'Configurações',
119
- icon: FaCog,
120
- notifications: state.notifications.settings
121
- },
122
- {
123
- id: 'files',
124
- label: 'Arquivos',
125
- icon: FaFolder,
126
- notifications: state.notifications.files
127
- },
128
- {
129
- id: 'analytics',
130
- label: 'Monitoramento',
131
- icon: FaServer,
132
- notifications: state.notifications.analytics
133
- },
134
- {
135
- id: 'config',
136
- label: 'FluxStack Config',
137
- icon: FaTools,
138
- notifications: state.notifications.config
139
- }
140
- ]
141
-
142
- const handleNavigate = async (page: string) => {
143
- try {
144
- await call('navigateTo', { page })
145
- onPageChange(page)
146
- } catch (error) {
147
- console.error('Navigation error:', error)
148
- }
149
- }
150
-
151
- const handleToggleSidebar = async () => {
152
- try {
153
- await call('toggleSidebar')
154
- } catch (error) {
155
- console.error('Toggle sidebar error:', error)
156
- }
157
- }
158
-
159
- const handleToggleTheme = async () => {
160
- try {
161
- const newTheme = state.theme === 'light' ? 'dark' : 'light'
162
- await call('setTheme', { theme: newTheme })
163
- } catch (error) {
164
- console.error('Theme toggle error:', error)
165
- }
166
- }
167
-
168
- const handleClearNotifications = async () => {
169
- try {
170
- await call('clearAllNotifications')
171
- } catch (error) {
172
- console.error('Clear notifications error:', error)
173
- }
174
- }
175
-
176
- return (
177
- <div style={{
178
- width: sidebarWidth,
179
- height: '100vh',
180
- backgroundColor: isDark ? '#1f2937' : '#ffffff',
181
- borderRight: `1px solid ${isDark ? '#374151' : '#e5e7eb'}`,
182
- display: 'flex',
183
- flexDirection: 'column',
184
- transition: 'width 0.3s ease',
185
- overflow: 'hidden',
186
- boxShadow: '2px 0 10px rgba(0, 0, 0, 0.1)'
187
- }}>
188
- {/* Header */}
189
- <div style={{
190
- padding: '1.5rem',
191
- borderBottom: `1px solid ${isDark ? '#374151' : '#e5e7eb'}`,
192
- display: 'flex',
193
- alignItems: 'center',
194
- justifyContent: 'space-between'
195
- }}>
196
- {!state.isCollapsed && (
197
- <h2 style={{
198
- color: isDark ? '#f9fafb' : '#111827',
199
- margin: 0,
200
- fontSize: '1.25rem',
201
- fontWeight: 'bold'
202
- }}>
203
- 🔥 FluxStack
204
- </h2>
205
- )}
206
-
207
- <button
208
- onClick={handleToggleSidebar}
209
- style={{
210
- background: 'none',
211
- border: 'none',
212
- color: isDark ? '#9ca3af' : '#6b7280',
213
- cursor: 'pointer',
214
- padding: '0.5rem',
215
- borderRadius: '0.5rem',
216
- display: 'flex',
217
- alignItems: 'center',
218
- justifyContent: 'center',
219
- fontSize: '1.1rem'
220
- }}
221
- >
222
- {state.isCollapsed ? <FaBars /> : <FaTimes />}
223
- </button>
224
- </div>
225
-
226
- {/* Navigation Menu */}
227
- <nav style={{
228
- flex: 1,
229
- padding: '1rem',
230
- display: 'flex',
231
- flexDirection: 'column',
232
- gap: '0.5rem'
233
- }}>
234
- {menuItems.map((item) => {
235
- const Icon = item.icon
236
- const isActive = state.currentPage === item.id
237
- const hasNotifications = item.notifications > 0
238
-
239
- return (
240
- <button
241
- key={item.id}
242
- onClick={() => handleNavigate(item.id)}
243
- style={{
244
- display: 'flex',
245
- alignItems: 'center',
246
- gap: '1rem',
247
- padding: '1rem',
248
- borderRadius: '0.75rem',
249
- border: 'none',
250
- cursor: 'pointer',
251
- transition: 'all 0.2s ease',
252
- backgroundColor: isActive
253
- ? (isDark ? '#3b82f6' : '#2563eb')
254
- : 'transparent',
255
- color: isActive
256
- ? '#ffffff'
257
- : (isDark ? '#d1d5db' : '#374151'),
258
- position: 'relative',
259
- justifyContent: state.isCollapsed ? 'center' : 'flex-start',
260
- minHeight: '3rem'
261
- }}
262
- onMouseEnter={(e) => {
263
- if (!isActive) {
264
- e.currentTarget.style.backgroundColor = isDark ? '#374151' : '#f3f4f6'
265
- }
266
- }}
267
- onMouseLeave={(e) => {
268
- if (!isActive) {
269
- e.currentTarget.style.backgroundColor = 'transparent'
270
- }
271
- }}
272
- >
273
- <Icon size={20} />
274
-
275
- {!state.isCollapsed && (
276
- <>
277
- <span style={{
278
- fontSize: '0.95rem',
279
- fontWeight: isActive ? 'bold' : 'normal'
280
- }}>
281
- {item.label}
282
- </span>
283
-
284
- {hasNotifications && (
285
- <span style={{
286
- backgroundColor: '#ef4444',
287
- color: 'white',
288
- borderRadius: '50%',
289
- width: '20px',
290
- height: '20px',
291
- display: 'flex',
292
- alignItems: 'center',
293
- justifyContent: 'center',
294
- fontSize: '0.75rem',
295
- fontWeight: 'bold',
296
- marginLeft: 'auto'
297
- }}>
298
- {item.notifications}
299
- </span>
300
- )}
301
- </>
302
- )}
303
-
304
- {state.isCollapsed && hasNotifications && (
305
- <div style={{
306
- position: 'absolute',
307
- top: '0.5rem',
308
- right: '0.5rem',
309
- backgroundColor: '#ef4444',
310
- borderRadius: '50%',
311
- width: '12px',
312
- height: '12px',
313
- border: '2px solid white'
314
- }} />
315
- )}
316
- </button>
317
- )
318
- })}
319
- </nav>
320
-
321
- {/* Footer Actions */}
322
- <div style={{
323
- padding: '1rem',
324
- borderTop: `1px solid ${isDark ? '#374151' : '#e5e7eb'}`,
325
- display: 'flex',
326
- flexDirection: state.isCollapsed ? 'column' : 'row',
327
- gap: '0.5rem'
328
- }}>
329
- {/* Theme Toggle */}
330
- <button
331
- onClick={handleToggleTheme}
332
- style={{
333
- display: 'flex',
334
- alignItems: 'center',
335
- justifyContent: 'center',
336
- gap: state.isCollapsed ? 0 : '0.5rem',
337
- padding: '0.75rem',
338
- borderRadius: '0.5rem',
339
- border: 'none',
340
- cursor: 'pointer',
341
- backgroundColor: isDark ? '#374151' : '#f3f4f6',
342
- color: isDark ? '#d1d5db' : '#374151',
343
- flex: state.isCollapsed ? 'none' : 1,
344
- fontSize: '0.9rem'
345
- }}
346
- >
347
- {isDark ? <FaSun /> : <FaMoon />}
348
- {!state.isCollapsed && (
349
- <span>{isDark ? 'Claro' : 'Escuro'}</span>
350
- )}
351
- </button>
352
-
353
- {/* Clear Notifications */}
354
- {!state.isCollapsed && (
355
- <button
356
- onClick={handleClearNotifications}
357
- style={{
358
- display: 'flex',
359
- alignItems: 'center',
360
- justifyContent: 'center',
361
- gap: '0.5rem',
362
- padding: '0.75rem',
363
- borderRadius: '0.5rem',
364
- border: 'none',
365
- cursor: 'pointer',
366
- backgroundColor: isDark ? '#374151' : '#f3f4f6',
367
- color: isDark ? '#d1d5db' : '#374151',
368
- flex: 1,
369
- fontSize: '0.9rem'
370
- }}
371
- >
372
- <FaBell />
373
- <span>Limpar</span>
374
- </button>
375
- )}
376
- </div>
377
-
378
- {/* Connection Status (when collapsed) */}
379
- {state.isCollapsed && (
380
- <div style={{
381
- padding: '0.5rem',
382
- textAlign: 'center',
383
- fontSize: '0.75rem',
384
- color: isDark ? '#6b7280' : '#9ca3af'
385
- }}>
386
- {connected ? '🟢' : '🔴'}
387
- </div>
388
- )}
389
- </div>
390
- )
391
- }
@@ -1,178 +0,0 @@
1
- /**
2
- * State Management Demo Component
3
- * Demonstrates the usage of FluxStack state management system with Zustand
4
- */
5
-
6
- import React from 'react'
7
- import { useNotifications } from '../hooks/useNotifications'
8
- import { useAuth } from '../hooks/useAuth'
9
- import { useUIStore } from '../store/slices/uiSlice'
10
-
11
- export function StateDemo() {
12
- const {
13
- theme,
14
- sidebarOpen,
15
- notifications,
16
- loading,
17
- setTheme,
18
- toggleSidebar,
19
- setGlobalLoading
20
- } = useUIStore()
21
-
22
- const { success, error, warning, info, clearNotifications } = useNotifications()
23
- const { currentUser, isAuthenticated, login, logout } = useAuth()
24
-
25
- const handleThemeChange = (newTheme: 'light' | 'dark' | 'system') => {
26
- setTheme(newTheme)
27
- }
28
-
29
- const handleToggleSidebar = () => {
30
- toggleSidebar()
31
- }
32
-
33
- const handleToggleLoading = () => {
34
- setGlobalLoading(!loading.global)
35
- }
36
-
37
- const handleTestNotifications = () => {
38
- success('Success!', 'This is a success notification')
39
- setTimeout(() => error('Error!', 'This is an error notification'), 1000)
40
- setTimeout(() => warning('Warning!', 'This is a warning notification'), 2000)
41
- setTimeout(() => info('Info!', 'This is an info notification'), 3000)
42
- }
43
-
44
- const handleTestAuth = async () => {
45
- if (isAuthenticated) {
46
- await logout()
47
- } else {
48
- try {
49
- await login({ email: 'test@example.com', password: 'password' })
50
- } catch (error) {
51
- // Error is handled by the hook
52
- }
53
- }
54
- }
55
-
56
- return (
57
- <div className="p-6 bg-white rounded-lg shadow-lg">
58
- <h2 className="text-2xl font-bold mb-6 text-gray-800">
59
- 🔄 State Management Demo
60
- </h2>
61
-
62
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
63
- {/* Theme Controls */}
64
- <div className="space-y-4">
65
- <h3 className="text-lg font-semibold text-gray-700">Theme</h3>
66
- <div className="flex space-x-2">
67
- {(['light', 'dark', 'system'] as const).map((themeOption) => (
68
- <button
69
- key={themeOption}
70
- onClick={() => handleThemeChange(themeOption)}
71
- className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${theme === themeOption
72
- ? 'bg-blue-500 text-white'
73
- : 'bg-gray-200 text-gray-700 hover:bg-gray-300'
74
- }`}
75
- >
76
- {themeOption.charAt(0).toUpperCase() + themeOption.slice(1)}
77
- </button>
78
- ))}
79
- </div>
80
- <p className="text-sm text-gray-600">Current theme: {theme}</p>
81
- </div>
82
-
83
- {/* UI Controls */}
84
- <div className="space-y-4">
85
- <h3 className="text-lg font-semibold text-gray-700">UI State</h3>
86
- <div className="space-y-2">
87
- <button
88
- onClick={handleToggleSidebar}
89
- className="block w-full px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors"
90
- >
91
- {sidebarOpen ? 'Close Sidebar' : 'Open Sidebar'}
92
- </button>
93
- <button
94
- onClick={handleToggleLoading}
95
- className="block w-full px-4 py-2 bg-purple-500 text-white rounded-md hover:bg-purple-600 transition-colors"
96
- >
97
- {loading.global ? 'Stop Loading' : 'Start Loading'}
98
- </button>
99
- </div>
100
- <div className="text-sm text-gray-600">
101
- <p>Sidebar: {sidebarOpen ? 'Open' : 'Closed'}</p>
102
- <p>Loading: {loading.global ? 'Yes' : 'No'}</p>
103
- </div>
104
- </div>
105
-
106
- {/* Notifications */}
107
- <div className="space-y-4">
108
- <h3 className="text-lg font-semibold text-gray-700">Notifications</h3>
109
- <div className="space-y-2">
110
- <button
111
- onClick={handleTestNotifications}
112
- className="block w-full px-4 py-2 bg-orange-500 text-white rounded-md hover:bg-orange-600 transition-colors"
113
- >
114
- Test Notifications
115
- </button>
116
- <button
117
- onClick={clearNotifications}
118
- className="block w-full px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 transition-colors"
119
- >
120
- Clear Notifications
121
- </button>
122
- </div>
123
- <p className="text-sm text-gray-600">
124
- Active notifications: {notifications.length}
125
- </p>
126
- </div>
127
-
128
- {/* Authentication */}
129
- <div className="space-y-4">
130
- <h3 className="text-lg font-semibold text-gray-700">Authentication</h3>
131
- <button
132
- onClick={handleTestAuth}
133
- className={`block w-full px-4 py-2 rounded-md transition-colors ${isAuthenticated
134
- ? 'bg-red-500 text-white hover:bg-red-600'
135
- : 'bg-blue-500 text-white hover:bg-blue-600'
136
- }`}
137
- >
138
- {isAuthenticated ? 'Logout' : 'Login (Demo)'}
139
- </button>
140
- <div className="text-sm text-gray-600">
141
- <p>Status: {isAuthenticated ? 'Authenticated' : 'Not authenticated'}</p>
142
- {currentUser && (
143
- <p>User: {currentUser.name} ({currentUser.email})</p>
144
- )}
145
- </div>
146
- </div>
147
- </div>
148
-
149
- {/* State Inspector */}
150
- <div className="mt-8 p-4 bg-gray-50 rounded-md">
151
- <h4 className="text-md font-semibold text-gray-700 mb-2">State Inspector</h4>
152
- <details className="text-sm">
153
- <summary className="cursor-pointer text-blue-600 hover:text-blue-800">
154
- View Current State (Click to expand)
155
- </summary>
156
- <pre className="mt-2 p-2 bg-white rounded border text-xs overflow-auto">
157
- {JSON.stringify({
158
- ui: {
159
- theme,
160
- sidebarOpen,
161
- notificationCount: notifications.length,
162
- globalLoading: loading.global
163
- },
164
- user: {
165
- isAuthenticated,
166
- currentUser: currentUser ? {
167
- id: currentUser.id,
168
- name: currentUser.name,
169
- email: currentUser.email
170
- } : null
171
- }
172
- }, null, 2)}
173
- </pre>
174
- </details>
175
- </div>
176
- </div>
177
- )
178
- }