@necrolab/dashboard 0.5.15 → 0.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/api.js +2 -3
- package/eslint.config.js +46 -0
- package/index.html +2 -1
- package/package.json +5 -2
- package/src/App.vue +140 -170
- package/src/assets/css/base/mixins.scss +72 -0
- package/src/assets/css/base/reset.scss +0 -2
- package/src/assets/css/base/scroll.scss +43 -36
- package/src/assets/css/base/typography.scss +9 -10
- package/src/assets/css/base/variables.scss +43 -0
- package/src/assets/css/components/accessibility.scss +37 -0
- package/src/assets/css/components/buttons.scss +58 -15
- package/src/assets/css/components/forms.scss +31 -32
- package/src/assets/css/components/headers.scss +12 -20
- package/src/assets/css/components/modals.scss +2 -2
- package/src/assets/css/components/search-groups.scss +28 -22
- package/src/assets/css/components/tables.scss +5 -7
- package/src/assets/css/components/toasts.scss +7 -7
- package/src/assets/css/components/utilities.scss +220 -0
- package/src/assets/css/main.scss +66 -77
- package/src/components/Auth/LoginForm.vue +5 -84
- package/src/components/Editors/Account/Account.vue +8 -10
- package/src/components/Editors/Account/AccountCreator.vue +28 -59
- package/src/components/Editors/Account/AccountView.vue +38 -86
- package/src/components/Editors/Account/CreateAccount.vue +8 -50
- package/src/components/Editors/Profile/CreateProfile.vue +74 -131
- package/src/components/Editors/Profile/Profile.vue +15 -17
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +16 -60
- package/src/components/Editors/Profile/ProfileView.vue +46 -96
- package/src/components/Editors/TagLabel.vue +16 -55
- package/src/components/Editors/TagToggle.vue +20 -8
- package/src/components/Filter/Filter.vue +62 -75
- package/src/components/Filter/FilterPreview.vue +161 -135
- package/src/components/Filter/PriceSortToggle.vue +36 -43
- package/src/components/Table/Header.vue +1 -1
- package/src/components/Table/Table.vue +45 -51
- package/src/components/Tasks/CheckStock.vue +7 -16
- package/src/components/Tasks/Controls/DesktopControls.vue +15 -60
- package/src/components/Tasks/Controls/MobileControls.vue +5 -20
- package/src/components/Tasks/CreateTaskAXS.vue +20 -118
- package/src/components/Tasks/CreateTaskTM.vue +33 -189
- package/src/components/Tasks/EventDetailRow.vue +21 -0
- package/src/components/Tasks/MassEdit.vue +6 -16
- package/src/components/Tasks/QuickSettings.vue +140 -216
- package/src/components/Tasks/ScrapeVenue.vue +4 -13
- package/src/components/Tasks/Stats.vue +19 -38
- package/src/components/Tasks/Task.vue +65 -268
- package/src/components/Tasks/TaskLabel.vue +9 -3
- package/src/components/Tasks/TaskView.vue +43 -63
- package/src/components/Tasks/Utilities.vue +10 -44
- package/src/components/Tasks/ViewTask.vue +23 -107
- package/src/components/icons/Close.vue +2 -8
- package/src/components/icons/Gear.vue +8 -8
- package/src/components/icons/Hash.vue +5 -0
- package/src/components/icons/Key.vue +2 -8
- package/src/components/icons/Pencil.vue +2 -8
- package/src/components/icons/Profile.vue +2 -8
- package/src/components/icons/Sell.vue +2 -8
- package/src/components/icons/Spinner.vue +4 -7
- package/src/components/icons/SquareCheck.vue +2 -8
- package/src/components/icons/SquareUncheck.vue +2 -8
- package/src/components/icons/Wildcard.vue +2 -8
- package/src/components/icons/index.js +3 -1
- package/src/components/ui/ActionButtonGroup.vue +113 -52
- package/src/components/ui/BalanceIndicator.vue +60 -0
- package/src/components/ui/EmptyState.vue +24 -0
- package/src/components/ui/EnableDisableToggle.vue +23 -0
- package/src/components/ui/FormField.vue +48 -48
- package/src/components/ui/IconLabel.vue +23 -0
- package/src/components/ui/InfoRow.vue +21 -54
- package/src/components/ui/Modal.vue +89 -56
- package/src/components/ui/Navbar.vue +60 -41
- package/src/components/ui/ReadonlyFieldsSection.vue +31 -0
- package/src/components/ui/ReconnectIndicator.vue +111 -124
- package/src/components/ui/SectionCard.vue +6 -14
- package/src/components/ui/Splash.vue +2 -10
- package/src/components/ui/StatusBadge.vue +26 -28
- package/src/components/ui/TaskToggle.vue +54 -0
- package/src/components/ui/controls/CountryChooser.vue +27 -64
- package/src/components/ui/controls/EyeToggle.vue +1 -1
- package/src/components/ui/controls/atomic/Checkbox.vue +40 -121
- package/src/components/ui/controls/atomic/Dropdown.vue +103 -139
- package/src/components/ui/controls/atomic/MultiDropdown.vue +71 -119
- package/src/components/ui/controls/atomic/Switch.vue +21 -84
- package/src/composables/useColorMapping.js +15 -0
- package/src/composables/useCopyToClipboard.js +1 -1
- package/src/composables/useDateFormatting.js +21 -0
- package/src/composables/useDeviceDetection.js +14 -0
- package/src/composables/useDropdownPosition.js +3 -4
- package/src/composables/useDynamicTableHeight.js +31 -0
- package/src/composables/useRowSelection.js +0 -3
- package/src/composables/useTicketPricing.js +16 -0
- package/src/composables/useWindowDimensions.js +21 -0
- package/src/libs/Filter.js +14 -20
- package/src/libs/panzoom.js +1 -5
- package/src/libs/utils/array.js +60 -0
- package/src/{stores/utils.js → libs/utils/dataGeneration.js} +2 -250
- package/src/libs/utils/eventUrl.js +40 -0
- package/src/libs/utils/string.js +28 -0
- package/src/libs/utils/time.js +20 -0
- package/src/libs/utils/validation.js +88 -0
- package/src/main.js +0 -2
- package/src/stores/connection.js +1 -4
- package/src/stores/logger.js +6 -12
- package/src/stores/sampleData.js +1 -2
- package/src/stores/ui.js +59 -36
- package/src/views/Accounts.vue +13 -24
- package/src/views/Console.vue +70 -172
- package/src/views/Editor.vue +211 -379
- package/src/views/FilterBuilder.vue +188 -371
- package/src/views/Login.vue +3 -28
- package/src/views/Profiles.vue +8 -15
- package/src/views/Tasks.vue +49 -36
- package/tailwind.config.js +82 -71
- package/workbox-config.cjs +47 -5
- package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2438
- package/exit +0 -209
- package/run +0 -177
- package/src/assets/css/base/color-fallbacks.scss +0 -10
- package/switch-branch.sh +0 -41
- /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
|
@@ -9,21 +9,17 @@
|
|
|
9
9
|
<div>
|
|
10
10
|
<div class="my-3 grid grid-cols-12 gap-3">
|
|
11
11
|
<!-- Profile tag -->
|
|
12
|
-
<
|
|
13
|
-
<label class="label-override mb-2">
|
|
14
|
-
Profile Tag
|
|
15
|
-
<TagIcon />
|
|
16
|
-
</label>
|
|
12
|
+
<FormField label="Profile Tag" :icon="TagIcon" z-index="0" class="col-span-12 md:col-span-4" noWrapper>
|
|
17
13
|
<Dropdown
|
|
18
14
|
:class="`input-default dropdown w-full`"
|
|
19
15
|
:default="ui.profile.tags[0]"
|
|
20
16
|
:options="ui.profile.tags"
|
|
21
|
-
:onClick="(f) => (
|
|
17
|
+
:onClick="(f) => (formProfile.tag = f)"
|
|
22
18
|
:capitalize="true" />
|
|
23
|
-
</
|
|
19
|
+
</FormField>
|
|
24
20
|
|
|
25
21
|
<!-- Card Number -->
|
|
26
|
-
<FormField label="Card Number" :icon="CartIcon" :error="errors.includes('cardNumber')" z-index="0" class="col-span-8">
|
|
22
|
+
<FormField label="Card Number" :icon="CartIcon" :error="errors.includes('cardNumber')" z-index="0" class="col-span-12 md:col-span-8">
|
|
27
23
|
<input
|
|
28
24
|
ref="cardNumberInput"
|
|
29
25
|
placeholder="Enter card number"
|
|
@@ -35,51 +31,39 @@
|
|
|
35
31
|
</FormField>
|
|
36
32
|
|
|
37
33
|
<!-- Country chooser -->
|
|
38
|
-
<
|
|
39
|
-
<label class="label-override mb-2">
|
|
40
|
-
Country
|
|
41
|
-
<StadiumIcon />
|
|
42
|
-
</label>
|
|
34
|
+
<FormField label="Country" :icon="StadiumIcon" z-index="0" class="col-span-12 md:col-span-2" noWrapper>
|
|
43
35
|
<ProfileCountryChooser
|
|
44
|
-
class="h-
|
|
45
|
-
:value="
|
|
36
|
+
class="h-10"
|
|
37
|
+
:value="formProfile.country"
|
|
46
38
|
:onClick="chooseCountry"
|
|
47
39
|
:disabled="true" />
|
|
48
|
-
</
|
|
40
|
+
</FormField>
|
|
49
41
|
|
|
50
42
|
<!-- Exp Year -->
|
|
51
|
-
<
|
|
52
|
-
<label class="label-override mb-2">
|
|
53
|
-
Expiry Year
|
|
54
|
-
<TimerIcon />
|
|
55
|
-
</label>
|
|
43
|
+
<FormField label="Expiry Year" :icon="TimerIcon" :error="errors.includes('expYear')" z-index="0" class="col-span-6 md:col-span-5" noWrapper>
|
|
56
44
|
<Dropdown
|
|
57
45
|
:class="`input-default dropdown w-full ${errors.includes('expYear') ? 'error' : ''}`"
|
|
58
46
|
default="Expiry Year"
|
|
59
47
|
:value="
|
|
60
|
-
|
|
61
|
-
? '20' +
|
|
62
|
-
:
|
|
63
|
-
?
|
|
48
|
+
formProfile.expYear && !formProfile?.expYear?.startsWith('20')
|
|
49
|
+
? '20' + formProfile.expYear
|
|
50
|
+
: formProfile.expYear
|
|
51
|
+
? formProfile.expYear
|
|
64
52
|
: undefined
|
|
65
53
|
"
|
|
66
54
|
:options="['2025', '2026', '2027', '2028', '2029', '2030', '2031']"
|
|
67
|
-
:onClick="(f) => (
|
|
68
|
-
</
|
|
55
|
+
:onClick="(f) => (formProfile.expYear = f)" />
|
|
56
|
+
</FormField>
|
|
69
57
|
|
|
70
58
|
<!-- Exp Month -->
|
|
71
|
-
<
|
|
72
|
-
<label class="label-override mb-2">
|
|
73
|
-
Expiry Month
|
|
74
|
-
<TimerIcon />
|
|
75
|
-
</label>
|
|
59
|
+
<FormField label="Expiry Month" :icon="TimerIcon" :error="errors.includes('expMonth')" z-index="0" class="col-span-6 md:col-span-5" noWrapper>
|
|
76
60
|
<Dropdown
|
|
77
61
|
:class="`input-default dropdown w-full ${errors.includes('expMonth') ? 'error' : ''}`"
|
|
78
62
|
default="Expiry Month"
|
|
79
|
-
:value="
|
|
63
|
+
:value="formProfile.expMonth ? formProfile.expMonth : undefined"
|
|
80
64
|
:options="['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']"
|
|
81
|
-
:onClick="(f) => (
|
|
82
|
-
</
|
|
65
|
+
:onClick="(f) => (formProfile.expMonth = f)" />
|
|
66
|
+
</FormField>
|
|
83
67
|
|
|
84
68
|
<!-- CVV -->
|
|
85
69
|
<FormField label="CVV" :icon="ShieldIcon" :error="errors.includes('cvv')" z-index="0" class="col-span-6 md:col-span-4">
|
|
@@ -89,55 +73,45 @@
|
|
|
89
73
|
max="9999"
|
|
90
74
|
maxlength="4"
|
|
91
75
|
minlength="3"
|
|
92
|
-
v-model="
|
|
76
|
+
v-model="formProfile.cvv" />
|
|
93
77
|
</FormField>
|
|
94
78
|
|
|
95
79
|
<!-- City -->
|
|
96
80
|
<FormField label="City" :icon="StadiumIcon" :error="errors.includes('city')" z-index="0" class="col-span-6 md:col-span-4">
|
|
97
|
-
<input placeholder="Denver" v-model="
|
|
81
|
+
<input placeholder="Denver" v-model="formProfile.city" />
|
|
98
82
|
</FormField>
|
|
99
83
|
|
|
100
84
|
<!-- State -->
|
|
101
|
-
<
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
:options="usStates"
|
|
112
|
-
:allowDefault="false"
|
|
113
|
-
rightAmount="right-2"
|
|
114
|
-
:value="profile.state" />
|
|
115
|
-
</div>
|
|
85
|
+
<FormField label="State" :icon="SandclockIcon" z-index="0" class="col-span-6 md:col-span-4" noWrapper>
|
|
86
|
+
<Dropdown
|
|
87
|
+
v-if="formProfile.country === 'US'"
|
|
88
|
+
class="input-default w-full"
|
|
89
|
+
default="Select State"
|
|
90
|
+
:onClick="(state) => (formProfile.state = state)"
|
|
91
|
+
:options="usStates"
|
|
92
|
+
:allowDefault="false"
|
|
93
|
+
rightAmount="right-2"
|
|
94
|
+
:value="formProfile.state" />
|
|
116
95
|
<div v-else class="input-default">
|
|
117
96
|
<input disabled placeholder="N/A" value="" />
|
|
118
97
|
</div>
|
|
119
|
-
</
|
|
98
|
+
</FormField>
|
|
120
99
|
|
|
121
100
|
<!-- Zip -->
|
|
122
101
|
<FormField label="Zip" :icon="KeyIcon" :error="errors.includes('zipCode')" z-index="0" class="col-span-6 md:col-span-4">
|
|
123
|
-
<input placeholder="10005" type="number" min="1" max="12" v-model="
|
|
102
|
+
<input placeholder="10005" type="number" min="1" max="12" v-model="formProfile.zipCode" />
|
|
124
103
|
</FormField>
|
|
125
104
|
|
|
126
105
|
<!-- Address -->
|
|
127
106
|
<FormField label="Address" :icon="HandIcon" :error="errors.includes('address')" z-index="0" class="col-span-6 md:col-span-4">
|
|
128
|
-
<input placeholder="100 5th Avenue" v-model="
|
|
107
|
+
<input placeholder="100 5th Avenue" v-model="formProfile.address" />
|
|
129
108
|
</FormField>
|
|
130
109
|
|
|
131
110
|
<!-- Generate -->
|
|
132
|
-
<
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
</label>
|
|
137
|
-
<div class="input-default mt-2 flex h-10 w-full items-center">
|
|
138
|
-
<button
|
|
139
|
-
@click="generate"
|
|
140
|
-
class="flex w-full items-center justify-center gap-2 text-xs text-white">
|
|
111
|
+
<FormField label="Fake ID" :icon="WildcardIcon" z-index="0" class="col-span-6 md:col-span-4">
|
|
112
|
+
<button
|
|
113
|
+
@click="generate"
|
|
114
|
+
class="flex h-full w-full items-center justify-center gap-2 text-xs text-white">
|
|
141
115
|
<svg
|
|
142
116
|
xmlns="http://www.w3.org/2000/svg"
|
|
143
117
|
width="14"
|
|
@@ -153,80 +127,49 @@
|
|
|
153
127
|
<line x1="17" y1="2" x2="17" y2="6" />
|
|
154
128
|
</svg>
|
|
155
129
|
<span>Generate</span>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
</div>
|
|
130
|
+
</button>
|
|
131
|
+
</FormField>
|
|
159
132
|
</div>
|
|
160
133
|
|
|
161
134
|
<!-- Readonly fields when editing -->
|
|
162
|
-
<
|
|
163
|
-
<div v-if="ui.currentlyEditing.tags && ui.currentlyEditing.tags.length > 0" class="col-span-6">
|
|
164
|
-
<label class="label-override mb-2">Tags</label>
|
|
165
|
-
<div class="flex gap-2 flex-wrap">
|
|
166
|
-
<TagLabel v-for="tag in ui.currentlyEditing.tags" :key="tag" :text="tag" />
|
|
167
|
-
</div>
|
|
168
|
-
</div>
|
|
169
|
-
<div class="col-span-6">
|
|
170
|
-
<label class="label-override mb-2">Status</label>
|
|
171
|
-
<div class="flex items-center gap-3 h-10">
|
|
172
|
-
<StatusBadge :enabled="ui.currentlyEditing.enabled" size="large" />
|
|
173
|
-
<span class="text-sm font-medium" :class="ui.currentlyEditing.enabled ? 'text-green-400' : 'text-red-400'">
|
|
174
|
-
{{ ui.currentlyEditing.enabled ? 'Enabled' : 'Disabled' }}
|
|
175
|
-
</span>
|
|
176
|
-
</div>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
135
|
+
<ReadonlyFieldsSection v-if="ui.currentlyEditing?.profileName" :data="ui.currentlyEditing" />
|
|
179
136
|
</div>
|
|
180
137
|
|
|
181
|
-
<button
|
|
182
|
-
class="button-default ml-auto mt-4 flex w-48 items-center justify-center gap-x-2 bg-dark-400 text-xs"
|
|
183
|
-
@click="done()">
|
|
138
|
+
<button class="btn-modal ml-auto mt-4 w-48" @click="done()">
|
|
184
139
|
Save
|
|
185
|
-
<EditIcon />
|
|
140
|
+
<EditIcon class="ml-2" />
|
|
186
141
|
</button>
|
|
187
142
|
</Modal>
|
|
188
143
|
</template>
|
|
189
|
-
<style lang="scss" scoped>
|
|
190
|
-
.label-override {
|
|
191
|
-
@apply flex items-center;
|
|
192
|
-
color: #e1e1e4 !important;
|
|
193
|
-
|
|
194
|
-
svg {
|
|
195
|
-
@apply ml-2;
|
|
196
|
-
|
|
197
|
-
path {
|
|
198
|
-
fill: #e1e1e4 !important;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
</style>
|
|
203
144
|
<script setup>
|
|
204
145
|
import Modal from "@/components/ui/Modal.vue";
|
|
205
146
|
import FormField from "@/components/ui/FormField.vue";
|
|
206
147
|
import {
|
|
207
|
-
MailIcon,
|
|
208
148
|
CartIcon,
|
|
209
149
|
ShieldIcon,
|
|
210
150
|
StadiumIcon,
|
|
211
151
|
KeyIcon,
|
|
212
152
|
HandIcon,
|
|
213
|
-
ProfileIcon,
|
|
214
153
|
SandclockIcon,
|
|
215
154
|
TimerIcon,
|
|
216
155
|
TagIcon,
|
|
217
156
|
WildcardIcon
|
|
218
157
|
} from "@/components/icons";
|
|
219
158
|
import { EditIcon } from "@/components/icons";
|
|
220
|
-
import
|
|
221
|
-
import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
159
|
+
import ReadonlyFieldsSection from "@/components/ui/ReadonlyFieldsSection.vue";
|
|
222
160
|
import ProfileCountryChooser from "@/components/Editors/Profile/ProfileCountryChooser.vue";
|
|
223
161
|
import { useUIStore } from "@/stores/ui";
|
|
224
162
|
import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
|
|
225
|
-
import { ref,
|
|
226
|
-
import { fakeId } from "@/
|
|
227
|
-
import { validateCard } from "@/
|
|
228
|
-
|
|
229
|
-
|
|
163
|
+
import { ref, watch, nextTick, onMounted } from "vue";
|
|
164
|
+
import { fakeId } from "@/libs/utils/dataGeneration";
|
|
165
|
+
import { validateCard } from "@/libs/utils/validation";
|
|
166
|
+
|
|
167
|
+
defineProps({
|
|
168
|
+
profile: {
|
|
169
|
+
type: Object,
|
|
170
|
+
default: null
|
|
171
|
+
}
|
|
172
|
+
});
|
|
230
173
|
const errors = ref([]);
|
|
231
174
|
const ui = useUIStore();
|
|
232
175
|
|
|
@@ -283,7 +226,7 @@ const usStates = [
|
|
|
283
226
|
"WY"
|
|
284
227
|
];
|
|
285
228
|
const cardNumberInput = ref(null);
|
|
286
|
-
const
|
|
229
|
+
const formProfile = ref({
|
|
287
230
|
cvv: "",
|
|
288
231
|
cardNumber: "",
|
|
289
232
|
city: "",
|
|
@@ -293,15 +236,15 @@ const profile = ref({
|
|
|
293
236
|
zipCode: ""
|
|
294
237
|
});
|
|
295
238
|
|
|
296
|
-
if (ui.currentlyEditing?.profileName)
|
|
239
|
+
if (ui.currentlyEditing?.profileName) formProfile.value = ui.currentlyEditing;
|
|
297
240
|
|
|
298
241
|
// Reactive display value for the formatted card number
|
|
299
242
|
const displayCardNumber = ref("");
|
|
300
243
|
|
|
301
244
|
// Initialize display card number with formatting
|
|
302
245
|
const initializeCardNumberDisplay = () => {
|
|
303
|
-
if (
|
|
304
|
-
const cleanNumber =
|
|
246
|
+
if (formProfile.value.cardNumber) {
|
|
247
|
+
const cleanNumber = formProfile.value.cardNumber.replace(/\s+/g, "");
|
|
305
248
|
if (cleanNumber) {
|
|
306
249
|
const cardInfo = validateCard(cleanNumber);
|
|
307
250
|
displayCardNumber.value = cardInfo.formatted;
|
|
@@ -311,8 +254,8 @@ const initializeCardNumberDisplay = () => {
|
|
|
311
254
|
|
|
312
255
|
// Format card number display on focus
|
|
313
256
|
const formatCardNumberDisplay = () => {
|
|
314
|
-
if (
|
|
315
|
-
const cleanNumber =
|
|
257
|
+
if (formProfile.value.cardNumber) {
|
|
258
|
+
const cleanNumber = formProfile.value.cardNumber.replace(/\s+/g, "");
|
|
316
259
|
if (cleanNumber) {
|
|
317
260
|
const cardInfo = validateCard(cleanNumber);
|
|
318
261
|
displayCardNumber.value = cardInfo.formatted;
|
|
@@ -322,7 +265,7 @@ const formatCardNumberDisplay = () => {
|
|
|
322
265
|
|
|
323
266
|
// Watch for changes in profile.cardNumber to sync with display
|
|
324
267
|
watch(
|
|
325
|
-
() =>
|
|
268
|
+
() => formProfile.value.cardNumber,
|
|
326
269
|
(newValue) => {
|
|
327
270
|
if (newValue) {
|
|
328
271
|
const cleanNumber = newValue.replace(/\s+/g, "");
|
|
@@ -345,16 +288,16 @@ onMounted(() => {
|
|
|
345
288
|
|
|
346
289
|
const generate = () => {
|
|
347
290
|
const fake = fakeId();
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
291
|
+
formProfile.value.city = fake.city;
|
|
292
|
+
formProfile.value.zipCode = fake?.zipCode;
|
|
293
|
+
formProfile.value.address = fake.address;
|
|
294
|
+
formProfile.value.state = fake.state;
|
|
295
|
+
formProfile.value.country = "US";
|
|
353
296
|
};
|
|
354
297
|
|
|
355
298
|
const chooseCountry = (f) => {
|
|
356
|
-
|
|
357
|
-
if (f !== "US")
|
|
299
|
+
formProfile.value.country = f;
|
|
300
|
+
if (f !== "US") formProfile.value.state = "";
|
|
358
301
|
};
|
|
359
302
|
|
|
360
303
|
const validate = (p) => {
|
|
@@ -395,20 +338,20 @@ const handleCreditCardUpdate = (event) => {
|
|
|
395
338
|
const cardInfo = validateCard(subs);
|
|
396
339
|
|
|
397
340
|
// Store clean number (without spaces) in profile
|
|
398
|
-
|
|
341
|
+
formProfile.value.cardNumber = subs;
|
|
399
342
|
// Display formatted number in input
|
|
400
343
|
displayCardNumber.value = cardInfo.formatted;
|
|
401
344
|
};
|
|
402
345
|
|
|
403
346
|
function done() {
|
|
404
347
|
// Clear state if country is not US
|
|
405
|
-
if (
|
|
406
|
-
|
|
348
|
+
if (formProfile.value.country !== "US") {
|
|
349
|
+
formProfile.value.state = "";
|
|
407
350
|
}
|
|
408
351
|
|
|
409
|
-
ui.logger.Info("Created profile",
|
|
410
|
-
if (validate(
|
|
352
|
+
ui.logger.Info("Created profile", formProfile.value);
|
|
353
|
+
if (validate(formProfile.value) !== true) return;
|
|
411
354
|
ui.toggleModal("");
|
|
412
|
-
ui.addProfile(
|
|
355
|
+
ui.addProfile(formProfile.value);
|
|
413
356
|
}
|
|
414
357
|
</script>
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Row
|
|
3
|
-
class="relative grid-cols-
|
|
3
|
+
class="relative h-16 grid-cols-4 sm:grid-cols-5 md:grid-cols-7 lg:grid-cols-8 text-white"
|
|
4
4
|
@click="ui.setOpenContextMenu('')"
|
|
5
5
|
@click.right.prevent="ui.setOpenContextMenu('')"
|
|
6
6
|
@dblclick="handleDoubleClick"
|
|
7
7
|
@touchstart="handleTouchStart"
|
|
8
8
|
@touchend="handleTouchEnd">
|
|
9
|
-
<div class="col-span-3
|
|
9
|
+
<div class="col-span-2 sm:col-span-2 md:col-span-3 lg:col-span-2 flex">
|
|
10
10
|
<Checkbox
|
|
11
11
|
class="ml-0 mr-4"
|
|
12
12
|
:toggled="props.profile.selected"
|
|
13
13
|
@valueUpdate="ui.toggleProfileSelected(props.profile.id)" />
|
|
14
|
-
<h4 class="mx-auto text-white">
|
|
14
|
+
<h4 class="mx-auto text-center text-white">
|
|
15
15
|
{{ props.profile.profileName }}
|
|
16
16
|
</h4>
|
|
17
17
|
</div>
|
|
18
|
-
<div class="col-span-1 lg:col-span-2">
|
|
19
|
-
<h4 class="flex items-center justify-center gap-2 text-white">
|
|
18
|
+
<div class="col-span-1 hidden md:block lg:col-span-2">
|
|
19
|
+
<h4 class="flex items-center justify-center gap-2 text-center text-white">
|
|
20
20
|
<span class="hidden sm:block">
|
|
21
21
|
{{
|
|
22
22
|
props.profile.privacy
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
<img class="h-6 w-6" :src="getAccountType()" />
|
|
30
30
|
</h4>
|
|
31
31
|
</div>
|
|
32
|
-
<div class="col-span-1">
|
|
33
|
-
<h4 class="text-white">{{ expDate() }}</h4>
|
|
32
|
+
<div class="col-span-1 hidden md:block">
|
|
33
|
+
<h4 class="text-center text-white">{{ expDate() }}</h4>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="col-span-1 flex justify-center">
|
|
36
36
|
<StatusBadge :enabled="props.profile.enabled" size="small" />
|
|
37
37
|
</div>
|
|
38
38
|
|
|
39
39
|
<div class="col-span-1 hidden lg:block">
|
|
40
|
-
<h4 class="flex justify-center gap-1 text-white">
|
|
40
|
+
<h4 class="flex justify-center gap-1 text-center text-white">
|
|
41
41
|
<TagLabel v-for="tag in props.profile.tags" :key="tag" :text="tag" />
|
|
42
42
|
</h4>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
|
-
<div class="col-span-1 flex">
|
|
45
|
+
<div class="col-span-1 sm:col-span-1 flex">
|
|
46
46
|
<ActionButtonGroup>
|
|
47
47
|
<li>
|
|
48
48
|
<button @click="edit">
|
|
@@ -66,26 +66,24 @@
|
|
|
66
66
|
</div>
|
|
67
67
|
</Row>
|
|
68
68
|
</template>
|
|
69
|
-
<style lang="scss" scoped>
|
|
70
|
-
h4 {
|
|
71
|
-
@apply text-center;
|
|
72
|
-
}
|
|
73
|
-
</style>
|
|
74
69
|
<script setup>
|
|
75
70
|
import { Row } from "@/components/Table";
|
|
76
|
-
import {
|
|
71
|
+
import { TrashIcon, EditIcon } from "@/components/icons";
|
|
77
72
|
import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
|
|
78
73
|
import StatusBadge from "@/components/ui/StatusBadge.vue";
|
|
79
74
|
import ActionButtonGroup from "@/components/ui/ActionButtonGroup.vue";
|
|
80
75
|
import { useUIStore } from "@/stores/ui";
|
|
81
|
-
import { validateCard } from "@/
|
|
76
|
+
import { validateCard } from "@/libs/utils/validation";
|
|
82
77
|
import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
83
78
|
import { useRowSelection } from "@/composables/useRowSelection";
|
|
84
79
|
|
|
85
80
|
const ui = useUIStore();
|
|
86
81
|
|
|
87
82
|
const props = defineProps({
|
|
88
|
-
profile: {
|
|
83
|
+
profile: {
|
|
84
|
+
type: Object,
|
|
85
|
+
required: true
|
|
86
|
+
}
|
|
89
87
|
});
|
|
90
88
|
|
|
91
89
|
const getAccountType = () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div class="dropdown input-default
|
|
3
|
+
<div class="dropdown input-default h-10 w-12 md:h-10 flex justify-center items-center p-0 bg-dark-550 rounded-lg [background-clip:border-box]" ref="dropdownRef">
|
|
4
4
|
<span @click="toggleOpen" class="flex justify-between items-center z-50 text-white">
|
|
5
5
|
<div class="flex gap-3 justify-center">
|
|
6
6
|
<img class="w-5" :src="`/flags/${current?.toLowerCase()}.svg`" />
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<Teleport to="body">
|
|
10
10
|
<div
|
|
11
11
|
v-if="open && !disabled"
|
|
12
|
-
class="
|
|
12
|
+
class="min-w-20 bg-dark-400 border border-dark-650 rounded-lg shadow-2xl z-50 p-2 [max-height:192px] overflow-y-auto custom-scrollbar-y"
|
|
13
13
|
:style="menuStyle"
|
|
14
14
|
@click.stop
|
|
15
15
|
@wheel.stop
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
<div
|
|
18
18
|
v-for="(country, i) in countries"
|
|
19
19
|
v-bind:key="country"
|
|
20
|
-
:class="`cursor-pointer
|
|
20
|
+
:class="`px-3 py-2 text-sm text-white cursor-pointer rounded-md ${i === 0 ? '' : 'my-2'}`"
|
|
21
21
|
@click="set(country)">
|
|
22
|
-
<div class="flex
|
|
22
|
+
<div class="flex items-center justify-center gap-3 smooth-hover">
|
|
23
23
|
<span class="text-sm">{{ country }}</span>
|
|
24
24
|
<img class="w-5 ml-3" :src="`/flags/${country?.toLowerCase()}.svg`" />
|
|
25
25
|
</div>
|
|
@@ -40,9 +40,18 @@ const open = ref(false);
|
|
|
40
40
|
const dropdownRef = ref(null);
|
|
41
41
|
|
|
42
42
|
const props = defineProps({
|
|
43
|
-
value: {
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
value: {
|
|
44
|
+
type: String,
|
|
45
|
+
default: 'US'
|
|
46
|
+
},
|
|
47
|
+
onClick: {
|
|
48
|
+
type: Function,
|
|
49
|
+
required: true
|
|
50
|
+
},
|
|
51
|
+
disabled: {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: false
|
|
54
|
+
}
|
|
46
55
|
});
|
|
47
56
|
|
|
48
57
|
const current = ref(props.value || "US");
|
|
@@ -82,56 +91,3 @@ watch(
|
|
|
82
91
|
(n) => (current.value = n)
|
|
83
92
|
);
|
|
84
93
|
</script>
|
|
85
|
-
|
|
86
|
-
<style scoped>
|
|
87
|
-
.special-dropdown {
|
|
88
|
-
@apply min-w-20;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.small-dropdown {
|
|
92
|
-
@apply h-10 !important;
|
|
93
|
-
background-clip: border-box !important;
|
|
94
|
-
/* border-radius: 100% !important; */
|
|
95
|
-
padding: 0;
|
|
96
|
-
width: 3em !important;
|
|
97
|
-
display: flex;
|
|
98
|
-
justify-items: center;
|
|
99
|
-
justify-content: center;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@media (min-width: 768px) {
|
|
103
|
-
.small-dropdown {
|
|
104
|
-
height: 40px !important; /* Match input-default responsive height */
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.dropdown-content-portal {
|
|
109
|
-
@apply bg-dark-400 border border-dark-650 rounded-lg shadow-2xl z-50;
|
|
110
|
-
padding: 0.5rem;
|
|
111
|
-
max-height: 192px !important;
|
|
112
|
-
overflow-y: auto !important;
|
|
113
|
-
overscroll-behavior: contain !important;
|
|
114
|
-
touch-action: pan-y !important;
|
|
115
|
-
-webkit-overflow-scrolling: touch !important;
|
|
116
|
-
scrollbar-width: none;
|
|
117
|
-
-ms-overflow-style: none;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.dropdown-content-portal::-webkit-scrollbar {
|
|
121
|
-
display: none;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.dropdown-content-portal > div {
|
|
125
|
-
@apply px-3 py-2 text-sm text-white cursor-pointer;
|
|
126
|
-
border-radius: 6px;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.dropdown-content-portal > div:hover {
|
|
130
|
-
/* Removed hover background */
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.dropdown-content-portal > div .flex {
|
|
134
|
-
@apply items-center justify-center;
|
|
135
|
-
gap: 0.75rem;
|
|
136
|
-
}
|
|
137
|
-
</style>
|