add. Closes #8
All checks were successful
Deploy Nuxt App / deploy (push) Successful in 3m59s

This commit is contained in:
2025-06-21 10:21:05 +04:00
parent 5c97679188
commit 925b6197f2
16 changed files with 380 additions and 30 deletions

View File

@ -1,17 +1,21 @@
{
"title": "Корзина",
"items": [
{
"id": 1,
"name": "Как влюбить в себя любого \n Книга I. \n Откровения бывшего Казановы",
"src": "/assets/img/png/book1.png",
"buy": "добавить Книгу I"
"src": "/img/books/book1.png",
"buy": "добавить Книгу I",
"price": 520,
"message": "💡 Купи обе книги и получи \n скидку 10% - 936 за комплект"
},
{
"id": 2,
"name": "Как влюбить в себя любого \n Книга II. \n Тонкая игра",
"src": "/assets/img/png/book2.png",
"buy": "добавить Книгу II"
"src": "/img/books/book2.png",
"buy": "добавить Книгу II",
"price": 520,
"message": "💡 Купи обе книги и получи \n скидку 10% - 936 за комплект"
}
],
"message": "💡 Купи обе книги и получи скидку 10% - 936 за комплект",
"price": "520 ₽"
"message": "💡 Купи обе книги и получи скидку 10% - 936 за комплект"
}

View File

@ -1,8 +1,113 @@
<template>
<section class="relative z-50">
<UiHeading tag="h1" size="300"> Корзина </UiHeading>
<section class="relative z-50 ml-4">
<UiHeading tag="h1" size="300" class="font-bold mb-16"> Корзина </UiHeading>
<div class="-ml-6">
<div
v-for="({ name, src, price, message, buy, id }, index) in cartList.items"
:key="index"
class="flex items-center mb-24"
>
<div class="w-40 h-40">
<img :src="`${src}`" alt="book" />
</div>
<UiParagraph size="300" class="whitespace-pre mb-10 mr-12 w-80">{{ name }}</UiParagraph>
<UiParagraph size="300" class="whitespace-pre mb-10 mr-20">{{ message }}</UiParagraph>
<UiButton
:id="id"
class="mb-10"
v-if="store.getQuantity(id) === 0"
@click="handleAddToCart(id)"
>{{ buy }}</UiButton
>
<template v-else>
<div class="flex items-center gap-8 mr-20">
<button
class="w-8 h-8 flex items-center justify-center rounded-full border border-white text-white text-2xl"
@click="handleRemove(id)"
aria-label="Уменьшить количество"
>
</button>
<span class="text-white text-2xl">{{ store.getQuantity(id) }}</span>
<button
class="w-8 h-8 flex items-center justify-center rounded-full border border-white text-white text-2xl"
@click="handleIncrement(id)"
aria-label="Увеличить количество"
>
+
</button>
</div>
<span class="text-white text-2xl font-bold mr-20 whitespace-nowrap">
{{ Number(price) * store.getQuantity(id) }}
</span>
<button
class="w-8 h-8 flex items-center justify-center rounded-full border border-white text-white text-xl"
@click="handleRemove(id)"
aria-label="Удалить товар"
>
×
</button>
</template>
</div>
<div class="flex items-center justify-end mt-8">
<UiParagraph is="span" size="300">Общая стоимость</UiParagraph>
<template v-if="isSpecialPrice">
<span class="text-white text-2xl font-bold ml-4 line-through select-none">
{{ regularTotalPrice }}
</span>
<span class="text-primary text-3xl font-bold ml-4">
{{ store.getTotalPrice(cartList.items) }}
</span>
</template>
<template v-else>
<span class="text-primary text-3xl font-bold ml-4">
{{ store.getTotalPrice(cartList.items) }}
</span>
</template>
</div>
</div>
<div class="mt-10 flex flex-col items-center justify-center">
<UiButton class="w-[660px]"> перейти к оформлению </UiButton>
<UiParagraph is="span" size="300" class="mb-10 mt-5"
>После оплаты книги сразу будут доступны для скачивания</UiParagraph
>
</div>
</section>
</template>
<script setup lang="ts">
import cartList from './_data/cart.json'
import UiHeading from '~/components/Typography/UiHeading.vue'
import UiParagraph from '~/components/Typography/UiParagraph.vue'
import { useSelectedBook } from '@/store/useSelectedBook'
import { computed } from 'vue'
const store = useSelectedBook()
function handleIncrement(id: number) {
store.increment(id)
}
function handleDecrement(id: number) {
store.decrement(id)
}
function handleRemove(id: number) {
store.reset(id)
}
function handleAddToCart(id: number) {
store.addToCart(id)
}
const selectedBooksCount = computed(() => store.cartQuantities.filter((i) => i.quantity > 0).length)
const isSpecialPrice = computed(() => selectedBooksCount.value === 2)
const regularTotalPrice = computed(() => {
// Сумма без скидки
return store.cartQuantities.reduce((sum, item) => {
const book = cartList.items.find((b: any) => b.id === item.id)
return sum + (book ? Number(book.price) * item.quantity : 0)
}, 0)
})
</script>