Grid mode

This commit is contained in:
William Buezas 2024-09-22 20:12:25 -03:00
parent ff0d2db8fe
commit 72cd9e6cd6
3 changed files with 158 additions and 65 deletions

View File

@ -104,10 +104,7 @@ onMounted(async () => {
</QBtn>
</Teleport>
<QPage class="vn-w-sm">
<QList
class="rounded-borders shadow-1 shadow-transition"
separator
>
<QList class="rounded-borders shadow-1 shadow-transition" separator>
<CardList
v-for="(address, index) in addresses"
:key="index"

View File

@ -1,40 +1,37 @@
<script setup>
import { onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import VnImg from 'src/components/ui/VnImg.vue';
import CardList from 'src/components/ui/CardList.vue';
import { currency } from 'src/lib/filters.js';
defineProps({
item: { type: Object, default: () => {} }
item: { type: Object, default: () => {} },
viewMode: { type: String, default: 'grid' }
});
const { t } = useI18n();
onMounted(async () => {});
</script>
<template>
<QCard v-ripple class="catalog-card">
<QCard v-if="viewMode === 'grid'" 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">
<div class="text-subtitle2 ellipsis-2-lines">
{{ item.item }}
</div>
<div
class="row justify-between sub-name text-uppercase text-subtitle1 text-grey-7"
class="row justify-between text-uppercase text-subtitle1 text-grey-7"
>
<span class="text-subtitle2">
{{ item.subName }}
@ -42,29 +39,15 @@ onMounted(async () => {});
<span> #{{ item.id }}</span>
</div>
<div class="tags q-pt-xs text-caption">
<div class="full-width row">
<div
v-for="(tag, index) in item.previewTags"
:key="index"
class="full-width row"
>
<span class="text-grey-7 col">
{{ item.tag5 }}
{{ tag.name }}
</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>
<span class="col ellipsis">{{ tag.value }}</span>
</div>
</div>
</div>
@ -103,6 +86,71 @@ onMounted(async () => {});
</div>
</div>
</QCard>
<CardList v-else class="vn-w-sm">
<template #prepend>
<div style="min-height: 105px; min-width: 105px" class="q-mr-md">
<VnImg
storage="catalog"
size="200x200"
:id="item.image"
rounded="bottom"
class="full-height full-width"
/>
</div>
</template>
<template #content>
<span class="ellipsis-2-lines">
{{ item.item }}
</span>
<div class="row justify-between text-uppercase text-grey-7">
<span>{{ item.subName }}</span>
<span>#{{ item.id }}</span>
</div>
<div
v-for="(tag, index) in item.previewTags"
:key="index"
class="full-width row"
>
<span class="text-grey-7 col">
{{ tag.name }}
</span>
<span class="col ellipsis">{{ tag.value }}</span>
</div>
<div class="row justify-end items-center q-gutter-x-xs q-mt-sm">
<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-3 justify-end text-body2"
>
<QTooltip>
{{ t('available') }}
</QTooltip>
</QBadge>
<QBadge
outline
:label="currency(item.price)"
color="accent"
text-color="black"
class="col-3 justify-end text-body2"
>
<QTooltip>
{{ t('groupingPrice') }}
</QTooltip>
</QBadge>
</div>
</template>
</CardList>
</template>
<style lang="scss" scoped>
@ -118,12 +166,17 @@ onMounted(async () => {});
<i18n lang="yaml">
en-US:
groupingPrice: Price per group
minGrouping: Minimum packing
es-ES:
groupingPrice: Precio por grupo
minGrouping: Cantidad mínima
ca-ES:
groupingPrice: Preu per grup
minGrouping: Empaquetament mínim
fr-FR:
groupingPrice: Prix par groupe
minGrouping: Emballage minimum
pt-PT:
groupingPrice: Preço por grupo
minGrouping: Embalagem mínima
</i18n>

View File

@ -20,20 +20,28 @@
/>
</template>
</QInput> -->
<!-- <QBtn
:icon="$t(viewMode == 'list' ? 'view_list' : 'grid_on')"
:label="$t(viewMode == 'list' ? 'listView' : 'gridView')"
<QBtn
:icon="viewTypeButtonContent.icon"
:label="viewTypeButtonContent.label"
@click="onViewModeClick()"
rounded
no-caps
/> -->
>
<QTooltip>
{{ viewTypeButtonContent.label }}
</QTooltip>
</QBtn>
<QBtn
icon="shopping_cart_checkout"
:label="t('shoppingCart')"
:to="{ name: 'basket' }"
rounded
no-caps
/>
>
<QTooltip>
{{ t('shoppingCart') }}
</QTooltip>
</QBtn>
</Teleport>
<div style="padding-bottom: 5em">
<QDrawer v-model="rightDrawerOpen" side="right" :width="250">
@ -214,7 +222,13 @@
</div> -->
</QDrawer>
<QInfiniteScroll>
<div class="q-pa-md row justify-center q-gutter-md">
<div
:class="
viewMode === 'grid'
? 'q-pa-md row justify-center q-gutter-md'
: 'column items-center'
"
>
<QSpinner
v-if="loading"
color="primary"
@ -233,6 +247,7 @@
v-for="_item in items"
:key="_item.id"
:item="_item"
:view-mode="viewMode"
@click="showItem(_item)"
/>
</div>
@ -354,6 +369,7 @@ const selectedItem = ref(null);
const showItemDialog = ref(false);
const loading = ref(false);
const isGuest = ref(false); // TODO: Integrate isGuest logic
const viewMode = ref('grid');
// Filters options
const categories = ref([]);
@ -423,10 +439,10 @@ const selectedCategory = computed({
category.value = value;
router.push({ params: { category: category.value, type: null } });
onCategoryChange();
refreshTitle();
if (!value) return;
getFilters();
getItems();
refreshTitle();
}
});
@ -511,7 +527,7 @@ const queryFilter = computed(() => {
// Filtro principal
if (selectedCategory.value) {
filters.push(`t.categoryFk = ${selectedCategory.value}`);
filters.push(`(t.categoryFk = ${selectedCategory.value})`);
}
const otherFilters = {
@ -524,7 +540,7 @@ const queryFilter = computed(() => {
// Añadir solo aquellos filtros que tengan valor
Object.entries(otherFilters).forEach(([key, value]) => {
if (value) {
filters.push(`${key} = ${value}`);
filters.push(`(${key} = ${value})`);
}
});
@ -542,6 +558,13 @@ const isSomeFilterSelected = computed(() => {
);
});
const viewTypeButtonContent = computed(() => {
return {
label: t(viewMode.value === 'list' ? 'listView' : 'gridView'),
icon: viewMode.value === 'list' ? 'view_list' : 'grid_on'
};
});
const getOrder = async () => {
try {
const [data] = await jApi.query(
@ -619,10 +642,26 @@ const getItemColors = async () => {
}
};
const onItemsFetched = async () => {
items.value.forEach(item => {
const previewTags = [
{ name: item.tag5, value: item.value5 },
{ name: item.tag6, value: item.value6 },
{ name: item.tag7, value: item.value7 }
];
item.previewTags = previewTags;
});
};
const getItems = async () => {
try {
if (
!selectedCategory.value ||
!basketOrderId.value ||
!isSomeFilterSelected.value
)
return;
loading.value = true;
if (!selectedCategory.value || !basketOrderId.value) return;
const res = await jApi.execQuery(
`DROP TEMPORARY TABLE IF EXISTS tmp.item;
@ -656,11 +695,10 @@ const getItems = async () => {
{ orderId: basketOrderId.value }
);
items.value = res.results[3].data;
console.log('get items: ', items.value);
await onItemsFetched();
loading.value = false;
} catch (error) {
console.error('Error getting items:', error);
} finally {
loading.value = false;
}
};
@ -709,13 +747,14 @@ const getSubcategories = async () => {
try {
const res = await jApi.execQuery(
`CALL myOrder_getAvailable(#orderId);
SELECT DISTINCT i.category, i.category
SELECT DISTINCT i.category
FROM vn.item i
JOIN vn.itemType t ON t.id = i.typeFk
JOIN tmp.itemAvailable a ON a.id = i.id
WHERE #filter
WHERE (${queryFilter.value})
ORDER BY category;
DROP TEMPORARY TABLE tmp.itemAvailable;`
DROP TEMPORARY TABLE tmp.itemAvailable;`,
{ orderId: basketOrderId.value }
);
itemSubcategories.value = res.results[1].data;
} catch (error) {
@ -739,12 +778,11 @@ const showItem = async item => {
if (isGuest.value) return;
const itemLots = await calcItem(item.id);
const tags = await getItemTags(item.id);
item.tags = tags;
const tags = getItemTags(item.id);
item.lots = itemLots;
item.tags = tags;
showItemDialog.value = true;
selectedItem.value = item;
console.log('selected item: ', selectedItem.value);
};
const removeCategory = () => {
@ -759,7 +797,6 @@ const onCategoryChange = () => {
selectedOrigin.value = null;
selectedSubcategory.value = null;
items.value = [];
router.push({ params: { category: null, type: null } });
};
const getItemTags = async itemFk => {
@ -891,7 +928,6 @@ const refreshTitle = () => {
const _category = categories.value.find(
i => i.id === selectedCategory.value
);
if (_category) {
title = _category.name;
@ -899,7 +935,6 @@ const refreshTitle = () => {
const _type = itemFamilies.value.find(
i => i.id === selectedType.value
);
if (_type) {
subtitle = title;
title = _type.name;
@ -911,6 +946,10 @@ const refreshTitle = () => {
appStore.$patch({ title, subtitle });
};
const onViewModeClick = () => {
viewMode.value = viewMode.value === 'list' ? 'grid' : 'list';
};
onBeforeMount(async () => {
if (!isGuest.value) {
await appStore.check('catalog');
@ -924,8 +963,9 @@ onBeforeMount(async () => {
await getOrder();
await getCategories();
if (route.params.category) selectedCategory.value = route.params.category;
if (route.params.type) selectedType.value = route.params.type;
if (route.params.category)
selectedCategory.value = Number(route.params.category);
if (route.params.type) selectedType.value = Number(route.params.type);
});
</script>
@ -977,12 +1017,11 @@ en-US:
higherSize: Higher size
lowerPrice: Lower price
higherPrice: Higher price
minGrouping: Minimum packing
add: Add
added: Added
listView: List view
gridView: Grid view
es-ES:
gridView: Vista de rejilla
listView: Vista de lista
warehouse: Almacén
agency: Agencia
modify: Modificar
@ -1002,9 +1041,10 @@ es-ES:
higherSize: Medida más grande
lowerPrice: Precio más bajo
higherPrice: Precio más alto
minGrouping: Cantidad mínima
add: Añadir
added: Añadido
listView: Vista de lista
gridView: Vista de rejilla
ca-ES:
category: Categoría
deleteFilter: Eliminar filtro
@ -1020,8 +1060,9 @@ ca-ES:
higherSize: Mida més gran
lowerPrice: Preu més baix
higherPrice: Preu més alt
minGrouping: Empaquetament mínim
add: Afegir
listView: Vista de llista
gridView: Vista de graella
fr-FR:
category: Catégorie
deleteFilter: Supprimer le filtre
@ -1037,8 +1078,9 @@ fr-FR:
higherSize: Taille le plus élevé
lowerPrice: Prix le plus bas
higherPrice: Prix le plus élevé
minGrouping: Emballage minimum
add: Ajouter
listView: Vue en liste
gridView: Vue en grille
pt-PT:
category: Categoria
deleteFilter: Apagar filtro
@ -1054,6 +1096,7 @@ pt-PT:
higherSize: Tamanho maior
lowerPrice: Preço mais baixo
higherPrice: Preço mais alto
minGrouping: Embalagem mínima
add: Adicionar
listView: Vista de lista
gridView: Vista de grade
</i18n>