feat: product options, speedup home page, themes

This commit is contained in:
Nikita Kiselev
2025-07-21 13:37:09 +03:00
parent 51ce6ed959
commit e3cc0d4b10
18 changed files with 181 additions and 79 deletions

View File

@@ -1,11 +1,11 @@
<template>
<div>
<div class="pb-10">
<div>
<ProductImageSwiper :images="product.images"/>
<!-- Product info -->
<div
class="mx-auto max-w-2xl px-4 pt-3 pb-16 sm:px-6 lg:grid lg:max-w-7xl lg:grid-cols-3 lg:grid-rows-[auto_auto_1fr] lg:gap-x-8 lg:px-8 lg:pt-16 lg:pb-24">
class="mx-auto max-w-2xl px-4 pt-3 pb-16 sm:px-6 lg:grid lg:max-w-7xl lg:grid-cols-3 lg:grid-rows-[auto_auto_1fr] lg:gap-x-8 lg:px-8 lg:pt-16 lg:pb-24 rounded-t-lg">
<div class="lg:col-span-2 lg:border-r lg:pr-8">
<h1 class="text-2xl font-bold tracking-tight sm:text-3xl">{{ product.name }}</h1>
</div>
@@ -34,14 +34,21 @@
</div>
</div>
<div class="px-4 pb-10 pt-4 fixed bottom-0 left-0 w-full bg-info-content z-50 flex justify-between gap-2 border-t-1 border-t-success-content">
<button
class="btn btn-lg flex-1"
:class="isInCartNow ? 'btn-success' : 'btn-primary'"
@click="actionBtnClick"
>
{{ buttonText }}
</button>
<div v-if="product.id" class="px-4 pb-10 pt-4 fixed bottom-0 left-0 w-full bg-base-200 z-50 flex justify-between gap-2 border-t-1 border-t-base-300">
<div class="flex-1">
<button
class="btn btn-lg w-full"
:class="isInCartNow ? 'btn-success' : 'btn-primary'"
:disabled="canAddToCart === false"
@click="actionBtnClick"
>
<span>{{ buttonText }}</span><br>
</button>
<div v-if="canAddToCart === false" class="text-error text-center text-xs mt-1">
Выберите обязательные опции
</div>
</div>
<Quantity
v-if="quantity > 0"
@@ -76,6 +83,22 @@ const buttonText = computed(() => {
: 'Добавить в корзину'
});
const canAddToCart = computed(() => {
if (!product.value || product.value.options === undefined || product.value.options?.length === 0) {
return true;
}
const required = product.value.options.filter(item => {
return ['checkbox', 'radio', 'select', 'text', 'textarea'].indexOf(item.type) !== -1
&& item.required === true
&& !item.value;
});
console.log(required);
return required.length === 0;
});
const isInCartNow = computed(() => {
return cart.hasProduct(productId.value);
});
@@ -108,17 +131,4 @@ onMounted(async () => {
const {data} = await $fetch(`/index.php?route=extension/tgshop/handle&api_action=product_show&id=${productId.value}`);
product.value = data;
});
const carouselRef = ref();
let lastScrollLeft = 0;
function onScroll(e) {
const scrollLeft = e.target.scrollLeft;
const delta = Math.abs(scrollLeft - lastScrollLeft);
if (delta > 30) {
hapticFeedback.impactOccurred('soft');
lastScrollLeft = scrollLeft;
}
}
</script>
</script>