0
1
Fork 0

Filters changes and create card component

This commit is contained in:
William Buezas 2024-09-22 18:47:06 -03:00
parent bbaa6d87ff
commit ff0d2db8fe
7 changed files with 205 additions and 145 deletions

View File

@ -104,6 +104,7 @@ export default {
password: 'Contrasenya', password: 'Contrasenya',
modify: 'Modificar', modify: 'Modificar',
shoppingCart: 'Cistella de la compra', shoppingCart: 'Cistella de la compra',
available: 'Disponible',
// Image related translations // Image related translations
'Cant lock cache': 'No es pot bloquejar la memòria cau', 'Cant lock cache': 'No es pot bloquejar la memòria cau',
'Bad file format': 'Format de fitxer no reconegut', 'Bad file format': 'Format de fitxer no reconegut',

View File

@ -137,6 +137,7 @@ export default {
password: 'Password', password: 'Password',
modify: 'Modify', modify: 'Modify',
shoppingCart: 'Shopping cart', shoppingCart: 'Shopping cart',
available: 'Available',
// Image related translations // Image related translations
'Cant lock cache': 'The cache could not be blocked', 'Cant lock cache': 'The cache could not be blocked',
'Bad file format': 'Unrecognized file format', 'Bad file format': 'Unrecognized file format',

View File

@ -136,6 +136,7 @@ export default {
of: 'de', of: 'de',
modify: 'Modificar', modify: 'Modificar',
shoppingCart: 'Cesta de la compra', shoppingCart: 'Cesta de la compra',
available: 'Disponible',
// Image related translations // Image related translations
'Cant lock cache': 'La caché no pudo ser bloqueada', 'Cant lock cache': 'La caché no pudo ser bloqueada',
'Bad file format': 'Formato de archivo no reconocido', 'Bad file format': 'Formato de archivo no reconocido',

View File

@ -104,6 +104,7 @@ export default {
password: 'Mot de passe', password: 'Mot de passe',
modify: 'Modifier', modify: 'Modifier',
shoppingCart: 'Panier', shoppingCart: 'Panier',
available: 'Disponible',
// Image related translations // Image related translations
'Cant lock cache': "Le cache n'a pas pu être verrouillé", 'Cant lock cache': "Le cache n'a pas pu être verrouillé",
'Bad file format': 'Format de fichier non reconnu', 'Bad file format': 'Format de fichier non reconnu',

View File

@ -102,6 +102,7 @@ export default {
password: 'Senha', password: 'Senha',
modify: 'Modificar', modify: 'Modificar',
shoppingCart: 'Cesta da compra', shoppingCart: 'Cesta da compra',
available: 'Disponível',
// Image related translations // Image related translations
'Cant lock cache': 'O cache não pôde ser bloqueado', 'Cant lock cache': 'O cache não pôde ser bloqueado',
'Bad file format': 'Formato de arquivo inválido', 'Bad file format': 'Formato de arquivo inválido',

View File

@ -0,0 +1,129 @@
<script setup>
import { onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import VnImg from 'src/components/ui/VnImg.vue';
import { currency } from 'src/lib/filters.js';
defineProps({
item: { type: Object, default: () => {} }
});
const { t } = useI18n();
onMounted(async () => {});
</script>
<template>
<QCard v-ripple class="catalog-card">
<div style="height: 210px">
<VnImg
storage="catalog"
size="200x200"
:id="item.image"
width="80px"
height="80px"
rounded="bottom"
class="full-height full-width"
/>
</div>
<div class="column" style="height: 205px; padding: 10px">
<div class="column" style="margin-bottom: auto">
<div class="text-subtitle2">
{{ item.item }}
</div>
<div
class="row justify-between sub-name text-uppercase text-subtitle1 text-grey-7"
>
<span class="text-subtitle2">
{{ item.subName }}
</span>
<span> #{{ item.id }}</span>
</div>
<div class="tags q-pt-xs text-caption">
<div class="full-width row">
<span class="text-grey-7 col">
{{ item.tag5 }}
</span>
<span class="col">{{ item.value5 }}</span>
</div>
<div class="full-width row">
<span class="text-grey-7 col">
{{ item.tag6 }}
</span>
<span class="col">{{ item.value6 }}</span>
</div>
<div class="full-width row">
<span class="text-grey-7 col">
{{ item.tag7 }}
</span>
<span class="col">{{ item.value7 }}</span>
</div>
<div class="full-width row">
<span class="text-grey-7 col">
{{ item.tag8 }}
</span>
<span class="col">{{ item.value8 }}</span>
</div>
</div>
</div>
<div class="row justify-between items-cente q-gutter-x-xs">
<QBadge
:label="`x${item.grouping}`"
color="grey"
class="col-2 justify-end text-body2"
>
<QTooltip>
{{ t('minGrouping') }}
</QTooltip>
</QBadge>
<QBadge
outline
:label="item.available"
color="accent"
text-color="black"
class="col justify-end text-body2"
>
<QTooltip>
{{ t('available') }}
</QTooltip>
</QBadge>
<QBadge
outline
:label="currency(item.price)"
color="accent"
text-color="black"
class="col justify-end text-body2"
>
<QTooltip>
{{ t('groupingPrice') }}
</QTooltip>
</QBadge>
</div>
</div>
</QCard>
</template>
<style lang="scss" scoped>
.catalog-card {
display: flex;
flex-direction: column;
width: 210px;
overflow: hidden;
cursor: pointer;
}
</style>
<i18n lang="yaml">
en-US:
groupingPrice: Price per group
es-ES:
groupingPrice: Precio por grupo
ca-ES:
groupingPrice: Preu per grup
fr-FR:
groupingPrice: Prix par groupe
pt-PT:
groupingPrice: Preço por grupo
</i18n>

View File

@ -222,109 +222,19 @@
:thickness="2" :thickness="2"
/> />
<div <div
v-else-if="!items || !items.length || !type" v-else-if="!items || !items.length || !isSomeFilterSelected"
class="text-subtitle1 text-grey-7 q-pa-md" class="text-subtitle1 text-grey-7 q-pa-md"
> >
<QIcon name="refresh" size="sm" class="q-mr-sm"></QIcon> <QIcon name="refresh" size="sm" class="q-mr-sm"></QIcon>
<span>{{ t('pleaseSetFilter') }}</span> <span>{{ t('pleaseSetFilter') }}</span>
</div> </div>
<CatalogCard
<QCard
v-else v-else
v-for="_item in items" v-for="_item in items"
:key="_item.id" :key="_item.id"
v-ripple :item="_item"
class="my-card"
@click="showItem(_item)" @click="showItem(_item)"
> />
<div style="height: 210px">
<VnImg
storage="catalog"
size="200x200"
:id="_item.image"
width="80px"
height="80px"
rounded="bottom"
class="full-height full-width"
/>
</div>
<div class="column" style="height: 205px; padding: 10px">
<div class="column" style="margin-bottom: auto">
<div class="text-subtitle2">
{{ _item.item }}
</div>
<div
class="row justify-between sub-name text-uppercase text-subtitle1 text-grey-7"
>
<span class="text-subtitle2">
{{ _item.subName }}
</span>
<span> #{{ _item.id }}</span>
</div>
<div class="tags q-pt-xs text-caption">
<div class="full-width row">
<span class="text-grey-7 col">
{{ _item.tag5 }}
</span>
<span class="col">{{ _item.value5 }}</span>
</div>
<div class="full-width row">
<span class="text-grey-7 col">
{{ _item.tag6 }}
</span>
<span class="col">{{ _item.value6 }}</span>
</div>
<div class="full-width row">
<span class="text-grey-7 col">
{{ _item.tag7 }}
</span>
<span class="col">{{ _item.value7 }}</span>
</div>
<div class="full-width row">
<span class="text-grey-7 col">
{{ _item.tag8 }}
</span>
<span class="col">{{ _item.value8 }}</span>
</div>
</div>
</div>
<div
class="row justify-between items-cente q-gutter-x-xs"
>
<QBadge
:label="`x${_item.grouping}`"
color="grey"
class="col-2 justify-end text-body2"
>
<QTooltip>
{{ t('minGrouping') }}
</QTooltip>
</QBadge>
<QBadge
outline
:label="_item.available"
color="accent"
text-color="black"
class="col justify-end text-body2"
>
<QTooltip>
{{ t('available') }}
</QTooltip>
</QBadge>
<QBadge
outline
:label="currency(_item.price)"
color="accent"
text-color="black"
class="col justify-end text-body2"
>
<QTooltip>
{{ t('groupingPrice') }}
</QTooltip>
</QBadge>
</div>
</div>
</QCard>
</div> </div>
</QInfiniteScroll> </QInfiniteScroll>
<QDialog v-model="showItemDialog"> <QDialog v-model="showItemDialog">
@ -417,11 +327,12 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { inject, onMounted, onBeforeMount, ref, computed } from 'vue'; import { inject, onBeforeMount, ref, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import VnImg from 'src/components/ui/VnImg.vue'; import VnImg from 'src/components/ui/VnImg.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import CatalogCard from 'src/pages/Ecomerce/CatalogCard.vue';
import { useAppStore } from 'stores/app'; import { useAppStore } from 'stores/app';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
@ -511,7 +422,8 @@ const selectedCategory = computed({
async set(value) { async set(value) {
category.value = value; category.value = value;
router.push({ params: { category: category.value, type: null } }); router.push({ params: { category: category.value, type: null } });
console.log('category', category.value); onCategoryChange();
refreshTitle();
if (!value) return; if (!value) return;
getFilters(); getFilters();
getItems(); getItems();
@ -525,9 +437,10 @@ const selectedType = computed({
set(value) { set(value) {
type.value = value; type.value = value;
router.push({ params: { category: category.value, type: type.value } }); router.push({ params: { category: category.value, type: type.value } });
console.log('type', type.value); if (!selectedCategory.value) return;
getFilters(); getFilters();
getItems(); getItems();
refreshTitle();
} }
}); });
@ -537,6 +450,7 @@ const selectedColor = computed({
}, },
set(value) { set(value) {
color.value = value; color.value = value;
if (!selectedCategory.value) return;
getFilters(); getFilters();
getItems(); getItems();
} }
@ -548,7 +462,7 @@ const selectedProducer = computed({
}, },
set(value) { set(value) {
producer.value = value; producer.value = value;
if (!value) return; if (!value || !selectedCategory.value) return;
getFilters(); getFilters();
getItems(); getItems();
} }
@ -560,7 +474,7 @@ const selectedOrigin = computed({
}, },
set(value) { set(value) {
origin.value = value; origin.value = value;
if (!value) return; if (!value || !selectedCategory.value) return;
getFilters(); getFilters();
getItems(); getItems();
} }
@ -572,7 +486,7 @@ const selectedSubcategory = computed({
}, },
set(value) { set(value) {
subcategory.value = value; subcategory.value = value;
if (!value) return; if (!value && !selectedCategory.value) return;
getFilters(); getFilters();
getItems(); getItems();
} }
@ -593,20 +507,29 @@ const selectedOrderBy = computed({
}); });
const queryFilter = computed(() => { const queryFilter = computed(() => {
let filter = ''; const filters = [];
// Filtro principal
if (selectedCategory.value) { if (selectedCategory.value) {
filter = `(t.categoryFk = ${selectedCategory.value})`; filters.push(`t.categoryFk = ${selectedCategory.value}`);
}
if (selectedType.value) {
if (filter) filter += ' AND ';
filter += `(i.typeFk = ${selectedType.value})`;
}
if (selectedColor.value) {
if (filter) filter += ' AND ';
filter += `(i.inkFk = '${selectedColor?.value}')`;
} }
return filter; const otherFilters = {
'i.typeFk': selectedType.value,
'i.inkFk': selectedColor?.value ? `'${selectedColor.value}'` : null,
'i.producerFk': selectedProducer.value,
'i.originFk': selectedOrigin.value
};
// Añadir solo aquellos filtros que tengan valor
Object.entries(otherFilters).forEach(([key, value]) => {
if (value) {
filters.push(`${key} = ${value}`);
}
});
// Concatenar todos los filtros
return filters.join(' AND ');
}); });
const isSomeFilterSelected = computed(() => { const isSomeFilterSelected = computed(() => {
@ -629,7 +552,6 @@ const getOrder = async () => {
{ orderId: basketOrderId.value } { orderId: basketOrderId.value }
); );
order.value = data; order.value = data;
console.log('order', order.value);
} catch (error) { } catch (error) {
console.error('Error getting order:', error); console.error('Error getting order:', error);
} }
@ -700,12 +622,7 @@ const getItemColors = async () => {
const getItems = async () => { const getItems = async () => {
try { try {
loading.value = true; loading.value = true;
if ( if (!selectedCategory.value || !basketOrderId.value) return;
!selectedCategory.value ||
!basketOrderId.value ||
!selectedType.value
)
return;
const res = await jApi.execQuery( const res = await jApi.execQuery(
`DROP TEMPORARY TABLE IF EXISTS tmp.item; `DROP TEMPORARY TABLE IF EXISTS tmp.item;
@ -762,7 +679,6 @@ const getProducers = async () => {
{ orderId: basketOrderId.value } { orderId: basketOrderId.value }
); );
itemProducers.value = res.results[1].data; itemProducers.value = res.results[1].data;
console.log('Producers:', itemProducers.value);
} catch (error) { } catch (error) {
console.error('Error getting productors:', error); console.error('Error getting productors:', error);
} }
@ -784,7 +700,6 @@ const getOrigins = async () => {
{ orderId: basketOrderId.value } { orderId: basketOrderId.value }
); );
itemOrigins.value = res.results[1].data; itemOrigins.value = res.results[1].data;
console.log('Producers:', itemOrigins.value);
} catch (error) { } catch (error) {
console.error('Error getting productors:', error); console.error('Error getting productors:', error);
} }
@ -834,6 +749,10 @@ const showItem = async item => {
const removeCategory = () => { const removeCategory = () => {
selectedCategory.value = null; selectedCategory.value = null;
onCategoryChange();
};
const onCategoryChange = () => {
selectedType.value = null; selectedType.value = null;
selectedColor.value = null; selectedColor.value = null;
selectedProducer.value = null; selectedProducer.value = null;
@ -963,7 +882,34 @@ const onConfirmClick = async params => {
} }
}; };
// const refreshTitle = () => {}; const refreshTitle = () => {
const { meta } = route;
let title = t(meta.title);
let subtitle;
if (selectedCategory.value) {
const _category = categories.value.find(
i => i.id === selectedCategory.value
);
if (_category) {
title = _category.name;
if (selectedType.value) {
const _type = itemFamilies.value.find(
i => i.id === selectedType.value
);
if (_type) {
subtitle = title;
title = _type.name;
}
}
}
}
appStore.$patch({ title, subtitle });
};
onBeforeMount(async () => { onBeforeMount(async () => {
if (!isGuest.value) { if (!isGuest.value) {
@ -975,13 +921,11 @@ onBeforeMount(async () => {
// resultSet.fetchResult(); // resultSet.fetchResult();
// this.orderId = resultSet.fetchValue(); // this.orderId = resultSet.fetchValue();
} }
getOrder(); await getOrder();
getCategories(); await getCategories();
});
onMounted(async () => { if (route.params.category) selectedCategory.value = route.params.category;
selectedCategory.value = route.params.category; if (route.params.type) selectedType.value = route.params.type;
selectedType.value = route.params.type;
}); });
</script> </script>
@ -1015,14 +959,6 @@ onMounted(async () => {
} }
} }
} }
.my-card {
display: flex;
flex-direction: column;
width: 210px;
overflow: hidden;
cursor: pointer;
}
</style> </style>
<i18n lang="yaml"> <i18n lang="yaml">
@ -1041,9 +977,7 @@ en-US:
higherSize: Higher size higherSize: Higher size
lowerPrice: Lower price lowerPrice: Lower price
higherPrice: Higher price higherPrice: Higher price
available: Available
minGrouping: Minimum packing minGrouping: Minimum packing
groupingPrice: Price per group
add: Add add: Add
added: Added added: Added
es-ES: es-ES:
@ -1068,9 +1002,7 @@ es-ES:
higherSize: Medida más grande higherSize: Medida más grande
lowerPrice: Precio más bajo lowerPrice: Precio más bajo
higherPrice: Precio más alto higherPrice: Precio más alto
available: Disponible
minGrouping: Cantidad mínima minGrouping: Cantidad mínima
groupingPrice: Precio por grupo
add: Añadir add: Añadir
added: Añadido added: Añadido
ca-ES: ca-ES:
@ -1088,9 +1020,7 @@ ca-ES:
higherSize: Mida més gran higherSize: Mida més gran
lowerPrice: Preu més baix lowerPrice: Preu més baix
higherPrice: Preu més alt higherPrice: Preu més alt
available: Disponible
minGrouping: Empaquetament mínim minGrouping: Empaquetament mínim
groupingPrice: Preu per grup
add: Afegir add: Afegir
fr-FR: fr-FR:
category: Catégorie category: Catégorie
@ -1107,9 +1037,7 @@ fr-FR:
higherSize: Taille le plus élevé higherSize: Taille le plus élevé
lowerPrice: Prix le plus bas lowerPrice: Prix le plus bas
higherPrice: Prix le plus élevé higherPrice: Prix le plus élevé
available: Disponible
minGrouping: Emballage minimum minGrouping: Emballage minimum
groupingPrice: Prix par groupe
add: Ajouter add: Ajouter
pt-PT: pt-PT:
category: Categoria category: Categoria
@ -1126,8 +1054,6 @@ pt-PT:
higherSize: Tamanho maior higherSize: Tamanho maior
lowerPrice: Preço mais baixo lowerPrice: Preço mais baixo
higherPrice: Preço mais alto higherPrice: Preço mais alto
available: Disponível
minGrouping: Embalagem mínima minGrouping: Embalagem mínima
groupingPrice: Preço por grupo
add: Adicionar add: Adicionar
</i18n> </i18n>