- Esporta Lista Carrello (Totale)
- Sconto Applicato
This commit is contained in:
@@ -47,7 +47,198 @@
|
||||
.qta{
|
||||
font-size: 1.15rem;
|
||||
font-weight: bold;
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
}
|
||||
.autori{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.elimina-btn{
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, #ff3860, #e61e4d); /*negative gradient */
|
||||
color: white;
|
||||
font-size: 1.2rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.quantity-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, #34c759, #2ecc71); /*positive gradient */
|
||||
&[data-gradiente="negative"] {
|
||||
background: linear-gradient(135deg, #ff3860, #e61e4d); /*negative gradient */
|
||||
}
|
||||
color: white;
|
||||
font-size: 1.2rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.quantity-btn:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.quantity-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.quantity-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.quantity-display {
|
||||
min-width: 60px;
|
||||
text-align: center;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
background: #f8fafc;
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
border: 2px solid #e2e8f0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.quantity-display.updating {
|
||||
transform: scale(1.1);
|
||||
border-color: #667eea;
|
||||
background: #eff6ff;
|
||||
}
|
||||
|
||||
.remove-btn {
|
||||
background: linear-gradient(135deg, #ef4444, #dc2626);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 12px 20px;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.remove-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(239, 68, 68, 0.3);
|
||||
}
|
||||
|
||||
.cart-summary {
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
color: white;
|
||||
border-radius: 20px;
|
||||
padding: 24px;
|
||||
margin-top: 32px;
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.cart-summary.hidden {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.total-amount {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.total-items {
|
||||
opacity: 0.9;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.checkout-btn {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
color: white;
|
||||
padding: 16px 32px;
|
||||
border-radius: 12px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.checkout-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.empty-cart {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #6b7280;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
.empty-cart.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.empty-cart i {
|
||||
font-size: 4rem;
|
||||
margin-bottom: 20px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.05); }
|
||||
}
|
||||
|
||||
.pulse {
|
||||
animation: pulse 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeInUp 0.5s ease forwards;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.product-content {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.quantity-controls {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.remove-btn {
|
||||
margin: 16px auto 0;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import { tools } from '../../store/Modules/tools'
|
||||
import { CCardState } from '../CCardState'
|
||||
import { CCopyBtn } from '../CCopyBtn'
|
||||
import { tools } from '../../store/Modules/tools';
|
||||
import { CCardState } from '../CCardState';
|
||||
import { CCopyBtn } from '../CCopyBtn';
|
||||
|
||||
import type { IOrder} from '@src/model';
|
||||
import { IOperators, IProduct } from '@src/model'
|
||||
import type { PropType} from 'vue';
|
||||
import { defineComponent, toRef, ref, watch, onMounted } from 'vue'
|
||||
import { CTitleBanner } from '@src/components/CTitleBanner'
|
||||
import { useProducts } from '@store/Products'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useQuasar } from 'quasar'
|
||||
import { loadRouteLocation } from 'vue-router'
|
||||
import type { IOrder } from '@src/model';
|
||||
import { IOperators, IProduct } from '@src/model';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent, toRef, ref, watch, onMounted } from 'vue';
|
||||
import { CTitleBanner } from '@src/components/CTitleBanner';
|
||||
import { useProducts } from '@store/Products';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { loadRouteLocation } from 'vue-router';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CSingleCart',
|
||||
@@ -42,11 +42,11 @@ export default defineComponent({
|
||||
},
|
||||
components: { CTitleBanner, CCardState, CCopyBtn },
|
||||
setup(props, { emit }) {
|
||||
const products = useProducts()
|
||||
const order = toRef(props, 'order')
|
||||
const { t } = useI18n()
|
||||
const products = useProducts();
|
||||
const order = toRef(props, 'order');
|
||||
const { t } = useI18n();
|
||||
|
||||
const $q = useQuasar()
|
||||
const $q = useQuasar();
|
||||
|
||||
const orderQuantity = ref(<number | undefined>undefined);
|
||||
const weight = ref(<number | undefined>undefined);
|
||||
@@ -54,161 +54,179 @@ export default defineComponent({
|
||||
const orderQuantityPreordered = ref(<number | undefined>undefined);
|
||||
const orderTotalPriceProduct = ref(<number | undefined>undefined);
|
||||
|
||||
const enableQty = ref(false)
|
||||
const endload = ref(false)
|
||||
const enableQtyPreordered = ref(false)
|
||||
const enableChangeTotalPrice = ref(false)
|
||||
const enableQty = ref(false);
|
||||
const endload = ref(false);
|
||||
const enableQtyPreordered = ref(false);
|
||||
const enableChangeTotalPrice = ref(false);
|
||||
|
||||
watch(orderQuantity, (newValue: any) => {
|
||||
if (!newValue)
|
||||
order.value.quantity = 0
|
||||
else
|
||||
order.value.quantity = parseFloat(newValue);
|
||||
if (!newValue) order.value.quantity = 0;
|
||||
else order.value.quantity = parseFloat(newValue);
|
||||
|
||||
enableChangeTotalPrice.value = false
|
||||
enableChangeTotalPrice.value = false;
|
||||
});
|
||||
|
||||
watch(weight, (newValue: any) => {
|
||||
if (order.value.product) {
|
||||
if (!newValue)
|
||||
order.value.product.productInfo.weight = 0
|
||||
else
|
||||
order.value.product.productInfo.weight = parseFloat(newValue);
|
||||
if (!newValue) order.value.product.productInfo.weight = 0;
|
||||
else order.value.product.productInfo.weight = parseFloat(newValue);
|
||||
}
|
||||
enableChangeTotalPrice.value = false
|
||||
enableChangeTotalPrice.value = false;
|
||||
});
|
||||
|
||||
watch(price, (newValue: any) => {
|
||||
if (order.value) {
|
||||
if (!newValue)
|
||||
order.value.price = 0
|
||||
else
|
||||
order.value.price = parseFloat(newValue);
|
||||
if (!newValue) order.value.price = 0;
|
||||
else order.value.price = parseFloat(newValue);
|
||||
}
|
||||
enableChangeTotalPrice.value = false
|
||||
enableChangeTotalPrice.value = false;
|
||||
});
|
||||
|
||||
watch(orderQuantityPreordered, (newValue: any) => {
|
||||
if (!newValue)
|
||||
order.value.quantitypreordered = 0
|
||||
else
|
||||
order.value.quantitypreordered = parseFloat(newValue);
|
||||
if (!newValue) order.value.quantitypreordered = 0;
|
||||
else order.value.quantitypreordered = parseFloat(newValue);
|
||||
|
||||
enableChangeTotalPrice.value = false
|
||||
enableChangeTotalPrice.value = false;
|
||||
});
|
||||
|
||||
watch(orderTotalPriceProduct, (newValue: any) => {
|
||||
if (!newValue)
|
||||
order.value.TotalPriceProduct = 0
|
||||
else
|
||||
order.value.TotalPriceProduct = parseFloat(newValue);
|
||||
if (!newValue) order.value.TotalPriceProduct = 0;
|
||||
else order.value.TotalPriceProduct = parseFloat(newValue);
|
||||
});
|
||||
|
||||
watch(() => props.order.TotalPriceProduct, (newValue: any) => {
|
||||
if (!newValue)
|
||||
orderTotalPriceProduct.value = 0
|
||||
else
|
||||
orderTotalPriceProduct.value = parseFloat(newValue);
|
||||
});
|
||||
watch(
|
||||
() => props.order.TotalPriceProduct,
|
||||
(newValue: any) => {
|
||||
if (!newValue) orderTotalPriceProduct.value = 0;
|
||||
else orderTotalPriceProduct.value = parseFloat(newValue);
|
||||
}
|
||||
);
|
||||
|
||||
function myimgclass() {
|
||||
if (props.showall) {
|
||||
return 'imgNormal'
|
||||
return 'imgNormal';
|
||||
} else {
|
||||
return 'imgSmall'
|
||||
return 'imgSmall';
|
||||
}
|
||||
}
|
||||
|
||||
function qtyInCart() {
|
||||
return props.order.quantity + props.order.quantitypreordered;
|
||||
}
|
||||
|
||||
async function addsubqty(addqty: boolean, subqty: boolean) {
|
||||
if (products.isQtyAvailableByOrder(props.order)) {
|
||||
if (addqty) {
|
||||
if (props.order.quantity >= 100)
|
||||
return false
|
||||
if (props.order.quantity >= 100) return false;
|
||||
}
|
||||
|
||||
if (subqty) {
|
||||
if (props.order.quantity === 0)
|
||||
return false
|
||||
if (props.order.quantity === 0) return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (products.isInPreorderByOrder(props.order)) {
|
||||
if (addqty) {
|
||||
if (props.order.quantitypreordered >= 100)
|
||||
return false
|
||||
if (props.order.quantitypreordered >= 100) return false;
|
||||
}
|
||||
|
||||
if (subqty) {
|
||||
if (props.order.quantitypreordered === 0)
|
||||
return false
|
||||
if (props.order.quantitypreordered === 0) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await products.addSubQtyToItem({
|
||||
addqty,
|
||||
subqty,
|
||||
order: props.order,
|
||||
}).then((res: any) => {
|
||||
if (res.risult) {
|
||||
if (res.myord) {
|
||||
order.value.quantity = res.myord.quantity
|
||||
order.value.quantitypreordered = res.myord.quantitypreordered
|
||||
return await products
|
||||
.addSubQtyToItem({
|
||||
addqty,
|
||||
subqty,
|
||||
order: props.order,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.risult) {
|
||||
if (res.myord) {
|
||||
order.value.quantity = res.myord.quantity;
|
||||
order.value.quantitypreordered = res.myord.quantitypreordered;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function isApplicatoSconto() {
|
||||
const totalipotetico = order.value.product!.price * (order.value.quantity + order.value.quantitypreordered)
|
||||
const totalipotetico =
|
||||
order.value.product!.price *
|
||||
(order.value.quantity + order.value.quantitypreordered);
|
||||
if (totalipotetico.toFixed(2) > order.value.TotalPriceProduct.toFixed(2)) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
function removeFromCard() {
|
||||
products.removeFromCart({ order: order.value })
|
||||
|
||||
$q.dialog({
|
||||
title: order.value.product.productInfo.name,
|
||||
message: 'Sicuro di voler rimuovere il prodotto dal carrello?',
|
||||
ok: {
|
||||
label: 'Rimuovi',
|
||||
color: 'negative',
|
||||
rounded: true,
|
||||
},
|
||||
cancel: {
|
||||
label: 'Annulla',
|
||||
color: 'primary',
|
||||
rounded: true,
|
||||
},
|
||||
}).onOk(() => {
|
||||
products.removeFromCart({ order: order.value });
|
||||
});
|
||||
}
|
||||
|
||||
async function updateOrder(paramstoupdate: any) {
|
||||
endload.value = false
|
||||
endload.value = false;
|
||||
if (enableChangeTotalPrice.value) {
|
||||
paramstoupdate = { ...paramstoupdate, TotalPriceProduct: order.value.TotalPriceProduct }
|
||||
paramstoupdate = {
|
||||
...paramstoupdate,
|
||||
TotalPriceProduct: order.value.TotalPriceProduct,
|
||||
};
|
||||
}
|
||||
const myOrdersCart = await products.updateOrderByOrder(props.idOrdersCart, order.value._id, paramstoupdate)
|
||||
emit('update')
|
||||
mounted()
|
||||
const myOrdersCart = await products.updateOrderByOrder(
|
||||
props.idOrdersCart,
|
||||
order.value._id,
|
||||
paramstoupdate
|
||||
);
|
||||
emit('update');
|
||||
mounted();
|
||||
}
|
||||
|
||||
function getRisparmio(): string {
|
||||
return ((order.value.product!.price * order.value.quantity) - order.value.TotalPriceProduct).toFixed(2)
|
||||
return (
|
||||
order.value.product!.price * order.value.quantity -
|
||||
order.value.TotalPriceProduct
|
||||
).toFixed(2);
|
||||
}
|
||||
|
||||
function mounted() {
|
||||
endload.value = false
|
||||
weight.value = props.order.product?.productInfo.weight
|
||||
price.value = props.order.price
|
||||
endload.value = false;
|
||||
weight.value = props.order.product?.productInfo.weight;
|
||||
price.value = props.order.price;
|
||||
if (props.order.quantity !== 0) {
|
||||
orderQuantity.value = props.order.quantity
|
||||
enableQty.value = true
|
||||
orderQuantity.value = props.order.quantity;
|
||||
enableQty.value = true;
|
||||
}
|
||||
if (props.order.quantitypreordered !== 0) {
|
||||
orderQuantityPreordered.value = props.order.quantitypreordered
|
||||
enableQtyPreordered.value = true
|
||||
orderQuantityPreordered.value = props.order.quantitypreordered;
|
||||
enableQtyPreordered.value = true;
|
||||
}
|
||||
|
||||
orderTotalPriceProduct.value = props.order.TotalPriceProduct
|
||||
endload.value = true
|
||||
orderTotalPriceProduct.value = props.order.TotalPriceProduct;
|
||||
endload.value = true;
|
||||
}
|
||||
|
||||
function changeTotalPrice() {
|
||||
console.log('changeTotalPrice')
|
||||
enableChangeTotalPrice.value = true
|
||||
console.log('changeTotalPrice');
|
||||
enableChangeTotalPrice.value = true;
|
||||
}
|
||||
|
||||
onMounted(mounted)
|
||||
onMounted(mounted);
|
||||
|
||||
return {
|
||||
myimgclass,
|
||||
@@ -229,6 +247,7 @@ export default defineComponent({
|
||||
changeTotalPrice,
|
||||
orderTotalPriceProduct,
|
||||
endload,
|
||||
}
|
||||
qtyInCart,
|
||||
};
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
@@ -86,26 +86,30 @@
|
||||
<div class="row q-mb-xs no-wrap items-center centeritems">
|
||||
<q-btn
|
||||
v-if="showall && !nomodif && products.CanDeleteIfSub(order)"
|
||||
icon="fas fa-trash"
|
||||
color="negative"
|
||||
icon="fas fa-trash-alt"
|
||||
round
|
||||
size="xs"
|
||||
size="sm"
|
||||
class="elimina-btn"
|
||||
@click="removeFromCard"
|
||||
>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
v-else-if="showall && !nomodif"
|
||||
:disable="!products.enableSubQty(order)"
|
||||
size="sm"
|
||||
icon="fas fa-cart-arrow-down"
|
||||
:color="products.enableSubQty(order) ? 'negative' : 'grey'"
|
||||
@click="addsubqty(false, true)"
|
||||
rounded
|
||||
:label="
|
||||
<!--
|
||||
:label="
|
||||
t('products.subcart', {
|
||||
qta: products.qtaNextSub(order, order.product),
|
||||
})
|
||||
"
|
||||
-->
|
||||
<q-btn
|
||||
v-else-if="!nomodif"
|
||||
:disable="!products.enableSubQty(order)"
|
||||
size="sm"
|
||||
class="quantity-btn"
|
||||
data-gradiente="negative"
|
||||
:icon="qtyInCart() === 1 ? 'fas fa-trash': 'fas fa-minus'"
|
||||
:color="products.enableSubQty(order) ? undefined : 'grey'"
|
||||
@click="qtyInCart() === 1 ? removeFromCard(): addsubqty(false, true)"
|
||||
rounded
|
||||
></q-btn>
|
||||
<div v-if="editmode">
|
||||
<q-input
|
||||
@@ -115,6 +119,7 @@
|
||||
debounce="500"
|
||||
borderless
|
||||
rounded
|
||||
class="quantity-display"
|
||||
dense
|
||||
:label="t('products.quantity')"
|
||||
></q-input>
|
||||
@@ -124,6 +129,7 @@
|
||||
autofocus
|
||||
debounce="500"
|
||||
borderless
|
||||
class="quantity-display"
|
||||
rounded
|
||||
densep
|
||||
:label="t('ecomm.preord')"
|
||||
@@ -159,24 +165,25 @@
|
||||
</q-btn>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="showall"
|
||||
v-else
|
||||
:class="`q-mx-sm text-blue-14 qta`"
|
||||
>
|
||||
{{ order.quantity + order.quantitypreordered }}
|
||||
</div>
|
||||
|
||||
<q-btn
|
||||
v-if="showall && !nomodif"
|
||||
icon-right="fas fa-cart-plus"
|
||||
color="positive"
|
||||
:disable="!products.enableAddQty(order, order.product)"
|
||||
rounded
|
||||
size="sm"
|
||||
:label="
|
||||
<!-- :label="
|
||||
t('products.addcart', {
|
||||
qta: products.qtaNextAdd(order, order.product),
|
||||
})
|
||||
"
|
||||
-->
|
||||
<q-btn
|
||||
v-if="!nomodif"
|
||||
icon-right="fas fa-plus"
|
||||
class="quantity-btn"
|
||||
:disable="!products.enableAddQty(order, order.product)"
|
||||
rounded
|
||||
size="sm"
|
||||
@click="addsubqty(true, false)"
|
||||
>
|
||||
</q-btn>
|
||||
@@ -229,7 +236,7 @@
|
||||
</div>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<!--<q-item-section side>
|
||||
<q-item-label>
|
||||
<div class="col-2">
|
||||
<q-btn
|
||||
@@ -243,7 +250,7 @@
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item-section>-->
|
||||
|
||||
<!--<q-item-section side top>
|
||||
<q-item-label caption>meta</q-item-label>
|
||||
|
||||
Reference in New Issue
Block a user