schon/storefront/components/store/top.vue
Alexandr SaVBaD Waltz 129ad1a6fa Features: 1) Build standalone pages for search, contact, catalog, category, brand, product, and home with localized metadata and scoped styles; 2) Add extensive TypeScript definitions for API and app-level structures, including products, orders, brands, and categories; 3) Implement i18n configuration with dynamic browser language detection and fallback system;
Fixes: None;

Extra: 1) Create Pinia stores for app, user, category, and company management; 2) Add utility functions for error handling and category slug lookups; 3) Include German locale file and robots.txt for improved SEO and accessibility; 4) Add SVG assets and improve general folder structure for better maintainability.
2025-06-27 00:10:35 +03:00

184 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">
<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
}>()
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: 1;
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>