@necrolab/dashboard 0.4.47 → 0.4.49

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 (39) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/exit +209 -0
  3. package/index.html +1 -1
  4. package/package.json +1 -1
  5. package/postinstall.js +9 -0
  6. package/public/manifest.json +8 -3
  7. package/src/assets/css/_input.scss +104 -111
  8. package/src/assets/css/_utilities.scss +441 -0
  9. package/src/assets/css/main.scss +228 -154
  10. package/src/components/Auth/LoginForm.vue +8 -8
  11. package/src/components/Editors/Account/Account.vue +156 -146
  12. package/src/components/Editors/Account/AccountCreator.vue +1 -1
  13. package/src/components/Editors/Account/AccountView.vue +13 -13
  14. package/src/components/Editors/Account/CreateAccount.vue +25 -16
  15. package/src/components/Editors/Profile/CreateProfile.vue +1 -1
  16. package/src/components/Editors/Profile/Profile.vue +1 -1
  17. package/src/components/Editors/Profile/ProfileCountryChooser.vue +83 -19
  18. package/src/components/Editors/Profile/ProfileView.vue +11 -11
  19. package/src/components/Tasks/CreateTaskAXS.vue +3 -3
  20. package/src/components/Tasks/CreateTaskTM.vue +7 -35
  21. package/src/components/Tasks/QuickSettings.vue +112 -9
  22. package/src/components/Tasks/Stats.vue +29 -25
  23. package/src/components/Tasks/Task.vue +489 -365
  24. package/src/components/Tasks/TaskView.vue +21 -23
  25. package/src/components/icons/Sandclock.vue +2 -2
  26. package/src/components/icons/Stadium.vue +1 -1
  27. package/src/components/ui/Modal.vue +37 -35
  28. package/src/components/ui/controls/CountryChooser.vue +200 -62
  29. package/src/components/ui/controls/atomic/Dropdown.vue +177 -91
  30. package/src/components/ui/controls/atomic/MultiDropdown.vue +247 -168
  31. package/src/composables/useClickOutside.js +21 -0
  32. package/src/composables/useDropdownPosition.js +174 -0
  33. package/src/stores/ui.js +5 -4
  34. package/src/views/Accounts.vue +2 -2
  35. package/src/views/Console.vue +25 -45
  36. package/src/views/Editor.vue +1194 -730
  37. package/src/views/Profiles.vue +2 -2
  38. package/src/views/Tasks.vue +170 -137
  39. package/tailwind.config.js +47 -21
@@ -1,28 +1,27 @@
1
1
  @use "input";
2
+ @use "utilities";
3
+
4
+ /* ==========================================================================
5
+ GLOBAL RESETS & BASE STYLES
6
+ ========================================================================== */
2
7
 
3
- /* Global input styling fixes for iOS and other platforms */
4
8
  input,
5
9
  textarea,
6
10
  select,
7
11
  button {
8
- /* Remove iOS blue highlight/border */
9
12
  -webkit-tap-highlight-color: transparent;
10
13
  -webkit-touch-callout: none;
11
-
12
- /* Remove default focus outline */
13
14
  outline: none;
14
15
  }
15
16
 
16
17
  input,
17
18
  textarea,
18
19
  select {
19
- /* Remove browser default styling */
20
20
  -webkit-appearance: none;
21
21
  -moz-appearance: none;
22
22
  appearance: none;
23
23
  }
24
24
 
25
- /* Enhanced focus state removal for iOS */
26
25
  input:focus,
27
26
  textarea:focus,
28
27
  select:focus {
@@ -31,7 +30,10 @@ select:focus {
31
30
  box-shadow: none !important;
32
31
  }
33
32
 
34
- // Base styles - Ultra bulletproof scroll prevention
33
+ /* ==========================================================================
34
+ SCROLL PREVENTION & TOUCH HANDLING
35
+ ========================================================================== */
36
+
35
37
  html {
36
38
  overflow: hidden !important;
37
39
  overscroll-behavior: none !important;
@@ -48,7 +50,6 @@ html {
48
50
  overscroll-behavior: none !important;
49
51
  }
50
52
 
51
- // Override for textareas to allow scrolling and selection
52
53
  textarea,
53
54
  .code-editor,
54
55
  .proxy-editor {
@@ -60,41 +61,102 @@ textarea,
60
61
  touch-action: pan-y !important;
61
62
  }
62
63
 
63
- // Override for dropdown menus to allow scrolling - must be very specific to override global rules
64
64
  .dropdown-menu,
65
65
  .dropdown-menu *,
66
+ .dropdown-content-portal,
67
+ .dropdown-content-portal *,
66
68
  .option-list,
67
69
  .option-list *,
68
- .dropdown-menu.scrollable,
69
- .dropdown-menu.scrollable * {
70
+ .console,
71
+ .console * {
70
72
  overscroll-behavior: auto !important;
71
73
  touch-action: pan-y !important;
72
74
  -webkit-overflow-scrolling: touch !important;
75
+ }
76
+
77
+ /* Specific overrides for dropdown content portals */
78
+ .dropdown-content-portal {
79
+ overflow: auto !important;
73
80
  overflow-y: auto !important;
81
+ overscroll-behavior: auto !important;
82
+ touch-action: pan-y !important;
83
+ -webkit-overflow-scrolling: touch !important;
84
+ scroll-behavior: smooth !important;
74
85
  }
75
86
 
76
- // Additional specific overrides for dropdown buttons and text
77
- .dropdown-item,
78
- .dropdown-item *,
79
- .dropdown-item-text {
87
+ .dropdown-content-portal * {
88
+ overflow: auto !important;
80
89
  overscroll-behavior: auto !important;
81
90
  touch-action: pan-y !important;
91
+ -webkit-overflow-scrolling: touch !important;
92
+ user-select: auto !important;
93
+ -webkit-user-select: auto !important;
94
+ -moz-user-select: auto !important;
95
+ -ms-user-select: auto !important;
82
96
  }
83
97
 
84
- // Override for console scrolling
85
- .console,
86
- .console *,
87
- .console.scrollable {
98
+ /* Ultra-specific overrides to beat the global * selector */
99
+ body .dropdown-content-portal,
100
+ html .dropdown-content-portal,
101
+ div .dropdown-content-portal {
102
+ overflow: auto !important;
103
+ overflow-y: auto !important;
104
+ overscroll-behavior: auto !important;
105
+ touch-action: pan-y !important;
106
+ -webkit-overflow-scrolling: touch !important;
107
+ }
108
+
109
+ /* Force scrolling on teleported dropdown content */
110
+ body > .dropdown-content-portal,
111
+ [data-v-app] .dropdown-content-portal {
112
+ overflow: auto !important;
113
+ overflow-y: auto !important;
114
+ overscroll-behavior: auto !important;
115
+ touch-action: pan-y !important;
116
+ -webkit-overflow-scrolling: touch !important;
117
+ }
118
+
119
+ .code-editor,
120
+ .proxy-editor,
121
+ .editor-container,
122
+ .proxy-editor-container {
88
123
  overscroll-behavior: auto !important;
89
124
  touch-action: pan-y !important;
90
125
  -webkit-overflow-scrolling: touch !important;
91
126
  }
92
127
 
128
+ /* iPhone landscape mode - critical editor scrolling overrides */
129
+ @media (max-height: 500px) and (orientation: landscape) {
130
+ .code-editor,
131
+ .proxy-editor,
132
+ .editor-container,
133
+ .proxy-editor-container,
134
+ .editor-wrapper {
135
+ overflow: auto !important;
136
+ -webkit-overflow-scrolling: touch !important;
137
+ touch-action: pan-y !important;
138
+ overscroll-behavior: contain !important;
139
+ }
140
+
141
+ body {
142
+ overflow-y: auto !important;
143
+ touch-action: pan-y !important;
144
+ overscroll-behavior: contain !important;
145
+ }
146
+
147
+ html {
148
+ overflow-y: auto !important;
149
+ overscroll-behavior: contain !important;
150
+ }
151
+ }
152
+
153
+ /* ==========================================================================
154
+ BODY & LAYOUT
155
+ ========================================================================== */
156
+
93
157
  body {
94
158
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
95
- background: url("@/assets/img/background.svg") center center, #1a1b1e;
96
- background-size: cover;
97
- background-attachment: fixed;
159
+ background-color: #1a1b1e;
98
160
  min-height: 100vh;
99
161
  overflow: hidden !important;
100
162
  overscroll-behavior: none !important;
@@ -104,14 +166,37 @@ body {
104
166
  -moz-osx-font-smoothing: grayscale;
105
167
  touch-action: none !important;
106
168
  color: #e2e2e5;
169
+ position: relative;
107
170
  @apply bg-dark-300;
171
+
172
+ &::before {
173
+ content: "";
174
+ position: fixed;
175
+ top: 0;
176
+ left: 0;
177
+ right: 0;
178
+ bottom: 0;
179
+ background-image: url("@/assets/img/background.svg");
180
+ background-position: center center;
181
+ background-size: cover;
182
+ background-repeat: no-repeat;
183
+ -webkit-background-size: cover;
184
+ z-index: -1;
185
+ pointer-events: none;
186
+ will-change: transform;
187
+ -webkit-transform: translateZ(0);
188
+ transform: translateZ(0);
189
+ }
108
190
  }
109
191
 
110
192
  img {
111
193
  pointer-events: none;
112
194
  }
113
195
 
114
- // Layout utilities
196
+ /* ==========================================================================
197
+ UTILITY CLASSES
198
+ ========================================================================== */
199
+
115
200
  .flex-center {
116
201
  @apply flex items-center justify-center;
117
202
  }
@@ -124,7 +209,6 @@ img {
124
209
  @apply flex flex-col items-center justify-center;
125
210
  }
126
211
 
127
- // Text utilities
128
212
  .text-heading {
129
213
  @apply text-base font-semibold;
130
214
  color: #e2e2e5;
@@ -140,7 +224,26 @@ img {
140
224
  color: #a0a0a6;
141
225
  }
142
226
 
143
- // Button utilities
227
+ .card-dark {
228
+ @apply bg-dark-400 border border-dark-650 rounded shadow-sm;
229
+ }
230
+
231
+ .grid-tasks {
232
+ @apply grid grid-cols-12 gap-2 items-center;
233
+ }
234
+
235
+ .grid-responsive {
236
+ @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4;
237
+ }
238
+
239
+ .form-grid {
240
+ @apply grid grid-cols-1 md:grid-cols-2 gap-4;
241
+ }
242
+
243
+ /* ==========================================================================
244
+ BUTTON COMPONENTS
245
+ ========================================================================== */
246
+
144
247
  .btn-primary {
145
248
  @apply bg-dark-550 hover:bg-dark-650 text-white font-medium px-4 py-2 rounded transition-all duration-150;
146
249
  border: 1px solid #44454b;
@@ -175,56 +278,10 @@ img {
175
278
  color: #e2e2e5;
176
279
  }
177
280
 
178
- // Form utilities
179
- .form-grid {
180
- @apply grid grid-cols-1 md:grid-cols-2 gap-4;
181
- }
182
-
183
- .label-override {
184
- @apply flex items-center text-xs mb-2;
185
- color: #a0a0a6;
186
-
187
- svg {
188
- @apply ml-2;
189
- color: #a0a0a6 !important;
190
- width: 16px;
191
- height: 16px;
192
- fill: #a0a0a6 !important;
193
- }
194
- }
281
+ /* ==========================================================================
282
+ COMPONENT UTILITIES
283
+ ========================================================================== */
195
284
 
196
- // Use CSS custom property to avoid global path selector
197
- .label-override svg {
198
- color: #a0a0a6 !important;
199
- fill: #a0a0a6 !important;
200
- }
201
-
202
- .label-override svg path {
203
- fill: #a0a0a6 !important;
204
- color: #a0a0a6 !important;
205
- }
206
-
207
- .label-override svg * {
208
- fill: #a0a0a6 !important;
209
- color: #a0a0a6 !important;
210
- }
211
-
212
- .switch-wrapper svg {
213
- color: #a0a0a6 !important;
214
- fill: #a0a0a6 !important;
215
- }
216
-
217
- .switch-wrapper svg path {
218
- fill: #a0a0a6 !important;
219
- color: #a0a0a6 !important;
220
- }
221
-
222
- .switch-wrapper svg * {
223
- fill: #a0a0a6 !important;
224
- color: #a0a0a6 !important;
225
- }
226
-
227
- // Component utilities
228
285
  .smooth-hover {
229
286
  @apply transition-all duration-200 hover:opacity-80;
230
287
  }
@@ -233,20 +290,6 @@ img {
233
290
  @apply w-2 h-2 rounded-full flex-shrink-0;
234
291
  min-width: 4px;
235
292
  min-height: 4px;
236
-
237
- @media (max-width: 768px) {
238
- width: 6px;
239
- height: 6px;
240
- min-width: 6px;
241
- min-height: 6px;
242
- }
243
-
244
- @media (max-width: 480px) {
245
- width: 5px;
246
- height: 5px;
247
- min-width: 5px;
248
- min-height: 5px;
249
- }
250
293
  }
251
294
 
252
295
  .mobile-icons {
@@ -262,25 +305,36 @@ img {
262
305
  }
263
306
  }
264
307
 
265
- .card-dark {
266
- @apply bg-dark-400 border border-dark-650 rounded shadow-sm;
308
+ .loading-spinner {
309
+ @apply animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full;
267
310
  }
268
311
 
269
- // Grid utilities
270
- .grid-tasks {
271
- @apply grid grid-cols-12 gap-2 items-center;
272
- }
312
+ /* ==========================================================================
313
+ LABEL & ICON STYLING
314
+ ========================================================================== */
273
315
 
274
- .grid-responsive {
275
- @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4;
316
+ .label-override {
317
+ @apply flex items-center text-xs mb-2;
318
+ color: #a0a0a6;
319
+
320
+ svg {
321
+ @apply ml-2;
322
+ color: #a0a0a6 !important;
323
+ width: 16px;
324
+ height: 16px;
325
+ fill: #a0a0a6 !important;
326
+ }
276
327
  }
277
328
 
278
- // Loading states
279
- .loading-spinner {
280
- @apply animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full;
329
+ .switch-wrapper svg {
330
+ color: #a0a0a6 !important;
331
+ fill: #a0a0a6 !important;
281
332
  }
282
333
 
283
- // Scrollbar utilities
334
+ /* ==========================================================================
335
+ SCROLLBAR UTILITIES
336
+ ========================================================================== */
337
+
284
338
  .hidden-scrollbars {
285
339
  scrollbar-width: none;
286
340
  -ms-overflow-style: none;
@@ -290,39 +344,33 @@ img {
290
344
  }
291
345
  }
292
346
 
293
- // Dynamic heights for different devices - conservative approach to prevent partial items
294
- .max-h-big {
295
- max-height: calc(100vh - 12rem); // Account for navbar, header, stats, controls, utilities
296
- min-height: 8rem; // 2 items minimum (2 * 64px = 128px = 8rem)
297
- overflow: hidden; // Ensure no partial items show
298
- }
299
-
300
- @media only screen and (min-width: 1440px) {
301
- .max-h-big {
302
- max-height: calc(100vh - 11rem); // Large screens get slightly more space
303
- }
304
- }
347
+ /* ==========================================================================
348
+ DYNAMIC HEIGHTS & RESPONSIVE DESIGN
349
+ ========================================================================== */
305
350
 
306
- @media only screen and (min-device-width: 768px) and (max-device-width: 1366px) {
307
- .max-h-big {
308
- max-height: calc(100vh - 12rem);
309
- }
351
+ .max-h-big {
352
+ max-height: calc(100vh - 12rem);
353
+ min-height: 8rem;
354
+ overflow: hidden;
310
355
  }
311
356
 
312
- @media only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait) {
357
+ @screen xl {
313
358
  .max-h-big {
314
- max-height: calc(100vh - 12rem);
359
+ max-height: calc(100vh - 11rem);
315
360
  }
316
361
  }
317
362
 
318
- @media screen and (max-device-height: 500px) {
363
+ @screen h-sm {
319
364
  .max-h-big {
320
365
  max-height: calc(100vh - 12rem);
321
366
  min-height: 8rem;
322
367
  }
323
368
  }
324
369
 
325
- // Transitions
370
+ /* ==========================================================================
371
+ TRANSITIONS & ANIMATIONS
372
+ ========================================================================== */
373
+
326
374
  .fade-enter-active,
327
375
  .fade-leave-active {
328
376
  transition: opacity 0.15s ease;
@@ -333,28 +381,14 @@ img {
333
381
  opacity: 0;
334
382
  }
335
383
 
336
- // Performance
337
384
  .will-change-auto {
338
385
  will-change: auto;
339
386
  }
340
387
 
341
- // Root configuration
342
- :root {
343
- touch-action: pan-x pan-y;
344
- height: 100%;
345
- --toastify-toast-width: 520px;
346
- }
347
-
348
- // iOS layout stabilization
349
- @supports (-webkit-appearance: none) {
350
- .component-container,
351
- .card-dark,
352
- h1, h2, h3, h4, h5, h6 {
353
- transform: translate3d(0, 0, 0);
354
- }
355
- }
388
+ /* ==========================================================================
389
+ TOAST NOTIFICATIONS
390
+ ========================================================================== */
356
391
 
357
- // Toast notifications
358
392
  .Toastify__toast-theme--colored.Toastify__toast--default,
359
393
  .Toastify__toast-theme--light {
360
394
  @apply bg-dark-550 text-white;
@@ -379,7 +413,6 @@ img {
379
413
  fill: currentColor !important;
380
414
  }
381
415
 
382
- // Toast container
383
416
  .Toastify__toast-container {
384
417
  pointer-events: none;
385
418
  --toastify-toast-bd-radius: 6px;
@@ -387,19 +420,17 @@ img {
387
420
 
388
421
  .Toastify__toast {
389
422
  min-height: 50px !important;
390
- height: 50px !important; // Keep fixed height for consistency
423
+ height: 50px !important;
391
424
  pointer-events: auto !important;
392
425
  margin-bottom: 6px !important;
393
-
394
- // Ultra-smooth animations with optimized timing
426
+
395
427
  transition: transform 0.18s cubic-bezier(0.25, 0.1, 0.25, 1), opacity 0.12s cubic-bezier(0.25, 0.1, 0.25, 1) !important;
396
428
  transform: translate3d(0, 0, 0);
397
-
398
- // Override default animations with smoother curves
429
+
399
430
  &.Toastify__slide-enter-active {
400
431
  animation: slideInRight 0.22s cubic-bezier(0.25, 0.1, 0.25, 1);
401
432
  }
402
-
433
+
403
434
  &.Toastify__slide-exit-active {
404
435
  animation: slideOutRight 0.12s cubic-bezier(0.4, 0, 1, 1);
405
436
  }
@@ -416,7 +447,6 @@ img {
416
447
  }
417
448
  }
418
449
 
419
- // Tighter, more precise animations
420
450
  @keyframes slideInRight {
421
451
  0% {
422
452
  transform: translateX(110%);
@@ -453,11 +483,37 @@ img {
453
483
 
454
484
  .Toastify__progress-bar {
455
485
  height: 2px;
456
- transition: width 0.08s cubic-bezier(0.25, 0.1, 0.25, 1); // Ultra-smooth progress bar
486
+ transition: width 0.08s cubic-bezier(0.25, 0.1, 0.25, 1);
487
+ }
488
+
489
+ /* ==========================================================================
490
+ ROOT CONFIGURATION & iOS OPTIMIZATIONS
491
+ ========================================================================== */
492
+
493
+ :root {
494
+ touch-action: pan-x pan-y;
495
+ height: 100%;
496
+ --toastify-toast-width: 520px;
497
+ }
498
+
499
+ @supports (-webkit-appearance: none) {
500
+ .component-container,
501
+ .card-dark,
502
+ h1,
503
+ h2,
504
+ h3,
505
+ h4,
506
+ h5,
507
+ h6 {
508
+ transform: translate3d(0, 0, 0);
509
+ }
457
510
  }
458
511
 
459
- // Mobile optimizations
460
- @media (max-width: 768px) {
512
+ /* ==========================================================================
513
+ MOBILE RESPONSIVE OPTIMIZATIONS - CONSOLIDATED
514
+ ========================================================================== */
515
+
516
+ @screen md {
461
517
  .text-heading {
462
518
  @apply text-sm;
463
519
  }
@@ -469,19 +525,37 @@ img {
469
525
 
470
526
  .btn-action {
471
527
  @apply text-sm px-6 h-12;
472
- min-height: 48px; // Apple's recommended minimum touch target size
528
+ min-height: 48px;
473
529
  }
474
530
 
475
- .form-grid {
476
- @apply grid-cols-1;
531
+ .status-indicator {
532
+ width: 6px;
533
+ height: 6px;
534
+ min-width: 6px;
535
+ min-height: 6px;
536
+ }
537
+ }
538
+
539
+ @screen mobile-portrait {
540
+ .btn-action {
541
+ @apply text-base px-8 h-14;
542
+ min-height: 56px;
543
+ font-weight: 600;
544
+ border-radius: 8px;
545
+ }
546
+
547
+ .status-indicator {
548
+ width: 5px;
549
+ height: 5px;
550
+ min-width: 5px;
551
+ min-height: 5px;
477
552
  }
478
553
  }
479
554
 
480
- // iPhone landscape mode - larger buttons for easier touch
481
- @media only screen and (max-device-width: 430px) and (orientation: landscape) {
555
+ @screen mobile-landscape {
482
556
  .btn-action {
483
557
  @apply text-base px-8 h-14;
484
- min-height: 56px; // Extra large for landscape touch
558
+ min-height: 56px;
485
559
  font-weight: 600;
486
560
  }
487
561
  }
@@ -2,20 +2,20 @@
2
2
  <div class="form-section">
3
3
  <!-- Username -->
4
4
  <div class="input-wrapper mb-4">
5
- <label style="display: flex; align-items: center; font-size: 12px; margin-bottom: 8px; color: #a0a0a6">
6
- Username
7
- <ProfileIcon style="margin-left: 8px; width: 16px; height: 16px" />
8
- </label>
5
+ <label class="label-override">
6
+ Username
7
+ <ProfileIcon />
8
+ </label>
9
9
  <div class="input-default">
10
10
  <input v-model="user" placeholder="Username" />
11
11
  </div>
12
12
  </div>
13
13
  <!-- Password -->
14
14
  <div class="input-wrapper">
15
- <label style="display: flex; align-items: center; font-size: 12px; margin-bottom: 8px; color: #a0a0a6">
16
- Password
17
- <KeyIcon style="margin-left: 8px; width: 16px; height: 16px" />
18
- </label>
15
+ <label class="label-override">
16
+ Password
17
+ <KeyIcon />
18
+ </label>
19
19
  <div class="input-default">
20
20
  <input v-model="password" type="password" placeholder="Password" />
21
21
  </div>