создаю телегу товаров
All checks were successful
Deploy / build (push) Successful in 43s

This commit is contained in:
alsaze 2025-09-26 23:17:53 +03:00
parent 7c811a4841
commit 83d2a56e52
7 changed files with 138 additions and 26 deletions

View File

@ -1,4 +1,4 @@
import api from '~/api/instance' import api from '~/api/instance'
export const postOrdersCreate = async (parent_id: number | undefined) => export const postOrdersCreate = async (line_items: object[]) =>
await api.wc.v3OrdersCreate({ parent_id }) await api.wc.v3OrdersCreate({ line_items })

View File

@ -7,12 +7,12 @@ export const usePostOrdersCreate = () => {
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation({ return useMutation({
mutationFn: (params: { parent_id: MaybeRef<number | undefined> }) => mutationFn: (params: { line_items: MaybeRef<object[]> }) =>
postOrdersCreate(unref(params.parent_id)), postOrdersCreate(unref(params.line_items)),
onSuccess: (data, variables) => { onSuccess: (data, variables) => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: ['post-orders-create', unref(variables.parent_id)], queryKey: ['post-orders-create', unref(variables.line_items)],
}) })
}, },
}) })

View File

@ -39,9 +39,13 @@
class="justify-content-center" class="justify-content-center"
label="Добавить в корзину" label="Добавить в корзину"
size="xl" size="xl"
@click="addToCartBtn" @click="addToCartBtn()"
/> />
currentSize
<pre>
{{ currentSize }}
</pre>
<UAccordion :items="items" /> <UAccordion :items="items" />
</div> </div>
</template> </template>
@ -51,7 +55,7 @@ import ProductVariations from '~/components/ProductVariations.vue'
import { useCurrentProduct, useProduct } from '~/composables' import { useCurrentProduct, useProduct } from '~/composables'
const { t } = useI18n() const { t } = useI18n()
const { addToCart } = useCart() const { cartAddItem } = useCart()
const { productsData, colors, getAttribute } = useProduct() const { productsData, colors, getAttribute } = useProduct()
const { currentVariant, currentColor, currentMaterial } = useCurrentProduct() const { currentVariant, currentColor, currentMaterial } = useCurrentProduct()
@ -87,7 +91,7 @@ const items = computed(() => [
]) ])
function addToCartBtn() { function addToCartBtn() {
addToCart(currentSize?.value?.id) cartAddItem({ variation_id: currentSize?.value?.id })
} }
</script> </script>

View File

@ -0,0 +1,74 @@
<template>
<div class="cart-item">
<NuxtLink :to="`/product/${productsData?.parent_id}`">
<img
class="cart-item__image"
:src="productsData?.images[0]?.src"
alt="cart?.image"
>
</NuxtLink>
<pre>
{{ variations }}
</pre>
<div>
{{ productsData?.name }}
<div class="d-flex align-items-center">
{{ productsData?.price }}
<Icon name="ph:currency-rub" />
</div>
<div class="cart-item__attributes">
{{ t(`colors.${color}`) }}
{{ t(`materials.${material}`) }}
{{ `размер ${size}` }}
</div>
<div>
<UButton
icon="i-lucide-trash"
@click="deleteItem(cartItem)"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
cartItem: {
type: String,
required: true,
},
})
const { t } = useI18n()
const { cartRemoveItem } = useCart()
const { productsData, color, material, size } = useProduct(props?.cartItem?.variation_id)
const deleteItem = (item) => {
cartRemoveItem({ variation_id: item?.variation_id })
}
</script>
<style lang="scss">
.cart-item {
max-width: 600px;
display: flex;
flex-direction: row;
gap: 20px;
&__image {
width: 120px;
cursor: pointer;
}
&__attributes {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
</style>

View File

@ -1,19 +1,30 @@
export const useCart = () => { import { useStorage } from '@vueuse/core'
const addToCart = (item: any) => {
if (process.client) { export interface ICartItem {
localStorage.setItem('cart', JSON.stringify(item)) variation_id: number
}
} }
const getCart = () => { export interface ICart {
if (process.client) { line_items: ICartItem[]
return localStorage.getItem('cart')
} }
return null
export const useCart = () => {
const cart = useStorage<ICart>('cart', { line_items: [] })
const cartAddItem = (item: ICartItem) => {
cart.value.line_items.push(item)
}
const cartRemoveItem = (item: ICartItem) => {
cart?.value?.line_items
?.splice(cart?.value?.line_items
?.findIndex((cartItem: ICartItem) =>
cartItem?.variation_id === item?.variation_id), 1)
} }
return { return {
addToCart, cart,
getCart, cartAddItem,
cartRemoveItem,
} }
} }

View File

@ -1,8 +1,8 @@
import { useGetProductsDetail, useGetProductsVariationsList } from '~/api/queries' import { useGetProductsDetail, useGetProductsVariationsList } from '~/api/queries'
export const useProduct = () => { export const useProduct = (variantId) => {
const route = useRoute() const route = useRoute()
const currentId = ref<number>(route.params.id) const currentId = ref<number>(route.params.id ?? variantId)
const { data: productsData } = useGetProductsDetail(currentId) const { data: productsData } = useGetProductsDetail(currentId)
const { data: productsVariationsData } = useGetProductsVariationsList(currentId) const { data: productsVariationsData } = useGetProductsVariationsList(currentId)
@ -24,6 +24,10 @@ export const useProduct = () => {
const materials = computed(() => getAttribute(productsData?.value?.attributes, 'material')?.options) const materials = computed(() => getAttribute(productsData?.value?.attributes, 'material')?.options)
const sizes = computed(() => getAttribute(productsData?.value?.attributes, 'size')?.options) const sizes = computed(() => getAttribute(productsData?.value?.attributes, 'size')?.options)
const color = computed(() => getAttribute(productsData?.value?.attributes, 'color')?.option)
const material = computed(() => getAttribute(productsData?.value?.attributes, 'material')?.option)
const size = computed(() => getAttribute(productsData?.value?.attributes, 'size')?.option)
function getIdentifier(productVariant) { function getIdentifier(productVariant) {
const color = getAttribute(productVariant?.attributes, 'color')?.option const color = getAttribute(productVariant?.attributes, 'color')?.option
const material = getAttribute(productVariant?.attributes, 'material')?.option const material = getAttribute(productVariant?.attributes, 'material')?.option
@ -60,6 +64,10 @@ export const useProduct = () => {
materials, materials,
sizes, sizes,
color,
material,
size,
variations, variations,
getAttribute, getAttribute,

View File

@ -1,9 +1,16 @@
<template> <template>
<div class="cart"> <div class="cart">
<div v-if="cartProducts"> <div class="cart__items">
{{ cartProducts }} <div
v-for="cartItem in cart?.line_items"
:key="cartItem.variation_id"
>
<CartItem :cart-item="cartItem" />
</div>
</div>
</div> </div>
<div>
<UButton @click="createOrder"> <UButton @click="createOrder">
Оформить заказ Оформить заказ
</UButton> </UButton>
@ -13,15 +20,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { usePostOrdersCreate } from '~/api/mutations' import { usePostOrdersCreate } from '~/api/mutations'
const { getCart } = useCart() const { cart } = useCart()
const cartProducts = getCart()
const { mutateAsync } = usePostOrdersCreate() const { mutateAsync } = usePostOrdersCreate()
const createOrder = () => { const createOrder = () => {
mutateAsync(cartProducts) mutateAsync(cart)
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.cart {
display: flex;
flex-direction: row;
justify-content: space-between;
&__items {
display: flex;
flex-direction: column;
}
}
</style> </style>