create-fluxstack 1.0.13 β†’ 1.0.15

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 +196 -33
  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
@@ -1,8 +1,24 @@
1
1
  import { useState, useEffect } from 'react'
2
2
  import { api, getErrorMessage } from './lib/eden-api'
3
- import TestPage from './components/TestPage'
4
-
5
- type TabType = 'overview' | 'demo' | 'api-docs' | 'tests'
3
+ import {
4
+ FaRocket, FaReact, FaLink, FaDocker, FaFlask, FaPalette,
5
+ FaCheckCircle, FaTimesCircle, FaSpinner, FaSync,
6
+ FaUsers, FaTrash, FaPlus, FaBook, FaCode, FaCog,
7
+ FaServer, FaDatabase, FaShieldAlt, FaBolt, FaLock,
8
+ FaBullseye, FaGlobe, FaFileAlt,
9
+ FaClipboardList, FaFire, FaFlask as FaTest,
10
+ } from 'react-icons/fa'
11
+ import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
12
+
13
+ // Import page components
14
+ import { OverviewPage } from './pages/Overview'
15
+ import { DemoPage } from './pages/Demo'
16
+ import { HybridLivePage } from './pages/HybridLive'
17
+ import { ApiDocsPage } from './pages/ApiDocs'
18
+ import { MainLayout } from './components/MainLayout'
19
+ import { LiveClock } from './components/LiveClock'
20
+
21
+ // State management is now handled by Zustand stores directly
6
22
 
7
23
  interface User {
8
24
  id: number
@@ -11,8 +27,7 @@ interface User {
11
27
  createdAt: string
12
28
  }
13
29
 
14
- function App() {
15
- const [activeTab, setActiveTab] = useState<TabType>('overview')
30
+ function AppContent() {
16
31
  const [users, setUsers] = useState<User[]>([])
17
32
  const [loading, setLoading] = useState(false)
18
33
  const [apiStatus, setApiStatus] = useState<'online' | 'offline'>('offline')
@@ -49,7 +64,6 @@ function App() {
49
64
  return
50
65
  }
51
66
 
52
- // ✨ Eden Treaty infere automaticamente que data.users é User[]
53
67
  setUsers(data.users || [])
54
68
  } catch (error) {
55
69
  showMessage('error', getErrorMessage(error))
@@ -74,7 +88,6 @@ function App() {
74
88
  return
75
89
  }
76
90
 
77
- // ✨ Eden Treaty infere que result é UserResponse
78
91
  if (result.success && result.user) {
79
92
  setUsers(prev => [...prev, result.user])
80
93
  setName('')
@@ -94,7 +107,6 @@ function App() {
94
107
  if (!confirm(`Tem certeza que deseja remover ${userName}?`)) return
95
108
 
96
109
  try {
97
- // ✨ Chamar API de delete via Eden Treaty nativo
98
110
  const { data: result, error } = await api.users({ id: userId }).delete()
99
111
 
100
112
  if (error) {
@@ -102,9 +114,7 @@ function App() {
102
114
  return
103
115
  }
104
116
 
105
- // ✨ Eden Treaty infere que result é UserResponse
106
117
  if (result.success) {
107
- // Remover da lista local apΓ³s sucesso da API
108
118
  setUsers(prev => prev.filter(user => user.id !== userId))
109
119
  showMessage('success', `UsuΓ‘rio ${userName} removido com sucesso!`)
110
120
  } else {
@@ -124,525 +134,141 @@ function App() {
124
134
  return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)
125
135
  }
126
136
 
127
- const renderOverview = () => (
128
- <div className="relative">
129
- {/* Hero Section with gradient background */}
130
- <div className="relative overflow-hidden bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 rounded-3xl mb-12">
131
- <div className="absolute inset-0 bg-gradient-to-r from-blue-900/20 to-purple-900/20"></div>
132
- <div className="relative px-8 py-16 text-center">
133
- <div className="mx-auto max-w-4xl">
134
- <h1 className="text-5xl font-bold text-white mb-6 bg-gradient-to-r from-blue-400 via-purple-400 to-emerald-400 bg-clip-text text-transparent">
135
- πŸ”₯ FluxStack v1.4.0 ⚑
136
- </h1>
137
- <p className="text-xl text-slate-300 mb-8 max-w-2xl mx-auto leading-relaxed">
138
- Framework full-stack TypeScript moderno com hot reload coordenado e Tailwind CSS 4! πŸš€
139
- </p>
140
- <div className="flex flex-wrap justify-center gap-3 mb-8">
141
- <span className="px-4 py-2 bg-blue-500/20 text-blue-300 rounded-full text-sm font-medium border border-blue-500/30">
142
- TypeScript
143
- </span>
144
- <span className="px-4 py-2 bg-purple-500/20 text-purple-300 rounded-full text-sm font-medium border border-purple-500/30">
145
- Elysia.js
146
- </span>
147
- <span className="px-4 py-2 bg-emerald-500/20 text-emerald-300 rounded-full text-sm font-medium border border-emerald-500/30">
148
- React 19
149
- </span>
150
- <span className="px-4 py-2 bg-orange-500/20 text-orange-300 rounded-full text-sm font-medium border border-orange-500/30">
151
- Tailwind CSS 4
152
- </span>
153
- </div>
154
- </div>
155
- </div>
156
- </div>
157
-
158
- {/* Features Grid */}
159
- <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 mb-12">
160
- {[
161
- {
162
- icon: "πŸš€",
163
- title: "Elysia.js",
164
- description: "Backend rΓ‘pido e type-safe com Bun runtime",
165
- color: "from-blue-500 to-cyan-500"
166
- },
167
- {
168
- icon: "βš›οΈ",
169
- title: "React + Vite",
170
- description: "Frontend moderno com hot-reload ultrarrΓ‘pido",
171
- color: "from-purple-500 to-pink-500"
172
- },
173
- {
174
- icon: "πŸ”—",
175
- title: "Eden Treaty",
176
- description: "API type-safe com inferΓͺncia automΓ‘tica de tipos",
177
- color: "from-emerald-500 to-teal-500"
178
- },
179
- {
180
- icon: "🐳",
181
- title: "Docker Ready",
182
- description: "Deploy fΓ‘cil com configuraΓ§Γ΅es otimizadas",
183
- color: "from-indigo-500 to-purple-500"
184
- },
185
- {
186
- icon: "πŸ§ͺ",
187
- title: "Testing",
188
- description: "Vitest + Testing Library configurados",
189
- color: "from-orange-500 to-red-500"
190
- },
191
- {
192
- icon: "🎨",
193
- title: "Tailwind CSS 4",
194
- description: "Styling moderno e responsivo",
195
- color: "from-teal-500 to-green-500"
196
- }
197
- ].map((feature, index) => (
198
- <div
199
- key={index}
200
- className="group relative bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 border border-gray-200"
201
- >
202
- <div className={`absolute inset-0 bg-gradient-to-r ${feature.color} opacity-0 group-hover:opacity-5 rounded-2xl transition-opacity duration-300`}></div>
203
- <div className="relative">
204
- <div className="text-4xl mb-4">{feature.icon}</div>
205
- <h3 className="text-xl font-semibold text-gray-900 mb-2">{feature.title}</h3>
206
- <p className="text-gray-600 leading-relaxed">{feature.description}</p>
207
- </div>
208
- </div>
209
- ))}
210
- </div>
211
-
212
- {/* Tech Stack Section */}
213
- <div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
214
- <div className="bg-gradient-to-r from-gray-50 to-slate-100 px-8 py-6 border-b border-gray-200">
215
- <h2 className="text-2xl font-bold text-gray-900 text-center">Stack TecnolΓ³gica</h2>
216
- </div>
217
- <div className="p-8">
218
- <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
219
- {[
220
- {
221
- title: "Backend",
222
- color: "blue",
223
- items: [
224
- "Elysia.js - Web framework",
225
- "Bun - Runtime & package manager",
226
- "TypeScript - Type safety"
227
- ]
228
- },
229
- {
230
- title: "Frontend",
231
- color: "purple",
232
- items: [
233
- "React 19 - UI library",
234
- "Vite - Build tool",
235
- "Tailwind CSS 4 - Styling"
236
- ]
237
- },
238
- {
239
- title: "ComunicaΓ§Γ£o",
240
- color: "emerald",
241
- items: [
242
- "Eden Treaty - Type-safe API",
243
- "End-to-end TypeScript",
244
- "Automatic type inference"
245
- ]
246
- }
247
- ].map((category, index) => (
248
- <div key={index} className="space-y-4">
249
- <h3 className={`text-lg font-semibold text-${category.color}-600 pb-2 border-b-2 border-${category.color}-100`}>
250
- {category.title}
251
- </h3>
252
- <ul className="space-y-3">
253
- {category.items.map((item, itemIndex) => (
254
- <li key={itemIndex} className="flex items-start gap-3 text-gray-600">
255
- <div className={`w-2 h-2 rounded-full bg-${category.color}-400 flex-shrink-0 mt-2`}></div>
256
- <span>{item}</span>
257
- </li>
258
- ))}
259
- </ul>
260
- </div>
261
- ))}
262
- </div>
263
- </div>
264
- </div>
265
- </div>
266
- )
267
-
268
- const renderDemo = () => (
269
- <div className="space-y-8">
270
- {/* Header */}
271
- <div className="text-center">
272
- <h2 className="text-3xl font-bold text-gray-900 mb-4">πŸ”₯ Demo Interativo</h2>
273
- <p className="text-lg text-gray-600 max-w-2xl mx-auto">
274
- Teste a API em tempo real com hot reload coordenado e Eden Treaty πŸš€
275
- </p>
276
- </div>
277
-
278
- {/* Stats Cards */}
279
- <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
280
- <div className="bg-gradient-to-br from-blue-50 to-blue-100 border border-blue-200 rounded-2xl p-6 text-center">
281
- <div className="text-4xl font-bold text-blue-600 mb-2">{users.length}</div>
282
- <div className="text-sm font-medium text-blue-700 uppercase tracking-wide">UsuΓ‘rios</div>
283
- </div>
284
- <div className={`bg-gradient-to-br ${apiStatus === 'online' ? 'from-emerald-50 to-emerald-100 border-emerald-200' : 'from-red-50 to-red-100 border-red-200'} border rounded-2xl p-6 text-center`}>
285
- <div className="text-4xl mb-2">{apiStatus === 'online' ? 'βœ…' : '❌'}</div>
286
- <div className={`text-sm font-medium uppercase tracking-wide ${apiStatus === 'online' ? 'text-emerald-700' : 'text-red-700'}`}>
287
- API {apiStatus === 'online' ? 'Online' : 'Offline'}
288
- </div>
289
- </div>
290
- <div className="bg-gradient-to-br from-purple-50 to-purple-100 border border-purple-200 rounded-2xl p-6 text-center">
291
- <div className="text-4xl mb-2">πŸš€</div>
292
- <div className="text-sm font-medium text-purple-700 uppercase tracking-wide">Eden Treaty</div>
293
- </div>
294
- </div>
295
-
296
- {/* Add User Form */}
297
- <div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
298
- <div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
299
- <h3 className="text-lg font-semibold text-gray-900">Adicionar UsuΓ‘rio</h3>
300
- </div>
301
- <div className="p-6">
302
- <form onSubmit={handleSubmit} className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-6">
303
- <div className="space-y-2">
304
- <label className="block text-sm font-medium text-gray-700">Nome</label>
305
- <input
306
- type="text"
307
- className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 placeholder-gray-400"
308
- value={name}
309
- onChange={(e) => setName(e.target.value)}
310
- placeholder="Nome completo"
311
- required
312
- />
313
- </div>
314
- <div className="space-y-2">
315
- <label className="block text-sm font-medium text-gray-700">Email</label>
316
- <input
317
- type="email"
318
- className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 placeholder-gray-400"
319
- value={email}
320
- onChange={(e) => setEmail(e.target.value)}
321
- placeholder="email@exemplo.com"
322
- required
323
- />
324
- </div>
325
- <div className="md:col-span-2">
326
- <button
327
- type="submit"
328
- className="w-full md:w-auto px-8 py-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white font-medium rounded-xl hover:from-blue-700 hover:to-blue-800 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 shadow-lg hover:shadow-xl"
329
- disabled={submitting || !name.trim() || !email.trim()}
330
- >
331
- {submitting ? (
332
- <span className="flex items-center gap-2">
333
- <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
334
- Adicionando...
335
- </span>
336
- ) : (
337
- 'Adicionar UsuΓ‘rio'
338
- )}
339
- </button>
340
- </div>
341
- </form>
342
- </div>
343
- </div>
344
-
345
- {/* Users List */}
346
- <div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
347
- <div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200 flex justify-between items-center">
348
- <h3 className="text-lg font-semibold text-gray-900">UsuΓ‘rios ({users.length})</h3>
349
- <button
350
- className="flex items-center gap-2 px-4 py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 transition-all duration-200"
351
- onClick={loadUsers}
352
- disabled={loading}
353
- >
354
- {loading ? (
355
- <div className="w-4 h-4 border-2 border-gray-400 border-t-transparent rounded-full animate-spin"></div>
356
- ) : (
357
- <span className="text-lg">↻</span>
358
- )}
359
- Atualizar
360
- </button>
361
- </div>
362
-
363
- <div className="p-6">
364
- {loading ? (
365
- <div className="text-center py-12">
366
- <div className="w-8 h-8 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mx-auto mb-4"></div>
367
- <p className="text-gray-600">Carregando usuΓ‘rios...</p>
368
- </div>
369
- ) : users.length === 0 ? (
370
- <div className="text-center py-12">
371
- <div className="text-6xl mb-4 opacity-50">πŸ‘₯</div>
372
- <h4 className="text-lg font-medium text-gray-900 mb-2">Nenhum usuΓ‘rio encontrado</h4>
373
- <p className="text-gray-600">Adicione o primeiro usuΓ‘rio usando o formulΓ‘rio acima</p>
374
- </div>
375
- ) : (
376
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
377
- {users.map(user => (
378
- <div key={user.id} className="group bg-gray-50 border border-gray-200 rounded-xl p-4 hover:shadow-lg hover:border-blue-300 transition-all duration-200">
379
- <div className="flex items-start gap-3">
380
- <div className="w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white font-bold text-sm flex-shrink-0">
381
- {getInitials(user.name)}
382
- </div>
383
- <div className="flex-1 min-w-0">
384
- <h4 className="font-medium text-gray-900 truncate">{user.name}</h4>
385
- <p className="text-sm text-gray-600 truncate">{user.email}</p>
386
- <button
387
- className="mt-3 w-full px-3 py-2 bg-red-50 text-red-700 border border-red-200 rounded-lg hover:bg-red-100 hover:border-red-300 focus:ring-2 focus:ring-red-500 focus:ring-offset-2 transition-all duration-200 text-sm font-medium"
388
- onClick={() => handleDelete(user.id, user.name)}
389
- >
390
- Remover
391
- </button>
137
+ return (
138
+ <div>
139
+ <Routes>
140
+ {/* Full-screen Live App Route */}
141
+ <Route path="/live-app" element={<MainLayout />} />
142
+
143
+ {/* Regular routes with header and layout */}
144
+ <Route path="*" element={
145
+ <div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-100">
146
+ {/* Header */}
147
+ <header className="bg-white/80 backdrop-blur-sm border-b border-gray-200 sticky top-0 z-50">
148
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
149
+ <div className="flex justify-between items-center h-16">
150
+ {/* Logo and Navigation */}
151
+ <div className="flex items-center space-x-8">
152
+ <div className="flex items-center space-x-3">
153
+ <div className="flex items-center gap-2">
154
+ <FaFire className="text-2xl text-orange-500" />
155
+ <div className="text-2xl font-bold bg-gradient-to-r from-blue-600 via-purple-600 to-indigo-600 bg-clip-text text-transparent">
156
+ FluxStack
157
+ </div>
158
+ </div>
159
+ <span className="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
160
+ v1.4.0
161
+ </span>
392
162
  </div>
163
+
164
+ {/* Navigation Tabs */}
165
+ <nav className="hidden md:flex space-x-1">
166
+ {[
167
+ { id: 'overview', label: 'VisΓ£o Geral', icon: <FaClipboardList />, path: '/' },
168
+ { id: 'demo', label: 'Demo', icon: <FaRocket />, path: '/demo' },
169
+ { id: 'hybrid-live', label: 'Hybrid Live', icon: <FaBolt />, path: '/hybrid-live' },
170
+ { id: 'live-app', label: 'Live App', icon: <FaFire />, path: '/live-app' },
171
+ { id: 'api-docs', label: 'API Docs', icon: <FaBook />, path: '/api-docs' },
172
+ { id: 'tests', label: 'Testes', icon: <FaTest />, path: '/tests' }
173
+ ].map(tab => (
174
+ <Link
175
+ key={tab.id}
176
+ to={tab.path}
177
+ className={`px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200 ${
178
+ location.pathname === tab.path
179
+ ? 'bg-blue-100 text-blue-700 shadow-sm'
180
+ : 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
181
+ }`}
182
+ >
183
+ <div className="flex items-center gap-2">
184
+ {tab.icon}
185
+ {tab.label}
186
+ </div>
187
+ </Link>
188
+ ))}
189
+ </nav>
393
190
  </div>
394
- </div>
395
- ))}
396
- </div>
397
- )}
398
- </div>
399
- </div>
400
- </div>
401
- )
402
191
 
403
- const renderApiDocs = () => (
404
- <div className="space-y-8">
405
- {/* Header */}
406
- <div className="text-center">
407
- <h2 className="text-3xl font-bold text-gray-900 mb-4">πŸ“š DocumentaΓ§Γ£o da API</h2>
408
- <p className="text-lg text-gray-600 max-w-2xl mx-auto">
409
- DocumentaΓ§Γ£o interativa gerada automaticamente com Swagger UI
410
- </p>
411
- </div>
412
-
413
- {/* Quick Links */}
414
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
415
- <div className="group bg-white rounded-2xl p-6 shadow-lg border border-gray-200 hover:shadow-xl hover:border-blue-300 transition-all duration-300">
416
- <div className="text-center">
417
- <div className="text-4xl mb-4">πŸ“‹</div>
418
- <h3 className="text-xl font-semibold text-gray-900 mb-2">Swagger UI Interativo</h3>
419
- <p className="text-gray-600 mb-6">Interface completa para testar todos os endpoints da API</p>
420
- <a
421
- href="/swagger"
422
- target="_blank"
423
- rel="noopener noreferrer"
424
- className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white font-medium rounded-xl hover:from-blue-700 hover:to-blue-800 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all duration-200 shadow-lg hover:shadow-xl"
425
- >
426
- πŸš€ Abrir em Nova Aba
427
- </a>
428
- </div>
429
- </div>
430
-
431
- <div className="group bg-white rounded-2xl p-6 shadow-lg border border-gray-200 hover:shadow-xl hover:border-purple-300 transition-all duration-300">
432
- <div className="text-center">
433
- <div className="text-4xl mb-4">πŸ“„</div>
434
- <h3 className="text-xl font-semibold text-gray-900 mb-2">OpenAPI Spec (JSON)</h3>
435
- <p className="text-gray-600 mb-6">EspecificaΓ§Γ£o OpenAPI em formato JSON para integraΓ§Γ£o</p>
436
- <a
437
- href="/swagger/json"
438
- target="_blank"
439
- rel="noopener noreferrer"
440
- className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-purple-600 to-purple-700 text-white font-medium rounded-xl hover:from-purple-700 hover:to-purple-800 focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 transition-all duration-200 shadow-lg hover:shadow-xl"
441
- >
442
- πŸ“‹ Ver JSON
443
- </a>
444
- </div>
445
- </div>
446
- </div>
447
-
448
- {/* Embedded Swagger */}
449
- <div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
450
- <div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
451
- <h3 className="text-lg font-semibold text-gray-900">πŸ”§ DocumentaΓ§Γ£o Integrada</h3>
452
- </div>
453
- <iframe
454
- src="/swagger"
455
- className="w-full h-[600px] border-0"
456
- title="Swagger UI"
457
- />
458
- </div>
459
-
460
- {/* Eden Treaty Guide */}
461
- <div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
462
- <div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
463
- <h3 className="text-lg font-semibold text-gray-900">πŸ”§ Como usar Eden Treaty</h3>
464
- </div>
465
- <div className="p-6 space-y-6">
466
- <div>
467
- <h4 className="text-base font-semibold text-gray-900 mb-3">ConfiguraΓ§Γ£o do Cliente:</h4>
468
- <pre className="bg-gray-900 text-gray-100 p-4 rounded-xl overflow-x-auto text-sm border border-gray-700">
469
- {`import { treaty } from '@elysiajs/eden'
470
- import type { App } from './server'
471
-
472
- const client = treaty<App>('http://localhost:3000')
473
- export const api = client.api`}
474
- </pre>
475
- </div>
476
-
477
- <div>
478
- <h4 className="text-base font-semibold text-gray-900 mb-3">Exemplos de Uso:</h4>
479
- <pre className="bg-gray-900 text-gray-100 p-4 rounded-xl overflow-x-auto text-sm border border-gray-700">
480
- {`// Listar usuΓ‘rios
481
- const users = await api.users.get()
482
-
483
- // Criar usuΓ‘rio
484
- const newUser = await api.users.post({
485
- name: "JoΓ£o Silva",
486
- email: "joao@example.com"
487
- })
488
-
489
- // Deletar usuΓ‘rio
490
- await api.users["1"].delete()
491
-
492
- // Health check
493
- const health = await api.health.get()`}
494
- </pre>
495
- </div>
496
-
497
- <div>
498
- <h4 className="text-base font-semibold text-gray-900 mb-3">Com tratamento de erros:</h4>
499
- <pre className="bg-gray-900 text-gray-100 p-4 rounded-xl overflow-x-auto text-sm border border-gray-700">
500
- {`try {
501
- const result = await apiCall(api.users.post({
502
- name: "Maria Silva",
503
- email: "maria@example.com"
504
- }))
505
-
506
- if (result.success) {
507
- console.log('UsuΓ‘rio criado:', result.user)
508
- }
509
- } catch (error) {
510
- console.error('Erro:', getErrorMessage(error))
511
- }`}
512
- </pre>
513
- </div>
514
- </div>
515
- </div>
516
-
517
- {/* Features */}
518
- <div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
519
- <div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
520
- <h3 className="text-lg font-semibold text-gray-900 text-center">✨ Funcionalidades</h3>
521
- </div>
522
- <div className="p-6">
523
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
524
- {[
525
- {
526
- icon: "πŸ”’",
527
- title: "Type Safety",
528
- description: "Tipos TypeScript inferidos automaticamente"
529
- },
530
- {
531
- icon: "⚑",
532
- title: "Auto-complete",
533
- description: "IntelliSense completo no editor"
534
- },
535
- {
536
- icon: "πŸ”„",
537
- title: "SincronizaΓ§Γ£o",
538
- description: "MudanΓ§as no backend refletem automaticamente no frontend"
539
- },
540
- {
541
- icon: "πŸ›",
542
- title: "Debugging",
543
- description: "Erros de tipo detectados em tempo de compilaΓ§Γ£o"
544
- }
545
- ].map((feature, index) => (
546
- <div key={index} className="flex items-start gap-4 p-4 rounded-xl bg-gray-50 hover:bg-gray-100 transition-colors duration-200">
547
- <div className="text-2xl">{feature.icon}</div>
548
- <div>
549
- <h4 className="font-semibold text-gray-900 mb-1">{feature.title}</h4>
550
- <p className="text-gray-600 text-sm">{feature.description}</p>
192
+ {/* Status Badge */}
193
+ <div className={`flex items-center space-x-2 px-3 py-2 rounded-full text-sm font-medium ${
194
+ apiStatus === 'online'
195
+ ? 'bg-emerald-100 text-emerald-700'
196
+ : 'bg-red-100 text-red-700'
197
+ }`}>
198
+ <div className={`w-2 h-2 rounded-full ${
199
+ apiStatus === 'online' ? 'bg-emerald-400' : 'bg-red-400'
200
+ }`}></div>
201
+ <span>API {apiStatus === 'online' ? 'Online' : 'Offline'}</span>
202
+ </div>
551
203
  </div>
552
- </div>
553
- ))}
554
- </div>
555
- </div>
556
- </div>
557
- </div>
558
- )
559
204
 
560
- return (
561
- <div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-100">
562
- {/* Header */}
563
- <header className="bg-white/80 backdrop-blur-sm border-b border-gray-200 sticky top-0 z-50">
564
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
565
- <div className="flex justify-between items-center h-16">
566
- {/* Logo and Navigation */}
567
- <div className="flex items-center space-x-8">
568
- <div className="flex items-center space-x-3">
569
- <div className="text-2xl font-bold bg-gradient-to-r from-blue-600 via-purple-600 to-indigo-600 bg-clip-text text-transparent">
570
- πŸ”₯ FluxStack
205
+ {/* Mobile Navigation */}
206
+ <div className="md:hidden pb-3">
207
+ <nav className="flex space-x-1">
208
+ {[
209
+ { id: 'overview', label: 'VisΓ£o', icon: <FaClipboardList />, path: '/' },
210
+ { id: 'demo', label: 'Demo', icon: <FaRocket />, path: '/demo' },
211
+ { id: 'hybrid-live', label: 'Hybrid', icon: <FaBolt />, path: '/hybrid-live' },
212
+ { id: 'live-app', label: 'Live', icon: <FaFire />, path: '/live-app' },
213
+ { id: 'api-docs', label: 'Docs', icon: <FaBook />, path: '/api-docs' },
214
+ { id: 'tests', label: 'Testes', icon: <FaTest />, path: '/tests' }
215
+ ].map(tab => (
216
+ <Link
217
+ key={tab.id}
218
+ to={tab.path}
219
+ className={`flex-1 px-3 py-2 text-xs font-medium rounded-lg transition-all duration-200 ${
220
+ location.pathname === tab.path
221
+ ? 'bg-blue-100 text-blue-700'
222
+ : 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
223
+ }`}
224
+ >
225
+ <div className="flex flex-col items-center gap-1">
226
+ {tab.icon}
227
+ <span>{tab.label}</span>
228
+ </div>
229
+ </Link>
230
+ ))}
231
+ </nav>
571
232
  </div>
572
- <span className="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
573
- v1.4.0
574
- </span>
575
233
  </div>
576
-
577
- {/* Navigation Tabs */}
578
- <nav className="hidden md:flex space-x-1">
579
- {[
580
- { id: 'overview', label: 'πŸ“‹ VisΓ£o Geral', icon: 'πŸ“‹' },
581
- { id: 'demo', label: 'πŸš€ Demo', icon: 'πŸš€' },
582
- { id: 'api-docs', label: 'πŸ“š API Docs', icon: 'πŸ“š' },
583
- { id: 'tests', label: 'πŸ§ͺ Testes', icon: 'πŸ§ͺ' }
584
- ].map(tab => (
585
- <button
586
- key={tab.id}
587
- className={`px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200 ${
588
- activeTab === tab.id
589
- ? 'bg-blue-100 text-blue-700 shadow-sm'
590
- : 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
591
- }`}
592
- onClick={() => setActiveTab(tab.id as TabType)}
593
- >
594
- {tab.label}
595
- </button>
596
- ))}
597
- </nav>
598
- </div>
599
-
600
- {/* Status Badge */}
601
- <div className={`flex items-center space-x-2 px-3 py-2 rounded-full text-sm font-medium ${
602
- apiStatus === 'online'
603
- ? 'bg-emerald-100 text-emerald-700'
604
- : 'bg-red-100 text-red-700'
605
- }`}>
606
- <div className={`w-2 h-2 rounded-full ${
607
- apiStatus === 'online' ? 'bg-emerald-400' : 'bg-red-400'
608
- }`}></div>
609
- <span>API {apiStatus === 'online' ? 'Online' : 'Offline'}</span>
610
- </div>
611
- </div>
612
-
613
- {/* Mobile Navigation */}
614
- <div className="md:hidden pb-3">
615
- <nav className="flex space-x-1">
616
- {[
617
- { id: 'overview', label: 'πŸ“‹ VisΓ£o Geral' },
618
- { id: 'demo', label: 'πŸš€ Demo' },
619
- { id: 'api-docs', label: 'πŸ“š Docs' },
620
- { id: 'tests', label: 'πŸ§ͺ Testes' }
621
- ].map(tab => (
622
- <button
623
- key={tab.id}
624
- className={`flex-1 px-3 py-2 text-xs font-medium rounded-lg transition-all duration-200 ${
625
- activeTab === tab.id
626
- ? 'bg-blue-100 text-blue-700'
627
- : 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
628
- }`}
629
- onClick={() => setActiveTab(tab.id as TabType)}
630
- >
631
- {tab.label}
632
- </button>
633
- ))}
634
- </nav>
234
+ </header>
235
+
236
+ {/* Main Content */}
237
+ <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
238
+ <Routes>
239
+ <Route path="/" element={<OverviewPage />} />
240
+ <Route
241
+ path="/demo"
242
+ element={
243
+ <DemoPage
244
+ users={users}
245
+ apiStatus={apiStatus}
246
+ loading={loading}
247
+ submitting={submitting}
248
+ name={name}
249
+ email={email}
250
+ setName={setName}
251
+ setEmail={setEmail}
252
+ handleSubmit={handleSubmit}
253
+ handleDelete={handleDelete}
254
+ loadUsers={loadUsers}
255
+ getInitials={getInitials}
256
+ />
257
+ }
258
+ />
259
+ <Route path="/hybrid-live" element={<HybridLivePage />} />
260
+ <Route path="/api-docs" element={<ApiDocsPage />} />
261
+ <Route path="/tests" element={
262
+ <div className="p-6">
263
+ <h2 className="text-2xl font-bold mb-4">πŸ§ͺ Tests</h2>
264
+ <p className="text-gray-600">Test suite functionality will be available here.</p>
265
+ </div>
266
+ } />
267
+ </Routes>
268
+ </main>
635
269
  </div>
636
- </div>
637
- </header>
638
-
639
- {/* Main Content */}
640
- <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
641
- {activeTab === 'overview' && renderOverview()}
642
- {activeTab === 'demo' && renderDemo()}
643
- {activeTab === 'api-docs' && renderApiDocs()}
644
- {activeTab === 'tests' && <TestPage />}
645
- </main>
270
+ } />
271
+ </Routes>
646
272
 
647
273
  {/* Toast Notification */}
648
274
  {message && (
@@ -655,9 +281,11 @@ const health = await api.health.get()`}
655
281
  onClick={() => setMessage(null)}
656
282
  >
657
283
  <div className="flex items-center space-x-2">
658
- <span className="text-lg">
659
- {message.type === 'success' ? 'βœ…' : '❌'}
660
- </span>
284
+ {message.type === 'success' ? (
285
+ <FaCheckCircle className="text-lg" />
286
+ ) : (
287
+ <FaTimesCircle className="text-lg" />
288
+ )}
661
289
  <span className="font-medium">{message.text}</span>
662
290
  </div>
663
291
  </div>
@@ -666,4 +294,9 @@ const health = await api.health.get()`}
666
294
  )
667
295
  }
668
296
 
297
+ // Main App component - Zustand stores are available globally
298
+ function App() {
299
+ return <AppContent />
300
+ }
301
+
669
302
  export default App