@necrolab/dashboard 0.5.15 → 0.5.16

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 (121) hide show
  1. package/backend/api.js +2 -3
  2. package/eslint.config.js +46 -0
  3. package/index.html +2 -1
  4. package/package.json +5 -2
  5. package/src/App.vue +140 -170
  6. package/src/assets/css/base/mixins.scss +72 -0
  7. package/src/assets/css/base/reset.scss +0 -2
  8. package/src/assets/css/base/scroll.scss +43 -36
  9. package/src/assets/css/base/typography.scss +9 -10
  10. package/src/assets/css/base/variables.scss +43 -0
  11. package/src/assets/css/components/accessibility.scss +37 -0
  12. package/src/assets/css/components/buttons.scss +58 -15
  13. package/src/assets/css/components/forms.scss +31 -32
  14. package/src/assets/css/components/headers.scss +12 -20
  15. package/src/assets/css/components/modals.scss +2 -2
  16. package/src/assets/css/components/search-groups.scss +28 -22
  17. package/src/assets/css/components/tables.scss +5 -7
  18. package/src/assets/css/components/toasts.scss +7 -7
  19. package/src/assets/css/components/utilities.scss +220 -0
  20. package/src/assets/css/main.scss +66 -77
  21. package/src/components/Auth/LoginForm.vue +5 -84
  22. package/src/components/Editors/Account/Account.vue +8 -10
  23. package/src/components/Editors/Account/AccountCreator.vue +28 -59
  24. package/src/components/Editors/Account/AccountView.vue +38 -86
  25. package/src/components/Editors/Account/CreateAccount.vue +8 -50
  26. package/src/components/Editors/Profile/CreateProfile.vue +74 -131
  27. package/src/components/Editors/Profile/Profile.vue +15 -17
  28. package/src/components/Editors/Profile/ProfileCountryChooser.vue +16 -60
  29. package/src/components/Editors/Profile/ProfileView.vue +46 -96
  30. package/src/components/Editors/TagLabel.vue +16 -55
  31. package/src/components/Editors/TagToggle.vue +20 -8
  32. package/src/components/Filter/Filter.vue +62 -75
  33. package/src/components/Filter/FilterPreview.vue +161 -135
  34. package/src/components/Filter/PriceSortToggle.vue +36 -43
  35. package/src/components/Table/Header.vue +1 -1
  36. package/src/components/Table/Table.vue +45 -51
  37. package/src/components/Tasks/CheckStock.vue +7 -16
  38. package/src/components/Tasks/Controls/DesktopControls.vue +15 -60
  39. package/src/components/Tasks/Controls/MobileControls.vue +5 -20
  40. package/src/components/Tasks/CreateTaskAXS.vue +20 -118
  41. package/src/components/Tasks/CreateTaskTM.vue +33 -189
  42. package/src/components/Tasks/EventDetailRow.vue +21 -0
  43. package/src/components/Tasks/MassEdit.vue +6 -16
  44. package/src/components/Tasks/QuickSettings.vue +140 -216
  45. package/src/components/Tasks/ScrapeVenue.vue +4 -13
  46. package/src/components/Tasks/Stats.vue +19 -38
  47. package/src/components/Tasks/Task.vue +65 -268
  48. package/src/components/Tasks/TaskLabel.vue +9 -3
  49. package/src/components/Tasks/TaskView.vue +43 -63
  50. package/src/components/Tasks/Utilities.vue +10 -44
  51. package/src/components/Tasks/ViewTask.vue +23 -107
  52. package/src/components/icons/Close.vue +2 -8
  53. package/src/components/icons/Gear.vue +8 -8
  54. package/src/components/icons/Hash.vue +5 -0
  55. package/src/components/icons/Key.vue +2 -8
  56. package/src/components/icons/Pencil.vue +2 -8
  57. package/src/components/icons/Profile.vue +2 -8
  58. package/src/components/icons/Sell.vue +2 -8
  59. package/src/components/icons/Spinner.vue +4 -7
  60. package/src/components/icons/SquareCheck.vue +2 -8
  61. package/src/components/icons/SquareUncheck.vue +2 -8
  62. package/src/components/icons/Wildcard.vue +2 -8
  63. package/src/components/icons/index.js +3 -1
  64. package/src/components/ui/ActionButtonGroup.vue +113 -52
  65. package/src/components/ui/BalanceIndicator.vue +60 -0
  66. package/src/components/ui/EmptyState.vue +24 -0
  67. package/src/components/ui/EnableDisableToggle.vue +23 -0
  68. package/src/components/ui/FormField.vue +48 -48
  69. package/src/components/ui/IconLabel.vue +23 -0
  70. package/src/components/ui/InfoRow.vue +21 -54
  71. package/src/components/ui/Modal.vue +89 -56
  72. package/src/components/ui/Navbar.vue +60 -41
  73. package/src/components/ui/ReadonlyFieldsSection.vue +31 -0
  74. package/src/components/ui/ReconnectIndicator.vue +111 -124
  75. package/src/components/ui/SectionCard.vue +6 -14
  76. package/src/components/ui/Splash.vue +2 -10
  77. package/src/components/ui/StatusBadge.vue +26 -28
  78. package/src/components/ui/TaskToggle.vue +54 -0
  79. package/src/components/ui/controls/CountryChooser.vue +27 -64
  80. package/src/components/ui/controls/EyeToggle.vue +1 -1
  81. package/src/components/ui/controls/atomic/Checkbox.vue +40 -121
  82. package/src/components/ui/controls/atomic/Dropdown.vue +103 -139
  83. package/src/components/ui/controls/atomic/MultiDropdown.vue +71 -119
  84. package/src/components/ui/controls/atomic/Switch.vue +21 -84
  85. package/src/composables/useColorMapping.js +15 -0
  86. package/src/composables/useCopyToClipboard.js +1 -1
  87. package/src/composables/useDateFormatting.js +21 -0
  88. package/src/composables/useDeviceDetection.js +14 -0
  89. package/src/composables/useDropdownPosition.js +3 -4
  90. package/src/composables/useDynamicTableHeight.js +31 -0
  91. package/src/composables/useRowSelection.js +0 -3
  92. package/src/composables/useTicketPricing.js +16 -0
  93. package/src/composables/useWindowDimensions.js +21 -0
  94. package/src/libs/Filter.js +14 -20
  95. package/src/libs/panzoom.js +1 -5
  96. package/src/libs/utils/array.js +60 -0
  97. package/src/{stores/utils.js → libs/utils/dataGeneration.js} +2 -250
  98. package/src/libs/utils/eventUrl.js +40 -0
  99. package/src/libs/utils/string.js +28 -0
  100. package/src/libs/utils/time.js +20 -0
  101. package/src/libs/utils/validation.js +88 -0
  102. package/src/main.js +0 -2
  103. package/src/stores/connection.js +1 -4
  104. package/src/stores/logger.js +6 -12
  105. package/src/stores/sampleData.js +1 -2
  106. package/src/stores/ui.js +59 -36
  107. package/src/views/Accounts.vue +13 -24
  108. package/src/views/Console.vue +70 -172
  109. package/src/views/Editor.vue +211 -379
  110. package/src/views/FilterBuilder.vue +188 -371
  111. package/src/views/Login.vue +3 -28
  112. package/src/views/Profiles.vue +8 -15
  113. package/src/views/Tasks.vue +49 -36
  114. package/tailwind.config.js +82 -71
  115. package/workbox-config.cjs +47 -5
  116. package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2438
  117. package/exit +0 -209
  118. package/run +0 -177
  119. package/src/assets/css/base/color-fallbacks.scss +0 -10
  120. package/switch-branch.sh +0 -41
  121. /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <div
4
- class="dropdown input-default p-4 w-16 bg-dark-550 small-dropdown"
4
+ class="dropdown input-default !rounded-full !p-0 !w-[3em] !h-[3em] flex justify-center items-center !bg-clip-border bg-dark-550"
5
5
  ref="dropdownRef"
6
6
  @click="toggleOpen"
7
7
  >
@@ -17,42 +17,42 @@
17
17
  <transition name="fade">
18
18
  <div
19
19
  v-if="open"
20
- class="dropdown-content-portal special-dropdown"
20
+ class="bg-dark-400 border border-dark-650 rounded-lg shadow-2xl z-50 p-2 !max-h-52 !overflow-y-auto custom-scrollbar-y min-w-20 w-25"
21
21
  :style="menuStyle"
22
22
  @click.stop
23
23
  @wheel.stop
24
24
  @touchmove.stop
25
25
  >
26
- <div class="header-item">TM</div>
26
+ <div class="country-header-item">TM</div>
27
27
  <div
28
28
  v-bind:key="country.id"
29
29
  v-for="country in countries.TM"
30
30
  class="country-item"
31
31
  @click="selectCountry(country, 'TM')"
32
32
  >
33
- <div class="flex items-center justify-center gap-2">
34
- <span class="text-xs font-medium">{{
33
+ <div class="flex items-center justify-center gap-1.5 w-full flex-nowrap">
34
+ <span class="text-xs font-medium whitespace-nowrap flex-shrink-0 text-center">{{
35
35
  country.siteId.split("_")[1]
36
36
  }}</span>
37
37
  <img
38
- class="w-5 h-4"
38
+ class="w-4.5 h-3.5 flex-shrink-0"
39
39
  :src="`/flags/${country.siteId.split('_')[1].toLowerCase()}.svg`"
40
40
  />
41
41
  </div>
42
42
  </div>
43
- <div class="header-item">AXS</div>
43
+ <div class="country-header-item">AXS</div>
44
44
  <div
45
45
  v-bind:key="country.id"
46
46
  v-for="country in countries.AXS"
47
47
  class="country-item"
48
48
  @click="selectCountry(country, 'AXS')"
49
49
  >
50
- <div class="flex items-center justify-center gap-2">
51
- <span class="text-xs font-medium">{{
50
+ <div class="flex items-center justify-center gap-1.5 w-full flex-nowrap">
51
+ <span class="text-xs font-medium whitespace-nowrap flex-shrink-0 text-center">{{
52
52
  country.siteId.split("_")[1]
53
53
  }}</span>
54
54
  <img
55
- class="w-5 h-4"
55
+ class="w-4.5 h-3.5 flex-shrink-0"
56
56
  :src="`/flags/${country.siteId.split('_')[1].toLowerCase()}.svg`"
57
57
  />
58
58
  </div>
@@ -108,74 +108,37 @@ const selectCountry = (country, module) => {
108
108
  </script>
109
109
 
110
110
  <style scoped>
111
- .special-dropdown {
112
- @apply min-w-20;
113
- }
114
-
115
- .small-dropdown {
116
- @apply bg-clip-border rounded-full w-12 h-12 flex justify-center items-center;
117
- padding: 0;
118
- }
119
-
120
- .dropdown-content-portal {
121
- @apply bg-dark-400 border border-dark-650 rounded-lg shadow-2xl z-50;
122
- @apply max-h-52 overflow-y-auto touch-pan-y;
123
- padding: 0.5rem;
124
- overscroll-behavior: contain;
125
- -webkit-overflow-scrolling: touch;
126
- scrollbar-width: none;
127
- -ms-overflow-style: none;
128
- min-width: 100px;
129
- width: 100px;
130
- }
131
-
132
- .dropdown-content-portal::-webkit-scrollbar {
133
- display: none;
134
- }
135
-
136
- .header-item {
111
+ .country-header-item {
137
112
  @apply text-center text-xs font-bold text-white;
138
- @apply py-2 px-1 mx-0.5 my-1 rounded-md;
113
+ @apply py-2 px-1 my-1 mx-0.5;
114
+ @apply cursor-default pointer-events-none;
115
+ @apply border rounded-md tracking-wider;
139
116
  @apply flex items-center justify-center;
140
- @apply pointer-events-none cursor-default;
141
117
  @apply relative;
142
- background: linear-gradient(
143
- 135deg,
144
- rgba(255, 255, 255, 0.08) 0%,
145
- rgba(255, 255, 255, 0.04) 100%
146
- );
147
- border: 1px solid rgba(255, 255, 255, 0.1);
148
- letter-spacing: 0.5px;
118
+ border-color: rgba(255, 255, 255, 0.1);
119
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%);
149
120
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
150
121
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
151
122
  }
152
123
 
153
- .header-item:first-child {
124
+ .country-header-item:first-of-type {
154
125
  @apply mt-0.5;
155
126
  }
156
127
 
157
- .header-item::before {
158
- content: "";
159
- position: absolute;
160
- top: 0;
161
- left: 0;
162
- right: 0;
163
- height: 1px;
164
- background: linear-gradient(
165
- 90deg,
166
- transparent 0%,
167
- rgba(255, 255, 255, 0.2) 50%,
168
- transparent 100%
169
- );
170
- border-radius: 6px 6px 0 0;
128
+ .country-header-item::before {
129
+ content: '';
130
+ @apply absolute top-0 left-0 right-0 h-px rounded-t-md;
131
+ background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.2) 50%, transparent 100%);
171
132
  }
172
133
 
173
134
  .country-item {
174
- @apply py-2 px-1 mx-0.5 my-px text-sm text-white;
175
- @apply cursor-pointer rounded-md min-h-8;
135
+ @apply py-2 px-1 my-px mx-0.5 min-h-8;
136
+ @apply text-sm text-white cursor-pointer rounded-md;
176
137
  @apply flex items-center justify-center;
177
- transition: all 0.15s ease;
138
+ @apply transition-all duration-150 ease-in-out;
178
139
  }
179
140
 
180
- /* Flex layout already defined in template with Tailwind classes */
141
+ .country-item:hover {
142
+ @apply bg-dark-650;
143
+ }
181
144
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <button @click="toggle" class="w-22 cursor-pointer">
2
+ <button @click="toggle" class="w-22 cursor-pointer" :aria-label="value ? 'Hide' : 'Show'" :aria-pressed="value">
3
3
  <img v-if="value" class="w-5 h-5" src="@/assets/img/eyes/open.svg" alt="Open Eye" />
4
4
  <img v-else class="w-5 h-5" src="@/assets/img/eyes/closed.svg" alt="Closed Eye" />
5
5
  </button>
@@ -1,137 +1,56 @@
1
1
  <template>
2
2
  <button
3
- class="modern-checkbox"
3
+ class="checkbox-base"
4
+ :class="[
5
+ isHeader ? 'size-4.5 border-dark-550' : 'size-5 border-2 border-dark-700',
6
+ toggled ? 'bg-accent-green border-accent-green hover:bg-accent-green-hover hover:border-accent-green-hover' : 'hover:border-dark-550',
7
+ isHeader && !toggled ? 'hover:border-accent-green hover:bg-accent-green/10' : ''
8
+ ]"
9
+ role="checkbox"
10
+ :aria-checked="toggled"
11
+ :aria-label="isHeader ? 'Select all' : 'Select item'"
4
12
  @click="
5
13
  checked = !checked;
6
14
  $emit('valueUpdate', checked);
7
15
  "
8
- :class="{ checked: toggled, 'header-checkbox': isHeader }"
9
16
  >
10
- <div class="checkbox-inner">
11
- <!-- Header checkbox design -->
12
- <div v-if="isHeader" class="header-indicator" :class="{ visible: toggled }"></div>
13
-
14
- <!-- Row checkbox design -->
15
- <svg
16
- v-else
17
- class="checkmark"
18
- :class="{ visible: toggled }"
19
- viewBox="0 0 24 24"
20
- fill="none"
21
- xmlns="http://www.w3.org/2000/svg"
22
- >
23
- <path
24
- d="M20 6L9 17L4 12"
25
- stroke="currentColor"
26
- stroke-width="3"
27
- stroke-linecap="round"
28
- stroke-linejoin="round"
29
- />
30
- </svg>
31
- </div>
17
+ <!-- Header checkbox indicator -->
18
+ <div
19
+ v-if="isHeader"
20
+ class="size-1.5 rounded-full bg-white transition-all duration-200 ease-out"
21
+ :class="toggled ? 'opacity-100 scale-100' : 'opacity-0 scale-[0.3]'"
22
+ ></div>
23
+
24
+ <!-- Row checkbox checkmark -->
25
+ <svg
26
+ v-else
27
+ class="size-2 text-white transition-all duration-200 ease-out hover:[@media(hover:hover)]:scale-110"
28
+ :class="toggled ? 'opacity-100 scale-100' : 'opacity-0 scale-50'"
29
+ viewBox="0 0 24 24"
30
+ fill="none"
31
+ >
32
+ <path
33
+ d="M20 6L9 17L4 12"
34
+ stroke="currentColor"
35
+ stroke-width="3"
36
+ stroke-linecap="round"
37
+ stroke-linejoin="round"
38
+ />
39
+ </svg>
32
40
  </button>
33
41
  </template>
34
- <style lang="scss" scoped>
35
- .modern-checkbox {
36
- @apply relative flex items-center justify-center cursor-pointer flex-shrink-0;
37
- width: 18px;
38
- height: 18px;
39
- border-radius: 50%;
40
- border: 2px solid oklch(0.28 0 0);
41
- background: transparent;
42
- transition: all 0.2s ease;
43
-
44
- &:hover {
45
- border-color: oklch(0.33 0 0);
46
- transform: scale(1.05);
47
- }
48
-
49
- &.checked {
50
- background: oklch(0.72 0.15 145);
51
- border-color: oklch(0.72 0.15 145);
52
-
53
- &:hover {
54
- background: oklch(0.78 0.12 145);
55
- border-color: oklch(0.78 0.12 145);
56
- }
57
- }
58
-
59
- &.header-checkbox {
60
- width: 16px;
61
- height: 16px;
62
- border-color: oklch(0.33 0 0);
63
-
64
- &:hover {
65
- border-color: oklch(0.72 0.15 145);
66
- background: rgba(136, 201, 153, 0.1);
67
- }
68
-
69
- &.checked {
70
- background: oklch(0.72 0.15 145);
71
- border-color: oklch(0.72 0.15 145);
72
-
73
- &:hover {
74
- background: oklch(0.78 0.12 145);
75
- border-color: oklch(0.78 0.12 145);
76
- }
77
- }
78
- }
79
-
80
- &:focus-visible {
81
- outline: 2px solid oklch(0.72 0.15 145);
82
- outline-offset: 2px;
83
- }
84
- }
85
-
86
- .checkbox-inner {
87
- @apply relative w-full h-full flex items-center justify-center;
88
- }
89
-
90
- .checkmark {
91
- width: 8px;
92
- height: 8px;
93
- color: #ffffff;
94
- opacity: 0;
95
- transform: scale(0.5);
96
- transition: all 0.2s ease;
97
-
98
- &.visible {
99
- opacity: 1;
100
- transform: scale(1);
101
- }
102
- }
103
-
104
- .header-indicator {
105
- width: 6px;
106
- height: 6px;
107
- background: #ffffff;
108
- border-radius: 50%;
109
- opacity: 0;
110
- transform: scale(0.3);
111
- transition: all 0.2s ease;
112
42
 
113
- &.visible {
114
- opacity: 1;
115
- transform: scale(1);
116
- }
117
- }
118
-
119
- @media (hover: hover) {
120
- .modern-checkbox:hover {
121
- transform: scale(1.05);
122
- }
123
-
124
- .modern-checkbox.checked:hover .checkmark {
125
- transform: scale(1.1);
126
- }
127
- }
128
- </style>
129
43
  <script setup>
130
- import { CheckmarkIcon } from "@/components/icons";
131
44
  import { ref } from "vue";
132
45
  const props = defineProps({
133
- toggled: { type: Boolean, required: false, default: false },
134
- isHeader: { type: Boolean, required: false, default: false }
46
+ toggled: {
47
+ type: Boolean,
48
+ default: false
49
+ },
50
+ isHeader: {
51
+ type: Boolean,
52
+ default: false
53
+ }
135
54
  });
136
55
 
137
56
  const checked = ref(props.toggled);