@necrolab/dashboard 0.5.5 → 0.5.7
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/package.json +1 -1
- package/src/App.vue +71 -110
- package/src/assets/css/base/reset.scss +10 -0
- package/src/assets/css/base/scroll.scss +5 -0
- package/src/assets/css/components/forms.scss +11 -0
- package/src/assets/css/main.scss +25 -0
- package/src/components/Editors/Account/Account.vue +107 -44
- package/src/components/Editors/Account/AccountView.vue +15 -17
- package/src/components/Editors/Account/CreateAccount.vue +75 -1
- package/src/components/Editors/Profile/CreateProfile.vue +76 -2
- package/src/components/Editors/Profile/Profile.vue +105 -46
- package/src/components/Editors/Profile/ProfileView.vue +18 -18
- package/src/components/Editors/TagLabel.vue +19 -29
- package/src/components/Tasks/Task.vue +40 -3
- package/src/components/Tasks/TaskView.vue +23 -14
- package/src/components/icons/Checkmark.vue +1 -1
- package/src/components/icons/CloseX.vue +1 -1
- package/src/components/ui/Navbar.vue +3 -8
- package/src/components/ui/controls/atomic/Dropdown.vue +26 -11
- package/src/components/ui/controls/atomic/MultiDropdown.vue +61 -24
- package/src/views/Accounts.vue +12 -3
- package/src/views/Profiles.vue +12 -1
- package/src/views/Tasks.vue +27 -13
|
@@ -64,6 +64,30 @@
|
|
|
64
64
|
</div>
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
67
|
+
|
|
68
|
+
<!-- Readonly fields when editing -->
|
|
69
|
+
<div v-if="ui.currentlyEditing?.email" class="mt-6 grid grid-cols-12 gap-3 pt-4 border-t border-dark-600">
|
|
70
|
+
<div v-if="ui.currentlyEditing.tags && ui.currentlyEditing.tags.length > 0" class="col-span-6">
|
|
71
|
+
<label class="label-override mb-2">Tags</label>
|
|
72
|
+
<div class="flex gap-2 flex-wrap">
|
|
73
|
+
<TagLabel v-for="tag in ui.currentlyEditing.tags" :key="tag" :text="tag" />
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="col-span-6">
|
|
77
|
+
<label class="label-override mb-2">Status</label>
|
|
78
|
+
<div class="flex items-center gap-3 h-10">
|
|
79
|
+
<div v-if="ui.currentlyEditing.enabled" class="enabled-badge-large">
|
|
80
|
+
<CheckmarkIcon />
|
|
81
|
+
</div>
|
|
82
|
+
<div v-else class="disabled-badge-large">
|
|
83
|
+
<CloseXIcon />
|
|
84
|
+
</div>
|
|
85
|
+
<span class="text-sm font-medium" :class="ui.currentlyEditing.enabled ? 'text-green-400' : 'text-red-400'">
|
|
86
|
+
{{ ui.currentlyEditing.enabled ? 'Enabled' : 'Disabled' }}
|
|
87
|
+
</span>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
67
91
|
</div>
|
|
68
92
|
|
|
69
93
|
<button
|
|
@@ -75,6 +99,53 @@
|
|
|
75
99
|
</Modal>
|
|
76
100
|
</template>
|
|
77
101
|
<style lang="scss" scoped>
|
|
102
|
+
.enabled-badge-large {
|
|
103
|
+
@apply flex items-center justify-center rounded-full;
|
|
104
|
+
background: oklch(0.72 0.15 145 / 0.12);
|
|
105
|
+
border: 1.5px solid oklch(0.72 0.15 145);
|
|
106
|
+
width: 26px;
|
|
107
|
+
height: 26px;
|
|
108
|
+
padding: 0;
|
|
109
|
+
|
|
110
|
+
svg {
|
|
111
|
+
color: oklch(0.72 0.15 145) !important;
|
|
112
|
+
width: 14px !important;
|
|
113
|
+
height: auto !important;
|
|
114
|
+
max-height: 14px !important;
|
|
115
|
+
display: block;
|
|
116
|
+
margin: 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
svg path {
|
|
120
|
+
stroke: oklch(0.72 0.15 145) !important;
|
|
121
|
+
fill: oklch(0.72 0.15 145) !important;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.disabled-badge-large {
|
|
126
|
+
@apply flex items-center justify-center rounded-full;
|
|
127
|
+
background: oklch(0.60 0.20 25 / 0.12);
|
|
128
|
+
border: 1.5px solid oklch(0.60 0.20 25);
|
|
129
|
+
width: 26px;
|
|
130
|
+
height: 26px;
|
|
131
|
+
padding: 0;
|
|
132
|
+
color: oklch(0.60 0.20 25) !important;
|
|
133
|
+
|
|
134
|
+
svg {
|
|
135
|
+
color: oklch(0.60 0.20 25) !important;
|
|
136
|
+
width: 14px !important;
|
|
137
|
+
height: 14px !important;
|
|
138
|
+
display: block;
|
|
139
|
+
margin: 0;
|
|
140
|
+
fill: oklch(0.60 0.20 25) !important;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
svg path {
|
|
144
|
+
stroke: oklch(0.60 0.20 25) !important;
|
|
145
|
+
fill: oklch(0.60 0.20 25) !important;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
78
149
|
.input-wrapper {
|
|
79
150
|
label {
|
|
80
151
|
@apply flex;
|
|
@@ -105,10 +176,13 @@ import {
|
|
|
105
176
|
TimerIcon,
|
|
106
177
|
SandclockIcon,
|
|
107
178
|
TagIcon,
|
|
108
|
-
ScannerIcon
|
|
179
|
+
ScannerIcon,
|
|
180
|
+
CheckmarkIcon,
|
|
181
|
+
CloseXIcon
|
|
109
182
|
} from "@/components/icons";
|
|
110
183
|
import { useUIStore } from "@/stores/ui";
|
|
111
184
|
import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
|
|
185
|
+
import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
112
186
|
|
|
113
187
|
import { ref } from "vue";
|
|
114
188
|
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
<div class="input-wrapper col-span-2">
|
|
45
45
|
<label class="label-override mb-2">
|
|
46
46
|
Country
|
|
47
|
-
<
|
|
47
|
+
<StadiumIcon />
|
|
48
48
|
</label>
|
|
49
49
|
<ProfileCountryChooser
|
|
50
50
|
class="h-8"
|
|
@@ -187,6 +187,30 @@
|
|
|
187
187
|
</div>
|
|
188
188
|
</div>
|
|
189
189
|
</div>
|
|
190
|
+
|
|
191
|
+
<!-- Readonly fields when editing -->
|
|
192
|
+
<div v-if="ui.currentlyEditing?.profileName" class="mt-6 grid grid-cols-12 gap-3 pt-4 border-t border-dark-600">
|
|
193
|
+
<div v-if="ui.currentlyEditing.tags && ui.currentlyEditing.tags.length > 0" class="col-span-6">
|
|
194
|
+
<label class="label-override mb-2">Tags</label>
|
|
195
|
+
<div class="flex gap-2 flex-wrap">
|
|
196
|
+
<TagLabel v-for="tag in ui.currentlyEditing.tags" :key="tag" :text="tag" />
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="col-span-6">
|
|
200
|
+
<label class="label-override mb-2">Status</label>
|
|
201
|
+
<div class="flex items-center gap-3 h-10">
|
|
202
|
+
<div v-if="ui.currentlyEditing.enabled" class="enabled-badge-large">
|
|
203
|
+
<CheckmarkIcon />
|
|
204
|
+
</div>
|
|
205
|
+
<div v-else class="disabled-badge-large">
|
|
206
|
+
<CloseXIcon />
|
|
207
|
+
</div>
|
|
208
|
+
<span class="text-sm font-medium" :class="ui.currentlyEditing.enabled ? 'text-green-400' : 'text-red-400'">
|
|
209
|
+
{{ ui.currentlyEditing.enabled ? 'Enabled' : 'Disabled' }}
|
|
210
|
+
</span>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
190
214
|
</div>
|
|
191
215
|
|
|
192
216
|
<button
|
|
@@ -198,6 +222,53 @@
|
|
|
198
222
|
</Modal>
|
|
199
223
|
</template>
|
|
200
224
|
<style lang="scss" scoped>
|
|
225
|
+
.enabled-badge-large {
|
|
226
|
+
@apply flex items-center justify-center rounded-full;
|
|
227
|
+
background: oklch(0.72 0.15 145 / 0.12);
|
|
228
|
+
border: 1.5px solid oklch(0.72 0.15 145);
|
|
229
|
+
width: 26px;
|
|
230
|
+
height: 26px;
|
|
231
|
+
padding: 0;
|
|
232
|
+
|
|
233
|
+
svg {
|
|
234
|
+
color: oklch(0.72 0.15 145) !important;
|
|
235
|
+
width: 14px !important;
|
|
236
|
+
height: auto !important;
|
|
237
|
+
max-height: 14px !important;
|
|
238
|
+
display: block;
|
|
239
|
+
margin: 0;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
svg path {
|
|
243
|
+
stroke: oklch(0.72 0.15 145) !important;
|
|
244
|
+
fill: oklch(0.72 0.15 145) !important;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.disabled-badge-large {
|
|
249
|
+
@apply flex items-center justify-center rounded-full;
|
|
250
|
+
background: oklch(0.60 0.20 25 / 0.12);
|
|
251
|
+
border: 1.5px solid oklch(0.60 0.20 25);
|
|
252
|
+
width: 26px;
|
|
253
|
+
height: 26px;
|
|
254
|
+
padding: 0;
|
|
255
|
+
color: oklch(0.60 0.20 25) !important;
|
|
256
|
+
|
|
257
|
+
svg {
|
|
258
|
+
color: oklch(0.60 0.20 25) !important;
|
|
259
|
+
width: 14px !important;
|
|
260
|
+
height: 14px !important;
|
|
261
|
+
display: block;
|
|
262
|
+
margin: 0;
|
|
263
|
+
fill: oklch(0.60 0.20 25) !important;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
svg path {
|
|
267
|
+
stroke: oklch(0.60 0.20 25) !important;
|
|
268
|
+
fill: oklch(0.60 0.20 25) !important;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
201
272
|
.input-wrapper {
|
|
202
273
|
label {
|
|
203
274
|
@apply flex;
|
|
@@ -231,9 +302,12 @@ import {
|
|
|
231
302
|
SandclockIcon,
|
|
232
303
|
TimerIcon,
|
|
233
304
|
TagIcon,
|
|
234
|
-
WildcardIcon
|
|
305
|
+
WildcardIcon,
|
|
306
|
+
CheckmarkIcon,
|
|
307
|
+
CloseXIcon
|
|
235
308
|
} from "@/components/icons";
|
|
236
309
|
import { EditIcon } from "@/components/icons";
|
|
310
|
+
import TagLabel from "@/components/Editors/TagLabel.vue";
|
|
237
311
|
import ProfileCountryChooser from "@/components/Editors/Profile/ProfileCountryChooser.vue";
|
|
238
312
|
import { useUIStore } from "@/stores/ui";
|
|
239
313
|
import Dropdown from "@/components/ui/controls/atomic/Dropdown.vue";
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
<h4 class="text-white">{{ expDate() }}</h4>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="col-span-1">
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
</
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
</
|
|
36
|
+
<div v-if="props.profile.enabled" class="enabled-badge">
|
|
37
|
+
<CheckmarkIcon class="w-3.5 h-3.5" />
|
|
38
|
+
</div>
|
|
39
|
+
<div v-else class="disabled-badge">
|
|
40
|
+
<CloseXIcon class="w-3.5 h-3.5" />
|
|
41
|
+
</div>
|
|
42
42
|
</div>
|
|
43
43
|
|
|
44
44
|
<div class="col-span-1 hidden lg:block">
|
|
@@ -72,34 +72,80 @@
|
|
|
72
72
|
</Row>
|
|
73
73
|
</template>
|
|
74
74
|
<style lang="scss" scoped>
|
|
75
|
-
.
|
|
76
|
-
|
|
75
|
+
.enabled-badge {
|
|
76
|
+
@apply flex items-center justify-center mx-auto rounded-full;
|
|
77
|
+
background: oklch(0.72 0.15 145 / 0.12);
|
|
78
|
+
border: 1.5px solid oklch(0.72 0.15 145);
|
|
79
|
+
width: 24px;
|
|
80
|
+
height: 24px;
|
|
81
|
+
padding: 0;
|
|
82
|
+
|
|
83
|
+
svg {
|
|
84
|
+
color: oklch(0.72 0.15 145) !important;
|
|
85
|
+
width: 12px !important;
|
|
86
|
+
height: auto !important;
|
|
87
|
+
max-height: 12px !important;
|
|
88
|
+
display: block;
|
|
89
|
+
margin: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
svg path {
|
|
93
|
+
stroke: oklch(0.72 0.15 145) !important;
|
|
94
|
+
fill: oklch(0.72 0.15 145) !important;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.disabled-badge {
|
|
99
|
+
@apply flex items-center justify-center mx-auto rounded-full;
|
|
100
|
+
background: oklch(0.60 0.20 25 / 0.12);
|
|
101
|
+
border: 1.5px solid oklch(0.60 0.20 25);
|
|
102
|
+
width: 24px;
|
|
103
|
+
height: 24px;
|
|
104
|
+
padding: 0;
|
|
105
|
+
color: oklch(0.60 0.20 25) !important;
|
|
106
|
+
|
|
107
|
+
svg {
|
|
108
|
+
color: oklch(0.60 0.20 25) !important;
|
|
109
|
+
width: 12px !important;
|
|
110
|
+
height: 12px !important;
|
|
111
|
+
display: block;
|
|
112
|
+
margin: 0;
|
|
113
|
+
fill: oklch(0.60 0.20 25) !important;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
svg path {
|
|
117
|
+
stroke: oklch(0.60 0.20 25) !important;
|
|
118
|
+
fill: oklch(0.60 0.20 25) !important;
|
|
119
|
+
}
|
|
77
120
|
}
|
|
78
121
|
|
|
79
122
|
h4 {
|
|
80
123
|
@apply text-center;
|
|
81
124
|
}
|
|
82
125
|
.profile-buttons {
|
|
83
|
-
@apply mx-auto flex items-center justify-center rounded
|
|
126
|
+
@apply mx-auto flex items-center justify-center rounded;
|
|
127
|
+
background: oklch(0.2046 0 0);
|
|
128
|
+
border: 2px solid oklch(0.2809 0 0);
|
|
84
129
|
padding: 3px;
|
|
85
130
|
gap: 2px;
|
|
131
|
+
flex-shrink: 0;
|
|
132
|
+
overflow: visible;
|
|
86
133
|
|
|
87
134
|
button {
|
|
88
135
|
@apply relative flex items-center justify-center rounded border-0 outline-0 transition-all duration-150;
|
|
89
136
|
background: transparent;
|
|
90
137
|
width: 28px;
|
|
91
138
|
height: 28px;
|
|
92
|
-
color: oklch(0.
|
|
139
|
+
color: oklch(0.90 0 0);
|
|
140
|
+
border-radius: 6px;
|
|
93
141
|
|
|
94
142
|
&:hover {
|
|
95
|
-
background:
|
|
96
|
-
color:
|
|
97
|
-
transform: scale(1.05);
|
|
143
|
+
background: oklch(0.72 0.15 145 / 0.15);
|
|
144
|
+
color: oklch(1 0 0);
|
|
98
145
|
}
|
|
99
146
|
|
|
100
147
|
&:active {
|
|
101
|
-
background:
|
|
102
|
-
transform: scale(0.95);
|
|
148
|
+
background: oklch(0.72 0.15 145 / 0.25);
|
|
103
149
|
}
|
|
104
150
|
}
|
|
105
151
|
|
|
@@ -116,19 +162,17 @@ h4 {
|
|
|
116
162
|
}
|
|
117
163
|
}
|
|
118
164
|
|
|
119
|
-
// Tablet
|
|
120
|
-
@media (max-width:
|
|
121
|
-
h4 {
|
|
122
|
-
font-size: 10px !important;
|
|
123
|
-
}
|
|
124
|
-
|
|
165
|
+
// Tablet sizing - medium buttons
|
|
166
|
+
@media (min-width: 768px) and (max-width: 1023px) {
|
|
125
167
|
.profile-buttons {
|
|
126
|
-
padding:
|
|
127
|
-
gap:
|
|
168
|
+
padding: 2px;
|
|
169
|
+
gap: 1px;
|
|
170
|
+
border-radius: 6px;
|
|
128
171
|
|
|
129
172
|
button {
|
|
130
173
|
width: 26px;
|
|
131
174
|
height: 26px;
|
|
175
|
+
border-radius: 5px;
|
|
132
176
|
}
|
|
133
177
|
|
|
134
178
|
svg,
|
|
@@ -137,59 +181,74 @@ h4 {
|
|
|
137
181
|
height: 14px;
|
|
138
182
|
}
|
|
139
183
|
}
|
|
140
|
-
|
|
141
|
-
.profile-id {
|
|
142
|
-
font-size: 6px !important;
|
|
143
|
-
margin-right: -12px;
|
|
144
|
-
margin-top: 20px;
|
|
145
|
-
}
|
|
146
184
|
}
|
|
147
185
|
|
|
148
|
-
//
|
|
149
|
-
@media (
|
|
186
|
+
// Desktop sizing - large buttons
|
|
187
|
+
@media (min-width: 1024px) {
|
|
150
188
|
.profile-buttons {
|
|
151
|
-
padding:
|
|
152
|
-
gap:
|
|
189
|
+
padding: 3px;
|
|
190
|
+
gap: 2px;
|
|
191
|
+
border-radius: 8px;
|
|
153
192
|
|
|
154
193
|
button {
|
|
155
|
-
width:
|
|
156
|
-
height:
|
|
194
|
+
width: 28px;
|
|
195
|
+
height: 28px;
|
|
196
|
+
border-radius: 6px;
|
|
157
197
|
}
|
|
158
198
|
|
|
159
199
|
svg,
|
|
160
200
|
img {
|
|
161
|
-
width:
|
|
162
|
-
height:
|
|
201
|
+
width: 16px;
|
|
202
|
+
height: 16px;
|
|
163
203
|
}
|
|
164
204
|
}
|
|
165
205
|
}
|
|
166
206
|
|
|
167
|
-
//
|
|
168
|
-
@media (max-width:
|
|
207
|
+
// Mobile specific styling
|
|
208
|
+
@media (max-width: 640px) {
|
|
169
209
|
.profile-buttons {
|
|
170
|
-
padding:
|
|
210
|
+
padding: 1px;
|
|
171
211
|
gap: 1px;
|
|
212
|
+
border-radius: 4px;
|
|
213
|
+
border: 2px solid oklch(0.2809 0 0) !important;
|
|
214
|
+
max-width: 100%;
|
|
215
|
+
min-height: 28px;
|
|
216
|
+
height: auto;
|
|
217
|
+
flex-wrap: wrap;
|
|
218
|
+
justify-content: center;
|
|
219
|
+
align-items: center;
|
|
220
|
+
background: oklch(0.2046 0 0);
|
|
172
221
|
|
|
173
222
|
button {
|
|
174
|
-
width:
|
|
175
|
-
height:
|
|
223
|
+
width: 20px;
|
|
224
|
+
height: 20px;
|
|
225
|
+
border-radius: 3px;
|
|
226
|
+
min-width: 20px;
|
|
227
|
+
border: none !important;
|
|
228
|
+
flex-shrink: 0;
|
|
229
|
+
margin: 0.5px;
|
|
230
|
+
background: transparent;
|
|
176
231
|
|
|
177
232
|
&:hover {
|
|
178
|
-
|
|
233
|
+
background: oklch(0.72 0.15 145 / 0.15);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
&:active {
|
|
237
|
+
background: oklch(0.72 0.15 145 / 0.25);
|
|
179
238
|
}
|
|
180
239
|
}
|
|
181
240
|
|
|
182
241
|
svg,
|
|
183
242
|
img {
|
|
184
|
-
width:
|
|
185
|
-
height:
|
|
243
|
+
width: 12px;
|
|
244
|
+
height: 12px;
|
|
186
245
|
}
|
|
187
246
|
}
|
|
188
247
|
}
|
|
189
248
|
</style>
|
|
190
249
|
<script setup>
|
|
191
250
|
import { Row } from "@/components/Table";
|
|
192
|
-
import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon } from "@/components/icons";
|
|
251
|
+
import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon, CheckmarkIcon, CloseXIcon } from "@/components/icons";
|
|
193
252
|
import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
|
|
194
253
|
import { useUIStore } from "@/stores/ui";
|
|
195
254
|
import { validateCard } from "@/stores/utils";
|
|
@@ -33,22 +33,15 @@
|
|
|
33
33
|
<h4 class="hidden md:flex">Actions</h4>
|
|
34
34
|
</div>
|
|
35
35
|
</Header>
|
|
36
|
-
<div
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<Profile
|
|
46
|
-
@click="i[props.item.index]++"
|
|
47
|
-
:class="props.item.index % 2 == 1 ? 'table-row-even' : 'table-row-odd'"
|
|
48
|
-
:profile="props.item" />
|
|
49
|
-
</div>
|
|
50
|
-
</template>
|
|
51
|
-
</RecycleScroller>
|
|
36
|
+
<div
|
|
37
|
+
v-if="toRender.length != 0"
|
|
38
|
+
class="hidden-scrollbars stop-pan flex flex-col divide-y divide-dark-650 overflow-y-auto overflow-x-hidden"
|
|
39
|
+
:style="{ maxHeight: dynamicTableHeight }">
|
|
40
|
+
<div v-for="(profile, i) in toRender" :key="profile.id || profile.index" class="profile-row-container">
|
|
41
|
+
<Profile
|
|
42
|
+
:class="i % 2 == 1 ? 'table-row-even' : 'table-row-odd'"
|
|
43
|
+
:profile="profile" />
|
|
44
|
+
</div>
|
|
52
45
|
</div>
|
|
53
46
|
<div v-else class="empty-state flex flex-col items-center justify-center bg-dark-400 py-8 text-center">
|
|
54
47
|
<ProfileIcon class="mb-3 h-12 w-12 text-dark-400 opacity-50" />
|
|
@@ -58,9 +51,16 @@
|
|
|
58
51
|
</Table>
|
|
59
52
|
</template>
|
|
60
53
|
<style lang="scss" scoped>
|
|
61
|
-
.profile {
|
|
62
|
-
height: 64px;
|
|
54
|
+
.profile-row-container {
|
|
55
|
+
min-height: 64px;
|
|
56
|
+
flex-shrink: 0;
|
|
57
|
+
transition: background-color 0.15s ease;
|
|
58
|
+
|
|
59
|
+
&:hover {
|
|
60
|
+
@apply bg-dark-550 !important;
|
|
61
|
+
}
|
|
63
62
|
}
|
|
63
|
+
|
|
64
64
|
h4 {
|
|
65
65
|
@apply text-white;
|
|
66
66
|
}
|
|
@@ -6,63 +6,53 @@
|
|
|
6
6
|
|
|
7
7
|
<style lang="scss" scoped>
|
|
8
8
|
.tag-pill {
|
|
9
|
-
@apply inline-flex items-center justify-center rounded-
|
|
10
|
-
background:
|
|
11
|
-
border:
|
|
12
|
-
padding: 0.
|
|
9
|
+
@apply inline-flex items-center justify-center rounded-full;
|
|
10
|
+
background: oklch(0.72 0.15 145 / 0.12);
|
|
11
|
+
border: 1.5px solid oklch(0.72 0.15 145 / 0.25);
|
|
12
|
+
padding: 0.25rem 0.625rem;
|
|
13
13
|
min-width: 2rem;
|
|
14
|
-
max-width:
|
|
15
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
|
16
|
-
|
|
17
|
-
&:hover {
|
|
18
|
-
background: linear-gradient(145deg, oklch(0.28 0 0), oklch(0.26 0 0));
|
|
19
|
-
border-color: oklch(0.33 0 0);
|
|
20
|
-
transform: translateY(-0.5px);
|
|
21
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
22
|
-
}
|
|
14
|
+
max-width: 5rem;
|
|
23
15
|
}
|
|
24
16
|
|
|
25
17
|
.tag-text {
|
|
26
|
-
@apply
|
|
18
|
+
@apply truncate font-semibold;
|
|
19
|
+
color: oklch(0.72 0.15 145);
|
|
27
20
|
font-size: 0.6875rem;
|
|
28
|
-
line-height: 1.
|
|
29
|
-
letter-spacing: 0.
|
|
30
|
-
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
|
|
21
|
+
line-height: 1.2;
|
|
22
|
+
letter-spacing: 0.015em;
|
|
31
23
|
}
|
|
32
24
|
|
|
33
|
-
//
|
|
25
|
+
// Responsive design
|
|
34
26
|
@media (max-width: 1024px) {
|
|
35
27
|
.tag-pill {
|
|
36
|
-
padding: 0.
|
|
37
|
-
max-width:
|
|
28
|
+
padding: 0.2rem 0.5rem;
|
|
29
|
+
max-width: 4rem;
|
|
38
30
|
}
|
|
39
31
|
|
|
40
32
|
.tag-text {
|
|
41
|
-
font-size: 0.
|
|
33
|
+
font-size: 0.625rem;
|
|
42
34
|
}
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
@media (max-width: 768px) {
|
|
46
38
|
.tag-pill {
|
|
47
|
-
padding: 0.
|
|
48
|
-
max-width:
|
|
49
|
-
min-width: 1.25rem;
|
|
39
|
+
padding: 0.1875rem 0.4rem;
|
|
40
|
+
max-width: 3.5rem;
|
|
50
41
|
}
|
|
51
42
|
|
|
52
43
|
.tag-text {
|
|
53
|
-
font-size: 0.
|
|
44
|
+
font-size: 0.6rem;
|
|
54
45
|
}
|
|
55
46
|
}
|
|
56
47
|
|
|
57
48
|
@media (max-width: 480px) {
|
|
58
49
|
.tag-pill {
|
|
59
|
-
padding: 0.
|
|
60
|
-
max-width:
|
|
61
|
-
min-width: 1rem;
|
|
50
|
+
padding: 0.15rem 0.35rem;
|
|
51
|
+
max-width: 3rem;
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
.tag-text {
|
|
65
|
-
font-size: 0.
|
|
55
|
+
font-size: 0.575rem;
|
|
66
56
|
}
|
|
67
57
|
}
|
|
68
58
|
</style>
|
|
@@ -10,7 +10,25 @@
|
|
|
10
10
|
class="ml-2 mr-4 flex-shrink-0"
|
|
11
11
|
:toggled="props.task.selected"
|
|
12
12
|
@valueUpdate="ui.toggleTaskSelected(props.task.taskId)" />
|
|
13
|
+
<div
|
|
14
|
+
v-if="props.preferEventName && props.task.eventName"
|
|
15
|
+
class="event-details hidden cursor-pointer lg:flex flex-col gap-0.5"
|
|
16
|
+
@click="copy(props.task.eventId)"
|
|
17
|
+
:title="`Event ID: ${props.task.eventId}`">
|
|
18
|
+
<div class="event-name text-white text-xs font-semibold leading-tight">
|
|
19
|
+
{{ props.task.eventName }}
|
|
20
|
+
</div>
|
|
21
|
+
<div v-if="props.task.eventVenue" class="event-venue flex items-center gap-1 text-[10px] text-light-400">
|
|
22
|
+
<StadiumIcon class="w-2.5 h-2.5 flex-shrink-0" />
|
|
23
|
+
<span class="truncate">{{ props.task.eventVenue }}</span>
|
|
24
|
+
</div>
|
|
25
|
+
<div v-if="props.task.eventLocalDate" class="event-date flex items-center gap-1 text-[10px] text-light-400">
|
|
26
|
+
<TimerIcon class="w-2.5 h-2.5 flex-shrink-0" />
|
|
27
|
+
<span>{{ formatEventDate(props.task.eventLocalDate) }}</span>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
13
30
|
<h4
|
|
31
|
+
v-else
|
|
14
32
|
class="task-event-id mx-auto hidden cursor-pointer text-white hover:text-light-300 lg:block"
|
|
15
33
|
@click="copy(props.task.eventId)">
|
|
16
34
|
{{ props.task.eventId }}
|
|
@@ -90,7 +108,6 @@
|
|
|
90
108
|
</h4>
|
|
91
109
|
</div>
|
|
92
110
|
|
|
93
|
-
<!-- Context menu -->
|
|
94
111
|
<transition name="fade">
|
|
95
112
|
<div
|
|
96
113
|
v-if="ui.openContextMenu === task.taskId"
|
|
@@ -376,7 +393,7 @@ h4 {
|
|
|
376
393
|
/// <reference path="@/types/index.js" />
|
|
377
394
|
|
|
378
395
|
import { Row } from "@/components/Table";
|
|
379
|
-
import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon, EyeIcon } from "@/components/icons";
|
|
396
|
+
import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon, EyeIcon, StadiumIcon, TimerIcon } from "@/components/icons";
|
|
380
397
|
import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
|
|
381
398
|
import { useUIStore } from "@/stores/ui";
|
|
382
399
|
import TaskLabel from "@/components/Tasks/TaskLabel.vue";
|
|
@@ -387,9 +404,29 @@ const ui = useUIStore();
|
|
|
387
404
|
|
|
388
405
|
/** @type {{ task: Task }} */
|
|
389
406
|
const props = defineProps({
|
|
390
|
-
task: { type: Object }
|
|
407
|
+
task: { type: Object },
|
|
408
|
+
preferEventName: { type: Boolean, default: false }
|
|
391
409
|
});
|
|
392
410
|
|
|
411
|
+
// Format event date for display
|
|
412
|
+
const formatEventDate = (dateString) => {
|
|
413
|
+
if (!dateString) return '';
|
|
414
|
+
try {
|
|
415
|
+
const date = new Date(dateString);
|
|
416
|
+
const options = {
|
|
417
|
+
month: 'short',
|
|
418
|
+
day: 'numeric',
|
|
419
|
+
year: 'numeric',
|
|
420
|
+
hour: 'numeric',
|
|
421
|
+
minute: '2-digit',
|
|
422
|
+
hour12: true
|
|
423
|
+
};
|
|
424
|
+
return date.toLocaleString('en-US', options).replace(',', '');
|
|
425
|
+
} catch {
|
|
426
|
+
return dateString;
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
|
|
393
430
|
// Context menu positioning
|
|
394
431
|
const contextMenuPosition = ref({});
|
|
395
432
|
const contextMenuRef = ref(null);
|