@necrolab/dashboard 0.5.15 → 0.5.17

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 (137) 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 +70 -566
  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 +61 -74
  13. package/src/assets/css/components/forms.scss +31 -32
  14. package/src/assets/css/components/headers.scss +13 -21
  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 +295 -0
  20. package/src/assets/css/main.scss +55 -139
  21. package/src/components/Auth/LoginForm.vue +7 -86
  22. package/src/components/Console/ConsoleToolbar.vue +123 -0
  23. package/src/components/Editors/Account/Account.vue +12 -12
  24. package/src/components/Editors/Account/AccountView.vue +38 -111
  25. package/src/components/Editors/Account/CreateAccount.vue +11 -61
  26. package/src/components/Editors/Account/{AccountCreator.vue → CreateAccountBatch.vue} +28 -59
  27. package/src/components/Editors/AdminFileEditor.vue +179 -0
  28. package/src/components/Editors/Profile/CreateProfile.vue +77 -150
  29. package/src/components/Editors/Profile/Profile.vue +20 -21
  30. package/src/components/Editors/Profile/ProfileCountryChooser.vue +16 -60
  31. package/src/components/Editors/Profile/ProfileView.vue +41 -116
  32. package/src/components/Editors/ProxyFileEditor.vue +86 -0
  33. package/src/components/Editors/TagLabel.vue +16 -55
  34. package/src/components/Editors/TagToggle.vue +20 -8
  35. package/src/components/Filter/Filter.vue +66 -79
  36. package/src/components/Filter/FilterPreview.vue +153 -135
  37. package/src/components/Filter/PriceSortToggle.vue +36 -43
  38. package/src/components/Table/Header.vue +1 -1
  39. package/src/components/Table/Table.vue +45 -51
  40. package/src/components/Tasks/CheckStock.vue +7 -16
  41. package/src/components/Tasks/Controls/DesktopControls.vue +15 -60
  42. package/src/components/Tasks/Controls/MobileControls.vue +5 -20
  43. package/src/components/Tasks/CreateTaskAXS.vue +20 -118
  44. package/src/components/Tasks/CreateTaskTM.vue +33 -189
  45. package/src/components/Tasks/EventDetailRow.vue +21 -0
  46. package/src/components/Tasks/MassEdit.vue +6 -16
  47. package/src/components/Tasks/QuickSettings.vue +140 -216
  48. package/src/components/Tasks/ScrapeVenue.vue +4 -13
  49. package/src/components/Tasks/Stats.vue +20 -39
  50. package/src/components/Tasks/Task.vue +64 -270
  51. package/src/components/Tasks/TaskLabel.vue +9 -3
  52. package/src/components/Tasks/TaskView.vue +45 -64
  53. package/src/components/Tasks/Utilities.vue +10 -44
  54. package/src/components/Tasks/ViewTask.vue +23 -107
  55. package/src/components/icons/Close.vue +2 -8
  56. package/src/components/icons/Gear.vue +8 -8
  57. package/src/components/icons/Hash.vue +5 -0
  58. package/src/components/icons/Key.vue +2 -8
  59. package/src/components/icons/Pencil.vue +2 -8
  60. package/src/components/icons/Profile.vue +2 -8
  61. package/src/components/icons/Sell.vue +2 -8
  62. package/src/components/icons/Spinner.vue +4 -7
  63. package/src/components/icons/Wildcard.vue +2 -8
  64. package/src/components/icons/index.js +3 -5
  65. package/src/components/ui/ActionButtonGroup.vue +113 -52
  66. package/src/components/ui/BalanceIndicator.vue +60 -0
  67. package/src/components/ui/EmptyState.vue +24 -0
  68. package/src/components/ui/EnableDisableToggle.vue +23 -0
  69. package/src/components/ui/FormField.vue +49 -49
  70. package/src/components/ui/IconLabel.vue +23 -0
  71. package/src/components/ui/InfoRow.vue +21 -54
  72. package/src/components/ui/Modal.vue +161 -54
  73. package/src/components/ui/Navbar.vue +63 -44
  74. package/src/components/ui/ReadonlyFieldsSection.vue +31 -0
  75. package/src/components/ui/ReconnectIndicator.vue +111 -124
  76. package/src/components/ui/SectionCard.vue +6 -14
  77. package/src/components/ui/Splash.vue +2 -10
  78. package/src/components/ui/StatusBadge.vue +26 -28
  79. package/src/components/ui/TaskToggle.vue +54 -0
  80. package/src/components/ui/controls/CountryChooser.vue +29 -66
  81. package/src/components/ui/controls/EyeToggle.vue +1 -1
  82. package/src/components/ui/controls/atomic/Checkbox.vue +40 -121
  83. package/src/components/ui/controls/atomic/Dropdown.vue +103 -139
  84. package/src/components/ui/controls/atomic/MultiDropdown.vue +72 -120
  85. package/src/components/ui/controls/atomic/Switch.vue +21 -84
  86. package/src/composables/useCodeEditor.js +117 -0
  87. package/src/composables/useColorMapping.js +15 -0
  88. package/src/composables/useCopyToClipboard.js +1 -1
  89. package/src/composables/useDateFormatting.js +21 -0
  90. package/src/composables/useDeviceDetection.js +14 -0
  91. package/src/composables/useDropdownPosition.js +1 -4
  92. package/src/composables/useDynamicTableHeight.js +31 -0
  93. package/src/composables/useEnableDisable.js +6 -0
  94. package/src/composables/useFilterCSS.js +71 -0
  95. package/src/composables/useFormValidation.js +92 -0
  96. package/src/composables/useGetAllTags.js +9 -0
  97. package/src/composables/useIOSViewportHandling.js +76 -0
  98. package/src/composables/useNotchHandling.js +306 -0
  99. package/src/composables/useRowSelection.js +0 -3
  100. package/src/composables/useTableRender.js +23 -0
  101. package/src/composables/useTicketPricing.js +16 -0
  102. package/src/composables/useWindowDimensions.js +21 -0
  103. package/src/composables/useZoomPrevention.js +96 -0
  104. package/src/constants/tableLayout.js +14 -0
  105. package/src/libs/Filter.js +14 -20
  106. package/src/libs/panzoom.js +1 -5
  107. package/src/libs/utils/array.js +58 -0
  108. package/src/{stores/utils.js → libs/utils/dataGeneration.js} +2 -250
  109. package/src/libs/utils/eventUrl.js +40 -0
  110. package/src/libs/utils/string.js +3 -0
  111. package/src/libs/utils/time.js +20 -0
  112. package/src/libs/utils/validation.js +64 -0
  113. package/src/main.js +0 -2
  114. package/src/stores/connection.js +1 -29
  115. package/src/stores/logger.js +6 -12
  116. package/src/stores/sampleData.js +1 -2
  117. package/src/stores/ui.js +80 -71
  118. package/src/utils/tableHelpers.js +1 -0
  119. package/src/views/Accounts.vue +19 -38
  120. package/src/views/Console.vue +74 -253
  121. package/src/views/Editor.vue +47 -1114
  122. package/src/views/FilterBuilder.vue +190 -461
  123. package/src/views/Login.vue +3 -28
  124. package/src/views/Profiles.vue +17 -32
  125. package/src/views/Tasks.vue +51 -38
  126. package/tailwind.config.js +82 -71
  127. package/workbox-config.cjs +47 -5
  128. package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2438
  129. package/exit +0 -209
  130. package/run +0 -177
  131. package/src/assets/css/base/color-fallbacks.scss +0 -10
  132. package/src/assets/img/background.svg.backup +0 -11
  133. package/src/components/icons/SquareCheck.vue +0 -18
  134. package/src/components/icons/SquareUncheck.vue +0 -18
  135. package/src/components/ui/controls/atomic/LoadingButton.vue +0 -45
  136. package/switch-branch.sh +0 -41
  137. /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
@@ -8,7 +8,7 @@
8
8
  <div>
9
9
  <div class="form-grid mb-4 mt-7">
10
10
  <div class="input-wrapper relative-positioned z-tooltip col-span-8">
11
- <label class="label-override mb-2">
11
+ <label class="label-override mb-2 flex">
12
12
  Account Tag
13
13
  <TagIcon />
14
14
  </label>
@@ -23,11 +23,11 @@
23
23
  </div>
24
24
 
25
25
  <div class="input-wrapper col-span-4">
26
- <label class="label-override mb-2">
26
+ <label class="label-override mb-2 flex">
27
27
  Threads
28
28
  <EditIcon />
29
29
  </label>
30
- <div :class="`input-default ${errors.includes('threads') ? 'error' : ''}`">
30
+ <div :class="`input-default ${errors.includes('threads') ? 'border-2 border-error-300' : ''}`">
31
31
  <input placeholder="1" type="number" min="1" max="50" v-model="creatorConfig.threads" />
32
32
  <div class="input-incrementer">
33
33
  <button @click="creatorConfig.threads++">
@@ -40,20 +40,20 @@
40
40
  </div>
41
41
  </div>
42
42
  <div class="input-wrapper col-span-8">
43
- <label class="label-override mb-2">
43
+ <label class="label-override mb-2 flex">
44
44
  Email catchall
45
45
  <MailIcon />
46
46
  </label>
47
- <div :class="`input-default ${errors.includes('catchall') ? 'error' : ''}`">
47
+ <div :class="`input-default ${errors.includes('catchall') ? 'border-2 border-error-300' : ''}`">
48
48
  <input placeholder="example.com" v-model="creatorConfig.catchall" />
49
49
  </div>
50
50
  </div>
51
51
  <div class="input-wrapper col-span-4">
52
- <label class="label-override mb-2">
52
+ <label class="label-override mb-2 flex">
53
53
  Catchall amount
54
54
  <BagIcon />
55
55
  </label>
56
- <div :class="`input-default ${errors.includes('number') ? 'error' : ''}`">
56
+ <div :class="`input-default ${errors.includes('number') ? 'border-2 border-error-300' : ''}`">
57
57
  <input placeholder="1" type="number" min="0" max="5000" v-model="creatorConfig.number" />
58
58
  <div class="input-incrementer">
59
59
  <button @click="creatorConfig.number++">
@@ -66,71 +66,28 @@
66
66
  </div>
67
67
  </div>
68
68
  <div class="input-wrapper col-span-12">
69
- <label class="label-override mb-2">
69
+ <label class="label-override mb-2 flex">
70
70
  Emails
71
71
  <MailIcon />
72
72
  </label>
73
- <div :class="`${errors.includes('emails') ? 'error-border' : ''}`">
74
- <textarea
75
- v-model="creatorConfig.emails"
76
- class="proxy-editor"
77
- spellcheck="false"
78
- style="max-height: 250px; min-height: 150px"
79
- placeholder="Enter emails here - One per line"></textarea>
80
- </div>
73
+ <textarea
74
+ v-model="creatorConfig.emails"
75
+ :class="['textarea-emails', errors.includes('emails') && 'textarea-error']"
76
+ spellcheck="false"
77
+ style="max-height: 250px; min-height: 150px; line-height: 1.6; tab-size: 4; font-family: 'JetBrains Mono', 'Fira Code', 'Menlo', 'Monaco', 'Courier New', monospace"
78
+ placeholder="Enter emails here - One per line"></textarea>
81
79
  </div>
82
80
  </div>
83
- <button
84
- class="button-default ml-auto mt-4 flex w-48 items-center justify-center gap-x-2 bg-dark-400 text-xs"
85
- @click="done()">
81
+ <button class="btn-modal ml-auto mt-4" @click="done()">
86
82
  Start
87
83
  <EditIcon />
88
84
  </button>
89
85
  </div>
90
86
  </Modal>
91
87
  </template>
92
- <style lang="scss" scoped>
93
- .input-wrapper {
94
- label {
95
- @apply flex;
96
- }
97
- }
98
- .error {
99
- border-width: 2px !important;
100
- border-color: rgb(238 130 130) !important;
101
- }
102
-
103
- .error-border {
104
- border: 2px solid rgb(238 130 130) !important;
105
- border-radius: 8px;
106
- }
107
-
108
- /* Proxy editor styles */
109
- .proxy-editor {
110
- width: 100%;
111
- background-color: oklch(0.19 0 0);
112
- color: oklch(0.90 0 0);
113
- font-family: "JetBrains Mono", "Fira Code", "Menlo", "Monaco", "Courier New", monospace;
114
- padding: 12px;
115
- border: none;
116
- resize: none;
117
- font-size: 14px;
118
- line-height: 1.6;
119
- tab-size: 4;
120
- outline: none;
121
- border: 1px solid oklch(0.26 0 0);
122
- border-radius: 8px;
123
- overflow: auto;
124
- }
125
-
126
- .proxy-editor:focus {
127
- border-color: oklch(0.28 0 0);
128
- box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.2);
129
- }
130
- </style>
131
88
  <script setup>
132
89
  import Modal from "@/components/ui/Modal.vue";
133
- import { EditIcon, TagIcon, SpinnerIcon, UpIcon, DownIcon, MailIcon, BagIcon } from "@/components/icons";
90
+ import { EditIcon, TagIcon, UpIcon, DownIcon, MailIcon, BagIcon } from "@/components/icons";
134
91
  import { useUIStore } from "@/stores/ui";
135
92
  import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
136
93
 
@@ -168,3 +125,15 @@ function done() {
168
125
  ui.createAcconts(creatorConfig.value);
169
126
  }
170
127
  </script>
128
+ <style scoped>
129
+ .textarea-emails {
130
+ @apply w-full rounded border bg-dark-350 p-3 font-mono text-light-300;
131
+ @apply outline-none resize-none overflow-auto text-sm;
132
+ @apply border border-dark-550 hover:border-dark-650;
133
+ @apply focus:border-dark-700 focus:shadow-focus-ring;
134
+ }
135
+
136
+ .textarea-error {
137
+ @apply border-2 border-error-300 hover:border-error-300;
138
+ }
139
+ </style>
@@ -0,0 +1,179 @@
1
+ <template>
2
+ <div class="admin-editor-section" :class="{ 'landscape-hidden': isHidden }">
3
+ <h5 class="text-white text-xl font-bold flex gap-x-3 mb-3">Admin Editor</h5>
4
+ <div class="flex flex-wrap items-center gap-3 w-full">
5
+ <div class="unified-search-group flex w-full flex-shrink-0 dropdown-container z-dropdown-high lg:w-auto lg:min-w-64">
6
+ <Dropdown
7
+ class="admin-file-dropdown flex-1"
8
+ default="Select a file"
9
+ :onClick="loadFile"
10
+ :options="availableFiles"
11
+ :allowDefault="false"
12
+ :includeAdjacentButtons="true"
13
+ rightAmount="right-1" />
14
+ <button
15
+ class="refresh-button flex items-center justify-center w-9 h-10 flex-shrink-0 text-white bg-dark-400 transition-standard hover:bg-dark-450"
16
+ @click="$emit('refresh-files')"
17
+ title="Refresh file list">
18
+ <ReloadIcon class="refresh-icon icon-md" />
19
+ </button>
20
+ </div>
21
+ <div v-if="isEditorVisible" class="flex gap-1.5 ml-auto">
22
+ <button
23
+ class="button-default bg-dark-400"
24
+ @click="$emit('format')"
25
+ v-if="isJsonFile"
26
+ title="Format JSON">
27
+ <svg
28
+ xmlns="http://www.w3.org/2000/svg"
29
+ width="16"
30
+ height="16"
31
+ viewBox="0 0 24 24"
32
+ fill="none"
33
+ stroke="currentColor"
34
+ stroke-width="2"
35
+ stroke-linecap="round"
36
+ stroke-linejoin="round">
37
+ <path d="M21 10H7" />
38
+ <path d="M21 6H3" />
39
+ <path d="M21 14H3" />
40
+ <path d="M21 18H7" />
41
+ </svg>
42
+ </button>
43
+ <button class="button-default bg-dark-400" @click="$emit('save')" title="Save File">
44
+ <svg
45
+ xmlns="http://www.w3.org/2000/svg"
46
+ width="16"
47
+ height="16"
48
+ viewBox="0 0 24 24"
49
+ fill="none"
50
+ stroke="currentColor"
51
+ stroke-width="2"
52
+ stroke-linecap="round"
53
+ stroke-linejoin="round">
54
+ <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
55
+ <polyline points="17 21 17 13 7 13 7 21" />
56
+ <polyline points="7 3 7 8 15 8" />
57
+ </svg>
58
+ </button>
59
+ <button class="button-default bg-dark-400" @click="$emit('close')" title="Close File">
60
+ <svg
61
+ xmlns="http://www.w3.org/2000/svg"
62
+ width="16"
63
+ height="16"
64
+ viewBox="0 0 24 24"
65
+ fill="none"
66
+ stroke="currentColor"
67
+ stroke-width="2"
68
+ stroke-linecap="round"
69
+ stroke-linejoin="round">
70
+ <line x1="18" y1="6" x2="6" y2="18"></line>
71
+ <line x1="6" y1="6" x2="18" y2="18"></line>
72
+ </svg>
73
+ </button>
74
+ </div>
75
+ </div>
76
+
77
+ <transition name="fade">
78
+ <div v-if="isEditorVisible" class="my-3 relative">
79
+ <div class="pb-4">
80
+ <div class="editor-container overflow-hidden rounded-lg shadow-card bg-dark-350" :class="{ 'has-error': errorMessage }">
81
+ <div class="relative w-full h-full">
82
+ <pre ref="codeDisplay" class="code-highlight language-json"></pre>
83
+ <textarea
84
+ ref="codeEditor"
85
+ :value="content"
86
+ @input="$emit('update:content', $event.target.value)"
87
+ class="code-editor"
88
+ spellcheck="false"
89
+ @scroll="handleScroll"
90
+ @keydown.tab.prevent="handleTabKey"></textarea>
91
+ </div>
92
+ </div>
93
+ </div>
94
+
95
+ <div v-if="errorMessage" class="error-container">
96
+ <div class="error-icon">
97
+ <svg
98
+ width="16"
99
+ height="16"
100
+ viewBox="0 0 24 24"
101
+ fill="none"
102
+ stroke="currentColor"
103
+ stroke-width="2">
104
+ <circle cx="12" cy="12" r="10" />
105
+ <line x1="15" y1="9" x2="9" y2="15" />
106
+ <line x1="9" y1="9" x2="15" y2="15" />
107
+ </svg>
108
+ </div>
109
+ <div class="error-content">
110
+ <div class="error-title">JSON Syntax Error</div>
111
+ <div class="error-text">{{ errorMessage }}</div>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </transition>
116
+ </div>
117
+ </template>
118
+
119
+ <script setup>
120
+ import { ref, computed, watch, nextTick, onMounted } from 'vue';
121
+ import { ReloadIcon } from '@/components/icons';
122
+ import Dropdown from '@/components/ui/controls/atomic/Dropdown.vue';
123
+ import { useCodeEditor } from '@/composables/useCodeEditor';
124
+
125
+ const props = defineProps({
126
+ availableFiles: { type: Array, required: true },
127
+ currentFile: { type: String, default: '' },
128
+ content: { type: String, default: '' },
129
+ isHidden: { type: Boolean, default: false },
130
+ logger: { type: Object, required: true }
131
+ });
132
+
133
+ const emit = defineEmits(['update:content', 'load-file', 'refresh-files', 'save', 'close', 'format']);
134
+
135
+ const codeEditor = ref(null);
136
+ const codeDisplay = ref(null);
137
+ const { highlightCode, syncScroll, handleTab } = useCodeEditor(props.logger);
138
+
139
+ const isEditorVisible = computed(() => props.currentFile !== '');
140
+ const isJsonFile = computed(() => props.currentFile.endsWith('.json'));
141
+
142
+ const errorMessage = computed(() => {
143
+ if (!isJsonFile.value) return;
144
+ try {
145
+ JSON.parse(props.content);
146
+ } catch (e) {
147
+ return e.message;
148
+ }
149
+ });
150
+
151
+ const loadFile = (fileName) => {
152
+ emit('load-file', fileName);
153
+ };
154
+
155
+ const handleScroll = () => {
156
+ syncScroll(codeDisplay.value, codeEditor.value);
157
+ };
158
+
159
+ const handleTabKey = () => {
160
+ const contentRef = ref(props.content);
161
+ handleTab(codeEditor.value, contentRef, () => {
162
+ emit('update:content', contentRef.value);
163
+ });
164
+ };
165
+
166
+ watch(() => props.content, () => {
167
+ nextTick(() => {
168
+ highlightCode(codeDisplay.value, codeEditor.value, props.content, props.currentFile);
169
+ });
170
+ });
171
+
172
+ onMounted(() => {
173
+ if (props.content) {
174
+ nextTick(() => {
175
+ highlightCode(codeDisplay.value, codeEditor.value, props.content, props.currentFile);
176
+ });
177
+ }
178
+ });
179
+ </script>