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.
185 lines
No EOL
3.9 KiB
Vue
185 lines
No EOL
3.9 KiB
Vue
<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> |