create-fluxstack 1.0.13 → 1.0.14

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 (214) hide show
  1. package/.env.example +29 -29
  2. package/app/client/README.md +69 -69
  3. package/app/client/index.html +14 -13
  4. package/app/client/src/App.tsx +157 -524
  5. package/app/client/src/components/ErrorBoundary.tsx +107 -0
  6. package/app/client/src/components/ErrorDisplay.css +365 -0
  7. package/app/client/src/components/ErrorDisplay.tsx +258 -0
  8. package/app/client/src/components/FluxStackConfig.tsx +1321 -0
  9. package/app/client/src/components/HybridLiveCounter.tsx +140 -0
  10. package/app/client/src/components/LiveClock.tsx +286 -0
  11. package/app/client/src/components/MainLayout.tsx +390 -0
  12. package/app/client/src/components/SidebarNavigation.tsx +391 -0
  13. package/app/client/src/components/StateDemo.tsx +178 -0
  14. package/app/client/src/components/SystemMonitor.tsx +1038 -0
  15. package/app/client/src/components/Teste.tsx +104 -0
  16. package/app/client/src/components/UserProfile.tsx +809 -0
  17. package/app/client/src/hooks/useAuth.ts +39 -0
  18. package/app/client/src/hooks/useNotifications.ts +56 -0
  19. package/app/client/src/lib/eden-api.ts +189 -53
  20. package/app/client/src/lib/errors.ts +340 -0
  21. package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
  22. package/app/client/src/lib/index.ts +45 -0
  23. package/app/client/src/main.tsx +3 -2
  24. package/app/client/src/pages/ApiDocs.tsx +182 -0
  25. package/app/client/src/pages/Demo.tsx +174 -0
  26. package/app/client/src/pages/HybridLive.tsx +263 -0
  27. package/app/client/src/pages/Overview.tsx +155 -0
  28. package/app/client/src/store/README.md +43 -0
  29. package/app/client/src/store/index.ts +16 -0
  30. package/app/client/src/store/slices/uiSlice.ts +151 -0
  31. package/app/client/src/store/slices/userSlice.ts +161 -0
  32. package/app/client/src/test/README.md +257 -0
  33. package/app/client/src/test/setup.ts +70 -0
  34. package/app/client/src/test/types.ts +12 -0
  35. package/app/client/src/vite-env.d.ts +1 -1
  36. package/app/client/tsconfig.app.json +44 -43
  37. package/app/client/tsconfig.json +7 -7
  38. package/app/client/tsconfig.node.json +25 -25
  39. package/app/client/zustand-setup.md +65 -0
  40. package/app/server/controllers/users.controller.ts +68 -68
  41. package/app/server/index.ts +9 -1
  42. package/app/server/live/CounterComponent.ts +191 -0
  43. package/app/server/live/FluxStackConfig.ts +529 -0
  44. package/app/server/live/LiveClockComponent.ts +214 -0
  45. package/app/server/live/SidebarNavigation.ts +156 -0
  46. package/app/server/live/SystemMonitor.ts +594 -0
  47. package/app/server/live/SystemMonitorIntegration.ts +151 -0
  48. package/app/server/live/TesteComponent.ts +87 -0
  49. package/app/server/live/UserProfileComponent.ts +135 -0
  50. package/app/server/live/register-components.ts +28 -0
  51. package/app/server/middleware/auth.ts +136 -0
  52. package/app/server/middleware/errorHandling.ts +250 -0
  53. package/app/server/middleware/index.ts +10 -0
  54. package/app/server/middleware/rateLimit.ts +193 -0
  55. package/app/server/middleware/requestLogging.ts +215 -0
  56. package/app/server/middleware/validation.ts +270 -0
  57. package/app/server/routes/index.ts +14 -2
  58. package/app/server/routes/upload.ts +92 -0
  59. package/app/server/routes/users.routes.ts +2 -9
  60. package/app/server/services/NotificationService.ts +302 -0
  61. package/app/server/services/UserService.ts +222 -0
  62. package/app/server/services/index.ts +46 -0
  63. package/core/cli/commands/plugin-deps.ts +263 -0
  64. package/core/cli/generators/README.md +339 -0
  65. package/core/cli/generators/component.ts +770 -0
  66. package/core/cli/generators/controller.ts +299 -0
  67. package/core/cli/generators/index.ts +144 -0
  68. package/core/cli/generators/interactive.ts +228 -0
  69. package/core/cli/generators/prompts.ts +83 -0
  70. package/core/cli/generators/route.ts +513 -0
  71. package/core/cli/generators/service.ts +465 -0
  72. package/core/cli/generators/template-engine.ts +154 -0
  73. package/core/cli/generators/types.ts +71 -0
  74. package/core/cli/generators/utils.ts +192 -0
  75. package/core/cli/index.ts +69 -0
  76. package/core/cli/plugin-discovery.ts +16 -85
  77. package/core/client/fluxstack.ts +17 -0
  78. package/core/client/hooks/index.ts +7 -0
  79. package/core/client/hooks/state-validator.ts +130 -0
  80. package/core/client/hooks/useAuth.ts +49 -0
  81. package/core/client/hooks/useChunkedUpload.ts +258 -0
  82. package/core/client/hooks/useHybridLiveComponent.ts +967 -0
  83. package/core/client/hooks/useWebSocket.ts +373 -0
  84. package/core/client/index.ts +47 -0
  85. package/core/client/state/createStore.ts +193 -0
  86. package/core/client/state/index.ts +15 -0
  87. package/core/config/env-dynamic.ts +1 -1
  88. package/core/config/env.ts +2 -1
  89. package/core/config/runtime-config.ts +3 -3
  90. package/core/config/schema.ts +84 -49
  91. package/core/framework/server.ts +30 -0
  92. package/core/index.ts +25 -0
  93. package/core/live/ComponentRegistry.ts +399 -0
  94. package/core/live/types.ts +164 -0
  95. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
  96. package/core/plugins/built-in/live-components/index.ts +27 -0
  97. package/core/plugins/built-in/logger/index.ts +1 -1
  98. package/core/plugins/built-in/monitoring/index.ts +1 -1
  99. package/core/plugins/built-in/static/index.ts +1 -1
  100. package/core/plugins/built-in/swagger/index.ts +1 -1
  101. package/core/plugins/built-in/vite/index.ts +1 -1
  102. package/core/plugins/dependency-manager.ts +384 -0
  103. package/core/plugins/index.ts +5 -1
  104. package/core/plugins/manager.ts +7 -3
  105. package/core/plugins/registry.ts +88 -10
  106. package/core/plugins/types.ts +11 -11
  107. package/core/server/framework.ts +43 -0
  108. package/core/server/index.ts +11 -1
  109. package/core/server/live/ComponentRegistry.ts +1017 -0
  110. package/core/server/live/FileUploadManager.ts +272 -0
  111. package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
  112. package/core/server/live/SingleConnectionManager.ts +0 -0
  113. package/core/server/live/StateSignature.ts +644 -0
  114. package/core/server/live/WebSocketConnectionManager.ts +688 -0
  115. package/core/server/live/websocket-plugin.ts +435 -0
  116. package/core/server/middleware/errorHandling.ts +141 -0
  117. package/core/server/middleware/index.ts +16 -0
  118. package/core/server/plugins/static-files-plugin.ts +232 -0
  119. package/core/server/services/BaseService.ts +95 -0
  120. package/core/server/services/ServiceContainer.ts +144 -0
  121. package/core/server/services/index.ts +9 -0
  122. package/core/templates/create-project.ts +46 -2
  123. package/core/testing/index.ts +10 -0
  124. package/core/testing/setup.ts +74 -0
  125. package/core/types/build.ts +38 -14
  126. package/core/types/types.ts +319 -0
  127. package/core/utils/env-runtime.ts +7 -0
  128. package/core/utils/errors/handlers.ts +264 -39
  129. package/core/utils/errors/index.ts +528 -18
  130. package/core/utils/errors/middleware.ts +114 -0
  131. package/core/utils/logger/formatters.ts +222 -0
  132. package/core/utils/logger/index.ts +167 -48
  133. package/core/utils/logger/middleware.ts +253 -0
  134. package/core/utils/logger/performance.ts +384 -0
  135. package/core/utils/logger/transports.ts +365 -0
  136. package/create-fluxstack.ts +296 -296
  137. package/fluxstack.config.ts +17 -1
  138. package/package-template.json +66 -66
  139. package/package.json +31 -6
  140. package/public/README.md +16 -0
  141. package/vite.config.ts +29 -14
  142. package/.claude/settings.local.json +0 -74
  143. package/.github/workflows/ci-build-tests.yml +0 -480
  144. package/.github/workflows/dependency-management.yml +0 -324
  145. package/.github/workflows/release-validation.yml +0 -355
  146. package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
  147. package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
  148. package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
  149. package/CLAUDE.md +0 -200
  150. package/Dockerfile +0 -58
  151. package/Dockerfile.backend +0 -52
  152. package/Dockerfile.frontend +0 -54
  153. package/README-Docker.md +0 -85
  154. package/ai-context/00-QUICK-START.md +0 -86
  155. package/ai-context/README.md +0 -88
  156. package/ai-context/development/eden-treaty-guide.md +0 -362
  157. package/ai-context/development/patterns.md +0 -382
  158. package/ai-context/development/plugins-guide.md +0 -572
  159. package/ai-context/examples/crud-complete.md +0 -626
  160. package/ai-context/project/architecture.md +0 -399
  161. package/ai-context/project/overview.md +0 -213
  162. package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
  163. package/ai-context/recent-changes/type-inference-fix.md +0 -223
  164. package/ai-context/reference/environment-vars.md +0 -384
  165. package/ai-context/reference/troubleshooting.md +0 -407
  166. package/app/client/src/components/TestPage.tsx +0 -453
  167. package/bun.lock +0 -1063
  168. package/bunfig.toml +0 -16
  169. package/core/__tests__/integration.test.ts +0 -227
  170. package/core/build/index.ts +0 -186
  171. package/core/config/__tests__/config-loader.test.ts +0 -554
  172. package/core/config/__tests__/config-merger.test.ts +0 -657
  173. package/core/config/__tests__/env-converter.test.ts +0 -372
  174. package/core/config/__tests__/env-processor.test.ts +0 -431
  175. package/core/config/__tests__/env.test.ts +0 -452
  176. package/core/config/__tests__/integration.test.ts +0 -418
  177. package/core/config/__tests__/loader.test.ts +0 -331
  178. package/core/config/__tests__/schema.test.ts +0 -129
  179. package/core/config/__tests__/validator.test.ts +0 -318
  180. package/core/framework/__tests__/server.test.ts +0 -233
  181. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  182. package/core/plugins/__tests__/manager.test.ts +0 -398
  183. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  184. package/core/plugins/__tests__/registry.test.ts +0 -335
  185. package/core/utils/__tests__/errors.test.ts +0 -139
  186. package/core/utils/__tests__/helpers.test.ts +0 -297
  187. package/core/utils/__tests__/logger.test.ts +0 -141
  188. package/create-test-app.ts +0 -156
  189. package/docker-compose.microservices.yml +0 -75
  190. package/docker-compose.simple.yml +0 -57
  191. package/docker-compose.yml +0 -71
  192. package/eslint.config.js +0 -23
  193. package/flux-cli.ts +0 -214
  194. package/nginx-lb.conf +0 -37
  195. package/publish.sh +0 -63
  196. package/run-clean.ts +0 -26
  197. package/run-env-tests.ts +0 -313
  198. package/tailwind.config.js +0 -34
  199. package/tests/__mocks__/api.ts +0 -56
  200. package/tests/fixtures/users.ts +0 -69
  201. package/tests/integration/api/users.routes.test.ts +0 -221
  202. package/tests/setup.ts +0 -29
  203. package/tests/unit/app/client/App-simple.test.tsx +0 -56
  204. package/tests/unit/app/client/App.test.tsx.skip +0 -237
  205. package/tests/unit/app/client/eden-api.test.ts +0 -186
  206. package/tests/unit/app/client/simple.test.tsx +0 -23
  207. package/tests/unit/app/controllers/users.controller.test.ts +0 -150
  208. package/tests/unit/core/create-project.test.ts.skip +0 -95
  209. package/tests/unit/core/framework.test.ts +0 -144
  210. package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
  211. package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
  212. package/tests/utils/test-helpers.ts +0 -61
  213. package/vitest.config.ts +0 -50
  214. package/workspace.json +0 -6
@@ -0,0 +1,1038 @@
1
+ // 🔥 System Monitor Dashboard Component
2
+
3
+ import { useState } from 'react'
4
+ import { useHybridLiveComponent } from 'fluxstack'
5
+ import {
6
+ FaServer,
7
+ FaHome,
8
+ FaMemory,
9
+ FaHeartbeat,
10
+ FaChartLine,
11
+ FaClock,
12
+ FaWifi,
13
+ FaPlay,
14
+ FaPause,
15
+ FaSync,
16
+ FaTrash,
17
+ FaInfo,
18
+ FaExclamationTriangle,
19
+ FaCheckCircle,
20
+ FaTimesCircle,
21
+ FaEye,
22
+ FaBolt,
23
+ FaDatabase,
24
+ FaStop
25
+ } from 'react-icons/fa'
26
+
27
+ export interface SystemMonitorState {
28
+ totalComponents: number
29
+ activeConnections: number
30
+ totalRooms: number
31
+ messagesPerSecond: number
32
+ averageResponseTime: number
33
+ componentsByType: Record<string, number>
34
+ roomDetails: Record<string, number>
35
+ memoryUsage: {
36
+ used: number
37
+ total: number
38
+ percentage: number
39
+ }
40
+ recentConnections: Array<{
41
+ id: string
42
+ timestamp: number
43
+ componentType: string
44
+ status: 'connected' | 'disconnected' | 'rehydrated'
45
+ }>
46
+ recentMessages: Array<{
47
+ id: string
48
+ timestamp: number
49
+ type: string
50
+ componentId: string
51
+ success: boolean
52
+ responseTime?: number
53
+ }>
54
+ systemHealth: {
55
+ status: 'healthy' | 'warning' | 'critical'
56
+ uptime: number
57
+ lastRestart: number
58
+ errors: number
59
+ warnings: number
60
+ }
61
+ autoRefresh: boolean
62
+ refreshInterval: number
63
+ lastUpdated: number
64
+ }
65
+
66
+ const initialState: SystemMonitorState = {
67
+ totalComponents: 0,
68
+ activeConnections: 0,
69
+ totalRooms: 0,
70
+ messagesPerSecond: 0,
71
+ averageResponseTime: 0,
72
+ componentsByType: {},
73
+ roomDetails: {},
74
+ memoryUsage: {
75
+ used: 0,
76
+ total: 0,
77
+ percentage: 0
78
+ },
79
+ recentConnections: [],
80
+ recentMessages: [],
81
+ systemHealth: {
82
+ status: 'healthy',
83
+ uptime: 0,
84
+ lastRestart: Date.now(),
85
+ errors: 0,
86
+ warnings: 0
87
+ },
88
+ autoRefresh: true,
89
+ refreshInterval: 2000,
90
+ lastUpdated: Date.now()
91
+ }
92
+
93
+ export function SystemMonitor() {
94
+ const { state, call, connected, status, error } = useHybridLiveComponent<SystemMonitorState>(
95
+ 'SystemMonitor',
96
+ initialState,
97
+ { debug: true }
98
+ )
99
+
100
+ const [selectedTab, setSelectedTab] = useState<'overview' | 'components' | 'activity' | 'system'>('overview')
101
+
102
+ // Show loading state
103
+ if (!connected || status !== 'synced') {
104
+ const getStatusMessage = () => {
105
+ switch (status) {
106
+ case 'connecting':
107
+ return '🔄 Conectando ao monitoramento...'
108
+ case 'reconnecting':
109
+ return '🔄 Reconectando sistema...'
110
+ case 'mounting':
111
+ return '🚀 Iniciando monitoramento...'
112
+ case 'loading':
113
+ return '⏳ Carregando métricas...'
114
+ case 'error':
115
+ return '❌ Erro no monitoramento'
116
+ default:
117
+ return '🔄 Preparando sistema...'
118
+ }
119
+ }
120
+
121
+ return (
122
+ <div style={{
123
+ padding: '4rem',
124
+ textAlign: 'center',
125
+ backgroundColor: '#f8fafc',
126
+ minHeight: '100vh',
127
+ display: 'flex',
128
+ flexDirection: 'column',
129
+ alignItems: 'center',
130
+ justifyContent: 'center'
131
+ }}>
132
+ <FaServer size={48} style={{ marginBottom: '2rem', color: '#6b7280' }} />
133
+ <h2 style={{ color: '#374151', marginBottom: '1rem' }}>
134
+ Sistema de Monitoramento
135
+ </h2>
136
+ <p style={{ color: '#6b7280', marginBottom: '2rem' }}>
137
+ {getStatusMessage()}
138
+ </p>
139
+ {error && (
140
+ <div style={{
141
+ backgroundColor: '#fee2e2',
142
+ color: '#dc2626',
143
+ padding: '1rem',
144
+ borderRadius: '8px',
145
+ border: '1px solid #fecaca'
146
+ }}>
147
+ {error}
148
+ </div>
149
+ )}
150
+ </div>
151
+ )
152
+ }
153
+
154
+ const handleToggleAutoRefresh = async () => {
155
+ try {
156
+ await call('toggleAutoRefresh')
157
+ } catch (error) {
158
+ console.error('Toggle auto-refresh error:', error)
159
+ }
160
+ }
161
+
162
+ const handleRefreshMetrics = async () => {
163
+ try {
164
+ await call('refreshMetrics')
165
+ } catch (error) {
166
+ console.error('Refresh metrics error:', error)
167
+ }
168
+ }
169
+
170
+ const handleEmergencyStop = async () => {
171
+ try {
172
+ await call('emergencyStop')
173
+ } catch (error) {
174
+ console.error('Emergency stop error:', error)
175
+ }
176
+ }
177
+
178
+ const handleClearActivity = async () => {
179
+ try {
180
+ await call('clearActivity')
181
+ } catch (error) {
182
+ console.error('Clear activity error:', error)
183
+ }
184
+ }
185
+
186
+ const formatUptime = (seconds: number) => {
187
+ const hours = Math.floor(seconds / 3600)
188
+ const minutes = Math.floor((seconds % 3600) / 60)
189
+ const secs = seconds % 60
190
+ return `${hours}h ${minutes}m ${secs}s`
191
+ }
192
+
193
+ const formatTimestamp = (timestamp: number) => {
194
+ return new Date(timestamp).toLocaleTimeString()
195
+ }
196
+
197
+ const getHealthIcon = (status: string) => {
198
+ switch (status) {
199
+ case 'healthy':
200
+ return <FaCheckCircle style={{ color: '#10b981' }} />
201
+ case 'warning':
202
+ return <FaExclamationTriangle style={{ color: '#f59e0b' }} />
203
+ case 'critical':
204
+ return <FaTimesCircle style={{ color: '#ef4444' }} />
205
+ default:
206
+ return <FaHeartbeat style={{ color: '#6b7280' }} />
207
+ }
208
+ }
209
+
210
+ const getHealthColor = (status: string) => {
211
+ switch (status) {
212
+ case 'healthy':
213
+ return '#10b981'
214
+ case 'warning':
215
+ return '#f59e0b'
216
+ case 'critical':
217
+ return '#ef4444'
218
+ default:
219
+ return '#6b7280'
220
+ }
221
+ }
222
+
223
+ const getConnectionStatusIcon = (status: string) => {
224
+ switch (status) {
225
+ case 'connected':
226
+ return <FaWifi style={{ color: '#10b981' }} />
227
+ case 'disconnected':
228
+ return <FaTimesCircle style={{ color: '#ef4444' }} />
229
+ case 'rehydrated':
230
+ return <FaSync style={{ color: '#3b82f6' }} />
231
+ default:
232
+ return <FaWifi style={{ color: '#6b7280' }} />
233
+ }
234
+ }
235
+
236
+ return (
237
+ <div style={{
238
+ padding: '2rem',
239
+ backgroundColor: '#f8fafc',
240
+ minHeight: '100vh'
241
+ }}>
242
+ {/* Header */}
243
+ <div style={{
244
+ marginBottom: '2rem'
245
+ }}>
246
+ <div style={{
247
+ display: 'flex',
248
+ alignItems: 'center',
249
+ justifyContent: 'space-between',
250
+ marginBottom: '1rem'
251
+ }}>
252
+ <div style={{
253
+ display: 'flex',
254
+ alignItems: 'center',
255
+ gap: '1rem'
256
+ }}>
257
+ <FaServer size={32} style={{ color: '#374151' }} />
258
+ <div>
259
+ <h1 style={{
260
+ color: '#374151',
261
+ margin: 0,
262
+ fontSize: '2rem'
263
+ }}>
264
+ 🔥 Sistema de Monitoramento
265
+ </h1>
266
+ <p style={{
267
+ color: '#6b7280',
268
+ margin: 0,
269
+ fontSize: '1.1rem'
270
+ }}>
271
+ Monitoramento em tempo real dos Live Components
272
+ </p>
273
+ </div>
274
+ </div>
275
+
276
+ {/* Controls */}
277
+ <div style={{
278
+ display: 'flex',
279
+ gap: '1rem',
280
+ alignItems: 'center'
281
+ }}>
282
+ <button
283
+ onClick={handleToggleAutoRefresh}
284
+ style={{
285
+ display: 'flex',
286
+ alignItems: 'center',
287
+ gap: '0.5rem',
288
+ padding: '0.75rem 1rem',
289
+ borderRadius: '8px',
290
+ border: 'none',
291
+ cursor: 'pointer',
292
+ backgroundColor: state.autoRefresh ? '#10b981' : '#6b7280',
293
+ color: 'white',
294
+ fontSize: '0.9rem'
295
+ }}
296
+ >
297
+ {state.autoRefresh ? <FaPause /> : <FaPlay />}
298
+ {state.autoRefresh ? 'Pausar' : 'Iniciar'}
299
+ </button>
300
+
301
+ <button
302
+ onClick={handleRefreshMetrics}
303
+ style={{
304
+ display: 'flex',
305
+ alignItems: 'center',
306
+ gap: '0.5rem',
307
+ padding: '0.75rem 1rem',
308
+ borderRadius: '8px',
309
+ border: '1px solid #d1d5db',
310
+ cursor: 'pointer',
311
+ backgroundColor: 'white',
312
+ color: '#374151',
313
+ fontSize: '0.9rem'
314
+ }}
315
+ >
316
+ <FaSync />
317
+ Atualizar
318
+ </button>
319
+
320
+ <button
321
+ onClick={handleClearActivity}
322
+ style={{
323
+ display: 'flex',
324
+ alignItems: 'center',
325
+ gap: '0.5rem',
326
+ padding: '0.75rem 1rem',
327
+ borderRadius: '8px',
328
+ border: '1px solid #d1d5db',
329
+ cursor: 'pointer',
330
+ backgroundColor: 'white',
331
+ color: '#ef4444',
332
+ fontSize: '0.9rem'
333
+ }}
334
+ >
335
+ <FaTrash />
336
+ Limpar
337
+ </button>
338
+
339
+ <button
340
+ onClick={handleEmergencyStop}
341
+ style={{
342
+ display: 'flex',
343
+ alignItems: 'center',
344
+ gap: '0.5rem',
345
+ padding: '0.75rem 1rem',
346
+ borderRadius: '8px',
347
+ border: '2px solid #dc2626',
348
+ cursor: 'pointer',
349
+ backgroundColor: '#dc2626',
350
+ color: 'white',
351
+ fontSize: '0.9rem',
352
+ fontWeight: 'bold'
353
+ }}
354
+ >
355
+ <FaStop />
356
+ 🚨 PARAR TUDO
357
+ </button>
358
+ </div>
359
+ </div>
360
+
361
+ {/* Status Bar */}
362
+ <div style={{
363
+ display: 'flex',
364
+ alignItems: 'center',
365
+ gap: '2rem',
366
+ padding: '1rem',
367
+ backgroundColor: 'white',
368
+ borderRadius: '12px',
369
+ boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'
370
+ }}>
371
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
372
+ {getHealthIcon(state.systemHealth.status)}
373
+ <span style={{
374
+ color: getHealthColor(state.systemHealth.status),
375
+ fontWeight: 'bold'
376
+ }}>
377
+ {state.systemHealth.status.charAt(0).toUpperCase() + state.systemHealth.status.slice(1)}
378
+ </span>
379
+ </div>
380
+
381
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
382
+ <FaClock style={{ color: '#6b7280' }} />
383
+ <span style={{ color: '#374151' }}>
384
+ Uptime: {formatUptime(state.systemHealth.uptime)}
385
+ </span>
386
+ </div>
387
+
388
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
389
+ <FaSync style={{ color: '#6b7280' }} />
390
+ <span style={{ color: '#374151' }}>
391
+ Auto-refresh: {state.autoRefresh ? 'ON' : 'OFF'}
392
+ ({state.refreshInterval}ms)
393
+ </span>
394
+ </div>
395
+
396
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
397
+ <FaClock style={{ color: '#6b7280' }} />
398
+ <span style={{ color: '#374151' }}>
399
+ Última atualização: {formatTimestamp(state.lastUpdated)}
400
+ </span>
401
+ </div>
402
+ </div>
403
+ </div>
404
+
405
+ {/* Navigation Tabs */}
406
+ <div style={{
407
+ display: 'flex',
408
+ gap: '1rem',
409
+ marginBottom: '2rem'
410
+ }}>
411
+ {[
412
+ { id: 'overview', label: 'Visão Geral', icon: <FaChartLine /> },
413
+ { id: 'components', label: 'Componentes', icon: <FaBolt /> },
414
+ { id: 'activity', label: 'Atividade', icon: <FaEye /> },
415
+ { id: 'system', label: 'Sistema', icon: <FaDatabase /> }
416
+ ].map(tab => (
417
+ <button
418
+ key={tab.id}
419
+ onClick={() => setSelectedTab(tab.id as any)}
420
+ style={{
421
+ display: 'flex',
422
+ alignItems: 'center',
423
+ gap: '0.5rem',
424
+ padding: '1rem 1.5rem',
425
+ borderRadius: '8px',
426
+ border: 'none',
427
+ cursor: 'pointer',
428
+ backgroundColor: selectedTab === tab.id ? '#3b82f6' : 'white',
429
+ color: selectedTab === tab.id ? 'white' : '#374151',
430
+ fontSize: '0.95rem',
431
+ boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'
432
+ }}
433
+ >
434
+ {tab.icon}
435
+ {tab.label}
436
+ </button>
437
+ ))}
438
+ </div>
439
+
440
+ {/* Content */}
441
+ {selectedTab === 'overview' && (
442
+ <div>
443
+ {/* Metrics Cards */}
444
+ <div style={{
445
+ display: 'grid',
446
+ gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
447
+ gap: '1.5rem',
448
+ marginBottom: '2rem'
449
+ }}>
450
+ {[
451
+ {
452
+ title: 'Componentes Ativos',
453
+ value: state.totalComponents,
454
+ icon: <FaBolt />,
455
+ color: '#3b82f6',
456
+ subtitle: 'Live Components'
457
+ },
458
+ {
459
+ title: 'Conexões WebSocket',
460
+ value: state.activeConnections,
461
+ icon: <FaWifi />,
462
+ color: '#10b981',
463
+ subtitle: 'Conexões ativas'
464
+ },
465
+ {
466
+ title: 'Salas',
467
+ value: state.totalRooms,
468
+ icon: <FaHome />,
469
+ color: '#f59e0b',
470
+ subtitle: 'Rooms ativas'
471
+ },
472
+ {
473
+ title: 'Mensagens/seg',
474
+ value: state.messagesPerSecond,
475
+ icon: <FaChartLine />,
476
+ color: '#8b5cf6',
477
+ subtitle: 'Taxa de mensagens'
478
+ },
479
+ {
480
+ title: 'Tempo de Resposta',
481
+ value: `${state.averageResponseTime}ms`,
482
+ icon: <FaClock />,
483
+ color: '#06b6d4',
484
+ subtitle: 'Tempo médio'
485
+ },
486
+ {
487
+ title: 'Uso de Memória',
488
+ value: `${state.memoryUsage.percentage}%`,
489
+ icon: <FaMemory />,
490
+ color: state.memoryUsage.percentage > 75 ? '#ef4444' : '#10b981',
491
+ subtitle: `${state.memoryUsage.used}MB / ${state.memoryUsage.total}MB`
492
+ }
493
+ ].map((metric, index) => (
494
+ <div key={index} style={{
495
+ backgroundColor: 'white',
496
+ padding: '2rem',
497
+ borderRadius: '16px',
498
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
499
+ border: '1px solid #e5e7eb'
500
+ }}>
501
+ <div style={{
502
+ display: 'flex',
503
+ alignItems: 'center',
504
+ gap: '1rem',
505
+ marginBottom: '1rem'
506
+ }}>
507
+ <div style={{
508
+ backgroundColor: metric.color,
509
+ padding: '0.75rem',
510
+ borderRadius: '12px',
511
+ color: 'white',
512
+ fontSize: '1.2rem'
513
+ }}>
514
+ {metric.icon}
515
+ </div>
516
+ <div>
517
+ <h3 style={{
518
+ margin: 0,
519
+ fontSize: '1rem',
520
+ color: '#374151'
521
+ }}>
522
+ {metric.title}
523
+ </h3>
524
+ <p style={{
525
+ margin: 0,
526
+ fontSize: '1.8rem',
527
+ fontWeight: 'bold',
528
+ color: metric.color
529
+ }}>
530
+ {metric.value}
531
+ </p>
532
+ <p style={{
533
+ margin: 0,
534
+ fontSize: '0.9rem',
535
+ color: '#6b7280'
536
+ }}>
537
+ {metric.subtitle}
538
+ </p>
539
+ </div>
540
+ </div>
541
+ </div>
542
+ ))}
543
+ </div>
544
+
545
+ {/* System Health */}
546
+ <div style={{
547
+ backgroundColor: 'white',
548
+ padding: '2rem',
549
+ borderRadius: '16px',
550
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
551
+ marginBottom: '2rem'
552
+ }}>
553
+ <h3 style={{
554
+ color: '#374151',
555
+ marginBottom: '1rem',
556
+ display: 'flex',
557
+ alignItems: 'center',
558
+ gap: '0.5rem'
559
+ }}>
560
+ <FaHeartbeat />
561
+ Status do Sistema
562
+ </h3>
563
+
564
+ <div style={{
565
+ display: 'grid',
566
+ gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
567
+ gap: '1rem'
568
+ }}>
569
+ <div style={{
570
+ padding: '1rem',
571
+ backgroundColor: '#f8fafc',
572
+ borderRadius: '8px',
573
+ border: '1px solid #e2e8f0'
574
+ }}>
575
+ <div style={{
576
+ display: 'flex',
577
+ alignItems: 'center',
578
+ gap: '0.5rem',
579
+ marginBottom: '0.5rem'
580
+ }}>
581
+ {getHealthIcon(state.systemHealth.status)}
582
+ <span style={{ fontWeight: 'bold', color: '#374151' }}>
583
+ Status Geral
584
+ </span>
585
+ </div>
586
+ <p style={{
587
+ margin: 0,
588
+ color: getHealthColor(state.systemHealth.status),
589
+ fontWeight: 'bold'
590
+ }}>
591
+ {state.systemHealth.status.toUpperCase()}
592
+ </p>
593
+ </div>
594
+
595
+ <div style={{
596
+ padding: '1rem',
597
+ backgroundColor: '#f8fafc',
598
+ borderRadius: '8px',
599
+ border: '1px solid #e2e8f0'
600
+ }}>
601
+ <div style={{
602
+ display: 'flex',
603
+ alignItems: 'center',
604
+ gap: '0.5rem',
605
+ marginBottom: '0.5rem'
606
+ }}>
607
+ <FaTimesCircle style={{ color: '#ef4444' }} />
608
+ <span style={{ fontWeight: 'bold', color: '#374151' }}>
609
+ Erros
610
+ </span>
611
+ </div>
612
+ <p style={{ margin: 0, color: '#ef4444', fontWeight: 'bold' }}>
613
+ {state.systemHealth.errors}
614
+ </p>
615
+ </div>
616
+
617
+ <div style={{
618
+ padding: '1rem',
619
+ backgroundColor: '#f8fafc',
620
+ borderRadius: '8px',
621
+ border: '1px solid #e2e8f0'
622
+ }}>
623
+ <div style={{
624
+ display: 'flex',
625
+ alignItems: 'center',
626
+ gap: '0.5rem',
627
+ marginBottom: '0.5rem'
628
+ }}>
629
+ <FaExclamationTriangle style={{ color: '#f59e0b' }} />
630
+ <span style={{ fontWeight: 'bold', color: '#374151' }}>
631
+ Avisos
632
+ </span>
633
+ </div>
634
+ <p style={{ margin: 0, color: '#f59e0b', fontWeight: 'bold' }}>
635
+ {state.systemHealth.warnings}
636
+ </p>
637
+ </div>
638
+
639
+ <div style={{
640
+ padding: '1rem',
641
+ backgroundColor: '#f8fafc',
642
+ borderRadius: '8px',
643
+ border: '1px solid #e2e8f0'
644
+ }}>
645
+ <div style={{
646
+ display: 'flex',
647
+ alignItems: 'center',
648
+ gap: '0.5rem',
649
+ marginBottom: '0.5rem'
650
+ }}>
651
+ <FaClock style={{ color: '#6b7280' }} />
652
+ <span style={{ fontWeight: 'bold', color: '#374151' }}>
653
+ Uptime
654
+ </span>
655
+ </div>
656
+ <p style={{ margin: 0, color: '#374151', fontWeight: 'bold' }}>
657
+ {formatUptime(state.systemHealth.uptime)}
658
+ </p>
659
+ </div>
660
+ </div>
661
+ </div>
662
+ </div>
663
+ )}
664
+
665
+ {selectedTab === 'components' && (
666
+ <div>
667
+ {/* Components by Type */}
668
+ <div style={{
669
+ backgroundColor: 'white',
670
+ padding: '2rem',
671
+ borderRadius: '16px',
672
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
673
+ marginBottom: '2rem'
674
+ }}>
675
+ <h3 style={{
676
+ color: '#374151',
677
+ marginBottom: '1.5rem',
678
+ display: 'flex',
679
+ alignItems: 'center',
680
+ gap: '0.5rem'
681
+ }}>
682
+ <FaBolt />
683
+ Componentes por Tipo
684
+ </h3>
685
+
686
+ <div style={{
687
+ display: 'grid',
688
+ gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
689
+ gap: '1rem'
690
+ }}>
691
+ {Object.entries(state.componentsByType).map(([type, count]) => (
692
+ <div key={type} style={{
693
+ padding: '1.5rem',
694
+ backgroundColor: '#f8fafc',
695
+ borderRadius: '12px',
696
+ border: '1px solid #e2e8f0',
697
+ textAlign: 'center'
698
+ }}>
699
+ <h4 style={{
700
+ margin: '0 0 0.5rem 0',
701
+ color: '#374151',
702
+ fontSize: '1rem'
703
+ }}>
704
+ {type}
705
+ </h4>
706
+ <p style={{
707
+ margin: 0,
708
+ fontSize: '2rem',
709
+ fontWeight: 'bold',
710
+ color: count > 0 ? '#10b981' : '#6b7280'
711
+ }}>
712
+ {count}
713
+ </p>
714
+ <p style={{
715
+ margin: 0,
716
+ fontSize: '0.9rem',
717
+ color: '#6b7280'
718
+ }}>
719
+ {count === 1 ? 'instância' : 'instâncias'}
720
+ </p>
721
+ </div>
722
+ ))}
723
+ </div>
724
+ </div>
725
+
726
+ {/* Room Details */}
727
+ <div style={{
728
+ backgroundColor: 'white',
729
+ padding: '2rem',
730
+ borderRadius: '16px',
731
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
732
+ }}>
733
+ <h3 style={{
734
+ color: '#374151',
735
+ marginBottom: '1.5rem',
736
+ display: 'flex',
737
+ alignItems: 'center',
738
+ gap: '0.5rem'
739
+ }}>
740
+ <FaHome />
741
+ Salas Ativas
742
+ </h3>
743
+
744
+ {Object.keys(state.roomDetails).length > 0 ? (
745
+ <div style={{
746
+ display: 'grid',
747
+ gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
748
+ gap: '1rem'
749
+ }}>
750
+ {Object.entries(state.roomDetails).map(([room, count]) => (
751
+ <div key={room} style={{
752
+ padding: '1.5rem',
753
+ backgroundColor: '#f0f9ff',
754
+ borderRadius: '12px',
755
+ border: '1px solid #bae6fd',
756
+ textAlign: 'center'
757
+ }}>
758
+ <h4 style={{
759
+ margin: '0 0 0.5rem 0',
760
+ color: '#0369a1',
761
+ fontSize: '1rem'
762
+ }}>
763
+ {room}
764
+ </h4>
765
+ <p style={{
766
+ margin: 0,
767
+ fontSize: '2rem',
768
+ fontWeight: 'bold',
769
+ color: '#0284c7'
770
+ }}>
771
+ {count}
772
+ </p>
773
+ <p style={{
774
+ margin: 0,
775
+ fontSize: '0.9rem',
776
+ color: '#0369a1'
777
+ }}>
778
+ {count === 1 ? 'componente' : 'componentes'}
779
+ </p>
780
+ </div>
781
+ ))}
782
+ </div>
783
+ ) : (
784
+ <div style={{
785
+ textAlign: 'center',
786
+ padding: '3rem',
787
+ color: '#6b7280'
788
+ }}>
789
+ <FaHome size={48} style={{ marginBottom: '1rem', opacity: 0.5 }} />
790
+ <p>Nenhuma sala ativa no momento</p>
791
+ </div>
792
+ )}
793
+ </div>
794
+ </div>
795
+ )}
796
+
797
+ {selectedTab === 'activity' && (
798
+ <div style={{
799
+ display: 'grid',
800
+ gridTemplateColumns: '1fr 1fr',
801
+ gap: '2rem'
802
+ }}>
803
+ {/* Recent Connections */}
804
+ <div style={{
805
+ backgroundColor: 'white',
806
+ padding: '2rem',
807
+ borderRadius: '16px',
808
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
809
+ }}>
810
+ <h3 style={{
811
+ color: '#374151',
812
+ marginBottom: '1.5rem',
813
+ display: 'flex',
814
+ alignItems: 'center',
815
+ gap: '0.5rem'
816
+ }}>
817
+ <FaWifi />
818
+ Conexões Recentes
819
+ </h3>
820
+
821
+ {state.recentConnections.length > 0 ? (
822
+ <div style={{
823
+ maxHeight: '400px',
824
+ overflowY: 'auto'
825
+ }}>
826
+ {state.recentConnections.slice(0, 20).map(connection => (
827
+ <div key={connection.id} style={{
828
+ display: 'flex',
829
+ alignItems: 'center',
830
+ gap: '1rem',
831
+ padding: '1rem',
832
+ marginBottom: '0.5rem',
833
+ backgroundColor: '#f8fafc',
834
+ borderRadius: '8px',
835
+ border: '1px solid #e2e8f0'
836
+ }}>
837
+ {getConnectionStatusIcon(connection.status)}
838
+ <div style={{ flex: 1 }}>
839
+ <p style={{
840
+ margin: 0,
841
+ fontWeight: 'bold',
842
+ color: '#374151'
843
+ }}>
844
+ {connection.componentType}
845
+ </p>
846
+ <p style={{
847
+ margin: 0,
848
+ fontSize: '0.9rem',
849
+ color: '#6b7280'
850
+ }}>
851
+ {connection.status} - {formatTimestamp(connection.timestamp)}
852
+ </p>
853
+ </div>
854
+ </div>
855
+ ))}
856
+ </div>
857
+ ) : (
858
+ <div style={{
859
+ textAlign: 'center',
860
+ padding: '3rem',
861
+ color: '#6b7280'
862
+ }}>
863
+ <FaWifi size={48} style={{ marginBottom: '1rem', opacity: 0.5 }} />
864
+ <p>Nenhuma conexão recente</p>
865
+ </div>
866
+ )}
867
+ </div>
868
+
869
+ {/* Recent Messages */}
870
+ <div style={{
871
+ backgroundColor: 'white',
872
+ padding: '2rem',
873
+ borderRadius: '16px',
874
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
875
+ }}>
876
+ <h3 style={{
877
+ color: '#374151',
878
+ marginBottom: '1.5rem',
879
+ display: 'flex',
880
+ alignItems: 'center',
881
+ gap: '0.5rem'
882
+ }}>
883
+ <FaBolt />
884
+ Mensagens Recentes
885
+ </h3>
886
+
887
+ {state.recentMessages.length > 0 ? (
888
+ <div style={{
889
+ maxHeight: '400px',
890
+ overflowY: 'auto'
891
+ }}>
892
+ {state.recentMessages.slice(0, 20).map(message => (
893
+ <div key={message.id} style={{
894
+ display: 'flex',
895
+ alignItems: 'center',
896
+ gap: '1rem',
897
+ padding: '1rem',
898
+ marginBottom: '0.5rem',
899
+ backgroundColor: '#f8fafc',
900
+ borderRadius: '8px',
901
+ border: '1px solid #e2e8f0'
902
+ }}>
903
+ {message.success ?
904
+ <FaCheckCircle style={{ color: '#10b981' }} /> :
905
+ <FaTimesCircle style={{ color: '#ef4444' }} />
906
+ }
907
+ <div style={{ flex: 1 }}>
908
+ <p style={{
909
+ margin: 0,
910
+ fontWeight: 'bold',
911
+ color: '#374151'
912
+ }}>
913
+ {message.type}
914
+ </p>
915
+ <p style={{
916
+ margin: 0,
917
+ fontSize: '0.9rem',
918
+ color: '#6b7280'
919
+ }}>
920
+ {message.componentId.substring(0, 8)}... - {formatTimestamp(message.timestamp)}
921
+ {message.responseTime && ` (${message.responseTime}ms)`}
922
+ </p>
923
+ </div>
924
+ </div>
925
+ ))}
926
+ </div>
927
+ ) : (
928
+ <div style={{
929
+ textAlign: 'center',
930
+ padding: '3rem',
931
+ color: '#6b7280'
932
+ }}>
933
+ <FaBolt size={48} style={{ marginBottom: '1rem', opacity: 0.5 }} />
934
+ <p>Nenhuma mensagem recente</p>
935
+ </div>
936
+ )}
937
+ </div>
938
+ </div>
939
+ )}
940
+
941
+ {selectedTab === 'system' && (
942
+ <div>
943
+ <div style={{
944
+ backgroundColor: 'white',
945
+ padding: '2rem',
946
+ borderRadius: '16px',
947
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
948
+ }}>
949
+ <h3 style={{
950
+ color: '#374151',
951
+ marginBottom: '1.5rem',
952
+ display: 'flex',
953
+ alignItems: 'center',
954
+ gap: '0.5rem'
955
+ }}>
956
+ <FaInfo />
957
+ Informações do Sistema
958
+ </h3>
959
+
960
+ <div style={{
961
+ display: 'grid',
962
+ gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
963
+ gap: '1.5rem'
964
+ }}>
965
+ <div style={{
966
+ padding: '1.5rem',
967
+ backgroundColor: '#f8fafc',
968
+ borderRadius: '12px',
969
+ border: '1px solid #e2e8f0'
970
+ }}>
971
+ <h4 style={{ color: '#374151', marginBottom: '1rem' }}>
972
+ Performance
973
+ </h4>
974
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
975
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
976
+ <span style={{ color: '#6b7280' }}>Memória Usada:</span>
977
+ <span style={{ color: '#374151', fontWeight: 'bold' }}>
978
+ {state.memoryUsage.used}MB
979
+ </span>
980
+ </div>
981
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
982
+ <span style={{ color: '#6b7280' }}>Memória Total:</span>
983
+ <span style={{ color: '#374151', fontWeight: 'bold' }}>
984
+ {state.memoryUsage.total}MB
985
+ </span>
986
+ </div>
987
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
988
+ <span style={{ color: '#6b7280' }}>Uso de Memória:</span>
989
+ <span style={{
990
+ color: state.memoryUsage.percentage > 75 ? '#ef4444' : '#10b981',
991
+ fontWeight: 'bold'
992
+ }}>
993
+ {state.memoryUsage.percentage}%
994
+ </span>
995
+ </div>
996
+ </div>
997
+ </div>
998
+
999
+ <div style={{
1000
+ padding: '1.5rem',
1001
+ backgroundColor: '#f8fafc',
1002
+ borderRadius: '12px',
1003
+ border: '1px solid #e2e8f0'
1004
+ }}>
1005
+ <h4 style={{ color: '#374151', marginBottom: '1rem' }}>
1006
+ Configurações
1007
+ </h4>
1008
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
1009
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1010
+ <span style={{ color: '#6b7280' }}>Auto-refresh:</span>
1011
+ <span style={{
1012
+ color: state.autoRefresh ? '#10b981' : '#ef4444',
1013
+ fontWeight: 'bold'
1014
+ }}>
1015
+ {state.autoRefresh ? 'ATIVO' : 'INATIVO'}
1016
+ </span>
1017
+ </div>
1018
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1019
+ <span style={{ color: '#6b7280' }}>Intervalo:</span>
1020
+ <span style={{ color: '#374151', fontWeight: 'bold' }}>
1021
+ {state.refreshInterval}ms
1022
+ </span>
1023
+ </div>
1024
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1025
+ <span style={{ color: '#6b7280' }}>Última atualização:</span>
1026
+ <span style={{ color: '#374151', fontWeight: 'bold' }}>
1027
+ {formatTimestamp(state.lastUpdated)}
1028
+ </span>
1029
+ </div>
1030
+ </div>
1031
+ </div>
1032
+ </div>
1033
+ </div>
1034
+ </div>
1035
+ )}
1036
+ </div>
1037
+ )
1038
+ }