@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
@@ -7,92 +7,88 @@
7
7
  </template>
8
8
 
9
9
  <div>
10
- <div class="my-3 grid grid-cols-12 gap-3">
10
+ <div class="grid grid-cols-12 gap-3 my-3">
11
11
  <!-- Profile tag -->
12
- <div class="input-wrapper z-dropdown col-span-4">
13
- <label class="label-override mb-2">
14
- Profile Tag
15
- <TagIcon />
16
- </label>
17
- <Dropdown
18
- :class="`input-default dropdown w-full ${errors.includes('profileTag') ? 'error' : ''}`"
19
- :default="ui.profile.tags[0]"
20
- :options="ui.profile.tags"
21
- :onClick="(f) => (profile.tag = f)"
22
- :capitalize="true" />
12
+ <div class="input-wrapper col-span-4" style="z-index: 30 !important">
13
+ <label class="label-override mb-2">Profile Tag </label>
14
+ <div :class="`input-default ${errors.includes('profileTag') ? 'error' : ''}`">
15
+ <Dropdown
16
+ class="text-xs w-64 h-8"
17
+ :default="ui.profile.accountTags[0]"
18
+ :options="ui.profile.accountTags"
19
+ :onClick="(f) => (profile.tag = f)"
20
+ :capitalize="true"
21
+ rightAmount="right-6 md:right-2 top-2"
22
+ />
23
+ </div>
23
24
  </div>
24
25
 
25
26
  <!-- Card Number -->
26
- <div class="input-wrapper z-0 col-span-8">
27
- <label class="label-override mb-2">
28
- Card Number
29
- <CartIcon />
30
- </label>
27
+ <div class="input-wrapper col-span-8 z-0">
28
+ <label class="label-override mb-2">Card Number </label>
31
29
  <div :class="`input-default ${errors.includes('cardNumber') ? 'error' : ''}`">
32
30
  <input
33
- ref="cardNumberInput"
34
31
  placeholder="Enter card number"
35
- v-model="displayCardNumber"
36
- maxlength="23"
32
+ v-model="profile.cardNumber"
33
+ maxlength="19"
37
34
  inputmode="numeric"
38
35
  @input="handleCreditCardUpdate"
39
- @focus="formatCardNumberDisplay" />
36
+ />
40
37
  </div>
41
38
  </div>
42
39
 
43
40
  <!-- Country chooser -->
44
41
  <div class="input-wrapper col-span-2">
45
- <label class="label-override mb-2">
46
- Country
47
- <SandclockIcon />
48
- </label>
42
+ <label class="label-override mb-2">Country </label>
49
43
  <ProfileCountryChooser
50
44
  class="h-8"
51
45
  :value="profile.country"
52
46
  :onClick="chooseCountry"
53
- :disabled="true" />
47
+ :disabled="true"
48
+ />
54
49
  </div>
55
50
 
56
51
  <!-- Exp Year -->
57
52
  <div class="input-wrapper col-span-5">
58
- <label class="label-override z-0 mb-2">
59
- Expiry Year
60
- <TimerIcon />
61
- </label>
62
- <Dropdown
63
- :class="`input-default dropdown w-full ${errors.includes('expYear') ? 'error' : ''}`"
64
- default="Expiry Year"
65
- :value="
66
- profile.expYear && !profile?.expYear?.startsWith('20')
67
- ? '20' + profile.expYear
68
- : profile.expYear
69
- ? profile.expYear
70
- : undefined
71
- "
72
- :options="['2025', '2026', '2027', '2028', '2029', '2030', '2031']"
73
- :onClick="(f) => (profile.expYear = f)" />
53
+ <label class="label-override mb-2 z-0">Expiry Year </label>
54
+ <div :class="`input-default ${errors.includes('expYear') ? 'error' : ''}`">
55
+ <Dropdown
56
+ class="text-xs w-64 h-8"
57
+ default="Expiry Year"
58
+ :value="
59
+ profile.expYear && !profile?.expYear?.startsWith('20')
60
+ ? '20' + profile.expYear
61
+ : profile.expYear
62
+ ? profile.expYear
63
+ : undefined
64
+ "
65
+ :options="['2025', '2026', '2027', '2028', '2029', '2030', '2031']"
66
+ :onClick="(f) => (profile.expYear = f)"
67
+ rightAmount="right-2 top-2"
68
+ topPadding="pt-2 mt-2"
69
+ />
70
+ </div>
74
71
  </div>
75
72
 
76
73
  <!-- Exp Month -->
77
- <div class="input-wrapper z-2 col-span-5">
78
- <label class="label-override mb-2">
79
- Expiry Month
80
- <TimerIcon />
81
- </label>
82
- <Dropdown
83
- :class="`input-default dropdown w-full ${errors.includes('expMonth') ? 'error' : ''}`"
84
- default="Expiry Month"
85
- :value="profile.expMonth ? profile.expMonth : undefined"
86
- :options="['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']"
87
- :onClick="(f) => (profile.expMonth = f)" />
74
+ <div class="input-wrapper col-span-5">
75
+ <label class="label-override mb-2">Expiry Month </label>
76
+ <div :class="`input-default ${errors.includes('expMonth') ? 'error' : ''}`">
77
+ <Dropdown
78
+ class="text-xs w-64 h-8"
79
+ default="Expiry Month"
80
+ :value="profile.expMonth ? profile.expMonth : undefined"
81
+ :options="['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']"
82
+ :onClick="(f) => (profile.expMonth = f)"
83
+ rightAmount="right-2 top-2"
84
+ topPadding="pt-2 mt-2"
85
+ />
86
+ </div>
88
87
  </div>
89
88
 
90
89
  <!-- CVV -->
91
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
92
- <label class="label-override mb-2">
93
- CVV
94
- <ShieldIcon />
95
- </label>
90
+ <div class="input-wrapper col-span-6 md:col-span-4 z-0">
91
+ <label class="label-override mb-2">CVV </label>
96
92
  <div :class="`input-default ${errors.includes('cvv') ? 'error' : ''}`">
97
93
  <input
98
94
  placeholder="183"
@@ -100,88 +96,51 @@
100
96
  max="9999"
101
97
  maxlength="4"
102
98
  minlength="3"
103
- v-model="profile.cvv" />
99
+ v-model="profile.cvv"
100
+ />
104
101
  </div>
105
102
  </div>
106
103
 
107
104
  <!-- City -->
108
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
109
- <label class="label-override mb-2">
110
- City
111
- <StadiumIcon />
112
- </label>
105
+ <div class="input-wrapper col-span-6 md:col-span-4 z-0">
106
+ <label class="label-override mb-2">City </label>
113
107
  <div :class="`input-default ${errors.includes('city') ? 'error' : ''}`">
114
108
  <input placeholder="Denver" v-model="profile.city" />
115
109
  </div>
116
110
  </div>
117
111
 
118
112
  <!-- State -->
119
- <div class="input-wrapper z-1 col-span-6 md:col-span-4">
120
- <label class="label-override mb-2">
121
- State
122
- <SandclockIcon />
123
- </label>
124
- <div v-if="profile.country === 'US'" :class="`${errors.includes('state') ? 'error' : ''}`">
125
- <Dropdown
126
- class="input-default w-full"
127
- default="Select State"
128
- :onClick="(state) => (profile.state = state)"
129
- :options="usStates"
130
- :allowDefault="false"
131
- rightAmount="right-2"
132
- :value="profile.state" />
133
- </div>
134
- <div v-else :class="`input-default ${errors.includes('state') ? 'error' : ''}`">
135
- <input disabled placeholder="N/A" value="" />
113
+ <div class="input-wrapper col-span-6 md:col-span-4 z-0">
114
+ <label class="label-override mb-2">State </label>
115
+ <div :class="`input-default ${errors.includes('state') ? 'error' : ''}`">
116
+ <input :disabled="profile.country !== 'US'" placeholder="CO" v-model="profile.state" />
136
117
  </div>
137
118
  </div>
138
119
 
139
120
  <!-- Zip -->
140
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
141
- <label class="label-override mb-2">
142
- Zip
143
- <KeyIcon />
144
- </label>
121
+ <div class="input-wrapper col-span-6 md:col-span-4 z-0">
122
+ <label class="label-override mb-2">Zip </label>
145
123
  <div :class="`input-default ${errors.includes('zipCode') ? 'error' : ''}`">
146
- <input placeholder="10005" type="number" min="1" max="12" v-model="profile.zipCode" />
124
+ <input placeholder="80281" type="number" min="1" max="12" v-model="profile.zipCode" />
147
125
  </div>
148
126
  </div>
149
127
 
150
128
  <!-- Address -->
151
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
152
- <label class="label-override mb-2">
153
- Address
154
- <HandIcon />
155
- </label>
129
+ <div class="input-wrapper col-span-6 md:col-span-4 z-0">
130
+ <label class="label-override mb-2">Address </label>
156
131
  <div :class="`input-default ${errors.includes('address') ? 'error' : ''}`">
157
- <input placeholder="100 5th Avenue" v-model="profile.address" />
132
+ <input placeholder="Denver" v-model="profile.address" />
158
133
  </div>
159
134
  </div>
160
135
 
161
136
  <!-- Generate -->
162
- <div class="input-wrapper z-0 col-span-6 md:col-span-4">
163
- <label class="label-override mb-2">
164
- Fake ID
165
- <WildcardIcon />
166
- </label>
167
- <div class="input-default mt-2 flex h-10 w-full items-center">
137
+ <div class="input-wrapper col-span-6 md:col-span-4 z-0">
138
+ <label class="label-override mb-2 z-0"> Fake ID</label>
139
+ <div class="input-default mt-2 w-full">
168
140
  <button
169
141
  @click="generate"
170
- class="flex w-full items-center justify-center gap-2 text-xs text-white">
171
- <svg
172
- xmlns="http://www.w3.org/2000/svg"
173
- width="14"
174
- height="14"
175
- viewBox="0 0 24 24"
176
- fill="none"
177
- stroke="currentColor"
178
- stroke-width="2"
179
- stroke-linecap="round"
180
- stroke-linejoin="round">
181
- <rect x="3" y="4" width="18" height="16" rx="2" />
182
- <line x1="7" y1="2" x2="7" y2="6" />
183
- <line x1="17" y1="2" x2="17" y2="6" />
184
- </svg>
142
+ class="text-white w-full button-default text-xs flex items-center justify-center"
143
+ >
185
144
  <span>Generate</span>
186
145
  </button>
187
146
  </div>
@@ -190,10 +149,10 @@
190
149
  </div>
191
150
 
192
151
  <button
193
- class="button-default ml-auto mt-4 flex w-48 items-center justify-center gap-x-2 bg-dark-400 text-xs hover:opacity-70 active:opacity-50"
194
- @click="done()">
195
- Save
196
- <EditIcon />
152
+ class="button-default hover:opacity-70 active:opacity-50 bg-dark-400 w-48 text-xs flex items-center justify-center gap-x-2 ml-auto mt-4"
153
+ @click="done()"
154
+ >
155
+ Save <EditIcon />
197
156
  </button>
198
157
  </Modal>
199
158
  </template>
@@ -206,12 +165,6 @@
206
165
  .z-0 {
207
166
  z-index: 0 !important;
208
167
  }
209
- .z-1 {
210
- z-index: 1 !important;
211
- }
212
- .z-1 {
213
- z-index: 2 !important;
214
- }
215
168
 
216
169
  .error {
217
170
  border-width: 2px !important;
@@ -220,89 +173,22 @@
220
173
  </style>
221
174
  <script setup>
222
175
  import Modal from "@/components/ui/Modal.vue";
223
- import {
224
- MailIcon,
225
- CartIcon,
226
- ShieldIcon,
227
- StadiumIcon,
228
- KeyIcon,
229
- HandIcon,
230
- ProfileIcon,
231
- SandclockIcon,
232
- TimerIcon,
233
- TagIcon,
234
- WildcardIcon
235
- } from "@/components/icons";
236
176
  import { EditIcon } from "@/components/icons";
237
- import ProfileCountryChooser from "@/components/Editors/Profile/ProfileCountryChooser.vue";
177
+ import ProfileCountryChooser from "@/components/editors/Profile/ProfileCountryChooser.vue";
238
178
  import { useUIStore } from "@/stores/ui";
239
179
  import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
240
- import { ref, computed, watch, nextTick, onMounted } from "vue";
180
+ import { ref } from "vue";
241
181
  import { fakeId } from "@/stores/utils";
242
182
  import { validateCard } from "@/stores/utils";
243
183
 
244
184
  const props = defineProps({ profile: { type: Object, required: false } });
245
185
  const errors = ref([]);
246
186
  const ui = useUIStore();
247
-
248
- // US States list (excluding GA and PR, alphabetically ordered)
249
- const usStates = [
250
- "AK",
251
- "AL",
252
- "AR",
253
- "AZ",
254
- "CA",
255
- "CO",
256
- "CT",
257
- "DE",
258
- "FL",
259
- "HI",
260
- "IA",
261
- "ID",
262
- "IL",
263
- "IN",
264
- "KS",
265
- "KY",
266
- "LA",
267
- "MA",
268
- "MD",
269
- "ME",
270
- "MI",
271
- "MN",
272
- "MO",
273
- "MS",
274
- "MT",
275
- "NC",
276
- "ND",
277
- "NE",
278
- "NH",
279
- "NJ",
280
- "NM",
281
- "NV",
282
- "NY",
283
- "OH",
284
- "OK",
285
- "OR",
286
- "PA",
287
- "RI",
288
- "SC",
289
- "SD",
290
- "TN",
291
- "TX",
292
- "UT",
293
- "VA",
294
- "VT",
295
- "WA",
296
- "WI",
297
- "WV",
298
- "WY"
299
- ];
300
- const cardNumberInput = ref(null);
301
187
  const profile = ref({
302
188
  cvv: "",
303
189
  cardNumber: "",
304
190
  city: "",
305
- tag: ui.profile.tags[0],
191
+ tag: ui.profile.accountTags[0],
306
192
  state: "",
307
193
  country: "US",
308
194
  zipCode: ""
@@ -310,54 +196,6 @@ const profile = ref({
310
196
 
311
197
  if (ui.currentlyEditing?.profileName) profile.value = ui.currentlyEditing;
312
198
 
313
- // Reactive display value for the formatted card number
314
- const displayCardNumber = ref("");
315
-
316
- // Initialize display card number with formatting
317
- const initializeCardNumberDisplay = () => {
318
- if (profile.value.cardNumber) {
319
- const cleanNumber = profile.value.cardNumber.replace(/\s+/g, "");
320
- if (cleanNumber) {
321
- const cardInfo = validateCard(cleanNumber);
322
- displayCardNumber.value = cardInfo.formatted;
323
- }
324
- }
325
- };
326
-
327
- // Format card number display on focus
328
- const formatCardNumberDisplay = () => {
329
- if (profile.value.cardNumber) {
330
- const cleanNumber = profile.value.cardNumber.replace(/\s+/g, "");
331
- if (cleanNumber) {
332
- const cardInfo = validateCard(cleanNumber);
333
- displayCardNumber.value = cardInfo.formatted;
334
- }
335
- }
336
- };
337
-
338
- // Watch for changes in profile.cardNumber to sync with display
339
- watch(
340
- () => profile.value.cardNumber,
341
- (newValue) => {
342
- if (newValue) {
343
- const cleanNumber = newValue.replace(/\s+/g, "");
344
- if (cleanNumber) {
345
- const cardInfo = validateCard(cleanNumber);
346
- displayCardNumber.value = cardInfo.formatted;
347
- }
348
- } else {
349
- displayCardNumber.value = "";
350
- }
351
- }
352
- );
353
-
354
- // Initialize on modal open
355
- onMounted(() => {
356
- nextTick(() => {
357
- initializeCardNumberDisplay();
358
- });
359
- });
360
-
361
199
  const generate = () => {
362
200
  const fake = fakeId();
363
201
  profile.value.city = fake.city;
@@ -382,13 +220,7 @@ const validate = (p) => {
382
220
  if (!p.city) errors.value.push("city");
383
221
  if (!p.country) errors.value.push("country");
384
222
  if (!/^\d{3,4}$/.test(`${p.cvv}`)) errors.value.push("cvv");
385
- const cleanCardNumber = p.cardNumber.replace(/\s+/g, "");
386
- // Validate card number based on type and length
387
- const isValidCard =
388
- cleanCardNumber.match(/^4\d{15}$/) || // Visa (16 digits)
389
- cleanCardNumber.match(/^5[1-5]\d{14}$/) || // Mastercard (16 digits)
390
- cleanCardNumber.match(/^3[47]\d{13}$/); // AMEX (15 digits)
391
- if (!isValidCard) errors.value.push("cardNumber");
223
+ if (!/^[345]\d{14,15}$/.test(p.cardNumber)) errors.value.push("cardNumber");
392
224
  if (!p.expYear) errors.value.push("expYear");
393
225
  if (!p.expMonth) errors.value.push("expMonth");
394
226
  if (!p.expMonth) errors.value.push("expMonth");
@@ -397,30 +229,12 @@ const validate = (p) => {
397
229
 
398
230
  const handleCreditCardUpdate = (event) => {
399
231
  const value = event.target.value.replace(/\D/g, "");
400
-
401
- // Determine max length based on card type
402
- let maxLength = 16; // Default for Visa/Mastercard
403
- if (value.startsWith("3")) {
404
- maxLength = 15; // AMEX
405
- } else if (value.startsWith("4") || value.startsWith("5")) {
406
- maxLength = 16; // Visa/Mastercard
407
- }
408
-
409
- const subs = value.substring(0, maxLength);
232
+ const subs = value.substring(0, 16);
410
233
  const cardInfo = validateCard(subs);
411
-
412
- // Store clean number (without spaces) in profile
413
- profile.value.cardNumber = subs;
414
- // Display formatted number in input
415
- displayCardNumber.value = cardInfo.formatted;
234
+ profile.value.cardNumber = cardInfo.formatted;
416
235
  };
417
236
 
418
237
  function done() {
419
- // Clear state if country is not US
420
- if (profile.value.country !== "US") {
421
- profile.value.state = "";
422
- }
423
-
424
238
  ui.logger.Info("Created profile", profile.value);
425
239
  if (validate(profile.value) !== true) return;
426
240
  ui.toggleModal("");