@necrolab/dashboard 0.5.13 → 0.5.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.
- package/docs/plans/2026-02-08-tailwind-consolidation.md +330 -308
- package/package.json +1 -1
- package/src/assets/css/base/color-fallbacks.scss +10 -0
- package/src/assets/css/components/headers.scss +127 -0
- package/src/assets/css/components/search-groups.scss +3 -0
- package/src/assets/css/main.scss +8 -0
- package/src/components/Table/Table.vue +60 -5
- package/src/components/Tasks/Utilities.vue +4 -2
- package/src/components/ui/InfoRow.vue +3 -1
- package/src/components/ui/Modal.vue +33 -25
- package/src/components/ui/controls/atomic/Dropdown.vue +56 -13
- package/src/components/ui/controls/atomic/MultiDropdown.vue +28 -2
- package/src/composables/useDropdownPosition.js +2 -2
- package/src/views/Accounts.vue +4 -7
- package/src/views/Console.vue +6 -4
- package/src/views/Editor.vue +6 -4
- package/src/views/FilterBuilder.vue +4 -4
- package/src/views/Profiles.vue +4 -7
- package/src/views/Tasks.vue +7 -7
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
### Task 1.1: Extend Tailwind Color Tokens
|
|
18
18
|
|
|
19
19
|
**Files:**
|
|
20
|
+
|
|
20
21
|
- Modify: `tailwind.config.js:30-77`
|
|
21
22
|
|
|
22
23
|
**Step 1: Add extended dark scale for rgba replacements**
|
|
@@ -98,6 +99,7 @@ git commit -m "feat: extend Tailwind color tokens for theme consolidation
|
|
|
98
99
|
### Task 1.2: Extend Shadow System
|
|
99
100
|
|
|
100
101
|
**Files:**
|
|
102
|
+
|
|
101
103
|
- Modify: `tailwind.config.js:135-138`
|
|
102
104
|
|
|
103
105
|
**Step 1: Replace boxShadow extend section**
|
|
@@ -171,6 +173,7 @@ git commit -m "feat: extend Tailwind design tokens
|
|
|
171
173
|
### Task 2.1: Clean Up App.vue iPhone Landscape Code
|
|
172
174
|
|
|
173
175
|
**Files:**
|
|
176
|
+
|
|
174
177
|
- Modify: `src/App.vue`
|
|
175
178
|
|
|
176
179
|
**Step 1: Read current App.vue**
|
|
@@ -180,6 +183,7 @@ Run: Read `src/App.vue`
|
|
|
180
183
|
**Step 2: Remove iPhone landscape lock overlay**
|
|
181
184
|
|
|
182
185
|
Find and remove:
|
|
186
|
+
|
|
183
187
|
- `.landscape-lock` class styles (lines ~739-796)
|
|
184
188
|
- `.landscape-lock-content` styles
|
|
185
189
|
- `LandscapeLockIcon` component
|
|
@@ -189,6 +193,7 @@ Find and remove:
|
|
|
189
193
|
**Step 3: Remove mobile-landscape breakpoint styles**
|
|
190
194
|
|
|
191
195
|
Search for `@media` queries containing:
|
|
196
|
+
|
|
192
197
|
- `mobile-landscape`
|
|
193
198
|
- `(orientation: landscape) and (max-height: 500px)`
|
|
194
199
|
|
|
@@ -217,6 +222,7 @@ git commit -m "refactor: remove iPhone landscape support
|
|
|
217
222
|
### Task 2.2: Update Tailwind Config - Remove Landscape Breakpoints
|
|
218
223
|
|
|
219
224
|
**Files:**
|
|
225
|
+
|
|
220
226
|
- Modify: `tailwind.config.js:92-116`
|
|
221
227
|
|
|
222
228
|
**Step 1: Remove mobile-landscape breakpoint**
|
|
@@ -261,6 +267,7 @@ git commit -m "refactor: remove mobile-landscape breakpoint
|
|
|
261
267
|
### Task 3.1: Create StatusBadge Component
|
|
262
268
|
|
|
263
269
|
**Files:**
|
|
270
|
+
|
|
264
271
|
- Create: `src/components/ui/StatusBadge.vue`
|
|
265
272
|
- Test: Manual testing in Account.vue, Profile.vue
|
|
266
273
|
|
|
@@ -268,48 +275,47 @@ git commit -m "refactor: remove mobile-landscape breakpoint
|
|
|
268
275
|
|
|
269
276
|
```vue
|
|
270
277
|
<script setup>
|
|
271
|
-
import
|
|
272
|
-
import
|
|
273
|
-
import CloseXIcon from '@/assets/icons/close-x.svg'
|
|
278
|
+
import CheckmarkIcon from "@/assets/icons/checkmark.svg";
|
|
279
|
+
import CloseXIcon from "@/assets/icons/close-x.svg";
|
|
274
280
|
|
|
275
281
|
const props = defineProps({
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
})
|
|
282
|
+
enabled: {
|
|
283
|
+
type: Boolean,
|
|
284
|
+
required: true
|
|
285
|
+
},
|
|
286
|
+
size: {
|
|
287
|
+
type: String,
|
|
288
|
+
default: "small",
|
|
289
|
+
validator: (value) => ["small", "large"].includes(value)
|
|
290
|
+
}
|
|
291
|
+
});
|
|
286
292
|
|
|
287
293
|
const sizeClasses = {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
294
|
+
small: "w-6 h-6",
|
|
295
|
+
large: "w-[26px] h-[26px]"
|
|
296
|
+
};
|
|
291
297
|
|
|
292
|
-
const enabledClasses =
|
|
293
|
-
const disabledClasses =
|
|
298
|
+
const enabledClasses = "bg-accent-green/20 border-accent-green/30";
|
|
299
|
+
const disabledClasses = "bg-red-500/20 border-red-500/30";
|
|
294
300
|
</script>
|
|
295
301
|
|
|
296
302
|
<template>
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
</div>
|
|
303
|
+
<div
|
|
304
|
+
:class="[
|
|
305
|
+
'flex items-center justify-center rounded-full border-2 transition-all duration-200',
|
|
306
|
+
enabled ? enabledClasses : disabledClasses,
|
|
307
|
+
sizeClasses[size]
|
|
308
|
+
]">
|
|
309
|
+
<CheckmarkIcon v-if="enabled" class="h-3 w-3 text-accent-green" />
|
|
310
|
+
<CloseXIcon v-else class="h-3 w-3 text-red-500" />
|
|
311
|
+
</div>
|
|
307
312
|
</template>
|
|
308
313
|
```
|
|
309
314
|
|
|
310
315
|
**Step 2: Test component in isolation**
|
|
311
316
|
|
|
312
317
|
Create temporary test in a view to verify rendering:
|
|
318
|
+
|
|
313
319
|
- Enabled state
|
|
314
320
|
- Disabled state
|
|
315
321
|
- Small size
|
|
@@ -332,6 +338,7 @@ git commit -m "feat: create StatusBadge component
|
|
|
332
338
|
### Task 3.2: Replace StatusBadge in Account.vue
|
|
333
339
|
|
|
334
340
|
**Files:**
|
|
341
|
+
|
|
335
342
|
- Modify: `src/components/Editors/Account/Account.vue`
|
|
336
343
|
|
|
337
344
|
**Step 1: Import StatusBadge**
|
|
@@ -339,7 +346,7 @@ git commit -m "feat: create StatusBadge component
|
|
|
339
346
|
Add to imports:
|
|
340
347
|
|
|
341
348
|
```javascript
|
|
342
|
-
import StatusBadge from
|
|
349
|
+
import StatusBadge from "@/components/ui/StatusBadge.vue";
|
|
343
350
|
```
|
|
344
351
|
|
|
345
352
|
**Step 2: Replace enabled badge markup**
|
|
@@ -353,6 +360,7 @@ Find lines with class `enabled-badge` or `disabled-badge` and replace with:
|
|
|
353
360
|
**Step 3: Remove old badge styles**
|
|
354
361
|
|
|
355
362
|
Remove from `<style scoped>`:
|
|
363
|
+
|
|
356
364
|
- `.enabled-badge` class (lines ~60-105)
|
|
357
365
|
- `.disabled-badge` class
|
|
358
366
|
|
|
@@ -377,6 +385,7 @@ git commit -m "refactor: use StatusBadge component in Account.vue
|
|
|
377
385
|
### Task 3.3: Replace StatusBadge in Profile.vue
|
|
378
386
|
|
|
379
387
|
**Files:**
|
|
388
|
+
|
|
380
389
|
- Modify: `src/components/Editors/Profile/Profile.vue`
|
|
381
390
|
|
|
382
391
|
**Step 1: Import StatusBadge**
|
|
@@ -399,6 +408,7 @@ git commit -m "refactor: use StatusBadge component in Profile.vue"
|
|
|
399
408
|
### Task 3.4: Replace StatusBadge in CreateAccount.vue
|
|
400
409
|
|
|
401
410
|
**Files:**
|
|
411
|
+
|
|
402
412
|
- Modify: `src/components/Editors/Account/CreateAccount.vue`
|
|
403
413
|
|
|
404
414
|
**Step 1-5:** Same as Task 3.3
|
|
@@ -415,6 +425,7 @@ git commit -m "refactor: use StatusBadge component in CreateAccount.vue"
|
|
|
415
425
|
### Task 3.5: Replace StatusBadge in CreateProfile.vue
|
|
416
426
|
|
|
417
427
|
**Files:**
|
|
428
|
+
|
|
418
429
|
- Modify: `src/components/Editors/Profile/CreateProfile.vue`
|
|
419
430
|
|
|
420
431
|
**Step 1-5:** Same as Task 3.3
|
|
@@ -431,6 +442,7 @@ git commit -m "refactor: use StatusBadge component in CreateProfile.vue"
|
|
|
431
442
|
### Task 3.6: Create useRowSelection Composable
|
|
432
443
|
|
|
433
444
|
**Files:**
|
|
445
|
+
|
|
434
446
|
- Create: `src/composables/useRowSelection.js`
|
|
435
447
|
|
|
436
448
|
**Step 1: Create composable file**
|
|
@@ -446,43 +458,43 @@ git commit -m "refactor: use StatusBadge component in CreateProfile.vue"
|
|
|
446
458
|
* @returns {Object} Event handlers for @dblclick, @touchstart, @touchend
|
|
447
459
|
*/
|
|
448
460
|
export function useRowSelection(toggleCallback) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
461
|
+
let lastTapTime = 0;
|
|
462
|
+
const DOUBLE_TAP_DELAY = 300;
|
|
463
|
+
|
|
464
|
+
const handleDoubleClick = (event) => {
|
|
465
|
+
// Don't trigger on button or checkbox clicks
|
|
466
|
+
if (event.target.closest("button") || event.target.closest(".checkbox")) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
toggleCallback();
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const handleTouchStart = (event) => {
|
|
473
|
+
const currentTime = Date.now();
|
|
474
|
+
const tapGap = currentTime - lastTapTime;
|
|
475
|
+
|
|
476
|
+
if (tapGap < DOUBLE_TAP_DELAY && tapGap > 0) {
|
|
477
|
+
// Don't trigger on button or checkbox taps
|
|
478
|
+
if (!event.target.closest("button") && !event.target.closest(".checkbox")) {
|
|
479
|
+
event.preventDefault();
|
|
480
|
+
toggleCallback();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
lastTapTime = currentTime;
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
const handleTouchEnd = (event) => {
|
|
487
|
+
// Prevent default touch behavior on buttons/checkboxes
|
|
488
|
+
if (event.target.closest("button") || event.target.closest(".checkbox")) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
handleDoubleClick,
|
|
495
|
+
handleTouchStart,
|
|
496
|
+
handleTouchEnd
|
|
497
|
+
};
|
|
486
498
|
}
|
|
487
499
|
```
|
|
488
500
|
|
|
@@ -502,12 +514,13 @@ git commit -m "feat: create useRowSelection composable
|
|
|
502
514
|
### Task 3.7: Use useRowSelection in Task.vue
|
|
503
515
|
|
|
504
516
|
**Files:**
|
|
517
|
+
|
|
505
518
|
- Modify: `src/components/Tasks/Task.vue`
|
|
506
519
|
|
|
507
520
|
**Step 1: Import composable**
|
|
508
521
|
|
|
509
522
|
```javascript
|
|
510
|
-
import { useRowSelection } from
|
|
523
|
+
import { useRowSelection } from "@/composables/useRowSelection";
|
|
511
524
|
```
|
|
512
525
|
|
|
513
526
|
**Step 2: Use composable in setup**
|
|
@@ -516,8 +529,8 @@ Replace manual event handler logic with:
|
|
|
516
529
|
|
|
517
530
|
```javascript
|
|
518
531
|
const { handleDoubleClick, handleTouchStart, handleTouchEnd } = useRowSelection(() => {
|
|
519
|
-
|
|
520
|
-
})
|
|
532
|
+
emit("toggle", props.task);
|
|
533
|
+
});
|
|
521
534
|
```
|
|
522
535
|
|
|
523
536
|
**Step 3: Update template event handlers**
|
|
@@ -525,11 +538,7 @@ const { handleDoubleClick, handleTouchStart, handleTouchEnd } = useRowSelection(
|
|
|
525
538
|
Replace existing `@dblclick`, `@touchstart`, `@touchend` with:
|
|
526
539
|
|
|
527
540
|
```vue
|
|
528
|
-
<tr
|
|
529
|
-
@dblclick="handleDoubleClick"
|
|
530
|
-
@touchstart="handleTouchStart"
|
|
531
|
-
@touchend="handleTouchEnd"
|
|
532
|
-
>
|
|
541
|
+
<tr @dblclick="handleDoubleClick" @touchstart="handleTouchStart" @touchend="handleTouchEnd"></tr>
|
|
533
542
|
```
|
|
534
543
|
|
|
535
544
|
**Step 4: Remove old event handler code**
|
|
@@ -558,6 +567,7 @@ git commit -m "refactor: use useRowSelection composable in Task.vue
|
|
|
558
567
|
### Task 3.8: Use useRowSelection in Account.vue
|
|
559
568
|
|
|
560
569
|
**Files:**
|
|
570
|
+
|
|
561
571
|
- Modify: `src/components/Editors/Account/Account.vue`
|
|
562
572
|
|
|
563
573
|
**Step 1-6:** Same as Task 3.7, adapted for Account component
|
|
@@ -574,6 +584,7 @@ git commit -m "refactor: use useRowSelection composable in Account.vue"
|
|
|
574
584
|
### Task 3.9: Use useRowSelection in Profile.vue
|
|
575
585
|
|
|
576
586
|
**Files:**
|
|
587
|
+
|
|
577
588
|
- Modify: `src/components/Editors/Profile/Profile.vue`
|
|
578
589
|
|
|
579
590
|
**Step 1-6:** Same as Task 3.7, adapted for Profile component
|
|
@@ -590,12 +601,13 @@ git commit -m "refactor: use useRowSelection composable in Profile.vue"
|
|
|
590
601
|
### Task 3.10: Create useCopyToClipboard Composable
|
|
591
602
|
|
|
592
603
|
**Files:**
|
|
604
|
+
|
|
593
605
|
- Create: `src/composables/useCopyToClipboard.js`
|
|
594
606
|
|
|
595
607
|
**Step 1: Create composable**
|
|
596
608
|
|
|
597
609
|
```javascript
|
|
598
|
-
import { useUIStore } from
|
|
610
|
+
import { useUIStore } from "@/stores/ui";
|
|
599
611
|
|
|
600
612
|
/**
|
|
601
613
|
* useCopyToClipboard - Composable for copying text with user feedback
|
|
@@ -603,22 +615,23 @@ import { useUIStore } from '@/stores/ui'
|
|
|
603
615
|
* @returns {Object} Copy function with success notification
|
|
604
616
|
*/
|
|
605
617
|
export function useCopyToClipboard() {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
618
|
+
const ui = useUIStore();
|
|
619
|
+
|
|
620
|
+
const copy = (text, message = "Copied to clipboard") => {
|
|
621
|
+
if (!text) return;
|
|
622
|
+
|
|
623
|
+
navigator.clipboard
|
|
624
|
+
.writeText(text)
|
|
625
|
+
.then(() => {
|
|
626
|
+
ui.showSuccess(message);
|
|
627
|
+
})
|
|
628
|
+
.catch((err) => {
|
|
629
|
+
ui.showError("Failed to copy");
|
|
630
|
+
console.error("Copy failed:", err);
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
return { copy };
|
|
622
635
|
}
|
|
623
636
|
```
|
|
624
637
|
|
|
@@ -638,14 +651,15 @@ git commit -m "feat: create useCopyToClipboard composable
|
|
|
638
651
|
### Task 3.11: Use useCopyToClipboard in Task.vue
|
|
639
652
|
|
|
640
653
|
**Files:**
|
|
654
|
+
|
|
641
655
|
- Modify: `src/components/Tasks/Task.vue`
|
|
642
656
|
|
|
643
657
|
**Step 1: Import and use composable**
|
|
644
658
|
|
|
645
659
|
```javascript
|
|
646
|
-
import { useCopyToClipboard } from
|
|
660
|
+
import { useCopyToClipboard } from "@/composables/useCopyToClipboard";
|
|
647
661
|
|
|
648
|
-
const { copy } = useCopyToClipboard()
|
|
662
|
+
const { copy } = useCopyToClipboard();
|
|
649
663
|
```
|
|
650
664
|
|
|
651
665
|
**Step 2: Replace manual copy logic**
|
|
@@ -653,7 +667,7 @@ const { copy } = useCopyToClipboard()
|
|
|
653
667
|
Replace `navigator.clipboard.writeText()` calls with:
|
|
654
668
|
|
|
655
669
|
```javascript
|
|
656
|
-
copy(task.id,
|
|
670
|
+
copy(task.id, "Copied task ID");
|
|
657
671
|
```
|
|
658
672
|
|
|
659
673
|
**Step 3: Remove old copy code**
|
|
@@ -674,6 +688,7 @@ git commit -m "refactor: use useCopyToClipboard composable in Task.vue"
|
|
|
674
688
|
### Task 3.12: Use useCopyToClipboard in ViewTask.vue
|
|
675
689
|
|
|
676
690
|
**Files:**
|
|
691
|
+
|
|
677
692
|
- Modify: `src/components/Tasks/ViewTask.vue`
|
|
678
693
|
|
|
679
694
|
**Step 1-5:** Same as Task 3.11
|
|
@@ -690,6 +705,7 @@ git commit -m "refactor: use useCopyToClipboard composable in ViewTask.vue"
|
|
|
690
705
|
### Task 3.13: Use useCopyToClipboard in Account.vue
|
|
691
706
|
|
|
692
707
|
**Files:**
|
|
708
|
+
|
|
693
709
|
- Modify: `src/components/Editors/Account/Account.vue`
|
|
694
710
|
|
|
695
711
|
**Step 1-5:** Same as Task 3.11
|
|
@@ -708,6 +724,7 @@ git commit -m "refactor: use useCopyToClipboard composable in Account.vue"
|
|
|
708
724
|
### Task 4.1: Clean Up App.vue Global Styles
|
|
709
725
|
|
|
710
726
|
**Files:**
|
|
727
|
+
|
|
711
728
|
- Modify: `src/App.vue`
|
|
712
729
|
|
|
713
730
|
**Step 1: Read current App.vue styles**
|
|
@@ -717,10 +734,11 @@ Run: Read `src/App.vue` focusing on `<style>` section
|
|
|
717
734
|
**Step 2: Remove global !important overrides**
|
|
718
735
|
|
|
719
736
|
Find and remove/replace:
|
|
737
|
+
|
|
720
738
|
- `html, body` with !important on overflow, width, height, touch-action (lines ~679-688)
|
|
721
|
-
|
|
739
|
+
- Replace with proper overflow utilities on specific elements
|
|
722
740
|
- Global `* { touch-action: manipulation !important }` (lines ~699-702)
|
|
723
|
-
|
|
741
|
+
- Remove entirely, use `touch-manipulation` class where needed
|
|
724
742
|
|
|
725
743
|
**Step 3: Convert .layout to Tailwind**
|
|
726
744
|
|
|
@@ -728,15 +746,15 @@ Replace:
|
|
|
728
746
|
|
|
729
747
|
```css
|
|
730
748
|
.layout {
|
|
731
|
-
|
|
732
|
-
|
|
749
|
+
min-height: 90vh;
|
|
750
|
+
height: 100vh !important;
|
|
733
751
|
}
|
|
734
752
|
```
|
|
735
753
|
|
|
736
754
|
With template classes:
|
|
737
755
|
|
|
738
756
|
```vue
|
|
739
|
-
<div class="layout
|
|
757
|
+
<div class="layout h-screen min-h-screen"></div>
|
|
740
758
|
```
|
|
741
759
|
|
|
742
760
|
Remove CSS block.
|
|
@@ -747,14 +765,14 @@ Replace:
|
|
|
747
765
|
|
|
748
766
|
```css
|
|
749
767
|
.component-container {
|
|
750
|
-
padding-left: 1rem;
|
|
751
|
-
padding-right: 1rem;
|
|
752
|
-
}
|
|
753
|
-
@media (min-width: 480px) {
|
|
754
|
-
.component-container {
|
|
755
768
|
padding-left: 1rem;
|
|
756
769
|
padding-right: 1rem;
|
|
757
|
-
|
|
770
|
+
}
|
|
771
|
+
@media (min-width: 480px) {
|
|
772
|
+
.component-container {
|
|
773
|
+
padding-left: 1rem;
|
|
774
|
+
padding-right: 1rem;
|
|
775
|
+
}
|
|
758
776
|
}
|
|
759
777
|
/* etc */
|
|
760
778
|
```
|
|
@@ -762,7 +780,7 @@ Replace:
|
|
|
762
780
|
With template classes:
|
|
763
781
|
|
|
764
782
|
```vue
|
|
765
|
-
<div class="component-container px-4 xs:px-4 md:px-2 lg:px-6 xl:px-10">
|
|
783
|
+
<div class="component-container px-4 xs:px-4 md:px-2 lg:px-6 xl:px-10"></div>
|
|
766
784
|
```
|
|
767
785
|
|
|
768
786
|
Remove CSS block.
|
|
@@ -795,6 +813,7 @@ git commit -m "refactor: clean up App.vue global styles
|
|
|
795
813
|
### Task 4.2: Clean Up Navbar.vue
|
|
796
814
|
|
|
797
815
|
**Files:**
|
|
816
|
+
|
|
798
817
|
- Modify: `src/components/ui/Navbar.vue`
|
|
799
818
|
|
|
800
819
|
**Step 1: Read Navbar.vue styles**
|
|
@@ -822,15 +841,15 @@ Replace:
|
|
|
822
841
|
|
|
823
842
|
```css
|
|
824
843
|
svg {
|
|
825
|
-
|
|
826
|
-
|
|
844
|
+
width: 20px !important;
|
|
845
|
+
height: 20px !important;
|
|
827
846
|
}
|
|
828
847
|
```
|
|
829
848
|
|
|
830
849
|
With template classes on SVG components:
|
|
831
850
|
|
|
832
851
|
```vue
|
|
833
|
-
<SomeIcon class="
|
|
852
|
+
<SomeIcon class="h-5 w-5" />
|
|
834
853
|
```
|
|
835
854
|
|
|
836
855
|
**Step 4: Convert .navbar-link height**
|
|
@@ -839,8 +858,8 @@ Replace:
|
|
|
839
858
|
|
|
840
859
|
```css
|
|
841
860
|
.navbar-link {
|
|
842
|
-
|
|
843
|
-
|
|
861
|
+
height: 40px;
|
|
862
|
+
border-bottom: 2px solid transparent;
|
|
844
863
|
}
|
|
845
864
|
```
|
|
846
865
|
|
|
@@ -873,7 +892,7 @@ Replace:
|
|
|
873
892
|
|
|
874
893
|
```css
|
|
875
894
|
.force-z {
|
|
876
|
-
|
|
895
|
+
z-index: 20000;
|
|
877
896
|
}
|
|
878
897
|
```
|
|
879
898
|
|
|
@@ -915,6 +934,7 @@ git commit -m "refactor: clean up Navbar.vue styles
|
|
|
915
934
|
### Task 4.3: Clean Up Modal.vue
|
|
916
935
|
|
|
917
936
|
**Files:**
|
|
937
|
+
|
|
918
938
|
- Modify: `src/components/ui/Modal.vue`
|
|
919
939
|
|
|
920
940
|
**Step 1: Read Modal.vue styles**
|
|
@@ -927,23 +947,23 @@ Replace:
|
|
|
927
947
|
|
|
928
948
|
```css
|
|
929
949
|
.modal-mask {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
950
|
+
position: fixed;
|
|
951
|
+
z-index: 25000;
|
|
952
|
+
top: 0;
|
|
953
|
+
left: 0;
|
|
954
|
+
width: 100%;
|
|
955
|
+
height: 100%;
|
|
956
|
+
background-color: rgba(17, 17, 17, 0.85);
|
|
957
|
+
backdrop-filter: blur(4px);
|
|
958
|
+
display: flex;
|
|
959
|
+
padding-top: 3.5rem;
|
|
940
960
|
}
|
|
941
961
|
```
|
|
942
962
|
|
|
943
963
|
With template classes:
|
|
944
964
|
|
|
945
965
|
```vue
|
|
946
|
-
<div class="modal-mask
|
|
966
|
+
<div class="modal-mask bg-overlay-dark backdrop-blur-xs fixed inset-0 z-modal flex pt-14"></div>
|
|
947
967
|
```
|
|
948
968
|
|
|
949
969
|
**Step 3: Simplify .component-modal bottom margin**
|
|
@@ -953,7 +973,7 @@ Replace:
|
|
|
953
973
|
```css
|
|
954
974
|
margin-bottom: 20rem;
|
|
955
975
|
@media (max-width: 480px) {
|
|
956
|
-
|
|
976
|
+
margin-bottom: 25rem;
|
|
957
977
|
}
|
|
958
978
|
```
|
|
959
979
|
|
|
@@ -981,6 +1001,7 @@ class="pb-60 md:pb-12"
|
|
|
981
1001
|
**Step 5: Test modal**
|
|
982
1002
|
|
|
983
1003
|
Open any modal, test:
|
|
1004
|
+
|
|
984
1005
|
- Overlay appearance
|
|
985
1006
|
- Modal positioning
|
|
986
1007
|
- Scroll behavior
|
|
@@ -1005,6 +1026,7 @@ git commit -m "refactor: clean up Modal.vue styles
|
|
|
1005
1026
|
### Task 4.4: Clean Up Task.vue
|
|
1006
1027
|
|
|
1007
1028
|
**Files:**
|
|
1029
|
+
|
|
1008
1030
|
- Modify: `src/components/Tasks/Task.vue`
|
|
1009
1031
|
|
|
1010
1032
|
**Step 1: Read Task.vue styles**
|
|
@@ -1017,7 +1039,7 @@ Replace:
|
|
|
1017
1039
|
|
|
1018
1040
|
```css
|
|
1019
1041
|
min-width: 10px !important;
|
|
1020
|
-
stroke: oklch(0.
|
|
1042
|
+
stroke: oklch(0.6 0 0) !important;
|
|
1021
1043
|
```
|
|
1022
1044
|
|
|
1023
1045
|
With proper component props or Tailwind classes:
|
|
@@ -1048,9 +1070,9 @@ Replace:
|
|
|
1048
1070
|
|
|
1049
1071
|
```css
|
|
1050
1072
|
@media (max-width: 480px) {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1073
|
+
left: 4rem !important;
|
|
1074
|
+
top: 0.25rem !important;
|
|
1075
|
+
z-index: 1 !important;
|
|
1054
1076
|
}
|
|
1055
1077
|
```
|
|
1056
1078
|
|
|
@@ -1112,6 +1134,7 @@ git commit -m "refactor: clean up Task.vue styles
|
|
|
1112
1134
|
### Task 4.5: Clean Up Dropdown.vue
|
|
1113
1135
|
|
|
1114
1136
|
**Files:**
|
|
1137
|
+
|
|
1115
1138
|
- Modify: `src/components/ui/controls/atomic/Dropdown.vue`
|
|
1116
1139
|
|
|
1117
1140
|
**Step 1: Read Dropdown.vue styles**
|
|
@@ -1201,109 +1224,97 @@ git commit -m "refactor: clean up Dropdown.vue styles
|
|
|
1201
1224
|
### Task 5.1: Create FormField Component
|
|
1202
1225
|
|
|
1203
1226
|
**Files:**
|
|
1227
|
+
|
|
1204
1228
|
- Create: `src/components/ui/FormField.vue`
|
|
1205
1229
|
|
|
1206
1230
|
**Step 1: Create component**
|
|
1207
1231
|
|
|
1208
1232
|
```vue
|
|
1209
1233
|
<script setup>
|
|
1210
|
-
import {
|
|
1211
|
-
import UpIcon from
|
|
1212
|
-
import DownIcon from
|
|
1234
|
+
import { defineEmits, useAttrs } from "vue";
|
|
1235
|
+
import UpIcon from "@/assets/icons/up.svg";
|
|
1236
|
+
import DownIcon from "@/assets/icons/down.svg";
|
|
1213
1237
|
|
|
1214
1238
|
const props = defineProps({
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
})
|
|
1253
|
-
|
|
1254
|
-
const emit = defineEmits([
|
|
1255
|
-
const attrs = useAttrs()
|
|
1239
|
+
label: {
|
|
1240
|
+
type: String,
|
|
1241
|
+
required: true
|
|
1242
|
+
},
|
|
1243
|
+
icon: {
|
|
1244
|
+
type: Object,
|
|
1245
|
+
default: null
|
|
1246
|
+
},
|
|
1247
|
+
modelValue: {
|
|
1248
|
+
type: [String, Number],
|
|
1249
|
+
default: ""
|
|
1250
|
+
},
|
|
1251
|
+
type: {
|
|
1252
|
+
type: String,
|
|
1253
|
+
default: "text"
|
|
1254
|
+
},
|
|
1255
|
+
placeholder: {
|
|
1256
|
+
type: String,
|
|
1257
|
+
default: ""
|
|
1258
|
+
},
|
|
1259
|
+
required: {
|
|
1260
|
+
type: Boolean,
|
|
1261
|
+
default: false
|
|
1262
|
+
},
|
|
1263
|
+
hasError: {
|
|
1264
|
+
type: Boolean,
|
|
1265
|
+
default: false
|
|
1266
|
+
},
|
|
1267
|
+
incrementer: {
|
|
1268
|
+
type: Boolean,
|
|
1269
|
+
default: false
|
|
1270
|
+
},
|
|
1271
|
+
zIndex: {
|
|
1272
|
+
type: String,
|
|
1273
|
+
default: "0",
|
|
1274
|
+
validator: (value) => ["dropdown", "tooltip", "0", "1", "2"].includes(value)
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
|
|
1278
|
+
const emit = defineEmits(["update:modelValue", "increment", "decrement"]);
|
|
1279
|
+
const attrs = useAttrs();
|
|
1256
1280
|
|
|
1257
1281
|
const zIndexClasses = {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
}
|
|
1282
|
+
dropdown: "z-dropdown",
|
|
1283
|
+
tooltip: "z-tooltip",
|
|
1284
|
+
0: "z-0",
|
|
1285
|
+
1: "z-10",
|
|
1286
|
+
2: "z-20"
|
|
1287
|
+
};
|
|
1264
1288
|
</script>
|
|
1265
1289
|
|
|
1266
1290
|
<template>
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
class="px-2 py-1 hover:bg-dark-650 transition-colors"
|
|
1294
|
-
>
|
|
1295
|
-
<UpIcon class="w-3 h-3 text-light-400" />
|
|
1296
|
-
</button>
|
|
1297
|
-
<button
|
|
1298
|
-
@click="emit('decrement')"
|
|
1299
|
-
type="button"
|
|
1300
|
-
class="px-2 py-1 hover:bg-dark-650 transition-colors"
|
|
1301
|
-
>
|
|
1302
|
-
<DownIcon class="w-3 h-3 text-light-400" />
|
|
1303
|
-
</button>
|
|
1304
|
-
</div>
|
|
1291
|
+
<div class="flex flex-col" :class="zIndexClasses[zIndex]">
|
|
1292
|
+
<label class="mb-2 flex items-center gap-2 text-sm font-medium text-light-400">
|
|
1293
|
+
{{ label }}
|
|
1294
|
+
<component :is="icon" v-if="icon" class="h-4 w-4" />
|
|
1295
|
+
</label>
|
|
1296
|
+
<div
|
|
1297
|
+
class="relative flex items-center rounded-md border bg-dark-500 transition-colors"
|
|
1298
|
+
:class="[hasError ? 'border-error-500' : 'border-dark-600', required ? 'ring-primary/20 ring-2' : '']">
|
|
1299
|
+
<slot>
|
|
1300
|
+
<input
|
|
1301
|
+
:type="type"
|
|
1302
|
+
:placeholder="placeholder"
|
|
1303
|
+
:value="modelValue"
|
|
1304
|
+
@input="emit('update:modelValue', $event.target.value)"
|
|
1305
|
+
v-bind="attrs"
|
|
1306
|
+
class="w-full bg-transparent px-3 py-2 text-light-300 outline-none" />
|
|
1307
|
+
</slot>
|
|
1308
|
+
<div v-if="incrementer" class="flex flex-col border-l border-dark-600">
|
|
1309
|
+
<button @click="emit('increment')" type="button" class="px-2 py-1 transition-colors hover:bg-dark-650">
|
|
1310
|
+
<UpIcon class="h-3 w-3 text-light-400" />
|
|
1311
|
+
</button>
|
|
1312
|
+
<button @click="emit('decrement')" type="button" class="px-2 py-1 transition-colors hover:bg-dark-650">
|
|
1313
|
+
<DownIcon class="h-3 w-3 text-light-400" />
|
|
1314
|
+
</button>
|
|
1315
|
+
</div>
|
|
1316
|
+
</div>
|
|
1305
1317
|
</div>
|
|
1306
|
-
</div>
|
|
1307
1318
|
</template>
|
|
1308
1319
|
```
|
|
1309
1320
|
|
|
@@ -1324,12 +1335,13 @@ git commit -m "feat: create FormField component
|
|
|
1324
1335
|
### Task 5.2: Replace FormField in CreateTaskAXS.vue
|
|
1325
1336
|
|
|
1326
1337
|
**Files:**
|
|
1338
|
+
|
|
1327
1339
|
- Modify: `src/components/Tasks/CreateTaskAXS.vue`
|
|
1328
1340
|
|
|
1329
1341
|
**Step 1: Import FormField**
|
|
1330
1342
|
|
|
1331
1343
|
```javascript
|
|
1332
|
-
import FormField from
|
|
1344
|
+
import FormField from "@/components/ui/FormField.vue";
|
|
1333
1345
|
```
|
|
1334
1346
|
|
|
1335
1347
|
**Step 2: Replace input wrapper markup**
|
|
@@ -1351,12 +1363,7 @@ Find all instances of:
|
|
|
1351
1363
|
Replace with:
|
|
1352
1364
|
|
|
1353
1365
|
```vue
|
|
1354
|
-
<FormField
|
|
1355
|
-
label="Name"
|
|
1356
|
-
:icon="NameIcon"
|
|
1357
|
-
v-model="name"
|
|
1358
|
-
type="text"
|
|
1359
|
-
/>
|
|
1366
|
+
<FormField label="Name" :icon="NameIcon" v-model="name" type="text" />
|
|
1360
1367
|
```
|
|
1361
1368
|
|
|
1362
1369
|
**Step 3: Remove old input-wrapper styles**
|
|
@@ -1380,6 +1387,7 @@ git commit -m "refactor: use FormField component in CreateTaskAXS.vue
|
|
|
1380
1387
|
### Task 5.3: Replace FormField in CreateTaskTM.vue
|
|
1381
1388
|
|
|
1382
1389
|
**Files:**
|
|
1390
|
+
|
|
1383
1391
|
- Modify: `src/components/Tasks/CreateTaskTM.vue`
|
|
1384
1392
|
|
|
1385
1393
|
**Step 1-5:** Same as Task 5.2
|
|
@@ -1396,6 +1404,7 @@ git commit -m "refactor: use FormField component in CreateTaskTM.vue"
|
|
|
1396
1404
|
### Task 5.4: Replace FormField in CreateAccount.vue
|
|
1397
1405
|
|
|
1398
1406
|
**Files:**
|
|
1407
|
+
|
|
1399
1408
|
- Modify: `src/components/Editors/Account/CreateAccount.vue`
|
|
1400
1409
|
|
|
1401
1410
|
**Step 1-5:** Same as Task 5.2
|
|
@@ -1412,6 +1421,7 @@ git commit -m "refactor: use FormField component in CreateAccount.vue"
|
|
|
1412
1421
|
### Task 5.5: Replace FormField in CreateProfile.vue
|
|
1413
1422
|
|
|
1414
1423
|
**Files:**
|
|
1424
|
+
|
|
1415
1425
|
- Modify: `src/components/Editors/Profile/CreateProfile.vue`
|
|
1416
1426
|
|
|
1417
1427
|
**Step 1-5:** Same as Task 5.2
|
|
@@ -1428,71 +1438,63 @@ git commit -m "refactor: use FormField component in CreateProfile.vue"
|
|
|
1428
1438
|
### Task 5.6: Create InfoRow Component
|
|
1429
1439
|
|
|
1430
1440
|
**Files:**
|
|
1441
|
+
|
|
1431
1442
|
- Create: `src/components/ui/InfoRow.vue`
|
|
1432
1443
|
|
|
1433
1444
|
**Step 1: Create component**
|
|
1434
1445
|
|
|
1435
1446
|
```vue
|
|
1436
1447
|
<script setup>
|
|
1437
|
-
import {
|
|
1438
|
-
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
|
1448
|
+
import { useCopyToClipboard } from "@/composables/useCopyToClipboard";
|
|
1439
1449
|
|
|
1440
1450
|
const props = defineProps({
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
})
|
|
1466
|
-
|
|
1467
|
-
const { copy } = useCopyToClipboard()
|
|
1451
|
+
icon: {
|
|
1452
|
+
type: Object,
|
|
1453
|
+
default: null
|
|
1454
|
+
},
|
|
1455
|
+
label: {
|
|
1456
|
+
type: String,
|
|
1457
|
+
required: true
|
|
1458
|
+
},
|
|
1459
|
+
value: {
|
|
1460
|
+
type: [String, Number],
|
|
1461
|
+
default: ""
|
|
1462
|
+
},
|
|
1463
|
+
valueClass: {
|
|
1464
|
+
type: String,
|
|
1465
|
+
default: ""
|
|
1466
|
+
},
|
|
1467
|
+
copyable: {
|
|
1468
|
+
type: Boolean,
|
|
1469
|
+
default: false
|
|
1470
|
+
},
|
|
1471
|
+
copyText: {
|
|
1472
|
+
type: String,
|
|
1473
|
+
default: ""
|
|
1474
|
+
}
|
|
1475
|
+
});
|
|
1476
|
+
|
|
1477
|
+
const { copy } = useCopyToClipboard();
|
|
1468
1478
|
|
|
1469
1479
|
const handleCopy = () => {
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
}
|
|
1480
|
+
if (props.copyable) {
|
|
1481
|
+
copy(props.copyText || props.value, "Copied");
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1474
1484
|
</script>
|
|
1475
1485
|
|
|
1476
1486
|
<template>
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
<span
|
|
1489
|
-
class="text-sm text-light-300 flex-1 text-right"
|
|
1490
|
-
:class="valueClass"
|
|
1491
|
-
>
|
|
1492
|
-
<slot>{{ value }}</slot>
|
|
1493
|
-
</span>
|
|
1494
|
-
<slot name="actions" />
|
|
1495
|
-
</div>
|
|
1487
|
+
<div
|
|
1488
|
+
class="flex items-center gap-3 rounded-md px-3 py-2 transition-colors hover:bg-dark-400/50"
|
|
1489
|
+
:class="{ 'cursor-pointer': copyable }"
|
|
1490
|
+
@click="handleCopy">
|
|
1491
|
+
<component :is="icon" v-if="icon" class="h-5 w-5 flex-shrink-0 text-light-500" />
|
|
1492
|
+
<span class="min-w-[100px] text-sm text-light-500">{{ label }}</span>
|
|
1493
|
+
<span class="flex-1 text-right text-sm text-light-300" :class="valueClass">
|
|
1494
|
+
<slot>{{ value }}</slot>
|
|
1495
|
+
</span>
|
|
1496
|
+
<slot name="actions" />
|
|
1497
|
+
</div>
|
|
1496
1498
|
</template>
|
|
1497
1499
|
```
|
|
1498
1500
|
|
|
@@ -1514,12 +1516,13 @@ git commit -m "feat: create InfoRow component
|
|
|
1514
1516
|
### Task 5.7: Replace InfoRow in ViewTask.vue
|
|
1515
1517
|
|
|
1516
1518
|
**Files:**
|
|
1519
|
+
|
|
1517
1520
|
- Modify: `src/components/Tasks/ViewTask.vue`
|
|
1518
1521
|
|
|
1519
1522
|
**Step 1: Import InfoRow**
|
|
1520
1523
|
|
|
1521
1524
|
```javascript
|
|
1522
|
-
import InfoRow from
|
|
1525
|
+
import InfoRow from "@/components/ui/InfoRow.vue";
|
|
1523
1526
|
```
|
|
1524
1527
|
|
|
1525
1528
|
**Step 2: Replace info row markup**
|
|
@@ -1537,13 +1540,7 @@ Find instances like:
|
|
|
1537
1540
|
Replace with:
|
|
1538
1541
|
|
|
1539
1542
|
```vue
|
|
1540
|
-
<InfoRow
|
|
1541
|
-
:icon="IdIcon"
|
|
1542
|
-
label="ID"
|
|
1543
|
-
:value="task.id"
|
|
1544
|
-
copyable
|
|
1545
|
-
:copy-text="task.id"
|
|
1546
|
-
/>
|
|
1543
|
+
<InfoRow :icon="IdIcon" label="ID" :value="task.id" copyable :copy-text="task.id" />
|
|
1547
1544
|
```
|
|
1548
1545
|
|
|
1549
1546
|
**Step 3: Test**
|
|
@@ -1566,32 +1563,28 @@ git commit -m "refactor: use InfoRow component in ViewTask.vue
|
|
|
1566
1563
|
### Task 5.8: Create SectionCard Component
|
|
1567
1564
|
|
|
1568
1565
|
**Files:**
|
|
1566
|
+
|
|
1569
1567
|
- Create: `src/components/ui/SectionCard.vue`
|
|
1570
1568
|
|
|
1571
1569
|
**Step 1: Create component**
|
|
1572
1570
|
|
|
1573
1571
|
```vue
|
|
1574
1572
|
<script setup>
|
|
1575
|
-
import { defineProps } from 'vue'
|
|
1576
|
-
|
|
1577
1573
|
const props = defineProps({
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
})
|
|
1574
|
+
title: {
|
|
1575
|
+
type: String,
|
|
1576
|
+
default: ""
|
|
1577
|
+
}
|
|
1578
|
+
});
|
|
1583
1579
|
</script>
|
|
1584
1580
|
|
|
1585
1581
|
<template>
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
</h3>
|
|
1593
|
-
<slot />
|
|
1594
|
-
</div>
|
|
1582
|
+
<div class="rounded-lg border border-dark-600 bg-dark-400 p-4">
|
|
1583
|
+
<h3 v-if="title" class="mb-4 border-b border-dark-600 pb-2 text-lg font-semibold text-light-300">
|
|
1584
|
+
{{ title }}
|
|
1585
|
+
</h3>
|
|
1586
|
+
<slot />
|
|
1587
|
+
</div>
|
|
1595
1588
|
</template>
|
|
1596
1589
|
```
|
|
1597
1590
|
|
|
@@ -1611,6 +1604,7 @@ git commit -m "feat: create SectionCard component
|
|
|
1611
1604
|
### Task 5.9: Use SectionCard in ViewTask.vue
|
|
1612
1605
|
|
|
1613
1606
|
**Files:**
|
|
1607
|
+
|
|
1614
1608
|
- Modify: `src/components/Tasks/ViewTask.vue`
|
|
1615
1609
|
|
|
1616
1610
|
**Step 1: Import SectionCard**
|
|
@@ -1650,15 +1644,16 @@ git commit -m "refactor: use SectionCard component in ViewTask.vue"
|
|
|
1650
1644
|
### Task 5.10: Create ActionButtonGroup Component
|
|
1651
1645
|
|
|
1652
1646
|
**Files:**
|
|
1647
|
+
|
|
1653
1648
|
- Create: `src/components/ui/ActionButtonGroup.vue`
|
|
1654
1649
|
|
|
1655
1650
|
**Step 1: Create component**
|
|
1656
1651
|
|
|
1657
1652
|
```vue
|
|
1658
1653
|
<template>
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1654
|
+
<ul class="flex items-center gap-1 mobile-portrait:gap-0.5">
|
|
1655
|
+
<slot />
|
|
1656
|
+
</ul>
|
|
1662
1657
|
</template>
|
|
1663
1658
|
|
|
1664
1659
|
<style scoped>
|
|
@@ -1682,6 +1677,7 @@ git commit -m "feat: create ActionButtonGroup component
|
|
|
1682
1677
|
### Task 5.11: Use ActionButtonGroup in Task.vue
|
|
1683
1678
|
|
|
1684
1679
|
**Files:**
|
|
1680
|
+
|
|
1685
1681
|
- Modify: `src/components/Tasks/Task.vue`
|
|
1686
1682
|
|
|
1687
1683
|
**Step 1: Import ActionButtonGroup**
|
|
@@ -1725,6 +1721,7 @@ git commit -m "refactor: use ActionButtonGroup in Task.vue
|
|
|
1725
1721
|
### Task 5.12: Use ActionButtonGroup in Account.vue
|
|
1726
1722
|
|
|
1727
1723
|
**Files:**
|
|
1724
|
+
|
|
1728
1725
|
- Modify: `src/components/Editors/Account/Account.vue`
|
|
1729
1726
|
|
|
1730
1727
|
**Step 1-5:** Same as Task 5.11
|
|
@@ -1741,6 +1738,7 @@ git commit -m "refactor: use ActionButtonGroup in Account.vue"
|
|
|
1741
1738
|
### Task 5.13: Use ActionButtonGroup in Profile.vue
|
|
1742
1739
|
|
|
1743
1740
|
**Files:**
|
|
1741
|
+
|
|
1744
1742
|
- Modify: `src/components/Editors/Profile/Profile.vue`
|
|
1745
1743
|
|
|
1746
1744
|
**Step 1-5:** Same as Task 5.11
|
|
@@ -1759,6 +1757,7 @@ git commit -m "refactor: use ActionButtonGroup in Profile.vue"
|
|
|
1759
1757
|
### Task 6.1: Replace Hardcoded Gray Colors
|
|
1760
1758
|
|
|
1761
1759
|
**Files:**
|
|
1760
|
+
|
|
1762
1761
|
- Modify: `src/components/Editors/Account/AccountView.vue`
|
|
1763
1762
|
- Modify: `src/components/Editors/Profile/ProfileView.vue`
|
|
1764
1763
|
- Modify: `src/components/Tasks/TaskView.vue`
|
|
@@ -1792,6 +1791,7 @@ git commit -m "refactor: replace hardcoded gray text colors with theme tokens
|
|
|
1792
1791
|
### Task 6.2: Replace rgba Gray Backgrounds in Filter.vue
|
|
1793
1792
|
|
|
1794
1793
|
**Files:**
|
|
1794
|
+
|
|
1795
1795
|
- Modify: `src/components/Filter/Filter.vue`
|
|
1796
1796
|
|
|
1797
1797
|
**Step 1: Replace rgba(61, 62, 68, X)**
|
|
@@ -1836,6 +1836,7 @@ git commit -m "refactor: replace rgba gray backgrounds with dark scale tokens
|
|
|
1836
1836
|
### Task 6.3: Replace Error Color Variations
|
|
1837
1837
|
|
|
1838
1838
|
**Files:**
|
|
1839
|
+
|
|
1839
1840
|
- Modify: `src/components/Filter/Filter.vue`
|
|
1840
1841
|
- Modify: `src/components/Editors/Profile/CreateProfile.vue`
|
|
1841
1842
|
- Modify: `src/components/Editors/Account/CreateAccount.vue`
|
|
@@ -1870,6 +1871,7 @@ git commit -m "refactor: standardize error colors
|
|
|
1870
1871
|
### Task 6.4: Replace Modal Overlay Color
|
|
1871
1872
|
|
|
1872
1873
|
**Files:**
|
|
1874
|
+
|
|
1873
1875
|
- Modify: `src/components/ui/Modal.vue` (if not done in Task 4.3)
|
|
1874
1876
|
|
|
1875
1877
|
**Step 1: Replace rgba(17, 17, 17, 0.85)**
|
|
@@ -1893,6 +1895,7 @@ git commit -m "refactor: use overlay-dark token for modal background"
|
|
|
1893
1895
|
### Task 6.5: Replace Accent Color Variations in ReconnectIndicator
|
|
1894
1896
|
|
|
1895
1897
|
**Files:**
|
|
1898
|
+
|
|
1896
1899
|
- Modify: `src/components/ui/ReconnectIndicator.vue`
|
|
1897
1900
|
|
|
1898
1901
|
**Step 1: Replace rgba(136, 201, 153, X)**
|
|
@@ -1929,6 +1932,7 @@ git commit -m "refactor: use accent-green token for reconnect indicator
|
|
|
1929
1932
|
### Task 7.1: Clean Up CountryChooser.vue
|
|
1930
1933
|
|
|
1931
1934
|
**Files:**
|
|
1935
|
+
|
|
1932
1936
|
- Modify: `src/components/ui/controls/CountryChooser.vue`
|
|
1933
1937
|
|
|
1934
1938
|
**Step 1: Replace circular button hack**
|
|
@@ -1988,6 +1992,7 @@ git commit -m "refactor: clean up CountryChooser.vue
|
|
|
1988
1992
|
### Task 7.2: Clean Up Table.vue
|
|
1989
1993
|
|
|
1990
1994
|
**Files:**
|
|
1995
|
+
|
|
1991
1996
|
- Modify: `src/components/Table/Table.vue`
|
|
1992
1997
|
|
|
1993
1998
|
**Step 1: Remove scroll !important**
|
|
@@ -2016,8 +2021,8 @@ Remove:
|
|
|
2016
2021
|
|
|
2017
2022
|
```css
|
|
2018
2023
|
@media (orientation: landscape) {
|
|
2019
|
-
|
|
2020
|
-
|
|
2024
|
+
max-height: calc(100vh - 160px) !important;
|
|
2025
|
+
margin-bottom: 2rem !important;
|
|
2021
2026
|
}
|
|
2022
2027
|
```
|
|
2023
2028
|
|
|
@@ -2044,6 +2049,7 @@ git commit -m "refactor: clean up Table.vue
|
|
|
2044
2049
|
### Task 7.3: Clean Up Console.vue
|
|
2045
2050
|
|
|
2046
2051
|
**Files:**
|
|
2052
|
+
|
|
2047
2053
|
- Modify: `src/views/Console.vue`
|
|
2048
2054
|
|
|
2049
2055
|
**Step 1: Optimize responsive padding**
|
|
@@ -2053,7 +2059,7 @@ Replace:
|
|
|
2053
2059
|
```css
|
|
2054
2060
|
padding-bottom: 4rem;
|
|
2055
2061
|
@media (max-width: 480px) {
|
|
2056
|
-
|
|
2062
|
+
padding-bottom: 6rem;
|
|
2057
2063
|
}
|
|
2058
2064
|
```
|
|
2059
2065
|
|
|
@@ -2081,6 +2087,7 @@ git commit -m "refactor: clean up Console.vue responsive padding"
|
|
|
2081
2087
|
### Task 7.4: Clean Up Tasks.vue
|
|
2082
2088
|
|
|
2083
2089
|
**Files:**
|
|
2090
|
+
|
|
2084
2091
|
- Modify: `src/views/Tasks.vue`
|
|
2085
2092
|
|
|
2086
2093
|
**Step 1: Remove PWA padding hack**
|
|
@@ -2089,7 +2096,7 @@ Find:
|
|
|
2089
2096
|
|
|
2090
2097
|
```css
|
|
2091
2098
|
@media (display-mode: standalone) {
|
|
2092
|
-
|
|
2099
|
+
padding-bottom: X !important;
|
|
2093
2100
|
}
|
|
2094
2101
|
```
|
|
2095
2102
|
|
|
@@ -2113,6 +2120,7 @@ git commit -m "refactor: clean up Tasks.vue PWA hacks"
|
|
|
2113
2120
|
### Task 7.5: Clean Up Switch.vue
|
|
2114
2121
|
|
|
2115
2122
|
**Files:**
|
|
2123
|
+
|
|
2116
2124
|
- Modify: `src/components/ui/controls/atomic/Switch.vue`
|
|
2117
2125
|
|
|
2118
2126
|
**Step 1: Convert hardcoded px to Tailwind**
|
|
@@ -2135,6 +2143,7 @@ git commit -m "refactor: optimize Switch.vue with Tailwind where applicable"
|
|
|
2135
2143
|
### Task 7.6: Clean Up Splash.vue
|
|
2136
2144
|
|
|
2137
2145
|
**Files:**
|
|
2146
|
+
|
|
2138
2147
|
- Modify: `src/components/ui/Splash.vue`
|
|
2139
2148
|
|
|
2140
2149
|
**Step 1: Replace background-color**
|
|
@@ -2160,6 +2169,7 @@ git commit -m "refactor: use theme color in Splash.vue"
|
|
|
2160
2169
|
### Task 8.1: Run Automated Verification Plan
|
|
2161
2170
|
|
|
2162
2171
|
**Files:**
|
|
2172
|
+
|
|
2163
2173
|
- Reference: `/Users/luca/Documents/GitHub/Necro/Dashboard/VERIFICATION_PLAN.md`
|
|
2164
2174
|
|
|
2165
2175
|
**Step 1: Start both dev servers**
|
|
@@ -2170,6 +2180,7 @@ Expected: Servers on 5173 and 8081
|
|
|
2170
2180
|
**Step 2: Manual quick check**
|
|
2171
2181
|
|
|
2172
2182
|
Test critical paths:
|
|
2183
|
+
|
|
2173
2184
|
- Login flow
|
|
2174
2185
|
- Navigate to each route
|
|
2175
2186
|
- Open/close modals
|
|
@@ -2180,6 +2191,7 @@ Test critical paths:
|
|
|
2180
2191
|
**Step 3: Responsive testing**
|
|
2181
2192
|
|
|
2182
2193
|
Test at breakpoints:
|
|
2194
|
+
|
|
2183
2195
|
- Mobile portrait (375px)
|
|
2184
2196
|
- iPad Pro (1024px)
|
|
2185
2197
|
- Desktop (1920px)
|
|
@@ -2207,6 +2219,7 @@ git commit -m "docs: verification results for Tailwind consolidation"
|
|
|
2207
2219
|
### Task 8.2: Count Remaining CSS Lines
|
|
2208
2220
|
|
|
2209
2221
|
**Files:**
|
|
2222
|
+
|
|
2210
2223
|
- All Vue files
|
|
2211
2224
|
|
|
2212
2225
|
**Step 1: Count <style> blocks**
|
|
@@ -2220,10 +2233,12 @@ Run: `grep -r "!important" src/components src/views | wc -l`
|
|
|
2220
2233
|
**Step 3: Compare with baseline**
|
|
2221
2234
|
|
|
2222
2235
|
Baseline:
|
|
2236
|
+
|
|
2223
2237
|
- 53 files with `<style>` blocks
|
|
2224
2238
|
- 378 `!important` declarations
|
|
2225
2239
|
|
|
2226
2240
|
Target:
|
|
2241
|
+
|
|
2227
2242
|
- < 20 files with `<style>` blocks (animations only)
|
|
2228
2243
|
- < 50 `!important` declarations
|
|
2229
2244
|
|
|
@@ -2236,6 +2251,7 @@ Create summary in docs/plans/2026-02-08-tailwind-consolidation-results.md
|
|
|
2236
2251
|
### Task 8.3: Create Final Summary Report
|
|
2237
2252
|
|
|
2238
2253
|
**Files:**
|
|
2254
|
+
|
|
2239
2255
|
- Create: `docs/plans/2026-02-08-tailwind-consolidation-results.md`
|
|
2240
2256
|
|
|
2241
2257
|
**Step 1: Document changes**
|
|
@@ -2246,12 +2262,14 @@ Create summary in docs/plans/2026-02-08-tailwind-consolidation-results.md
|
|
|
2246
2262
|
## Metrics
|
|
2247
2263
|
|
|
2248
2264
|
**Before:**
|
|
2265
|
+
|
|
2249
2266
|
- Files with <style> blocks: 53
|
|
2250
2267
|
- !important declarations: 378
|
|
2251
2268
|
- Lines of CSS: ~2000
|
|
2252
2269
|
- Duplicate components: 7 patterns identified
|
|
2253
2270
|
|
|
2254
2271
|
**After:**
|
|
2272
|
+
|
|
2255
2273
|
- Files with <style> blocks: X
|
|
2256
2274
|
- !important declarations: X
|
|
2257
2275
|
- Lines of CSS: ~X
|
|
@@ -2275,7 +2293,7 @@ Create summary in docs/plans/2026-02-08-tailwind-consolidation-results.md
|
|
|
2275
2293
|
- Dark scale extensions: 350, 450, 475, 625, 675
|
|
2276
2294
|
- Error colors: 300, 400, 500
|
|
2277
2295
|
- Overlay colors: dark, darker
|
|
2278
|
-
- Semantic tokens: text
|
|
2296
|
+
- Semantic tokens: text-_, bg-_, border-focus, primary
|
|
2279
2297
|
- Shadow system: 7 new shadows
|
|
2280
2298
|
- Font sizes: xxs, xxxs
|
|
2281
2299
|
|
|
@@ -2310,6 +2328,7 @@ git commit -m "docs: Tailwind consolidation completion report"
|
|
|
2310
2328
|
### Task 9.1: Update README (if exists)
|
|
2311
2329
|
|
|
2312
2330
|
**Files:**
|
|
2331
|
+
|
|
2313
2332
|
- Modify: `README.md` (if exists)
|
|
2314
2333
|
|
|
2315
2334
|
**Step 1: Document new components**
|
|
@@ -2393,6 +2412,7 @@ All functionality verified, no regressions."
|
|
|
2393
2412
|
**Estimated time:** 8-12 hours (depending on file complexity)
|
|
2394
2413
|
|
|
2395
2414
|
**Recommended approach:**
|
|
2415
|
+
|
|
2396
2416
|
1. Execute phases sequentially
|
|
2397
2417
|
2. Test after each phase before moving to next
|
|
2398
2418
|
3. Commit frequently (after each task)
|
|
@@ -2400,12 +2420,14 @@ All functionality verified, no regressions."
|
|
|
2400
2420
|
|
|
2401
2421
|
**Rollback strategy:**
|
|
2402
2422
|
If any phase causes issues, rollback to previous phase commit:
|
|
2423
|
+
|
|
2403
2424
|
```bash
|
|
2404
2425
|
git log --oneline
|
|
2405
2426
|
git reset --hard <commit-hash>
|
|
2406
2427
|
```
|
|
2407
2428
|
|
|
2408
2429
|
**Testing checklist per phase:**
|
|
2430
|
+
|
|
2409
2431
|
- [ ] Phase 1: Dev server starts, no config errors
|
|
2410
2432
|
- [ ] Phase 2: App loads without landscape lock
|
|
2411
2433
|
- [ ] Phase 3: Components render correctly
|