@necrolab/dashboard 0.5.14 → 0.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +119 -0
- package/src/assets/css/components/modals.scss +2 -2
- package/src/assets/css/components/search-groups.scss +28 -19
- 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 +72 -75
- 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 +61 -12
- 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 -42
- 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 +78 -37
- 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 +102 -95
- package/src/components/ui/controls/atomic/MultiDropdown.vue +72 -94
- 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 +5 -6
- 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 +17 -31
- package/src/views/Console.vue +76 -176
- package/src/views/Editor.vue +217 -383
- package/src/views/FilterBuilder.vue +190 -373
- package/src/views/Login.vue +3 -28
- package/src/views/Profiles.vue +12 -22
- package/src/views/Tasks.vue +51 -38
- package/tailwind.config.js +82 -71
- package/workbox-config.cjs +47 -5
- package/docs/plans/2026-02-08-tailwind-consolidation.md +0 -2416
- package/exit +0 -209
- package/run +0 -177
- package/switch-branch.sh +0 -41
- /package/public/{reconnect-logo.png → img/reconnect-logo.png} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="modal-mask
|
|
3
|
-
<div class="
|
|
2
|
+
<div class="modal-mask" role="dialog" aria-modal="true" @touchmove.stop>
|
|
3
|
+
<div class="modal-content" ref="target">
|
|
4
4
|
<div class="modal-header">
|
|
5
5
|
<slot name="header" />
|
|
6
|
-
<button @click="ui.toggleModal()" class="btn-icon border-none hover:bg-dark-400">
|
|
6
|
+
<button @click="ui.toggleModal()" class="btn-icon border-none hover:bg-dark-400 ml-auto" aria-label="Close modal">
|
|
7
7
|
<CloseIcon />
|
|
8
8
|
</button>
|
|
9
9
|
</div>
|
|
@@ -54,65 +54,106 @@ onClickOutside(target, (event) => {
|
|
|
54
54
|
if (event.target.classList.contains("modal-mask")) ui.toggleModal();
|
|
55
55
|
});
|
|
56
56
|
</script>
|
|
57
|
-
<style
|
|
57
|
+
<style scoped>
|
|
58
58
|
.modal-mask {
|
|
59
|
-
@apply
|
|
60
|
-
|
|
61
|
-
justify-
|
|
62
|
-
|
|
59
|
+
@apply fixed left-0 top-0;
|
|
60
|
+
@apply flex w-screen overflow-y-auto;
|
|
61
|
+
@apply items-start justify-center;
|
|
62
|
+
@apply p-4 pt-14;
|
|
63
|
+
@apply duration-300 ease-in-out;
|
|
64
|
+
@apply z-modal-mask;
|
|
65
|
+
|
|
66
|
+
/* Background with opacity */
|
|
67
|
+
background-color: rgba(0, 0, 0, 0.85);
|
|
68
|
+
backdrop-filter: blur(8px);
|
|
69
|
+
|
|
70
|
+
/* Height with modern viewport units and fallback */
|
|
63
71
|
height: 100dvh;
|
|
64
|
-
|
|
72
|
+
|
|
73
|
+
/* Touch handling for mobile */
|
|
65
74
|
-webkit-overflow-scrolling: touch;
|
|
66
75
|
touch-action: pan-y !important;
|
|
76
|
+
}
|
|
67
77
|
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
@supports (height: 100dvh) {
|
|
79
|
+
.modal-mask {
|
|
80
|
+
height: 100dvh;
|
|
70
81
|
}
|
|
71
82
|
}
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
@supports not (height: 100dvh) {
|
|
85
|
+
.modal-mask {
|
|
86
|
+
height: 100vh;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
/* Tablet breakpoint */
|
|
91
|
+
@media (max-width: 810px) {
|
|
92
|
+
.modal-mask {
|
|
93
|
+
@apply items-start justify-center;
|
|
94
|
+
@apply p-4 pt-12;
|
|
95
|
+
padding-bottom: 15rem !important;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
80
98
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
99
|
+
/* Mobile portrait breakpoint */
|
|
100
|
+
@media (max-width: 480px) and (orientation: portrait) {
|
|
101
|
+
.modal-mask {
|
|
102
|
+
padding-bottom: 3rem !important;
|
|
84
103
|
}
|
|
104
|
+
}
|
|
85
105
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
106
|
+
.modal-content {
|
|
107
|
+
@apply flex flex-col rounded-lg;
|
|
108
|
+
@apply bg-dark-400 px-5 py-5;
|
|
109
|
+
@apply w-160 mb-80;
|
|
110
|
+
@apply overflow-y-visible;
|
|
111
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.8),
|
|
112
|
+
0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Mobile breakpoint for modal-content */
|
|
116
|
+
@media (max-width: 480px) {
|
|
117
|
+
.modal-content {
|
|
118
|
+
margin-bottom: 25rem;
|
|
89
119
|
}
|
|
90
120
|
}
|
|
91
121
|
|
|
122
|
+
/* Tablet breakpoint for modal-content */
|
|
92
123
|
@media (max-width: 810px) {
|
|
93
|
-
.modal-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
padding: 1rem;
|
|
97
|
-
padding-top: 3rem;
|
|
124
|
+
.modal-content {
|
|
125
|
+
width: calc(100vw - 2rem);
|
|
126
|
+
margin-bottom: 10rem;
|
|
98
127
|
}
|
|
128
|
+
}
|
|
99
129
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
130
|
+
/* Mobile portrait overrides */
|
|
131
|
+
@media (max-width: 480px) and (orientation: portrait) {
|
|
132
|
+
.modal-content {
|
|
133
|
+
margin-bottom: 3rem !important;
|
|
134
|
+
max-height: none !important;
|
|
103
135
|
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.modal-header {
|
|
139
|
+
@apply flex font-bold text-white;
|
|
140
|
+
}
|
|
104
141
|
|
|
142
|
+
.modal-body {
|
|
143
|
+
@apply flex flex-col flex-1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* Tablet breakpoint for modal-body */
|
|
147
|
+
@media (max-width: 810px) {
|
|
105
148
|
.modal-body {
|
|
106
|
-
overflow-y
|
|
107
|
-
flex: 1;
|
|
108
|
-
min-height: 0;
|
|
149
|
+
@apply pb-16 overflow-y-visible min-h-0;
|
|
109
150
|
}
|
|
110
151
|
}
|
|
111
152
|
|
|
112
|
-
/*
|
|
153
|
+
/* Mobile portrait breakpoint for modal-body */
|
|
113
154
|
@media (max-width: 480px) and (orientation: portrait) {
|
|
114
|
-
.
|
|
115
|
-
|
|
155
|
+
.modal-body {
|
|
156
|
+
padding-bottom: 1rem !important;
|
|
116
157
|
}
|
|
117
158
|
}
|
|
118
159
|
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="navbar" :class="{ 'z
|
|
3
|
-
<div :class="['component-container ios-wrapper flex items-center relative px-
|
|
2
|
+
<div class="navbar" :class="{ 'force-z': menuOpen }">
|
|
3
|
+
<div :class="['component-container ios-wrapper flex items-center relative px-3 lg:px-4', { 'ios-wrapper': landscapeIos }]">
|
|
4
4
|
<router-link to="/">
|
|
5
5
|
<img src="@/assets/img/logo_trans.png" class="h-6 lg:h-8 mr-4 z-30 object-cover cursor-pointer" alt="Logo: Necro" />
|
|
6
6
|
</router-link>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
</li>
|
|
32
32
|
</ul>
|
|
33
33
|
|
|
34
|
-
<button class="hidden lg:block ml-auto mr-4 smooth-hover" @click="logout()">
|
|
34
|
+
<button class="hidden lg:block ml-auto mr-4 smooth-hover" @click="logout()" aria-label="Logout">
|
|
35
35
|
<LogoutIcon />
|
|
36
36
|
</button>
|
|
37
37
|
<h4 v-if="ui.profile?.name" class="hidden lg:block text-white text-sm font-medium">
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<div v-else class="h-10 w-10 rounded-full hidden lg:block mx-4 bg-dark-400" />
|
|
51
51
|
<CountryChooser class="hidden lg:block" />
|
|
52
52
|
|
|
53
|
-
<button class="flex lg:hidden ml-auto z-30" @click="toggleMenu">
|
|
53
|
+
<button class="flex lg:hidden ml-auto z-30" @click="toggleMenu" aria-label="Toggle navigation menu" :aria-expanded="menuOpen">
|
|
54
54
|
<MenuIcon />
|
|
55
55
|
</button>
|
|
56
56
|
</div>
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
</ul>
|
|
86
86
|
<CountryChooser class="mx-auto block landscape:hidden mb-auto" />
|
|
87
87
|
<div class="flex mx-auto items-center landscape:mb-0">
|
|
88
|
-
<button class="mr-4" @click="logout()">
|
|
88
|
+
<button class="mr-4" @click="logout()" aria-label="Logout">
|
|
89
89
|
<LogoutIcon />
|
|
90
90
|
</button>
|
|
91
91
|
<h4 class="text-white text-sm font-medium mr-4">
|
|
@@ -111,15 +111,19 @@
|
|
|
111
111
|
</template>
|
|
112
112
|
<style lang="scss" scoped>
|
|
113
113
|
.navbar {
|
|
114
|
-
@apply border-b py-5 fixed w-full
|
|
114
|
+
@apply border-b py-5 fixed w-full;
|
|
115
115
|
top: 0;
|
|
116
116
|
left: 0;
|
|
117
117
|
z-index: 1000;
|
|
118
|
+
background: theme('colors.dark.300 / 0.95');
|
|
119
|
+
backdrop-filter: blur(23px);
|
|
120
|
+
-webkit-backdrop-filter: blur(23px);
|
|
121
|
+
border-color: theme('colors.border');
|
|
118
122
|
|
|
119
123
|
// Consistent padding base
|
|
120
124
|
padding-top: 1.25rem;
|
|
121
125
|
padding-bottom: 1.25rem;
|
|
122
|
-
|
|
126
|
+
|
|
123
127
|
// Only add safe area top padding for portrait notch devices
|
|
124
128
|
@supports (padding-top: env(safe-area-inset-top)) {
|
|
125
129
|
@media (max-device-width: 430px) and (orientation: portrait) {
|
|
@@ -135,7 +139,7 @@
|
|
|
135
139
|
left: 0;
|
|
136
140
|
right: 0;
|
|
137
141
|
height: 100px;
|
|
138
|
-
background:
|
|
142
|
+
background: theme('colors.dark.300');
|
|
139
143
|
backdrop-filter: blur(8px);
|
|
140
144
|
-webkit-backdrop-filter: blur(8px);
|
|
141
145
|
z-index: -1;
|
|
@@ -144,27 +148,38 @@
|
|
|
144
148
|
ul {
|
|
145
149
|
@apply gap-x-4;
|
|
146
150
|
|
|
151
|
+
// Global SVG normalization - force all icons to be identical
|
|
152
|
+
svg {
|
|
153
|
+
width: 20px !important;
|
|
154
|
+
height: 20px !important;
|
|
155
|
+
display: block !important;
|
|
156
|
+
flex-shrink: 0 !important;
|
|
157
|
+
box-sizing: border-box !important;
|
|
158
|
+
}
|
|
159
|
+
|
|
147
160
|
li a {
|
|
148
|
-
@apply flex text-white text-sm items-center rounded-lg
|
|
161
|
+
@apply flex text-white text-sm items-center rounded-lg;
|
|
162
|
+
height: 40px;
|
|
163
|
+
border: 1px solid transparent;
|
|
149
164
|
border-left: 3px solid transparent;
|
|
150
165
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
151
166
|
position: relative;
|
|
152
167
|
|
|
153
168
|
svg {
|
|
154
|
-
@apply mr-2
|
|
169
|
+
@apply mr-2;
|
|
155
170
|
}
|
|
156
171
|
|
|
157
172
|
&.router-link-exact-active {
|
|
158
|
-
border-bottom: 2px solid
|
|
159
|
-
color:
|
|
160
|
-
background:
|
|
173
|
+
border-bottom: 2px solid theme('colors.primary');
|
|
174
|
+
color: theme('colors.primary');
|
|
175
|
+
background: theme('colors.primary / 0.08');
|
|
161
176
|
margin-bottom: -2px;
|
|
162
177
|
|
|
163
178
|
// Mobile styling
|
|
164
179
|
@media (max-width: 1023px) {
|
|
165
|
-
border: 2px solid
|
|
166
|
-
color:
|
|
167
|
-
background:
|
|
180
|
+
border: 2px solid theme('colors.primary');
|
|
181
|
+
color: theme('colors.primary');
|
|
182
|
+
background: theme('colors.primary / 0.08');
|
|
168
183
|
padding: 0.5rem 0.75rem;
|
|
169
184
|
border-radius: 0.5rem;
|
|
170
185
|
margin-bottom: 0;
|
|
@@ -175,26 +190,35 @@
|
|
|
175
190
|
// Desktop mode (lg to xl): icon-only view with perfect centering
|
|
176
191
|
@media (min-width: 1024px) and (max-width: 1279px) {
|
|
177
192
|
li a {
|
|
178
|
-
|
|
179
|
-
|
|
193
|
+
width: 40px;
|
|
194
|
+
height: 40px;
|
|
195
|
+
padding: 0 !important;
|
|
196
|
+
display: flex !important;
|
|
197
|
+
align-items: center !important;
|
|
198
|
+
justify-content: center !important;
|
|
180
199
|
position: relative;
|
|
181
200
|
|
|
182
201
|
// Hide text completely in icon-only mode
|
|
183
202
|
span {
|
|
184
|
-
display: none;
|
|
203
|
+
display: none !important;
|
|
185
204
|
}
|
|
186
205
|
|
|
187
206
|
svg {
|
|
188
|
-
|
|
207
|
+
margin: 0 !important;
|
|
208
|
+
padding: 0 !important;
|
|
209
|
+
position: absolute;
|
|
210
|
+
top: 50%;
|
|
211
|
+
left: 50%;
|
|
189
212
|
transform: translate(-50%, -50%);
|
|
190
|
-
padding: 0;
|
|
191
213
|
}
|
|
192
214
|
|
|
193
215
|
&.router-link-exact-active {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
216
|
+
border: 2px solid theme('colors.primary') !important;
|
|
217
|
+
color: theme('colors.primary') !important;
|
|
218
|
+
background: theme('colors.primary / 0.08') !important;
|
|
219
|
+
border-radius: 0.5rem !important;
|
|
220
|
+
width: 40px !important;
|
|
221
|
+
height: 40px !important;
|
|
198
222
|
}
|
|
199
223
|
}
|
|
200
224
|
}
|
|
@@ -202,7 +226,8 @@
|
|
|
202
226
|
// XL and above: full width with text
|
|
203
227
|
@media (min-width: 1280px) {
|
|
204
228
|
li a {
|
|
205
|
-
@apply px-4
|
|
229
|
+
@apply px-4;
|
|
230
|
+
height: 40px;
|
|
206
231
|
|
|
207
232
|
svg {
|
|
208
233
|
@apply mr-2;
|
|
@@ -212,6 +237,9 @@
|
|
|
212
237
|
}
|
|
213
238
|
}
|
|
214
239
|
|
|
240
|
+
.force-z {
|
|
241
|
+
z-index: 20000;
|
|
242
|
+
}
|
|
215
243
|
|
|
216
244
|
.mobile-menu {
|
|
217
245
|
margin-top: 0;
|
|
@@ -231,17 +259,17 @@
|
|
|
231
259
|
|
|
232
260
|
.version-badge {
|
|
233
261
|
@apply flex items-center gap-x-2 px-3 py-2 rounded-lg border;
|
|
234
|
-
background:
|
|
235
|
-
border-color:
|
|
262
|
+
background: theme('colors.bg-elevated');
|
|
263
|
+
border-color: theme('colors.dark.550');
|
|
236
264
|
|
|
237
265
|
.version-label {
|
|
238
266
|
@apply text-xs font-medium;
|
|
239
|
-
color:
|
|
267
|
+
color: theme('colors.text-muted');
|
|
240
268
|
}
|
|
241
269
|
|
|
242
270
|
.version-number {
|
|
243
271
|
@apply text-xs font-bold;
|
|
244
|
-
color:
|
|
272
|
+
color: theme('colors.primary');
|
|
245
273
|
}
|
|
246
274
|
}
|
|
247
275
|
</style>
|
|
@@ -263,20 +291,11 @@ import { useUIStore } from "@/stores/ui";
|
|
|
263
291
|
import router from "@/router/index";
|
|
264
292
|
import CountryChooser from "@/components/ui/controls/CountryChooser.vue";
|
|
265
293
|
import { sendLogout } from "@/stores/requests";
|
|
294
|
+
import { useDeviceDetection } from "@/composables/useDeviceDetection";
|
|
266
295
|
|
|
267
296
|
const landscapeIos = ref(false);
|
|
268
297
|
|
|
269
|
-
|
|
270
|
-
if (/iPad|iPhone|iPod/.test(navigator.platform)) {
|
|
271
|
-
return true;
|
|
272
|
-
} else {
|
|
273
|
-
return navigator.maxTouchPoints && navigator.maxTouchPoints > 2 && /MacIntel/.test(navigator.platform);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function isIpadOS() {
|
|
278
|
-
return navigator.maxTouchPoints && navigator.maxTouchPoints > 2 && /MacIntel/.test(navigator.platform);
|
|
279
|
-
}
|
|
298
|
+
const { isIOS, isIpadOS } = useDeviceDetection();
|
|
280
299
|
|
|
281
300
|
window.matchMedia("(orientation: portrait)").addEventListener("change", (e) => {
|
|
282
301
|
if (!e.matches && isIOS() && !isIpadOS()) landscapeIos.value = true;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="mt-6 grid grid-cols-12 gap-3 pt-4 border-t border-dark-550">
|
|
3
|
+
<div v-if="data.tags && data.tags.length > 0" class="col-span-6">
|
|
4
|
+
<label class="flex items-center mb-2 text-light-200 font-medium">Tags</label>
|
|
5
|
+
<div class="flex gap-2 flex-wrap">
|
|
6
|
+
<TagLabel v-for="tag in data.tags" :key="tag" :text="tag" />
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="col-span-6">
|
|
10
|
+
<label class="flex items-center mb-2 text-light-200 font-medium">Status</label>
|
|
11
|
+
<div class="flex items-center gap-3 h-10">
|
|
12
|
+
<StatusBadge :enabled="data.enabled" size="large" />
|
|
13
|
+
<span class="text-sm font-medium" :class="data.enabled ? 'text-green-400' : 'text-red-400'">
|
|
14
|
+
{{ data.enabled ? 'Enabled' : 'Disabled' }}
|
|
15
|
+
</span>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup>
|
|
22
|
+
import StatusBadge from "@/components/ui/StatusBadge.vue";
|
|
23
|
+
import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
24
|
+
|
|
25
|
+
defineProps({
|
|
26
|
+
data: {
|
|
27
|
+
type: Object,
|
|
28
|
+
required: true
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
</script>
|