@necrolab/dashboard 0.4.61 → 0.4.208

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 (133) hide show
  1. package/.prettierrc +1 -27
  2. package/.vscode/extensions.json +1 -1
  3. package/README.md +79 -43
  4. package/backend/api.js +48 -40
  5. package/backend/auth.js +3 -3
  6. package/backend/batching.js +1 -1
  7. package/backend/endpoints.js +77 -13
  8. package/backend/index.js +2 -2
  9. package/backend/mock-data.js +38 -29
  10. package/backend/mock-src/classes/logger.js +8 -8
  11. package/backend/mock-src/classes/utils.js +3 -7
  12. package/backend/mock-src/database.js +0 -0
  13. package/backend/mock-src/ticketmaster.js +79 -79
  14. package/backend/validator.js +2 -2
  15. package/config/configs.json +3 -2
  16. package/config/filter.json +3 -2
  17. package/index.html +10 -81
  18. package/index.js +1 -1
  19. package/package.json +25 -40
  20. package/postcss.config.js +1 -1
  21. package/postinstall.js +17 -98
  22. package/public/android-chrome-192x192.png +0 -0
  23. package/public/android-chrome-512x512.png +0 -0
  24. package/public/apple-touch-icon.png +0 -0
  25. package/public/favicon-16x16.png +0 -0
  26. package/public/favicon-32x32.png +0 -0
  27. package/public/favicon.ico +0 -0
  28. package/public/manifest.json +7 -12
  29. package/public/sw.js +2 -0
  30. package/public/workbox-49fdaf31.js +2 -0
  31. package/public/workbox-49fdaf31.js.map +1 -0
  32. package/public/workbox-88575b92.js +2 -0
  33. package/public/workbox-88575b92.js.map +1 -0
  34. package/public/workbox-a67a7b11.js +2 -0
  35. package/public/workbox-a67a7b11.js.map +1 -0
  36. package/public/workbox-d4314735.js +2 -0
  37. package/public/workbox-d4314735.js.map +1 -0
  38. package/public/workbox-e0f89ef3.js +2 -0
  39. package/public/workbox-e0f89ef3.js.map +1 -0
  40. package/run +9 -176
  41. package/src/App.vue +85 -498
  42. package/src/assets/css/_input.scss +99 -144
  43. package/src/assets/css/main.scss +99 -450
  44. package/src/assets/img/background.svg +2 -2
  45. package/src/assets/img/logo_icon.png +0 -0
  46. package/src/components/Auth/LoginForm.vue +11 -62
  47. package/src/components/Editors/Account/Account.vue +40 -116
  48. package/src/components/Editors/Account/AccountCreator.vue +39 -88
  49. package/src/components/Editors/Account/AccountView.vue +34 -102
  50. package/src/components/Editors/Account/CreateAccount.vue +32 -80
  51. package/src/components/Editors/Profile/CreateProfile.vue +83 -269
  52. package/src/components/Editors/Profile/Profile.vue +47 -132
  53. package/src/components/Editors/Profile/ProfileCountryChooser.vue +20 -82
  54. package/src/components/Editors/Profile/ProfileView.vue +34 -91
  55. package/src/components/Editors/TagLabel.vue +6 -67
  56. package/src/components/Filter/Filter.vue +72 -289
  57. package/src/components/Filter/FilterPreview.vue +30 -171
  58. package/src/components/Filter/PriceSortToggle.vue +4 -74
  59. package/src/components/Table/Header.vue +1 -1
  60. package/src/components/Table/Row.vue +1 -1
  61. package/src/components/Table/Table.vue +2 -19
  62. package/src/components/Tasks/CheckStock.vue +13 -28
  63. package/src/components/Tasks/Controls/DesktopControls.vue +17 -17
  64. package/src/components/Tasks/Controls/MobileControls.vue +45 -8
  65. package/src/components/Tasks/CreateTaskAXS.vue +73 -79
  66. package/src/components/Tasks/CreateTaskTM.vue +142 -94
  67. package/src/components/Tasks/MassEdit.vue +7 -9
  68. package/src/components/Tasks/QuickSettings.vue +55 -169
  69. package/src/components/Tasks/ScrapeVenue.vue +4 -7
  70. package/src/components/Tasks/Stats.vue +23 -52
  71. package/src/components/Tasks/Task.vue +136 -378
  72. package/src/components/Tasks/TaskView.vue +47 -107
  73. package/src/components/Tasks/Utilities.vue +6 -5
  74. package/src/components/icons/Bag.vue +1 -1
  75. package/src/components/icons/Loyalty.vue +1 -1
  76. package/src/components/icons/Mail.vue +2 -2
  77. package/src/components/icons/Play.vue +2 -2
  78. package/src/components/icons/Reload.vue +5 -4
  79. package/src/components/icons/Sandclock.vue +2 -2
  80. package/src/components/icons/Stadium.vue +1 -1
  81. package/src/components/icons/index.js +1 -24
  82. package/src/components/ui/Modal.vue +13 -105
  83. package/src/components/ui/Navbar.vue +38 -171
  84. package/src/components/ui/ReconnectIndicator.vue +55 -351
  85. package/src/components/ui/Splash.vue +35 -5
  86. package/src/components/ui/controls/CountryChooser.vue +62 -200
  87. package/src/components/ui/controls/atomic/Checkbox.vue +10 -119
  88. package/src/components/ui/controls/atomic/Dropdown.vue +39 -208
  89. package/src/components/ui/controls/atomic/MultiDropdown.vue +37 -300
  90. package/src/libs/Filter.js +170 -200
  91. package/src/registerServiceWorker.js +1 -1
  92. package/src/stores/connection.js +53 -51
  93. package/src/stores/logger.js +3 -11
  94. package/src/stores/sampleData.js +235 -207
  95. package/src/stores/ui.js +44 -112
  96. package/src/stores/utils.js +6 -90
  97. package/src/views/Accounts.vue +35 -44
  98. package/src/views/Console.vue +90 -341
  99. package/src/views/Editor.vue +123 -1176
  100. package/src/views/FilterBuilder.vue +251 -607
  101. package/src/views/Login.vue +14 -76
  102. package/src/views/Profiles.vue +25 -44
  103. package/src/views/Tasks.vue +100 -187
  104. package/static/offline.html +50 -192
  105. package/tailwind.config.js +26 -104
  106. package/vite.config.js +16 -73
  107. package/vue.config.js +32 -0
  108. package/workbox-config.js +11 -0
  109. package/artwork/image.png +0 -0
  110. package/dev-server.js +0 -136
  111. package/exit +0 -209
  112. package/jsconfig.json +0 -16
  113. package/src/assets/css/_utilities.scss +0 -388
  114. package/src/assets/img/background.svg.backup +0 -11
  115. package/src/components/icons/Check.vue +0 -5
  116. package/src/components/icons/Close.vue +0 -21
  117. package/src/components/icons/CloseX.vue +0 -5
  118. package/src/components/icons/Key.vue +0 -21
  119. package/src/components/icons/Pencil.vue +0 -21
  120. package/src/components/icons/Profile.vue +0 -18
  121. package/src/components/icons/Sell.vue +0 -21
  122. package/src/components/icons/Spinner.vue +0 -42
  123. package/src/components/icons/SquareCheck.vue +0 -18
  124. package/src/components/icons/SquareUncheck.vue +0 -18
  125. package/src/components/icons/Wildcard.vue +0 -18
  126. package/src/components/ui/controls/atomic/LoadingButton.vue +0 -45
  127. package/src/composables/useClickOutside.js +0 -21
  128. package/src/composables/useDropdownPosition.js +0 -174
  129. package/src/types/index.js +0 -41
  130. package/src/utils/debug.js +0 -1
  131. package/switch-branch.sh +0 -41
  132. package/workbox-config.cjs +0 -63
  133. /package/src/assets/img/{logo_icon-old.png → logo_icon_2.png} +0 -0
package/src/stores/ui.js CHANGED
@@ -3,11 +3,11 @@ import { defineStore } from "pinia";
3
3
  import { ConnectionHandler } from "@/stores/connection.js";
4
4
  import { toast } from "vue3-toastify";
5
5
  import { createLogger } from "@/stores/logger";
6
- import { timeDifference, betterSort, sortTaskIds } from "@/stores/utils";
6
+ import { timeDifference, sortAlphaNum } from "@/stores/utils";
7
7
 
8
8
  import mockTaskData from "@/stores/sampleData.js";
9
9
  import { useRouter } from "vue-router";
10
- import { DEBUG } from "@/utils/debug";
10
+ const DEBUG = window.location.href.startsWith("http://localhost:5173");
11
11
 
12
12
  const ALL_SELECTED = 0;
13
13
  const SOME_SELECTED = 1;
@@ -26,13 +26,11 @@ export const useUIStore = defineStore("ui", () => {
26
26
  const tasks = ref({});
27
27
 
28
28
  const showSpinner = ref(false);
29
- const botVersion = ref("0.0.0");
30
-
31
29
  const spinnerMessage = ref("");
32
30
 
33
31
  const profile = ref({
34
32
  profileTags: [],
35
- tags: [],
33
+ accountTags: [],
36
34
  admin: false,
37
35
  name: ""
38
36
  });
@@ -103,48 +101,16 @@ export const useUIStore = defineStore("ui", () => {
103
101
  const t1 = new Date();
104
102
  for (const [key, value] of Object.entries(tasks.value)) {
105
103
  if (value.expirationTime)
106
- tasks.value[key]._timeLeftString =
107
- value.expirationTime == "Invalid Date"
108
- ? "No Cartholds"
109
- : timeDifference(Date.parse(value.expirationTime), t1.getTime());
104
+ tasks.value[key]._timeLeftString = timeDifference(Date.parse(value.expirationTime), t1.getTime());
105
+ else if (value.noCartholds) tasks.value[key]._timeLeftString = "No Cartholds";
110
106
  else tasks.value[key]._timeLeftString = undefined;
111
107
  }
112
-
113
- if (t1.getSeconds() % 10 === 0) {
114
- const allIds = new Set(Object.keys(tasks.value));
115
- const orderIds = new Set(taskIdOrder.value);
116
-
117
- const missingIds = [...allIds].filter((id) => !orderIds.has(id));
118
- const extraIds = [...orderIds].filter((id) => !allIds.has(id));
119
-
120
- if (missingIds.length > 0 || extraIds.length > 0) {
121
- taskIdOrder.value = taskIdOrder.value.filter((id) => allIds.has(id));
122
-
123
- if (missingIds.length > 0) {
124
- missingIds.sort(sortTaskIds);
125
- for (const id of missingIds) {
126
- let pos = taskIdOrder.value.length;
127
- for (let i = 0; i < taskIdOrder.value.length; i++) {
128
- if (sortTaskIds(id, taskIdOrder.value[i]) < 0) {
129
- pos = i;
130
- break;
131
- }
132
- }
133
- taskIdOrder.value.splice(pos, 0, id);
134
- }
135
- }
136
- }
137
- }
138
108
  }, 1000);
139
109
 
140
110
  connection.init("/api/updates?type=tasks");
141
111
 
142
112
  const pd = (e) => {
143
- if (
144
- !e.target.closest(".scrollable") &&
145
- !e.target.closest(".dropdown-menu") &&
146
- !e.target.closest(".option-list")
147
- ) {
113
+ if (!e.target.closest(".scrollable")) {
148
114
  e.preventDefault();
149
115
  }
150
116
  };
@@ -234,21 +200,22 @@ export const useUIStore = defineStore("ui", () => {
234
200
 
235
201
  let relevantTasks = Object.values(tasks.value).filter((t) => t.siteId === currentCountry.value.siteId);
236
202
  if (currentEvent.value) relevantTasks = relevantTasks.filter((t) => t.eventId === currentEvent.value);
203
+ // logger.Info("mqm tasks:", relevantTasks);
204
+ const tasksInQueue = relevantTasks.filter((t) => t.status.includes(" - ETA:"));
237
205
 
238
- queueStats.value.queued = relevantTasks.filter((t) => t.inQueue).length || 0;
206
+ queueStats.value.total = 0;
207
+ queueStats.value.queued =
208
+ tasksInQueue.length + relevantTasks.filter((t) => t.status?.toLowerCase()?.includes("queueit")).length || 0;
209
+ queueStats.value.show = queueStats.value.total > 0;
239
210
  const sleepingStatuses = ["sleeping in queue", "waiting for drop", "waiting for carting", "waiting for queue"];
240
211
  queueStats.value.sleeping = relevantTasks.filter((t) =>
241
212
  sleepingStatuses.includes(t.status.toLowerCase())
242
213
  ).length;
243
- const positions = relevantTasks
244
- .map((t) => t.queuePosition)
245
- .filter((e) => !isNaN(e))
246
- .filter(Boolean);
214
+ const positions = tasksInQueue
215
+ .map((t) => parseInt(t.status.split(" users ahead - ETA:")[0]))
216
+ .filter((e) => !isNaN(e));
247
217
  queueStats.value.nextQueuePasses = positions.sort((a, b) => a - b);
248
-
249
- // Only show stats if there are any queued tasks, sleeping tasks, or queue positions
250
- queueStats.value.show =
251
- queueStats.value.queued > 0 || queueStats.value.sleeping > 0 || queueStats.value.nextQueuePasses.length > 0;
218
+ // logger.Info("Refreshing queue stats", queueStats.value);
252
219
  };
253
220
 
254
221
  const toggleModal = (name, clearValue = false) => {
@@ -268,28 +235,13 @@ export const useUIStore = defineStore("ui", () => {
268
235
 
269
236
  const sortTasks = () => {
270
237
  try {
271
- if (!sortData.value.sortBy) {
272
- // When no specific sort column is set, default to sorting by taskId
273
- const taskArr = Object.entries(tasks.value).map(([taskId, task]) => ({ taskId, ...task }));
274
- taskArr.sort((a, b) => sortTaskIds(a.taskId, b.taskId));
275
- taskIdOrder.value = taskArr.map((task) => task.taskId);
276
-
277
- if (sortData.value.reversed) {
278
- taskIdOrder.value.reverse();
279
- }
280
- return;
281
- }
282
-
238
+ if (!sortData.value.sortBy) return;
283
239
  logger.Info("Sorting", sortData.value.sortBy);
284
240
  const taskArr = Object.entries(tasks.value).map(([taskId, task]) => ({ taskId, ...task }));
285
-
286
- if (sortData.value.sortBy === "taskId") {
287
- taskArr.sort((a, b) => sortTaskIds(a.taskId, b.taskId));
288
- } else {
289
- taskArr.sort((a, b) => betterSort(a[sortData.value.sortBy], b[sortData.value.sortBy]));
290
- }
291
-
292
- taskIdOrder.value = taskArr.map((task) => task.taskId);
241
+ const sortedTaskArr = taskArr.sort((a, b) =>
242
+ sortAlphaNum(a[sortData.value.sortBy], b[sortData.value.sortBy])
243
+ );
244
+ taskIdOrder.value = sortedTaskArr.map((task) => task.taskId);
293
245
  if (sortData.value.reversed) {
294
246
  taskIdOrder.value.reverse();
295
247
  }
@@ -468,9 +420,10 @@ export const useUIStore = defineStore("ui", () => {
468
420
  deleteTasks: () => {
469
421
  if (!confirm("Do you want do delete all selected tasks?")) return;
470
422
  const selectedTasks = getSelectedTasks();
471
- for (const value of Object.values(selectedTasks)) connection.sendDeleteTask(value.taskId);
423
+ if (selectedTasks.length === Object.keys(tasks.value).length) connection.sendDeleteAllTasks();
424
+ else for (const value of Object.values(selectedTasks)) connection.sendDeleteTask(value.taskId);
472
425
  },
473
- foldTasks: () => {
426
+ decreaseTasks: () => {
474
427
  const selectedTasks = getSelectedTasks();
475
428
  for (const key of Object.keys(selectedTasks)) tasks.value[key].isExpanded = false;
476
429
  },
@@ -480,11 +433,17 @@ export const useUIStore = defineStore("ui", () => {
480
433
  },
481
434
  startTasks: () => {
482
435
  const selectedTasks = getSelectedTasks();
483
- for (const value of Object.values(selectedTasks)) if (!value.active) connection.sendStartTask(value.taskId);
436
+ if (selectedTasks.length === Object.keys(tasks.value).length) connection.sendStartAllTasks();
437
+ else
438
+ for (const value of Object.values(selectedTasks))
439
+ if (!value.active) connection.sendStartTask(value.taskId);
484
440
  },
485
441
  stopTasks: () => {
486
442
  const selectedTasks = getSelectedTasks();
487
- for (const value of Object.values(selectedTasks)) if (value.active) connection.sendStopTask(value.taskId);
443
+ if (selectedTasks.length === Object.keys(tasks.value).length) connection.sendStopAllTasks();
444
+ else
445
+ for (const value of Object.values(selectedTasks))
446
+ if (value.active) connection.sendStopTask(value.taskId);
488
447
  },
489
448
  toggleTaskSelected: (taskId) => {
490
449
  tasks.value[taskId].selected = !tasks.value[taskId].selected;
@@ -492,45 +451,22 @@ export const useUIStore = defineStore("ui", () => {
492
451
  },
493
452
 
494
453
  toggleProfileSelected: (id) => {
495
- const idx = profiles.value.findIndex((p) => p.id === id);
454
+ const idx = profiles.value.findIndex((p) => p._id === id);
496
455
  profiles.value[idx].selected = !profiles.value[idx].selected;
497
456
  },
498
457
  toggleAccountSelected: (id) => {
499
- const idx = accounts.value.findIndex((p) => p.id === id);
458
+ const idx = accounts.value.findIndex((p) => p._id === id);
500
459
  accounts.value[idx].selected = !accounts.value[idx].selected;
501
460
  },
502
461
 
503
462
  // proxy for connection functions
504
- checkStock: (eventId, presaleCode, eventDid, clOrigin) =>
505
- connection.sendCheckStock(eventId, presaleCode, eventDid, clOrigin),
463
+ checkStock: (eventId, presaleCode) => connection.sendCheckStock(eventId, presaleCode),
506
464
  scrapeVenue: (eventId) => connection.sendScrapeMap(eventId),
507
465
  massEditPresaleCode: (eventId, presaleCode) => connection.sendMassEditPresaleCode(eventId, presaleCode),
508
466
 
509
467
  // alerts
510
- showError: (err) =>
511
- toast.error(err, {
512
- autoClose: 1400,
513
- pauseOnHover: false,
514
- hideProgressBar: false,
515
- closeOnClick: true,
516
- pauseOnFocusLoss: false,
517
- transition: "slide",
518
- position: "top-right",
519
- closeButton: true,
520
- newestOnTop: true
521
- }),
522
- showSuccess: (msg) =>
523
- toast.success(msg, {
524
- autoClose: 1400,
525
- pauseOnHover: false,
526
- hideProgressBar: false,
527
- closeOnClick: true,
528
- pauseOnFocusLoss: false,
529
- transition: "slide",
530
- position: "top-right",
531
- closeButton: true,
532
- newestOnTop: true
533
- }),
468
+ showError: (err) => toast.error(err, { autoClose: 2000 }),
469
+ showSuccess: (msg) => toast.success(msg, { autoClose: 2000 }),
534
470
  // Country
535
471
  currentCountry,
536
472
  setCurrentCountry: (country, closeModal, newModule) => {
@@ -546,8 +482,8 @@ export const useUIStore = defineStore("ui", () => {
546
482
  // Event
547
483
  currentEvent,
548
484
  setCurrentEvent: (event) => {
549
- if (event) logger.Info("Setting current event to:", event);
550
- currentEvent.value = event?.match(/\s\((.*?)\)$/)?.[1] || "";
485
+ logger.Info("Setting current event", event);
486
+ currentEvent.value = event;
551
487
  localStorage.setItem("current-event", currentEvent.value);
552
488
  refreshQueueStats();
553
489
  },
@@ -563,26 +499,26 @@ export const useUIStore = defineStore("ui", () => {
563
499
  accounts,
564
500
  addAccount: (acc) => {
565
501
  if (!DEBUG) return connection.sendSaveAccount(acc);
566
- const isEdit = accounts.value.findIndex((p) => p.id === acc.id);
502
+ const isEdit = accounts.value.findIndex((p) => p._id === acc._id);
567
503
  if (DEBUG && isEdit !== -1) {
568
504
  Object.keys(acc).forEach((k) => (accounts.value[isEdit][k] = acc[k]));
569
- } else accounts.value.push({ ...acc, id: Math.random() });
505
+ } else accounts.value.push({ ...acc, _id: Math.random() });
570
506
  },
571
507
  setAccounts: (accs) => accounts.value.push(...accs),
572
508
  profiles,
573
509
  addProfile: (profile) => {
574
510
  if (!DEBUG) return connection.sendSaveProfile(profile);
575
- const isEdit = profiles.value.findIndex((p) => p.id === profile.id);
511
+ const isEdit = profiles.value.findIndex((p) => p._id === profile._id);
576
512
 
577
513
  if (DEBUG && isEdit !== -1) {
578
514
  Object.keys(profile).forEach((k) => (accounts.value[isEdit][k] = profile[k]));
579
515
  } else {
580
- profiles.value.push({ ...profile, id: Math.random() });
516
+ profiles.value.push({ ...profile, _id: Math.random() });
581
517
  }
582
518
  },
583
519
  deleteProfile: (id) => {
584
520
  if (!DEBUG) return connection.sendDeleteProfile(id);
585
- else profiles.value = profiles.value.filter((p) => p.id != id);
521
+ else profiles.value = profiles.value.filter((p) => p._id != id);
586
522
  },
587
523
  setProfiles: (profs) => (profiles.value = profs),
588
524
  proxies,
@@ -601,10 +537,6 @@ export const useUIStore = defineStore("ui", () => {
601
537
  showSpinner.value = false;
602
538
  enableScroll();
603
539
  },
604
- setBotVersion: (version) => {
605
- botVersion.value = version;
606
- },
607
- botVersion,
608
540
 
609
541
  spinnerMessage,
610
542
  showSpinner,
@@ -361,29 +361,7 @@ const timeDifference = (date1, date2) => {
361
361
  return str;
362
362
  };
363
363
 
364
- const parseAxsEventUrl = (url) => {
365
- const HOST = "www.axs.com";
366
-
367
- if (!url.startsWith("https://")) return { eventId: url };
368
- if (!url.includes(`https://${HOST}`)) return {};
369
-
370
- const siteMatch = url.match(new RegExp(`https://${HOST}(/uk)?`));
371
- const eventMatch = url.match(/\/events\/(\d+)/);
372
- const promoMatch = url.match(/\/promopage\/(\d+)/);
373
-
374
- if (!siteMatch || !eventMatch) return {};
375
-
376
- const siteId = siteMatch[1] === "/uk" ? "AXS_UK" : "AXS_US";
377
- const eventId = eventMatch[1];
378
- const promoId = promoMatch?.[1];
379
-
380
- const result = { eventId, siteId };
381
- if (promoId) result.promoId = promoId;
382
-
383
- return result;
384
- };
385
-
386
- const parseTmEventUrl = (url) => {
364
+ const parseEventUrl = (url) => {
387
365
  if (!url.includes("https://")) {
388
366
  return { eventId: url };
389
367
  }
@@ -398,17 +376,16 @@ const parseTmEventUrl = (url) => {
398
376
  };
399
377
  };
400
378
 
401
- const isEU = (siteId) => !["US", "AU", "UK", "CA", "NZ", "IE"].includes(siteId.split("_")?.[1] || siteId);
379
+ const isEU = (siteId) => !["US", "AU", "UK", "LN", "CA", "NZ", "IE"].includes(siteId.replaceAll("TM_", ""));
402
380
 
403
381
  const removeDuplicates = (arr) => [...new Set(arr)];
404
382
 
405
383
  const pickRandom = (arr) => arr[Math.floor(Math.random() * arr.length)];
406
384
 
407
385
  const fakeId = () => {
408
- const cityInfo = pickRandom(cities.filter((x) => x[2] != "GA" && x[2] != "PR" && x[0] > 10000));
409
-
386
+ const cityInfo = pickRandom(cities);
410
387
  const profile = {
411
- zipCode: String(cityInfo[0]),
388
+ zipCode: cityInfo[0],
412
389
  address: generateStreetAddress()
413
390
  };
414
391
 
@@ -505,76 +482,15 @@ function validateCard(cardNumber) {
505
482
  };
506
483
  }
507
484
 
508
- function sortTaskIds(a, b) {
509
- const parseId = (id) => {
510
- if (!id) return { prefix: "", num: -1 };
511
-
512
- if (/^\d+$/.test(id)) {
513
- return { prefix: "", num: parseInt(id, 10) };
514
- }
515
-
516
- const match = id.match(/^([A-Za-z-]+)(\d+)$/);
517
- if (match) {
518
- return { prefix: match[1], num: parseInt(match[2], 10) };
519
- }
520
-
521
- return { prefix: id, num: -1 };
522
- };
523
-
524
- const aInfo = parseId(a);
525
- const bInfo = parseId(b);
526
-
527
- if (aInfo.prefix !== bInfo.prefix) {
528
- return aInfo.prefix.localeCompare(bInfo.prefix);
529
- }
530
-
531
- return aInfo.num - bInfo.num;
532
- }
533
-
534
- const firstUpper = (str) => `${str[0].toUpperCase()}${str.slice(1).toLowerCase()}`;
535
-
536
- function betterSort(a, b) {
537
- if (a === undefined || a === null) return b === undefined || b === null ? 0 : -1;
538
- if (b === undefined || b === null) return 1;
539
-
540
- const aStr = String(a);
541
- const bStr = String(b);
542
-
543
- if (!isNaN(aStr) && !isNaN(bStr)) {
544
- return Number(aStr) - Number(bStr);
545
- }
546
-
547
- const aParts = aStr.split(/(\d+)/).filter(Boolean);
548
- const bParts = bStr.split(/(\d+)/).filter(Boolean);
549
-
550
- const len = Math.min(aParts.length, bParts.length);
551
- for (let i = 0; i < len; i++) {
552
- if (!isNaN(aParts[i]) && !isNaN(bParts[i])) {
553
- const numA = parseInt(aParts[i], 10);
554
- const numB = parseInt(bParts[i], 10);
555
- if (numA !== numB) return numA - numB;
556
- } else {
557
- const cmp = aParts[i].localeCompare(bParts[i]);
558
- if (cmp !== 0) return cmp;
559
- }
560
- }
561
-
562
- return aParts.length - bParts.length;
563
- }
564
-
565
485
  export {
566
486
  generateStreetAddress,
567
487
  timeDifference,
568
488
  sortAlphaNum,
569
- parseAxsEventUrl,
570
- parseTmEventUrl,
489
+ parseEventUrl,
571
490
  isEU,
572
491
  removeDuplicates,
573
492
  pickRandom,
574
493
  fakeId,
575
494
  getCardType,
576
- validateCard,
577
- sortTaskIds,
578
- firstUpper,
579
- betterSort
495
+ validateCard
580
496
  };
@@ -1,14 +1,11 @@
1
1
  <template>
2
2
  <div>
3
- <div class="flex-between pt-5 pb-2">
3
+ <div class="flex items-center">
4
4
  <!-- Heading -->
5
- <div class="flex-center gap-4">
6
- <MailIcon class="cursor-pointer smooth-hover text-white" />
7
- <h4 class="text-heading">
8
- Accounts
9
- <span class="text-subheading pl-1">{{ ui.getSelectedAccounts().length }}</span>
10
- </h4>
11
- </div>
5
+ <h4 class="text-white text-base font-bold mb-5 pt-5">
6
+ Accounts
7
+ <span class="text-light-300 pl-1">{{ ui.getSelectedAccounts().length }}</span>
8
+ </h4>
12
9
  <ul class="mobile-icons">
13
10
  <li>
14
11
  <EyeToggle v-model="privacy" />
@@ -17,16 +14,16 @@
17
14
  <button
18
15
  :disabled="ui.disabledButtons['create-accounts']"
19
16
  @click="ui.toggleModal('account-creator', true)"
20
- class="smooth-hover">
21
- <PlayIcon class="w-4 h-4" />
17
+ >
18
+ <PlayIcon />
22
19
  </button>
23
20
  </li>
24
21
  <li>
25
22
  <button
26
23
  :disabled="ui.disabledButtons['add-accounts']"
27
24
  @click="ui.toggleModal('create-account', true)"
28
- class="smooth-hover">
29
- <PlusIcon class="w-4 h-4" />
25
+ >
26
+ <PlusIcon />
30
27
  </button>
31
28
  </li>
32
29
  </ul>
@@ -37,16 +34,13 @@
37
34
  <TagToggle
38
35
  class="smooth-hover rounded-l min-w-9"
39
36
  :options="['All', 'Enabled', 'Disabled']"
40
- @change="(f) => (ui.search.accounts.show = f)" />
37
+ @change="(f) => (ui.search.accounts.show = f)"
38
+ />
41
39
  <input
42
40
  class="h-10 w-44 text-white text-sm p-2 bg-dark-500 flex items-center relative border-2 border-dark-550"
43
41
  placeholder="Search Email"
44
- autocomplete="new-password"
45
- data-dashlane-rid=""
46
- data-dashlane-label=""
47
- data-dashlane-classification=""
48
- data-form-type="other"
49
- v-model="ui.search.accounts.query" />
42
+ v-model="ui.search.accounts.query"
43
+ />
50
44
 
51
45
  <!-- <Dropdown
52
46
  class="min-w-16 text-sm lg:w-24 bg-dark-550 rounded-none"
@@ -63,34 +57,37 @@
63
57
  /> -->
64
58
 
65
59
  <Dropdown
66
- class="dropdown-base rounded-r-lg min-w-32 relative z-50 search-dropdown"
60
+ class="rounded-r min-w-32 bg-dark-500 relative z-50 border-2 border-dark-550"
61
+ style="margin-left: 0 !important; border-width: 2px !important"
67
62
  rightAmount="right-1"
68
63
  default="Any"
69
64
  :value="ui.search.accounts.tag"
70
65
  :onClick="(f) => (ui.search.accounts.tag = f)"
71
66
  :options="allTags"
72
- :includeAdjacentButtons="true"
73
- :capitalize="true" />
67
+ :capitalize="true"
68
+ />
74
69
  </div>
75
70
 
76
71
  <div class="ml-auto gap-2 hidden lg:flex">
77
72
  <div
78
- class="bg-dark-400 border border-dark-650 justify-between px-4 w-44 flex text-white text-xs font-medium items-center rounded-md ml-auto h-10">
73
+ class="bg-dark-400 justify-between px-4 w-44 flex text-white text-sm items-center py-1 rounded-lg ml-auto h-10"
74
+ >
79
75
  <p>Privacy</p>
80
76
  <Switch class="scale-75" v-model="privacy" />
81
77
  </div>
82
78
  <button
83
79
  :disabled="ui.disabledButtons['create-accounts']"
84
- class="bg-dark-400 disabled:opacity-70 smooth-hover border border-dark-650 hover:border-dark-700 w-44 flex text-white text-xs font-medium justify-center items-center rounded-md ml-auto h-10"
85
- @click="ui.toggleModal('account-creator')">
86
- Create Accounts
87
- <PlayIcon class="ml-2" />
80
+ class="bg-dark-400 disabled:opacity-70 smooth-hover w-44 flex text-white text-sm justify-center items-center py-1 px-2 rounded-lg ml-auto h-10"
81
+ @click="ui.toggleModal('account-creator')"
82
+ >
83
+ Create Accounts <PlayIcon class="ml-2" />
88
84
  </button>
89
85
 
90
86
  <button
91
87
  :disabled="ui.disabledButtons['add-accounts']"
92
- class="bg-dark-400 disabled:opacity-70 smooth-hover border border-dark-650 hover:border-dark-700 w-44 flex text-white text-xs font-medium justify-center items-center rounded-md ml-auto h-10"
93
- @click="ui.toggleModal('create-account')">
88
+ class="bg-dark-400 disabled:opacity-70 smooth-hover w-44 flex text-white text-sm justify-center items-center py-1 px-2 rounded-lg ml-auto h-10"
89
+ @click="ui.toggleModal('create-account')"
90
+ >
94
91
  Add Account
95
92
  <PlusIcon class="ml-2" />
96
93
  </button>
@@ -98,10 +95,10 @@
98
95
  </div>
99
96
 
100
97
  <!-- Tasks (Table) -->
101
- <AccountView :accounts="processedTasks" class="max-h-big-acc" />
98
+ <AccountView :tasks="processedTasks" class="max-h-big-acc" />
102
99
 
103
100
  <!-- Modal -->
104
- <transition-group name="fade">
101
+ <transition-group name="fade" mode="out-in">
105
102
  <CreateAccount v-if="activeModal === 'create-account'" />
106
103
  <AccountCreator v-if="activeModal === 'account-creator'" />
107
104
  </transition-group>
@@ -111,14 +108,7 @@
111
108
  .custom-dropdown-content {
112
109
  top: 2.6rem !important;
113
110
  left: -13px;
114
- @apply border border-dark-650;
115
- }
116
-
117
- /* Search dropdown should always be h-10 and have no left corners */
118
- .search-dropdown {
119
- height: 2.5rem !important; /* Always 40px regardless of screen size */
120
- border-top-left-radius: 0 !important;
121
- border-bottom-left-radius: 0 !important;
111
+ @apply border border-light-300;
122
112
  }
123
113
  .max-h-big-acc {
124
114
  max-height: calc(100vh - 14rem);
@@ -127,11 +117,11 @@
127
117
  </style>
128
118
  <script setup>
129
119
  import { computed, watch, ref } from "vue";
130
- import AccountView from "@/components/Editors/Account/AccountView.vue";
131
- import AccountCreator from "@/components/Editors/Account/AccountCreator.vue";
132
- import CreateAccount from "@/components/Editors/Account/CreateAccount.vue";
120
+ import AccountView from "@/components/editors/account/AccountView.vue";
121
+ import AccountCreator from "@/components/editors/account/AccountCreator.vue";
122
+ import CreateAccount from "@/components/editors/account/CreateAccount.vue";
133
123
  import { useUIStore } from "@/stores/ui";
134
- import { PlusIcon, PlayIcon, MailIcon } from "@/components/icons";
124
+ import { PlusIcon, PlayIcon } from "@/components/icons";
135
125
  import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
136
126
  import TagToggle from "@/components/Editors/TagToggle.vue";
137
127
  import Switch from "@/components/ui/controls/atomic/Switch.vue";
@@ -148,8 +138,9 @@ const filterAccounts = () => {
148
138
  if (show === "Enabled") accs = accs.filter((p) => p.enabled);
149
139
  if (show === "Disabled") accs = accs.filter((p) => !p.enabled);
150
140
  ui.logger.Info(`Filtered accounts for ${ui.currentModule}`);
151
-
141
+ console.log(accs);
152
142
  accs = accs.filter((acc) => acc.module === ui.currentModule);
143
+ console.log(accs);
153
144
 
154
145
  if (tag !== "Any") accs = accs.filter((p) => p.tags.includes(ui.search.accounts.tag));
155
146
  if (!query) return (ui.search.accounts.results = accs);