- caaloghi, categorie

This commit is contained in:
Surya Paolo
2024-05-08 16:07:42 +02:00
parent 84e7f6e9f4
commit 58f53f8c52
20 changed files with 704 additions and 415 deletions

View File

@@ -1,8 +1,8 @@
{ {
"name": "riso", "name": "gruppomacro",
"version": "0.6.1", "version": "0.6.1",
"description": "Siamo la Rete Italiana di Scambio Orizzontale, abbiamo creato questa piattaforma per metterla al servizio di chi vuole riscoprire il valore della condivisione e della cooperazione. Valori semplici e profondi che ci aiutano a ritrovare il Senso della Vita, perduto in questa società consumista, e riporti quei Sani Pricìpi Naturali ed Umani di Fratellanza che intere popolazioni antiche conoscevano bene.", "description": "Gruppo Macro Editori",
"productName": "Riso", "productName": "Gruppo Macro",
"author": "Paolo Arena", "author": "Paolo Arena",
"private": true, "private": true,
"keywords": [], "keywords": [],

View File

@@ -1 +1 @@
TERMINA DI LAVORARE SU gruppomacro.app: (Sovrascrivo !) TERMINA DI LAVORARE SU riso.app: (Sovrascrivo !)

View File

@@ -2124,7 +2124,7 @@ export const shared_consts = {
{ {
label: 'Usato', label: 'Usato',
value: 2, value: 2,
color: 'warning', color: 'orange-9',
}, },
{ {
label: 'Download', label: 'Download',

View File

@@ -10,35 +10,6 @@
place-content: center; place-content: center;
} }
.prod_price {
font-size: 1.1rem;
font-style: bold;
@media (max-width: 718px) {
font-size: 1rem;
}
}
.prod_sale_price {
font-size: 1.10rem;
font-style: bold;
@media (max-width: 718px) {
font-size: 1.05rem;
}
}
.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 { .prod_disp {
font-size: 1.2rem; font-size: 1.2rem;
@@ -136,18 +107,6 @@
height: 70px; height: 70px;
} }
.image-container {
width: 300px;
height: 300px;
position: relative;
overflow: hidden;
@media (max-width: 718px) {
width: 200px;
height: 200px;
}
}
.book-image-fixed{ .book-image-fixed{
max-width: 300px; max-width: 300px;
max-height: 600px; max-height: 600px;
@@ -168,12 +127,6 @@
} }
.book-card { .book-card {
width: 300px;
background-color: #f8f8f8;
}
.book-card {
width: 300px;
background-color: #f8f8f8; background-color: #f8f8f8;
} }
@@ -198,19 +151,32 @@
padding: 20px; padding: 20px;
} }
.book-title { .book-title {
margin: 8px; margin: 8px;
font-family: 'Poppins,sans-serif'; font-family: 'Poppins,sans-serif';
font-size: 1.15rem;
line-height: 20px;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
display: block; display: block;
text-align: center; text-align: center;
text-shadow: 1px 1px 1px #555;
}
.book-title[data-col=c1] {
font-size: 1.15rem;
line-height: 20px;
}
.book-title[data-col=c2] {
font-size: 1rem;
line-height: 19px;
} }
.book-author { .book-author {
font-size: 1.1em; /* Dimensione del font leggermente più grande per enfatizzare l'importanza del nome dell'autore */ color: grey; /* Colore scuro per garantire una buona leggibilità */
}
.author{
color: darkblue; /* Colore scuro per garantire una buona leggibilità */ color: darkblue; /* Colore scuro per garantire una buona leggibilità */
text-transform: capitalize; /* Capitalizzazione delle iniziali per ogni parola del nome */ text-transform: capitalize; /* Capitalizzazione delle iniziali per ogni parola del nome */
background-color: #f9f9f9; /* Sfondo leggermente diverso per evidenziare il nome */ background-color: #f9f9f9; /* Sfondo leggermente diverso per evidenziare il nome */
@@ -219,6 +185,30 @@
font-style: italic; /* Stile del testo in corsivo per evidenziare l'autore */ font-style: italic; /* Stile del testo in corsivo per evidenziare l'autore */
} }
.author[data-col=c1]{
font-size: 1.1em; /* Dimensione del font leggermente più grande per enfatizzare l'importanza del nome dell'autore */
}
.author[data-col=c2]{
font-size: 1em; /* Dimensione del font leggermente più grande per enfatizzare l'importanza del nome dell'autore */
}
.book-category {
font-size: 1em; /* Dimensione del font leggermente più grande per enfatizzare l'importanza del nome dell'autore */
color: grey; /* Colore scuro per garantire una buona leggibilità */
}
.category{
font-size: 1.0em; /* Dimensione del font leggermente più grande per enfatizzare l'importanza del nome dell'autore */
color: green; /* Colore scuro per garantire una buona leggibilità */
text-transform: capitalize; /* Capitalizzazione delle iniziali per ogni parola del nome */
background-color: #f9f9f9; /* Sfondo leggermente diverso per evidenziare il nome */
border-radius: 2px; /* Bordi arrotondati per un aspetto più soft-edged */
display: inline-block; /* Tratta il blocco come elementi inline-block per adattarlo al contenuto */
font-style: italic; /* Stile del testo in corsivo per evidenziare l'autore */
box-shadow: 0 0 5px gray;
}
.book-description { .book-description {
font-size: 0.85rem; font-size: 0.85rem;
color: #777; color: #777;
@@ -226,12 +216,23 @@
.block-variazione { .block-variazione {
border: 1px solid gray; border: 1px solid gray;
margin: auto;
// effetto 3d // effetto 3d
box-shadow: 0 0 5px gray; box-shadow: 0 0 5px gray;
border-radius: 5px; border-radius: 5px;
padding: 2px; padding: 4px;
margin: 2px;
cursor: pointer; cursor: pointer;
.q-badge {
font-size: 1rem;
padding: 4px 6px;
}
}
.colfix_prodotti_1 {
width: 350px;
}
.colfix_prodotti_2 {
width: 175px;
} }
.block-variazione-selected { .block-variazione-selected {
@@ -280,3 +281,22 @@
margin-left: 5px; margin-left: 5px;
} }
} }
.book-3d:hover img {
transform: translateZ(50px) rotateY(-20deg); /* Applica la trasformazione 3D quando si passa con il mouse sopra */
}
// Contenitore del libro, con effetto 3d, ed animazione 3D
.book-3d {
perspective: 1000px;
transform-style: preserve-3d;
transition: transform 0.5s ease-in-out;
transform-origin: center center;
img {
transform-origin: center center;
transition: transform 0.5s ease-in-out;
}
}

View File

@@ -8,6 +8,7 @@ import { CTitleBanner } from '../CTitleBanner'
import { CCardState } from '../CCardState' import { CCardState } from '../CCardState'
import { CCopyBtn } from '../CCopyBtn' import { CCopyBtn } from '../CCopyBtn'
import { CMyValueDb } from '../CMyValueDb' import { CMyValueDb } from '../CMyValueDb'
import { CPrice } from '../CPrice'
import { func_tools, toolsext } from '@store/Modules/toolsext' import { func_tools, toolsext } from '@store/Modules/toolsext'
@@ -48,8 +49,13 @@ export default defineComponent({
required: false, required: false,
default: false, default: false,
}, },
options: {
type: Object,
required: false,
default: () => { }
}
}, },
components: { CTitleBanner, CCardState, CCopyBtn, CMyValueDb, VuePdfApp }, components: { CTitleBanner, CCardState, CCopyBtn, CMyValueDb, VuePdfApp, CPrice },
setup(props, { emit }) { setup(props, { emit }) {
const $q = useQuasar() const $q = useQuasar()
const { t } = useI18n() const { t } = useI18n()
@@ -91,7 +97,7 @@ export default defineComponent({
const openlistorders = ref(false) const openlistorders = ref(false)
const endload = ref(false) const endload = ref(false)
const myproduct = ref(<IProduct>{}) const myproduct = ref(<IProduct | null>{})
const isFullScreen = ref(false) const isFullScreen = ref(false)
const imageSrc = ref('URL_DEL_TUO_FILE_IMMAGINE') const imageSrc = ref('URL_DEL_TUO_FILE_IMMAGINE')
@@ -129,12 +135,14 @@ export default defineComponent({
return false return false
} }
if (myproduct.value) {
const ris = await products.addtoCartBase({ $q, t, id: myproduct.value._id, order: myorder, addqty: add }) const ris = await products.addtoCartBase({ $q, t, id: myproduct.value._id, order: myorder, addqty: add })
updateproduct() updateproduct()
if (ris && ris.myord) { if (ris && ris.myord) {
} }
} }
}
function getnumstore() { function getnumstore() {
if (myproduct.value) { if (myproduct.value) {
@@ -148,6 +156,9 @@ export default defineComponent({
function getSingleStorehouse() { function getSingleStorehouse() {
try { try {
if (!myproduct.value)
return ''
const mystore = myproduct.value.storehouses[0] const mystore = myproduct.value.storehouses[0]
if (mystore) if (mystore)
return mystore.name + ' (' + mystore.city + ')' return mystore.name + ' (' + mystore.city + ')'
@@ -183,28 +194,30 @@ export default defineComponent({
} }
function updateproduct() { async function updateproduct() {
myproduct.value = products.getProductById(props.id) myproduct.value = null;
myproduct.value = await products.getProductById(props.id)
// products.updateQuantityAvailable(myproduct.value._id) // products.updateQuantityAvailable(myproduct.value._id)
} }
async function ricarica() { async function ricarica() {
endload.value = false endload.value = false
if (myproduct.value) {
const prod = await products.loadProductById(myproduct.value._id) const prod = await products.loadProductById(myproduct.value._id)
if (prod) { if (prod) {
myproduct.value = prod myproduct.value = prod
} }
load() }
endload.value = true await load()
} }
function updateproductmodif() { async function updateproductmodif() {
try { try {
myproduct.value = products.getProductById(props.id) myproduct.value = await products.getProductById(props.id)
updateLabel() updateLabel()
} catch (e) { } catch (e) {
@@ -256,9 +269,9 @@ export default defineComponent({
return '' return ''
} }
watch(() => props.id, (newval, oldval) => { watch(() => props.id, async (newval, oldval) => {
// console.log('change code') // console.log('change code')
load() await load()
}) })
watch(() => storeSelected.value, (newval, oldval) => { watch(() => storeSelected.value, (newval, oldval) => {
@@ -289,12 +302,8 @@ export default defineComponent({
updateTimerLabel() updateTimerLabel()
} }
function mounted() { async function mounted() {
load() await load()
if (props.complete && myproduct.value && myproduct.value.arrvariazioni) {
indvariazSel.value = 0
}
// Start the timer when the component is mounted // Start the timer when the component is mounted
startTimer(); startTimer();
@@ -306,15 +315,18 @@ export default defineComponent({
} }
function updateTimerLabel() { function updateTimerLabel() {
if (myproduct.value && myproduct.value.gasordine && myproduct.value.gasordine._id && myproduct.value.gasordine.dataora_chiusura_ordini) 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) timerLabelScadenza.value = tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini)
else else
timerLabelScadenza.value = '' timerLabelScadenza.value = ''
} }
function isOrdineChiuso() { function isOrdineChiuso() {
if (myproduct.value) {
return myproduct.value.gasordine && myproduct.value.gasordine.dataora_chiusura_ordini && return myproduct.value.gasordine && myproduct.value.gasordine.dataora_chiusura_ordini &&
tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini) === '' tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini) === ''
} else
return false
} }
function startTimer() { function startTimer() {
@@ -322,17 +334,18 @@ export default defineComponent({
timerInterval.value = setInterval(() => updateTimerLabel(), 60000); timerInterval.value = setInterval(() => updateTimerLabel(), 60000);
} }
function load() { async function load() {
indvariazSel.value = -1
initproduct() initproduct()
updateproduct() await updateproduct()
labelDataArrivoMerce.value = '' labelDataArrivoMerce.value = ''
labelDataRitiro.value = '' labelDataRitiro.value = ''
// console.log('Load', myproduct.value.name) // console.log('Load', myproduct.value.name)
if (!!myproduct.value) {
arrordersCart.value = products.getOrdersCartInAttesaByIdProduct(myproduct.value._id) arrordersCart.value = products.getOrdersCartInAttesaByIdProduct(myproduct.value._id)
if (!!myproduct.value) {
if (myproduct.value.storehouses && myproduct.value.storehouses.length === 1) { if (myproduct.value.storehouses && myproduct.value.storehouses.length === 1) {
// Se solo 1 presente, metto fisso l'unico negozio ! // Se solo 1 presente, metto fisso l'unico negozio !
myorder.idStorehouse = myproduct.value.storehouses[0]._id myorder.idStorehouse = myproduct.value.storehouses[0]._id
@@ -356,6 +369,13 @@ export default defineComponent({
updateLabel() updateLabel()
// console.log('myproduct', myproduct.value, 'arrvariaz', myproduct.value.arrvariazioni, 'compl', props.complete)
if (props.complete && myproduct.value && myproduct.value.arrvariazioni) {
// console.log('ENTRATO')
indvariazSel.value = 0
}
// console.log('°°° ENDLOAD °°°') // console.log('°°° ENDLOAD °°°')
endload.value = true endload.value = true
} }
@@ -366,25 +386,35 @@ export default defineComponent({
function visuListDisponibili() { function visuListDisponibili() {
if (myproduct.value) {
openlistorders.value = true openlistorders.value = true
sumval.value = products.getSumQtyOrderProductInOrdersCart(myproduct.value._id) sumval.value = products.getSumQtyOrderProductInOrdersCart(myproduct.value._id)
listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => { listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => {
return accumulator + item.order.quantity return accumulator + item.order.quantity
}, 0)) }, 0))
} else
return false
} }
function visuListBookable() { function visuListBookable() {
if (myproduct.value) {
openlistorders.value = true openlistorders.value = true
sumval.value = products.getSumQtyPreOrderInOrdersCart(myproduct.value._id) sumval.value = products.getSumQtyPreOrderInOrdersCart(myproduct.value._id)
listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => { listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => {
return accumulator + item.order.quantitypreordered return accumulator + item.order.quantitypreordered
}, 0)) }, 0))
} else {
return ''
}
} }
function isOrdGas(): boolean { function isOrdGas(): boolean {
if (myproduct.value)
return (myproduct.value && !!myproduct.value.idGasordine && myproduct.value.gasordine! && myproduct.value.gasordine.active) return (myproduct.value && !!myproduct.value.idGasordine && myproduct.value.gasordine! && myproduct.value.gasordine.active)
else
return false
} }
function getpercqtaraggiunta(): number { function getpercqtaraggiunta(): number {
@@ -436,9 +466,11 @@ export default defineComponent({
function setvariazioneSelected(indvariaz: number) { function setvariazioneSelected(indvariaz: number) {
if (indvariazSel.value === indvariaz) if (indvariazSel.value === indvariaz)
indvariazSel.value = -1 indvariazSel.value = -1
else else {
indvariazSel.value = -1
indvariazSel.value = indvariaz indvariazSel.value = indvariaz
} }
}
onMounted(mounted) onMounted(mounted)
onBeforeUnmount(beforeDestroy) onBeforeUnmount(beforeDestroy)

View File

@@ -1,11 +1,17 @@
<template> <template>
<div class="row items-start q-gutter-sm"> <div
:class="{
'row items-start q-gutter-sm': true,
}"
>
<q-spinner v-if="!endload" color="primary" size="3em" :thickness="2" /> <q-spinner v-if="!endload" color="primary" size="3em" :thickness="2" />
<div <div
v-if="!!myproduct && !!myproduct.productInfo" v-if="!!myproduct && !!myproduct.productInfo"
:class="{ :class="{
'my-card-big': complete, 'my-card-big book-details': complete,
'book-card book-details': !complete, 'book-card': !complete,
colfix_prodotti_1: options.quante_col == 'c1',
colfix_prodotti_2: options.quante_col == 'c2',
}" }"
> >
<q-toggle <q-toggle
@@ -18,7 +24,10 @@
> >
</q-toggle> </q-toggle>
<q-card-section> <q-card-section>
<div class="flex" style="place-content: center"> <div
:class="{ 'flex q-pa-sm': true, 'shadow-2': options.in_3d }"
style="place-content: center"
>
<q-img <q-img
:src=" :src="
myproduct.productInfo.img myproduct.productInfo.img
@@ -29,6 +38,7 @@
:class="{ :class="{
'book-image-fixed': complete, 'book-image-fixed': complete,
'cursor-pointer': !complete, 'cursor-pointer': !complete,
'shadow-4': true,
}" }"
@click=" @click="
complete complete
@@ -36,48 +46,82 @@
: naviga(`/catalogo/` + myproduct._id + '/' + cosa) : naviga(`/catalogo/` + myproduct._id + '/' + cosa)
" "
> >
</q-img> <div
class="absolute transparent"
style="left: 90%; top: 0; transform: translateX(-50%)"
>
<q-btn <q-btn
color="blue" color="blue"
class="semi-transparent"
round round
icon="search" icon="search"
class="absolute semi-transparent ingrandisci"
size="md"
@click="toggleFullScreen" @click="toggleFullScreen"
style="left: 55%; top: 5px; transform: translateX(-50%)" size="md"
/> />
</div>
</q-img>
<div class="scheda-book"> <div class="scheda-book">
<q-card-title class="book-title" <q-card-title>
>{{ myproduct.productInfo.name }} <span class="book-title" :data-col="options.quante_col">{{
myproduct.productInfo.name
}}</span>
</q-card-title> </q-card-title>
<q-card-subtitle <q-card-subtitle
v-if="myproduct.productInfo.authors" v-if="myproduct.productInfo.authors"
class="book-author" class="book-author"
:data-col="options.quante_col"
> >
di
<span <span
v-for="author in myproduct.productInfo.authors" v-for="(author, index) in myproduct.productInfo.authors"
:key="author._id" :key="author._id"
> >
{{ author.name }} {{ author.surname }} <span class="author"
>{{ author.name }} {{ author.surname }}</span
>
<span v-if="index > 0">, </span>
</span> </span>
</q-card-subtitle> </q-card-subtitle>
<q-card-subtitle
v-if="myproduct.productInfo.catprods && options.show_cat"
class="book-category"
>
<div
v-for="catprod in myproduct.productInfo.catprods"
:key="catprod._id"
>
<q-chip
dense
color="primary"
text-color="white"
icon="category"
>
{{ catprod.name }}
</q-chip>
</div>
</q-card-subtitle>
<q-card-main <q-card-main
v-if="myproduct.productInfo.short_descr" v-if="
options.show_short_descr && myproduct.productInfo.short_descr
"
class="book-short-descr" class="book-short-descr"
>{{ >{{
tools.firstchars(myproduct.productInfo.short_descr, 200, true) tools.firstchars(myproduct.productInfo.short_descr, 200, true)
}}</q-card-main }}</q-card-main
> >
<div v-if="myproduct.isbn" class="book-isbn"> <div
ISBN: {{ myproduct.isbn }} v-if="myproduct.productInfo.numpages && complete"
</div> class="book-pages"
<div v-if="myproduct.productInfo.numpages" class="book-pages"> >
Pagine: {{ myproduct.productInfo.numpages }} Pagine: {{ myproduct.productInfo.numpages }}
</div> </div>
<div v-if="myproduct.productInfo.publisher" class="book-pages">
Casa Editrice: {{ myproduct.productInfo.publisher }}
</div>
<div <div
v-if="myproduct.productInfo.date_publishing" v-if="myproduct.productInfo.date_publishing && complete"
class="book-data-pub" class="book-data-pub"
> >
Data Pubblicazione: Data Pubblicazione:
@@ -86,25 +130,33 @@
<q-separator class="q-my-sm"></q-separator> <q-separator class="q-my-sm"></q-separator>
<div v-if="options.show_price">
<div <div
:class=" :class="{
`row items-center q-pa-nome block-variazione ` + 'row items-center q-pa-nome block-variazione': true,
(indvariazSel == index ? 'block-variazione-selected' : '') 'block-variazione-selected': indvariazSel == index,
" }"
v-for="(variazione, index) of myproduct.arrvariazioni" v-for="(variazione, index) of myproduct.arrvariazioni"
:key="index" :key="index"
@click="setvariazioneSelected(index)" @click="setvariazioneSelected(index)"
> >
<div class="flex justify-between items-center q-mx-sm"> <div class="flex justify-between items-center q-mx-sm">
<q-badge <q-badge
v-if="variazione.versione > 0" class="q-badge--large"
:color=" :color="
shared_consts.VERSIONI_PRODOTTO[variazione.versione].color shared_consts.VERSIONI_PRODOTTO[variazione.versione].color
" "
>{{
shared_consts.VERSIONI_PRODOTTO[variazione.versione].label
}}</q-badge
> >
<q-icon
v-if="variazione.versione > 0"
:name="tools.getIconByVersione(variazione.versione)"
color="white"
></q-icon
>&nbsp;
{{
shared_consts.VERSIONI_PRODOTTO[variazione.versione].label
}}
</q-badge>
<div v-if="variazione.formato && false"> <div v-if="variazione.formato && false">
formato: {{ variazione.formato }} formato: {{ variazione.formato }}
</div> </div>
@@ -123,28 +175,18 @@
</div> </div>
<q-item-section> <q-item-section>
<q-item-label> <q-item-label>
<span class="prod_sale_price" v-if="!!variazione.sale_price" <CPrice
>{{ :sale_price="variazione.sale_price"
variazione.sale_price :price="variazione.price"
? variazione.sale_price.toFixed(2) ></CPrice>
: 0
}}
</span
>
<span
:class="
variazione.sale_price ? 'prod_off_price' : 'prod_price'
"
v-if="!!variazione.price"
>{{ variazione.price ? variazione.price.toFixed(2) : 0 }}
</span>
<span v-if="!!myproduct.after_price">{{ <span v-if="!!myproduct.after_price">{{
myproduct.after_price myproduct.after_price
}}</span> }}</span>
</q-item-label> </q-item-label>
<q-item-label <q-item-label
v-if=" v-if="
myproduct.scontisticas && myproduct.scontisticas.length > 0 myproduct.scontisticas &&
myproduct.scontisticas.length > 0
" "
> >
<div <div
@@ -183,14 +225,15 @@
/> />
</q-item-section> </q-item-section>
</div> </div>
<q-slide-transition>
<div v-if="indvariazSel >= 0">
<div <div
v-if=" v-for="(variazione, index) of myproduct.arrvariazioni"
:key="index"
>
<div v-show="indvariazSel == index">
<div
v-show="
indvariazSel >= 0 && indvariazSel >= 0 &&
tools.disponibStr( tools.disponibStr(variazione.quantita)
myproduct.arrvariazioni[indvariazSel].quantita
)
" "
class="row justify-center q-mt-sm vertical-middle" class="row justify-center q-mt-sm vertical-middle"
style="align-items: center" style="align-items: center"
@@ -202,89 +245,51 @@
size="md" size="md"
dense dense
text-color="white" text-color="white"
:color=" :color="tools.colordisponib(variazione.quantita)"
tools.colordisponib( >{{ tools.disponibStr(variazione.quantita) }}</q-chip
myproduct.arrvariazioni[indvariazSel].quantita
)
"
>{{
tools.disponibStr(
myproduct.arrvariazioni[indvariazSel].quantita
)
}}</q-chip
> >
</div> </div>
<div <div
v-if="indvariazSel >= 0" v-show="indvariazSel >= 0"
class="row justify-center vertical-middle" class="row justify-center vertical-middle"
style="align-items: center" style="align-items: center"
> >
<span class="q-mr-sm">{{ $t('products.price') }}:</span> <span class="q-mr-sm">{{ $t('products.price') }}:</span>
<span <CPrice
class="prod_sale_price text-bold" :sale_price="variazione.sale_price"
v-if="!!myproduct.arrvariazioni[indvariazSel].sale_price" :price="variazione.price"
>{{ bold="true"
myproduct.arrvariazioni[indvariazSel].sale_price ></CPrice>
? myproduct.arrvariazioni[ <span v-show="!!myproduct.after_price">{{
indvariazSel
].sale_price.toFixed(2)
: 0
}}
€</span
>
<span
:class="
myproduct.arrvariazioni[indvariazSel].sale_price
? 'prod_off_price'
: 'prod_price'
"
v-if="!!myproduct.arrvariazioni[indvariazSel].price"
>{{
myproduct.arrvariazioni[indvariazSel].price
? myproduct.arrvariazioni[indvariazSel].price.toFixed(2)
: 0
}}
</span>
<span v-if="!!myproduct.after_price">{{
myproduct.after_price myproduct.after_price
}}</span> }}</span>
</div> </div>
<div <div
v-if=" v-show="indvariazSel >= 0 && !!variazione.formato"
indvariazSel >= 0 &&
!!myproduct.arrvariazioni[indvariazSel].formato
"
class="row justify-center q-ma-sm vertical-middle" class="row justify-center q-ma-sm vertical-middle"
style="align-items: center" style="align-items: center"
> >
<span class="q-mr-sm">{{ $t('products.formato') }}:</span> <span class="q-mr-sm">{{ $t('products.formato') }}:</span>
<q-badge <q-badge
v-if="myproduct.arrvariazioni[indvariazSel].versione > 0" v-show="variazione.versione > 0"
:color=" :color="
shared_consts.VERSIONI_PRODOTTO[ shared_consts.VERSIONI_PRODOTTO[variazione.versione]
myproduct.arrvariazioni[indvariazSel].versione .color
].color
" "
>{{ >{{ variazione.formato }}</q-badge
myproduct.arrvariazioni[indvariazSel].formato
}}</q-badge
> >
</div> </div>
<div <div class="row justify-center q-mt-sm">
v-if="indvariazSel >= 0"
class="row justify-center q-mt-sm"
>
<q-btn <q-btn
v-if=" v-if="
myproduct.arrvariazioni[indvariazSel].addtocart_link && indVariazSel >= 0 && variazione.addtocart_link && true
true
" "
:href="myproduct.arrvariazioni[indvariazSel].addtocart_link" :href="variazione.addtocart_link"
target="_blank" target="_blank"
color="primary" color="primary"
icon="fas fa-cart-plus" icon="fas fa-cart-plus"
class="q-mr-sm"
no-caps no-caps
:label="$t('products.addtocart_ext')" :label="$t('products.addtocart_ext')"
></q-btn> ></q-btn>
@@ -292,6 +297,7 @@
v-if="myproduct.productInfo.checkout_link && true" v-if="myproduct.productInfo.checkout_link && true"
:href="myproduct.productInfo.checkout_link" :href="myproduct.productInfo.checkout_link"
target="_blank" target="_blank"
class="q-ml-sm"
color="white" color="white"
icon="fas fa-shopping-cart" icon="fas fa-shopping-cart"
outline outline
@@ -301,7 +307,8 @@
></q-btn> ></q-btn>
</div> </div>
</div> </div>
</q-slide-transition> </div>
</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>
@@ -490,12 +497,14 @@
: myproduct.productInfo.image_link : myproduct.productInfo.image_link
" "
:alt="myproduct.productInfo.name" :alt="myproduct.productInfo.name"
:fit="tools.isMobile() ? 'fill' : 'none'" :fit="tools.isMobile() ? 'fill' : 'contain'"
class="fullscreen-image"
@touchstart="onTouchStart" @touchstart="onTouchStart"
@touchmove="onTouchMove" @touchmove="onTouchMove"
@touchend="onTouchEnd" @touchend="onTouchEnd"
ref="fullscreenImage" ref="fullscreenImage"
/> >
</q-img>
<br /> <br />
</div> </div>
<div class="text-center"> <div class="text-center">

103
src/components/CPrice/CPrice.scss Executable file
View File

@@ -0,0 +1,103 @@
.prod_price {
font-size: 1.1rem;
font-style: bold;
@media (max-width: 718px) {
font-size: 1rem;
}
}
.prod_sale_price {
font-size: 1.10rem;
font-style: bold;
@media (max-width: 718px) {
font-size: 1.05rem;
}
}
.prod_off_price {
font-size: 1rem;
@media (max-width: 718px) {
font-size: 0.85rem;
}
color: gray;
text-decoration: line-through;
padding-left: 8px;
}
/* ******** */
.a-price {
text-decoration: none;
position: relative;
line-height: normal
}
.a-price[data-a-strike=true]:after {
border-top: .1rem solid;
position: absolute;
content: "";
right: 0;
top: 50%;
left: 0
}
.a-price .a-price-fraction+.a-price-symbol {
left: .2em
}
.a-price .a-offscreen {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
.a-price[data-a-size=mini][data-a-strike=true],.a-price[data-a-size="s"][data-a-strike=true],.a-price[data-a-size="b"][data-a-strike=true] {
display: inline-block;
text-decoration: inherit
}
.a-price[data-a-color=base] {
color: #0F1111
}
.a-price[data-a-color=price] {
color: #B12704
}
.a-price[data-a-color=secondary] {
color: #565959
}
.a-price[data-a-color=tertiary] {
color: #767676
}
.a-price[data-a-size$=plus] .a-price-fraction,.a-price[data-a-size$=plus] .a-price-symbol,.a-price[data-a-size$=l] .a-price-fraction,.a-price[data-a-size$=l] .a-price-symbol {
position: relative
}
.a-price[data-a-size$=plus] .a-price-decimal,.a-price[data-a-size$=l] .a-price-decimal {
position: absolute;
opacity: 0
}
.a-price[data-a-size=l] {
font-size: 1.3rem
}
.a-price[data-a-size=l] .a-price-symbol {
font-size: 1.1rem
}
.a-price[data-a-size=l] .a-price-fraction {
top: -.5em;
font-size: 0.8rem
}
.a-text-price {
color: inherit
}

37
src/components/CPrice/CPrice.ts Executable file
View File

@@ -0,0 +1,37 @@
import { defineComponent, onMounted, ref, toRef, watch } from 'vue'
import { tools } from '@store/Modules/tools'
export default defineComponent({
name: 'CPrice',
props: {
sale_price: {
type: Number,
},
price: {
type: Number,
},
bold: {
type: Boolean,
default: false,
},
},
setup(props) {
const real_price = ref(0)
onMounted(() => {
if (props.sale_price)
real_price.value = props.sale_price
else
real_price.value = props.price ? props.price : 0
})
return {
tools,
real_price,
}
},
})

View File

@@ -0,0 +1,25 @@
<template>
<span class="a-price" data-a-size="l" data-a-color="base">
<span aria-hidden="true" v-if="!!real_price">
<span class="a-price-whole">{{ tools.getIntPart(real_price) }}</span>
<span class="a-price-decimal">,</span>
<span class="a-price-fraction">{{
tools.getDecPart2Digit(real_price)
}}</span>
<span class="a-price-symbol"></span>
</span>
</span>
<span v-if="!!sale_price && !bold" :class="sale_price ? 'prod_off_price' : ''"
>{{ price ? price.toFixed(2) : 0 }}
</span>
</template>
<script lang="ts" src="./CPrice.ts">
</script>
<style lang="scss" scoped>
@import './CPrice.scss';
</style>

1
src/components/CPrice/index.ts Executable file
View File

@@ -0,0 +1 @@
export { default as CPrice } from './CPrice.vue'

View File

@@ -181,9 +181,9 @@ export default defineComponent({
} }
function updateproduct() { async function updateproduct() {
myproduct.value = products.getProductById(props.id) myproduct.value = await products.getProductById(props.id)
// products.updateQuantityAvailable(myproduct.value._id) // products.updateQuantityAvailable(myproduct.value._id)
} }
@@ -194,15 +194,15 @@ export default defineComponent({
if (prod) { if (prod) {
myproduct.value = prod myproduct.value = prod
} }
load() await load()
endload.value = true endload.value = true
} }
function updateproductmodif() { async function updateproductmodif() {
try { try {
myproduct.value = products.getProductById(props.id) myproduct.value = await products.getProductById(props.id)
updateLabel() updateLabel()
} catch (e) { } catch (e) {
@@ -250,9 +250,9 @@ export default defineComponent({
return '' return ''
} }
watch(() => props.id, (newval, oldval) => { watch(() => props.id, async (newval, oldval) => {
// console.log('change code') // console.log('change code')
load() await load()
}) })
watch(() => storeSelected.value, (newval, oldval) => { watch(() => storeSelected.value, (newval, oldval) => {
@@ -283,8 +283,8 @@ export default defineComponent({
updateTimerLabel() updateTimerLabel()
} }
function mounted() { async function mounted() {
load() await load()
// Start the timer when the component is mounted // Start the timer when the component is mounted
startTimer(); startTimer();
@@ -312,9 +312,9 @@ export default defineComponent({
timerInterval.value = setInterval(() => updateTimerLabel(), 60000); timerInterval.value = setInterval(() => updateTimerLabel(), 60000);
} }
function load() { async function load() {
initproduct() initproduct()
updateproduct() await updateproduct()
labelDataArrivoMerce.value = '' labelDataArrivoMerce.value = ''
labelDataRitiro.value = '' labelDataRitiro.value = ''

View File

@@ -997,7 +997,8 @@
<q-img <q-img
:src="myproduct.productInfo.img ? `` + myproduct.productInfo.img : myproduct.productInfo.image_link" :src="myproduct.productInfo.img ? `` + myproduct.productInfo.img : myproduct.productInfo.image_link"
:alt="myproduct.productInfo.name" :alt="myproduct.productInfo.name"
:fit="tools.isMobile() ? 'fill' : 'none'" :fit="tools.isMobile() ? 'fill' : 'cover'"
class="fullscreen-image"
@touchstart="onTouchStart" @touchstart="onTouchStart"
@touchmove="onTouchMove" @touchmove="onTouchMove"
@touchend="onTouchEnd" @touchend="onTouchEnd"

View File

@@ -31,9 +31,11 @@ export interface IProductInfo {
link?: string link?: string
link_scheda?: string link_scheda?: string
checkout_link?: string checkout_link?: string
idAuthors?: string[]
authors?: string[] authors?: string[]
collezione?: string collezione?: string
publisher?: string idPublisher?: string
publisher?: IPublisher
date_publishing?: Date date_publishing?: Date
numpages?: number numpages?: number
productType?: number productType?: number
@@ -191,6 +193,13 @@ export interface IQueryAI {
color?: string, color?: string,
} }
export interface IPublisher {
_id?: any
idapp?: string
name?: string
link?: string
}
export interface ISubCatProd { export interface ISubCatProd {
_id?: any _id?: any
idCatProd: string idCatProd: string

File diff suppressed because one or more lines are too long

View File

@@ -8582,8 +8582,41 @@ export const tools = {
} }
return color return color
} },
getIconByVersione (versione: number ) {
let str = ''
if (versione === shared_consts.VERSIONE.NUOVO)
str = 'fas fa-book'
else if (versione === shared_consts.VERSIONE.USATO)
// Versione Libro usato
str = 'fas fa-book-open'
else if (versione === shared_consts.VERSIONE.DOWNLOAD)
str = 'fas fa-file-download'
else if (versione === shared_consts.VERSIONE.DVD)
str = 'fas fa-film'
else if (versione === shared_consts.VERSIONE.PDF)
str = 'fas fa-file-pdf'
else if (versione === shared_consts.VERSIONE.EPUB)
// Libro elettronico EPUB
str = 'fas fa-book-open-reader'
else if (versione === shared_consts.VERSIONE.DVD)
str = 'fas fa-video'
else if (versione === shared_consts.VERSIONE.STREAMING)
str = 'fas fa-stream'
return str
},
// get the integer part, no round, of a decimal number
getIntPart(number: number) {
return Math.trunc(number)
},
// get the last 2 digit fraction part, of a decimal number
getDecPart2Digit(number: number) {
return Math.round(number * 100) % 100
}
// FINE ! // FINE !

View File

@@ -172,12 +172,6 @@ export const useProducts = defineStore('Products', {
} }
}, },
getProductById: (state: IProductsState) => (id: string): IProduct => {
const prod = state.products.find((prod: IProduct) => prod._id === id)
return prod ? prod : getRecordProductEmpty()
},
getProductByCode: (state: IProductsState) => (code: string): IProduct => { getProductByCode: (state: IProductsState) => (code: string): IProduct => {
if (!code) { if (!code) {
return getRecordProductEmpty() return getRecordProductEmpty()
@@ -410,6 +404,19 @@ export const useProducts = defineStore('Products', {
this.products = [...arrprod] this.products = [...arrprod]
},*/ },*/
async getProductById (id: string): Promise<IProduct> {
let prod = null
if (!this.products) {
// Se non lo carico all'avvio, allora fai la chiamata al server
prod = await this.loadProductById(id)
} else {
prod = this.products.find((prod: IProduct) => prod._id === id)
}
return prod ? prod : getRecordProductEmpty()
},
async loadProducts() { async loadProducts() {
const userStore = useUserStore() const userStore = useUserStore()
@@ -882,7 +889,7 @@ export const useProducts = defineStore('Products', {
return ris return ris
}, },
async addtoCartBase({ $q, t, id, order, addqty }: { $q: any, t: any, id: string, order: IOrder, addqty: boolean }) { async addtoCartBase({ $q, t, id, order, addqty }: { $q: any, t: any, id: string, order: IOrder, addqty: boolean }) {
let product = this.getProductById(id) let product = await this.getProductById(id)
return await this.addToCart({ product, order, addqty }) return await this.addToCart({ product, order, addqty })
.then((ris) => { .then((ris) => {

View File

@@ -4,14 +4,14 @@ $heightBtn: 100%;
height: 300px; height: 300px;
} }
.container{ .container {
margin-top: 4px; margin-top: 4px;
margin-bottom: 4px; margin-bottom: 4px;
} }
.prod_trov{ .prod_trov {
font-style: italic; font-style: italic;
color: blue; color: grey;
} }
.fixed-group { .fixed-group {
@@ -19,7 +19,36 @@ $heightBtn: 100%;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
background-color: #ffffff; /* Customize the background color as needed */ background-color: #ffffff;
z-index: 1000; /* Adjust the z-index to ensure it's above other elements */ /* Customize the background color as needed */
z-index: 1000;
/* Adjust the z-index to ensure it's above other elements */
transition: all 1s ease; transition: all 1s ease;
} }
// Underline like a href
.category {
color: darkblue;
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
line-height: 19px;
cursor: pointer;
}
.category_sel {
color: white !important;
background: #5c8ef4 !important;
padding: 2px;
}
.category-title{
font-weight: bold;
font-size: 1.1rem;
margin-bottom: 0.5rem;
margin-top: 0.5rem;
color: black;
text-align: center;
}

View File

@@ -121,12 +121,12 @@ export default defineComponent({
// Use a regular expression to match whole words // Use a regular expression to match whole words
let codeMatch = new RegExp(`\\b${lowerSearchText}\\b`, 'i'); let codeMatch = new RegExp(`\\b${lowerSearchText}\\b`, 'i');
let nameMatch = new RegExp(`\\b${lowerSearchText}`, 'i'); let nameMatch = new RegExp(`\\b(?=.*\\b${lowerSearchText.split(/\s+/).map(word => `(${word})\\b`).join('.*\\b')}\\b)`, 'i');
// Check if any word in lowerName starts with lowerSearchText // Check if all words in lowerSearchText are present in lowerName
let anyWordStartsWithSearch = lowerName.split(/\s+/).some(word => nameMatch.test(word)); let allWordsPresent = lowerSearchText.split(/\s+/).every(word => new RegExp(`\\b${word}\\b`, 'i').test(lowerName));
return (codeMatch.test(product.productInfo.code!) || anyWordStartsWithSearch) && hasCategoria && productgassel; return (codeMatch.test(product.productInfo.code!) || allWordsPresent) && hasCategoria && productgassel;
} }
}); });
} }

View File

@@ -4,51 +4,7 @@
<q-spinner v-if="!loadpage" color="primary" size="3em" :thickness="2" /> <q-spinner v-if="!loadpage" color="primary" size="3em" :thickness="2" />
</div> </div>
<div v-if="loadpage" class="panel"> <div v-if="loadpage" class="panel">
<div v-if="true"> <div v-if="true"></div>
<!--<CSelectUserActive></CSelectUserActive>-->
<!-- <div class="text-center text-h7 text-blue">Filtra Prodotti per:</div>
<div class="text-center">
<q-btn-toggle
v-model="cosa"
push
:size="tools.isMobile() ? '0.75rem' : '1rem'"
rounded
glossy
toggle-color="primary"
:options="[
{ value: shared_consts.PROD.GAS, slot: 'gas' },
{ value: shared_consts.PROD.BOTTEGA, slot: 'bottega' },
]"
>
<template v-slot:tutti>
<div class="row items-center no-wrap">
<div class="text-center">
{{ t('ecomm.tutti') }}
</div>
<q-icon right name="fas fa-check-square" />
</div>
</template>
<template v-slot:gas>
<div class="row items-center no-wrap">
<div class="text-center">
{{ t('gas.ordina_sul_gas') }}
</div>
<q-icon right name="fas fa-user-friends" />
</div>
</template>
<template v-slot:bottega>
<div class="row items-center no-wrap">
<div class="text-center">
{{ t('gas.bottega') }}
</div>
<q-icon right name="fas fa-store" />
</div>
</template>
</q-btn-toggle>
</div> -->
</div>
<div class="container"> <div class="container">
<q-slide-transition> <q-slide-transition>
@@ -163,9 +119,19 @@
</div> </div>
</div> </div>
<div v-else> <div v-else>
<div class="row q-gutter-xs justify-center q-mx-auto"> <div class="category-title">Categorie</div>
<div class="row q-gutter-xs justify-center q-mx-auto bg-blue-1">
<div v-for="(reccat, index) in getCatProds()" :key="index"> <div v-for="(reccat, index) in getCatProds()" :key="index">
<q-btn <span
:class="{
category: true,
category_sel: cat === reccat.value,
}"
@click="cat = reccat.value"
>{{ reccat.label }}
</span>
|
<!--<q-btn
:push="cat === reccat.value" :push="cat === reccat.value"
dense dense
:size="tools.isMobile() ? '0.70rem' : '1rem'" :size="tools.isMobile() ? '0.70rem' : '1rem'"
@@ -176,7 +142,7 @@
:label="reccat.label" :label="reccat.label"
@click="cat = reccat.value" @click="cat = reccat.value"
> >
</q-btn> </q-btn>-->
</div> </div>
</div> </div>
<div class="text-center q-py-sm prod_trov"> <div class="text-center q-py-sm prod_trov">
@@ -264,6 +230,13 @@
:id="product._id" :id="product._id"
:complete="false" :complete="false"
:cosa="cosa" :cosa="cosa"
:options="{
show_short_descr: false,
show_price: false,
show_cat: false,
quante_col: 'c2',
in_3d: false,
}"
/> />
<CProductCard <CProductCard
v-else-if="product.active || show_hide" v-else-if="product.active || show_hide"

View File

@@ -3,7 +3,18 @@
<div class="panel"> <div class="panel">
<div class="container"> <div class="container">
<div class="row justify-center"> <div class="row justify-center">
<CCatalogoCard :id="id" :cosa="cosa" :complete="true"/> <CCatalogoCard
:id="id"
:cosa="cosa"
:complete="true"
:options="{
show_short_descr: true,
show_price: true,
show_cat: true,
quante_col: 'c1',
in_3d: true,
}"
/>
</div> </div>
</div> </div>
</div> </div>
@@ -11,7 +22,6 @@
</template> </template>
<script lang="ts" src="./catalogoInfo.ts"> <script lang="ts" src="./catalogoInfo.ts">
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>