@necrolab/dashboard 0.4.220 → 0.5.1
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/.prettierrc +27 -1
- package/.vscode/extensions.json +1 -1
- package/README.md +64 -2
- package/artwork/image.png +0 -0
- package/backend/api.js +26 -24
- package/backend/auth.js +2 -2
- package/backend/batching.js +1 -1
- package/backend/endpoints.js +8 -11
- package/backend/index.js +2 -2
- package/backend/mock-data.js +27 -36
- package/backend/mock-src/classes/logger.js +5 -7
- package/backend/mock-src/classes/utils.js +3 -2
- package/backend/mock-src/ticketmaster.js +4 -4
- package/backend/validator.js +2 -2
- package/config/configs.json +0 -1
- package/dev-server.js +134 -0
- package/exit +209 -0
- package/index.html +78 -8
- package/index.js +1 -1
- package/jsconfig.json +16 -0
- package/package.json +39 -25
- package/postcss.config.js +1 -1
- package/postinstall.js +124 -20
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/img/logo_trans.png +0 -0
- package/public/img/necro_logo.png +0 -0
- package/public/manifest.json +16 -10
- package/run +176 -9
- package/src/App.vue +498 -85
- package/src/assets/css/base/reset.scss +43 -0
- package/src/assets/css/base/scroll.scss +114 -0
- package/src/assets/css/base/typography.scss +37 -0
- package/src/assets/css/components/buttons.scss +216 -0
- package/src/assets/css/components/forms.scss +221 -0
- package/src/assets/css/components/modals.scss +13 -0
- package/src/assets/css/components/tables.scss +27 -0
- package/src/assets/css/components/toasts.scss +100 -0
- package/src/assets/css/main.scss +201 -122
- package/src/assets/img/background.svg +2 -2
- package/src/assets/img/background.svg.backup +11 -0
- package/src/assets/img/logo_trans.png +0 -0
- package/src/components/Auth/LoginForm.vue +62 -11
- package/src/components/Editors/Account/Account.vue +116 -40
- package/src/components/Editors/Account/AccountCreator.vue +88 -39
- package/src/components/Editors/Account/AccountView.vue +102 -34
- package/src/components/Editors/Account/CreateAccount.vue +80 -32
- package/src/components/Editors/Profile/CreateProfile.vue +269 -83
- package/src/components/Editors/Profile/Profile.vue +132 -47
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +82 -20
- package/src/components/Editors/Profile/ProfileView.vue +89 -32
- package/src/components/Editors/TagLabel.vue +67 -6
- package/src/components/Editors/TagToggle.vue +7 -2
- package/src/components/Filter/Filter.vue +288 -71
- package/src/components/Filter/FilterPreview.vue +202 -31
- package/src/components/Filter/PriceSortToggle.vue +76 -6
- package/src/components/Table/Header.vue +1 -1
- package/src/components/Table/Row.vue +1 -1
- package/src/components/Table/Table.vue +19 -2
- package/src/components/Tasks/CheckStock.vue +6 -8
- package/src/components/Tasks/Controls/DesktopControls.vue +27 -17
- package/src/components/Tasks/Controls/MobileControls.vue +8 -45
- package/src/components/Tasks/CreateTaskAXS.vue +80 -72
- package/src/components/Tasks/CreateTaskTM.vue +95 -141
- package/src/components/Tasks/MassEdit.vue +4 -6
- package/src/components/Tasks/QuickSettings.vue +199 -30
- package/src/components/Tasks/ScrapeVenue.vue +5 -6
- package/src/components/Tasks/Stats.vue +50 -24
- package/src/components/Tasks/Task.vue +384 -179
- package/src/components/Tasks/TaskLabel.vue +2 -2
- package/src/components/Tasks/TaskView.vue +136 -48
- package/src/components/Tasks/Utilities.vue +25 -10
- package/src/components/Tasks/ViewTask.vue +321 -0
- package/src/components/icons/Bag.vue +1 -1
- package/src/components/icons/Check.vue +5 -0
- package/src/components/icons/Close.vue +21 -0
- package/src/components/icons/CloseX.vue +5 -0
- package/src/components/icons/Eye.vue +6 -0
- package/src/components/icons/Key.vue +21 -0
- package/src/components/icons/Loyalty.vue +1 -1
- package/src/components/icons/Mail.vue +2 -2
- package/src/components/icons/Pencil.vue +21 -0
- package/src/components/icons/Play.vue +2 -2
- package/src/components/icons/Profile.vue +18 -0
- package/src/components/icons/Reload.vue +4 -5
- package/src/components/icons/Sandclock.vue +2 -2
- package/src/components/icons/Sell.vue +21 -0
- package/src/components/icons/Spinner.vue +42 -0
- package/src/components/icons/SquareCheck.vue +18 -0
- package/src/components/icons/SquareUncheck.vue +18 -0
- package/src/components/icons/Stadium.vue +1 -1
- package/src/components/icons/Wildcard.vue +18 -0
- package/src/components/icons/index.js +26 -1
- package/src/components/ui/Modal.vue +107 -13
- package/src/components/ui/Navbar.vue +175 -40
- package/src/components/ui/ReconnectIndicator.vue +351 -55
- package/src/components/ui/Splash.vue +5 -35
- package/src/components/ui/controls/CountryChooser.vue +200 -62
- package/src/components/ui/controls/atomic/Checkbox.vue +119 -10
- package/src/components/ui/controls/atomic/Dropdown.vue +216 -39
- package/src/components/ui/controls/atomic/LoadingButton.vue +45 -0
- package/src/components/ui/controls/atomic/MultiDropdown.vue +300 -37
- package/src/components/ui/controls/atomic/Switch.vue +53 -25
- package/src/composables/useClickOutside.js +21 -0
- package/src/composables/useDropdownPosition.js +174 -0
- package/src/libs/Filter.js +60 -24
- package/src/registerServiceWorker.js +1 -1
- package/src/stores/connection.js +4 -4
- package/src/stores/sampleData.js +172 -199
- package/src/stores/ui.js +55 -20
- package/src/stores/utils.js +30 -4
- package/src/types/index.js +41 -0
- package/src/utils/debug.js +1 -0
- package/src/views/Accounts.vue +116 -50
- package/src/views/Console.vue +394 -79
- package/src/views/Editor.vue +1176 -123
- package/src/views/FilterBuilder.vue +528 -250
- package/src/views/Login.vue +76 -14
- package/src/views/Profiles.vue +119 -34
- package/src/views/Tasks.vue +266 -98
- package/static/offline.html +192 -50
- package/switch-branch.sh +41 -0
- package/tailwind.config.js +119 -27
- package/vite.config.js +73 -16
- package/workbox-config.cjs +63 -0
- package/ICONS.md +0 -21
- package/public/img/background.svg +0 -14
- package/public/img/logo.png +0 -0
- package/public/img/logo_icon.png +0 -0
- package/public/img/logo_icon_2.png +0 -0
- package/src/assets/css/_input.scss +0 -143
- package/src/assets/img/logo.png +0 -0
- package/src/assets/img/logo_icon.png +0 -0
- package/src/assets/img/logo_icon_2.png +0 -0
- package/vue.config.js +0 -32
- package/workbox-config.js +0 -7
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
3
|
@click="increase"
|
|
4
|
-
class="h-10 px-1 text-white bg-dark-500 relative
|
|
4
|
+
class="h-10 px-1 text-white bg-dark-500 relative overflow-hidden"
|
|
5
|
+
:class="noBorder ? 'border-0' : 'border-2 border-dark-550'"
|
|
5
6
|
>
|
|
6
7
|
<span v-if="sortOptions[currentOpt % sortOptions.length] === 'Enabled'"
|
|
7
8
|
><img class="mx-auto" height="16px" width="14px" src="@/assets/img/square_check.svg"
|
|
@@ -27,7 +28,11 @@ const props = defineProps({
|
|
|
27
28
|
index: Number,
|
|
28
29
|
expandedFilter: Number,
|
|
29
30
|
filterBuilder: Object,
|
|
30
|
-
options: Object
|
|
31
|
+
options: Object,
|
|
32
|
+
noBorder: {
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: false
|
|
35
|
+
}
|
|
31
36
|
});
|
|
32
37
|
|
|
33
38
|
sortOptions.value = props.options;
|
|
@@ -1,104 +1,147 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
2
|
+
<div
|
|
3
|
+
class="filter-card group text-white text-sm transition-all duration-200 hover:bg-dark-400 relative"
|
|
4
|
+
:class="{
|
|
5
|
+
'expanded-filter': filterBuilder.expandedFilter === filter.id,
|
|
6
|
+
'excluded-filter': filter.exclude,
|
|
7
|
+
'normal-filter': !filterBuilder.expandedFilter && !filter.exclude
|
|
8
|
+
}"
|
|
9
|
+
>
|
|
10
|
+
<div class="grid grid-cols-12 items-center py-3 px-2 sm:px-4 gap-2 sm:gap-3">
|
|
11
|
+
<div class="col-span-9 sm:col-span-10">
|
|
12
|
+
<div class="flex items-center gap-2 sm:gap-3 cursor-pointer flex-1" @click="handleFilterClick(filter.id)">
|
|
13
|
+
<div class="filter-type-badge flex-shrink-0">
|
|
14
|
+
<component :is="getFilterIcon()" class="w-3 h-3 sm:w-4 sm:h-4" />
|
|
15
|
+
</div>
|
|
16
|
+
<div class="flex-1 min-w-0">
|
|
17
|
+
<h3 class="font-medium text-white group-hover:text-light-400 transition-colors text-sm sm:text-base truncate">{{ filterTitle }}</h3>
|
|
18
|
+
<p class="text-xs mt-1 truncate text-light-400" v-if="getFilterSubtitle()">{{ getFilterSubtitle() }}</p>
|
|
19
|
+
</div>
|
|
16
20
|
</div>
|
|
17
|
-
<div
|
|
21
|
+
<div class="expanded-content mt-4 mx-2 sm:mx-0" v-if="filterBuilder.expandedFilter === filter.id">
|
|
18
22
|
<!-- NORMAL -->
|
|
19
|
-
<div v-if="filterType === 2">
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
<div v-if="filterType === 2" class="space-y-2">
|
|
24
|
+
<div class="info-row">
|
|
25
|
+
<span class="label">Section:</span>
|
|
26
|
+
<span class="value">{{ filter?.section }}</span>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="info-row" v-if="filter.rows?.length">
|
|
29
|
+
<span class="label">Rows:</span>
|
|
30
|
+
<span class="value">{{ filter?.rows?.join(", ") }}</span>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="info-row">
|
|
33
|
+
<span class="label">Event:</span>
|
|
34
|
+
<span class="value">{{ filter?.event || filter?.eventId || "-" }}</span>
|
|
35
|
+
</div>
|
|
23
36
|
</div>
|
|
24
37
|
<!-- NORMAL_FIRSTROW -->
|
|
25
|
-
<div v-if="filterType === 3">
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
<div v-if="filterType === 3" class="space-y-2">
|
|
39
|
+
<div class="info-row">
|
|
40
|
+
<span class="label">Section:</span>
|
|
41
|
+
<span class="value">{{ filter?.section }}</span>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="info-row">
|
|
44
|
+
<span class="label">Row:</span>
|
|
45
|
+
<span class="value">{{ filter?._row }}</span>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="info-row">
|
|
48
|
+
<span class="label">Event:</span>
|
|
49
|
+
<span class="value">{{ filter?.event || "-" }}</span>
|
|
50
|
+
</div>
|
|
29
51
|
</div>
|
|
30
52
|
<!-- CATCH_ALL_GA -->
|
|
31
53
|
<div v-if="filterType === 1">
|
|
32
54
|
<button
|
|
33
|
-
@click="update({ buyAny: true, floor: false, generalAdmission: false })"
|
|
34
|
-
class="
|
|
55
|
+
@click.stop="update({ buyAny: true, floor: false, generalAdmission: false })"
|
|
56
|
+
class="conversion-btn"
|
|
35
57
|
>
|
|
58
|
+
<component :is="'WildcardIcon'" class="w-4 h-4" />
|
|
36
59
|
Convert to wildcard
|
|
37
60
|
</button>
|
|
38
61
|
</div>
|
|
39
62
|
<!-- CATCH_ALL -->
|
|
40
63
|
<div v-if="filterType === 0">
|
|
41
64
|
<button
|
|
42
|
-
@click="update({ floor: true, buyAny: false, generalAdmission: false })"
|
|
43
|
-
class="
|
|
65
|
+
@click.stop="update({ floor: true, buyAny: false, generalAdmission: false })"
|
|
66
|
+
class="conversion-btn"
|
|
44
67
|
>
|
|
68
|
+
<component :is="'BoxIcon'" class="w-4 h-4" />
|
|
45
69
|
Convert to Floor Wildcard
|
|
46
70
|
</button>
|
|
47
71
|
</div>
|
|
48
72
|
<!-- CATCH_ALL_FLOOR -->
|
|
49
73
|
<div v-if="filterType === 5">
|
|
50
74
|
<button
|
|
51
|
-
@click="update({ generalAdmission: true, floor: false, buyAny: false })"
|
|
52
|
-
class="
|
|
75
|
+
@click.stop="update({ generalAdmission: true, floor: false, buyAny: false })"
|
|
76
|
+
class="conversion-btn"
|
|
53
77
|
>
|
|
78
|
+
<component :is="'GroupIcon'" class="w-4 h-4" />
|
|
54
79
|
Convert to GA Wildcard
|
|
55
80
|
</button>
|
|
56
81
|
</div>
|
|
57
82
|
</div>
|
|
58
|
-
<div v-if="filterBuilder.expandedFilter === filter.id" class="
|
|
59
|
-
<div class="flex
|
|
60
|
-
<
|
|
61
|
-
|
|
83
|
+
<div v-if="filterBuilder.expandedFilter === filter.id" class="controls-section mt-4 mx-2 sm:mx-0">
|
|
84
|
+
<div class="flex flex-col sm:flex-row flex-wrap gap-3 sm:items-center">
|
|
85
|
+
<div class="flex items-center gap-2 control-group">
|
|
86
|
+
<Checkbox :toggled="filter.exclude || false" @valueUpdate="handleExcludeClick" />
|
|
87
|
+
<label class="text-sm font-medium">Excluded</label>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="flex items-center gap-2 control-group">
|
|
90
|
+
<label class="text-xs whitespace-nowrap text-light-400">Min:</label>
|
|
91
|
+
<input
|
|
92
|
+
type="number"
|
|
93
|
+
:value="filter.minPrice"
|
|
94
|
+
@change="
|
|
95
|
+
(e) =>
|
|
96
|
+
update(
|
|
97
|
+
{
|
|
98
|
+
minPrice: e.target.value - 0
|
|
99
|
+
},
|
|
100
|
+
true
|
|
101
|
+
)
|
|
102
|
+
"
|
|
103
|
+
placeholder="0"
|
|
104
|
+
class="filter-input w-16 sm:w-20"
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
<div class="flex items-center gap-2 control-group">
|
|
108
|
+
<label class="text-xs whitespace-nowrap text-light-400">Max:</label>
|
|
109
|
+
<input
|
|
110
|
+
type="number"
|
|
111
|
+
:value="filter.maxPrice"
|
|
112
|
+
@change="
|
|
113
|
+
(e) =>
|
|
114
|
+
update(
|
|
115
|
+
{
|
|
116
|
+
maxPrice: e.target.value - 0
|
|
117
|
+
},
|
|
118
|
+
true
|
|
119
|
+
)
|
|
120
|
+
"
|
|
121
|
+
placeholder="1000"
|
|
122
|
+
class="filter-input w-16 sm:w-20"
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="control-group">
|
|
126
|
+
<PriceSortToggle
|
|
127
|
+
:current="filter.priceSort"
|
|
128
|
+
@change="(e) => props.filterBuilder.replaceById(filter.id, { priceSort: e })"
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
62
131
|
</div>
|
|
63
|
-
<input
|
|
64
|
-
type="text"
|
|
65
|
-
:value="filter.minPrice"
|
|
66
|
-
@change="
|
|
67
|
-
(e) =>
|
|
68
|
-
update(
|
|
69
|
-
{
|
|
70
|
-
minPrice: e.target.value - 0
|
|
71
|
-
},
|
|
72
|
-
true
|
|
73
|
-
)
|
|
74
|
-
"
|
|
75
|
-
placeholder="min"
|
|
76
|
-
class="w-16 bg-dark-500 border-2 rounded border-dark-550 px-1 h-8"
|
|
77
|
-
/>
|
|
78
|
-
<input
|
|
79
|
-
type="number"
|
|
80
|
-
:value="filter.maxPrice"
|
|
81
|
-
@change="
|
|
82
|
-
(e) =>
|
|
83
|
-
update(
|
|
84
|
-
{
|
|
85
|
-
maxPrice: e.target.value - 0
|
|
86
|
-
},
|
|
87
|
-
true
|
|
88
|
-
)
|
|
89
|
-
"
|
|
90
|
-
placeholder="max"
|
|
91
|
-
class="w-16 bg-dark-500 border-2 rounded border-dark-550 px-1 h-8"
|
|
92
|
-
/>
|
|
93
|
-
<PriceSortToggle
|
|
94
|
-
:current="filter.priceSort"
|
|
95
|
-
@change="(e) => props.filterBuilder.replaceById(filter.id, { priceSort: e })"
|
|
96
|
-
/>
|
|
97
132
|
</div>
|
|
98
133
|
</div>
|
|
99
|
-
<div class="col-span-
|
|
100
|
-
<
|
|
101
|
-
|
|
134
|
+
<div class="col-span-3 sm:col-span-2 flex justify-end items-center gap-1 sm:gap-2">
|
|
135
|
+
<div class="drag-handle handle filter-action-btn drag-btn cursor-grab active:cursor-grabbing" title="Drag to reorder">
|
|
136
|
+
<MenuIcon class="w-3 h-3 sm:w-4 sm:h-4" />
|
|
137
|
+
</div>
|
|
138
|
+
<button
|
|
139
|
+
@click="filterBuilder.deleteFilterById(filter.id)"
|
|
140
|
+
class="delete-btn filter-action-btn"
|
|
141
|
+
title="Delete filter"
|
|
142
|
+
>
|
|
143
|
+
<TrashIcon class="w-3 h-3 sm:w-4 sm:h-4" />
|
|
144
|
+
</button>
|
|
102
145
|
</div>
|
|
103
146
|
</div>
|
|
104
147
|
</div>
|
|
@@ -113,7 +156,7 @@ import { useUIStore } from "@/stores/ui";
|
|
|
113
156
|
const ui = useUIStore();
|
|
114
157
|
|
|
115
158
|
// eslint-disable-next-line no-unused-vars
|
|
116
|
-
import { UpIcon, DownIcon, ReloadIcon, TrashIcon, MenuIcon } from "@/components/icons";
|
|
159
|
+
import { UpIcon, DownIcon, ReloadIcon, TrashIcon, MenuIcon, WildcardIcon, BoxIcon, GroupIcon, FilterIcon, StadiumIcon } from "@/components/icons";
|
|
117
160
|
|
|
118
161
|
let isAllRows = ref(false);
|
|
119
162
|
|
|
@@ -136,6 +179,46 @@ const handleFilterClick = (id) => {
|
|
|
136
179
|
};
|
|
137
180
|
|
|
138
181
|
const filterTypes = props.filterBuilder.filterTypes;
|
|
182
|
+
|
|
183
|
+
const getFilterIcon = () => {
|
|
184
|
+
switch (filterType.value) {
|
|
185
|
+
case filterTypes.CATCH_ALL:
|
|
186
|
+
return WildcardIcon;
|
|
187
|
+
case filterTypes.CATCH_ALL_GA:
|
|
188
|
+
return GroupIcon;
|
|
189
|
+
case filterTypes.CATCH_ALL_FLOOR:
|
|
190
|
+
return BoxIcon;
|
|
191
|
+
case filterTypes.NORMAL:
|
|
192
|
+
case filterTypes.NORMAL_FIRSTROW:
|
|
193
|
+
return StadiumIcon;
|
|
194
|
+
default:
|
|
195
|
+
return FilterIcon;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const getFilterSubtitle = () => {
|
|
200
|
+
switch (filterType.value) {
|
|
201
|
+
case filterTypes.NORMAL: {
|
|
202
|
+
const selectedRowAmount = filter.value?.rows?.length;
|
|
203
|
+
if (filter.value?.rows?.length && selectedRowAmount <= 5) {
|
|
204
|
+
return `Rows: ${filter.value.rows.join(", ")}`;
|
|
205
|
+
} else if (selectedRowAmount > 5) {
|
|
206
|
+
return `${selectedRowAmount} rows selected`;
|
|
207
|
+
}
|
|
208
|
+
return selectedRowAmount === 0 ? "Full section" : null;
|
|
209
|
+
}
|
|
210
|
+
case filterTypes.NORMAL_FIRSTROW:
|
|
211
|
+
return `First row in ${filter.value.section}`;
|
|
212
|
+
case filterTypes.CATCH_ALL:
|
|
213
|
+
return "Matches all tickets";
|
|
214
|
+
case filterTypes.CATCH_ALL_GA:
|
|
215
|
+
return "Matches all GA tickets";
|
|
216
|
+
case filterTypes.CATCH_ALL_FLOOR:
|
|
217
|
+
return "Matches all floor tickets";
|
|
218
|
+
default:
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
139
222
|
const getFilterTitle = () => {
|
|
140
223
|
const excluded = filter.value.exclude ? "[BL]" : "";
|
|
141
224
|
switch (filterType.value) {
|
|
@@ -202,3 +285,137 @@ props.filterBuilder.onUpdate(() => {
|
|
|
202
285
|
// else if (newData.id === filter.value.id) update(newData);
|
|
203
286
|
});
|
|
204
287
|
</script>
|
|
288
|
+
|
|
289
|
+
<style scoped>
|
|
290
|
+
.filter-card {
|
|
291
|
+
@apply bg-dark-500 border-dark-550 relative;
|
|
292
|
+
border: 1px solid rgba(61, 62, 68, 0.3);
|
|
293
|
+
margin-bottom: 8px;
|
|
294
|
+
transition: all 0.15s ease-out;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.filter-card:hover:not(.expanded-filter) {
|
|
298
|
+
border-color: rgba(61, 62, 68, 0.6);
|
|
299
|
+
background-color: rgba(46, 47, 52, 0.8);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.expanded-filter:hover {
|
|
303
|
+
border-color: rgba(61, 62, 68, 0.8);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.filter-card + .filter-card {
|
|
307
|
+
border-top: 1px solid rgba(61, 62, 68, 0.2);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.filter-type-badge {
|
|
311
|
+
@apply w-6 h-6 sm:w-8 sm:h-8 rounded-full bg-dark-400 flex items-center justify-center flex-shrink-0;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.info-row {
|
|
315
|
+
@apply flex justify-between items-center;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.label {
|
|
319
|
+
@apply text-xs font-medium text-light-400;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.value {
|
|
323
|
+
@apply text-sm text-white;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.conversion-btn {
|
|
327
|
+
@apply flex items-center gap-2 px-3 py-2 bg-dark-400 hover:bg-dark-300 border border-dark-550 rounded-md text-sm font-medium transition-colors;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.control-group {
|
|
331
|
+
@apply flex items-center gap-2;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.filter-input {
|
|
335
|
+
@apply border border-dark-550 rounded px-2 py-1.5 text-sm text-white focus:outline-none transition-colors;
|
|
336
|
+
background-color: rgba(35, 36, 41, 0.9);
|
|
337
|
+
color: white;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.filter-input:focus {
|
|
341
|
+
border-color: oklch(0.28 0 0);
|
|
342
|
+
background-color: rgba(46, 47, 52, 0.9);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.filter-input::placeholder {
|
|
346
|
+
color: #9CA3AF;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.filter-action-btn {
|
|
350
|
+
@apply flex items-center justify-center rounded-full transition-all duration-200 border-2 border-transparent;
|
|
351
|
+
width: 28px;
|
|
352
|
+
height: 28px;
|
|
353
|
+
color: #9CA3AF;
|
|
354
|
+
background-color: rgba(35, 36, 41, 0.8);
|
|
355
|
+
backdrop-filter: blur(4px);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
@media (min-width: 640px) {
|
|
359
|
+
.filter-action-btn {
|
|
360
|
+
width: 32px;
|
|
361
|
+
height: 32px;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.filter-action-btn:hover {
|
|
366
|
+
color: white;
|
|
367
|
+
transform: scale(1.15);
|
|
368
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.drag-btn:hover {
|
|
372
|
+
background-color: rgba(68, 69, 75, 0.8);
|
|
373
|
+
border-color: oklch(0.28 0 0);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.delete-btn:hover {
|
|
377
|
+
background-color: rgba(239, 68, 68, 0.8);
|
|
378
|
+
border-color: #F87171;
|
|
379
|
+
color: #F87171;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.drag-handle.sortable-chosen {
|
|
383
|
+
border: 1px solid oklch(0.28 0 0);
|
|
384
|
+
background-color: rgba(68, 69, 75, 0.2);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.filter-card.sortable-ghost {
|
|
388
|
+
@apply opacity-50;
|
|
389
|
+
border: 1px solid oklch(0.28 0 0);
|
|
390
|
+
background-color: rgba(68, 69, 75, 0.1);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.filter-card.sortable-drag {
|
|
394
|
+
@apply shadow-lg transform rotate-2 scale-105;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.expanded-filter {
|
|
398
|
+
border-left: 4px solid oklch(0.28 0 0);
|
|
399
|
+
background-color: rgba(26, 27, 30, 0.95);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.expanded-content {
|
|
403
|
+
background-color: rgba(26, 27, 30, 0.95);
|
|
404
|
+
border-radius: 6px;
|
|
405
|
+
padding: 12px;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.controls-section {
|
|
409
|
+
background-color: rgba(26, 27, 30, 0.98);
|
|
410
|
+
border-radius: 6px;
|
|
411
|
+
padding: 12px;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.excluded-filter {
|
|
415
|
+
border-left: 4px solid #EE8282;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.normal-filter {
|
|
419
|
+
border-left: 4px solid transparent;
|
|
420
|
+
}
|
|
421
|
+
</style>
|