create-fullstack-boilerplate 2.1.10 → 2.2.0

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.
@@ -1,135 +1,522 @@
1
- import { useState, useEffect } from 'react';
2
1
  import { useTheme } from '../contexts/ThemeContext';
3
- import { axiosDashboardClient } from '../config/axiosClient';
4
- import SpinningLoader from '../components/Loader';
2
+ import ReactFlow, {
3
+ Background,
4
+ Controls,
5
+ MiniMap,
6
+ useNodesState,
7
+ useEdgesState,
8
+ } from 'reactflow';
9
+ import 'reactflow/dist/style.css';
5
10
 
6
11
  const Dashboard = () => {
7
12
  const { isDark } = useTheme();
8
- const [sections, setSections] = useState([]);
9
- const [loading, setLoading] = useState(false);
10
- const [error, setError] = useState(null);
11
-
12
- const fetchDashboardInfo = async () => {
13
- setLoading(true);
14
- try {
15
- const response = await axiosDashboardClient.get('getDashboardHealth');
16
- setSections(response.data);
17
- } catch (err) {
18
- setError(err.message);
19
- } finally {
20
- setLoading(false);
21
- }
22
- };
23
-
24
- useEffect(() => {
25
- fetchDashboardInfo();
26
- }, []);
27
13
 
28
- return (
29
- <div className={`min-h-screen transition-colors duration-300
30
- ${isDark ? "bg-[#0a0a0a]" : "bg-[#fafafa]"}`}>
14
+ const initialNodes = [
15
+ // Row 1: Frontend Entry & Setup
16
+ {
17
+ id: 'browser',
18
+ type: 'input',
19
+ data: { label: '🌐 User Interaction\nBrowser Request' },
20
+ position: { x: 50, y: 20 },
21
+ style: {
22
+ background: isDark ? 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' : 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
23
+ color: '#fff',
24
+ border: '2px solid #4c51bf',
25
+ borderRadius: '12px',
26
+ padding: '20px',
27
+ fontSize: '16px',
28
+ fontWeight: '600',
29
+ width: 200,
30
+ minHeight: '90px',
31
+ },
32
+ },
33
+ {
34
+ id: 'app',
35
+ data: { label: '📱 App.jsx\nApplication Root\nMounts Providers' },
36
+ position: { x: 300, y: 20 },
37
+ style: {
38
+ background: isDark ? '#1e293b' : '#f8fafc',
39
+ color: isDark ? '#e2e8f0' : '#334155',
40
+ border: `2px solid ${isDark ? '#475569' : '#cbd5e1'}`,
41
+ borderRadius: '12px',
42
+ padding: '18px',
43
+ fontSize: '15px',
44
+ fontWeight: '500',
45
+ width: 200,
46
+ minHeight: '90px',
47
+ },
48
+ },
49
+ {
50
+ id: 'providers',
51
+ data: { label: '🔧 Context Providers\nAuth + Theme State\nWraps All Components' },
52
+ position: { x: 550, y: 20 },
53
+ style: {
54
+ background: isDark ? '#1e293b' : '#f8fafc',
55
+ color: isDark ? '#e2e8f0' : '#334155',
56
+ border: `2px solid ${isDark ? '#475569' : '#cbd5e1'}`,
57
+ borderRadius: '12px',
58
+ padding: '18px',
59
+ fontSize: '14px',
60
+ fontWeight: '500',
61
+ width: 200,
62
+ minHeight: '90px',
63
+ },
64
+ },
65
+ {
66
+ id: 'router',
67
+ data: { label: '🛣️ React Router\nRoute Matching\nURL → Component' },
68
+ position: { x: 800, y: 20 },
69
+ style: {
70
+ background: isDark ? '#1e293b' : '#f8fafc',
71
+ color: isDark ? '#e2e8f0' : '#334155',
72
+ border: `2px solid ${isDark ? '#475569' : '#cbd5e1'}`,
73
+ borderRadius: '12px',
74
+ padding: '18px',
75
+ fontSize: '14px',
76
+ fontWeight: '500',
77
+ width: 200,
78
+ minHeight: '90px',
79
+ },
80
+ },
81
+ {
82
+ id: 'protected',
83
+ data: { label: '🛡️ ProtectedRoute\nAuth Verification\nRedirect if Not Logged' },
84
+ position: { x: 1050, y: 20 },
85
+ style: {
86
+ background: isDark ? '#422006' : '#fef3c7',
87
+ color: isDark ? '#fbbf24' : '#92400e',
88
+ border: `2px solid ${isDark ? '#f59e0b' : '#fbbf24'}`,
89
+ borderRadius: '12px',
90
+ padding: '18px',
91
+ fontSize: '13px',
92
+ fontWeight: '500',
93
+ width: 200,
94
+ minHeight: '90px',
95
+ },
96
+ },
97
+ {
98
+ id: 'layout',
99
+ data: { label: '📐 Layout Component\nRenders Sidebar\nPage Structure' },
100
+ position: { x: 1300, y: 20 },
101
+ style: {
102
+ background: isDark ? '#0f172a' : '#fff',
103
+ color: isDark ? '#94a3b8' : '#64748b',
104
+ border: `2px solid ${isDark ? '#334155' : '#e2e8f0'}`,
105
+ borderRadius: '12px',
106
+ padding: '18px',
107
+ fontSize: '14px',
108
+ width: 200,
109
+ minHeight: '90px',
110
+ },
111
+ },
112
+ {
113
+ id: 'sidebar',
114
+ data: { label: '📋 Sidebar\nNavigation Links\nRoute Selection' },
115
+ position: { x: 1300, y: 160 },
116
+ style: {
117
+ background: isDark ? '#0f172a' : '#fff',
118
+ color: isDark ? '#94a3b8' : '#64748b',
119
+ border: `2px solid ${isDark ? '#334155' : '#e2e8f0'}`,
120
+ borderRadius: '12px',
121
+ padding: '18px',
122
+ fontSize: '13px',
123
+ width: 200,
124
+ minHeight: '80px',
125
+ },
126
+ },
127
+ {
128
+ id: 'pages',
129
+ data: { label: '📄 Page Components\nDashboard/Settings\nRender UI + Logic' },
130
+ position: { x: 1550, y: 20 },
131
+ style: {
132
+ background: isDark ? '#0f172a' : '#fff',
133
+ color: isDark ? '#94a3b8' : '#64748b',
134
+ border: `2px solid ${isDark ? '#334155' : '#e2e8f0'}`,
135
+ borderRadius: '12px',
136
+ padding: '18px',
137
+ fontSize: '14px',
138
+ width: 200,
139
+ minHeight: '90px',
140
+ },
141
+ },
142
+
143
+ // Row 2: API & Encryption Layer
144
+ {
145
+ id: 'encryption',
146
+ data: { label: '🔒 CryptoJS Encrypt\nEncrypt Credentials\nBefore API Call' },
147
+ position: { x: 1050, y: 300 },
148
+ style: {
149
+ background: isDark ? '#134e4a' : '#ccfbf1',
150
+ color: isDark ? '#5eead4' : '#115e59',
151
+ border: `2px solid ${isDark ? '#14b8a6' : '#5eead4'}`,
152
+ borderRadius: '12px',
153
+ padding: '18px',
154
+ fontSize: '13px',
155
+ width: 200,
156
+ minHeight: '80px',
157
+ },
158
+ },
159
+ {
160
+ id: 'axios',
161
+ data: { label: '🌐 Axios Instances\nAPI Client Setup\nBase URL + Config' },
162
+ position: { x: 1550, y: 160 },
163
+ style: {
164
+ background: isDark ? '#134e4a' : '#ccfbf1',
165
+ color: isDark ? '#5eead4' : '#115e59',
166
+ border: `2px solid ${isDark ? '#14b8a6' : '#5eead4'}`,
167
+ borderRadius: '12px',
168
+ padding: '18px',
169
+ fontSize: '13px',
170
+ width: 200,
171
+ minHeight: '80px',
172
+ },
173
+ },
174
+ {
175
+ id: 'interceptors',
176
+ data: { label: '⚙️ Request Interceptors\nAttach JWT Token\nHandle 401 Errors' },
177
+ position: { x: 1550, y: 300 },
178
+ style: {
179
+ background: isDark ? '#134e4a' : '#ccfbf1',
180
+ color: isDark ? '#5eead4' : '#115e59',
181
+ border: `2px solid ${isDark ? '#14b8a6' : '#5eead4'}`,
182
+ borderRadius: '12px',
183
+ padding: '18px',
184
+ fontSize: '13px',
185
+ width: 200,
186
+ minHeight: '80px',
187
+ },
188
+ },
189
+
190
+ // Row 3: Backend Entry & Routing
191
+ {
192
+ id: 'backend',
193
+ data: { label: '🖥️ Express Server\nEntry Point\nserver.js' },
194
+ position: { x: 50, y: 480 },
195
+ style: {
196
+ background: isDark ? 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' : 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
197
+ color: '#fff',
198
+ border: '2px solid #ec4899',
199
+ borderRadius: '12px',
200
+ padding: '20px',
201
+ fontSize: '16px',
202
+ fontWeight: '600',
203
+ width: 200,
204
+ minHeight: '90px',
205
+ },
206
+ },
207
+ {
208
+ id: 'mainRouter',
209
+ data: { label: '🔀 Main API Router\nRoute Distribution\napp.use("/api", ...)' },
210
+ position: { x: 300, y: 480 },
211
+ style: {
212
+ background: isDark ? '#1e1b4b' : '#f5f3ff',
213
+ color: isDark ? '#c4b5fd' : '#5b21b6',
214
+ border: `2px solid ${isDark ? '#6366f1' : '#c4b5fd'}`,
215
+ borderRadius: '12px',
216
+ padding: '18px',
217
+ fontSize: '14px',
218
+ width: 200,
219
+ minHeight: '90px',
220
+ },
221
+ },
222
+ {
223
+ id: 'authMiddleware',
224
+ data: { label: '🛡️ Auth Middleware\nVerify JWT Token\nProtect Routes' },
225
+ position: { x: 550, y: 340 },
226
+ style: {
227
+ background: isDark ? '#422006' : '#fef3c7',
228
+ color: isDark ? '#fbbf24' : '#92400e',
229
+ border: `2px solid ${isDark ? '#f59e0b' : '#fbbf24'}`,
230
+ borderRadius: '12px',
231
+ padding: '18px',
232
+ fontSize: '13px',
233
+ fontWeight: '500',
234
+ width: 200,
235
+ minHeight: '80px',
236
+ },
237
+ },
238
+ {
239
+ id: 'authRoutes',
240
+ data: { label: '🔑 Auth Routes\n/api/auth/*\nLogin/Register/Logout' },
241
+ position: { x: 550, y: 480 },
242
+ style: {
243
+ background: isDark ? '#18181b' : '#fafafa',
244
+ color: isDark ? '#a1a1aa' : '#52525b',
245
+ border: `2px solid ${isDark ? '#52525b' : '#d4d4d8'}`,
246
+ borderRadius: '12px',
247
+ padding: '18px',
248
+ fontSize: '13px',
249
+ width: 200,
250
+ minHeight: '90px',
251
+ },
252
+ },
253
+ {
254
+ id: 'dashRoutes',
255
+ data: { label: '📊 Dashboard Routes\n/api/dash/*\nGet Dashboard Data' },
256
+ position: { x: 800, y: 480 },
257
+ style: {
258
+ background: isDark ? '#18181b' : '#fafafa',
259
+ color: isDark ? '#a1a1aa' : '#52525b',
260
+ border: `2px solid ${isDark ? '#52525b' : '#d4d4d8'}`,
261
+ borderRadius: '12px',
262
+ padding: '18px',
263
+ fontSize: '13px',
264
+ width: 200,
265
+ minHeight: '90px',
266
+ },
267
+ },
268
+ {
269
+ id: 'settingsRoutes',
270
+ data: { label: '⚙️ Settings Routes\n/api/settings/*\nUpdate User Settings' },
271
+ position: { x: 1050, y: 480 },
272
+ style: {
273
+ background: isDark ? '#18181b' : '#fafafa',
274
+ color: isDark ? '#a1a1aa' : '#52525b',
275
+ border: `2px solid ${isDark ? '#52525b' : '#d4d4d8'}`,
276
+ borderRadius: '12px',
277
+ padding: '18px',
278
+ fontSize: '13px',
279
+ width: 200,
280
+ minHeight: '90px',
281
+ },
282
+ },
283
+
284
+ // Row 4: Business Logic Services
285
+ {
286
+ id: 'cryptoService',
287
+ data: { label: '🔓 Crypto Service\nDecrypt Credentials\nCryptoJS Decrypt' },
288
+ position: { x: 300, y: 620 },
289
+ style: {
290
+ background: isDark ? '#422006' : '#fef3c7',
291
+ color: isDark ? '#fbbf24' : '#92400e',
292
+ border: `2px solid ${isDark ? '#f59e0b' : '#fbbf24'}`,
293
+ borderRadius: '12px',
294
+ padding: '18px',
295
+ fontSize: '13px',
296
+ width: 200,
297
+ minHeight: '80px',
298
+ },
299
+ },
300
+ {
301
+ id: 'authService',
302
+ data: { label: '🔐 Auth Service\nBcrypt Password Hash\nJWT Token Generation' },
303
+ position: { x: 550, y: 620 },
304
+ style: {
305
+ background: isDark ? '#1c1917' : '#fafaf9',
306
+ color: isDark ? '#d6d3d1' : '#57534e',
307
+ border: `2px solid ${isDark ? '#78716c' : '#d6d3d1'}`,
308
+ borderRadius: '12px',
309
+ padding: '18px',
310
+ fontSize: '13px',
311
+ width: 200,
312
+ minHeight: '80px',
313
+ },
314
+ },
315
+ {
316
+ id: 'dashService',
317
+ data: { label: '📊 Dashboard Service\nBusiness Logic\nData Processing' },
318
+ position: { x: 800, y: 620 },
319
+ style: {
320
+ background: isDark ? '#1c1917' : '#fafaf9',
321
+ color: isDark ? '#d6d3d1' : '#57534e',
322
+ border: `2px solid ${isDark ? '#78716c' : '#d6d3d1'}`,
323
+ borderRadius: '12px',
324
+ padding: '18px',
325
+ fontSize: '13px',
326
+ width: 200,
327
+ minHeight: '80px',
328
+ },
329
+ },
330
+ {
331
+ id: 'settingsService',
332
+ data: { label: '⚙️ Settings Service\nBusiness Logic\nUpdate Operations' },
333
+ position: { x: 1050, y: 620 },
334
+ style: {
335
+ background: isDark ? '#1c1917' : '#fafaf9',
336
+ color: isDark ? '#d6d3d1' : '#57534e',
337
+ border: `2px solid ${isDark ? '#78716c' : '#d6d3d1'}`,
338
+ borderRadius: '12px',
339
+ padding: '18px',
340
+ fontSize: '13px',
341
+ width: 200,
342
+ minHeight: '80px',
343
+ },
344
+ },
345
+
346
+ // Row 5: Database Layer
347
+ {
348
+ id: 'models',
349
+ data: { label: '📦 Sequelize Models\nORM Definitions\nUser/Post/etc Tables' },
350
+ position: { x: 1300, y: 620 },
351
+ style: {
352
+ background: isDark ? 'linear-gradient(135deg, #0f2027 0%, #203a43 50%, #2c5364 100%)' : 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
353
+ color: '#fff',
354
+ border: '2px solid #4c51bf',
355
+ borderRadius: '12px',
356
+ padding: '20px',
357
+ fontSize: '14px',
358
+ fontWeight: '600',
359
+ width: 200,
360
+ minHeight: '90px',
361
+ },
362
+ },
363
+ {
364
+ id: 'dbConfig',
365
+ data: { label: '⚙️ DB Config\nConnection Settings\ndbConfigs.js' },
366
+ position: { x: 1300, y: 480 },
367
+ style: {
368
+ background: isDark ? '#171717' : '#f5f5f5',
369
+ color: isDark ? '#a3a3a3' : '#525252',
370
+ border: `2px solid ${isDark ? '#525252' : '#a3a3a3'}`,
371
+ borderRadius: '12px',
372
+ padding: '18px',
373
+ fontSize: '13px',
374
+ width: 200,
375
+ minHeight: '80px',
376
+ },
377
+ },
378
+ {
379
+ id: 'dbInit',
380
+ data: { label: '🚀 DB Initialization\nConnect + Sync\nRun on Server Start' },
381
+ position: { x: 50, y: 620 },
382
+ style: {
383
+ background: isDark ? '#171717' : '#f5f5f5',
384
+ color: isDark ? '#a3a3a3' : '#525252',
385
+ border: `2px solid ${isDark ? '#525252' : '#a3a3a3'}`,
386
+ borderRadius: '12px',
387
+ padding: '18px',
388
+ fontSize: '13px',
389
+ width: 200,
390
+ minHeight: '80px',
391
+ },
392
+ },
393
+ {
394
+ id: 'database',
395
+ type: 'output',
396
+ data: { label: '💾 Database\nPostgres/MySQL\nPersistent Storage' },
397
+ position: { x: 1550, y: 620 },
398
+ style: {
399
+ background: isDark ? 'linear-gradient(135deg, #134e4a 0%, #065f46 100%)' : 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
400
+ color: '#fff',
401
+ border: '2px solid #059669',
402
+ borderRadius: '12px',
403
+ padding: '20px',
404
+ fontSize: '16px',
405
+ fontWeight: '600',
406
+ width: 200,
407
+ minHeight: '90px',
408
+ },
409
+ },
410
+ ];
411
+
412
+ const initialEdges = [
413
+ // ===== FRONTEND FLOW =====
414
+ // Main component hierarchy flow
415
+ { id: 'e1', source: 'browser', target: 'app', animated: true, style: { stroke: '#667eea', strokeWidth: 3 }, label: 'Load App' },
416
+ { id: 'e2', source: 'app', target: 'providers', animated: true, style: { stroke: '#667eea', strokeWidth: 3 }, label: 'Mount' },
417
+ { id: 'e3', source: 'providers', target: 'router', animated: true, style: { stroke: '#667eea', strokeWidth: 3 }, label: 'Wrap' },
418
+ { id: 'e4', source: 'router', target: 'protected', animated: true, style: { stroke: '#667eea', strokeWidth: 3 }, label: 'Route' },
419
+ { id: 'e5', source: 'protected', target: 'layout', animated: true, style: { stroke: '#f59e0b', strokeWidth: 3 }, label: 'Auth ✓' },
420
+ { id: 'e6', source: 'layout', target: 'sidebar', style: { stroke: '#94a3b8', strokeWidth: 2 }, label: 'Contains' },
421
+ { id: 'e7', source: 'layout', target: 'pages', animated: true, style: { stroke: '#667eea', strokeWidth: 3 }, label: 'Render' },
422
+
423
+ // Sidebar navigation
424
+ { id: 'e8', source: 'sidebar', target: 'pages', style: { stroke: '#94a3b8', strokeWidth: 2 }, label: 'Navigate', type: 'smoothstep' },
425
+
426
+ // ===== API CALL FLOW =====
427
+ // Pages to Axios
428
+ { id: 'e9', source: 'pages', target: 'axios', animated: true, style: { stroke: '#14b8a6', strokeWidth: 3 }, label: 'API Call' },
429
+ { id: 'e10', source: 'axios', target: 'interceptors', animated: true, style: { stroke: '#14b8a6', strokeWidth: 3 }, label: 'Process' },
430
+
431
+ // Encryption flow (for login/register)
432
+ { id: 'e11', source: 'protected', target: 'encryption', style: { stroke: '#14b8a6', strokeWidth: 2 }, label: 'Encrypt Data', type: 'smoothstep' },
433
+ { id: 'e12', source: 'encryption', target: 'axios', style: { stroke: '#14b8a6', strokeWidth: 2 }, label: 'Encrypted', type: 'smoothstep' },
434
+
435
+ // Interceptors to Backend
436
+ { id: 'e13', source: 'interceptors', target: 'backend', animated: true, style: { stroke: '#ec4899', strokeWidth: 4 }, label: 'HTTP Request', type: 'smoothstep' },
437
+
438
+ // ===== BACKEND FLOW =====
439
+ // Server initialization
440
+ { id: 'e14', source: 'backend', target: 'dbInit', style: { stroke: '#525252', strokeWidth: 2 }, label: 'Initialize', type: 'smoothstep' },
441
+ { id: 'e15', source: 'backend', target: 'mainRouter', animated: true, style: { stroke: '#ec4899', strokeWidth: 3 }, label: 'Route to /api' },
31
442
 
32
- {/* Content Container */}
33
- <div className="max-w-6xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
443
+ // Main Router distribution
444
+ { id: 'e16', source: 'mainRouter', target: 'authRoutes', animated: true, style: { stroke: '#6366f1', strokeWidth: 3 }, label: '/auth' },
445
+ { id: 'e17', source: 'mainRouter', target: 'dashRoutes', animated: true, style: { stroke: '#6366f1', strokeWidth: 3 }, label: '/dash' },
446
+ { id: 'e18', source: 'mainRouter', target: 'settingsRoutes', animated: true, style: { stroke: '#6366f1', strokeWidth: 3 }, label: '/settings' },
34
447
 
448
+ // Auth Middleware checks
449
+ { id: 'e19', source: 'mainRouter', target: 'authMiddleware', style: { stroke: '#f59e0b', strokeWidth: 2 }, label: 'Check Auth' },
450
+ { id: 'e20', source: 'authMiddleware', target: 'dashRoutes', style: { stroke: '#f59e0b', strokeWidth: 2 }, label: 'Authorize', type: 'smoothstep' },
451
+ { id: 'e21', source: 'authMiddleware', target: 'settingsRoutes', style: { stroke: '#f59e0b', strokeWidth: 2 }, label: 'Authorize', type: 'smoothstep' },
452
+
453
+ // ===== SERVICES LAYER =====
454
+ // Routes to Services
455
+ { id: 'e22', source: 'authRoutes', target: 'cryptoService', style: { stroke: '#f59e0b', strokeWidth: 2 }, label: 'Decrypt' },
456
+ { id: 'e23', source: 'cryptoService', target: 'authService', animated: true, style: { stroke: '#78716c', strokeWidth: 3 }, label: 'Process' },
457
+ { id: 'e24', source: 'authRoutes', target: 'authService', animated: true, style: { stroke: '#78716c', strokeWidth: 3 }, label: 'Handle' },
458
+ { id: 'e25', source: 'dashRoutes', target: 'dashService', animated: true, style: { stroke: '#78716c', strokeWidth: 3 }, label: 'Handle' },
459
+ { id: 'e26', source: 'settingsRoutes', target: 'settingsService', animated: true, style: { stroke: '#78716c', strokeWidth: 3 }, label: 'Handle' },
460
+
461
+ // ===== DATABASE LAYER =====
462
+ // Services to Models
463
+ { id: 'e27', source: 'authService', target: 'models', animated: true, style: { stroke: '#4c51bf', strokeWidth: 3 }, label: 'Query' },
464
+ { id: 'e28', source: 'dashService', target: 'models', animated: true, style: { stroke: '#4c51bf', strokeWidth: 3 }, label: 'Query' },
465
+ { id: 'e29', source: 'settingsService', target: 'models', animated: true, style: { stroke: '#4c51bf', strokeWidth: 3 }, label: 'Query' },
466
+
467
+ // Models configuration
468
+ { id: 'e30', source: 'models', target: 'dbConfig', style: { stroke: '#525252', strokeWidth: 2 }, label: 'Use Config' },
469
+ { id: 'e31', source: 'dbConfig', target: 'database', style: { stroke: '#10b981', strokeWidth: 2 }, label: 'Connect' },
470
+ { id: 'e32', source: 'models', target: 'database', animated: true, style: { stroke: '#10b981', strokeWidth: 3 }, label: 'Execute SQL' },
471
+
472
+ // DB initialization
473
+ { id: 'e33', source: 'dbInit', target: 'dbConfig', style: { stroke: '#525252', strokeWidth: 2 }, label: 'Load' },
474
+ { id: 'e34', source: 'dbInit', target: 'models', style: { stroke: '#525252', strokeWidth: 2 }, label: 'Sync Tables' },
475
+ ];
476
+
477
+
478
+ const [nodes, , onNodesChange] = useNodesState(initialNodes);
479
+ const [edges, , onEdgesChange] = useEdgesState(initialEdges);
480
+
481
+ return (
482
+ <div className={`min-h-screen transition-colors duration-300 ${isDark ? "bg-[#0a0a0a]" : "bg-[#fafafa]"}`}>
483
+ <div className="h-screen flex flex-col">
35
484
  {/* Header */}
36
- <div className="mb-12">
37
- <h1 className={`text-4xl sm:text-5xl font-semibold mb-3 tracking-tight
485
+ <div className="px-6 py-6">
486
+ <h1 className={`text-4xl sm:text-5xl font-semibold mb-2 tracking-tight
38
487
  ${isDark ? "text-white" : "text-gray-900"}`}
39
488
  style={{ fontFamily: "'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif" }}>
40
- Dashboard Overview
489
+ Application Flow
41
490
  </h1>
42
491
  <p className={`text-lg ${isDark ? "text-gray-400" : "text-gray-600"}`}>
43
- System architecture and configuration
492
+ Interactive visualization of the full-stack architecture
44
493
  </p>
45
494
  </div>
46
495
 
47
- {/* Loading State */}
48
- {loading && (
49
- <div className="flex justify-center items-center py-20">
50
- <SpinningLoader size={50} />
51
- </div>
52
- )}
53
-
54
- {/* Error State */}
55
- {error && (
56
- <div className={`p-4 rounded-xl border ${isDark
57
- ? "bg-red-900/20 border-red-800/50 text-red-400"
58
- : "bg-red-50 border-red-200 text-red-700"}`}>
59
- <p className="font-medium">Error: {error}</p>
60
- </div>
61
- )}
62
-
63
- {/* Dashboard Cards */}
64
- {!loading && !error && (
65
- <div className="space-y-6">
66
- {sections.map((section, index) => (
67
- <div
68
- key={index}
69
- className={`group rounded-2xl transition-all duration-300 overflow-hidden
70
- ${isDark
71
- ? "bg-[#141414] border border-gray-800/50 hover:border-gray-700/80"
72
- : "bg-white border border-gray-200 hover:border-gray-300 shadow-sm hover:shadow-md"}`}
73
- style={{
74
- animation: `fadeInUp 0.5s ease-out ${index * 0.1}s both`
75
- }}>
76
-
77
- {/* Card Header */}
78
- <div className={`px-8 py-6 border-b ${isDark ? "border-gray-800/50" : "border-gray-100"}`}>
79
- <div className="flex items-center gap-4">
80
- <div className={`flex-shrink-0 w-12 h-12 flex items-center justify-center rounded-xl text-2xl
81
- ${isDark ? "bg-gray-800/80" : "bg-gray-100"}`}>
82
- {section.icon}
83
- </div>
84
- <h2 className={`text-xl font-semibold ${isDark ? "text-gray-100" : "text-gray-900"}`}
85
- style={{ fontFamily: "'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif" }}>
86
- {section.title}
87
- </h2>
88
- </div>
89
- </div>
90
-
91
- {/* Card Content */}
92
- <div className="px-8 py-6">
93
- <ul className="space-y-4">
94
- {section.items.map((item, i) => (
95
- <li
96
- key={i}
97
- className="flex items-start gap-3 group/item">
98
- <div className={`flex-shrink-0 w-1.5 h-1.5 rounded-full mt-2.5 transition-all duration-200
99
- ${isDark
100
- ? "bg-gray-600 group-hover/item:bg-blue-500"
101
- : "bg-gray-400 group-hover/item:bg-blue-600"}`}>
102
- </div>
103
- <span className={`text-[15px] leading-relaxed transition-colors duration-200
104
- ${isDark
105
- ? "text-gray-400 group-hover/item:text-gray-300"
106
- : "text-gray-600 group-hover/item:text-gray-900"}`}
107
- style={{ fontFamily: "'SF Pro Text', -apple-system, BlinkMacSystemFont, sans-serif" }}>
108
- {item}
109
- </span>
110
- </li>
111
- ))}
112
- </ul>
113
- </div>
114
- </div>
115
- ))}
116
- </div>
117
- )}
496
+ {/* Flow Diagram */}
497
+ <div className={`flex-1 ${isDark ? 'bg-[#0a0a0a]' : 'bg-white'} rounded-xl mx-6 mb-6 border ${isDark ? 'border-gray-800' : 'border-gray-200'}`}>
498
+ <ReactFlow
499
+ nodes={nodes}
500
+ edges={edges}
501
+ onNodesChange={onNodesChange}
502
+ onEdgesChange={onEdgesChange}
503
+ fitView
504
+ attributionPosition="bottom-left"
505
+ >
506
+ <Background color={isDark ? '#1f2937' : '#e5e7eb'} gap={16} />
507
+ <Controls className={isDark ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'} />
508
+ <MiniMap
509
+ nodeColor={(node) => {
510
+ if (node.type === 'input') return '#667eea';
511
+ if (node.type === 'output') return '#10b981';
512
+ return isDark ? '#1e293b' : '#f8fafc';
513
+ }}
514
+ maskColor={isDark ? 'rgba(0, 0, 0, 0.6)' : 'rgba(255, 255, 255, 0.6)'}
515
+ className={isDark ? 'bg-gray-900 border-gray-700' : 'bg-gray-50 border-gray-200'}
516
+ />
517
+ </ReactFlow>
518
+ </div>
118
519
  </div>
119
-
120
- {/* Minimal Animations */}
121
- <style>{`
122
- @keyframes fadeInUp {
123
- from {
124
- opacity: 0;
125
- transform: translateY(20px);
126
- }
127
- to {
128
- opacity: 1;
129
- transform: translateY(0);
130
- }
131
- }
132
- `}</style>
133
520
  </div>
134
521
  );
135
522
  };
@@ -1,14 +0,0 @@
1
- // const path = require("path");
2
-
3
- // function assertDependency(depName, cwd) {
4
- // try {
5
- // return require(path.join(cwd, "node_modules", depName));
6
- // } catch (err) {
7
- // throw new Error(
8
- // `Dependency '${depName}' is not installed in ${cwd}.\n` +
9
- // `Run: cd ${cwd} && npm install ${depName}`
10
- // );
11
- // }
12
- // }
13
-
14
- // module.exports = assertDependency;
package/lib/ensureDir.js DELETED
@@ -1,7 +0,0 @@
1
- // const fs = require("fs-extra");
2
-
3
- // async function ensureDir(dir) {
4
- // await fs.ensureDir(dir);
5
- // }
6
-
7
- // module.exports = ensureDir;