- catalogo avanti, parte 1
This commit is contained in:
208
src/components/CCatalogoCard/CCatalogoCard.scss
Executable file
208
src/components/CCatalogoCard/CCatalogoCard.scss
Executable file
@@ -0,0 +1,208 @@
|
||||
.card .product-image {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.text-title {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.centeritems {
|
||||
place-content: center;
|
||||
}
|
||||
|
||||
.prod_price {
|
||||
font-size: 1.25rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.prod_sale_price {
|
||||
font-size: 1.25rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.prod_off_price {
|
||||
font-size: 1rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
color: gray;
|
||||
text-decoration: line-through;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.prod_disp {
|
||||
font-size: 1.2rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.prod_preorder {
|
||||
font-size: 1.2rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.prod_qtywarn {
|
||||
padding-left: 10px;
|
||||
font-size: 1rem;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.totali {
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.prod_sconti {
|
||||
font-size: 1.1rem;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.product_code {
|
||||
font-size: 0.75rem;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.label-qta {
|
||||
font-size: 1.15rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.countdown_scadenza {
|
||||
font-size: 1.15rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subtit_prod {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.icone_prod {
|
||||
font-size: 1.25rem;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.fullscreen-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.fullscreen-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.titolo_prod {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-section {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card_titolo_prod {
|
||||
text-align: center;
|
||||
padding: 4px 4px 4px 4px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: 718px) {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.img-pic {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.q-card__section--vert {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.book-details {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.book-card {
|
||||
max-width: 300px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.book-card-section {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.book-image {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.book-image q-img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.book-info {
|
||||
flex: 2;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.book-title {
|
||||
font-family: 'Poppins,sans-serif';
|
||||
font-size: 1rem;
|
||||
line-height: 20px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.book-author {
|
||||
color: #263238;
|
||||
display: block;
|
||||
font-family: Poppins, sans-serif;
|
||||
font-size: 0.85em;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.book-description {
|
||||
font-size: 0.85rem;
|
||||
color: #777;
|
||||
}
|
||||
478
src/components/CCatalogoCard/CCatalogoCard.ts
Executable file
478
src/components/CCatalogoCard/CCatalogoCard.ts
Executable file
@@ -0,0 +1,478 @@
|
||||
import { defineComponent, ref, toRef, computed, PropType, watch, onMounted, reactive, onBeforeUnmount } from 'vue'
|
||||
import { useI18n } from '@src/boot/i18n'
|
||||
import { useUserStore } from '@store/UserStore'
|
||||
import { useGlobalStore } from '@store/globalStore'
|
||||
import { useQuasar } from 'quasar'
|
||||
|
||||
import { CTitleBanner } from '../CTitleBanner'
|
||||
import { CCardState } from '../CCardState'
|
||||
import { CCopyBtn } from '../CCopyBtn'
|
||||
import { CMyValueDb } from '../CMyValueDb'
|
||||
|
||||
import { func_tools, toolsext } from '@store/Modules/toolsext'
|
||||
|
||||
import { IBaseOrder, IGasordine, IOrder, IOrderCart, IProduct } from '@src/model'
|
||||
import { tools } from '@store/Modules/tools'
|
||||
import { useProducts } from '@store/Products'
|
||||
|
||||
import { shared_consts } from '@src/common/shared_vuejs'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { costanti } from '@costanti'
|
||||
|
||||
import VuePdfApp from 'vue3-pdf-app'
|
||||
// import this to use default icons for buttons
|
||||
import 'vue3-pdf-app/dist/icons/main.css'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CCatalogoCard',
|
||||
props: {
|
||||
product: {
|
||||
type: Object as PropType<IProduct | null>,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
cosa: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
complete: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
components: { CTitleBanner, CCardState, CCopyBtn, CMyValueDb, VuePdfApp },
|
||||
setup(props, { emit }) {
|
||||
const $q = useQuasar()
|
||||
const { t } = useI18n()
|
||||
const userStore = useUserStore()
|
||||
const globalStore = useGlobalStore()
|
||||
const products = useProducts()
|
||||
|
||||
const listord = ref(<IOrderCart[]>[])
|
||||
const sumval = ref(0)
|
||||
const editOn = ref(false)
|
||||
|
||||
const site = ref(globalStore.site)
|
||||
|
||||
const $router = useRouter()
|
||||
|
||||
const fullscreenImage = ref(<any>null)
|
||||
|
||||
const apriSchedaPDF = ref(false)
|
||||
|
||||
let myorder = reactive(<IOrder>{
|
||||
idapp: process.env.APP_ID,
|
||||
quantity: 0,
|
||||
quantitypreordered: 0,
|
||||
idStorehouse: '',
|
||||
idGasordine: '',
|
||||
storehouse: {},
|
||||
gasordine: { active: false },
|
||||
})
|
||||
|
||||
const storeSelected = ref('')
|
||||
const arrordersCart = ref(<IOrderCart[]>[])
|
||||
|
||||
const timerInterval = ref(<any>null)
|
||||
const timerLabelScadenza = ref('')
|
||||
const labelDataRitiro = ref('')
|
||||
const labelDataArrivoMerce = ref('')
|
||||
|
||||
const openlistorders = ref(false)
|
||||
const endload = ref(false)
|
||||
const myproduct = ref(<IProduct>{})
|
||||
|
||||
const isFullScreen = ref(false)
|
||||
const imageSrc = ref('URL_DEL_TUO_FILE_IMMAGINE')
|
||||
const startX = ref(0)
|
||||
const startY = ref(0)
|
||||
const scale = ref(1)
|
||||
|
||||
|
||||
watch(() => editOn.value, (to: any, from: any) => {
|
||||
if (!editOn.value)
|
||||
ricarica()
|
||||
})
|
||||
|
||||
|
||||
/*const myproduct = computed((): IProduct => {
|
||||
console.log('getproduct computed')
|
||||
const ris = products.getProduct(props.code)
|
||||
console.log(' received', ris)
|
||||
return ris
|
||||
})*/
|
||||
|
||||
|
||||
function iconWhishlist(order: IProduct) {
|
||||
if (true) {
|
||||
return 'far fa-heart'
|
||||
} else {
|
||||
return 'fas fa-heart'
|
||||
}
|
||||
}
|
||||
async function addtoCart(add: boolean) {
|
||||
|
||||
if (!userStore.isLogged) {
|
||||
tools.showNeutralNotif($q, t('ecomm.area_personale'))
|
||||
globalStore.rightDrawerOpen = true
|
||||
return false
|
||||
}
|
||||
|
||||
const ris = await products.addtoCartBase({ $q, t, id: myproduct.value._id, order: myorder, addqty: add })
|
||||
updateproduct()
|
||||
if (ris && ris.myord) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function getnumstore() {
|
||||
if (myproduct.value) {
|
||||
if (myproduct.value.storehouses)
|
||||
return myproduct.value.storehouses.length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function getSingleStorehouse() {
|
||||
try {
|
||||
const mystore = myproduct.value.storehouses[0]
|
||||
if (mystore)
|
||||
return mystore.name + ' (' + mystore.city + ')'
|
||||
else
|
||||
return ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function getSingleGasordine(gasordine: IGasordine) {
|
||||
try {
|
||||
const mygas = gasordine
|
||||
if (mygas)
|
||||
/*return mygas.name + ' (' + mygas.city + ') ' + t('gas.dataora_chiusura_ordini') + ': ' + tools.getstrDateShort(mygas.dataora_chiusura_ordini)
|
||||
+ ' ' + t('gas.data_arrivo_merce') + ': ' + tools.getstrDateShort(mygas.data_arrivo_merce)
|
||||
+ ' ' + t('gas.dataora_ritiro') + ': ' + tools.getstrDateShort(mygas.dataora_ritiro)*/
|
||||
|
||||
return mygas.name
|
||||
else
|
||||
return ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function initproduct() {
|
||||
|
||||
myorder.quantity = 0
|
||||
myorder.quantitypreordered = 0
|
||||
myorder.idStorehouse = ''
|
||||
myorder.idGasordine = ''
|
||||
|
||||
}
|
||||
|
||||
function updateproduct() {
|
||||
|
||||
myproduct.value = products.getProductById(props.id)
|
||||
|
||||
// products.updateQuantityAvailable(myproduct.value._id)
|
||||
}
|
||||
|
||||
async function ricarica() {
|
||||
endload.value = false
|
||||
const prod = await products.loadProductById(myproduct.value._id)
|
||||
if (prod) {
|
||||
myproduct.value = prod
|
||||
}
|
||||
load()
|
||||
endload.value = true
|
||||
|
||||
}
|
||||
|
||||
function updateproductmodif() {
|
||||
|
||||
try {
|
||||
myproduct.value = products.getProductById(props.id)
|
||||
|
||||
updateLabel()
|
||||
} catch (e) {
|
||||
console.error('err', e)
|
||||
}
|
||||
}
|
||||
|
||||
function getStorehouses() {
|
||||
if (!myproduct.value)
|
||||
return []
|
||||
|
||||
const myarr: any = []
|
||||
let ind = 1
|
||||
myproduct.value.storehouses.forEach((store) => {
|
||||
myarr.push(
|
||||
{
|
||||
id: ind,
|
||||
label: store.name + ' (' + store.city + ')',
|
||||
value: store._id
|
||||
})
|
||||
|
||||
ind++
|
||||
})
|
||||
|
||||
// console.log('arraystore', myarr)
|
||||
return myarr
|
||||
}
|
||||
|
||||
function checkifCartDisable() {
|
||||
// return !myorder.idStorehouse
|
||||
return isOrdineChiuso()
|
||||
}
|
||||
|
||||
function getQtyWarn() {
|
||||
if (myorder.quantity > 0) {
|
||||
return t('ecomm.di_cui_x_in_carrello', { qty: myorder.quantity })
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function getQtyWarnPreOrdered() {
|
||||
if (myorder.quantitypreordered > 0) {
|
||||
return t('ecomm.di_cui_x_in_carrello', { qty: myorder.quantitypreordered })
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
watch(() => props.id, (newval, oldval) => {
|
||||
// console.log('change code')
|
||||
load()
|
||||
})
|
||||
|
||||
watch(() => storeSelected.value, (newval, oldval) => {
|
||||
myorder.idStorehouse = newval
|
||||
})
|
||||
|
||||
function updateLabel() {
|
||||
let dataArrivoMerce = ''
|
||||
let dataRitiro = ''
|
||||
try {
|
||||
if (myproduct.value && myproduct.value.gasordine) {
|
||||
if (myproduct.value.gasordine.data_arrivo_merce)
|
||||
dataArrivoMerce = tools.getstrDateShort(myproduct.value.gasordine.data_arrivo_merce)
|
||||
if (myproduct.value.gasordine.dataora_ritiro)
|
||||
dataRitiro = tools.getstrDateTime(myproduct.value.gasordine.dataora_ritiro)
|
||||
} else {
|
||||
dataArrivoMerce = ''
|
||||
dataRitiro = ''
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
if (labelDataArrivoMerce.value !== dataArrivoMerce)
|
||||
labelDataArrivoMerce.value = dataArrivoMerce
|
||||
if (labelDataRitiro.value !== dataRitiro)
|
||||
labelDataRitiro.value = dataRitiro
|
||||
|
||||
updateTimerLabel()
|
||||
}
|
||||
|
||||
function mounted() {
|
||||
load()
|
||||
|
||||
// Start the timer when the component is mounted
|
||||
startTimer();
|
||||
}
|
||||
|
||||
function beforeDestroy() {
|
||||
// Clear the interval when the component is destroyed to prevent memory leaks
|
||||
clearInterval(timerInterval.value);
|
||||
}
|
||||
|
||||
function updateTimerLabel() {
|
||||
if (myproduct.value && myproduct.value.gasordine && myproduct.value.gasordine._id && myproduct.value.gasordine.dataora_chiusura_ordini)
|
||||
timerLabelScadenza.value = tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini)
|
||||
else
|
||||
timerLabelScadenza.value = ''
|
||||
}
|
||||
|
||||
function isOrdineChiuso() {
|
||||
return myproduct.value.gasordine && myproduct.value.gasordine.dataora_chiusura_ordini &&
|
||||
tools.getCountDown(myproduct.value.gasordine.dataora_chiusura_ordini) === ''
|
||||
}
|
||||
|
||||
function startTimer() {
|
||||
// Update the timer label every second
|
||||
timerInterval.value = setInterval(() => updateTimerLabel(), 60000);
|
||||
}
|
||||
|
||||
function load() {
|
||||
initproduct()
|
||||
updateproduct()
|
||||
labelDataArrivoMerce.value = ''
|
||||
labelDataRitiro.value = ''
|
||||
|
||||
// console.log('Load', myproduct.value.name)
|
||||
|
||||
arrordersCart.value = products.getOrdersCartInAttesaByIdProduct(myproduct.value._id)
|
||||
|
||||
if (!!myproduct.value) {
|
||||
if (myproduct.value.storehouses && myproduct.value.storehouses.length === 1) {
|
||||
// Se solo 1 presente, metto fisso l'unico negozio !
|
||||
myorder.idStorehouse = myproduct.value.storehouses[0]._id
|
||||
}
|
||||
|
||||
if (myproduct.value.gasordine) {
|
||||
myorder.idGasordine = myproduct.value.gasordine._id
|
||||
}
|
||||
|
||||
const ord = products.getOrderProductInCart(myproduct.value._id)
|
||||
if (ord) {
|
||||
myorder.quantity = ord.quantity
|
||||
myorder.quantitypreordered = ord.quantitypreordered
|
||||
|
||||
// Seleziona il Negozio che avevo già scelto nell'ordine !
|
||||
if (ord.idStorehouse)
|
||||
storeSelected.value = ord.idStorehouse
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
updateLabel()
|
||||
|
||||
// console.log('°°° ENDLOAD °°°')
|
||||
endload.value = true
|
||||
}
|
||||
|
||||
function getclimgproduct() {
|
||||
return 'myimgproduct centermydiv'
|
||||
}
|
||||
|
||||
|
||||
function visuListDisponibili() {
|
||||
openlistorders.value = true
|
||||
sumval.value = products.getSumQtyOrderProductInOrdersCart(myproduct.value._id)
|
||||
|
||||
listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => {
|
||||
return accumulator + item.order.quantity
|
||||
}, 0))
|
||||
}
|
||||
|
||||
function visuListBookable() {
|
||||
openlistorders.value = true
|
||||
sumval.value = products.getSumQtyPreOrderInOrdersCart(myproduct.value._id)
|
||||
|
||||
listord.value = arrordersCart.value.filter((orderscart: IOrderCart) => orderscart.items!.reduce((accumulator, item) => {
|
||||
return accumulator + item.order.quantitypreordered
|
||||
}, 0))
|
||||
}
|
||||
|
||||
function isOrdGas(): boolean {
|
||||
return (myproduct.value && !!myproduct.value.idGasordine && myproduct.value.gasordine! && myproduct.value.gasordine.active)
|
||||
}
|
||||
|
||||
function getpercqtaraggiunta(): number {
|
||||
if (myproduct.value)
|
||||
return tools.calcperc((myproduct.value.bookableGASBloccatiQty + myproduct.value.QuantitaPrenotateInAttesa!) * myproduct.value.productInfo.weight!, myproduct.value.qtyToReachForGas * myproduct.value.productInfo.weight!) / 100
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
function toggleFullScreen() {
|
||||
isFullScreen.value = !isFullScreen.value;
|
||||
scale.value = 1;
|
||||
}
|
||||
|
||||
function onTouchStart(e: any) {
|
||||
startX.value = e.touches[0].pageX;
|
||||
startY.value = e.touches[0].pageY;
|
||||
}
|
||||
|
||||
function onTouchMove(e: any) {
|
||||
const deltaX = e.touches[0].pageX - startX.value;
|
||||
const deltaY = e.touches[0].pageY - startY.value;
|
||||
|
||||
// Calcola la distanza percorsa
|
||||
const distance = Math.sqrt(deltaX ** 2 + deltaY ** 2);
|
||||
|
||||
// Imposta il fattore di scala in base alla distanza percorsa
|
||||
scale.value = Math.min(Math.max(1, scale.value + distance / 100), 3);
|
||||
|
||||
// Salva le nuove coordinate di partenza
|
||||
startX.value = e.touches[0].pageX;
|
||||
startY.value = e.touches[0].pageY;
|
||||
|
||||
// Applica la trasformazione
|
||||
if (fullscreenImage.value)
|
||||
fullscreenImage.value.style.transform = `scale(${scale.value})`;
|
||||
}
|
||||
|
||||
function onTouchEnd() {
|
||||
// Ripristina la trasformazione quando l'utente solleva il dito
|
||||
if (fullscreenImage.value)
|
||||
fullscreenImage.value.fullscreenImage.style.transform = 'scale(1)';
|
||||
}
|
||||
|
||||
function naviga(path: string) {
|
||||
$router.push(path)
|
||||
}
|
||||
|
||||
onMounted(mounted)
|
||||
onBeforeUnmount(beforeDestroy)
|
||||
|
||||
return {
|
||||
visuListDisponibili,
|
||||
visuListBookable,
|
||||
addtoCart,
|
||||
iconWhishlist,
|
||||
getclimgproduct,
|
||||
getnumstore,
|
||||
getSingleStorehouse,
|
||||
getSingleGasordine,
|
||||
getStorehouses,
|
||||
checkifCartDisable,
|
||||
myproduct,
|
||||
myorder,
|
||||
tools,
|
||||
t,
|
||||
storeSelected,
|
||||
getQtyWarn,
|
||||
openlistorders,
|
||||
func_tools,
|
||||
toolsext,
|
||||
products,
|
||||
arrordersCart,
|
||||
endload,
|
||||
shared_consts,
|
||||
site,
|
||||
getQtyWarnPreOrdered,
|
||||
listord,
|
||||
sumval,
|
||||
timerLabelScadenza,
|
||||
labelDataRitiro,
|
||||
labelDataArrivoMerce,
|
||||
getpercqtaraggiunta,
|
||||
isOrdGas,
|
||||
isFullScreen,
|
||||
toggleFullScreen,
|
||||
onTouchStart,
|
||||
onTouchMove,
|
||||
onTouchEnd,
|
||||
naviga,
|
||||
globalStore,
|
||||
editOn,
|
||||
costanti,
|
||||
updateproduct,
|
||||
updateproductmodif,
|
||||
isOrdineChiuso,
|
||||
ricarica,
|
||||
apriSchedaPDF,
|
||||
}
|
||||
}
|
||||
})
|
||||
1139
src/components/CCatalogoCard/CCatalogoCard.vue
Executable file
1139
src/components/CCatalogoCard/CCatalogoCard.vue
Executable file
File diff suppressed because it is too large
Load Diff
1
src/components/CCatalogoCard/index.ts
Executable file
1
src/components/CCatalogoCard/index.ts
Executable file
@@ -0,0 +1 @@
|
||||
export {default as CCatalogoCard} from './CCatalogoCard.vue'
|
||||
Reference in New Issue
Block a user