queen-mq 0.1.1 → 0.1.2

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 (139) hide show
  1. package/API.md +1226 -0
  2. package/AUTH.md +2044 -0
  3. package/LICENSE.md +202 -0
  4. package/README.md +276 -53
  5. package/WEBAPP.md +1889 -0
  6. package/assets/dashboard-01.png +0 -0
  7. package/assets/queen-logo-blue.svg +210 -0
  8. package/assets/queen-logo-cyan.svg +210 -0
  9. package/assets/queen-logo-indigo.svg +210 -0
  10. package/assets/queen-logo-orange.svg +210 -0
  11. package/assets/queen-logo-pink.svg +210 -0
  12. package/assets/queen-logo-purple.svg +210 -0
  13. package/assets/queen-logo-rose.svg +239 -0
  14. package/assets/queen-logo.svg +263 -0
  15. package/examples/batch-processing.js +58 -0
  16. package/examples/test-dashboard-api.js +200 -0
  17. package/package.json +4 -2
  18. package/server.log +1 -0
  19. package/src/benchmark/consumer.js +207 -0
  20. package/src/benchmark/consumer_multi.js +216 -0
  21. package/src/benchmark/producer.js +75 -0
  22. package/src/benchmark/producer_multi.js +115 -0
  23. package/src/client/client.js +192 -16
  24. package/src/client/queenClient.js +5 -0
  25. package/src/cluster-server.js +242 -0
  26. package/src/config.js +19 -5
  27. package/src/database/connection.js +42 -16
  28. package/src/database/poolManager.js +7 -0
  29. package/src/database/schema-v2.sql +194 -130
  30. package/src/managers/queueManagerOptimized.js +823 -933
  31. package/src/managers/systemEventManager.js +8 -3
  32. package/src/routes/messages.js +127 -57
  33. package/src/routes/pop.js +27 -43
  34. package/src/routes/resources.js +61 -27
  35. package/src/routes/status.js +1037 -0
  36. package/src/server.js +308 -272
  37. package/src/services/evictionService.js +57 -28
  38. package/src/services/retentionService.js +44 -11
  39. package/src/test/advanced-pattern-tests.js +5 -5
  40. package/src/test/bus-mode-tests.js +24 -11
  41. package/src/test/edge-case-tests.js +12 -5
  42. package/src/test/enterprise-tests.js +48 -15
  43. package/src/test/utils.js +1 -1
  44. package/src/utils/streaming.js +231 -0
  45. package/src/utils/uuid.js +2 -2
  46. package/src/websocket/wsServer.js +10 -3
  47. package/test-keepalive-v2.sh +22 -0
  48. package/webapp/COLOR_GUIDE.md +118 -0
  49. package/webapp/README.md +143 -0
  50. package/webapp/index.html +14 -0
  51. package/webapp/package-lock.json +3184 -0
  52. package/webapp/package.json +25 -0
  53. package/webapp/postcss.config.js +7 -0
  54. package/webapp/public/assets/queen-logo-blue.svg +210 -0
  55. package/webapp/public/assets/queen-logo-cyan.svg +210 -0
  56. package/webapp/public/assets/queen-logo-indigo.svg +210 -0
  57. package/webapp/public/assets/queen-logo-orange.svg +210 -0
  58. package/webapp/public/assets/queen-logo-pink.svg +210 -0
  59. package/webapp/public/assets/queen-logo-purple.svg +210 -0
  60. package/webapp/public/assets/queen-logo-rose.svg +239 -0
  61. package/webapp/public/assets/queen-logo.svg +263 -0
  62. package/webapp/src/App.vue +19 -0
  63. package/webapp/src/api/analytics.js +10 -0
  64. package/webapp/src/api/client.js +29 -0
  65. package/webapp/src/api/consumers.js +52 -0
  66. package/webapp/src/api/health.js +7 -0
  67. package/webapp/src/api/messages.js +26 -0
  68. package/webapp/src/api/queues.js +14 -0
  69. package/webapp/src/api/resources.js +8 -0
  70. package/webapp/src/assets/styles/main.css +357 -0
  71. package/webapp/src/components/analytics/AnalyticsFilters.vue +87 -0
  72. package/webapp/src/components/analytics/AnalyticsMetrics.vue +57 -0
  73. package/webapp/src/components/analytics/MessageDistributionChart.vue +111 -0
  74. package/webapp/src/components/analytics/MessageFlowChart.vue +173 -0
  75. package/webapp/src/components/analytics/TimeRangeSelector.vue +27 -0
  76. package/webapp/src/components/analytics/TopQueuesChart.vue +132 -0
  77. package/webapp/src/components/common/ConfirmDialog.vue +56 -0
  78. package/webapp/src/components/common/LoadingSpinner.vue +6 -0
  79. package/webapp/src/components/common/MetricCard.vue +43 -0
  80. package/webapp/src/components/common/StatusBadge.vue +45 -0
  81. package/webapp/src/components/dashboard/MessageStatusCard.vue +50 -0
  82. package/webapp/src/components/dashboard/PerformanceCard.vue +38 -0
  83. package/webapp/src/components/dashboard/ThroughputChart.vue +182 -0
  84. package/webapp/src/components/dashboard/TopQueuesTable.vue +53 -0
  85. package/webapp/src/components/layout/AppLayout.vue +110 -0
  86. package/webapp/src/components/layout/AppSidebar.vue +304 -0
  87. package/webapp/src/components/messages/MessageDetailPanel.vue +242 -0
  88. package/webapp/src/components/messages/MessageFilters.vue +114 -0
  89. package/webapp/src/components/queue-detail/PartitionList.vue +79 -0
  90. package/webapp/src/components/queue-detail/PushMessageModal.vue +175 -0
  91. package/webapp/src/components/queue-detail/QueueConfig.vue +63 -0
  92. package/webapp/src/components/queue-detail/QueueDetailHeader.vue +53 -0
  93. package/webapp/src/components/queue-detail/RecentMessages.vue +76 -0
  94. package/webapp/src/components/queues/CreateQueueModal.vue +193 -0
  95. package/webapp/src/components/queues/QueueFilters.vue +90 -0
  96. package/webapp/src/composables/useApi.js +34 -0
  97. package/webapp/src/composables/useTheme.js +36 -0
  98. package/webapp/src/main.js +11 -0
  99. package/webapp/src/router/index.js +42 -0
  100. package/webapp/src/utils/colors.js +96 -0
  101. package/webapp/src/utils/formatters.js +49 -0
  102. package/webapp/src/views/Analytics.vue +377 -0
  103. package/webapp/src/views/ConsumerGroups.vue +433 -0
  104. package/webapp/src/views/Dashboard.vue +418 -0
  105. package/webapp/src/views/Messages.vue +361 -0
  106. package/webapp/src/views/QueueDetail.vue +582 -0
  107. package/webapp/src/views/Queues.vue +496 -0
  108. package/webapp/tailwind.config.js +25 -0
  109. package/webapp/vite.config.js +10 -0
  110. package/dashboard/.vscode/extensions.json +0 -3
  111. package/dashboard/README.md +0 -5
  112. package/dashboard/index.html +0 -14
  113. package/dashboard/package-lock.json +0 -1458
  114. package/dashboard/package.json +0 -25
  115. package/dashboard/public/vite.svg +0 -1
  116. package/dashboard/src/App.vue +0 -29
  117. package/dashboard/src/assets/styles/main.css +0 -908
  118. package/dashboard/src/assets/vue.svg +0 -1
  119. package/dashboard/src/components/cards/MetricCard.vue +0 -298
  120. package/dashboard/src/components/charts/QueueDepthChart.vue +0 -276
  121. package/dashboard/src/components/charts/QueueLagChart.vue +0 -436
  122. package/dashboard/src/components/charts/ThroughputChart.vue +0 -302
  123. package/dashboard/src/components/common/ActivityFeed.vue +0 -251
  124. package/dashboard/src/components/layout/AppHeader.vue +0 -208
  125. package/dashboard/src/components/layout/AppLayout.vue +0 -88
  126. package/dashboard/src/components/layout/AppSidebar.vue +0 -261
  127. package/dashboard/src/main.js +0 -44
  128. package/dashboard/src/router.js +0 -54
  129. package/dashboard/src/services/api.js +0 -187
  130. package/dashboard/src/services/websocket.js +0 -167
  131. package/dashboard/src/utils/constants.js +0 -56
  132. package/dashboard/src/utils/helpers.js +0 -118
  133. package/dashboard/src/views/Analytics.vue +0 -912
  134. package/dashboard/src/views/Dashboard.vue +0 -906
  135. package/dashboard/src/views/Messages.vue +0 -437
  136. package/dashboard/src/views/QueueDetail.vue +0 -501
  137. package/dashboard/src/views/Queues.vue +0 -333
  138. package/dashboard/vite.config.js +0 -30
  139. package/src/routes/analytics.js +0 -812
@@ -1,908 +0,0 @@
1
- /* Queen Dashboard V3 - Dark Theme with Rose Primary */
2
-
3
- /* ============================================
4
- Dark Mode Color System - Aura Theme
5
- ============================================ */
6
- :root.dark {
7
- /* Surface Colors - Dark Mode (Stone) */
8
- --surface-0: #0c0a09; /* Darkest background - stone-950 */
9
- --surface-50: #1c1917; /* Card backgrounds - stone-900 */
10
- --surface-100: #292524; /* Elevated surfaces - stone-800 */
11
- --surface-200: #44403c; /* Borders, dividers - stone-700 */
12
- --surface-300: #57534e; /* Disabled text - stone-600 */
13
- --surface-400: #78716c; /* Muted text - stone-500 */
14
- --surface-500: #a8a29e; /* Regular text - stone-400 */
15
- --surface-600: #d6d3d1; /* Emphasized text - stone-300 */
16
- --surface-700: #e7e5e4; /* Bright text - stone-200 */
17
- --surface-800: #f5f5f4; /* Brightest text - stone-100 */
18
- --surface-900: #fafaf9; /* Pure white - stone-50 */
19
-
20
- /* Rose/Pink Primary Colors */
21
- --primary-50: #fdf2f8;
22
- --primary-100: #fce7f3;
23
- --primary-200: #fbcfe8;
24
- --primary-300: #f9a8d4;
25
- --primary-400: #f472b6;
26
- --primary-500: #ec4899; /* Main rose */
27
- --primary-600: #db2777;
28
- --primary-700: #be185d;
29
- --primary-800: #9f1239;
30
- --primary-900: #881337;
31
-
32
- /* Gradient Definitions */
33
- --gradient-primary: linear-gradient(135deg, #ec4899 0%, #db2777 100%);
34
- --gradient-chart: linear-gradient(180deg, rgba(236, 72, 153, 0.4) 0%, rgba(236, 72, 153, 0.1) 100%);
35
- --gradient-glow: radial-gradient(circle at center, rgba(236, 72, 153, 0.2), transparent);
36
-
37
- /* Status Colors */
38
- --success-color: #10b981;
39
- --warning-color: #f59e0b;
40
- --danger-color: #ef4444;
41
- --info-color: #06b6d4;
42
-
43
- /* Semantic Colors */
44
- --text-color: var(--surface-600);
45
- --text-secondary: var(--surface-500);
46
- --text-muted: var(--surface-400);
47
- --bg-primary: var(--surface-0);
48
- --bg-secondary: var(--surface-50);
49
- --border-color: rgba(255, 255, 255, 0.05);
50
-
51
- /* Spacing */
52
- --spacing-xs: 0.25rem;
53
- --spacing-sm: 0.5rem;
54
- --spacing-md: 1rem;
55
- --spacing-lg: 1.5rem;
56
- --spacing-xl: 2rem;
57
- --spacing-2xl: 3rem;
58
-
59
- /* Border Radius */
60
- --radius-sm: 0.25rem;
61
- --radius-md: 0.375rem;
62
- --radius-lg: 0.5rem;
63
- --radius-xl: 0.75rem;
64
- --radius-2xl: 1rem;
65
- --radius-full: 9999px;
66
-
67
- /* Shadows - Dark Mode */
68
- --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
69
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
70
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
71
- --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6);
72
- --shadow-glow: 0 0 20px rgba(236, 72, 153, 0.3);
73
-
74
- /* Transitions */
75
- --transition-fast: 150ms ease;
76
- --transition-base: 250ms ease;
77
- --transition-slow: 350ms ease;
78
- }
79
-
80
- /* ============================================
81
- Base Styles
82
- ============================================ */
83
- * {
84
- margin: 0;
85
- padding: 0;
86
- box-sizing: border-box;
87
- }
88
-
89
- html {
90
- font-size: 14px;
91
- }
92
-
93
- body {
94
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
95
- background: #0c0a09;
96
- color: var(--text-color);
97
- line-height: 1.6;
98
- min-height: 100vh;
99
- -webkit-font-smoothing: antialiased;
100
- -moz-osx-font-smoothing: grayscale;
101
- transition: background-color var(--transition-base), color var(--transition-base);
102
- }
103
-
104
- .dark body {
105
- background: #0c0a09;
106
- }
107
-
108
- #app {
109
- min-height: 100vh;
110
- display: flex;
111
- flex-direction: column;
112
- background: #0c0a09;
113
- }
114
-
115
- /* ============================================
116
- Typography
117
- ============================================ */
118
- h1, h2, h3, h4, h5, h6 {
119
- font-weight: 600;
120
- line-height: 1.3;
121
- color: var(--surface-700);
122
- }
123
-
124
- h1 { font-size: 1.875rem; }
125
- h2 { font-size: 1.5rem; }
126
- h3 { font-size: 1.25rem; }
127
- h4 { font-size: 1.125rem; }
128
- h5 { font-size: 1rem; }
129
- h6 { font-size: 0.875rem; }
130
-
131
- p {
132
- color: var(--text-secondary);
133
- }
134
-
135
- /* ============================================
136
- Cards - Dark Theme V3
137
- ============================================ */
138
- .card-v3 {
139
- background: transparent;
140
- border: 1px solid rgba(255, 255, 255, 0.1);
141
- border-radius: 16px;
142
- padding: 1.5rem;
143
- position: relative;
144
- overflow: hidden;
145
- transition: all var(--transition-base);
146
- }
147
-
148
- .card-v3::before {
149
- content: '';
150
- position: absolute;
151
- top: 0;
152
- left: 0;
153
- right: 0;
154
- height: 1px;
155
- background: linear-gradient(90deg,
156
- transparent,
157
- rgba(236, 72, 153, 0.5),
158
- transparent
159
- );
160
- }
161
-
162
- .card-v3:hover {
163
- transform: translateY(-2px);
164
- box-shadow: var(--shadow-glow);
165
- border-color: rgba(236, 72, 153, 0.2);
166
- }
167
-
168
- /* ============================================
169
- Metric Cards - V3 Design
170
- ============================================ */
171
- .metric-card-v3 {
172
- background: transparent;
173
- border: 1px solid rgba(255, 255, 255, 0.08);
174
- border-radius: 12px;
175
- padding: 1.25rem;
176
- display: flex;
177
- align-items: flex-start;
178
- gap: 1rem;
179
- position: relative;
180
- overflow: hidden;
181
- transition: all var(--transition-base);
182
- }
183
-
184
- .metric-card-v3:hover {
185
- border-color: rgba(236, 72, 153, 0.15);
186
- }
187
-
188
- .metric-icon-wrapper {
189
- width: 48px;
190
- height: 48px;
191
- border-radius: 12px;
192
- background: var(--gradient-primary);
193
- display: flex;
194
- align-items: center;
195
- justify-content: center;
196
- flex-shrink: 0;
197
- }
198
-
199
- .metric-icon-wrapper i {
200
- font-size: 1.25rem;
201
- color: white;
202
- }
203
-
204
- .metric-content {
205
- flex: 1;
206
- min-width: 0;
207
- }
208
-
209
- .metric-label {
210
- font-size: 0.75rem;
211
- color: var(--surface-400);
212
- text-transform: uppercase;
213
- letter-spacing: 0.05em;
214
- margin-bottom: 0.25rem;
215
- }
216
-
217
- .metric-value {
218
- font-size: 1.75rem;
219
- font-weight: 700;
220
- color: var(--surface-700);
221
- line-height: 1;
222
- margin-bottom: 0.5rem;
223
- }
224
-
225
- .metric-change {
226
- display: inline-flex;
227
- align-items: center;
228
- gap: 0.25rem;
229
- font-size: 0.875rem;
230
- font-weight: 500;
231
- }
232
-
233
- .metric-change.positive {
234
- color: var(--success-color);
235
- }
236
-
237
- .metric-change.negative {
238
- color: var(--danger-color);
239
- }
240
-
241
- .metric-sparkline {
242
- position: absolute;
243
- right: 1rem;
244
- bottom: 1rem;
245
- width: 80px;
246
- height: 30px;
247
- opacity: 0.5;
248
- }
249
-
250
- /* ============================================
251
- Buttons - Dark Theme
252
- ============================================ */
253
- .btn-primary {
254
- background: var(--gradient-primary);
255
- border: none;
256
- color: white;
257
- padding: 0.625rem 1.25rem;
258
- border-radius: 8px;
259
- font-weight: 500;
260
- box-shadow: 0 4px 14px rgba(236, 72, 153, 0.3);
261
- cursor: pointer;
262
- transition: all var(--transition-base);
263
- }
264
-
265
- .btn-primary:hover {
266
- transform: translateY(-1px);
267
- box-shadow: 0 6px 20px rgba(236, 72, 153, 0.4);
268
- }
269
-
270
- .btn-secondary {
271
- background: rgba(255, 255, 255, 0.05);
272
- border: 1px solid rgba(255, 255, 255, 0.1);
273
- color: var(--surface-500);
274
- padding: 0.625rem 1.25rem;
275
- border-radius: 8px;
276
- font-weight: 500;
277
- cursor: pointer;
278
- transition: all var(--transition-base);
279
- }
280
-
281
- .btn-secondary:hover {
282
- background: rgba(255, 255, 255, 0.08);
283
- border-color: rgba(255, 255, 255, 0.2);
284
- color: var(--surface-600);
285
- }
286
-
287
- /* ============================================
288
- Input Fields - Dark Theme
289
- ============================================ */
290
- .input-v3 {
291
- background: rgba(0, 0, 0, 0.3);
292
- border: 1px solid rgba(255, 255, 255, 0.1);
293
- border-radius: 8px;
294
- color: var(--surface-600);
295
- padding: 0.625rem 1rem;
296
- font-size: 0.875rem;
297
- width: 100%;
298
- transition: all var(--transition-base);
299
- }
300
-
301
- .input-v3:focus {
302
- outline: none;
303
- border-color: var(--primary-500);
304
- box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.1);
305
- background: rgba(0, 0, 0, 0.5);
306
- }
307
-
308
- .input-v3::placeholder {
309
- color: var(--surface-300);
310
- }
311
-
312
- /* ============================================
313
- Tables - Dark Theme
314
- ============================================ */
315
- .dark-table-v3 {
316
- background: transparent;
317
- border-radius: 12px;
318
- overflow: hidden;
319
- border: none;
320
- }
321
-
322
- .dark-table-v3 thead {
323
- background: var(--surface-0);
324
- }
325
-
326
- .dark-table-v3 th {
327
- color: var(--surface-400);
328
- font-weight: 600;
329
- font-size: 0.75rem;
330
- text-transform: uppercase;
331
- letter-spacing: 0.05em;
332
- padding: 1rem;
333
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
334
- }
335
-
336
- .dark-table-v3 td {
337
- color: var(--surface-600);
338
- padding: 0.875rem 1rem;
339
- border-bottom: 1px solid rgba(255, 255, 255, 0.03);
340
- }
341
-
342
- .dark-table-v3 tbody tr {
343
- transition: all var(--transition-fast);
344
- }
345
-
346
- .dark-table-v3 tbody tr:hover {
347
- background: rgba(236, 72, 153, 0.05);
348
- }
349
-
350
- /* ============================================
351
- Queue Distribution Card
352
- ============================================ */
353
- .distribution-card {
354
- background: transparent;
355
- border: 1px solid rgba(255, 255, 255, 0.1);
356
- border-radius: 16px;
357
- padding: 1.5rem;
358
- }
359
-
360
- .distribution-header {
361
- display: flex;
362
- justify-content: space-between;
363
- align-items: center;
364
- margin-bottom: 1.5rem;
365
- }
366
-
367
- .distribution-header h3 {
368
- font-size: 1.125rem;
369
- color: var(--surface-700);
370
- }
371
-
372
- .distribution-bar {
373
- display: flex;
374
- height: 40px;
375
- border-radius: 8px;
376
- overflow: hidden;
377
- margin-bottom: 1.5rem;
378
- background: var(--surface-0);
379
- }
380
-
381
- .distribution-bar .segment {
382
- transition: all var(--transition-base);
383
- position: relative;
384
- }
385
-
386
- .distribution-bar .segment:hover {
387
- filter: brightness(1.2);
388
- }
389
-
390
- .distribution-legend {
391
- display: grid;
392
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
393
- gap: 0.75rem;
394
- }
395
-
396
- .legend-item {
397
- display: flex;
398
- align-items: center;
399
- gap: 0.5rem;
400
- font-size: 0.875rem;
401
- color: var(--surface-500);
402
- }
403
-
404
- .legend-item .dot {
405
- width: 8px;
406
- height: 8px;
407
- border-radius: 50%;
408
- flex-shrink: 0;
409
- }
410
-
411
- /* ============================================
412
- Status Colors - Dark Theme
413
- ============================================ */
414
- .status-pending {
415
- color: var(--warning-color);
416
- background-color: rgba(245, 158, 11, 0.15);
417
- padding: 0.25rem 0.75rem;
418
- border-radius: var(--radius-full);
419
- font-size: 0.75rem;
420
- font-weight: 600;
421
- }
422
-
423
- .status-processing {
424
- color: var(--info-color);
425
- background-color: rgba(6, 182, 212, 0.15);
426
- padding: 0.25rem 0.75rem;
427
- border-radius: var(--radius-full);
428
- font-size: 0.75rem;
429
- font-weight: 600;
430
- }
431
-
432
- .status-completed {
433
- color: var(--success-color);
434
- background-color: rgba(16, 185, 129, 0.15);
435
- padding: 0.25rem 0.75rem;
436
- border-radius: var(--radius-full);
437
- font-size: 0.75rem;
438
- font-weight: 600;
439
- }
440
-
441
- .status-failed {
442
- color: var(--danger-color);
443
- background-color: rgba(239, 68, 68, 0.15);
444
- padding: 0.25rem 0.75rem;
445
- border-radius: var(--radius-full);
446
- font-size: 0.75rem;
447
- font-weight: 600;
448
- }
449
-
450
- .status-dead_letter {
451
- color: var(--surface-400);
452
- background-color: rgba(148, 163, 184, 0.15);
453
- padding: 0.25rem 0.75rem;
454
- border-radius: var(--radius-full);
455
- font-size: 0.75rem;
456
- font-weight: 600;
457
- }
458
-
459
- /* ============================================
460
- Animations
461
- ============================================ */
462
- @keyframes fadeIn {
463
- from {
464
- opacity: 0;
465
- transform: translateY(10px);
466
- }
467
- to {
468
- opacity: 1;
469
- transform: translateY(0);
470
- }
471
- }
472
-
473
- @keyframes slideIn {
474
- from {
475
- opacity: 0;
476
- transform: translateX(-10px);
477
- }
478
- to {
479
- opacity: 1;
480
- transform: translateX(0);
481
- }
482
- }
483
-
484
- @keyframes pulse {
485
- 0%, 100% {
486
- opacity: 1;
487
- }
488
- 50% {
489
- opacity: 0.5;
490
- }
491
- }
492
-
493
- @keyframes spin {
494
- from {
495
- transform: rotate(0deg);
496
- }
497
- to {
498
- transform: rotate(360deg);
499
- }
500
- }
501
-
502
- @keyframes shimmer {
503
- 0% {
504
- background-position: -200% center;
505
- }
506
- 100% {
507
- background-position: 200% center;
508
- }
509
- }
510
-
511
- @keyframes glow {
512
- 0%, 100% {
513
- box-shadow: 0 0 5px rgba(236, 72, 153, 0.5);
514
- }
515
- 50% {
516
- box-shadow: 0 0 20px rgba(236, 72, 153, 0.8);
517
- }
518
- }
519
-
520
- .fade-in {
521
- animation: fadeIn 0.3s ease;
522
- }
523
-
524
- .slide-in {
525
- animation: slideIn 0.3s ease;
526
- }
527
-
528
- .pulse {
529
- animation: pulse 2s ease infinite;
530
- }
531
-
532
- .spin {
533
- animation: spin 1s linear infinite;
534
- }
535
-
536
- .glow {
537
- animation: glow 2s ease infinite;
538
- }
539
-
540
- /* ============================================
541
- Loading States
542
- ============================================ */
543
- .skeleton {
544
- background: linear-gradient(
545
- 90deg,
546
- var(--surface-100) 25%,
547
- var(--surface-200) 50%,
548
- var(--surface-100) 75%
549
- );
550
- background-size: 200% 100%;
551
- animation: shimmer 1.5s infinite;
552
- border-radius: var(--radius-md);
553
- }
554
-
555
- /* ============================================
556
- Utility Classes
557
- ============================================ */
558
- .container {
559
- max-width: 1400px;
560
- margin: 0 auto;
561
- padding: 0 var(--spacing-lg);
562
- }
563
-
564
- .flex {
565
- display: flex;
566
- }
567
-
568
- .flex-center {
569
- display: flex;
570
- align-items: center;
571
- justify-content: center;
572
- }
573
-
574
- .flex-between {
575
- display: flex;
576
- align-items: center;
577
- justify-content: space-between;
578
- }
579
-
580
- .grid {
581
- display: grid;
582
- }
583
-
584
- .gap-sm { gap: var(--spacing-sm); }
585
- .gap-md { gap: var(--spacing-md); }
586
- .gap-lg { gap: var(--spacing-lg); }
587
- .gap-xl { gap: var(--spacing-xl); }
588
-
589
- /* ============================================
590
- Layout Grids
591
- ============================================ */
592
- .dashboard-grid {
593
- display: grid;
594
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
595
- gap: var(--spacing-lg);
596
- }
597
-
598
- .analytics-grid {
599
- display: grid;
600
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
601
- gap: var(--spacing-lg);
602
- }
603
-
604
- /* ============================================
605
- Scrollbar Styling - Dark Theme
606
- ============================================ */
607
- ::-webkit-scrollbar {
608
- width: 8px;
609
- height: 8px;
610
- }
611
-
612
- ::-webkit-scrollbar-track {
613
- background: var(--surface-100);
614
- border-radius: var(--radius-full);
615
- }
616
-
617
- ::-webkit-scrollbar-thumb {
618
- background: var(--surface-200);
619
- border-radius: var(--radius-full);
620
- transition: background var(--transition-fast);
621
- }
622
-
623
- ::-webkit-scrollbar-thumb:hover {
624
- background: var(--surface-300);
625
- }
626
-
627
- /* ============================================
628
- PrimeVue Dark Theme Overrides
629
- ============================================ */
630
- .p-component {
631
- font-family: inherit;
632
- font-size: 0.875rem;
633
- }
634
-
635
- .p-button {
636
- transition: all var(--transition-base);
637
- border-radius: var(--radius-md);
638
- font-weight: 500;
639
- font-size: 0.875rem;
640
- padding: 0.5rem 1rem;
641
- }
642
-
643
- .p-button:hover {
644
- transform: translateY(-1px);
645
- box-shadow: 0 4px 12px rgba(236, 72, 153, 0.3);
646
- }
647
-
648
- .p-button-primary {
649
- background: var(--gradient-primary);
650
- border: none;
651
- }
652
-
653
- .p-button-primary:hover {
654
- box-shadow: 0 6px 20px rgba(236, 72, 153, 0.4);
655
- }
656
-
657
- .p-datatable {
658
- background: var(--surface-50);
659
- border-radius: 12px;
660
- overflow: hidden;
661
- border: 1px solid rgba(255, 255, 255, 0.05);
662
- font-size: 0.875rem;
663
- }
664
-
665
- .p-datatable .p-datatable-thead > tr > th {
666
- background: var(--surface-0);
667
- color: var(--surface-400);
668
- font-weight: 600;
669
- font-size: 0.75rem;
670
- text-transform: uppercase;
671
- letter-spacing: 0.05em;
672
- padding: 1rem;
673
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
674
- }
675
-
676
- .p-datatable .p-datatable-tbody > tr {
677
- transition: background-color var(--transition-fast);
678
- }
679
-
680
- .p-datatable .p-datatable-tbody > tr:hover {
681
- background-color: rgba(236, 72, 153, 0.05) !important;
682
- }
683
-
684
- .p-datatable .p-datatable-tbody > tr > td {
685
- padding: 0.875rem 1rem;
686
- font-size: 0.875rem;
687
- color: var(--surface-600);
688
- border-bottom: 1px solid rgba(255, 255, 255, 0.03);
689
- }
690
-
691
- .p-card {
692
- background: var(--surface-50);
693
- box-shadow: none;
694
- border: 1px solid rgba(255, 255, 255, 0.05);
695
- border-radius: 12px;
696
- }
697
-
698
- .p-card:hover {
699
- box-shadow: var(--shadow-glow);
700
- border-color: rgba(236, 72, 153, 0.2);
701
- }
702
-
703
- .p-tag {
704
- border-radius: var(--radius-full);
705
- font-weight: 600;
706
- padding: 0.25rem 0.75rem;
707
- font-size: 0.75rem;
708
- }
709
-
710
- .p-badge {
711
- border-radius: var(--radius-md);
712
- font-weight: 600;
713
- font-size: 0.75rem;
714
- }
715
-
716
- /* Chart container styling */
717
- .chart-container {
718
- background: transparent;
719
- border: 1px solid rgba(255, 255, 255, 0.1);
720
- border-radius: 16px;
721
- padding: 1.5rem;
722
- }
723
-
724
- .chart-header {
725
- display: flex;
726
- justify-content: space-between;
727
- align-items: center;
728
- margin-bottom: 1.5rem;
729
- }
730
-
731
- .chart-title {
732
- font-size: 1.125rem;
733
- font-weight: 600;
734
- color: var(--surface-700);
735
- }
736
-
737
- /* ============================================
738
- Connection Status
739
- ============================================ */
740
- .connection-status {
741
- display: inline-flex;
742
- align-items: center;
743
- gap: var(--spacing-xs);
744
- padding: var(--spacing-xs) var(--spacing-sm);
745
- border-radius: var(--radius-full);
746
- font-size: 0.875rem;
747
- font-weight: 500;
748
- }
749
-
750
- .connection-status.connected {
751
- background: rgba(16, 185, 129, 0.15);
752
- color: var(--success-color);
753
- }
754
-
755
- .connection-status.disconnected {
756
- background: rgba(239, 68, 68, 0.15);
757
- color: var(--danger-color);
758
- }
759
-
760
- .connection-status .indicator {
761
- width: 8px;
762
- height: 8px;
763
- border-radius: 50%;
764
- background: currentColor;
765
- }
766
-
767
- .connection-status.connected .indicator {
768
- animation: pulse 2s infinite;
769
- }
770
-
771
- /* ============================================
772
- Responsive Design
773
- ============================================ */
774
- @media (max-width: 1024px) {
775
- .dashboard-grid {
776
- grid-template-columns: repeat(2, 1fr);
777
- }
778
-
779
- .analytics-grid {
780
- grid-template-columns: 1fr;
781
- }
782
- }
783
-
784
- @media (max-width: 768px) {
785
- html {
786
- font-size: 13px;
787
- }
788
-
789
- .container {
790
- padding: 0 0.75rem;
791
- }
792
-
793
- .dashboard-grid {
794
- grid-template-columns: 1fr;
795
- gap: 0.75rem;
796
- }
797
-
798
- .analytics-grid {
799
- grid-template-columns: 1fr;
800
- }
801
-
802
- .card-v3,
803
- .metric-card-v3 {
804
- padding: 1rem;
805
- border-radius: var(--radius-lg);
806
- }
807
-
808
- .hide-mobile {
809
- display: none !important;
810
- }
811
- }
812
-
813
- @media (max-width: 480px) {
814
- html {
815
- font-size: 12px;
816
- }
817
-
818
- .dashboard-grid {
819
- gap: 0.5rem;
820
- }
821
-
822
- .card-v3,
823
- .metric-card-v3 {
824
- padding: 0.875rem;
825
- }
826
- }
827
-
828
- @media (min-width: 769px) {
829
- .hide-desktop {
830
- display: none !important;
831
- }
832
- }
833
-
834
- /* ============================================
835
- Activity Feed Styles
836
- ============================================ */
837
- .activity-feed {
838
- background: transparent;
839
- border: 1px solid rgba(255, 255, 255, 0.1);
840
- border-radius: 16px;
841
- padding: 1.5rem;
842
- max-height: 400px;
843
- overflow-y: auto;
844
- }
845
-
846
- .activity-item {
847
- display: flex;
848
- gap: 1rem;
849
- padding: 0.875rem;
850
- border-radius: 8px;
851
- margin-bottom: 0.5rem;
852
- background: var(--surface-0);
853
- border: 1px solid rgba(255, 255, 255, 0.03);
854
- transition: all var(--transition-fast);
855
- }
856
-
857
- .activity-item:hover {
858
- background: rgba(236, 72, 153, 0.05);
859
- border-color: rgba(236, 72, 153, 0.1);
860
- }
861
-
862
- .activity-icon {
863
- width: 36px;
864
- height: 36px;
865
- border-radius: 8px;
866
- display: flex;
867
- align-items: center;
868
- justify-content: center;
869
- flex-shrink: 0;
870
- }
871
-
872
- .activity-icon.push {
873
- background: rgba(16, 185, 129, 0.15);
874
- color: var(--success-color);
875
- }
876
-
877
- .activity-icon.pop {
878
- background: rgba(6, 182, 212, 0.15);
879
- color: var(--info-color);
880
- }
881
-
882
- .activity-icon.ack {
883
- background: rgba(236, 72, 153, 0.15);
884
- color: var(--primary-500);
885
- }
886
-
887
- .activity-content {
888
- flex: 1;
889
- min-width: 0;
890
- }
891
-
892
- .activity-title {
893
- font-size: 0.875rem;
894
- font-weight: 500;
895
- color: var(--surface-600);
896
- margin-bottom: 0.125rem;
897
- }
898
-
899
- .activity-description {
900
- font-size: 0.75rem;
901
- color: var(--surface-400);
902
- }
903
-
904
- .activity-time {
905
- font-size: 0.75rem;
906
- color: var(--surface-300);
907
- margin-left: auto;
908
- }