This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, watch } from "vue";
|
import { computed, onMounted, ref, watch } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
|
||||||
import { useCatalogSearch } from "@/composables/useCatalogSearch.js";
|
import { useCatalogSearch } from "@/composables/useCatalogSearch.js";
|
||||||
@@ -16,6 +16,7 @@ const route = useRoute();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const categories = ref([]);
|
const categories = ref([]);
|
||||||
const conditions = ref([]);
|
const conditions = ref([]);
|
||||||
|
const filtersOpen = ref(false);
|
||||||
const {
|
const {
|
||||||
query,
|
query,
|
||||||
category,
|
category,
|
||||||
@@ -52,6 +53,33 @@ const {
|
|||||||
initialPage: Number.parseInt(route.query.page, 10) || 1,
|
initialPage: Number.parseInt(route.query.page, 10) || 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const activeFilterCount = computed(() => [
|
||||||
|
category.value,
|
||||||
|
conditionId.value,
|
||||||
|
setName.value,
|
||||||
|
eventName.value,
|
||||||
|
tag.value,
|
||||||
|
status.value,
|
||||||
|
newlyAdded.value,
|
||||||
|
typeof minPriceMinor.value === "number",
|
||||||
|
typeof maxPriceMinor.value === "number",
|
||||||
|
sort.value !== "recent",
|
||||||
|
].filter(Boolean).length);
|
||||||
|
|
||||||
|
function resetFilters() {
|
||||||
|
category.value = "";
|
||||||
|
conditionId.value = "";
|
||||||
|
setName.value = "";
|
||||||
|
eventName.value = "";
|
||||||
|
tag.value = "";
|
||||||
|
status.value = "";
|
||||||
|
newlyAdded.value = false;
|
||||||
|
minPriceMinor.value = undefined;
|
||||||
|
maxPriceMinor.value = undefined;
|
||||||
|
sort.value = "recent";
|
||||||
|
page.value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
load(),
|
load(),
|
||||||
@@ -120,7 +148,29 @@ watch(
|
|||||||
placeholder="Try Charizard, 151, plush..."
|
placeholder="Try Charizard, 151, plush..."
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div class="catalog-filters">
|
<div class="catalog-filter-toolbar">
|
||||||
|
<button
|
||||||
|
class="catalog-filter-toggle"
|
||||||
|
type="button"
|
||||||
|
:aria-expanded="filtersOpen"
|
||||||
|
aria-controls="catalog-filter-panel"
|
||||||
|
@click="filtersOpen = !filtersOpen"
|
||||||
|
>
|
||||||
|
Filters<span v-if="activeFilterCount"> ({{ activeFilterCount }})</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-if="activeFilterCount"
|
||||||
|
class="catalog-filter-reset"
|
||||||
|
type="button"
|
||||||
|
@click="resetFilters"
|
||||||
|
>
|
||||||
|
Reset filters
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="catalog-filter-panel"
|
||||||
|
:class="['catalog-filters', { 'catalog-filters--open': filtersOpen }]"
|
||||||
|
>
|
||||||
<CatalogTextFilter v-model="setName" label="Set" placeholder="SV151" />
|
<CatalogTextFilter v-model="setName" label="Set" placeholder="SV151" />
|
||||||
<CatalogTextFilter v-model="eventName" label="Event" placeholder="Worlds" />
|
<CatalogTextFilter v-model="eventName" label="Event" placeholder="Worlds" />
|
||||||
<CatalogTextFilter v-model="tag" label="Tag" placeholder="binder" />
|
<CatalogTextFilter v-model="tag" label="Tag" placeholder="binder" />
|
||||||
@@ -212,3 +262,44 @@ watch(
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.catalog-filter-toolbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-3);
|
||||||
|
margin-top: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.catalog-filter-toggle,
|
||||||
|
.catalog-filter-reset {
|
||||||
|
min-height: 44px;
|
||||||
|
border: var(--border-thin) solid var(--color-border-strong);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: var(--space-2) var(--space-3);
|
||||||
|
background: var(--color-surface);
|
||||||
|
color: var(--color-text);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.catalog-filter-reset {
|
||||||
|
border-color: transparent;
|
||||||
|
color: var(--color-interactive-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.catalog-filters {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.catalog-filters.catalog-filters--open {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.catalog-filter-toolbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ Remaining roadmap areas are approved external provider credentials/adapters, bro
|
|||||||
- Public catalog filtering now supports URL-synchronized set, event, and tag text filters through a reusable atomic text-filter control and the shared search API.
|
- Public catalog filtering now supports URL-synchronized set, event, and tag text filters through a reusable atomic text-filter control and the shared search API.
|
||||||
- Public catalog filtering now supports explicit Available, Pending, Sold, and All status modes plus a 30-day Newly added toggle through the shared search API and atomic controls.
|
- Public catalog filtering now supports explicit Available, Pending, Sold, and All status modes plus a 30-day Newly added toggle through the shared search API and atomic controls.
|
||||||
- Public catalog sorting now supports latest manual/calculated market value low-to-high and high-to-low, with null values placed last.
|
- Public catalog sorting now supports latest manual/calculated market value low-to-high and high-to-low, with null values placed last.
|
||||||
|
- Public catalog filters now collapse behind an accessible mobile disclosure, show an active-filter count, and provide a reset action while preserving URL synchronization.
|
||||||
|
|
||||||
## Local Commands
|
## Local Commands
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user