- Catalogo: Aggiunta di Schede

This commit is contained in:
Surya Paolo
2024-10-31 23:23:06 +01:00
parent b6f73019fe
commit 2ea6468100
123 changed files with 3382 additions and 3595327 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/assets/fonts/DINPro.otf Normal file

Binary file not shown.

View File

@@ -3,11 +3,11 @@
max-width: 200px;
min-width: 120px;
padding: 1rem 1rem;
box-shadow: none;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
max-width: 150px;
padding: 0;
}
box-shadow: none;
}

View File

@@ -3,26 +3,28 @@
max-width: 200px;
min-width: 120px;
padding: 1rem 1rem;
@media (max-width: 718px) {
box-shadow: none;
// PER VERSIONE MOBILE
@media (max-width: 718px) {
max-width: 150px;
padding: 0;
}
box-shadow: none;
}
.my-card-small-stat {
width: 100%;
max-width: 60px;
min-width: 40px;
box-shadow: none;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
max-width: 50px;
min-width: 40px;
}
box-shadow: none;
}

View File

@@ -0,0 +1,600 @@
<template>
<div
:class="{
' items-start q-gutter-sm': true,
}"
:style="
optcatalogo.height
? ' height: ' + optcatalogo.height + ' !important; '
: ''
"
>
<q-spinner v-if="!endload" color="primary" size="3em" :thickness="2" />
<div
v-if="!!myproduct && !!myproduct.productInfo"
:class="{
'my-card-big book-details': complete,
'book-card': !complete && !optcatalogo.pdf,
colfix_prodotti_1: options.quante_col == 'c1' && !optcatalogo.pdf,
colfix_prodotti_2: options.quante_col == 'c2' && !optcatalogo.pdf,
colfix_prodotti_3: options.quante_col == 'c3' && !optcatalogo.pdf,
}"
>
<q-toggle
v-if="tools.isManager() && !optcatalogo.pdf"
v-model="editOn"
class="absolute-top-right"
color="green"
icon="fas fa-pencil-alt"
dense
>
</q-toggle>
<q-page-sticky
v-if="complete && !optcatalogo.pdf"
position="bottom-right"
:offset="[18, 0]"
style="z-index: 1000"
>
<q-btn
fab
icon="fas fa-arrow-up"
class="semi-transparent"
color="primary"
v-close-popup
/>
</q-page-sticky>
<q-card-section>
<div
:class="{
'flex q-pa-sm': !optcatalogo.pdf,
'shadow-2': options.in_3d,
'items-center': true, // Centrare verticalmente
}"
:style="'justify-items: center; '"
>
<q-img
v-if="myproduct.productInfo"
:src="
myproduct.productInfo.imagefile
? tools.getFullFileNameByImageFile(
'productInfos',
myproduct.productInfo.imagefile
)
: myproduct.productInfo.image_link
"
:alt="myproduct.productInfo.name"
:class="{
'book-image-fixed': complete,
'cursor-pointer': !complete,
'shadow-4': true,
'image-wrapper': optcatalogo.pdf,
'items-center': true,
}"
:style="
'place-items: center; ' +
(optcatalogo.width
? ' width: ' + optcatalogo.width + ' !important; '
: '')
"
@click="click_opendetail()"
>
<div
class="absolute transparent"
style="left: 90%; top: -18px; transform: translateX(-50%)"
>
<q-btn
v-if="!optcatalogo.pdf"
color="blue-6"
class="semi-transparent"
round
icon="search"
@click.stop="toggleFullScreen"
size="sm"
/>
</div>
</q-img>
<div v-if="false" class="scheda-book">
<div>
<span class="book-title" :data-col="options.quante_col">
<span
v-if="!complete"
class="cursor-pointer"
@click="click_opendetail()"
>{{ myproduct.productInfo.name }}
</span>
<span v-else>{{ myproduct.productInfo.name }} </span>
</span>
</div>
<div
v-if="myproduct.productInfo.authors"
class="book-author"
:data-col="options.quante_col"
>
di
<span
v-for="(author, index) in myproduct.productInfo.authors"
:key="author._id"
>
<span v-if="index > 0">, </span>
<span
class="author cursor-pointer text-primary"
@click="
click_author(author._id, author.name + ' ' + author.surname)
"
>{{ author.name }} {{ author.surname }}</span
>
</span>
</div>
<div
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>
</div>
<div
v-if="
options.show_short_descr && myproduct.productInfo.short_descr
"
class="book-short-descr"
>
{{
tools.firstchars(myproduct.productInfo.short_descr, 200, true)
}}
</div>
<div
v-if="myproduct.productInfo.numpages && complete"
class="book-pages"
>
Pagine: {{ myproduct.productInfo.numpages }}
</div>
<div v-if="myproduct.productInfo.publisher" class="book-pages">
{{ myproduct.productInfo.publisher.name }}
</div>
<div
v-if="myproduct.productInfo.date_publishing && complete"
class="book-data-pub"
>
Data Pubblicazione:
{{ tools.getstrDate(myproduct.productInfo.date_publishing) }}
</div>
<q-separator class="q-my-sm"></q-separator>
<div v-if="options.show_price">
<div
:class="{
'row items-center q-pa-nome block-variazione': true,
'block-variazione-selected': indvariazSel == index,
}"
v-for="(variazione, index) of myproduct.arrvariazioni"
:key="index"
@click="setvariazioneSelected(index)"
>
<div
v-if="checkIfVariazioneDaVisu(variazione)"
class="flex justify-between items-center q-mx-sm"
>
<q-badge
class="q-badge--large"
:color="
tools.getRecByVersioneProd(variazione.versione).color
"
>
<q-icon
v-if="variazione.versione > 0"
:name="tools.getIconByVersione(variazione.versione)"
color="white"
></q-icon
>&nbsp;
{{ tools.getRecByVersioneProd(variazione.versione).label }}
</q-badge>
<div v-if="variazione.formato && false">
formato: {{ variazione.formato }}
</div>
<div v-if="variazione.tipologia && false">
tipologia: {{ variazione.tipologia }}
</div>
<div v-if="variazione.status && false">
status: {{ variazione.status }}
</div>
<div v-if="variazione.preOrderDate">
preOrderDate: {{ variazione.preOrderDate }}
</div>
</div>
<q-item-section>
<q-item-label>
<CPrice
:sale_price="variazione.sale_price"
:price="variazione.price"
></CPrice>
<span v-if="!!myproduct.after_price">{{
myproduct.after_price
}}</span>
</q-item-label>
<q-item-label
v-if="
myproduct.scontisticas &&
myproduct.scontisticas.length > 0
"
>
<div
class="prod_sconti"
v-for="(sconti, index) of myproduct.scontisticas"
:key="index"
>
{{ sconti.description }}
</div>
</q-item-label>
</q-item-section>
<q-item-section side v-if="!!variazione.quantita">
<q-icon
v-if="variazione.quantita > 10"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-check"
/>
<q-icon
v-else-if="
variazione.quantita > 3 && variazione.quantita <= 10
"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-exclamation"
/>
<q-icon
v-else-if="
variazione.quantita > 0 && variazione.quantita <= 3
"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-exclamation"
/>
<q-icon
v-else-if="variazione.quantita === 0"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-times"
/>
</q-item-section>
</div>
<div
v-for="(variazione, index) of myproduct.arrvariazioni"
:key="index"
>
<div
v-show="
indvariazSel == index && checkIfVariazioneDaVisu(variazione)
"
>
<div
v-show="tools.disponibStr(variazione.quantita)"
class="row justify-center q-mt-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm"
>{{ $t('ecomm.disponibilita') }}:&nbsp;</span
>
<q-chip
size="md"
dense
text-color="white"
:color="tools.colordisponib(variazione.quantita)"
>{{ tools.disponibStr(variazione.quantita) }}</q-chip
>
</div>
<div
class="row justify-center vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.price') }}:</span>
<CPrice
:sale_price="variazione.sale_price"
:price="variazione.price"
bold="true"
></CPrice>
<span v-show="!!myproduct.after_price">{{
myproduct.after_price
}}</span>
</div>
<div
v-show="!!variazione.formato"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.formato') }}:</span>
<q-badge
v-show="variazione.versione > 0"
:color="
tools.getRecByVersioneProd(variazione.versione).color
"
>{{ variazione.formato }}</q-badge
>
</div>
<div
v-show="!!variazione.edizione"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.edizione') }}:</span>
{{ variazione.edizione }}
</div>
<div
v-show="!!myproduct.isbn"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.isbn') }}:</span>
{{ myproduct.isbn }}
</div>
<div
v-show="!!myproduct.productInfo.publisher"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.editore') }}:</span>
<q-badge
:color="
tools.getRecByVersioneProd(variazione.versione).color
"
>{{ myproduct.productInfo.publisher.name }}</q-badge
>
</div>
<div class="row justify-center q-mt-sm">
<q-btn
v-if="variazione.addtocart_link && true"
:href="variazione.addtocart_link"
target="_blank"
color="primary"
icon="fas fa-cart-plus"
class="q-mr-sm"
no-caps
:label="$t('products.addtocart_ext')"
></q-btn>
<q-btn
v-if="myproduct.productInfo.checkout_link && true"
:href="myproduct.productInfo.checkout_link"
target="_blank"
class="q-ml-sm"
color="white"
icon="fas fa-shopping-cart"
outline
text-color="black"
no-caps
:label="$t('ecomm.carrello')"
></q-btn>
</div>
</div>
</div>
</div>
</div>
</div>
</q-card-section>
<q-separator v-if="complete" class="q-my-sm"></q-separator>
<q-card-section v-if="complete && myproduct.productInfo.description">
<div class="title-descr text-blue row">Descrizione:</div>
<div class="row items-center">
<div class="text-title text-grey-9">
<span
class="text-grey-7"
v-html="myproduct.productInfo.description"
></span>
</div>
</div>
</q-card-section>
</div>
<q-dialog v-if="myproduct" v-model="openlistorders">
<q-card class="dialog_card">
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
{{ t('ecomm.listaord') }} - {{ myproduct.productInfo.name }}
</q-toolbar-title>
<q-btn flat round color="white" icon="close" v-close-popup></q-btn>
</q-toolbar>
<q-card-section class="q-pa-xs inset-shadow">
<q-markup-table
wrap-cells
bordered
separator="horizontal"
class="listaev__table"
>
<thead>
<tr>
<th>Data</th>
<th>Persona</th>
<th>Stato</th>
<th>Quantita</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr
v-for="(ordcart, index) of listord"
:key="index"
class="listaev listaev__table"
>
<td class="text-center">
<div>
{{ func_tools.getDateTimeShortStr(ordcart.created_at) }}
</div>
</td>
<td class="text-center">
<strong>{{
tools.getNomeUtenteEUsernameByRecUser(ordcart.user)
}}</strong>
</td>
<td class="text-center">
<strong>{{
shared_consts.getStatusStr(ordcart.status)
}}</strong>
</td>
<td class="text-center">
<div v-for="(singleord, index) in ordcart.items" :key="index">
<span
v-if="
singleord.order.idProduct === myproduct._id &&
singleord.order.quantity > 0
"
>
{{ singleord.order.quantity }}</span
>
<span
v-if="
singleord.order.idProduct === myproduct._id &&
singleord.order.quantitypreordered > 0
"
>
{{ singleord.order.quantitypreordered }}</span
>
</div>
</td>
<td class="text-center">
{{ ordcart.note }}
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td class="text-center">
Totali:
<span class="totali">{{ sumval }}</span>
</td>
<td>&nbsp;</td>
</tr>
</tbody>
</q-markup-table>
</q-card-section>
</q-card>
</q-dialog>
<q-dialog
v-if="
true &&
myproduct &&
myproduct.productInfo &&
myproduct.productInfo.link_scheda
"
v-model="apriSchedaPDF"
maximized
>
<q-card>
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
{{ myproduct.productInfo.name }}
</q-toolbar-title>
<q-btn
flat
round
color="white"
label="CHIUDI"
icon="close"
v-close-popup
></q-btn>
</q-toolbar>
<q-card-section>
<iframe
:src="myproduct.productInfo.link_scheda"
frameborder="0"
width="100%"
height="100%"
></iframe>
</q-card-section>
</q-card>
<q-card-actions align="bottom">
<q-btn color="primary" label="Chiudi" @click="apriSchedaPDF = false" />
</q-card-actions>
</q-dialog>
<q-dialog
v-if="
false &&
myproduct &&
myproduct.productInfo &&
myproduct.productInfo.link_scheda
"
v-model="apriSchedaPDF"
fullscreen
>
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
{{ myproduct.productInfo.name }}
</q-toolbar-title>
<q-btn
flat
round
color="white"
label="CHIUDI"
icon="close"
v-close-popup
></q-btn>
</q-toolbar>
<q-card-section>
<vue-pdf-app
:pdf="myproduct.productInfo.link_scheda"
style="height: 100vh"
></vue-pdf-app>
</q-card-section>
</q-dialog>
<q-dialog
v-model="isFullScreen"
position="top"
:maximized="true"
class="q-pt-none"
>
<div
v-if="isFullScreen"
class="fullscreen-container"
@touchmove.prevent
@click="toggleFullScreen"
>
<q-img
:src="
myproduct.productInfo.imagefile
? `` + myproduct.productInfo.imagefile
: myproduct.productInfo.image_link
"
:alt="myproduct.productInfo.name"
:fit="tools.isMobile() ? 'fill' : 'contain'"
class="fullscreen-image"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@touchend="onTouchEnd"
ref="fullscreenImage"
>
</q-img>
<br />
</div>
<div class="text-center">
<q-btn
class="q-ma-md"
@click="isFullScreen = false"
label="Chiudi"
rounded
color="primary"
icon="close"
></q-btn>
</div>
</q-dialog>
</div>
</template>
<script lang="ts" src="./CCatalogoCard.ts">
</script>
<style lang="scss" scoped>
@import './CCatalogoCard.scss';
</style>

View File

@@ -46,13 +46,19 @@
<q-card-section>
<div
:class="{
'flex q-pa-sm': !optcatalogo.pdf,
'shadow-2': options.in_3d,
'items-center': true, // Centrare verticalmente
:class="[
'flex q-pa-xs', // Classi comuni
{ 'shadow-2': options.in_3d }, // Classe condizionale
optcatalogo.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? 'flex-col'
: 'flex-row', // Layout flessibile
]"
:style="{
justifyContent: 'center',
alignItems: 'flex-start',
gap: '0.5rem',
width: '100%',
}"
:style="'justify-items: center; '"
>
<q-img
v-if="myproduct.productInfo"
@@ -70,14 +76,17 @@
'cursor-pointer': !complete,
'shadow-4': true,
'image-wrapper': optcatalogo.pdf,
'items-center': true,
}"
:style="
'place-items: center; ' +
(optcatalogo.width
? ' width: ' + optcatalogo.width + ' !important; '
: '')
"
:style="{
width:
optcatalogo.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? '50%'
: '45%',
...(optcatalogo.width && {
width: optcatalogo.width + ' !important',
}),
display: 'block',
}"
@click="click_opendetail()"
>
<div
@@ -96,288 +105,24 @@
</div>
</q-img>
<div class="scheda-book">
<q-card-title>
<span class="book-title" :data-col="options.quante_col">
<span
v-if="!complete"
class="cursor-pointer"
@click="click_opendetail()"
>{{ myproduct.productInfo.name }}
</span>
<span v-else>{{ myproduct.productInfo.name }} </span>
</span>
</q-card-title>
<q-card-subtitle
v-if="myproduct.productInfo.authors"
class="book-author"
:data-col="options.quante_col"
>
di
<span
v-for="(author, index) in myproduct.productInfo.authors"
:key="author._id"
>
<span v-if="index > 0">, </span>
<span
class="author cursor-pointer text-primary"
@click="
click_author(author._id, author.name + ' ' + author.surname)
"
>{{ author.name }} {{ author.surname }}</span
>
</span>
</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
v-if="
options.show_short_descr && myproduct.productInfo.short_descr
"
class="book-short-descr"
>{{
tools.firstchars(myproduct.productInfo.short_descr, 200, true)
}}</q-card-main
>
<!-- Testo associato all'immagine -->
<div
:style="{
width:
optcatalogo.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? '100%'
: '50%',
textAlign: 'center',
marginTop:
optcatalogo.posiz_text === costanti.POSIZ_TESTO.IN_BASSO
? '1rem'
: '0',
}"
>
<div
v-if="myproduct.productInfo.numpages && complete"
class="book-pages"
>
Pagine: {{ myproduct.productInfo.numpages }}
</div>
<div v-if="myproduct.productInfo.publisher" class="book-pages">
{{ myproduct.productInfo.publisher.name }}
</div>
<div
v-if="myproduct.productInfo.date_publishing && complete"
class="book-data-pub"
>
Data Pubblicazione:
{{ tools.getstrDate(myproduct.productInfo.date_publishing) }}
</div>
<q-separator class="q-my-sm"></q-separator>
<div v-if="options.show_price">
<div
:class="{
'row items-center q-pa-nome block-variazione': true,
'block-variazione-selected': indvariazSel == index,
}"
v-for="(variazione, index) of myproduct.arrvariazioni"
:key="index"
@click="setvariazioneSelected(index)"
>
<div
v-if="checkIfVariazioneDaVisu(variazione)"
class="flex justify-between items-center q-mx-sm"
>
<q-badge
class="q-badge--large"
:color="
tools.getRecByVersioneProd(variazione.versione).color
"
>
<q-icon
v-if="variazione.versione > 0"
:name="tools.getIconByVersione(variazione.versione)"
color="white"
></q-icon
>&nbsp;
{{ tools.getRecByVersioneProd(variazione.versione).label }}
</q-badge>
<div v-if="variazione.formato && false">
formato: {{ variazione.formato }}
</div>
<div v-if="variazione.tipologia && false">
tipologia: {{ variazione.tipologia }}
</div>
<div v-if="variazione.status && false">
status: {{ variazione.status }}
</div>
<div v-if="variazione.preOrderDate">
preOrderDate: {{ variazione.preOrderDate }}
</div>
</div>
<q-item-section>
<q-item-label>
<CPrice
:sale_price="variazione.sale_price"
:price="variazione.price"
></CPrice>
<span v-if="!!myproduct.after_price">{{
myproduct.after_price
}}</span>
</q-item-label>
<q-item-label
v-if="
myproduct.scontisticas &&
myproduct.scontisticas.length > 0
"
>
<div
class="prod_sconti"
v-for="(sconti, index) of myproduct.scontisticas"
:key="index"
>
{{ sconti.description }}
</div>
</q-item-label>
</q-item-section>
<q-item-section side v-if="!!variazione.quantita">
<q-icon
v-if="variazione.quantita > 10"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-check"
/>
<q-icon
v-else-if="
variazione.quantita > 3 && variazione.quantita <= 10
"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-exclamation"
/>
<q-icon
v-else-if="
variazione.quantita > 0 && variazione.quantita <= 3
"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-exclamation"
/>
<q-icon
v-else-if="variazione.quantita === 0"
:color="tools.colordisponib(variazione.quantita)"
name="fas fa-times"
/>
</q-item-section>
</div>
<div
v-for="(variazione, index) of myproduct.arrvariazioni"
:key="index"
>
<div
v-show="
indvariazSel == index && checkIfVariazioneDaVisu(variazione)
"
>
<div
v-show="tools.disponibStr(variazione.quantita)"
class="row justify-center q-mt-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm"
>{{ $t('ecomm.disponibilita') }}:&nbsp;</span
>
<q-chip
size="md"
dense
text-color="white"
:color="tools.colordisponib(variazione.quantita)"
>{{ tools.disponibStr(variazione.quantita) }}</q-chip
>
</div>
<div
class="row justify-center vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.price') }}:</span>
<CPrice
:sale_price="variazione.sale_price"
:price="variazione.price"
bold="true"
></CPrice>
<span v-show="!!myproduct.after_price">{{
myproduct.after_price
}}</span>
</div>
<div
v-show="!!variazione.formato"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.formato') }}:</span>
<q-badge
v-show="variazione.versione > 0"
:color="
tools.getRecByVersioneProd(variazione.versione).color
"
>{{ variazione.formato }}</q-badge
>
</div>
<div
v-show="!!variazione.edizione"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.edizione') }}:</span>
{{ variazione.edizione }}
</div>
<div
v-show="!!myproduct.isbn"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.isbn') }}:</span>
{{ myproduct.isbn }}
</div>
<div
v-show="!!myproduct.productInfo.publisher"
class="row justify-center q-ma-sm vertical-middle"
style="align-items: center"
>
<span class="q-mr-sm">{{ $t('products.editore') }}:</span>
<q-badge
:color="
tools.getRecByVersioneProd(variazione.versione).color
"
>{{ myproduct.productInfo.publisher.name }}</q-badge
>
</div>
<div class="row justify-center q-mt-sm">
<q-btn
v-if="variazione.addtocart_link && true"
:href="variazione.addtocart_link"
target="_blank"
color="primary"
icon="fas fa-cart-plus"
class="q-mr-sm"
no-caps
:label="$t('products.addtocart_ext')"
></q-btn>
<q-btn
v-if="myproduct.productInfo.checkout_link && true"
:href="myproduct.productInfo.checkout_link"
target="_blank"
class="q-ml-sm"
color="white"
icon="fas fa-shopping-cart"
outline
text-color="black"
no-caps
:label="$t('ecomm.carrello')"
></q-btn>
</div>
</div>
</div>
</div>
:style="`line-height: ${optcatalogo.line_height}%; `"
v-html="products.replaceKeyWordsByProduct(myproduct, optcatalogo.text)"
></div>
</div>
</div>
</q-card-section>
@@ -411,11 +156,13 @@
class="listaev__table"
>
<thead>
<th>Data</th>
<th>Persona</th>
<th>Stato</th>
<th>Quantita</th>
<th>Note</th>
<tr>
<th>Data</th>
<th>Persona</th>
<th>Stato</th>
<th>Quantita</th>
<th>Note</th>
</tr>
</thead>
<tbody>

View File

@@ -4,19 +4,19 @@
min-width: 120px;
padding: 1rem 1rem;
box-shadow: none;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
max-width: 150px;
padding: 0;
}
box-shadow: none;
}
.my-card-small-stat {
width: 100%;
max-width: 60px;
min-width: 40px;
box-shadow: none;
@media (max-width: 718px) {
// PER VERSIONE MOBILE
@@ -24,7 +24,6 @@
min-width: 40px;
}
box-shadow: none;
}

View File

@@ -2,7 +2,7 @@ import {
defineComponent, onMounted, PropType, computed, ref, toRef, watch,
} from 'vue'
import { IColGridTable, IElemText, IImgGallery, ILabelValue, IMyCard, IMyElem, IMyPage, IOperators } from '@src/model'
import { IColGridTable, IElemText, IImgGallery, ILabelValue, IMyCard, IMyElem, IMyPage, IMyScheda, IOperators, ISchedaSingola } from '@src/model'
import { useGlobalStore } from '@store/globalStore'
import { CImgTitle } from '@/components/CImgTitle'
@@ -40,7 +40,7 @@ export default defineComponent({
CCardCarousel, COpenStreetMap, CMyPage, CMyPageIntro, CMyEditor, CMyFieldRec,
CSelectColor, CSelectFontSize, CSelectImage, CImgPoster, CSelectAnimation, CMySlider
},
emits: ['saveElem', 'selElemClick', 'toggleSize', 'deleteElem'],
emits: ['saveElem', 'selElemClick', 'toggleSize', 'deleteElem', 'dupPage'],
props: {
myelem: {
type: Object as PropType<IMyElem>,
@@ -51,6 +51,11 @@ export default defineComponent({
required: false,
default: '',
},
IdPath: {
type: String,
required: false,
default: '',
},
editOn: {
type: Boolean,
required: false,
@@ -72,10 +77,16 @@ export default defineComponent({
const $q = useQuasar()
const { t } = useI18n()
const posizTextOptions = ref([
{ label: 'In basso', value: costanti.POSIZ_TESTO.IN_BASSO },
{ label: 'A Destra', value: costanti.POSIZ_TESTO.A_DESTRA },
])
const animare = ref(0)
const slide = ref(0)
const slide2 = ref(0)
const tabCard = ref('card0')
const tabCard = ref(0)
const tabScheda = ref(0)
const tabElemsText = ref('elem0')
const arrPages = ref([] as any[])
const disableSave = ref(true)
@@ -161,6 +172,9 @@ export default defineComponent({
// emit('updateAll', newrec)
}
async function dupPage() {
emit('dupPage', null)
}
async function dupElem(order?: number) {
const newrec: IMyElem = { ...props.myelem }
@@ -246,6 +260,77 @@ export default defineComponent({
}
function addNewScheda() {
let maxorder = 0
myel.value.catalogo!.arrSchede?.forEach(scheda => {
if (scheda.order > maxorder) {
maxorder = scheda.order
}
})
let newscheda: IMyScheda = {
_id: objectId(),
idapp: tools.appid()!,
isTemplate: false,
name: 'Scheda Nuova',
widthscheda: '360px',
line_height: 100,
widthpag: 800,
width: 150,
height: 234,
numschede_perRiga: 2,
numschede_perCol: 2,
margine_top: 12,
margine_pagina: '92px',
margine_riga: '41px',
text: '',
posiz_text: costanti.POSIZ_TESTO.A_DESTRA,
productTypes: [],
excludeproductTypes: [],
editore: [],
author: '',
sort: costanti.SORT_PUBDATE,
arrProdottiSpeciali: [],
}
if (!myel.value.catalogo!.arrSchede)
myel.value.catalogo!.arrSchede = []
myel.value.catalogo!.arrSchede.push(
{
_id: objectId(),
scheda: { ...newscheda },
order: maxorder + 10,
numSchede: 1,
}
)
// console.log('arrschede', myel.value.catalogo!.arrSchede)
modifElem()
}
function dupNewScheda(id: string) {
if (!myel.value.catalogo!.arrSchede)
return
const myfindscheda = myel.value.catalogo!.arrSchede.find((scheda: ISchedaSingola) => scheda._id === id)
if (myfindscheda) {
let myscheda = { ...myfindscheda }
delete myscheda._id
myscheda._id = objectId()
const bakscheda = [...myel.value.catalogo!.arrSchede]
myel.value.catalogo!.arrSchede = []
myel.value.catalogo!.arrSchede = [...bakscheda, myscheda]
modifElem()
}
}
function dupNewCard() {
if (!myel.value.listcards)
@@ -306,10 +391,17 @@ export default defineComponent({
myel.elemsText = myel.elemsText.filter((rec: IElemText) => rec._id !== id)
}
}
function delRecScheda(id: string, myel: IMyElem) {
//
myel.catalogo!.arrSchede = myel.catalogo!.arrSchede!.filter((scheda: ISchedaSingola) => scheda._id !== id)
modifElem()
}
function saveFieldElem(rec: any, newval: any, col: IColGridTable) {
console.log('saveFieldElem', rec, 'newval', newval, 'col', col)
//console.log('saveFieldElem', rec, 'newval', newval, 'col', col)
let iscatalogo = costanti.CATALOGO_FIELDS.includes(col.name)
@@ -366,7 +458,7 @@ export default defineComponent({
}
modifElem()
}
function showAnimation() {
@@ -399,6 +491,20 @@ export default defineComponent({
return options;
}
function SchedeOpt() {
const arrschede = globalStore.getMySchede()
let arr: any = []
if (arrschede) {
arrschede.forEach(scheda => {
arr.push({ label: scheda.name, value: scheda._id })
});
}
return arr
}
function updateSizeWidth(value: any) {
// Gestisce l'input dell'utente per un nuovo valore
myel.value.widthimg = value; // Aggiorna widthimg con il nuovo valore
@@ -409,36 +515,6 @@ export default defineComponent({
myel.value.catalogo!.width = value // Aggiorna widthimg con il nuovo valore
modifElem()
}
function updateCatalogoNumSchedePerCol(value: any) {
// Gestisce l'input dell'utente per un nuovo valore
myel.value.catalogo!.numschede_perCol = value // Aggiorna widthimg con il nuovo valore
modifElem()
}
function updateCatalogoNumSchedePerRiga(value: any) {
// Gestisce l'input dell'utente per un nuovo valore
myel.value.catalogo!.numschede_perRiga = value // Aggiorna widthimg con il nuovo valore
modifElem()
}
function updateCatalogoSizeWidthScheda(value: any) {
// Gestisce l'input dell'utente per un nuovo valore
myel.value.catalogo!.widthscheda = value // Aggiorna widthimg con il nuovo valore
modifElem()
}
function updateCatalogoSizeWidthPag(value: any) {
// Gestisce l'input dell'utente per un nuovo valore
myel.value.catalogo!.widthpag = value // Aggiorna widthimg con il nuovo valore
modifElem()
}
function updateCatalogoSizeWidthPagPrintable(value: any) {
// Gestisce l'input dell'utente per un nuovo valore
myel.value.catalogo!.widthpagPrintable = value // Aggiorna widthimg con il nuovo valore
modifElem()
}
function updateCatalogoSizeHeight(value: any) {
myel.value.catalogo!.height = value
modifElem()
}
function updateSizeHeight(value: any) {
myel.value.heightimg = value; // Aggiorna widthimg con il nuovo valore
modifElem()
@@ -466,10 +542,14 @@ export default defineComponent({
neworder.value = rec
}
function addProdSpeciale(rec: any) {
neworder.value = rec
}
async function moveElem(direz: any) {
let myelem = props.myelem
const elemprec = globalStore.getMyElemPrecThisElemId(props.path, myelem._id)
const elemprec = globalStore.getMyElemPrecThisElemId(props.path, myelem._id!)
const elemnext = globalStore.getMyElemNextThisElemId(props.path, myelem._id!)
let neworder = 0
@@ -589,12 +669,14 @@ export default defineComponent({
classiImmagineOptions,
saveFieldElem,
updateCatalogoSizeWidth,
updateCatalogoSizeHeight,
updateCatalogoSizeWidthScheda,
updateCatalogoSizeWidthPag,
updateCatalogoSizeWidthPagPrintable,
updateCatalogoNumSchedePerCol,
updateCatalogoNumSchedePerRiga,
dupPage,
posizTextOptions,
tabScheda,
addNewScheda,
dupNewScheda,
delRecScheda,
SchedeOpt,
addProdSpeciale,
}
},

View File

@@ -53,6 +53,15 @@
&nbsp;
<q-space />
<q-btn
icon="far fa-copy"
label="Duplica Pagina"
dense
size="sm"
color="fuchsia"
@click="dupPage()"
>
</q-btn>
<q-btn
icon="fas fa-trash-alt"
color="negative"
@@ -70,6 +79,15 @@
@click="dupElem(myel.order + 10 * direzadd)"
>
</q-btn>
<q-btn
dense
icon="fas fa-check"
color="positive"
label="Salva"
size="sm"
@click="saveElem"
>
</q-btn>
</q-bar>
<div class="fixed-button">
<div class="justify-center row q-ma-xs">
@@ -403,7 +421,7 @@
rounded
dense
color="primary"
label="Scheda"
label="Aggiungi"
icon="fas fa-plus"
@click="addNewCard"
>
@@ -412,7 +430,7 @@
rounded
dense
color="primary"
label="Scheda"
label="Duplica"
icon="fas fa-copy"
@click="dupNewCard"
>
@@ -1317,154 +1335,467 @@
</q-select>
</div>
<div v-else-if="myel.type === shared_consts.ELEMTYPE.CATALOGO">
<div v-if="enableEdit" class="row">
<div>Cataloghi:</div>
<br />
<q-toggle
v-model="myel.catalogo.pdf"
color="positive"
icon="fas fa-file-pdf"
label="Versione PDF"
@update:model-value="modifElem"
>
</q-toggle>
<br />
<!--++AddCATALOGO_FIELDS-->
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="enableEdit && myel.catalogo && myel.catalogo.productTypes"
rounded
outlined
v-model="myel.catalogo.productTypes"
:options="shared_consts.VERSIONI_PRODOTTO"
@update:model-value="modifElem"
multiple
dense
label="Includi"
style="width: 150px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="
enableEdit && myel.catalogo && myel.catalogo.excludeproductTypes
"
rounded
outlined
v-model="myel.catalogo.excludeproductTypes"
:options="shared_consts.VERSIONI_PRODOTTO"
@update:model-value="modifElem"
multiple
dense
label="Escludi"
style="width: 150px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="enableEdit"
rounded
outlined
v-model="myel.catalogo.Editore"
:options="Products.publishers"
@update:model-value="modifElem"
multiple
dense
label="Editori"
style="width: 150px"
emit-value
map-options
option-value="_id"
option-label="name"
>
</q-select>
<CMySlider
label="Larghezza Schede:"
v-model="myel.catalogo.widthscheda"
:min="10"
:max="1000"
color="green"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza Pagina:"
v-model="myel.catalogo.widthpag"
:min="10"
:max="1000"
color="green"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza Immagini:"
v-model="myel.catalogo.width"
:min="10"
:max="1000"
color="green"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Altezza Schede:"
v-model="myel.catalogo.height"
:min="10"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
</div>
<div class="sfondo_margine">
Margini:<br />
<CMySlider
label="Schede per Riga"
v-model="myel.catalogo.numschede_perRiga"
:min="1"
:max="10"
color="green"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Schede per Colonna"
v-model="myel.catalogo.numschede_perCol"
:min="1"
:max="10"
color="red"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Margine per Pagina"
v-model="myel.catalogo.margine_pagina"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Margine per Riga"
v-model="myel.catalogo.margine_riga"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
</div>
<div>Sfondo:</div>
<div v-if="enableEdit">
<q-expansion-item
dense
dense-toggle
expand-separator
label="Selezione Collane/Editori"
icon="fas fa-play-circle"
>
<div class="row">
<q-toggle
v-model="myel.catalogo.pdf"
color="positive"
icon="fas fa-file-pdf"
label="Versione PDF"
@update:model-value="modifElem"
>
</q-toggle>
<br />
<!--++AddCATALOGO_FIELDS-->
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="
enableEdit && myel.catalogo && myel.catalogo.productTypes
"
rounded
outlined
v-model="myel.catalogo.productTypes"
:options="shared_consts.VERSIONI_PRODOTTO"
@update:model-value="modifElem"
multiple
dense
label="Includi"
style="width: 150px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="
enableEdit &&
myel.catalogo &&
myel.catalogo.excludeproductTypes
"
rounded
outlined
v-model="myel.catalogo.excludeproductTypes"
:options="shared_consts.VERSIONI_PRODOTTO"
@update:model-value="modifElem"
multiple
dense
label="Escludi"
style="width: 150px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="enableEdit"
rounded
outlined
v-model="myel.catalogo.Editore"
:options="Products.publishers"
@update:model-value="modifElem"
multiple
dense
label="Editori"
style="width: 150px"
emit-value
map-options
option-value="_id"
option-label="name"
>
</q-select>
</div>
</q-expansion-item>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Schede"
icon="fas fa-play-circle"
>
<div class="row">
<q-btn
rounded
dense
color="primary"
label="Aggiungi"
icon="fas fa-plus"
@click="addNewScheda"
>
</q-btn>
<q-tabs
v-model="tabScheda"
dense
class="text-grey"
active-color="primary"
indicator-color="primary"
align="justify"
narrow-indicator
>
<q-tab
v-for="(rec, ind) in myel.catalogo.arrSchede"
:key="ind"
:name="ind"
:label="`Scheda ` + (ind + 1)"
icon="fas fa-pencil-alt"
>
</q-tab>
</q-tabs>
<q-tab-panels v-model="tabScheda" animated>
<q-tab-panel
v-for="(recscheda, ind) in myel.catalogo.arrSchede"
:key="ind"
:name="ind"
>
<q-bar v-if="recscheda" class="bg-primary text-white">
Scheda {{ ind + 1 }}
<span v-if="recscheda.scheda"> '{{
recscheda.scheda.name
}}'</span>
<q-space />
<q-btn
rounded
dense
color="primary"
label="Duplica"
icon="fas fa-copy"
@click="dupNewScheda(recscheda._id)"
>
</q-btn>
<q-btn
icon="fas fa-trash-alt"
color="negative"
dense
size="sm"
@click="delRecScheda(recscheda._id, myel)"
>
</q-btn>
</q-bar>
<div v-if="recscheda && recscheda.scheda">
<q-select
v-model="recscheda.order"
:options="orderOptions"
label="Posizionamento"
options-dense
dense
emit-value
map-options
style="width: 100px"
@update:model-value="modifElem"
fill-input
text-color="white"
>
</q-select>
<q-toggle
v-model="recscheda.scheda.isTemplate"
color="positive"
icon="fas fa-file-pdf"
label="E' un template"
@update:model-value="modifElem"
>
</q-toggle>
<q-input
dense
label="Nome Template"
@update:model-value="modifElem"
v-model="recscheda.scheda.name"
filled
v-on:keyup.enter="saveElem"
>
</q-input>
<!--<q-select
:behavior="
$q.platform.is.ios === true ? 'dialog' : 'menu'
"
v-if="enableEdit"
rounded
outlined
v-model="recscheda._id"
:options="SchedeOpt()"
@update:model-value="modifElem"
dense
label="Scegli Scheda"
style="width: 150px"
emit-value
map-options
>
</q-select>-->
<CMySlider
label="Schede da ripetere"
v-model="recscheda.numSchede"
:min="1"
:max="100"
color="green"
@update:model-value="modifElem"
></CMySlider>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Filtri"
icon="fas fa-play-circle"
>
<div class="row">
<q-select
:behavior="
$q.platform.is.ios === true ? 'dialog' : 'menu'
"
v-if="
enableEdit &&
myel.catalogo &&
myel.catalogo.productTypes
"
rounded
outlined
v-model="recscheda.scheda.productTypes"
:options="shared_consts.VERSIONI_PRODOTTO"
@update:model-value="modifElem"
multiple
dense
label="Includi"
style="width: 150px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="
$q.platform.is.ios === true ? 'dialog' : 'menu'
"
v-if="
enableEdit &&
myel.catalogo &&
myel.catalogo.excludeproductTypes
"
rounded
outlined
v-model="recscheda.scheda.excludeproductTypes"
:options="shared_consts.VERSIONI_PRODOTTO"
@update:model-value="modifElem"
multiple
dense
label="Escludi"
style="width: 150px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="
$q.platform.is.ios === true ? 'dialog' : 'menu'
"
v-if="enableEdit"
rounded
outlined
v-model="recscheda.scheda.Editore"
:options="Products.publishers"
@update:model-value="modifElem"
multiple
dense
label="Editori"
style="width: 150px"
emit-value
map-options
option-value="_id"
option-label="name"
>
</q-select>
<q-select
label="Prodotti Speciali:"
v-model="recscheda.scheda.arrProdottiSpeciali"
emit-value
map-options
:options="[]"
use-chips
multiple
@update:model-value="
recscheda.scheda.arrProdottiSpeciali
"
filled
use-input
new-value-mode="add-unique"
dense
style="width: 350px"
/>
</div>
</q-expansion-item>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Dimensioni Schede"
icon="fas fa-play-circle"
>
<div class="row">
<CMySlider
label="Schede per Riga"
v-model="recscheda.scheda.numschede_perRiga"
:min="1"
:max="10"
color="green"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Schede per Colonna"
v-model="recscheda.scheda.numschede_perCol"
:min="1"
:max="10"
color="red"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza Schede:"
v-model="recscheda.scheda.widthscheda"
:min="10"
:max="1000"
color="green"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza Pagina:"
v-model="recscheda.scheda.widthpag"
:min="10"
:max="1000"
color="green"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza Immagini:"
v-model="recscheda.scheda.width"
:min="10"
:max="1000"
color="green"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Altezza Schede:"
v-model="recscheda.scheda.height"
:min="10"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
</div>
</q-expansion-item>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Testo"
icon="fas fa-play-circle"
>
<q-select
v-model="recscheda.scheda.posiz_text"
:options="posizTextOptions"
label="Posizione"
options-dense
dense
emit-value
map-options
style="width: 100px"
@update:model-value="modifElem"
fill-input
text-color="white"
>
</q-select>
<CMySlider
label="Line Height:"
v-model="recscheda.scheda.line_height"
:min="70"
:max="200"
color="blue"
@update:model-value="modifElem"
></CMySlider>
<CMyFieldRec
title="Testo:"
table="catalogo"
:rec="myel.catalogo"
field="recscheda.scheda.text"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.html"
@save="saveFieldElem"
@update_col="update_col"
>
</CMyFieldRec>
</q-expansion-item>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Margini Pagina"
icon="fas fa-play-circle"
>
<div class="sfondo_margine row">
<CMySlider
label="Margine Top"
v-model="recscheda.scheda.margine_top"
:min="0"
:max="1000"
color="blue"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Margine per Pagina"
v-model="recscheda.scheda.margine_pagina"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Margine per Riga"
v-model="recscheda.scheda.margine_riga"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
</div>
</q-expansion-item>
</div>
</q-tab-panel>
</q-tab-panels>
</div>
</q-expansion-item>
</div>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Sfondi"
icon="fas fa-play-circle"
>
Nome File Web: {{ myel.catalogo.backgroundimage }}<br />
<CMyFieldRec
title="Per Web:"
@@ -1479,59 +1810,183 @@
>
</CMyFieldRec>
<br />
<div class="sfondo_print">
Per Stampa:
<q-toggle
v-model="myel.catalogo.printable"
color="positive"
icon="fas fa-file-pdf"
label="Versione Stampabile"
@update:model-value="modifElem"
>
</q-toggle>
</q-expansion-item>
<q-input
dense
label="Margine per Pagina:"
@update:model-value="modifElem"
v-model="myel.catalogo.margine_paginaPrintable"
filled
v-on:keyup.enter="saveFieldElem"
>
</q-input>
<q-input
dense
label="Margine per Riga:"
@update:model-value="modifElem"
v-model="myel.catalogo.margine_rigaPrintable"
filled
v-on:keyup.enter="saveFieldElem"
>
</q-input>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Prima Pagina"
icon="fas fa-play-circle"
>
Prima Pagina: {{ myel.catalogo.first_page_img }}<br />
<div class="row">
<CMySlider
label="Larghezza Pagina Stampa:"
v-model="myel.catalogo.widthpagPrintable"
label="Altezza:"
v-model="myel.catalogo.first_page_height"
:min="0"
:max="1000"
:max="4000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
Nome File Printable: {{ myel.catalogo.backgroundimage_printable }}
<CMyFieldRec
title="Sfondo:"
table="catalogo"
:rec="myel.catalogo"
field="backgroundimage_printable"
<CMySlider
label="Larghezza:"
v-model="myel.catalogo.first_page_width"
:min="0"
:max="4000"
color="red"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.image"
@save="saveFieldElem"
>
</CMyFieldRec>
></CMySlider>
</div>
<CMyFieldRec
title="Per Web:"
table="catalogo"
:rec="myel.catalogo"
field="first_page_img"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.image"
@save="saveFieldElem"
>
</CMyFieldRec>
<CMyFieldRec
title="Testo pagina:"
table="catalogo"
:rec="myel.catalogo"
field="first_page_html"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.html"
@save="saveFieldElem"
@update_col="update_col"
>
</CMyFieldRec>
<br />
</q-expansion-item>
<q-expansion-item
dense
dense-toggle
expand-separator
label="Ultima Pagina"
icon="fas fa-play-circle"
>
Immagine: {{ myel.catalogo.last_page_img }}<br />
<div class="row">
<CMySlider
label="Altezza:"
v-model="myel.catalogo.last_page_height"
:min="0"
:max="4000"
color="red"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza:"
v-model="myel.catalogo.last_page_width"
:min="0"
:max="4000"
color="red"
@update:model-value="modifElem"
></CMySlider>
</div>
<CMyFieldRec
title="Per Web:"
table="catalogo"
:rec="myel.catalogo"
field="last_page_img"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.image"
@save="saveFieldElem"
>
</CMyFieldRec>
<CMyFieldRec
title="Testo pagina:"
table="catalogo"
:rec="myel.catalogo"
field="last_page_html"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.html"
@save="saveFieldElem"
@update_col="update_col"
>
</CMyFieldRec>
<br />
</q-expansion-item>
<div v-if="enableEdit">
<q-expansion-item
dense
dense-toggle
expand-separator
label="Per Stampa"
icon="fas fa-play-circle"
>
<div class="sfondo_print">
Per Stampa:
<q-toggle
v-model="myel.catalogo.printable"
color="positive"
icon="fas fa-file-pdf"
label="Versione Stampabile"
@update:model-value="modifElem"
>
</q-toggle>
<CMySlider
label="Margine per Pagina"
v-model="myel.catalogo.margine_paginaPrintable"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Margine per Riga"
v-model="myel.catalogo.margine_rigaPrintable"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
<CMySlider
label="Larghezza Pagina Stampa:"
v-model="myel.catalogo.widthpagPrintable"
:min="0"
:max="1000"
color="red"
addstr="px"
@update:model-value="modifElem"
></CMySlider>
Nome File Printable:
{{ myel.catalogo.backgroundimage_printable }}
<CMyFieldRec
title="Sfondo:"
table="catalogo"
:rec="myel.catalogo"
field="backgroundimage_printable"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.image"
@save="saveFieldElem"
>
</CMyFieldRec>
</div>
</q-expansion-item>
</div>
</div>
</q-list>

View File

@@ -50,12 +50,13 @@ export default defineComponent({
const myfonts = ref({
arial: 'Arial',
arial_black: 'Arial Black',
AGaramondProRegular: 'AGaramondPro-Regular',
comic_sans: 'Comic Sans MS',
courier_new: 'Courier New',
impact: 'Impact',
lucida_grande: 'Lucida Grande',
times_new_roman: 'Times New Roman',
verdana: 'Verdana'
verdana: 'Verdana',
})
const showtools = ref(false)

View File

@@ -469,7 +469,6 @@ body.mobile .landing:before {
.elemEdit{
margin: 3px;
padding: 3px;
background-color: #3fdaff;
text-align: center;
font-weight: bold;
}

File diff suppressed because it is too large Load Diff

View File

@@ -173,7 +173,7 @@ export default defineComponent({
if (arrk.length > 2)
mysubsubkey.value = arrk[2]
}
console.log('### table', props.table, 'col.value', col.value, 'field', props.field, 'mykey', mykey.value, 'mysubkey', mysubkey.value)
// console.log('### table', props.table, 'col.value', col.value, 'field', props.field, 'mykey', mykey.value, 'mysubkey', mysubkey.value)
}
@@ -235,6 +235,11 @@ export default defineComponent({
}
}
function update_col(name: string, val: any) {
// console.log('update_col', name, val)
myrec.value[name] = val
}
onMounted(mounted)
return {
@@ -257,6 +262,7 @@ export default defineComponent({
visuElem,
getclass,
myrec,
update_col,
}
},
})

View File

@@ -67,6 +67,7 @@
:path="path"
:nosaveToDb="nosaveToDb"
@showandsave="showandsave"
@update_col="update_col"
>
</CMyPopupEdit>
</div>

View File

@@ -32,6 +32,11 @@ export default defineComponent({
type: String,
required: true,
},
myidPage: {
type: String,
required: false,
default: ''
},
img: {
type: String,
required: false,
@@ -62,6 +67,7 @@ export default defineComponent({
setup(props) {
const rec = ref<IMyPage | null>(null)
const mypathin = toRef(props, 'mypath')
const myidPage = toRef(props, 'idPage')
const $q = useQuasar()
@@ -91,7 +97,9 @@ export default defineComponent({
const onloading = ref(false)
const myelems = computed(() => {
if (mypathin.value)
if (myidPage.value)
return globalStore.getMyElemsByIdPage(myidPage.value)
else if (mypathin.value)
return globalStore.getMyElems(mypathin.value)
else
return null
@@ -159,6 +167,10 @@ export default defineComponent({
}
async function duplicatePage() {
await globalStore.duplicatePage(mypathin.value, $q, t)
}
onMounted(mounted)
@@ -179,6 +191,7 @@ export default defineComponent({
toggleSize,
onloading,
deleteElem,
duplicatePage,
}
},

View File

@@ -41,9 +41,11 @@
:myelem="selElem"
:editOn="true"
:path="rec.path"
:IdPath="rec._id"
@selElemClick="selElemClick"
@deleteElem="deleteElem"
@toggleSize="toggleSize"
@dupPage="duplicatePage"
>
</CMyEditElem>
</q-drawer>

View File

@@ -28,6 +28,11 @@ export default defineComponent({
type: String,
required: true,
},
myidPage: {
type: String,
required: false,
default: ''
},
img: {
type: String,
required: false,
@@ -74,7 +79,9 @@ export default defineComponent({
const editOn = computed(() => globalStore.editOn)
const myelems = computed(() => {
if (mypathin.value)
if (myidPage.value)
return globalStore.getMyElemsByIdPage(myidPage.value)
else if (mypathin.value)
return globalStore.getMyElems(mypathin.value)
else
return null

View File

@@ -411,7 +411,6 @@ export default defineComponent({
}
function changevalRecOrig(newval: any, subcol: string = '') {
// console.log('changevalRec', newval)
// if (!props.insertMode || (props.insertMode && col.value.fieldtype !== costanti.FieldType.multioption)) {
if (col.value && col.value.allowchar === costanti.ALLOWCHAR_CODE) {
newval = tools.removespaces_slash(newval)

View File

@@ -1,5 +1,5 @@
<template>
<div class="q-pa-xs" style="width: 300px">
<div class="q-pa-xs" style="width: 180px">
<q-badge color="primary"> {{ label }} {{ modelValue }} </q-badge>
<q-input

View File

@@ -19,13 +19,13 @@
.prod_off_price {
font-size: 1rem;
@media (max-width: 718px) {
font-size: 0.85rem;
}
color: gray;
text-decoration: line-through;
padding-left: 8px;
@media (max-width: 718px) {
font-size: 0.85rem;
}
}
/* ******** */

View File

@@ -1,5 +1,5 @@
<template>
<div class="row items-start q-gutter-sm">
<div class="row">
<q-spinner v-if="!endload" color="primary" size="3em" :thickness="2" />
<q-card
:class="{
@@ -30,7 +30,10 @@
<q-img
:src="
myproduct.productInfo.imagefile
? tools.getFullFileNameByImageFile('productInfos', myproduct.productInfo.imagefile)
? tools.getFullFileNameByImageFile(
'productInfos',
myproduct.productInfo.imagefile
)
: myproduct.productInfo.image_link
"
:alt="myproduct.productInfo.name"
@@ -45,11 +48,15 @@
color="primary"
round
icon="fas fa-eye"
class="absolute semi-transparent"
size="md"
@click="toggleFullScreen"
style="bottom: -10px; right: 0px; transform: translateY(-50%); z-index: 2"
style="
bottom: -10px;
right: 0px;
transform: translateY(-50%);
z-index: 2;
"
/>
</div>
@@ -226,7 +233,7 @@
<div v-if="false" class="barcode">
<barcode :value="myproduct.productInfo.code" format="EAN-13">
</barcode>
<vue-barcode ></vue-barcode>
<vue-barcode></vue-barcode>
</div>
<div
v-if="
@@ -375,7 +382,8 @@
<q-card-section
v-if="
editOn &&
(!!myproduct.productInfo.imagefile || myproduct.productInfo.imagefile === '')
(!!myproduct.productInfo.imagefile ||
myproduct.productInfo.imagefile === '')
"
>
<div class="text-center">
@@ -921,11 +929,13 @@
class="listaev__table"
>
<thead>
<th>Data</th>
<th>Persona</th>
<th>Stato</th>
<th>Quantita</th>
<th>Note</th>
<tr>
<th>Data</th>
<th>Persona</th>
<th>Stato</th>
<th>Quantita</th>
<th>Note</th>
</tr>
</thead>
<tbody>
@@ -1072,7 +1082,10 @@
<q-img
:src="
myproduct.productInfo.imagefile
? tools.getFullFileNameByImageFile('productInfos', myproduct.productInfo.imagefile)
? tools.getFullFileNameByImageFile(
'productInfos',
myproduct.productInfo.imagefile
)
: myproduct.productInfo.image_link
"
:alt="myproduct.productInfo.name"

View File

@@ -1,3 +1,12 @@
@use "sass:color";
@font-face {
font-family: 'AGaramondPro-Regular';
src: url('~src/assets/fonts/AGaramondPro-Regular.otf') format('opentype');
font-weight: normal;
font-style: normal;
}
body {
font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
-webkit-font-smoothing: antialiased;
@@ -977,11 +986,6 @@ h3 {
margin-right: auto;
min-width: 800px;
@media (max-width: 1024px) {
max-width: 1024px;
min-width: 300px;
}
padding-bottom: 20px;
margin-top: 1rem;
margin-bottom: 1rem;
@@ -989,6 +993,10 @@ h3 {
// transition: transform .2s ease-out;
@media (max-width: 1024px) {
max-width: 1024px;
min-width: 300px;
}
}
.my-card-shadow:hover {
@@ -1844,17 +1852,17 @@ h3 {
.buttons_bottom {
max-width: 700px !important;
@media (max-width: 700px) {
/* Versione Mobile */
max-width: 400px;
}
margin-left: auto;
justify-content: space-around;
margin-right: auto;
text-align: center;
padding-top: 8px;
padding-bottom: 8px;
@media (max-width: 700px) {
/* Versione Mobile */
max-width: 400px;
}
}
.body--light {
@@ -1888,9 +1896,6 @@ h3 {
}
.visudialog {
@media (max-width: 600px) {
/* ... */
}
else {
width: 700px !important;
@@ -2004,13 +2009,12 @@ h3 {
}
.fake-link {
font-weight: bold;
@media (max-width: 600px) {
color: #1976D2;
text-decoration: underline !important;
cursor: pointer;
}
font-weight: bold;
}
.fake-link:hover {
@@ -2199,9 +2203,23 @@ $coloreprincipale: lightblue;
}
.sfondo_gradiente_rosso {
background: linear-gradient(180deg, rgba(red($rosso), green($rosso), blue($rosso), $trasparenza), $coloreprincipale, rgba(red($rosso), green($rosso), blue($rosso), $trasparenza)) !important;
background: linear-gradient(
180deg,
rgba(
color.channel($rosso, "red", $space: rgb),
color.channel($rosso, "green", $space: rgb),
color.channel($rosso, "blue", $space: rgb),
$trasparenza
),
$coloreprincipale,
rgba(
color.channel($rosso, "red", $space: rgb),
color.channel($rosso, "green", $space: rgb),
color.channel($rosso, "blue", $space: rgb),
$trasparenza
)
) !important;
}
.card-carousel-container {
width: 100%;
overflow: hidden;
@@ -2249,9 +2267,9 @@ $coloreprincipale: lightblue;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
gap: 1rem;
gap: 0.5rem;
height: 100%;
padding: 1rem;
padding: 0.5rem;
}
.flex-card {
@@ -2461,7 +2479,7 @@ body.body--dark {
display: flex; /* Rende il div un container flex per allineare i contenuti */
justify-content: center; /* Allineamento orizzontale al centro */
align-items: center; /* Allineamento verticale al centro */
padding: 10px;
padding: 0px;
flex-grow: 1; /* Opzionale: permette agli elementi di crescere uniformemente */
break-inside: avoid;
@@ -2475,7 +2493,7 @@ body.body--dark {
.card-row {
display: flex;
justify-content: flex-start;
justify-content: center;
}
.cards-container {

View File

@@ -1,9 +1,9 @@
const msg_website_it = {
ws: {
sitename: 'Riso',
siteshortname: 'RISO',
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.',
keywords: 'riso, piattaforma di scambio, rete italiana scambio orizzontale, riso app, riso piattaforma, scambio e baratto, momenta RIS',
sitename: 'Gruppo Macro',
siteshortname: 'Gruppo Macro',
description: '',
keywords: '',
},
hours: {
descr: 'Descrizione',
@@ -16,23 +16,35 @@ const msg_website_it = {
pages: {
home: 'Home',
profile: 'Profilo',
install_site: 'Installa Sito',
profile2: 'ProfiloU',
mypage2: 'mypage2',
myservice2: 'myservice2',
myhosps2: 'myhosps2',
mygood2: 'mygood2',
catalogo: 'Catalogo',
fundraising: 'Sostieni il Progetto',
notifs: 'Configura le Notifiche',
unsubscribe: 'Disiscriviti',
unsubscribe_user: 'Disiscriviti User',
test: 'Test',
projects: 'Progetti',
report: 'Report Ore',
producer: 'Produttore',
orderinfo: 'Ordini Effettuati',
products: 'Prodotti',
cash: 'Cassa',
productInfos: 'Info Prodotti',
listinoprodotti: 'Listino Prodotti',
productslist: 'Lista Prodotti',
collabora: 'Collabora',
categories: 'Categorie',
storehouses: 'Magazzino',
providers: 'Fornitori',
catprods: 'Categorie',
subcatprods: 'Sotto-Categorie',
gasordine: 'Gas Ordine',
scontisticas: 'Scontistica',
departments: 'Uffici',
orders: 'Ordini Ricevuti',
orders2: 'Ordini Ricevuti',
@@ -121,15 +133,11 @@ const msg_website_it = {
only_residenti: 'Solo Residenti',
only_consiglio: 'Solo Consiglieri',
color: 'Colore',
mainMenu: 'Menu Principale',
subtitle: 'Sottotitolo',
lang: 'Lingua',
keywords: 'Parole Chiave',
desctiption: 'Descrizione',
heightimg: 'Altezza Immagine',
gasordini: 'Gas Ordini',
gestoreordini: 'Gestore Ordini',
},
msg: {
myAppName: 'Riso',
myAppName: 'Più che Buono',
myAppDescription: 'Il primo Vero Social Libero, Equo e Solidale, dove Vive Consapevolezza e Aiuto Comunitario. Gratuito',
underconstruction: 'App in costruzione...',
myDescriz: '',

View File

@@ -67,39 +67,6 @@ function getDynamicPages(site: ISites): IListRoutes[] {
inmenu: false,
infooter: false,
},
{
active: true,
order: 12,
path: '/goods',
materialIcon: 'fas fa-tshirt',
name: 'mypages.goods',
component: () => import('@/root/goods/goods.vue'),
meta: { requiresAuth: true },
inmenu: true,
infooter: true,
},
{
active: true,
order: 15,
path: '/services',
materialIcon: 'fas fa-house-user',
name: 'mypages.services',
component: () => import('@/root/services/services.vue'),
meta: { requiresAuth: true },
inmenu: true,
infooter: true,
},
{
active: true,
order: 15,
path: '/activities',
materialIcon: 'fas fa-house-user',
name: 'mypages.activities',
component: () => import('@/root/activities/activities.vue'),
meta: { requiresAuth: true },
inmenu: false,
infooter: false,
},
{
active: true,
order: 15,
@@ -111,17 +78,6 @@ function getDynamicPages(site: ISites): IListRoutes[] {
inmenu: false,
infooter: false,
},
{
active: true,
order: 15,
path: '/hosps',
materialIcon: 'fas fa-bed',
name: 'mypages.hosp',
component: () => import('@/root/hosp/hosp.vue'),
meta: { requiresAuth: true },
inmenu: true,
infooter: true,
},
{
active: site.confpages && site.confpages.enableCircuits,
order: 16,
@@ -209,7 +165,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
meta: { requiresAuth: true, newpage: true },
inmenu: false,
infooter: false,
},
},
{
active: true,
order: 137,
@@ -276,7 +232,7 @@ function getDynamicPages(site: ISites): IListRoutes[] {
{
active: true,
order: 150,
path: '/sostieniilprogetto',
path: '/fundraising',
materialIcon: 'fas fa-hand-holding-heart',
name: 'pages.fundraising',
component: () => import('@src/root/fundraising/fundraising.vue'),

View File

@@ -10,7 +10,7 @@
<meta name="description" content="<%= productDescription %>">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="version" content="1.1.6">
<meta name="version" content="1.1.7">
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">

View File

@@ -1,7 +1,8 @@
import { IAction } from '@src/model/Projects'
import { IFriends, IGroupShort, IMyGroup, IPaymentType } from '@src/model/UserStore'
import {
IDepartment, IQueryAI, IProducer, IShareWithUs, IStorehouse, IProductInfo, IProvider, IScontistica, ICategory, IGasordine, ICatProd, ISubCatProd, ICatAI
IDepartment, IQueryAI, IProducer, IShareWithUs, IStorehouse, IProductInfo, IProvider, IScontistica, ICategory, IGasordine, ICatProd, ISubCatProd, ICatAI,
IProduct
} from '@src/model/Products'
import { IUserFields, IUserProfile } from '@src/model/UserStore'
@@ -126,6 +127,7 @@ export interface IMyElem {
_id?: string
type?: number
path?: string
idPage?: string
img?: string
container?: string
container2?: string
@@ -417,6 +419,14 @@ export interface ITestp1 {
export type StateConnection = 'online' | 'offline'
export interface IFilterCatalogo {
author: string
sort: number
publisher: string
type: string
ageGroup: string
}
export interface IConfig {
_id: string,
key?: string,
@@ -474,6 +484,7 @@ export interface IGlobalState {
gallery: IGallery[],
mypage: IMyPage[],
myelems: IMyElem[],
myschedas: IMyScheda[],
templemail: ITemplEmail[],
opzemail: ISettings[],
mailinglist: IMailinglist[],
@@ -673,6 +684,42 @@ export interface IMyCard {
link?: string
}
export interface IMyScheda {
_id: string,
idapp: string,
isTemplate: boolean,
name: string,
widthscheda?: string
line_height?: number
widthpag?: number
width?: number
height?: number
numschede_perRiga?: number
numschede_perCol?: number
margine_top?: number
margine_pagina?: string
margine_riga?: string
text?: string
posiz_text?: number
productTypes?: number[]
excludeproductTypes?: number[]
editore?: string[]
author?: string
sort?: number
arrProdottiSpeciali?: string[]
// In Memoria:
arrProdToShow?: IProduct[][]
}
export interface ISchedaSingola {
_id?: string
scheda?: IMyScheda,
order?: number,
numSchede?: number,
}
export interface ICatalogo {
//++AddCATALOGO_FIELDS
productTypes: number[]
@@ -685,16 +732,22 @@ export interface ICatalogo {
backgroundimage_printable?: string
widthpag?: number
widthpagPrintable?: number
widthscheda?: string
width?: string
height?: string
printable?: boolean
numschede_perCol?: number
numschede_perRiga?: number
margine_pagina?: string
margine_riga?: string
margine_paginaPrintable?: string
margine_rigaPrintable?: string
first_page_img?: string
first_page_html?: string
first_page_height?: number
first_page_width?: number
last_page_img?: string
last_page_html?: string
last_page_height?: number
last_page_width?: number
arrSchede?: ISchedaSingola[]
}

View File

@@ -41,6 +41,7 @@ export interface IProductInfo {
numpages?: number
productTypes?: number[]
versioneGM?: string
short_descr: string
}
export interface IVariazione {
@@ -68,6 +69,11 @@ export interface IAuthor {
img?: string
}
export interface IProdView {
id: string
showed: boolean
}
export interface IProduct {
_id?: any
active?: boolean

View File

@@ -13,6 +13,8 @@ import { shared_consts } from '@/common/shared_vuejs'
import { IMyPage } from 'model'
import { useGlobalStore } from '@store/globalStore'
import objectId from '@src/js/objectId'
export default defineComponent({
name: 'editElems',
setup() {
@@ -29,26 +31,26 @@ export default defineComponent({
tools.setCookie('s_elems', newval)
})
const filtercustom = computed(() => [{ path: pageSel.value }] )
const filtercustom = computed(() => [{ idPage: pageSel.value }])
function mounted() {
arrPages.value = []
arrPages.value.push({label: '[Vuoto]', path: ''})
arrPages.value.push({ label: '[Vuoto]', path: '' })
for (const page of globalStore.mypage) {
const rec = {
// @ts-ignore
label: page.title,
// @ts-ignore
value: page.path
value: page._id
}
arrPages.value.push(rec)
}
// filtercustom.value = [{ userId: userStore.my._id }]
// filtercustom.value = [{ userId: userStore.my._id }]
}
onMounted(mounted)

View File

@@ -1,11 +1,17 @@
<template>
<CMyPage
:title="gettitle()" keywords="" description="" imgbackground="images/calendario_eventi.jpg"
sizes="max-height: 120px">
:title="gettitle()"
keywords=""
description=""
imgbackground="images/calendario_eventi.jpg"
sizes="max-height: 120px"
>
<div class="q-ma-sm q-pa-xs">
<div v-if="!showall()" class="text-h6 bg-red text-white text-center q-pa-xs shadow-max">Lista delle tue
prenotazioni agli Eventi:
<div
v-if="!showall()"
class="text-h6 bg-red text-white text-center q-pa-xs shadow-max"
>
Lista delle tue prenotazioni agli Eventi:
</div>
<q-space></q-space>
@@ -15,109 +21,163 @@
</div>
<div>
<q-markup-table wrap-cells bordered separator="horizontal" class="listaev__table">
<q-markup-table
wrap-cells
bordered
separator="horizontal"
class="listaev__table"
>
<thead>
<th>{{ $t('cal.data') }}</th>
<th>{{ $t('cal.event') }}</th>
<th v-if="!tools.isMobile()">{{ $t('cal.teachertitle') }}</th>
<th v-if="showall()">
<span v-if="!tools.isMobile()">{{ $t('cal.selnumpeople') }}</span>
<span v-else>{{ $t('cal.selnumpeople_short') }}</span>
</th>
<th v-if="showall()">
{{ $t('cal.selnumpeopleLunch') }}
</th>
<th v-if="showall()">
{{ $t('cal.selnumpeopleDinner') }}
</th>
<th v-if="showall()">
{{ $t('cal.selnumpeopleDinnerShared') }}
</th>
<th>{{ $t('cal.peoplebooked') }}</th>
<tr>
<th>{{ $t('cal.data') }}</th>
<th>{{ $t('cal.event') }}</th>
<th v-if="!tools.isMobile()">{{ $t('cal.teachertitle') }}</th>
<th v-if="showall()">
<span v-if="!tools.isMobile()">{{ $t('cal.selnumpeople') }}</span>
<span v-else>{{ $t('cal.selnumpeople_short') }}</span>
</th>
<th v-if="showall()">
{{ $t('cal.selnumpeopleLunch') }}
</th>
<th v-if="showall()">
{{ $t('cal.selnumpeopleDinner') }}
</th>
<th v-if="showall()">
{{ $t('cal.selnumpeopleDinnerShared') }}
</th>
<th>{{ $t('cal.peoplebooked') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(event, index) in getEventList()" :key="index" class="listaev listaev__table">
<td>
<div class="text-center text-blue">{{ func_tools.getDateStr(event.dateTimeStart) }}</div>
</td>
<td>
<div class="text-center boldhigh">{{ event.title }}</div>
</td>
<td v-if="!tools.isMobile()">
<div class="text-center">{{ getTeacherByUsername(event.teacher) }}
<span v-if="isValidUsername(event.teacher2)"> - {{ getTeacherByUsername(event.teacher2) }}</span>
<span v-if="isValidUsername(event.teacher3)"> - {{ getTeacherByUsername(event.teacher3) }}</span>
<span v-if="isValidUsername(event.teacher4)"> - {{ getTeacherByUsername(event.teacher4) }}</span>
</div>
</td>
<td v-if="showall()">
<div class="text-center">{{
calendarStore.getNumParticipants(event, showall, tools.peopleWhere.participants)
}}
</div>
</td>
<td v-if="showall()">
<div class="text-center">{{
calendarStore.getNumParticipants(event, showall, tools.peopleWhere.lunch)
}}
</div>
</td>
<td v-if="showall()">
<div class="text-center">{{
calendarStore.getNumParticipants(event, showall, tools.peopleWhere.dinner)
}}
</div>
</td>
<td v-if="showall()">
<div class="text-center">{{
calendarStore.getNumParticipants(event, showall, tools.peopleWhere.dinnerShared)
}}
</div>
</td>
<tr
v-for="(event, index) in getEventList()"
:key="index"
class="listaev listaev__table"
>
<td>
<div class="text-center text-blue">
{{ func_tools.getDateStr(event.dateTimeStart) }}
</div>
</td>
<td>
<div class="text-center boldhigh">{{ event.title }}</div>
</td>
<td v-if="!tools.isMobile()">
<div class="text-center">
{{ getTeacherByUsername(event.teacher) }}
<span v-if="isValidUsername(event.teacher2)">
- {{ getTeacherByUsername(event.teacher2) }}</span
>
<span v-if="isValidUsername(event.teacher3)">
- {{ getTeacherByUsername(event.teacher3) }}</span
>
<span v-if="isValidUsername(event.teacher4)">
- {{ getTeacherByUsername(event.teacher4) }}</span
>
</div>
</td>
<td v-if="showall()">
<div class="text-center">
{{
calendarStore.getNumParticipants(
event,
showall,
tools.peopleWhere.participants
)
}}
</div>
</td>
<td v-if="showall()">
<div class="text-center">
{{
calendarStore.getNumParticipants(
event,
showall,
tools.peopleWhere.lunch
)
}}
</div>
</td>
<td v-if="showall()">
<div class="text-center">
{{
calendarStore.getNumParticipants(
event,
showall,
tools.peopleWhere.dinner
)
}}
</div>
</td>
<td v-if="showall()">
<div class="text-center">
{{
calendarStore.getNumParticipants(
event,
showall,
tools.peopleWhere.dinnerShared
)
}}
</div>
</td>
<td class="text-center">
<q-btn
v-if="calendarStore.getNumParticipants(event, showall, tools.peopleWhere.participants) > 0"
flat
dense
color="positive"
rounded
icon="fas fa-user-check"
@click="showpeople = true; eventsel = event"
>
</q-btn>
<q-btn
dense
flat
rounded
:color="!!event.note ? 'positive' : 'dark'"
icon="fas fa-pencil-alt"
@click="shownote = true; eventsel = event"
>
</q-btn>
</td>
</tr>
<td class="text-center">
<q-btn
v-if="
calendarStore.getNumParticipants(
event,
showall,
tools.peopleWhere.participants
) > 0
"
flat
dense
color="positive"
rounded
icon="fas fa-user-check"
@click="
showpeople = true;
eventsel = event;
"
>
</q-btn>
<q-btn
dense
flat
rounded
:color="!!event.note ? 'positive' : 'dark'"
icon="fas fa-pencil-alt"
@click="
shownote = true;
eventsel = event;
"
>
</q-btn>
</td>
</tr>
</tbody>
</q-markup-table>
<q-dialog v-model="shownote">
<q-card v-if="eventsel" class="dialog_card">
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
Note: {{ eventsel.title }}
</q-toolbar-title>
<q-toolbar-title> Note: {{ eventsel.title }} </q-toolbar-title>
<q-btn flat round color="white" icon="close" v-close-popup></q-btn>
</q-toolbar>
<q-card-section class="q-pa-xs inset-shadow">
<q-input
v-model="eventsel.note" style="min-height: 50px; " label="Note:"
filled dense
v-model="eventsel.note"
style="min-height: 50px"
label="Note:"
filled
dense
autogrow
type="textarea" debounce="500"
type="textarea"
debounce="500"
input-class="myinput-area"
@update:model-value="change_rec(eventsel)">
@update:model-value="change_rec(eventsel)"
>
</q-input>
</q-card-section>
</q-card>
</q-dialog>
@@ -130,40 +190,78 @@
<q-btn flat round color="white" icon="close" v-close-popup></q-btn>
</q-toolbar>
<q-card-section class="q-pa-xs inset-shadow">
<q-markup-table wrap-cells bordered separator="horizontal" class="listaev__table">
<q-markup-table
wrap-cells
bordered
separator="horizontal"
class="listaev__table"
>
<thead>
<th>Data</th>
<th>Messaggio</th>
<th>Partec</th>
<th>Azione</th>
<tr>
<th>Data</th>
<th>Messaggio</th>
<th>Partec</th>
<th>Azione</th>
</tr>
</thead>
<tbody>
<tr
v-for="(eventbook, index) in calendarStore.getEventsBookedByIdEvent(eventsel._id, showall)"
:key="index"
class="listaev listaev__table">
<td class="text-center">
<div>{{ func_tools.getDateTimeShortStr(eventbook.datebooked) }}
</div>
</td>
<td class="text-center">
<strong>{{ userStore.getNameSurnameByUserId(eventbook.userId) }}</strong> <span
v-if="eventbook.msgbooking"> {{ $t('sendmsg.write') }}: </span><br>
{{ eventbook.msgbooking }}
</td>
<td class="text-center">
<span v-if="eventbook.numpeople > 0">Partecipanti: {{ eventbook.numpeople }}<br></span>
<span v-if="eventbook.numpeopleLunch > 0">Pranzo: {{ eventbook.numpeopleLunch }}<br></span>
<span v-if="eventbook.numpeopleDinner > 0">Cena: {{ eventbook.numpeopleDinner }}<br></span>
<span v-if="eventbook.numpeopleDinnerShared > 0">Cena Condivisa: {{ eventbook.numpeopleDinnerShared }}<br></span>
</td>
<td class="text-center">
<q-btn
flat round color="red" icon="fas fa-trash-alt" size="sm"
@click="tools.CancelBookingEvent($q, eventsel, eventbook._id, false)"></q-btn>
</td>
</tr>
<tr
v-for="(
eventbook, index
) in calendarStore.getEventsBookedByIdEvent(
eventsel._id,
showall
)"
:key="index"
class="listaev listaev__table"
>
<td class="text-center">
<div>
{{ func_tools.getDateTimeShortStr(eventbook.datebooked) }}
</div>
</td>
<td class="text-center">
<strong>{{
userStore.getNameSurnameByUserId(eventbook.userId)
}}</strong>
<span v-if="eventbook.msgbooking">
{{ $t('sendmsg.write') }}: </span
><br />
{{ eventbook.msgbooking }}
</td>
<td class="text-center">
<span v-if="eventbook.numpeople > 0"
>Partecipanti: {{ eventbook.numpeople }}<br
/></span>
<span v-if="eventbook.numpeopleLunch > 0"
>Pranzo: {{ eventbook.numpeopleLunch }}<br
/></span>
<span v-if="eventbook.numpeopleDinner > 0"
>Cena: {{ eventbook.numpeopleDinner }}<br
/></span>
<span v-if="eventbook.numpeopleDinnerShared > 0"
>Cena Condivisa: {{ eventbook.numpeopleDinnerShared }}<br
/></span>
</td>
<td class="text-center">
<q-btn
flat
round
color="red"
icon="fas fa-trash-alt"
size="sm"
@click="
tools.CancelBookingEvent(
$q,
eventsel,
eventbook._id,
false
)
"
></q-btn>
</td>
</tr>
</tbody>
</q-markup-table>
</q-card-section>
@@ -176,10 +274,9 @@
<div v-else class="text-blue text-center q-pa-xs shadow">
Non hai nessuna Prenotazione passata.
</div>
</div>
<br>
<br />
</div>
</CMyPage>
</template>

View File

@@ -1234,6 +1234,8 @@ const msg_it = {
circuits: 'Circuiti',
find_circuit: 'Cerca Circuiti',
follow_circuits: 'I tuoi Circuiti RIS',
duplicateok: 'Pagina Duplicata con successo',
duplicateerr: 'Errore nel duplicare la pagina',
},
friends: {
accept_trust: 'Accetta',

View File

@@ -109,7 +109,7 @@ export const Api = {
// Reset the refresh token if it was reset by the server
if (response.data.refreshToken) {
// console.log('salva refreshtoken', response.data.refreshToken)
userStore.setRefreshToken(response.data.refreshToken)
userStore.setRefreshToken(response.data.refreshToken)
}
// Return the new access token
@@ -131,27 +131,22 @@ export const Api = {
},
async SendReq(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false): Promise<Types.AxiosSuccess | Types.AxiosError> {
async SendReqBase(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false): Promise<Types.AxiosSuccess | Types.AxiosError> {
const mydataout = {
...mydata,
keyappid: process.env.PAO_APP_ID,
idapp: process.env.APP_ID,
}
// console.log('INIZIO - SendReq', url)
// console.log('mydata', mydata)
const userStore = useUserStore()
const globalStore = useGlobalStore()
const $router = useRouter()
userStore.setServerCode(tools.EMPTY)
userStore.setResStatus(0)
// eslint-disable-next-line @typescript-eslint/no-misused-promises
return new Promise((resolve, reject) => sendRequest(url, method, mydataout)
.then((res) => {
// console.log('status:', res.status)
setTimeout(() => {
if (method === 'get') {
globalStore.connData.downloading_server = 0
@@ -164,11 +159,8 @@ export const Api = {
if (res.status) {
userStore.setResStatus(res.status)
if (res.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) {
// Forbidden
// You probably is connectiong with other page...
userStore.setServerCode(toolsext.ERR_AUTHENTICATION)
userStore.setAuth('', '')
// $router.push('/signin')
return reject({ code: toolsext.ERR_AUTHENTICATION })
}
}
@@ -187,41 +179,92 @@ export const Api = {
}, 1000)
if (error.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_TOKEN_EXPIRED) {
// console.log('Token Expired')
// Prova ad ottenere un nuovo token di accesso
try {
// Se il token è scaduto, allora faccio la richiesta di un NUOVO TOKEN, passandogli refreshToken
const newAccessToken = await this.refreshToken();
if (newAccessToken) {
userStore.setAuth(newAccessToken, userStore.refreshToken);
// Riprova l'originale SendReq con il nuovo token.
// Assicurati di evitare un loop infinito in caso di errori continui
if (!evitaloop)
return resolve(this.SendReq(url, method, mydata, setAuthToken, true));
} else {
$router.push('/signin')
}
} catch (err2: any) {
// Gestisci errore di refresh token (es. redirect a signin)
console.error('err2', err2)
if (err2 && err2.hasOwnProperty('code') && err2.code === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) {
// Forbidden
// You probably is connectiong with other page...
if (err2?.code === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) {
userStore.setServerCode(toolsext.ERR_AUTHENTICATION)
userStore.setAuth('', '')
return reject({ code: toolsext.ERR_AUTHENTICATION })
}
// return reject(err2);
}
}
console.log('ERROR', error)
return reject(error)
}))
},
/**
* Creates a Promise that resolves after a specified number of milliseconds.
* Useful for creating delayed operations or pause in async functions.
*
* @param ms - The number of milliseconds to delay
* @returns A Promise that resolves after the specified delay
*
* @example
* // Basic usage
* await delay(1000); // waits for 1 second
*
* @example
* // Usage in an async function
* async function example() {
* console.log('Start');
* await delay(2000);
* console.log('2 seconds later');
* }
*
* @example
* // Usage with Promise chaining
* delay(1000).then(() => console.log('1 second passed'));
*/
async delay (ms: number): Promise<void> {
// Input validation
if (ms < 0) {
throw new Error('Delay time cannot be negative');
}
return new Promise(resolve => setTimeout(resolve, ms));
},
async SendReq(
url: string,
method: string,
mydata: any,
setAuthToken = false,
evitaloop = false,
retryCount = 5,
retryDelay = 3000
): Promise<Types.AxiosSuccess | Types.AxiosError> {
try {
const response = await this.SendReqBase(url, method, mydata, setAuthToken, evitaloop);
return response;
} catch (error) {
if (retryCount > 0) {
console.log(`❌❌❌ Retrying request. Attempts remaining: ${retryCount}`);
await this.delay(retryDelay);
return this.SendReq(
url,
method,
mydata,
setAuthToken,
evitaloop,
retryCount - 1,
retryDelay
);
}
throw error;
}
},
async syncAlternative(mystrparam: string) {
console.log('[ALTERNATIVE Background syncing', mystrparam)

View File

@@ -19,6 +19,11 @@ export const costanti = {
CERCO: 2,
},
POSIZ_TESTO: {
IN_BASSO: 0,
A_DESTRA: 1,
},
CATALOGO_FIELDS: [
'productTypes',
'excludeproductTypes',
@@ -40,6 +45,13 @@ export const costanti = {
'margine_riga',
'margine_paginaPrintable',
'margine_rigaPrintable',
'first_page_img',
'first_page_html',
'first_page_height',
'last_page_img?',
'last_page_html',
'last_page_height',
'text',
],
TIPOFAVBOOK: {

View File

@@ -147,6 +147,30 @@ export const colmylistcards = [
AddCol({ name: 'link', label_trans: 'link' }),
]
export const colmyScheda = [
AddCol({ name: 'name', label_trans: 'scheda.name', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'isTemplate', label_trans: 'scheda.isTemplate', fieldtype: costanti.FieldType.boolean }),
AddCol({ name: 'widthscheda', label_trans: 'scheda.widthscheda', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'widthpag', label_trans: 'scheda.widthpag', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'width', label_trans: 'scheda.width', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'height', label_trans: 'scheda.height', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'numschede_perCol', label_trans: 'scheda,numschede_perCol', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'numschede_perRiga', label_trans: 'scheda.numschede_perRiga', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'margine_top', label_trans: 'scheda.margine_top', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'margine_pagina', label_trans: 'scheda.margine_pagina', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'margine_riga', label_trans: 'scheda.margine_riga', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'text', label_trans: 'catalogo.text', fieldtype: costanti.FieldType.html }),
AddCol({ name: 'posiz_text', label_trans: 'catalogo.posiz_text', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'line_height', label_trans: 'catalogo.line_height', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'productTypes', label_trans: 'productTypes', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'excludeproductTypes', label_trans: 'excludeproductTypes', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'Editore', label_trans: 'Editore' }),
AddCol({ name: 'author', label_trans: 'author' }),
AddCol({ name: 'sort', label_trans: 'catalogo.sort', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'arrProdottiSpeciali', label_trans: 'Editore' }),
]
export const colmyelCatalogo = [
AddCol({ name: 'productTypes', label_trans: 'productTypes', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'excludeproductTypes', label_trans: 'excludeproductTypes', fieldtype: costanti.FieldType.number }),
@@ -154,22 +178,25 @@ export const colmyelCatalogo = [
AddCol({ name: 'Editore', label_trans: 'Editore' }),
AddCol({ name: 'backgroundimage', label_trans: 'backgroundimage', fieldtype: costanti.FieldType.image }),
AddCol({ name: 'backgroundimage_printable', label_trans: 'backgroundimage_printable', fieldtype: costanti.FieldType.image }),
AddCol({ name: 'widthscheda', label_trans: 'widthscheda', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'widthpag', label_trans: 'widthpag', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'widthpagPrintable', label_trans: 'widthpagPrintable', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'width', label_trans: 'width', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'height', label_trans: 'height', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'numschede_perCol', label_trans: 'numschede_perCol', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'numschede_perRiga', label_trans: 'numschede_perRiga', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'margine_pagina', label_trans: 'margine_pagina', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'margine_riga', label_trans: 'margine_riga', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'optcatalogo.', label_trans: 'catalogo.optcatalogo.', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'margine_paginaPrintable', label_trans: 'margine_paginaPrintable', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'margine_rigaPrintable', label_trans: 'margine_rigaPrintable', fieldtype: costanti.FieldType.string }),
AddCol({ name: 'first_page_img', label_trans: 'catalogo.first_page_img', fieldtype: costanti.FieldType.image }),
AddCol({ name: 'last_page_img', label_trans: 'catalogo.last_page_img', fieldtype: costanti.FieldType.image }),
AddCol({ name: 'first_page_html', label_trans: 'catalogo.first_page_html', fieldtype: costanti.FieldType.html }),
AddCol({ name: 'first_page_height', label_trans: 'catalogo.first_page_height', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'last_page_height', label_trans: 'catalogo.last_page_html', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'last_page_html', label_trans: 'catalogo.last_page_html', fieldtype: costanti.FieldType.html }),
]
export const colmyelems = [
AddCol({ name: 'active', label_trans: 'myelems.active', fieldtype: costanti.FieldType.boolean }),
AddCol({ name: 'path', label_trans: 'myelems.path' }),
AddCol({ name: 'idPage', label_trans: 'myelems.idPage' }),
AddCol({ name: 'order', label_trans: 'myelems.order', fieldtype: costanti.FieldType.number }),
AddCol({ name: 'type', label_trans: 'myelems.type', fieldtype: costanti.FieldType.select, jointable: 'elemtypes' }),
AddCol({ name: 'container', label_trans: 'myelems.container' }),
@@ -4158,6 +4185,13 @@ export const fieldsTable = {
colkey: '_id',
collabel: 'title',
},
{
value: 'scheda',
label: 'Elementi SCheda',
columns: colmyScheda,
colkey: '_id',
collabel: 'name',
},
{
value: 'listcards',
label: 'Elementi',

View File

@@ -8904,7 +8904,7 @@ export const tools = {
getsrcimg(gallerylist: any, dir: string) {
console.log('getsrcimg', gallerylist)
// console.log('getsrcimg', gallerylist)
let addtourl = ''
if (!gallerylist) {
@@ -9109,7 +9109,7 @@ export const tools = {
convertStringToUrl(str: string) {
return encodeURIComponent(str); // Codifica la stringa per URL
}
},
// FINE !

View File

@@ -131,7 +131,7 @@ export const useProducts = defineStore('Products', {
// Ottieni le categorie solo per i "products" che hanno come idGasOrdine il valore passato
if (idGasOrdine) {
arrcat = state.catprods_gas.filter((rec: ICatProd) => {
arrcat = state.catprods_gas.filter((rec: ICatProd) => {
const arrprod = state.products.filter((prod: IProduct) => {
if (prod.idGasordine === idGasOrdine && prod.productInfo.idCatProds?.includes(rec._id)) {
return true
@@ -140,12 +140,12 @@ export const useProducts = defineStore('Products', {
})
return arrprod.length > 0 ? true : false
})
} else {
return []
}
return arrcat
},
@@ -155,9 +155,9 @@ export const useProducts = defineStore('Products', {
// Ottieni le categorie solo per i "products" che hanno come idGasOrdine il valore passato
if (idGasOrdine) {
arrcat = state.subcatprods.filter((rec: ISubCatProd) => {
arrcat = state.subcatprods.filter((rec: ISubCatProd) => {
const arrprod = state.products.filter((prod: IProduct) => {
if (prod.idGasordine === idGasOrdine
if (prod.idGasordine === idGasOrdine
&& prod.productInfo.idSubCatProds?.includes(rec._id)
&& prod.productInfo.idCatProds?.includes(idCatProd)
) {
@@ -167,7 +167,7 @@ export const useProducts = defineStore('Products', {
})
return arrprod.length > 0 ? true : false
})
} else {
return []
}
@@ -473,7 +473,7 @@ export const useProducts = defineStore('Products', {
this.products = [...arrprod]
},*/
async getProductById (id: string): Promise<IProduct> {
async getProductById(id: string): Promise<IProduct> {
let prod = null
if (!this.products) {
// Se non lo carico all'avvio, allora fai la chiamata al server
@@ -481,7 +481,7 @@ export const useProducts = defineStore('Products', {
} else {
prod = this.products.find((prod: IProduct) => prod._id === id)
}
return prod ? prod : getRecordProductEmpty()
},
@@ -1244,6 +1244,62 @@ export const useProducts = defineStore('Products', {
return globalStore.gasordines.filter((rec) => rec.active)
},
getAutoriByArrayAuthors(authors: IAuthor[] | null) {
// Gestione degli autori
let authorString = '';
if (authors && Array.isArray(authors)) {
// Crea un array di nomi completi
const fullNames = authors.map(author =>
`${author.name} ${author.surname}`.trim()
);
// Formattazione degli autori
if (fullNames.length === 1) {
authorString = fullNames[0];
} else if (fullNames.length === 2) {
authorString = `${fullNames[0]} e ${fullNames[1]}`;
} else if (fullNames.length > 2) {
const lastAuthor = fullNames.pop();
authorString = `${fullNames.join(', ')} e ${lastAuthor}`;
}
}
return authorString
},
replaceKeyWordsByProduct(myproduct: IProduct, text_html: string) {
if (!myproduct || !text_html) {
return text_html;
}
const autori = this.getAutoriByArrayAuthors(myproduct.productInfo.authors)
const maxDescriptionLength = 100;
const description = myproduct.productInfo.short_descr || '';
const truncatedDescription = description.length > maxDescriptionLength
? description.substring(0, description.lastIndexOf(' ', maxDescriptionLength)) + '...'
: description;
const prezzo = myproduct.arrvariazioni ? myproduct.arrvariazioni[0].price?.toFixed(2) : ''
// Crea una mappa di sostituzioni
const replacements = {
'{autore}': autori || '',
'{titolo}': myproduct.productInfo.name || '',
'{descrizione}': truncatedDescription || '',
'{prezzo}': prezzo || '',
};
// Esegue le sostituzioni
let result = text_html;
for (const [key, value] of Object.entries(replacements)) {
result = result.replace(new RegExp(key, 'g'), value);
}
return result
},
},

View File

@@ -12,6 +12,7 @@ import {
ISites,
IStatusSkill,
StateConnection,
IMyScheda,
} from '@model'
import { static_data } from '@src/db/static_data'
import * as Types from '@src/store/Api/ApiTypes'
@@ -115,6 +116,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
mailinglist: [],
mypage: [],
myelems: [],
myscheda: [],
calzoom: [],
producers: [],
groups: [],
@@ -269,15 +271,20 @@ export const useGlobalStore = defineStore('GlobalStore', {
},
getPage: (state: IGlobalState) => (path: string): IMyPage | undefined => state.mypage.find((page) => (`/${page.path}`) === path),
getPageById: (state: IGlobalState) => (idpage: string): IMyPage | undefined => state.mypage.find((page) => (`/${page._id}`) === idpage),
getMyElems: (state: IGlobalState) => (path: string): IMyElem[] | [] => {
return state.myelems.filter((page: IMyElem) => (page.path === path)).sort((a: any, b: any) => a.order - b.order)
getMyElemsByIdPage: (state: IGlobalState) => (idPage?: string): IMyElem[] | [] => {
return state.myelems.filter((page: IMyElem) => (page._id === idPage)).sort((a: any, b: any) => a.order - b.order)
},
getMyElemPrecThisElemId: (state: IGlobalState) => (path: string, idelem: string): IMyElem => {
getMySchede: (state: IGlobalState) => (): IMyScheda[] | [] => {
return state.myschedas
},
getMyElemPrecThisElemId: (state: IGlobalState) => (idPage: string, idelem: string): IMyElem => {
// Ottieni tutti gli myelem con lo stesso path e ordinali per order
const sortedElems = state.myelems
.filter((elem: IMyElem) => elem.path === path)
.filter((elem: IMyElem) => elem.idPage === idPage)
.sort((a: any, b: any) => a.order - b.order);
// Trova l'indice dell'elemento con _id = idelem
@@ -291,10 +298,10 @@ export const useGlobalStore = defineStore('GlobalStore', {
}
},
getMyElemNextThisElemId: (state: IGlobalState) => (path: string, idelem: string): IMyElem => {
// Ottieni tutti gli myelem con lo stesso path e ordinali per order
getMyElemNextThisElemId: (state: IGlobalState) => (idPage: string, idelem: string): IMyElem => {
// Ottieni tutti gli myelem con lo stesso idpage e ordinali per order
const sortedElems = state.myelems
.filter((elem: IMyElem) => elem.path === path)
.filter((elem: IMyElem) => elem.idPage === idPage)
.sort((a: any, b: any) => a.order - b.order);
// Trova l'indice dell'elemento con _id = idelem
@@ -462,6 +469,20 @@ export const useGlobalStore = defineStore('GlobalStore', {
},
actions: {
getMyElems(path: string): IMyElem[] | [] {
const mypage = this.getPage(`/${path}`)
if (mypage) {
const idPage = mypage._id
let arrelems = this.myelems.filter((myelem: IMyElem) => (myelem.idPage === idPage)).sort((a: any, b: any) => a.order - b.order)
if (arrelems.length > 0)
return arrelems
// Se non lo trovo per ID allora lo cerco per path
const arrelempath = this.myelems.filter((myelem: IMyElem) => (myelem.path === path)).sort((a: any, b: any) => a.order - b.order)
return arrelempath
}
return [];
},
setValueSettingsByKey({ key, value, serv }: { key: string, value: any, serv: boolean }): any {
// Update the Server
@@ -1176,6 +1197,26 @@ export const useGlobalStore = defineStore('GlobalStore', {
})
},
async duplicatePage(path: string, $q: any, t: any) {
const userStore = useUserStore()
return Api.SendReq('/duppage', 'POST', { path })
.then((res) => {
if (res) {
tools.showPositiveNotif($q, t('mypages.duplicateok'))
return true
} else {
tools.showNegativeNotif($q, t('mypages.duplicateerr'))
return false
}
})
.catch((error) => {
console.log('error loadTable', error)
userStore.setErrorCatch(error)
return null
})
},
async loadPageTest() {
console.log('loadPageTest')
@@ -1670,6 +1711,8 @@ export const useGlobalStore = defineStore('GlobalStore', {
}
this.myelems = []
this.myelems = (res.data.myelems) ? [...res.data.myelems] : []
this.myschedas = []
this.myschedas = (res.data.myschedas) ? [...res.data.myschedas] : []
// console.log('this.mypage', this.mypage)
let isLogged = false
@@ -2068,7 +2111,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
// console.log('getServerHost API', myserv)
}
}
}
// console.log('getServerHost', myserv)
@@ -2076,7 +2119,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
return myserv
} catch (e) {
return process.env.MONGODB_HOST
}
}
},
@@ -2107,6 +2150,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
table: 'myelems',
data: {}
}
console.log(' DA SALVARE', myelem)
mydata.data = myelem
@@ -2119,6 +2163,8 @@ export const useGlobalStore = defineStore('GlobalStore', {
for (let i = 0; i < this.myelems.length; i++) {
if (this.myelems[i]._id === newelem._id) {
this.myelems[i] = newelem;
console.log('SALVATO', this.myelems[i])
break;
}
}
@@ -2173,6 +2219,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
_id: undefined,
type: newtype,
path: myelem.path,
idPage: myelem.idPage,
order: order ? order : 1000,
active: true,
container: ''

View File

@@ -729,6 +729,11 @@
color="positive"
@click="EseguiFunz('listCollectionsBySize')"
></q-btn>
<q-btn
label="MyElem (imposta come chiave l'ID della Pagina e non il path !)"
color="positive"
@click="EseguiFunz('MyElemSetIdPageInsteadThePah')"
></q-btn>
<br />
</div>

View File

@@ -60,4 +60,11 @@ $heightBtn: 100%;
.break {
flex-basis: 100%;
height: 0;
}
.first_page{
padding-top: 40px;
padding-bottom: 40px;
padding-left: 30px;
padding-right: 30px;
}

View File

@@ -14,7 +14,7 @@ import { CProductCard } from '@src/components/CProductCard'
import { CMySelect } from '@src/components/CMySelect'
import { CContainerCatalogoCard } from '@src/components/CContainerCatalogoCard'
import { CSelectUserActive } from '@src/components/CSelectUserActive'
import { ICatalogo, IProduct, ISearchList } from 'model'
import { ICatalogo, IFilterCatalogo, IMyScheda, IProdView, IProduct, ISearchList } from 'model'
import html2canvas from 'html2canvas'
// import { VueHtmlToPaper } from 'vue-html-to-paper'
@@ -54,7 +54,7 @@ export default defineComponent({
const pdfContent = ref(null);
const filter = ref(<any>{
const filter = ref(<IFilterCatalogo>{
author: '',
sort: 1,
publisher: '',
@@ -76,7 +76,8 @@ export default defineComponent({
const searchList = ref([] as ISearchList[])
const arrProducts = ref<any>([])
const arrProducts = ref<IProduct[]>([])
const arrProdToView = ref<IProdView[]>([])
const numRecLoaded = ref(0)
@@ -189,15 +190,15 @@ export default defineComponent({
}
function calcArrProducts() {
// console.log('calcArrProducts')
console.log('calcArrProducts')
// eventuali titoli specifici estratti dall'array di Prodotti Selezionati
//const searchtext = getSearchText()
const searchtext = getSearchText()
refreshpage.value = true
let arrprod = productStore.getProducts(cosa.value) || [];
let filtroAuthor = filter.value.author || '';
//++AddCATALOGO_FIELDS
let filtroProductTypes = props.optcatalogo.productTypes || [0]
@@ -280,10 +281,206 @@ export default defineComponent({
}
arrProducts.value = arrprod
generatearrProdToViewSorted()
loaddata()
refreshpage.value = false
}
function getProductsFilteredByScheda(scheda: IMyScheda) {
const searchtext = scheda.arrProdottiSpeciali
let arrprod = productStore.getProducts(cosa.value) || [];
let filtroAuthor = filter.value.author || '';
let filtroProductTypes = scheda.productTypes || [0]
let filtroExcludeProductTypes = scheda.excludeproductTypes || [0]
let boolfiltroVuotoProductTypes = (filtroProductTypes.length === 0 || (filtroProductTypes.length === 1 && (filtroProductTypes[0] === 0)))
let boolfiltroVuotoExcludeProductTypes = filtroExcludeProductTypes.length === 0
let filtroPublishers = scheda.editore || []
let boolfiltroVuotoEditore = (filtroPublishers.length === 0)
//console.log('filtroVersione', filtroProductTypes)
let catstr = cat.value || ''
let gasselstr = ''
if (cosa.value === shared_consts.PROD.GAS) {
gasselstr = idGasSel.value || '';
}
let lowerSearchTexts = (searchtext || []).map((text: string) =>
text.toLowerCase().trim().replace(/[-@:=]/g, '')
)
// Remove the condition that skips filtering if search text is too short
// Now it will work with multiple search terms
arrprod = arrprod.filter((product: IProduct) => {
if (product && product.productInfo) {
let lowerName = (product.productInfo.name || '').toLowerCase();
let lowerCode = (product.productInfo.code || '').toLowerCase();
let hasCategoria = !catstr || (catstr && (product.productInfo.idCatProds || []).includes(catstr));
let hasAuthor = !filtroAuthor || (filtroAuthor && (product.productInfo.idAuthors || []).includes(filtroAuthor));
// Check if ANY search term matches the product name or code
let searchMatch = lowerSearchTexts.length === 0 || lowerSearchTexts.some((searchTerm: any) => {
// Check if the entire search term is a whole word in name or code
let codeMatch = new RegExp(`\\b${searchTerm}\\b`, 'i').test(lowerCode);
// Check if all words in the search term are present in the name
let allWordsPresent = searchTerm.split(/\s+/).every((word: string) =>
new RegExp(`\\b${word}\\b`, 'i').test(lowerName)
);
return codeMatch || allWordsPresent;
});
let hasProductTypes = true
let hasPublished = true
let hasExcludeProductTypes = false
if (!boolfiltroVuotoProductTypes) {
// check if productInfo.productTypes array includes some item in scheda.ProductTypes array
hasProductTypes = !scheda.productTypes || (scheda.productTypes && (product.productInfo.productTypes || []).some((item: any) => scheda.productTypes.includes(item)))
}
if (!boolfiltroVuotoEditore) {
hasPublished = !scheda.editore || (scheda.editore && scheda.editore.includes(product.productInfo.idPublisher!))
}
if (!boolfiltroVuotoExcludeProductTypes) {
// check if productInfo.productTypes array exclude some item in scheda.ProductTypes array
hasExcludeProductTypes = !scheda.excludeproductTypes || (scheda.excludeproductTypes && (product.productInfo.productTypes || []).every((item: any) => scheda.excludeproductTypes.includes(item)))
}
return searchMatch && hasCategoria && hasAuthor && hasProductTypes && hasPublished && !hasExcludeProductTypes;
} else {
console.error('product or product.productInfo is null');
return false;
}
})
// console.log('filter.value.sort', filter.value.sort)
// sort using filter.value.sort :
if (scheda.sort === costanti.SORT_PUBDATE) {
arrprod = arrprod.sort((a: IProduct, b: IProduct) => {
return b.productInfo.date_publishing_ts - a.productInfo.date_publishing_ts
})
} else if (scheda.sort === costanti.SORT_ALPHA) {
}
return arrprod
}
function addNextProductToTheView(arrproductfiltrati: IProduct[], indprod: number) {
try {
let rectrovato = null;
while (true) {
if (indprod >= arrproductfiltrati.length) {
return { end: true }
}
rectrovato = arrProdToView.value.find(
(prodview: IProdView) => prodview.id === arrproductfiltrati[indprod]._id
);
if (rectrovato) {
indprod++
continue; // Era stato già aggiunto, quindi prova col prossimo
} else {
// Non è stato ancora aggiunto, quindi prendo questo e lo aggiungo alla lista !
const myrec = arrproductfiltrati[indprod]
arrProdToView.value.push({ id: myrec._id, showed: false });
return { myrec, added: true, indprod }
}
}
} catch (e) {
console.error(e);
return { rec: null, indprod }; // Assicurati di gestire correttamente l'errore
}
}
function getProdBySchedaRigaCol(scheda: IMyScheda, riga: number, col: number) {
try {
return scheda.arrProdToShow![riga][col]
} catch (e) {
return null
}
}
function generatearrProdToViewSorted() {
console.log('generatearrProdToViewSorted')
// Svuota
arrProdToView.value = []
for (const recscheda of props.optcatalogo.arrSchede!) {
if (recscheda && recscheda.scheda) {
let schedePerRiga = recscheda.scheda.numschede_perRiga || 1
let schedePerCol = recscheda.scheda.numschede_perCol || 1
let schedePerPagina = schedePerRiga * schedePerCol
// Filtra i prodotti in base ai filtri impostati !
const arrProdFiltrati = getProductsFilteredByScheda(recscheda.scheda)
let indprod = 0
let indadded = 0
recscheda.scheda.arrProdToShow = []
let riga = 0
let col = 0
for (let giro = 0; giro < schedePerPagina; giro++) {
// Aggiunge il prossimo prodotto che non è stato ancora inserito
const result = addNextProductToTheView(arrProdFiltrati, indprod);
if (result.end) {
break; // Esci dal ciclo se non ci sono più prodotti disponibili
} else {
if (result.indprod)
indprod = result.indprod // Aggiorna indprod per il prossimo giro
if (result.myrec) {
indadded++
let riga = Math.floor(indadded / schedePerCol)
let col = indadded % schedePerCol
if (!recscheda.scheda.arrProdToShow[riga]) {
recscheda.scheda.arrProdToShow[riga] = [];
}
recscheda.scheda.arrProdToShow[riga][col] = result.myrec
}
}
}
console.log('*** arrProdToShow', recscheda.scheda.arrProdToShow)
}
}
}
function getNextProd() {
let nextRecord = arrProdToView.value.find((rec: any) => !rec.showed)
// Se un tale record esiste, impostalo su mostrato
if (nextRecord) {
nextRecord.showed = true
return arrProducts.value.find((recprod: IProduct) => recprod._id === nextRecord.id)
}
return null
}
/*function getProducts() {
let arrprod = productStore.getProducts(cosa.value)
@@ -302,6 +499,7 @@ export default defineComponent({
}*/
async function mounted() {
console.log('mounted Catalogo')
loadpage.value = false
await productStore.loadProducts()
@@ -418,7 +616,7 @@ export default defineComponent({
return globalStore.getTableJoinByName(item.table, addall, addnone, item.filter)
})
const loadImage = (src) => {
const loadImage = (src: any) => {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => resolve(img)
@@ -476,55 +674,41 @@ export default defineComponent({
}
}
function getWidthPerc(): string {
function groupedPages(scheda: IMyScheda) {
if (scheda) {
const schedePerRiga = scheda.numschede_perRiga || 1
const schedePerCol = scheda.numschede_perCol || 1
const schedePerPagina = schedePerRiga * schedePerCol
let mynum = props.optcatalogo.numschede_perRiga! + 0
let indiceprodotto = 0
return (100 / mynum) + '%'
}
const pages = []
function getCardStyle(index: any) {
return {
'place-content': 'center',
'flex': `0 1 ${props.optcatalogo.widthscheda}`,
'width': getWidthPerc(), // per N elementi per riga
// 'margin-bottom': props.optcatalogo.margine_pagina, // spazio tra le righe
}
}
// Iterate attraverso l'array prodotti con step = schedePerPagina
for (let pageStart = 0; pageStart < arrProducts.value.length; pageStart += schedePerPagina) {
const page = []
function groupedPages() {
const schedePerRiga = props.optcatalogo.numschede_perRiga || 1
const schedePerCol = props.optcatalogo.numschede_perCol || 1
const schedePerPagina = schedePerRiga * schedePerCol
// Crea le righe per questa pagina
for (let rowStart = 0; rowStart < schedePerCol; rowStart++) {
const row = []
const pages = []
// Iterate attraverso l'array prodotti con step = schedePerPagina
for (let pageStart = 0; pageStart < arrProducts.value.length; pageStart += schedePerPagina) {
const page = []
// Crea le righe per questa pagina
for (let rowStart = 0; rowStart < schedePerCol; rowStart++) {
const row = []
// Riempi ogni riga con il numero corretto di prodotti
for (let col = 0; col < schedePerRiga; col++) {
const productIndex = pageStart + (rowStart * schedePerRiga) + col
if (productIndex < arrProducts.value.length) {
row.push(arrProducts.value[productIndex])
} else {
// Opzionale: riempi con null se non ci sono abbastanza prodotti
row.push(null)
// Riempi ogni riga con il numero corretto di prodotti
for (let col = 0; col < schedePerRiga; col++) {
const productIndex = pageStart + (rowStart * schedePerRiga) + col
row.push(indiceprodotto)
indiceprodotto++
}
page.push(row)
}
page.push(row)
pages.push(page)
}
pages.push(page)
return pages
}
return pages
return null
}
@@ -567,9 +751,9 @@ export default defineComponent({
generatePDF,
pdfContent,
tabcatalogo,
getCardStyle,
getWidthPerc,
groupedPages,
getNextProd,
getProdBySchedaRigaCol,
}
}
})

View File

@@ -8,6 +8,7 @@
>
<q-tab name="visu" icon="fas fa-eye" label="Visualizza"> </q-tab>
<q-tab name="sfondo" icon="fas fa-image" label="Sfondo"> </q-tab>
<q-tab name="pagine" icon="fas fa-book-reader" label="Pagine"> </q-tab>
<q-tab name="opzioni" icon="fas fa-save" label="Opzioni"> </q-tab>
</q-tabs>
<q-tab-panels v-model="tabcatalogo" animated class="">
@@ -60,18 +61,6 @@
>{{ reccat.label }}
</span>
|
<!--<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>
</q-tab-panel>
@@ -216,128 +205,226 @@
id="pdf-content"
ref="pdfContent"
:class="{ 'fixed-width': true }"
:style="{
backgroundImage: `url(${
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
(optcatalogo.printable
? optcatalogo.backgroundimage_printable
: optcatalogo.backgroundimage)
})`,
backgroundSize: 'contain',
'--width':
(optcatalogo.printable
? optcatalogo.widthpagPrintable
: optcatalogo.widthpag) + 'px',
}"
>
<div class="flex-container-book">
<q-infinite-scroll
v-if="!optcatalogo.pdf && arrLoaded && arrLoaded.length > 0"
ref="myinfscroll"
:initial-index="0"
@load="onLoadScroll"
:offset="2000"
debounce="200"
class="q-pa-xs row items-start"
style="place-content: center"
>
<div
class="q-pa-xs"
v-for="(product, index) in arrLoaded"
:key="index"
<div
v-if="optcatalogo.first_page_img"
:style="{
backgroundImage: `url(${
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
(optcatalogo.printable
? optcatalogo.first_page_img
: optcatalogo.first_page_img)
})`,
backgroundSize: 'cover',
height: optcatalogo.first_page_height + 'px',
width: optcatalogo.first_page_width + 'px',
}"
>
<div
class="first_page"
v-html="optcatalogo.first_page_html"
></div>
</div>
<div
:class="{ 'fixed-width': true }"
:style="{
backgroundImage: `url(${
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
(optcatalogo.printable
? optcatalogo.backgroundimage_printable
: optcatalogo.backgroundimage)
})`,
backgroundSize: 'contain',
'--width':
(optcatalogo.printable
? optcatalogo.widthpagPrintable
: optcatalogo.widthpag) + 'px',
}"
>
<div class="flex-container-book">
<q-infinite-scroll
v-if="
!optcatalogo.pdf && arrLoaded && arrLoaded.length > 0
"
ref="myinfscroll"
:initial-index="0"
@load="onLoadScroll"
:offset="2000"
debounce="200"
class="q-pa-xs row items-start"
style="place-content: center"
>
<CContainerCatalogoCard
v-if="
product.active ||
(show_hide &&
productInfo.productTypes.includes(
shared_consts.PRODUCTTYPE.PRODUCT
))
"
:id="product._id"
:complete="false"
:cosa="cosa"
:optcatalogo="optcatalogo"
:options="{
show_short_descr: false,
show_price: false,
show_cat: false,
quante_col: 'c2',
in_3d: false,
}"
@selauthor="selauthor"
/>
<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 v-else class="cards-container">
<!-- Itera sulle pagine -->
<div
v-for="(page, pageIndex) in groupedPages()"
:key="pageIndex"
class="card-page"
:style="`margin-bottom: ${optcatalogo.printable ? optcatalogo.margine_paginaPrintable : optcatalogo.margine_pagina};`"
>
<!-- Itera sulle righe di ogni pagina -->
<div
v-for="(row, rowIndex) in page"
:key="`${pageIndex}-${rowIndex}`"
class="card-row"
:style="`margin-bottom: ${optcatalogo.printable ? optcatalogo.margine_rigaPrintable : optcatalogo.margine_riga};`"
class="q-pa-xs"
v-for="(product, index) in arrLoaded"
:key="index"
>
<!-- Itera sui prodotti di ogni riga -->
<div
v-for="(product, colIndex) in row"
:key="`${pageIndex}-${rowIndex}-${colIndex}`"
class="flex-item-book image-container"
:style="
'place-content: center; ' +
('flex: 0 1 ' + optcatalogo.widthscheda + '; ')
<CContainerCatalogoCard
v-if="
product.active ||
(show_hide &&
productInfo.productTypes.includes(
shared_consts.PRODUCTTYPE.PRODUCT
))
"
>
<CContainerCatalogoCard
v-if="
product && product.active ||
(show_hide &&
productInfo.productTypes.includes(
shared_consts.PRODUCTTYPE.PRODUCT
))
"
:id="product._id"
:complete="false"
:cosa="cosa"
:optcatalogo="optcatalogo"
:options="{
show_short_descr: false,
show_price: false,
show_cat: false,
quante_col: 'c2',
in_3d: false,
}"
@selauthor="selauthor"
/>
<CProductCard
v-else-if="product && (product.active || show_hide)"
:id="product._id"
:complete="false"
:cosa="cosa"
/>
:id="product._id"
:complete="false"
:cosa="cosa"
:optcatalogo="optcatalogo"
:options="{
show_short_descr: false,
show_price: false,
show_cat: false,
quante_col: 'c2',
in_3d: false,
}"
@selauthor="selauthor"
/>
<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 v-else class="cards-container">
<!-- Itera sulle schede -->
<div
v-for="(
recscheda, schedaIndex
) in optcatalogo.arrSchede"
:key="schedaIndex"
>
<div v-if="recscheda && recscheda.scheda">
<!-- Itera sulle pagine -->
<div
v-for="(page, pageIndex) in groupedPages(
recscheda.scheda
)"
:key="pageIndex"
class="card-page"
:style="`margin-bottom: ${
optcatalogo.printable
? optcatalogo.margine_paginaPrintable
: optcatalogo.margine_pagina
}; margin-top: ${optcatalogo.margine_top + 'px'};`"
>
<!-- Itera sulle righe di ogni pagina -->
<div
v-for="(row, rowIndex) in page"
:key="`${pageIndex}-${rowIndex}`"
class="card-row"
:style="`margin-bottom: ${
optcatalogo.printable
? optcatalogo.margine_rigaPrintable
: optcatalogo.margine_riga
};`"
>
<!-- Itera sui prodotti di ogni riga -->
<div
v-for="(indprod, colIndex) in row"
:key="`${pageIndex}-${rowIndex}-${colIndex}`"
class="flex-item-book image-container"
:style="
'place-content: center; ' +
('flex: 0 1 ' +
recscheda.scheda.widthscheda ||
'100px' + '; ')
"
>
<CContainerCatalogoCard
v-if="
getProdBySchedaRigaCol(
recscheda.scheda,
rowIndex,
colIndex
) &&
getProdBySchedaRigaCol(
recscheda.scheda,
rowIndex,
colIndex
).active
"
:id="
getProdBySchedaRigaCol(
recscheda.scheda,
rowIndex,
colIndex
)._id
"
:complete="false"
:cosa="cosa"
:optcatalogo="optcatalogo"
:options="{
show_short_descr: false,
show_price: false,
show_cat: false,
quante_col: 'c2',
in_3d: false,
}"
@selauthor="selauthor"
/>
<CProductCard
v-else-if="
getProdBySchedaRigaCol(
recscheda.scheda,
rowIndex,
colIndex
) &&
(getProdBySchedaRigaCol(
recscheda.scheda,
rowIndex,
colIndex
).active ||
show_hide)
"
:id="
getProdBySchedaRigaCol(
recscheda.scheda,
rowIndex,
colIndex
)._id
"
:complete="false"
:cosa="cosa"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
v-if="optcatalogo.last_page_img"
:style="{
backgroundImage: `url(${
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
(optcatalogo.printable
? optcatalogo.last_page_img
: optcatalogo.last_page_img)
})`,
backgroundSize: 'cover',
height: optcatalogo.last_page_height + 'px',
width: optcatalogo.last_page_width + 'px',
}"
>
<div
class="last_page"
v-html="optcatalogo.last_page_html"
></div>
</div>
</div>
</div>
</div>
@@ -381,6 +468,44 @@
</q-img>
</div>
</q-tab-panel>
<q-tab-panel name="pagine">
<div class="row q-gutter-xs justify-center q-mx-auto bg-blue-1">
<div>
Prima Pagina:
{{
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
optcatalogo.first_page_img
}}
</div>
<q-img
:src="
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
optcatalogo.first_page_img
"
>
</q-img>
<div>
Ultima Pagina:
{{
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
optcatalogo.last_page_img
}}
</div>
<q-img
:src="
costanti.DIR_UPLOAD +
costanti.DIR_CATALOGO +
optcatalogo.last_page_img
"
>
</q-img>
</div>
</q-tab-panel>
<q-tab-panel name="opzioni">
<div class="row q-gutter-xs justify-center q-mx-auto bg-blue-1"></div>
</q-tab-panel>