- catalogo avanti, parte 1
This commit is contained in:
@@ -2087,4 +2087,77 @@ export const shared_consts = {
|
||||
TYPEHOSP_SCAMBIOCASA: 1,
|
||||
TYPEHOSP_OSPITALITA: 2,
|
||||
|
||||
PRODUCTTYPE: {
|
||||
BENE: 1,
|
||||
SERVIZIO: 2,
|
||||
OSPITALITA: 4,
|
||||
PRODOTTO: 10,
|
||||
LIBRO: 20,
|
||||
EBOOK: 21,
|
||||
AUDIOLIBRO: 22,
|
||||
VIDEO: 23,
|
||||
CARTE: 25,
|
||||
},
|
||||
|
||||
VERSIONE: {
|
||||
NUOVO: 1,
|
||||
USATO: 2,
|
||||
DOWNLOAD: 3,
|
||||
DVD: 4,
|
||||
EPUB: 5,
|
||||
MOBI: 6,
|
||||
PDF: 7,
|
||||
STREAMING: 8,
|
||||
},
|
||||
|
||||
VERSIONI_PRODOTTO: [
|
||||
{
|
||||
label: '[Nessuno]',
|
||||
value: 0,
|
||||
color: '',
|
||||
},
|
||||
{
|
||||
label: 'Nuovo',
|
||||
value: 1,
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
label: 'Usato',
|
||||
value: 2,
|
||||
color: 'warning',
|
||||
},
|
||||
{
|
||||
label: 'Download',
|
||||
value: 3,
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
label: 'DVD',
|
||||
value: 4,
|
||||
color: 'secondary',
|
||||
},
|
||||
{
|
||||
label: 'EPUB',
|
||||
value: 5,
|
||||
color: 'orange',
|
||||
},
|
||||
{
|
||||
label: 'MOBI',
|
||||
value: 6,
|
||||
color: 'indigo',
|
||||
},
|
||||
{
|
||||
label: 'PDF',
|
||||
value: 7,
|
||||
color: 'purple',
|
||||
},
|
||||
{
|
||||
label: 'Streaming',
|
||||
value: 8,
|
||||
color: 'red',
|
||||
},
|
||||
|
||||
],
|
||||
|
||||
|
||||
}
|
||||
|
||||
208
src/components/CCatalogoCard/CCatalogoCard.scss
Executable file
208
src/components/CCatalogoCard/CCatalogoCard.scss
Executable file
@@ -0,0 +1,208 @@
|
||||
.card .product-image {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.text-title {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.centeritems {
|
||||
place-content: center;
|
||||
}
|
||||
|
||||
.prod_price {
|
||||
font-size: 1.25rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.prod_sale_price {
|
||||
font-size: 1.25rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.prod_off_price {
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
color: gray;
|
||||
text-decoration: line-through;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.prod_disp {
|
||||
font-size: 1.2rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.prod_preorder {
|
||||
font-size: 1.2rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.prod_qtywarn {
|
||||
padding-left: 10px;
|
||||
font-size: 1rem;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.totali {
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.prod_sconti {
|
||||
font-size: 1.1rem;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.product_code {
|
||||
font-size: 0.75rem;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.label-qta {
|
||||
font-size: 1.15rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.countdown_scadenza {
|
||||
font-size: 1.15rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subtit_prod {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.icone_prod {
|
||||
font-size: 1.25rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.fullscreen-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.fullscreen-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.titolo_prod {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-section {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card_titolo_prod {
|
||||
text-align: center;
|
||||
padding: 4px 4px 4px 4px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.img-pic {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.q-card__section--vert {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.book-details {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.book-card {
|
||||
max-width: 300px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.book-card-section {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.book-image {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.book-image q-img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.book-info {
|
||||
flex: 2;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.book-title {
|
||||
font-family: 'Poppins,sans-serif';
|
||||
font-size: 1rem;
|
||||
line-height: 20px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.book-author {
|
||||
color: #263238;
|
||||
display: block;
|
||||
font-family: Poppins, sans-serif;
|
||||
font-size: 0.85em;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.book-description {
|
||||
font-size: 0.85rem;
|
||||
color: #777;
|
||||
}
|
||||
478
src/components/CCatalogoCard/CCatalogoCard.ts
Executable file
478
src/components/CCatalogoCard/CCatalogoCard.ts
Executable file
@@ -0,0 +1,478 @@
|
||||
import { defineComponent, ref, toRef, computed, PropType, watch, onMounted, reactive, onBeforeUnmount } from 'vue'
|
||||
import { useI18n } from '@src/boot/i18n'
|
||||
import { useUserStore } from '@store/UserStore'
|
||||
import { useGlobalStore } from '@store/globalStore'
|
||||
import { useQuasar } from 'quasar'
|
||||
|
||||
import { CTitleBanner } from '../CTitleBanner'
|
||||
import { CCardState } from '../CCardState'
|
||||
import { CCopyBtn } from '../CCopyBtn'
|
||||
import { CMyValueDb } from '../CMyValueDb'
|
||||
|
||||
import { func_tools, toolsext } from '@store/Modules/toolsext'
|
||||
|
||||
import { IBaseOrder, IGasordine, IOrder, IOrderCart, IProduct } from '@src/model'
|
||||
import { tools } from '@store/Modules/tools'
|
||||
import { useProducts } from '@store/Products'
|
||||
|
||||
import { shared_consts } from '@src/common/shared_vuejs'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { costanti } from '@costanti'
|
||||
|
||||
import VuePdfApp from 'vue3-pdf-app'
|
||||
// import this to use default icons for buttons
|
||||
import 'vue3-pdf-app/dist/icons/main.css'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CCatalogoCard',
|
||||
props: {
|
||||
product: {
|
||||
type: Object as PropType<IProduct | null>,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
cosa: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
complete: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
components: { CTitleBanner, CCardState, CCopyBtn, CMyValueDb, VuePdfApp },
|
||||
setup(props, { emit }) {
|
||||
const $q = useQuasar()
|
||||
const { t } = useI18n()
|
||||
const userStore = useUserStore()
|
||||
const globalStore = useGlobalStore()
|
||||
const products = useProducts()
|
||||
|
||||
const listord = ref(<IOrderCart[]>[])
|
||||
const sumval = ref(0)
|
||||
const editOn = ref(false)
|
||||
|
||||
const site = ref(globalStore.site)
|
||||
|
||||
const $router = useRouter()
|
||||
|
||||
const fullscreenImage = ref(<any>null)
|
||||
|
||||
const apriSchedaPDF = ref(false)
|
||||
|
||||
let myorder = reactive(<IOrder>{
|
||||
idapp: process.env.APP_ID,
|
||||
quantity: 0,
|
||||
quantitypreordered: 0,
|
||||
idStorehouse: '',
|
||||
idGasordine: '',
|
||||
storehouse: {},
|
||||
gasordine: { active: false },
|
||||
})
|
||||
|
||||
const storeSelected = ref('')
|
||||
const arrordersCart = ref(<IOrderCart[]>[])
|
||||
|
||||
const timerInterval = ref(<any>null)
|
||||
const timerLabelScadenza = ref('')
|
||||
const labelDataRitiro = ref('')
|
||||
const labelDataArrivoMerce = ref('')
|
||||
|
||||
const openlistorders = ref(false)
|
||||
const endload = ref(false)
|
||||
const myproduct = ref(<IProduct>{})
|
||||
|
||||
const isFullScreen = ref(false)
|
||||
const imageSrc = ref('URL_DEL_TUO_FILE_IMMAGINE')
|
||||
const startX = ref(0)
|
||||
const startY = ref(0)
|
||||
const scale = ref(1)
|
||||
|
||||
|
||||
watch(() => editOn.value, (to: any, from: any) => {
|
||||
if (!editOn.value)
|
||||
ricarica()
|
||||
})
|
||||
|
||||
|
||||
/*const myproduct = computed((): IProduct => {
|
||||
console.log('getproduct computed')
|
||||
const ris = products.getProduct(props.code)
|
||||
console.log(' received', ris)
|
||||
return ris
|
||||
})*/
|
||||
|
||||
|
||||
function iconWhishlist(order: IProduct) {
|
||||
if (true) {
|
||||
return 'far fa-heart'
|
||||
} else {
|
||||
return 'fas fa-heart'
|
||||
}
|
||||
}
|
||||
async function addtoCart(add: boolean) {
|
||||
|
||||
if (!userStore.isLogged) {
|
||||
tools.showNeutralNotif($q, t('ecomm.area_personale'))
|
||||
globalStore.rightDrawerOpen = true
|
||||
return false
|
||||
}
|
||||
|
||||
const ris = await products.addtoCartBase({ $q, t, id: myproduct.value._id, order: myorder, addqty: add })
|
||||
updateproduct()
|
||||
if (ris && ris.myord) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function getnumstore() {
|
||||
if (myproduct.value) {
|
||||
if (myproduct.value.storehouses)
|
||||
return myproduct.value.storehouses.length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function getSingleStorehouse() {
|
||||
try {
|
||||
const mystore = myproduct.value.storehouses[0]
|
||||
if (mystore)
|
||||
return mystore.name + ' (' + mystore.city + ')'
|
||||
else
|
||||
return ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function getSingleGasordine(gasordine: IGasordine) {
|
||||
try {
|
||||
const mygas = gasordine
|
||||
if (mygas)
|
||||
/*return mygas.name + ' (' + mygas.city + ') ' + t('gas.dataora_chiusura_ordini') + ': ' + tools.getstrDateShort(mygas.dataora_chiusura_ordini)
|
||||
+ ' ' + t('gas.data_arrivo_merce') + ': ' + tools.getstrDateShort(mygas.data_arrivo_merce)
|
||||
+ ' ' + t('gas.dataora_ritiro') + ': ' + tools.getstrDateShort(mygas.dataora_ritiro)*/
|
||||
|
||||
return mygas.name
|
||||
else
|
||||
return ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function initproduct() {
|
||||
|
||||
myorder.quantity = 0
|
||||
myorder.quantitypreordered = 0
|
||||
myorder.idStorehouse = ''
|
||||
myorder.idGasordine = ''
|
||||
|
||||
}
|
||||
|
||||
function updateproduct() {
|
||||
|
||||
myproduct.value = products.getProductById(props.id)
|
||||
|
||||
// products.updateQuantityAvailable(myproduct.value._id)
|
||||
}
|
||||
|
||||
async function ricarica() {
|
||||
endload.value = false
|
||||
const prod = await products.loadProductById(myproduct.value._id)
|
||||
if (prod) {
|
||||
myproduct.value = prod
|
||||
}
|
||||
load()
|
||||
endload.value = true
|
||||
|
||||
}
|
||||
|
||||
function updateproductmodif() {
|
||||
|
||||
try {
|
||||
myproduct.value = products.getProductById(props.id)
|
||||
|
||||
updateLabel()
|
||||
} catch (e) {
|
||||
console.error('err', e)
|
||||
}
|
||||
}
|
||||
|
||||
function getStorehouses() {
|
||||
if (!myproduct.value)
|
||||
return []
|
||||
|
||||
const myarr: any = []
|
||||
let ind = 1
|
||||
myproduct.value.storehouses.forEach((store) => {
|
||||
myarr.push(
|
||||
{
|
||||
id: ind,
|
||||
label: store.name + ' (' + store.city + ')',
|
||||
value: store._id
|
||||
})
|
||||
|
||||
ind++
|
||||
})
|
||||
|
||||
// console.log('arraystore', myarr)
|
||||
return myarr
|
||||
}
|
||||
|
||||
function checkifCartDisable() {
|
||||
// return !myorder.idStorehouse
|
||||
return isOrdineChiuso()
|
||||
}
|
||||
|
||||
function getQtyWarn() {
|
||||
if (myorder.quantity > 0) {
|
||||
return t('ecomm.di_cui_x_in_carrello', { qty: myorder.quantity })
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function getQtyWarnPreOrdered() {
|
||||
if (myorder.quantitypreordered > 0) {
|
||||
return t('ecomm.di_cui_x_in_carrello', { qty: myorder.quantitypreordered })
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
watch(() => props.id, (newval, oldval) => {
|
||||
// console.log('change code')
|
||||
load()
|
||||
})
|
||||
|
||||
watch(() => storeSelected.value, (newval, oldval) => {
|
||||
myorder.idStorehouse = newval
|
||||
})
|
||||
|
||||
function updateLabel() {
|
||||
let dataArrivoMerce = ''
|
||||
let dataRitiro = ''
|
||||
try {
|
||||
if (myproduct.value && myproduct.value.gasordine) {
|
||||
if (myproduct.value.gasordine.data_arrivo_merce)
|
||||
dataArrivoMerce = tools.getstrDateShort(myproduct.value.gasordine.data_arrivo_merce)
|
||||
if (myproduct.value.gasordine.dataora_ritiro)
|
||||
dataRitiro = tools.getstrDateTime(myproduct.value.gasordine.dataora_ritiro)
|
||||
} else {
|
||||
dataArrivoMerce = ''
|
||||
dataRitiro = ''
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
if (labelDataArrivoMerce.value !== dataArrivoMerce)
|
||||
labelDataArrivoMerce.value = dataArrivoMerce
|
||||
if (labelDataRitiro.value !== dataRitiro)
|
||||
labelDataRitiro.value = dataRitiro
|
||||
|
||||
updateTimerLabel()
|
||||
}
|
||||
|
||||
function mounted() {
|
||||
load()
|
||||
|
||||
// Start the timer when the component is mounted
|
||||
startTimer();
|
||||
}
|
||||
|
||||
function beforeDestroy() {
|
||||
// Clear the interval when the component is destroyed to prevent memory leaks
|
||||
clearInterval(timerInterval.value);
|
||||
}
|
||||
|
||||
function updateTimerLabel() {
|
||||
if (myproduct.value && myproduct.value.gasordine && myproduct.value.gasordine._id && myproduct.value.gasordine.dataora_chiusura_ordini)
|
||||
timerLabelScadenza.value = tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini)
|
||||
else
|
||||
timerLabelScadenza.value = ''
|
||||
}
|
||||
|
||||
function isOrdineChiuso() {
|
||||
return myproduct.value.gasordine && myproduct.value.gasordine.dataora_chiusura_ordini &&
|
||||
tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini) === ''
|
||||
}
|
||||
|
||||
function startTimer() {
|
||||
// Update the timer label every second
|
||||
timerInterval.value = setInterval(() => updateTimerLabel(), 60000);
|
||||
}
|
||||
|
||||
function load() {
|
||||
initproduct()
|
||||
updateproduct()
|
||||
labelDataArrivoMerce.value = ''
|
||||
labelDataRitiro.value = ''
|
||||
|
||||
// console.log('Load', myproduct.value.name)
|
||||
|
||||
arrordersCart.value = products.getOrdersCartInAttesaByIdProduct(myproduct.value._id)
|
||||
|
||||
if (!!myproduct.value) {
|
||||
if (myproduct.value.storehouses && myproduct.value.storehouses.length === 1) {
|
||||
// Se solo 1 presente, metto fisso l'unico negozio !
|
||||
myorder.idStorehouse = myproduct.value.storehouses[0]._id
|
||||
}
|
||||
|
||||
if (myproduct.value.gasordine) {
|
||||
myorder.idGasordine = myproduct.value.gasordine._id
|
||||
}
|
||||
|
||||
const ord = products.getOrderProductInCart(myproduct.value._id)
|
||||
if (ord) {
|
||||
myorder.quantity = ord.quantity
|
||||
myorder.quantitypreordered = ord.quantitypreordered
|
||||
|
||||
// Seleziona il Negozio che avevo già scelto nell'ordine !
|
||||
if (ord.idStorehouse)
|
||||
storeSelected.value = ord.idStorehouse
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
updateLabel()
|
||||
|
||||
// console.log('°°° ENDLOAD °°°')
|
||||
endload.value = true
|
||||
}
|
||||
|
||||
function getclimgproduct() {
|
||||
return 'myimgproduct centermydiv'
|
||||
}
|
||||
|
||||
|
||||
function visuListDisponibili() {
|
||||
openlistorders.value = true
|
||||
sumval.value = products.getSumQtyOrderProductInOrdersCart(myproduct.value._id)
|
||||
|
||||
listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => {
|
||||
return accumulator + item.order.quantity
|
||||
}, 0))
|
||||
}
|
||||
|
||||
function visuListBookable() {
|
||||
openlistorders.value = true
|
||||
sumval.value = products.getSumQtyPreOrderInOrdersCart(myproduct.value._id)
|
||||
|
||||
listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => {
|
||||
return accumulator + item.order.quantitypreordered
|
||||
}, 0))
|
||||
}
|
||||
|
||||
function isOrdGas(): boolean {
|
||||
return (myproduct.value && !!myproduct.value.idGasordine && myproduct.value.gasordine! && myproduct.value.gasordine.active)
|
||||
}
|
||||
|
||||
function getpercqtaraggiunta(): number {
|
||||
if (myproduct.value)
|
||||
return tools.calcperc((myproduct.value.bookableGASBloccatiQty + myproduct.value.QuantitaPrenotateInAttesa!) * myproduct.value.productInfo.weight!, myproduct.value.qtyToReachForGas * myproduct.value.productInfo.weight!) / 100
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
function toggleFullScreen() {
|
||||
isFullScreen.value = !isFullScreen.value;
|
||||
scale.value = 1;
|
||||
}
|
||||
|
||||
function onTouchStart(e: any) {
|
||||
startX.value = e.touches[0].pageX;
|
||||
startY.value = e.touches[0].pageY;
|
||||
}
|
||||
|
||||
function onTouchMove(e: any) {
|
||||
const deltaX = e.touches[0].pageX - startX.value;
|
||||
const deltaY = e.touches[0].pageY - startY.value;
|
||||
|
||||
// Calcola la distanza percorsa
|
||||
const distance = Math.sqrt(deltaX ** 2 + deltaY ** 2);
|
||||
|
||||
// Imposta il fattore di scala in base alla distanza percorsa
|
||||
scale.value = Math.min(Math.max(1, scale.value + distance / 100), 3);
|
||||
|
||||
// Salva le nuove coordinate di partenza
|
||||
startX.value = e.touches[0].pageX;
|
||||
startY.value = e.touches[0].pageY;
|
||||
|
||||
// Applica la trasformazione
|
||||
if (fullscreenImage.value)
|
||||
fullscreenImage.value.style.transform = `scale(${scale.value})`;
|
||||
}
|
||||
|
||||
function onTouchEnd() {
|
||||
// Ripristina la trasformazione quando l'utente solleva il dito
|
||||
if (fullscreenImage.value)
|
||||
fullscreenImage.value.fullscreenImage.style.transform = 'scale(1)';
|
||||
}
|
||||
|
||||
function naviga(path: string) {
|
||||
$router.push(path)
|
||||
}
|
||||
|
||||
onMounted(mounted)
|
||||
onBeforeUnmount(beforeDestroy)
|
||||
|
||||
return {
|
||||
visuListDisponibili,
|
||||
visuListBookable,
|
||||
addtoCart,
|
||||
iconWhishlist,
|
||||
getclimgproduct,
|
||||
getnumstore,
|
||||
getSingleStorehouse,
|
||||
getSingleGasordine,
|
||||
getStorehouses,
|
||||
checkifCartDisable,
|
||||
myproduct,
|
||||
myorder,
|
||||
tools,
|
||||
t,
|
||||
storeSelected,
|
||||
getQtyWarn,
|
||||
openlistorders,
|
||||
func_tools,
|
||||
toolsext,
|
||||
products,
|
||||
arrordersCart,
|
||||
endload,
|
||||
shared_consts,
|
||||
site,
|
||||
getQtyWarnPreOrdered,
|
||||
listord,
|
||||
sumval,
|
||||
timerLabelScadenza,
|
||||
labelDataRitiro,
|
||||
labelDataArrivoMerce,
|
||||
getpercqtaraggiunta,
|
||||
isOrdGas,
|
||||
isFullScreen,
|
||||
toggleFullScreen,
|
||||
onTouchStart,
|
||||
onTouchMove,
|
||||
onTouchEnd,
|
||||
naviga,
|
||||
globalStore,
|
||||
editOn,
|
||||
costanti,
|
||||
updateproduct,
|
||||
updateproductmodif,
|
||||
isOrdineChiuso,
|
||||
ricarica,
|
||||
apriSchedaPDF,
|
||||
}
|
||||
}
|
||||
})
|
||||
1139
src/components/CCatalogoCard/CCatalogoCard.vue
Executable file
1139
src/components/CCatalogoCard/CCatalogoCard.vue
Executable file
File diff suppressed because it is too large
Load Diff
1
src/components/CCatalogoCard/index.ts
Executable file
1
src/components/CCatalogoCard/index.ts
Executable file
@@ -0,0 +1 @@
|
||||
export {default as CCatalogoCard} from './CCatalogoCard.vue'
|
||||
@@ -3,39 +3,45 @@ import { IUserFields, IUserShort } from './UserStore'
|
||||
|
||||
export interface IProductInfo {
|
||||
_id?: any
|
||||
code?: string,
|
||||
id_wp?: string,
|
||||
name?: string,
|
||||
description?: string,
|
||||
department?: string,
|
||||
idCatProds?: string[],
|
||||
idSubCatProds?: string[],
|
||||
catprods?: ICatProd[],
|
||||
subcatprods?: ISubCatProd[],
|
||||
color?: string,
|
||||
size?: string,
|
||||
weight?: number,
|
||||
weight_lordo?: number,
|
||||
unit: number,
|
||||
unit_lordo?: number,
|
||||
sfuso?: boolean,
|
||||
stars?: number,
|
||||
date?: Date,
|
||||
icon?: string,
|
||||
code?: string
|
||||
id_wp?: string
|
||||
name?: string
|
||||
description?: string
|
||||
department?: string
|
||||
idCatProds?: string[]
|
||||
idSubCatProds?: string[]
|
||||
catprods?: ICatProd[]
|
||||
subcatprods?: ISubCatProd[]
|
||||
color?: string
|
||||
size?: string
|
||||
weight?: number
|
||||
weight_lordo?: number
|
||||
unit: number
|
||||
unit_lordo?: number
|
||||
sfuso?: boolean
|
||||
stars?: number
|
||||
date?: Date
|
||||
icon?: string
|
||||
img?: string
|
||||
img2?: string
|
||||
img3?: string
|
||||
img4?: string
|
||||
image_link?: string
|
||||
ingredienti?: string,
|
||||
link_scheda?: string,
|
||||
valori_nutrizionali?: string,
|
||||
author?: string,
|
||||
collezione?: string,
|
||||
publisher?: string,
|
||||
numpages?: number,
|
||||
ingredienti?: string
|
||||
link_scheda?: string
|
||||
valori_nutrizionali?: string
|
||||
authors?: string[]
|
||||
collezione?: string
|
||||
publisher?: string
|
||||
date_publishing?: Date
|
||||
numpages?: number
|
||||
productType?: number
|
||||
}
|
||||
|
||||
export interface IProduct {
|
||||
_id?: any
|
||||
active?: boolean
|
||||
isbn?: string
|
||||
idProductInfo?: string,
|
||||
productInfo: IProductInfo,
|
||||
idProducer?: string,
|
||||
@@ -56,6 +62,7 @@ export interface IProduct {
|
||||
QuantitaOrdinateInAttesa?: number,
|
||||
QuantitaPrenotateInAttesa?: number,
|
||||
note?: string
|
||||
versione?: number
|
||||
|
||||
stockQty: number, // UPDATING
|
||||
status?: string,
|
||||
|
||||
@@ -401,6 +401,8 @@ export default defineComponent({
|
||||
|
||||
if (cmd === shared_consts.Cmd.PRODUCTS_V2) {
|
||||
skipfirstrow.value = false
|
||||
} else if (cmd === shared_consts.Cmd.MACRO_CATALOGO_JSON) {
|
||||
skipfirstrow.value = false
|
||||
}
|
||||
|
||||
for (const rec of myarr) {
|
||||
|
||||
@@ -2077,6 +2077,7 @@ export const colTableProductInfos = [
|
||||
AddCol({ name: 'valori_nutrizionali', label_trans: 'products.valori_nutrizionali', fieldtype: costanti.FieldType.html }),
|
||||
AddCol({ name: 'author', label_trans: 'products.author', fieldtype: costanti.FieldType.string }),
|
||||
AddCol({ name: 'collezione', label_trans: 'products.collezione', fieldtype: costanti.FieldType.string }),
|
||||
AddCol({ name: 'date_publishing', label_trans: 'products.date_publishing', fieldtype: costanti.FieldType.onlydate }),
|
||||
AddCol({ name: 'publisher', label_trans: 'products.publisher', fieldtype: costanti.FieldType.string }),
|
||||
AddCol({ name: 'numpages', label_trans: 'products.numpages', fieldtype: costanti.FieldType.number }),
|
||||
AddCol({ name: 'note', label_trans: 'products.note', fieldtype: costanti.FieldType.html }),
|
||||
@@ -2096,6 +2097,7 @@ export const colTableOrdersCart = [
|
||||
|
||||
export const colTableProducts = [
|
||||
AddCol({ name: 'active', label_trans: 'products.active', fieldtype: costanti.FieldType.boolean }),
|
||||
AddCol({ name: 'isbn', label_trans: 'products.isbn' }),
|
||||
AddCol({
|
||||
name: 'idProductInfo',
|
||||
label_trans: 'products.productInfo',
|
||||
@@ -2182,6 +2184,12 @@ export const colTableProducts = [
|
||||
label_trans: 'ecomm.note',
|
||||
fieldtype: costanti.FieldType.html
|
||||
}),
|
||||
AddCol({
|
||||
name: 'versione',
|
||||
label_trans: 'products.versione',
|
||||
fieldtype: costanti.FieldType.select,
|
||||
jointable: 'versions',
|
||||
}),
|
||||
AddCol({
|
||||
name: 'maxbookableGASQty',
|
||||
label_trans: 'ecomm.maxbookableGASQty',
|
||||
|
||||
@@ -1896,6 +1896,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
|
||||
else if (table === toolsext.TABCALDATE) myarr = this.getArrDateEvent()
|
||||
else if (table === toolsext.TABCALALLDATE) myarr = this.getArrAllDateEvent()
|
||||
else if (table === toolsext.TABTYPEHOSP) myarr = shared_consts.TypeHosps
|
||||
else if (table === 'versions') myarr = shared_consts.VERSIONI_PRODOTTO
|
||||
else if (table === toolsext.TABPEOPLE) myarr = shared_consts.People
|
||||
else if (table === toolsext.TABTYPEACCOM) myarr = shared_consts.TypeAccom
|
||||
else if (table === toolsext.TABLOCACCOM) myarr = shared_consts.LocationAccom
|
||||
|
||||
@@ -11,12 +11,13 @@ import { costanti } from '@costanti'
|
||||
|
||||
import { shared_consts } from '@/common/shared_vuejs'
|
||||
import { CProductCard } from '@src/components/CProductCard'
|
||||
import { CCatalogoCard } from '@src/components/CCatalogoCard'
|
||||
import { CSelectUserActive } from '@src/components/CSelectUserActive'
|
||||
import { IProduct } from '@src/model'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Catalogo',
|
||||
components: { CProductCard, CSelectUserActive },
|
||||
components: { CCatalogoCard, CProductCard, CSelectUserActive },
|
||||
props: {},
|
||||
setup() {
|
||||
const userStore = useUserStore()
|
||||
@@ -28,18 +29,38 @@ export default defineComponent({
|
||||
|
||||
const search = ref('')
|
||||
|
||||
const filter = ref(<any>{
|
||||
author: '',
|
||||
publisher: '',
|
||||
type: '',
|
||||
ageGroup: ''
|
||||
})
|
||||
|
||||
const cosa = ref(0)
|
||||
const cat = ref('')
|
||||
const idGasSel = ref('')
|
||||
const loadpage = ref(false)
|
||||
const refreshpage = ref(false)
|
||||
const show_hide = ref(false)
|
||||
|
||||
const arrProducts = ref<any>([])
|
||||
|
||||
const numRecLoaded = ref(0)
|
||||
|
||||
|
||||
// Create a ref for the component to fix
|
||||
const componentToFixRef = ref(<any>null);
|
||||
|
||||
const isFixed = ref(false);
|
||||
|
||||
const arrLoaded = computed(() => {
|
||||
if (arrProducts.value && numRecLoaded.value)
|
||||
return arrProducts.value.slice(0, numRecLoaded.value)
|
||||
else {
|
||||
return []
|
||||
}
|
||||
})
|
||||
|
||||
// Register the scroll event on component mount
|
||||
const handleScroll = () => {
|
||||
const scrollTop = window.scrollY || document.documentElement.scrollTop;
|
||||
@@ -54,6 +75,11 @@ export default defineComponent({
|
||||
watch(() => cat.value, (newval, oldval) => {
|
||||
calcArrProducts()
|
||||
})
|
||||
|
||||
watch(() => idGasSel.value, (newval, oldval) => {
|
||||
calcArrProducts()
|
||||
})
|
||||
|
||||
watch(() => search.value, (newval, oldval) => {
|
||||
calcArrProducts()
|
||||
if (tools.scrollTop() > 300) {
|
||||
@@ -69,30 +95,44 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
function calcArrProducts() {
|
||||
// console.log('calcArrProducts')
|
||||
|
||||
refreshpage.value = true
|
||||
let arrprod = productStore.getProducts(cosa.value)
|
||||
let catstr = cat.value;
|
||||
let gasselstr = ''
|
||||
if (cosa.value === shared_consts.PROD.GAS) {
|
||||
gasselstr = idGasSel.value
|
||||
}
|
||||
let lowerSearchText = search.value.toLowerCase().trim();
|
||||
if ((!lowerSearchText || (lowerSearchText && lowerSearchText.length < 2)) && !catstr) {
|
||||
if ((!lowerSearchText || (lowerSearchText && lowerSearchText.length < 2)) && !catstr && (!gasselstr && (cosa.value !== shared_consts.PROD.GAS))) {
|
||||
|
||||
} else {
|
||||
|
||||
arrprod = arrprod.filter((product: IProduct) => {
|
||||
let lowerName = product.productInfo.name!.toLowerCase();
|
||||
let hasCategoria = !catstr || (catstr && product.productInfo.idCatProds?.includes(catstr));
|
||||
if (product && product.productInfo) {
|
||||
let lowerName = product.productInfo.name!.toLowerCase();
|
||||
let hasCategoria = !catstr || (catstr && product.productInfo.idCatProds?.includes(catstr));
|
||||
|
||||
// Use a regular expression to match whole words
|
||||
let codeMatch = new RegExp(`\\b${lowerSearchText}\\b`, 'i');
|
||||
let nameMatch = new RegExp(`\\b${lowerSearchText}`, 'i');
|
||||
let productgassel = true
|
||||
if (gasselstr || (cosa.value === shared_consts.PROD.GAS)) {
|
||||
productgassel = (product.idGasordine === gasselstr)
|
||||
}
|
||||
|
||||
// Check if any word in lowerName starts with lowerSearchText
|
||||
let anyWordStartsWithSearch = lowerName.split(/\s+/).some(word => nameMatch.test(word));
|
||||
// Use a regular expression to match whole words
|
||||
let codeMatch = new RegExp(`\\b${lowerSearchText}\\b`, 'i');
|
||||
let nameMatch = new RegExp(`\\b${lowerSearchText}`, 'i');
|
||||
|
||||
return (codeMatch.test(product.productInfo.code!) || anyWordStartsWithSearch) && hasCategoria;
|
||||
// Check if any word in lowerName starts with lowerSearchText
|
||||
let anyWordStartsWithSearch = lowerName.split(/\s+/).some(word => nameMatch.test(word));
|
||||
|
||||
return (codeMatch.test(product.productInfo.code!) || anyWordStartsWithSearch) && hasCategoria && productgassel;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
arrProducts.value = arrprod
|
||||
loaddata()
|
||||
refreshpage.value = false
|
||||
}
|
||||
|
||||
@@ -115,12 +155,21 @@ export default defineComponent({
|
||||
async function mounted() {
|
||||
loadpage.value = false
|
||||
await productStore.loadProducts()
|
||||
cosa.value = tools.getCookie(tools.COOK_COSA_PRODOTTI, shared_consts.PROD.TUTTI, true)
|
||||
cosa.value = tools.getCookie(tools.COOK_COSA_PRODOTTI, shared_consts.PROD.GAS, true)
|
||||
if (cosa.value === shared_consts.PROD.TUTTI)
|
||||
cosa.value = shared_consts.PROD.GAS
|
||||
|
||||
// Inizializza
|
||||
loadpage.value = true
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
|
||||
calcArrProducts()
|
||||
|
||||
loaddata()
|
||||
}
|
||||
|
||||
function loaddata() {
|
||||
numRecLoaded.value = 20
|
||||
}
|
||||
|
||||
// Remove the event listener on component destroy
|
||||
@@ -138,6 +187,26 @@ export default defineComponent({
|
||||
return riscat
|
||||
}
|
||||
|
||||
|
||||
function onLoadScroll(index: number, done: any) {
|
||||
if (index >= 1) {
|
||||
if (numRecLoaded.value < arrProducts.value.length) {
|
||||
|
||||
const step = 10
|
||||
let mynrec = numRecLoaded.value + step
|
||||
|
||||
if (mynrec > arrProducts.value.length)
|
||||
mynrec = arrProducts.value.length
|
||||
|
||||
numRecLoaded.value = mynrec
|
||||
|
||||
}
|
||||
done()
|
||||
} else {
|
||||
done(true)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(mounted)
|
||||
|
||||
return {
|
||||
@@ -150,6 +219,7 @@ export default defineComponent({
|
||||
shared_consts,
|
||||
getCatProds,
|
||||
cat,
|
||||
idGasSel,
|
||||
productStore,
|
||||
t,
|
||||
loadpage,
|
||||
@@ -157,6 +227,11 @@ export default defineComponent({
|
||||
componentToFixRef,
|
||||
isFixed,
|
||||
arrProducts,
|
||||
show_hide,
|
||||
onLoadScroll,
|
||||
numRecLoaded,
|
||||
arrLoaded,
|
||||
filter,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<q-spinner v-if="!loadpage" color="primary" size="3em" :thickness="2" />
|
||||
</div>
|
||||
<div v-if="loadpage" class="panel">
|
||||
<!--<div>
|
||||
<CSelectUserActive></CSelectUserActive>
|
||||
<div class="text-center text-h7 text-blue">Filtra per:</div>
|
||||
<div v-if="true">
|
||||
<!--<CSelectUserActive></CSelectUserActive>-->
|
||||
<div class="text-center text-h7 text-blue">Filtra Prodotti per:</div>
|
||||
<div class="text-center">
|
||||
<q-btn-toggle
|
||||
v-model="cosa"
|
||||
@@ -16,9 +16,8 @@
|
||||
glossy
|
||||
toggle-color="primary"
|
||||
:options="[
|
||||
{ value: shared_consts.PROD.TUTTI, slot: 'tutti' },
|
||||
{ value: shared_consts.PROD.BOTTEGA, slot: 'bottega' },
|
||||
{ value: shared_consts.PROD.GAS, slot: 'gas' },
|
||||
{ value: shared_consts.PROD.BOTTEGA, slot: 'bottega' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:tutti>
|
||||
@@ -34,6 +33,12 @@
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="text-center">
|
||||
{{ t('gas.ordina_sul_gas') }}
|
||||
<!--<br />
|
||||
{{
|
||||
t('gas.x_prodotti_gas', {
|
||||
qta: productStore.getNumQtaGas(),
|
||||
})
|
||||
}}-->
|
||||
</div>
|
||||
<q-icon right name="fas fa-user-friends" />
|
||||
</div>
|
||||
@@ -43,13 +48,19 @@
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="text-center">
|
||||
{{ t('gas.bottega') }}
|
||||
<!--<br />
|
||||
{{
|
||||
t('gas.x_prodotti_bottega', {
|
||||
qta: productStore.getNumQtaBottega(),
|
||||
})
|
||||
}}-->
|
||||
</div>
|
||||
<q-icon right name="fas fa-store" />
|
||||
</div>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<q-slide-transition>
|
||||
@@ -80,37 +91,204 @@
|
||||
</div>
|
||||
</div>
|
||||
</q-slide-transition>
|
||||
<div class="row q-gutter-xs justify-center q-mx-auto">
|
||||
<div v-for="(reccat, index) in getCatProds()" :key="index">
|
||||
<q-btn
|
||||
:push="cat === reccat.value"
|
||||
dense
|
||||
:size="tools.isMobile() ? '0.70rem' : '1rem'"
|
||||
:icon="reccat.icon ? reccat.icon : undefined"
|
||||
:color="cat === reccat.value ? 'primary' : undefined"
|
||||
:text-color="cat === reccat.value ? 'white' : 'black'"
|
||||
rounded
|
||||
:label="reccat.label"
|
||||
@click="cat = reccat.value"
|
||||
<div v-if="cosa === shared_consts.PROD.GAS">
|
||||
<div v-if="!idGasSel">
|
||||
<div class="text-center text-h6 text-red">Ordini Attivi:</div>
|
||||
</div>
|
||||
<div class="row q-gutter-xs justify-center q-mx-auto">
|
||||
<div
|
||||
v-for="(recgas, index) in productStore.getGasordinesActives()"
|
||||
:key="index"
|
||||
>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
push
|
||||
dense
|
||||
:size="tools.isMobile() ? '0.9rem' : '1.05rem'"
|
||||
:color="idGasSel === recgas._id ? 'primary' : undefined"
|
||||
:text-color="idGasSel === recgas._id ? 'white' : 'black'"
|
||||
:label="recgas.name"
|
||||
@click="idGasSel = recgas._id"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center q-py-sm prod_trov">
|
||||
<span
|
||||
v-show="productStore.getNumProdTot() !== arrProducts.length"
|
||||
>{{
|
||||
t('ecomm.prodotti_trovati', {
|
||||
qta: arrProducts.length,
|
||||
qtatot: productStore.getNumProdTot(),
|
||||
})
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="row justify-around" v-if="tools.isManager()">
|
||||
<q-toggle
|
||||
v-model="show_hide"
|
||||
push
|
||||
label="Mostra Nascosti"
|
||||
rounded
|
||||
glossy
|
||||
toggle-color="primary"
|
||||
></q-toggle>
|
||||
</div>
|
||||
<div class="row justify-around">
|
||||
<q-infinite-scroll
|
||||
v-if="arrLoaded && arrLoaded.length > 0"
|
||||
ref="myinfscroll"
|
||||
:initial-index="0"
|
||||
@load="onLoadScroll"
|
||||
:offset="2000"
|
||||
debounce="200"
|
||||
class="q-pa-xs row items-start"
|
||||
>
|
||||
<div
|
||||
class="q-pa-xs"
|
||||
v-for="(product, index) in arrLoaded"
|
||||
:key="index"
|
||||
>
|
||||
<CCatalogoCard
|
||||
v-if="
|
||||
product.active ||
|
||||
(show_hide &&
|
||||
productInfo.productType ===
|
||||
shared_consts.PRODUCTTYPE.PRODUCT)
|
||||
"
|
||||
:id="product._id"
|
||||
:complete="false"
|
||||
:cosa="cosa"
|
||||
/>
|
||||
<CProductCard
|
||||
v-else-if="product.active || show_hide"
|
||||
:id="product._id"
|
||||
:complete="false"
|
||||
:cosa="cosa"
|
||||
/>
|
||||
</div>
|
||||
<template v-slot:loading>
|
||||
<div class="text-center">
|
||||
<q-spinner-dots color="primary" size="40px" />
|
||||
</div>
|
||||
</template>
|
||||
</q-infinite-scroll>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center q-py-sm prod_trov">
|
||||
<span v-show="productStore.getNumProdTot() !== arrProducts.length">{{
|
||||
t('ecomm.prodotti_trovati', {
|
||||
qta: arrProducts.length,
|
||||
qtatot: productStore.getNumProdTot(),
|
||||
})
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="row justify-around">
|
||||
<div
|
||||
class="q-pa-xs row items-start"
|
||||
v-for="(product, index) in arrProducts"
|
||||
:key="index"
|
||||
>
|
||||
<CProductCard :id="product._id" :complete="false" :cosa="cosa" />
|
||||
<div v-else>
|
||||
<div class="row q-gutter-xs justify-center q-mx-auto">
|
||||
<div v-for="(reccat, index) in getCatProds()" :key="index">
|
||||
<q-btn
|
||||
:push="cat === reccat.value"
|
||||
dense
|
||||
:size="tools.isMobile() ? '0.70rem' : '1rem'"
|
||||
:icon="reccat.icon ? reccat.icon : undefined"
|
||||
:color="cat === reccat.value ? 'primary' : undefined"
|
||||
:text-color="cat === reccat.value ? 'white' : 'black'"
|
||||
rounded
|
||||
:label="reccat.label"
|
||||
@click="cat = reccat.value"
|
||||
>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center q-py-sm prod_trov">
|
||||
<span
|
||||
v-show="productStore.getNumProdTot() !== arrProducts.length"
|
||||
>{{
|
||||
t('ecomm.prodotti_trovati', {
|
||||
qta: arrProducts.length,
|
||||
qtatot: productStore.getNumProdTot(),
|
||||
})
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<div class="row justify-around" v-if="tools.isManager()">
|
||||
<q-toggle
|
||||
v-model="show_hide"
|
||||
push
|
||||
label="Mostra Nascosti"
|
||||
rounded
|
||||
glossy
|
||||
toggle-color="primary"
|
||||
></q-toggle>
|
||||
</div>
|
||||
|
||||
<q-toolbar>
|
||||
<q-input
|
||||
v-model="search"
|
||||
debounce="300"
|
||||
placeholder="Cerca libri..."
|
||||
dense
|
||||
/>
|
||||
<q-select
|
||||
v-model="filter.author"
|
||||
:options="authors"
|
||||
label="Autore"
|
||||
placeholder="Tutti"
|
||||
dense
|
||||
/>
|
||||
<q-select
|
||||
v-model="filter.publisher"
|
||||
:options="publishers"
|
||||
label="Editore"
|
||||
placeholder="Tutti"
|
||||
dense
|
||||
/>
|
||||
<q-select
|
||||
v-model="filter.type"
|
||||
:options="types"
|
||||
label="Tipo"
|
||||
placeholder="Tutti"
|
||||
dense
|
||||
/>
|
||||
<q-select
|
||||
v-model="filter.ageGroup"
|
||||
:options="ageGroups"
|
||||
label="Fascia d'età"
|
||||
placeholder="Tutte"
|
||||
dense
|
||||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<div class="row justify-around">
|
||||
<q-infinite-scroll
|
||||
v-if="arrLoaded && arrLoaded.length > 0"
|
||||
ref="myinfscroll"
|
||||
:initial-index="0"
|
||||
@load="onLoadScroll"
|
||||
:offset="2000"
|
||||
debounce="200"
|
||||
class="q-pa-xs row items-start"
|
||||
>
|
||||
<div
|
||||
class="q-pa-xs"
|
||||
v-for="(product, index) in arrLoaded"
|
||||
:key="index"
|
||||
>
|
||||
<CCatalogoCard
|
||||
v-if="
|
||||
product.active ||
|
||||
(show_hide &&
|
||||
productInfo.productType ===
|
||||
shared_consts.PRODUCTTYPE.PRODUCT)
|
||||
"
|
||||
:id="product._id"
|
||||
:complete="false"
|
||||
:cosa="cosa"
|
||||
/>
|
||||
<CProductCard
|
||||
v-else-if="product.active || show_hide"
|
||||
:id="product._id"
|
||||
:complete="false"
|
||||
:cosa="cosa"
|
||||
/>
|
||||
</div>
|
||||
<template v-slot:loading>
|
||||
<div class="text-center">
|
||||
<q-spinner-dots color="primary" size="40px" />
|
||||
</div>
|
||||
</template>
|
||||
</q-infinite-scroll>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -122,5 +300,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './catalogo';
|
||||
@import './catalogo.scss';
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user