Created
March 8, 2024 21:49
-
-
Save dansp89/7ca59c0477f7b797e9bb177d735e8781 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/stores/useCartStore.ts | |
import { empty, productSingleImage } from "@/core/helpers/functions"; | |
import ApiService from "@/core/services/ApiService"; | |
import { defineStore } from "pinia"; | |
// Definindo a interface Product baseada na descrição fornecida | |
interface MediaData { | |
// Defina os campos da mídia aqui se necessário | |
} | |
interface ShopCategory { | |
id: number; | |
attributes: { | |
title: string; | |
createdAt: string; | |
updatedAt: string; | |
key: string; | |
}; | |
} | |
interface Product { | |
id: number; | |
title: string; | |
description: string; | |
descriptionResume: string; | |
priceRegular: number; | |
priceSale: number; | |
priceSaleStart: string; | |
priceSaleEnd: string; | |
sku?: string | null; | |
stock?: number | null; | |
productCode?: string; | |
createdAt: string; | |
updatedAt: string; | |
priceSaleActiveCron: boolean; | |
medias?: { | |
data: MediaData[] | null; | |
}; | |
shop_categories: { | |
data: ShopCategory[]; | |
}; | |
} | |
// Extensão da interface Product para incluir quantidade no carrinho | |
// eslint-disable-next-line @typescript-eslint/no-unused-vars | |
interface CartProduct extends Product { | |
id: number; | |
quantity: number; | |
} | |
interface Coupon { | |
code?: string; | |
discount?: number; | |
type?: string; | |
} | |
export const useStoreCart = defineStore("cart", { | |
state: () => ({ | |
items: [], | |
total: 0, | |
coupon: { | |
code: "", | |
discount: 0, | |
type: "" | |
} as Coupon | |
}), | |
actions: { | |
/** | |
* Adiciona um produto ao carrinho. | |
* @param {Product} product - O produto a ser adicionado ao carrinho. | |
* @param {number} [quantity=1] - A quantidade do produto a ser adicionada. | |
* @param {string} [set='add'] - A ação a ser realizada ('add' para adicionar, 'update' para atualizar). | |
*/ | |
addProduct(product, qnt = 1, set = "add") { | |
const index = this.items.findIndex((item) => item.id === product.id); | |
const price = this.calculatePrice(product); | |
const stock = !empty(product.stock) ? product.stock : ""; | |
const imageUrl = productSingleImage(product); | |
if (index !== -1) { | |
// Produto já existe, incrementar quantidade | |
// this.items[index].qnt += 1; | |
if (set === "add") { | |
this.items[index].qnt += qnt; | |
} else if (set === "update") { | |
this.items[index].qnt = qnt; | |
} | |
} else { | |
// Novo produto, adicionar ao carrinho | |
this.items.push({ | |
id: product.id, | |
title: product.title, | |
price: price, | |
stock: stock, | |
qnt: qnt, | |
subtotal: price, | |
image: imageUrl | |
}); | |
} | |
this.updateCartItemSubtotal(); | |
this.calculateTotal(); | |
this.updateCartState(); | |
}, | |
/** | |
* Remove um produto do carrinho. | |
* @param {Product} product - O produto a ser removido do carrinho. | |
*/ | |
removeProduct(product) { | |
const index = this.items.findIndex((item) => item.id === product.id); | |
if (index !== -1) { | |
if (this.items[index].qnt > 1) { | |
this.items[index].qnt -= 1; | |
} else { | |
this.items.splice(index, 1); | |
} | |
// this.updateCartItemSubtotal(); | |
this.updateCartState(); | |
} | |
// this.calculateTotal(); | |
}, | |
/** | |
* Aplica um cupom de desconto ao carrinho. | |
* @param {string} code - O código do cupom. | |
* @param {number} discount - O valor de desconto do cupom. | |
* @param {string} type - O tipo de desconto do cupom ('percent' ou 'fixed'). | |
*/ | |
async applyCoupon(code, discount = 0, type = "") { | |
try { | |
const { data } = await ApiService.get("/shop-coupoms", `?filters[code][$eqi]=${code}`); | |
console.log( | |
"Código do cupom::datas", | |
data, | |
data?.data.length > 0, | |
data?.data?.[0]?.attributes | |
); | |
const cupom = data?.data?.[0]?.attributes; | |
this.coupon = { | |
code: !empty(cupom.code) ? cupom?.code : "", | |
discount: !empty(cupom.discount) ? cupom?.discount : discount, | |
type: !empty(cupom.type) ? cupom?.type : type | |
}; | |
} catch (error) { | |
console.error("Cupom inválido:", error); | |
this.coupon = { | |
code: "", | |
discount: 0, | |
type: "" | |
}; | |
} | |
this.calculateTotal(); | |
this.updateCartState(); | |
}, | |
/** | |
* Calcula o valor total do carrinho. | |
*/ | |
calculateTotal() { | |
this.total = this.items.reduce((acc, item) => acc + item.subtotal, 0); | |
if (this.total > 0) { | |
if (this.coupon) { | |
if (this.coupon.type === "percent") { | |
this.total *= 1 - this.coupon.discount / 100; | |
} else if (this.coupon.type === "fixed") { | |
this.total -= this.coupon.discount; | |
} | |
} | |
} | |
}, | |
/** | |
* Calcula o preço de um produto. | |
* @param {Product} product - O produto para o qual calcular o preço. | |
* @returns {number} O preço calculado do produto. | |
*/ | |
calculatePrice(product) { | |
if (!product.priceSale || product.priceSale >= product.priceRegular) { | |
return product.priceRegular; | |
} else if (product.priceSale > 0 && product.priceSale < product.priceRegular) { | |
return product.priceSale; | |
} else { | |
// Implementar lógica para priceSaleActiveCron aqui | |
// Pseudocódigo: se hoje está entre priceSaleStart e priceSaleEnd, use priceSale, senão priceRegular | |
const today = new Date(); | |
const saleStart = new Date(product.priceSaleStart); | |
const saleEnd = new Date(product.priceSaleEnd); | |
if (product.priceSaleActiveCron && today >= saleStart && today <= saleEnd) { | |
return product.priceSale; | |
} else { | |
return product.priceRegular; | |
} | |
} | |
}, | |
updateCartItemSubtotal() { | |
this.items = this.items.map((item) => ({ | |
...item, | |
subtotal: item.price * item.qnt | |
})); | |
}, | |
// loadCartState() { | |
// // Tentativa de carregar o estado do carrinho do localStorage | |
// const cartState = localStorage.getItem("cartState"); | |
// if (cartState) { | |
// const parsedState = JSON.parse(cartState); | |
// this.items = parsedState.items || []; | |
// this.total = parsedState.total || 0; | |
// this.coupon = parsedState.coupon || null; | |
// console.log("CART::", parsedState); | |
// // Recalcular o total para garantir que está atualizado | |
// this.calculateTotal(); | |
// } | |
// }, | |
loadCartState() { | |
// console.clear(); | |
const cartState = localStorage.getItem("cartState"); | |
console.log("[loadCartState]::cartState(A)", JSON.stringify(JSON.parse(cartState), null, 2)); | |
if (!empty(cartState)) { | |
const parsedState = JSON.parse(cartState); | |
this.$patch({ ...parsedState }); | |
this.calculateTotal(); | |
return parsedState; | |
} | |
const cartStateNull = { | |
items: [], | |
total: 0, | |
coupon: this.coupon | |
}; | |
console.log("[loadCartState]::cartState(B)", JSON.stringify(cartStateNull, null, 2)); | |
return cartStateNull; | |
}, | |
updateCartState() { | |
const cartState = { | |
items: this.items, | |
total: this.total, | |
coupon: this.coupon | |
}; | |
localStorage.setItem("cartState", JSON.stringify(cartState)); | |
this.calculateTotal(); | |
}, | |
clearCartState() { | |
this.items = []; | |
this.total = 0; | |
this.coupon = null; | |
localStorage.removeItem("cartState"); | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment