schon/storefront/components/store/top.vue
Alexandr SaVBaD Waltz 40ae24a04c Features: 1) Add SEO-related fragments to GraphQL queries including SEOMETA_FRAGMENT usage in brands, categories, and products queries; 2) Enable localized and dynamic SEO metadata handling in category pages with Vue composables and useSeoMeta; 3) Replace obsolete client-only wrapper with native Nuxt components like nuxt-marquee for enhanced rendering;
Fixes: 1) Correct file path imports by removing `.js` extensions in GraphQL fragments; 2) Resolve typo in `usePromocodeStore` composables to ensure consistent store usage; 3) Add missing `:type="submit"` to login form button for proper form submission handling;

Extra: 1) Remove unused `.idea` and `README.md` files for repository cleanup; 2) Delete extraneous dependencies from `package-lock.json` for streamlined package management; 3) Refactor category slug handling with improved composable logic for cleaner route parameters and SEO alignment.
2025-09-13 12:53:06 +03:00

185 lines
No EOL
3.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="top">
<div class="top__main">
<div class="top__sorting">
<p>{{ t('store.sorting') }}</p>
<client-only>
<el-select
v-model="select"
size="large"
style="width: 240px"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</client-only>
</div>
<div class="top__view">
<button
class="top__view-button"
:class="{ active: productView === 'list' }"
@click="setView('list')"
>
<icon name="material-symbols:view-list-sharp" size="16" />
</button>
<button
class="top__view-button"
:class="{ active: productView === 'grid' }"
@click="setView('grid')"
>
<icon name="material-symbols:grid-view" size="16" />
</button>
</div>
</div>
<div class="top__filter" v-if="isFiltersVisible">
<button
class="top__filter-button"
@click="$emit('toggle-filter')"
>
{{ t('store.filters.title') }}
<icon name="line-md:filter" size="16" />
</button>
</div>
</div>
</template>
<script setup lang="ts">
const {t} = useI18n()
import { useAppConfig } from '~/composables/config';
const props = defineProps<{
modelValue: string
isFiltersVisible: boolean
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
(e: 'toggle-filter'): void
}>()
const { COOKIES_PRODUCT_VIEW_KEY } = useAppConfig()
const productView = useCookie(COOKIES_PRODUCT_VIEW_KEY as string)
function setView(view: 'list' | 'grid') {
productView.value = view
}
const select = ref(props.modelValue || 'created')
const options = [
{
value: 'created',
label: 'New',
},
{
value: 'rating',
label: 'Rating',
},
{
value: 'price',
label: 'Сheap first',
},
{
value: '-price',
label: 'Expensive first',
}
]
watch(select, value => {
emit('update:modelValue', value)
})
</script>
<style scoped lang="scss">
.top {
margin-bottom: 20px;
width: 100%;
position: relative;
z-index: 2;
display: flex;
align-items: flex-start;
justify-content: space-between;
&__main {
display: flex;
align-items: center;
gap: 75px;
padding: 15px 30px;
background-color: $white;
border-radius: $default_border_radius;
border: 1px solid #dedede;
box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}
&__filter {
padding: 15px 30px;
background-color: $white;
border-radius: $default_border_radius;
border: 1px solid #dedede;
box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
&-button {
cursor: pointer;
border-radius: $default_border_radius;
background-color: rgba($accent, 0.2);
border: 1px solid $accent;
padding: 7px 20px;
display: flex;
align-items: center;
gap: 10px;
transition: 0.2s;
color: $accent;
font-size: 16px;
font-weight: 600;
@include hover {
background-color: $accent;
color: $white;
}
}
}
&__sorting {
display: flex;
align-items: center;
gap: 20px;
& p {
font-weight: 700;
font-size: 14px;
color: $accentDark;
}
}
&__view {
display: flex;
align-items: center;
gap: 1px;
border-radius: $default_border_radius;
border: 1px solid #7965d1;
background-color: rgba($accent, 0.2);
&-button {
cursor: pointer;
background-color: transparent;
display: grid;
place-items: center;
padding: 5px 12px;
transition: 0.2s;
color: $accent;
@include hover {
background-color: rgba($accent, 1);
color: $white;
}
&.active {
background-color: rgba($accent, 1);
color: $white;
}
}
}
}
</style>