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,1321 +0,0 @@
1
- // 🔥 FluxStack Configuration Viewer Component
2
-
3
- import { useState } from 'react'
4
- import { useHybridLiveComponent } from '@/core/client'
5
- import {
6
- FaCog,
7
- FaServer,
8
- FaPlug,
9
- FaLock,
10
- FaDatabase,
11
- FaCode,
12
- FaInfoCircle,
13
- FaSync,
14
- FaDownload,
15
- FaCheckCircle,
16
- FaTimesCircle,
17
- FaEye,
18
- FaEyeSlash,
19
- FaCopy,
20
- FaTerminal,
21
- FaMemory,
22
- FaFolder,
23
- FaGlobe,
24
- FaBolt,
25
- FaRocket,
26
- FaTools,
27
- FaTachometerAlt
28
- } from 'react-icons/fa'
29
-
30
- export interface FluxStackConfigState {
31
- environment: 'development' | 'production' | 'test'
32
- port: number
33
- host: string
34
- apiPrefix: string
35
- framework: {
36
- name: string
37
- version: string
38
- description: string
39
- author: string
40
- license: string
41
- }
42
- plugins: Array<{
43
- name: string
44
- version: string
45
- enabled: boolean
46
- dependencies: string[]
47
- config?: Record<string, any>
48
- }>
49
- runtime: {
50
- nodeVersion: string
51
- bunVersion: string
52
- platform: string
53
- architecture: string
54
- cpuCount: number
55
- totalMemory: number
56
- workingDirectory: string
57
- executablePath: string
58
- }
59
- liveComponents: {
60
- enabled: boolean
61
- autoDiscovery: boolean
62
- websocketPath: string
63
- signatureSecret: string
64
- maxConnections: number
65
- timeout: number
66
- }
67
- vite: {
68
- enabled: boolean
69
- port: number
70
- host: string
71
- hmr: boolean
72
- publicDir: string
73
- buildDir: string
74
- }
75
- staticFiles: {
76
- enabled: boolean
77
- publicPath: string
78
- uploadsPath: string
79
- maxFileSize: number
80
- allowedExtensions: string[]
81
- }
82
- swagger: {
83
- enabled: boolean
84
- title: string
85
- version: string
86
- description: string
87
- path: string
88
- }
89
- security: {
90
- cors: {
91
- enabled: boolean
92
- origins: string[]
93
- credentials: boolean
94
- }
95
- rateLimit: {
96
- enabled: boolean
97
- windowMs: number
98
- maxRequests: number
99
- }
100
- helmet: {
101
- enabled: boolean
102
- options: Record<string, any>
103
- }
104
- }
105
- performance: {
106
- compression: boolean
107
- cache: {
108
- enabled: boolean
109
- maxAge: number
110
- strategy: string
111
- }
112
- clustering: {
113
- enabled: boolean
114
- workers: number
115
- }
116
- }
117
- database: {
118
- enabled: boolean
119
- type?: string
120
- host?: string
121
- port?: number
122
- name?: string
123
- ssl?: boolean
124
- }
125
- logging: {
126
- level: 'debug' | 'info' | 'warn' | 'error'
127
- format: 'json' | 'pretty' | 'compact'
128
- file: {
129
- enabled: boolean
130
- path?: string
131
- maxSize?: string
132
- maxFiles?: number
133
- }
134
- console: {
135
- enabled: boolean
136
- colors: boolean
137
- }
138
- }
139
- advanced: {
140
- hotReload: boolean
141
- typeChecking: boolean
142
- sourceMap: boolean
143
- minification: boolean
144
- bundleAnalyzer: boolean
145
- }
146
- lastUpdated: number
147
- }
148
-
149
- const initialState: FluxStackConfigState = {
150
- environment: 'development',
151
- port: 3000,
152
- host: 'localhost',
153
- apiPrefix: '/api',
154
- framework: {
155
- name: 'FluxStack',
156
- version: '1.5.0',
157
- description: 'Loading...',
158
- author: 'FluxStack Team',
159
- license: 'MIT'
160
- },
161
- plugins: [],
162
- runtime: {
163
- nodeVersion: 'Loading...',
164
- bunVersion: 'Loading...',
165
- platform: 'Loading...',
166
- architecture: 'Loading...',
167
- cpuCount: 0,
168
- totalMemory: 0,
169
- workingDirectory: 'Loading...',
170
- executablePath: 'Loading...'
171
- },
172
- liveComponents: {
173
- enabled: false,
174
- autoDiscovery: false,
175
- websocketPath: '/api/live/ws',
176
- signatureSecret: '***hidden***',
177
- maxConnections: 1000,
178
- timeout: 30000
179
- },
180
- vite: {
181
- enabled: false,
182
- port: 5173,
183
- host: 'localhost',
184
- hmr: false,
185
- publicDir: 'public',
186
- buildDir: 'dist'
187
- },
188
- staticFiles: {
189
- enabled: false,
190
- publicPath: 'public',
191
- uploadsPath: 'uploads',
192
- maxFileSize: 0,
193
- allowedExtensions: []
194
- },
195
- swagger: {
196
- enabled: false,
197
- title: 'FluxStack API',
198
- version: '1.0.0',
199
- description: 'Loading...',
200
- path: '/swagger'
201
- },
202
- security: {
203
- cors: {
204
- enabled: false,
205
- origins: [],
206
- credentials: false
207
- },
208
- rateLimit: {
209
- enabled: false,
210
- windowMs: 0,
211
- maxRequests: 0
212
- },
213
- helmet: {
214
- enabled: false,
215
- options: {}
216
- }
217
- },
218
- performance: {
219
- compression: false,
220
- cache: {
221
- enabled: false,
222
- maxAge: 0,
223
- strategy: 'memory'
224
- },
225
- clustering: {
226
- enabled: false,
227
- workers: 0
228
- }
229
- },
230
- database: {
231
- enabled: false
232
- },
233
- logging: {
234
- level: 'info',
235
- format: 'pretty',
236
- file: {
237
- enabled: false
238
- },
239
- console: {
240
- enabled: true,
241
- colors: true
242
- }
243
- },
244
- advanced: {
245
- hotReload: false,
246
- typeChecking: false,
247
- sourceMap: false,
248
- minification: false,
249
- bundleAnalyzer: false
250
- },
251
- lastUpdated: Date.now()
252
- }
253
-
254
- export function FluxStackConfig() {
255
- const { state, call, callAndWait, connected, status, error } = useHybridLiveComponent<FluxStackConfigState>(
256
- 'FluxStackConfig',
257
- initialState,
258
- { debug: true }
259
- )
260
-
261
- const [activeTab, setActiveTab] = useState<string>('overview')
262
- const [showSensitive, setShowSensitive] = useState(false)
263
-
264
- // Show loading state
265
- if (!connected || status !== 'synced') {
266
- const getStatusMessage = () => {
267
- switch (status) {
268
- case 'connecting':
269
- return '🔄 Conectando configuração...'
270
- case 'reconnecting':
271
- return '🔄 Reconectando configuração...'
272
- case 'mounting':
273
- return '🚀 Carregando configuração...'
274
- case 'loading':
275
- return '⏳ Carregando...'
276
- case 'error':
277
- return '❌ Erro na configuração'
278
- default:
279
- return '🔄 Preparando configuração...'
280
- }
281
- }
282
-
283
- return (
284
- <div style={{
285
- padding: '2rem',
286
- textAlign: 'center',
287
- color: '#6b7280'
288
- }}>
289
- <FaCog size={48} style={{ marginBottom: '1rem', animation: 'spin 2s linear infinite' }} />
290
- <p style={{ fontSize: '1.1rem' }}>{getStatusMessage()}</p>
291
- {error && (
292
- <p style={{ fontSize: '0.9rem', marginTop: '0.5rem', color: '#ef4444' }}>
293
- {error}
294
- </p>
295
- )}
296
- </div>
297
- )
298
- }
299
-
300
- const handleRefreshConfiguration = async () => {
301
- try {
302
- await call('refreshConfiguration')
303
- } catch (error) {
304
- console.error('Refresh configuration error:', error)
305
- }
306
- }
307
-
308
- const handleExportConfiguration = async () => {
309
- try {
310
- const config = await call('exportConfiguration')
311
- const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' })
312
- const url = URL.createObjectURL(blob)
313
- const a = document.createElement('a')
314
- a.href = url
315
- a.download = `fluxstack-config-${new Date().toISOString().split('T')[0]}.json`
316
- a.click()
317
- URL.revokeObjectURL(url)
318
- } catch (error) {
319
- console.error('Export configuration error:', error)
320
- }
321
- }
322
-
323
- const handleValidateConfiguration = async () => {
324
- try {
325
- const result = await callAndWait('validateConfiguration')
326
- alert(`Validation ${result.valid ? 'passed' : 'failed'}!\n\nIssues: ${result.issues?.join(', ') || 'None'}`)
327
- } catch (error) {
328
- console.error('Validate configuration error:', error)
329
- }
330
- }
331
-
332
- const copyToClipboard = (text: string) => {
333
- navigator.clipboard.writeText(text).then(() => {
334
- // Could show a toast notification here
335
- })
336
- }
337
-
338
- const formatBytes = (bytes: number) => {
339
- const gb = bytes
340
- return `${gb} GB`
341
- }
342
-
343
- const formatMs = (ms: number) => {
344
- if (ms >= 60000) return `${Math.round(ms / 60000)}min`
345
- if (ms >= 1000) return `${Math.round(ms / 1000)}s`
346
- return `${ms}ms`
347
- }
348
-
349
- const getStatusIcon = (enabled: boolean) => {
350
- return enabled ?
351
- <FaCheckCircle style={{ color: '#10b981' }} /> :
352
- <FaTimesCircle style={{ color: '#ef4444' }} />
353
- }
354
-
355
- const getEnvironmentColor = () => {
356
- switch (state.environment) {
357
- case 'production': return '#ef4444'
358
- case 'development': return '#10b981'
359
- case 'test': return '#f59e0b'
360
- default: return '#6b7280'
361
- }
362
- }
363
-
364
- const tabs = [
365
- { id: 'overview', label: 'Visão Geral', icon: FaInfoCircle },
366
- { id: 'runtime', label: 'Runtime', icon: FaTerminal },
367
- { id: 'plugins', label: 'Plugins', icon: FaPlug },
368
- { id: 'livecomponents', label: 'Live Components', icon: FaRocket },
369
- { id: 'security', label: 'Segurança', icon: FaLock },
370
- { id: 'performance', label: 'Performance', icon: FaBolt },
371
- { id: 'advanced', label: 'Avançado', icon: FaTools }
372
- ]
373
-
374
- return (
375
- <div style={{
376
- padding: '2rem',
377
- maxWidth: '1400px',
378
- margin: '0 auto'
379
- }}>
380
- {/* Header */}
381
- <div style={{
382
- display: 'flex',
383
- alignItems: 'center',
384
- justifyContent: 'space-between',
385
- marginBottom: '2rem',
386
- padding: '1.5rem',
387
- backgroundColor: 'white',
388
- borderRadius: '16px',
389
- boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
390
- }}>
391
- <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
392
- <FaCog size={32} style={{ color: '#6b7280' }} />
393
- <div>
394
- <h1 style={{ color: '#374151', margin: 0, fontSize: '1.8rem' }}>
395
- 🔥 {state.framework.name} Configuration
396
- </h1>
397
- <p style={{ color: '#6b7280', margin: 0, fontSize: '1rem' }}>
398
- v{state.framework.version} • Environment:
399
- <span style={{
400
- color: getEnvironmentColor(),
401
- fontWeight: 'bold',
402
- marginLeft: '0.5rem',
403
- textTransform: 'uppercase'
404
- }}>
405
- {state.environment}
406
- </span>
407
- </p>
408
- </div>
409
- </div>
410
-
411
- <div style={{ display: 'flex', gap: '0.5rem' }}>
412
- <button
413
- onClick={() => setShowSensitive(!showSensitive)}
414
- style={{
415
- display: 'flex',
416
- alignItems: 'center',
417
- gap: '0.5rem',
418
- padding: '0.75rem 1rem',
419
- borderRadius: '8px',
420
- border: '1px solid #d1d5db',
421
- cursor: 'pointer',
422
- backgroundColor: 'white',
423
- color: '#6b7280',
424
- fontSize: '0.9rem'
425
- }}
426
- >
427
- {showSensitive ? <FaEyeSlash /> : <FaEye />}
428
- {showSensitive ? 'Ocultar' : 'Mostrar'} Sensíveis
429
- </button>
430
-
431
- <button
432
- onClick={handleRefreshConfiguration}
433
- style={{
434
- display: 'flex',
435
- alignItems: 'center',
436
- gap: '0.5rem',
437
- padding: '0.75rem 1rem',
438
- borderRadius: '8px',
439
- border: '1px solid #d1d5db',
440
- cursor: 'pointer',
441
- backgroundColor: 'white',
442
- color: '#3b82f6',
443
- fontSize: '0.9rem'
444
- }}
445
- >
446
- <FaSync />
447
- Atualizar
448
- </button>
449
-
450
- <button
451
- onClick={handleValidateConfiguration}
452
- style={{
453
- display: 'flex',
454
- alignItems: 'center',
455
- gap: '0.5rem',
456
- padding: '0.75rem 1rem',
457
- borderRadius: '8px',
458
- border: '1px solid #d1d5db',
459
- cursor: 'pointer',
460
- backgroundColor: 'white',
461
- color: '#10b981',
462
- fontSize: '0.9rem'
463
- }}
464
- >
465
- <FaCheckCircle />
466
- Validar
467
- </button>
468
-
469
- <button
470
- onClick={handleExportConfiguration}
471
- style={{
472
- display: 'flex',
473
- alignItems: 'center',
474
- gap: '0.5rem',
475
- padding: '0.75rem 1rem',
476
- borderRadius: '8px',
477
- border: '1px solid #d1d5db',
478
- cursor: 'pointer',
479
- backgroundColor: '#3b82f6',
480
- color: 'white',
481
- fontSize: '0.9rem'
482
- }}
483
- >
484
- <FaDownload />
485
- Exportar
486
- </button>
487
- </div>
488
- </div>
489
-
490
- {/* Tabs */}
491
- <div style={{
492
- display: 'flex',
493
- backgroundColor: 'white',
494
- borderRadius: '12px',
495
- padding: '0.5rem',
496
- marginBottom: '2rem',
497
- boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
498
- overflowX: 'auto'
499
- }}>
500
- {tabs.map((tab) => {
501
- const Icon = tab.icon
502
- const isActive = activeTab === tab.id
503
-
504
- return (
505
- <button
506
- key={tab.id}
507
- onClick={() => setActiveTab(tab.id)}
508
- style={{
509
- display: 'flex',
510
- alignItems: 'center',
511
- gap: '0.5rem',
512
- padding: '0.75rem 1rem',
513
- borderRadius: '8px',
514
- border: 'none',
515
- cursor: 'pointer',
516
- backgroundColor: isActive ? '#3b82f6' : 'transparent',
517
- color: isActive ? 'white' : '#6b7280',
518
- fontSize: '0.9rem',
519
- fontWeight: isActive ? 'bold' : 'normal',
520
- transition: 'all 0.2s ease',
521
- whiteSpace: 'nowrap'
522
- }}
523
- >
524
- <Icon size={16} />
525
- {tab.label}
526
- </button>
527
- )
528
- })}
529
- </div>
530
-
531
- {/* Content */}
532
- <div style={{
533
- backgroundColor: 'white',
534
- borderRadius: '16px',
535
- padding: '2rem',
536
- boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
537
- minHeight: '600px'
538
- }}>
539
- {/* Overview Tab */}
540
- {activeTab === 'overview' && (
541
- <div>
542
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
543
- <FaInfoCircle />
544
- Visão Geral do Sistema
545
- </h2>
546
-
547
- <div style={{
548
- display: 'grid',
549
- gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
550
- gap: '1.5rem',
551
- marginBottom: '2rem'
552
- }}>
553
- {/* Framework Info */}
554
- <div style={{
555
- padding: '1.5rem',
556
- backgroundColor: '#f8fafc',
557
- borderRadius: '12px',
558
- border: '1px solid #e2e8f0'
559
- }}>
560
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
561
- <FaRocket style={{ color: '#3b82f6' }} />
562
- Framework
563
- </h3>
564
- <div style={{ color: '#6b7280', lineHeight: 1.6 }}>
565
- <p><strong>Nome:</strong> {state.framework.name}</p>
566
- <p><strong>Versão:</strong> {state.framework.version}</p>
567
- <p><strong>Licença:</strong> {state.framework.license}</p>
568
- <p><strong>Descrição:</strong> {state.framework.description}</p>
569
- </div>
570
- </div>
571
-
572
- {/* Server Info */}
573
- <div style={{
574
- padding: '1.5rem',
575
- backgroundColor: '#f8fafc',
576
- borderRadius: '12px',
577
- border: '1px solid #e2e8f0'
578
- }}>
579
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
580
- <FaServer style={{ color: '#10b981' }} />
581
- Servidor
582
- </h3>
583
- <div style={{ color: '#6b7280', lineHeight: 1.6 }}>
584
- <p><strong>Host:</strong> {state.host}</p>
585
- <p><strong>Porta:</strong> {state.port}</p>
586
- <p><strong>API Prefix:</strong> {state.apiPrefix}</p>
587
- <p><strong>Ambiente:</strong>
588
- <span style={{
589
- color: getEnvironmentColor(),
590
- fontWeight: 'bold',
591
- marginLeft: '0.5rem'
592
- }}>
593
- {state.environment.toUpperCase()}
594
- </span>
595
- </p>
596
- </div>
597
- </div>
598
-
599
- {/* System Resources */}
600
- <div style={{
601
- padding: '1.5rem',
602
- backgroundColor: '#f8fafc',
603
- borderRadius: '12px',
604
- border: '1px solid #e2e8f0'
605
- }}>
606
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
607
- <FaMemory style={{ color: '#f59e0b' }} />
608
- Recursos do Sistema
609
- </h3>
610
- <div style={{ color: '#6b7280', lineHeight: 1.6 }}>
611
- <p><strong>CPUs:</strong> {state.runtime.cpuCount} cores</p>
612
- <p><strong>Memória:</strong> {formatBytes(state.runtime.totalMemory)}</p>
613
- <p><strong>Plataforma:</strong> {state.runtime.platform} ({state.runtime.architecture})</p>
614
- <p><strong>Node:</strong> {state.runtime.nodeVersion}</p>
615
- </div>
616
- </div>
617
- </div>
618
-
619
- {/* Quick Status */}
620
- <div style={{
621
- padding: '1.5rem',
622
- backgroundColor: '#f0f9ff',
623
- borderRadius: '12px',
624
- border: '1px solid #0ea5e9'
625
- }}>
626
- <h3 style={{ color: '#0369a1', marginBottom: '1rem' }}>
627
- 🎯 Status dos Componentes
628
- </h3>
629
- <div style={{
630
- display: 'grid',
631
- gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
632
- gap: '1rem'
633
- }}>
634
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', color: '#0369a1' }}>
635
- {getStatusIcon(state.liveComponents.enabled)}
636
- <span>Live Components</span>
637
- </div>
638
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', color: '#0369a1' }}>
639
- {getStatusIcon(state.vite.enabled)}
640
- <span>Vite Dev Server</span>
641
- </div>
642
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', color: '#0369a1' }}>
643
- {getStatusIcon(state.staticFiles.enabled)}
644
- <span>Static Files</span>
645
- </div>
646
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', color: '#0369a1' }}>
647
- {getStatusIcon(state.swagger.enabled)}
648
- <span>Swagger Documentation</span>
649
- </div>
650
- </div>
651
- </div>
652
- </div>
653
- )}
654
-
655
- {/* Runtime Tab */}
656
- {activeTab === 'runtime' && (
657
- <div>
658
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
659
- <FaTerminal />
660
- Informações de Runtime
661
- </h2>
662
-
663
- <div style={{
664
- display: 'grid',
665
- gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
666
- gap: '1.5rem'
667
- }}>
668
- {/* Runtime Versions */}
669
- <div style={{
670
- padding: '1.5rem',
671
- backgroundColor: '#f8fafc',
672
- borderRadius: '12px',
673
- border: '1px solid #e2e8f0'
674
- }}>
675
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
676
- <FaCode style={{ color: '#3b82f6' }} />
677
- Versões
678
- </h3>
679
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
680
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
681
- <span>Node.js:</span>
682
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>{state.runtime.nodeVersion}</span>
683
- </div>
684
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
685
- <span>Bun:</span>
686
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>{state.runtime.bunVersion}</span>
687
- </div>
688
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
689
- <span>Plataforma:</span>
690
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>{state.runtime.platform}</span>
691
- </div>
692
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
693
- <span>Arquitetura:</span>
694
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>{state.runtime.architecture}</span>
695
- </div>
696
- </div>
697
- </div>
698
-
699
- {/* System Resources */}
700
- <div style={{
701
- padding: '1.5rem',
702
- backgroundColor: '#f8fafc',
703
- borderRadius: '12px',
704
- border: '1px solid #e2e8f0'
705
- }}>
706
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
707
- <FaMemory style={{ color: '#10b981' }} />
708
- Recursos
709
- </h3>
710
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
711
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
712
- <span>CPUs:</span>
713
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>{state.runtime.cpuCount} cores</span>
714
- </div>
715
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
716
- <span>Memória Total:</span>
717
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>{formatBytes(state.runtime.totalMemory)}</span>
718
- </div>
719
- </div>
720
- </div>
721
-
722
- {/* Paths */}
723
- <div style={{
724
- padding: '1.5rem',
725
- backgroundColor: '#f8fafc',
726
- borderRadius: '12px',
727
- border: '1px solid #e2e8f0',
728
- gridColumn: '1 / -1'
729
- }}>
730
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
731
- <FaFolder style={{ color: '#f59e0b' }} />
732
- Caminhos do Sistema
733
- </h3>
734
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
735
- <div style={{ marginBottom: '1rem' }}>
736
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', marginBottom: '0.5rem' }}>
737
- <span style={{ fontWeight: 'bold' }}>Diretório de Trabalho:</span>
738
- <button
739
- onClick={() => copyToClipboard(state.runtime.workingDirectory)}
740
- style={{
741
- padding: '0.25rem 0.5rem',
742
- fontSize: '0.75rem',
743
- border: '1px solid #d1d5db',
744
- borderRadius: '4px',
745
- backgroundColor: 'white',
746
- cursor: 'pointer'
747
- }}
748
- >
749
- <FaCopy />
750
- </button>
751
- </div>
752
- <span style={{
753
- fontFamily: 'monospace',
754
- color: '#374151',
755
- backgroundColor: '#f3f4f6',
756
- padding: '0.5rem',
757
- borderRadius: '4px',
758
- display: 'block',
759
- wordBreak: 'break-all'
760
- }}>
761
- {state.runtime.workingDirectory}
762
- </span>
763
- </div>
764
-
765
- <div>
766
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', marginBottom: '0.5rem' }}>
767
- <span style={{ fontWeight: 'bold' }}>Executável:</span>
768
- <button
769
- onClick={() => copyToClipboard(state.runtime.executablePath)}
770
- style={{
771
- padding: '0.25rem 0.5rem',
772
- fontSize: '0.75rem',
773
- border: '1px solid #d1d5db',
774
- borderRadius: '4px',
775
- backgroundColor: 'white',
776
- cursor: 'pointer'
777
- }}
778
- >
779
- <FaCopy />
780
- </button>
781
- </div>
782
- <span style={{
783
- fontFamily: 'monospace',
784
- color: '#374151',
785
- backgroundColor: '#f3f4f6',
786
- padding: '0.5rem',
787
- borderRadius: '4px',
788
- display: 'block',
789
- wordBreak: 'break-all'
790
- }}>
791
- {showSensitive ? state.runtime.executablePath : '***hidden***'}
792
- </span>
793
- </div>
794
- </div>
795
- </div>
796
- </div>
797
- </div>
798
- )}
799
-
800
- {/* Plugins Tab */}
801
- {activeTab === 'plugins' && (
802
- <div>
803
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
804
- <FaPlug />
805
- Plugins Instalados ({state.plugins.length})
806
- </h2>
807
-
808
- <div style={{
809
- display: 'grid',
810
- gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))',
811
- gap: '1.5rem'
812
- }}>
813
- {state.plugins.map((plugin, index) => (
814
- <div key={index} style={{
815
- padding: '1.5rem',
816
- backgroundColor: plugin.enabled ? '#f0fdf4' : '#fef2f2',
817
- borderRadius: '12px',
818
- border: `1px solid ${plugin.enabled ? '#16a34a' : '#dc2626'}`
819
- }}>
820
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '1rem' }}>
821
- <h3 style={{
822
- color: '#374151',
823
- margin: 0,
824
- display: 'flex',
825
- alignItems: 'center',
826
- gap: '0.5rem'
827
- }}>
828
- {getStatusIcon(plugin.enabled)}
829
- {plugin.name}
830
- </h3>
831
- <span style={{
832
- backgroundColor: plugin.enabled ? '#16a34a' : '#dc2626',
833
- color: 'white',
834
- padding: '0.25rem 0.5rem',
835
- borderRadius: '4px',
836
- fontSize: '0.75rem',
837
- fontWeight: 'bold'
838
- }}>
839
- {plugin.enabled ? 'ATIVO' : 'INATIVO'}
840
- </span>
841
- </div>
842
-
843
- <div style={{ color: '#6b7280', lineHeight: 1.6 }}>
844
- <p><strong>Versão:</strong> {plugin.version}</p>
845
- {plugin.dependencies.length > 0 && (
846
- <p><strong>Dependências:</strong> {plugin.dependencies.join(', ')}</p>
847
- )}
848
-
849
- {plugin.config && Object.keys(plugin.config).length > 0 && (
850
- <div>
851
- <p><strong>Configuração:</strong></p>
852
- <div style={{
853
- backgroundColor: '#f3f4f6',
854
- padding: '0.75rem',
855
- borderRadius: '6px',
856
- fontFamily: 'monospace',
857
- fontSize: '0.85rem',
858
- marginTop: '0.5rem'
859
- }}>
860
- {Object.entries(plugin.config).map(([key, value]) => (
861
- <div key={key} style={{ marginBottom: '0.25rem' }}>
862
- <span style={{ color: '#7c3aed' }}>{key}:</span> {' '}
863
- <span style={{ color: '#059669' }}>
864
- {typeof value === 'string' ? `"${value}"` : JSON.stringify(value)}
865
- </span>
866
- </div>
867
- ))}
868
- </div>
869
- </div>
870
- )}
871
- </div>
872
- </div>
873
- ))}
874
- </div>
875
- </div>
876
- )}
877
-
878
- {/* Live Components Tab */}
879
- {activeTab === 'livecomponents' && (
880
- <div>
881
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
882
- <FaBolt />
883
- Live Components Configuration
884
- </h2>
885
-
886
- <div style={{
887
- display: 'grid',
888
- gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
889
- gap: '1.5rem'
890
- }}>
891
- {/* Main Settings */}
892
- <div style={{
893
- padding: '1.5rem',
894
- backgroundColor: '#f8fafc',
895
- borderRadius: '12px',
896
- border: '1px solid #e2e8f0'
897
- }}>
898
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
899
- <FaCog style={{ color: '#3b82f6' }} />
900
- Configurações Principais
901
- </h3>
902
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
903
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
904
- <span>Status:</span>
905
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
906
- {getStatusIcon(state.liveComponents.enabled)}
907
- <span style={{ fontWeight: 'bold', color: state.liveComponents.enabled ? '#10b981' : '#ef4444' }}>
908
- {state.liveComponents.enabled ? 'ATIVO' : 'INATIVO'}
909
- </span>
910
- </div>
911
- </div>
912
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
913
- <span>Auto-discovery:</span>
914
- <span style={{ fontWeight: 'bold' }}>
915
- {state.liveComponents.autoDiscovery ? 'SIM' : 'NÃO'}
916
- </span>
917
- </div>
918
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
919
- <span>WebSocket Path:</span>
920
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
921
- {state.liveComponents.websocketPath}
922
- </span>
923
- </div>
924
- </div>
925
- </div>
926
-
927
- {/* Performance Settings */}
928
- <div style={{
929
- padding: '1.5rem',
930
- backgroundColor: '#f8fafc',
931
- borderRadius: '12px',
932
- border: '1px solid #e2e8f0'
933
- }}>
934
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
935
- <FaBolt style={{ color: '#10b981' }} />
936
- Performance
937
- </h3>
938
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
939
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
940
- <span>Max Connections:</span>
941
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
942
- {state.liveComponents.maxConnections.toLocaleString()}
943
- </span>
944
- </div>
945
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
946
- <span>Timeout:</span>
947
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
948
- {formatMs(state.liveComponents.timeout)}
949
- </span>
950
- </div>
951
- </div>
952
- </div>
953
-
954
- {/* Security */}
955
- <div style={{
956
- padding: '1.5rem',
957
- backgroundColor: '#f8fafc',
958
- borderRadius: '12px',
959
- border: '1px solid #e2e8f0'
960
- }}>
961
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
962
- <FaLock style={{ color: '#f59e0b' }} />
963
- Segurança
964
- </h3>
965
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
966
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
967
- <span>Signature Secret:</span>
968
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
969
- {showSensitive ? state.liveComponents.signatureSecret : '***hidden***'}
970
- </span>
971
- </div>
972
- </div>
973
- </div>
974
- </div>
975
- </div>
976
- )}
977
-
978
- {/* Security Tab */}
979
- {activeTab === 'security' && (
980
- <div>
981
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
982
- <FaLock />
983
- Configurações de Segurança
984
- </h2>
985
-
986
- <div style={{
987
- display: 'grid',
988
- gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
989
- gap: '1.5rem'
990
- }}>
991
- {/* CORS */}
992
- <div style={{
993
- padding: '1.5rem',
994
- backgroundColor: '#f8fafc',
995
- borderRadius: '12px',
996
- border: '1px solid #e2e8f0'
997
- }}>
998
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
999
- <FaGlobe style={{ color: '#3b82f6' }} />
1000
- CORS
1001
- </h3>
1002
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
1003
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1004
- <span>Status:</span>
1005
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1006
- {getStatusIcon(state.security.cors.enabled)}
1007
- <span style={{ fontWeight: 'bold' }}>
1008
- {state.security.cors.enabled ? 'ATIVO' : 'INATIVO'}
1009
- </span>
1010
- </div>
1011
- </div>
1012
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1013
- <span>Credentials:</span>
1014
- <span style={{ fontWeight: 'bold' }}>
1015
- {state.security.cors.credentials ? 'SIM' : 'NÃO'}
1016
- </span>
1017
- </div>
1018
- <div style={{ marginTop: '1rem' }}>
1019
- <span style={{ fontWeight: 'bold' }}>Origins Permitidas:</span>
1020
- <div style={{ marginTop: '0.5rem' }}>
1021
- {state.security.cors.origins.map((origin, index) => (
1022
- <div key={index} style={{
1023
- backgroundColor: '#e0f2fe',
1024
- padding: '0.5rem',
1025
- borderRadius: '4px',
1026
- fontFamily: 'monospace',
1027
- fontSize: '0.85rem',
1028
- marginBottom: '0.25rem'
1029
- }}>
1030
- {origin}
1031
- </div>
1032
- ))}
1033
- </div>
1034
- </div>
1035
- </div>
1036
- </div>
1037
-
1038
- {/* Rate Limiting */}
1039
- <div style={{
1040
- padding: '1.5rem',
1041
- backgroundColor: '#f8fafc',
1042
- borderRadius: '12px',
1043
- border: '1px solid #e2e8f0'
1044
- }}>
1045
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1046
- <FaTachometerAlt style={{ color: '#f59e0b' }} />
1047
- Rate Limiting
1048
- </h3>
1049
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
1050
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1051
- <span>Status:</span>
1052
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1053
- {getStatusIcon(state.security.rateLimit.enabled)}
1054
- <span style={{ fontWeight: 'bold' }}>
1055
- {state.security.rateLimit.enabled ? 'ATIVO' : 'INATIVO'}
1056
- </span>
1057
- </div>
1058
- </div>
1059
- {state.security.rateLimit.enabled && (
1060
- <>
1061
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1062
- <span>Janela:</span>
1063
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
1064
- {formatMs(state.security.rateLimit.windowMs)}
1065
- </span>
1066
- </div>
1067
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1068
- <span>Max Requests:</span>
1069
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
1070
- {state.security.rateLimit.maxRequests}
1071
- </span>
1072
- </div>
1073
- </>
1074
- )}
1075
- </div>
1076
- </div>
1077
-
1078
- {/* Helmet */}
1079
- <div style={{
1080
- padding: '1.5rem',
1081
- backgroundColor: '#f8fafc',
1082
- borderRadius: '12px',
1083
- border: '1px solid #e2e8f0'
1084
- }}>
1085
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1086
- <FaLock style={{ color: '#10b981' }} />
1087
- Helmet (Security Headers)
1088
- </h3>
1089
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
1090
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1091
- <span>Status:</span>
1092
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1093
- {getStatusIcon(state.security.helmet.enabled)}
1094
- <span style={{ fontWeight: 'bold' }}>
1095
- {state.security.helmet.enabled ? 'ATIVO' : 'INATIVO'}
1096
- </span>
1097
- </div>
1098
- </div>
1099
- </div>
1100
- </div>
1101
- </div>
1102
- </div>
1103
- )}
1104
-
1105
- {/* Performance Tab */}
1106
- {activeTab === 'performance' && (
1107
- <div>
1108
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1109
- <FaTachometerAlt />
1110
- Configurações de Performance
1111
- </h2>
1112
-
1113
- <div style={{
1114
- display: 'grid',
1115
- gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
1116
- gap: '1.5rem'
1117
- }}>
1118
- {/* Compression */}
1119
- <div style={{
1120
- padding: '1.5rem',
1121
- backgroundColor: '#f8fafc',
1122
- borderRadius: '12px',
1123
- border: '1px solid #e2e8f0'
1124
- }}>
1125
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1126
- <FaDatabase style={{ color: '#3b82f6' }} />
1127
- Compressão
1128
- </h3>
1129
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
1130
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1131
- <span>Status:</span>
1132
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1133
- {getStatusIcon(state.performance.compression)}
1134
- <span style={{ fontWeight: 'bold' }}>
1135
- {state.performance.compression ? 'ATIVO' : 'INATIVO'}
1136
- </span>
1137
- </div>
1138
- </div>
1139
- </div>
1140
- </div>
1141
-
1142
- {/* Cache */}
1143
- <div style={{
1144
- padding: '1.5rem',
1145
- backgroundColor: '#f8fafc',
1146
- borderRadius: '12px',
1147
- border: '1px solid #e2e8f0'
1148
- }}>
1149
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1150
- <FaMemory style={{ color: '#10b981' }} />
1151
- Cache
1152
- </h3>
1153
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
1154
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1155
- <span>Status:</span>
1156
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1157
- {getStatusIcon(state.performance.cache.enabled)}
1158
- <span style={{ fontWeight: 'bold' }}>
1159
- {state.performance.cache.enabled ? 'ATIVO' : 'INATIVO'}
1160
- </span>
1161
- </div>
1162
- </div>
1163
- {state.performance.cache.enabled && (
1164
- <>
1165
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1166
- <span>Max Age:</span>
1167
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
1168
- {state.performance.cache.maxAge}s
1169
- </span>
1170
- </div>
1171
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1172
- <span>Strategy:</span>
1173
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
1174
- {state.performance.cache.strategy}
1175
- </span>
1176
- </div>
1177
- </>
1178
- )}
1179
- </div>
1180
- </div>
1181
-
1182
- {/* Clustering */}
1183
- <div style={{
1184
- padding: '1.5rem',
1185
- backgroundColor: '#f8fafc',
1186
- borderRadius: '12px',
1187
- border: '1px solid #e2e8f0'
1188
- }}>
1189
- <h3 style={{ color: '#374151', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1190
- <FaServer style={{ color: '#f59e0b' }} />
1191
- Clustering
1192
- </h3>
1193
- <div style={{ color: '#6b7280', lineHeight: 1.8 }}>
1194
- <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.5rem' }}>
1195
- <span>Status:</span>
1196
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1197
- {getStatusIcon(state.performance.clustering.enabled)}
1198
- <span style={{ fontWeight: 'bold' }}>
1199
- {state.performance.clustering.enabled ? 'ATIVO' : 'INATIVO'}
1200
- </span>
1201
- </div>
1202
- </div>
1203
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
1204
- <span>Workers:</span>
1205
- <span style={{ fontFamily: 'monospace', color: '#374151' }}>
1206
- {state.performance.clustering.workers}
1207
- </span>
1208
- </div>
1209
- </div>
1210
- </div>
1211
- </div>
1212
- </div>
1213
- )}
1214
-
1215
- {/* Advanced Tab */}
1216
- {activeTab === 'advanced' && (
1217
- <div>
1218
- <h2 style={{ color: '#374151', marginBottom: '1.5rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1219
- <FaTools />
1220
- Configurações Avançadas
1221
- </h2>
1222
-
1223
- <div style={{
1224
- display: 'grid',
1225
- gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
1226
- gap: '1.5rem'
1227
- }}>
1228
- {Object.entries(state.advanced).map(([key, value]) => (
1229
- <div key={key} style={{
1230
- padding: '1.5rem',
1231
- backgroundColor: '#f8fafc',
1232
- borderRadius: '12px',
1233
- border: '1px solid #e2e8f0'
1234
- }}>
1235
- <h3 style={{
1236
- color: '#374151',
1237
- marginBottom: '1rem',
1238
- fontSize: '1rem',
1239
- textTransform: 'capitalize'
1240
- }}>
1241
- {key.replace(/([A-Z])/g, ' $1').trim()}
1242
- </h3>
1243
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1244
- {getStatusIcon(value as boolean)}
1245
- <span style={{
1246
- fontWeight: 'bold',
1247
- color: value ? '#10b981' : '#ef4444'
1248
- }}>
1249
- {value ? 'ATIVO' : 'INATIVO'}
1250
- </span>
1251
- </div>
1252
- </div>
1253
- ))}
1254
- </div>
1255
-
1256
- {/* Vite Configuration */}
1257
- <div style={{
1258
- marginTop: '2rem',
1259
- padding: '1.5rem',
1260
- backgroundColor: '#f0f9ff',
1261
- borderRadius: '12px',
1262
- border: '1px solid #0ea5e9'
1263
- }}>
1264
- <h3 style={{ color: '#0369a1', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
1265
- <FaBolt style={{ color: '#0ea5e9' }} />
1266
- Vite Development Server
1267
- </h3>
1268
- <div style={{
1269
- display: 'grid',
1270
- gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
1271
- gap: '1rem',
1272
- color: '#0369a1'
1273
- }}>
1274
- <div>
1275
- <span style={{ fontWeight: 'bold' }}>Status:</span>
1276
- <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', marginTop: '0.25rem' }}>
1277
- {getStatusIcon(state.vite.enabled)}
1278
- <span>{state.vite.enabled ? 'ATIVO' : 'INATIVO'}</span>
1279
- </div>
1280
- </div>
1281
- <div>
1282
- <span style={{ fontWeight: 'bold' }}>Porta:</span>
1283
- <div style={{ fontFamily: 'monospace', marginTop: '0.25rem' }}>{state.vite.port}</div>
1284
- </div>
1285
- <div>
1286
- <span style={{ fontWeight: 'bold' }}>HMR:</span>
1287
- <div style={{ marginTop: '0.25rem' }}>{state.vite.hmr ? 'SIM' : 'NÃO'}</div>
1288
- </div>
1289
- <div>
1290
- <span style={{ fontWeight: 'bold' }}>Build Dir:</span>
1291
- <div style={{ fontFamily: 'monospace', marginTop: '0.25rem' }}>{state.vite.buildDir}</div>
1292
- </div>
1293
- </div>
1294
- </div>
1295
- </div>
1296
- )}
1297
- </div>
1298
-
1299
- {/* Footer */}
1300
- <div style={{
1301
- marginTop: '2rem',
1302
- padding: '1rem 1.5rem',
1303
- backgroundColor: '#f8fafc',
1304
- borderRadius: '12px',
1305
- border: '1px solid #e2e8f0',
1306
- display: 'flex',
1307
- justifyContent: 'space-between',
1308
- alignItems: 'center',
1309
- color: '#6b7280',
1310
- fontSize: '0.9rem'
1311
- }}>
1312
- <span>
1313
- Última atualização: {new Date(state.lastUpdated).toLocaleString('pt-BR')}
1314
- </span>
1315
- <span>
1316
- 🔥 FluxStack v{state.framework.version} • {state.environment.toUpperCase()}
1317
- </span>
1318
- </div>
1319
- </div>
1320
- )
1321
- }