@necrolab/dashboard 0.5.14 → 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 (120) 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 +119 -0
  15. package/src/assets/css/components/modals.scss +2 -2
  16. package/src/assets/css/components/search-groups.scss +28 -19
  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 +72 -75
  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 +61 -12
  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 -42
  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 +78 -37
  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 +102 -95
  83. package/src/components/ui/controls/atomic/MultiDropdown.vue +72 -94
  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 +5 -6
  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 +17 -31
  108. package/src/views/Console.vue +76 -176
  109. package/src/views/Editor.vue +217 -383
  110. package/src/views/FilterBuilder.vue +190 -373
  111. package/src/views/Login.vue +3 -28
  112. package/src/views/Profiles.vue +12 -22
  113. package/src/views/Tasks.vue +51 -38
  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 -2416
  117. package/exit +0 -209
  118. package/run +0 -177
  119. package/switch-branch.sh +0 -41
  120. /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
@@ -1,84 +1,39 @@
1
1
  <template>
2
- <div class="task-controls flex-row">
3
- <div class="control-buttons mb-4 xl:mb-0">
4
- <button @click="$emit('startAll')" class="bg-green-400 smooth-hover responsive-button border-none">
5
- Start <PlayIcon />
2
+ <div class="flex-row gap-x-3">
3
+ <div class="flex gap-x-3 items-center w-full mb-4 xl:mb-0">
4
+ <button @click="$emit('startAll')" class="btn-control-success" aria-label="Start all tasks">
5
+ Start <PlayIcon class="ml-2" />
6
6
  </button>
7
- <button @click="$emit('stopAll')" class="bg-red-400 smooth-hover responsive-button border-none">
8
- Stop <PauseIcon />
7
+ <button @click="$emit('stopAll')" class="btn-control-danger" aria-label="Stop all tasks">
8
+ Stop <PauseIcon class="ml-2" />
9
9
  </button>
10
- <button @click="$emit('deleteAll')" class="bg-dark-400 smooth-hover responsive-button border border-dark-650 hover:border-dark-700">
11
- Delete <TrashIcon />
10
+ <button @click="$emit('deleteAll')" class="btn-action-responsive bg-dark-400 border border-dark-650 hover:border-dark-700 smooth-hover min-w-20 max-w-30 flex-grow xl:flex-initial" aria-label="Delete all tasks">
11
+ Delete <TrashIcon class="ml-2" />
12
12
  </button>
13
13
  <h4 class="text-light-300 text-sm flex-grow xl:flex-initial"></h4>
14
14
  </div>
15
15
  <div class="flex gap-x-3">
16
16
  <button
17
17
  :disabled="ui.disabledButtons['add-tasks']"
18
- class="bg-dark-400 disabled:opacity-70 smooth-hover flex-grow xl:flex-initial w-36 border border-dark-650 hover:border-dark-700"
18
+ class="btn-modal disabled:opacity-70 flex-grow xl:flex-initial w-36"
19
19
  @click="ui.toggleModal('create-task')"
20
- >
21
- Create Task
22
- <PlusIcon class="ml-2" />
20
+ aria-label="Create new task">
21
+ Create Task <PlusIcon class="ml-2" />
23
22
  </button>
24
-
25
23
  <button
26
- class="bg-dark-400 smooth-hover flex-grow xl:flex-initial w-36 border border-dark-650 hover:border-dark-700"
24
+ class="btn-modal flex-grow xl:flex-initial w-36"
27
25
  @click="ui.toggleModal('mass-edit-presale-code')"
28
26
  :disabled="ui.disabledButtons['mass-edit']"
29
27
  v-if="ui.currentModule == 'TM'"
30
- >
31
- Mass Edit
32
- <EditIcon class="ml-2" />
28
+ aria-label="Mass edit presale codes">
29
+ Mass Edit <EditIcon class="ml-2" />
33
30
  </button>
34
31
  </div>
35
32
  </div>
36
33
  </template>
37
34
  <script setup>
38
- import { ref } from "vue";
39
35
  import { useUIStore } from "@/stores/ui";
40
- import { PlayIcon, PauseIcon, TrashIcon, ExpandIcon, ShrinkIcon, PlusIcon, EditIcon } from "@/components/icons";
36
+ import { PlayIcon, PauseIcon, TrashIcon, PlusIcon, EditIcon } from "@/components/icons";
41
37
 
42
38
  const ui = useUIStore();
43
- const isExpanded = ref(false);
44
39
  </script>
45
- <style lang="scss" scoped>
46
- button {
47
- @apply text-white h-10 rounded-md text-xs flex items-center justify-center font-medium px-4;
48
- transition: all 0.15s ease;
49
-
50
- &.bg-dark-400:active, &.bg-dark-400:focus {
51
- outline: 1px solid oklch(0.72 0.15 145);
52
- outline-offset: 0;
53
- border-color: oklch(0.72 0.15 145) !important;
54
- }
55
- }
56
-
57
- .responsive-button {
58
- min-width: 80px;
59
- max-width: 120px;
60
- @apply flex-grow xl:flex-initial;
61
-
62
- @media (max-width: 768px) {
63
- @apply h-10 text-xs;
64
- }
65
- }
66
-
67
- .task-controls {
68
- @apply gap-x-3;
69
- .control-buttons {
70
- @apply flex gap-x-3 items-center w-full;
71
- button {
72
- svg {
73
- @apply ml-2;
74
- }
75
- }
76
- }
77
- .expand-shrink {
78
- @apply flex gap-x-2;
79
- button {
80
- @apply text-white text-xs px-4 flex items-center justify-center gap-x-4 duration-200 border border-light-300 hover:border-light-400;
81
- }
82
- }
83
- }
84
- </style>
@@ -1,11 +1,11 @@
1
1
  <template>
2
- <div class="mobile-controls flex items-center justify-between" v-once>
3
- <div class="expand-shrink">
4
- <button class="mobile-btn" @click="$emit('expand')">
2
+ <div class="flex items-center justify-between" v-once>
3
+ <div class="flex gap-x-2">
4
+ <button class="btn-control-mobile" @click="$emit('expand')" aria-label="Expand all tasks">
5
5
  Expand
6
6
  <ExpandIcon />
7
7
  </button>
8
- <button class="mobile-btn" @click="$emit('fold')">
8
+ <button class="btn-control-mobile" @click="$emit('fold')" aria-label="Collapse all tasks">
9
9
  Fold
10
10
  <ShrinkIcon />
11
11
  </button>
@@ -13,20 +13,5 @@
13
13
  </div>
14
14
  </template>
15
15
  <script setup>
16
- import { useUIStore } from "@/stores/ui";
17
-
18
- import { PlayIcon, PauseIcon, TrashIcon, ExpandIcon, ShrinkIcon, EditIcon } from "@/components/icons";
19
- const ui = useUIStore();
16
+ import { ExpandIcon, ShrinkIcon } from "@/components/icons";
20
17
  </script>
21
- <style lang="scss" scoped>
22
- .mobile-controls {
23
- .expand-shrink {
24
- @apply flex gap-x-2;
25
- .mobile-btn {
26
- @apply text-white text-xs px-3 flex items-center justify-center gap-x-1 h-10 rounded-md bg-dark-400 border border-dark-650 hover:border-dark-700 transition-all duration-150 font-medium;
27
- width: 80px;
28
- font-size: 11px;
29
- }
30
- }
31
- }
32
- </style>
@@ -6,7 +6,7 @@
6
6
  </template>
7
7
 
8
8
  <!-- Task Form -->
9
- <div class="form-grid mb-4 mt-4">
9
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4 mt-4">
10
10
  <!-- Event ID -->
11
11
  <FormField label="Event ID" :icon="StadiumIcon" required>
12
12
  <input placeholder="827474" v-model="task.eventId" required />
@@ -38,30 +38,12 @@
38
38
  </FormField>
39
39
 
40
40
  <!-- Task Amount -->
41
- <div class="input-wrapper">
42
- <label class="label-override mb-2">
43
- Amount
44
- <span class="ml-2 h-[18px]">#</span>
45
- </label>
46
- <div class="input-default">
47
- <input placeholder="20" min="1" type="number" pattern="\d*" v-model="task.taskQuantity" />
48
- <div class="input-incrementer">
49
- <button @click="task.taskQuantity++">
50
- <UpIcon />
51
- </button>
52
- <button @click="if (task.taskQuantity > 1) task.taskQuantity--;">
53
- <DownIcon />
54
- </button>
55
- </div>
56
- </div>
57
- </div>
41
+ <FormField label="Amount" :icon="HashIcon" incrementer @increment="task.taskQuantity++" @decrement="task.taskQuantity > 1 && task.taskQuantity--">
42
+ <input placeholder="20" min="1" type="number" pattern="\d*" v-model="task.taskQuantity" />
43
+ </FormField>
58
44
 
59
45
  <!-- Profile Tag(s) -->
60
- <div class="input-wrapper">
61
- <label class="label-override mb-2">
62
- Profile Tag(s)
63
- <TagIcon />
64
- </label>
46
+ <FormField label="Profile Tag(s)" :icon="TagIcon" noWrapper>
65
47
  <MultiDropdown
66
48
  class="w-full will-change-auto"
67
49
  :onSelect="(v) => (task.profileTags = v)"
@@ -71,14 +53,10 @@
71
53
  return { label: opt, value: opt };
72
54
  })
73
55
  " />
74
- </div>
56
+ </FormField>
75
57
 
76
58
  <!-- Account Tag -->
77
- <div class="input-wrapper">
78
- <label class="label-override mb-2">
79
- Account Tag
80
- <ScannerIcon />
81
- </label>
59
+ <FormField label="Account Tag" :icon="ScannerIcon" noWrapper>
82
60
  <Dropdown
83
61
  :onClick="(f) => (task.accountTag = f)"
84
62
  default="Default tag"
@@ -87,7 +65,7 @@
87
65
  :allowDefault="false"
88
66
  :capitalize="true"
89
67
  class="dropdown w-full" />
90
- </div>
68
+ </FormField>
91
69
 
92
70
  <!-- Start Offset -->
93
71
  <FormField label="Start Offset (Minutes)" :icon="ShieldIcon" incrementer @increment="task.startOffset = (task.startOffset || 0) + 1" @decrement="task.startOffset > 0 && task.startOffset--">
@@ -101,47 +79,18 @@
101
79
  </div>
102
80
  <div class="mb-3 border border-dark-650" />
103
81
  <!-- Task Switches -->
104
- <div class="task-switches mb-4 grid grid-cols-4 justify-between gap-y-4">
105
- <div class="switch-wrapper flex flex-col">
106
- <h4>
107
- <span class="hidden xs:block">Do Not Pay</span>
108
- <span class="block xs:hidden">DNP</span>
109
- <SavingsIcon class="scale-90" />
110
- </h4>
111
- <Switch class="mx-auto" v-model="task.doNotPay" />
112
- </div>
113
- <div class="switch-wrapper flex flex-col">
114
- <h4>
115
- <span class="hidden xs:block">Smart Timer</span>
116
- <span class="block xs:hidden">Timer</span>
117
- <TimerIcon class="scale-90" />
118
- </h4>
119
- <Switch class="mx-auto" v-model="task.smartTimer" />
120
- </div>
121
- <div class="switch-wrapper flex flex-col">
122
- <h4>
123
- <span class="hidden xs:block">Quick Queue</span>
124
- <span class="block xs:hidden">Quick Q.</span>
125
- <SkiIcon class="scale-90" />
126
- </h4>
127
- <Switch class="mx-auto" v-model="task.quickQueue" />
128
- </div>
129
- <div class="switch-wrapper flex flex-col">
130
- <h4>
131
- Manual
132
- <HandIcon />
133
- </h4>
134
- <Switch class="mx-auto" v-model="task.manual" />
135
- </div>
82
+ <div class="mb-4 grid grid-cols-4 justify-between gap-y-4">
83
+ <TaskToggle :icon="SavingsIcon" label="Do Not Pay" responsive-label="DNP" v-model="task.doNotPay" />
84
+ <TaskToggle :icon="TimerIcon" label="Smart Timer" responsive-label="Timer" v-model="task.smartTimer" />
85
+ <TaskToggle :icon="SkiIcon" label="Quick Queue" responsive-label="Quick Q." v-model="task.quickQueue" />
86
+ <TaskToggle :icon="HandIcon" label="Manual" v-model="task.manual" icon-class="" />
136
87
  </div>
137
88
 
138
89
  <!-- Task prefab -->
139
90
  <div class="my-3 border border-dark-650" />
140
- <button
141
- class="button-default ml-auto mt-4 bg-dark-400"
142
- @click="createTask">
91
+ <button class="btn-modal ml-auto mt-4 w-36" @click="createTask">
143
92
  Create
144
- <EditIcon />
93
+ <EditIcon class="ml-2" />
145
94
  </button>
146
95
  </Modal>
147
96
  </template>
@@ -151,7 +100,7 @@ import { ref, watch } from "vue";
151
100
  import { countries } from "@/stores/countries";
152
101
  import Modal from "@/components/ui/Modal.vue";
153
102
  import FormField from "@/components/ui/FormField.vue";
154
- import Switch from "@/components/ui/controls/atomic/Switch.vue";
103
+ import TaskToggle from "@/components/ui/TaskToggle.vue";
155
104
  import {
156
105
  MailIcon,
157
106
  CameraIcon,
@@ -162,20 +111,17 @@ import {
162
111
  TagIcon,
163
112
  SkiIcon,
164
113
  HandIcon,
165
- GroupIcon,
166
114
  ShieldIcon,
167
115
  TimerIcon,
168
116
  SavingsIcon,
169
- EditIcon,
170
- UpIcon,
171
- DownIcon,
172
- SandclockIcon,
173
- CartIcon
117
+ EditIcon
174
118
  } from "@/components/icons";
175
119
  import { useUIStore } from "@/stores/ui";
176
120
  import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
177
121
  import MultiDropdown from "@/components/ui/controls/atomic/MultiDropdown.vue";
178
- import { firstUpper, parseAxsEventUrl, removeDuplicates } from "@/stores/utils";
122
+ import { firstUpper } from "@/libs/utils/string";
123
+ import { parseAxsEventUrl } from "@/libs/utils/eventUrl";
124
+ import { removeDuplicates } from "@/libs/utils/array";
179
125
 
180
126
  const ui = useUIStore();
181
127
 
@@ -250,7 +196,6 @@ watch(
250
196
  if (country) ui.setCurrentCountry(country, false, ui.currentModule);
251
197
 
252
198
  task.value.eventId = parsed.eventId;
253
- debugger;
254
199
  if (parsed.promoId) task.value.promoId = parsed.promoId;
255
200
  } catch (ex) {
256
201
  ui.logger.Error("Could not parse url (2)", ex);
@@ -258,47 +203,4 @@ watch(
258
203
  }
259
204
  );
260
205
 
261
- // fetchConfigs();
262
206
  </script>
263
-
264
- <style lang="scss" scoped>
265
- .label-override {
266
- @apply flex items-center;
267
- color: #e1e1e4 !important;
268
-
269
- svg {
270
- @apply ml-2;
271
-
272
- path {
273
- fill: #e1e1e4 !important;
274
- }
275
- }
276
- }
277
-
278
- .task-switches {
279
- h4 {
280
- color: #e1e1e4;
281
- @apply mx-auto flex items-center gap-x-2 text-center text-xs;
282
- }
283
-
284
- .switch-wrapper {
285
- @apply gap-y-2;
286
- }
287
- }
288
-
289
- @media (max-width: 720px) {
290
- .task-switches {
291
- h4 {
292
- font-size: 12px !important;
293
- }
294
- }
295
- }
296
-
297
- .switch-wrapper {
298
- svg {
299
- path {
300
- fill: oklch(0.65 0 0) !important;
301
- }
302
- }
303
- }
304
- </style>
@@ -8,7 +8,7 @@
8
8
  </template>
9
9
 
10
10
  <!-- Task Form -->
11
- <div class="grid-responsive-1-2 gap-responsive mb-4 mt-4">
11
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4 mt-4">
12
12
  <!-- Event ID -->
13
13
  <FormField label="Event ID" :icon="StadiumIcon" required>
14
14
  <input
@@ -43,30 +43,12 @@
43
43
  </FormField>
44
44
 
45
45
  <!-- Task Amount -->
46
- <div class="input-wrapper">
47
- <label class="label-override mb-2">
48
- Amount
49
- <span class="ml-2 h-[18px]">#</span>
50
- </label>
51
- <div class="input-default">
52
- <input placeholder="20" min="1" type="number" pattern="\d*" v-model="task.taskQuantity" />
53
- <div class="input-incrementer">
54
- <button @click="task.taskQuantity++">
55
- <UpIcon />
56
- </button>
57
- <button @click="if (task.taskQuantity > 1) task.taskQuantity--;">
58
- <DownIcon />
59
- </button>
60
- </div>
61
- </div>
62
- </div>
46
+ <FormField label="Amount" :icon="HashIcon" incrementer @increment="task.taskQuantity++" @decrement="task.taskQuantity > 1 && task.taskQuantity--">
47
+ <input placeholder="20" min="1" type="number" pattern="\d*" v-model="task.taskQuantity" />
48
+ </FormField>
63
49
 
64
50
  <!-- Profile Tag(s) -->
65
- <div class="input-wrapper">
66
- <label class="label-override mb-2">
67
- Profile Tag(s)
68
- <TagIcon />
69
- </label>
51
+ <FormField label="Profile Tag(s)" :icon="TagIcon" noWrapper>
70
52
  <MultiDropdown
71
53
  class="w-full will-change-auto"
72
54
  :onSelect="(v) => (task.profileTags = v)"
@@ -76,7 +58,7 @@
76
58
  return { label: opt, value: opt };
77
59
  })
78
60
  " />
79
- </div>
61
+ </FormField>
80
62
 
81
63
  <!-- CL Origin -->
82
64
  <FormField v-if="isEU(ui.currentCountry.siteId)" label="CL Origin" :icon="AwardIcon">
@@ -84,11 +66,7 @@
84
66
  </FormField>
85
67
 
86
68
  <!-- Account Tag -->
87
- <div class="input-wrapper">
88
- <label class="label-override mb-2">
89
- Account Tag
90
- <ScannerIcon />
91
- </label>
69
+ <FormField label="Account Tag" :icon="ScannerIcon" noWrapper>
92
70
  <Dropdown
93
71
  :onClick="(f) => (task.accountTag = f)"
94
72
  default="Default tag"
@@ -97,7 +75,7 @@
97
75
  :allowDefault="false"
98
76
  :capitalize="true"
99
77
  class="dropdown w-full" />
100
- </div>
78
+ </FormField>
101
79
 
102
80
  <!-- Start Offset -->
103
81
  <FormField label="Start Offset (Minutes)" :icon="ShieldIcon" incrementer @increment="task.startOffset = (task.startOffset || 0) + 1" @decrement="task.startOffset > 0 && task.startOffset--">
@@ -111,150 +89,37 @@
111
89
  </div>
112
90
  <div class="mb-3 border border-dark-650" />
113
91
  <!-- Task Switches -->
114
- <div v-if="!isEU(ui.currentCountry.siteId)" class="task-switches grid grid-cols-3 justify-between gap-y-1">
115
- <div class="switch-wrapper mb-2 flex flex-col">
116
- <h4 class="text-responsive-sm">
117
- Aged
118
- <span class="hidden xs:block">Account</span>
119
- <SandclockIcon />
120
- </h4>
121
- <Switch class="mx-auto" v-model="task.agedAccount" />
122
- </div>
123
- <div class="switch-wrapper flex flex-col">
124
- <h4>
125
- Manual
126
- <HandIcon />
127
- </h4>
128
- <Switch class="mx-auto" v-model="task.manual" />
129
- </div>
130
- <div class="switch-wrapper flex flex-col">
131
- <h4>
132
- <span class="hidden xs:block">Do Not Pay</span>
133
- <span class="block xs:hidden">DNP</span>
134
- <SavingsIcon />
135
- </h4>
136
- <Switch class="mx-auto" v-model="task.doNotPay" />
137
- </div>
138
- <div class="switch-wrapper flex flex-col">
139
- <h4>
140
- <span class="hidden xs:block">Quick Queue</span>
141
- <span class="block xs:hidden">Quick Q.</span>
142
- <SkiIcon />
143
- </h4>
144
- <Switch class="mx-auto" v-model="task.quickQueue" />
145
- </div>
146
- <div class="switch-wrapper flex flex-col">
147
- <h4>
148
- <span class="hidden xs:block">Login Later</span>
149
- <span class="block xs:hidden">Login Lat.</span>
150
-
151
- <GroupIcon />
152
- </h4>
153
- <Switch class="mx-auto" v-model="task.loginAfterCart" />
154
- </div>
155
- <div class="switch-wrapper flex flex-col">
156
- <h4>
157
- <span class="hidden xs:block">Smart Timer</span>
158
- <span class="block xs:hidden">Timer</span>
159
- <TimerIcon />
160
- </h4>
161
- <Switch class="mx-auto" v-model="task.smartTimer" />
162
- </div>
163
- <div class="switch-wrapper flex flex-col">
164
- <h4>
165
- <span class="hidden xs:block">Supports</span>
166
- OTP
167
- <MailIcon class="h-[17px] scale-90" />
168
- </h4>
169
- <Switch class="mx-auto" v-model="task.otpAccount" />
170
- </div>
171
- <div class="switch-wrapper flex flex-col">
172
- <h4>
173
- Presale
174
- <span class="hidden xs:block">Queue</span>
175
- <AwardIcon class="scale-90" />
176
- </h4>
177
- <Switch class="mx-auto" v-model="task.presaleMode" />
178
- </div>
179
- <div class="switch-wrapper flex flex-col">
180
- <h4>
181
- Strict
182
- <span class="hidden xs:block">Presale</span>
183
- <AwardIcon class="scale-90" />
184
- </h4>
185
- <Switch class="mx-auto" v-model="task.presaleStrict" />
186
- </div>
92
+ <div v-if="!isEU(ui.currentCountry.siteId)" class="grid grid-cols-3 justify-between gap-y-1">
93
+ <TaskToggle class="mb-2" :icon="SandclockIcon" label="Aged Account" responsive-label="Aged" v-model="task.agedAccount" icon-class="" />
94
+ <TaskToggle :icon="HandIcon" label="Manual" v-model="task.manual" icon-class="" />
95
+ <TaskToggle :icon="SavingsIcon" label="Do Not Pay" responsive-label="DNP" v-model="task.doNotPay" icon-class="" />
96
+ <TaskToggle :icon="SkiIcon" label="Quick Queue" responsive-label="Quick Q." v-model="task.quickQueue" icon-class="" />
97
+ <TaskToggle :icon="GroupIcon" label="Login Later" responsive-label="Login Lat." v-model="task.loginAfterCart" icon-class="" />
98
+ <TaskToggle :icon="TimerIcon" label="Smart Timer" responsive-label="Timer" v-model="task.smartTimer" icon-class="" />
99
+ <TaskToggle :icon="MailIcon" label="Supports OTP" responsive-label="OTP" v-model="task.otpAccount" icon-class="h-4.25 scale-90" />
100
+ <TaskToggle :icon="AwardIcon" label="Presale Queue" responsive-label="Presale" v-model="task.presaleMode" />
101
+ <TaskToggle :icon="AwardIcon" label="Strict Presale" responsive-label="Strict" v-model="task.presaleStrict" />
187
102
  </div>
188
103
  <div v-if="isEU(ui.currentCountry.siteId)">
189
- <div class="task-switches mb-4 grid grid-cols-4 justify-between gap-y-4">
190
- <div class="switch-wrapper flex flex-col">
191
- <h4 class="text-xs">
192
- Manual
193
- <HandIcon class="scale-90" />
194
- </h4>
195
- <Switch class="mx-auto" v-model="task.manual" />
196
- </div>
197
- <div class="switch-wrapper flex flex-col">
198
- <h4>
199
- <span class="hidden xs:block">Do Not Pay</span>
200
- <span class="block xs:hidden">DNP</span>
201
- <SavingsIcon class="scale-90" />
202
- </h4>
203
- <Switch class="mx-auto" v-model="task.doNotPay" />
204
- </div>
205
- <div class="switch-wrapper flex flex-col">
206
- <h4>
207
- <span class="hidden xs:block">Smart Timer</span>
208
- <span class="block xs:hidden">Timer</span>
209
- <TimerIcon class="scale-90" />
210
- </h4>
211
- <Switch class="mx-auto" v-model="task.smartTimer" />
212
- </div>
213
- <div class="switch-wrapper flex flex-col">
214
- <h4>
215
- <span class="hidden xs:block">Login Later</span>
216
- <span class="block xs:hidden">Login Lat.</span>
217
- <GroupIcon class="scale-90" />
218
- </h4>
219
- <Switch class="mx-auto" v-model="task.loginAfterCart" />
220
- </div>
104
+ <div class="mb-4 grid grid-cols-4 justify-between gap-y-4">
105
+ <TaskToggle :icon="HandIcon" label="Manual" v-model="task.manual" />
106
+ <TaskToggle :icon="SavingsIcon" label="Do Not Pay" responsive-label="DNP" v-model="task.doNotPay" />
107
+ <TaskToggle :icon="TimerIcon" label="Smart Timer" responsive-label="Timer" v-model="task.smartTimer" />
108
+ <TaskToggle :icon="GroupIcon" label="Login Later" responsive-label="Login Lat." v-model="task.loginAfterCart" />
221
109
  </div>
222
110
 
223
- <div class="task-switches grid grid-cols-4 justify-between gap-y-4">
224
- <div class="switch-wrapper flex flex-col">
225
- <h4>
226
- <span class="hidden xs:block">Quick Queue</span>
227
- <span class="block xs:hidden">Quick Q.</span>
228
- <SkiIcon class="scale-90" />
229
- </h4>
230
- <Switch class="mx-auto" v-model="task.quickQueue" />
231
- </div>
232
-
233
- <div class="switch-wrapper flex flex-col">
234
- <h4>
235
- Supports OTP
236
- <MailIcon class="h-[17px] scale-90" />
237
- </h4>
238
- <Switch class="mx-auto" v-model="task.otpAccount" />
239
- </div>
240
- <div class="switch-wrapper flex flex-col">
241
- <h4>
242
- Aged
243
- <span class="hidden xs:block">Account</span>
244
- <SandclockIcon />
245
- </h4>
246
- <Switch class="mx-auto" v-model="task.agedAccount" />
247
- </div>
111
+ <div class="grid grid-cols-4 justify-between gap-y-4">
112
+ <TaskToggle :icon="SkiIcon" label="Quick Queue" responsive-label="Quick Q." v-model="task.quickQueue" />
113
+ <TaskToggle :icon="MailIcon" label="Supports OTP" v-model="task.otpAccount" icon-class="h-4.25 scale-90" />
114
+ <TaskToggle :icon="SandclockIcon" label="Aged Account" responsive-label="Aged" v-model="task.agedAccount" icon-class="" />
248
115
  </div>
249
116
  </div>
250
117
 
251
118
  <!-- Task prefab -->
252
119
  <div class="my-3 border border-dark-650" />
253
- <button
254
- class="button-default ml-auto mt-4 bg-dark-400"
255
- @click="createTask">
120
+ <button class="btn-modal ml-auto mt-4 w-36" @click="createTask">
256
121
  Create
257
- <EditIcon />
122
+ <EditIcon class="ml-2" />
258
123
  </button>
259
124
  </Modal>
260
125
  </template>
@@ -263,7 +128,7 @@
263
128
  import { ref, watch } from "vue";
264
129
  import Modal from "@/components/ui/Modal.vue";
265
130
  import FormField from "@/components/ui/FormField.vue";
266
- import Switch from "@/components/ui/controls/atomic/Switch.vue";
131
+ import TaskToggle from "@/components/ui/TaskToggle.vue";
267
132
  import {
268
133
  MailIcon,
269
134
  CameraIcon,
@@ -279,17 +144,16 @@ import {
279
144
  TimerIcon,
280
145
  SavingsIcon,
281
146
  EditIcon,
282
- UpIcon,
283
- DownIcon,
284
147
  SandclockIcon,
285
- CartIcon,
286
148
  PencilIcon
287
149
  } from "@/components/icons";
288
150
  import { useUIStore } from "@/stores/ui";
289
151
  import { countries } from "@/stores/countries";
290
152
  import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
291
153
  import MultiDropdown from "@/components/ui/controls/atomic/MultiDropdown.vue";
292
- import { isEU, firstUpper, parseTmEventUrl, removeDuplicates } from "@/stores/utils";
154
+ import { firstUpper } from "@/libs/utils/string";
155
+ import { isEU, parseTmEventUrl } from "@/libs/utils/eventUrl";
156
+ import { removeDuplicates } from "@/libs/utils/array";
293
157
 
294
158
  const ui = useUIStore();
295
159
 
@@ -388,23 +252,3 @@ watch(
388
252
  );
389
253
  </script>
390
254
 
391
- <style lang="scss" scoped>
392
- .label-override {
393
- @apply flex items-center;
394
- color: #e1e1e4 !important;
395
-
396
- svg {
397
- @apply ml-2;
398
-
399
- path {
400
- fill: #e1e1e4 !important;
401
- }
402
- }
403
- }
404
-
405
- .switch-wrapper {
406
- svg path {
407
- fill: oklch(0.65 0 0) !important;
408
- }
409
- }
410
- </style>