Files
interview-demo-code/spa/src/stores/CartStore.js

166 lines
5.8 KiB
JavaScript

import {defineStore} from "pinia";
import {isNotEmpty} from "@/helpers.js";
import {addToCart, cartEditItem, cartRemoveItem, getCart, setCoupon, setVoucher} from "@/utils/ftch.js";
import {useYaMetrikaStore} from "@/stores/yaMetrikaStore.js";
import {useSettingsStore} from "@/stores/SettingsStore.js";
export const useCartStore = defineStore('cart', {
state: () => ({
items: [],
productsCount: 0,
total: 0,
isLoading: false,
reason: null,
error_warning: '',
attention: '',
success: '',
coupon: '',
voucher: '',
}),
getters: {
canCheckout: (state) => {
if (state.isLoading || state.error_warning.length > 0) {
return false;
}
},
},
actions: {
async getProducts() {
try {
this.isLoading = true;
const {data} = await getCart();
this.items = data.products;
this.productsCount = data.total_products_count;
this.totals = data.totals;
this.error_warning = data.error_warning;
this.attention = data.attention;
this.success = data.success;
} catch (error) {
console.error(error);
} finally {
this.isLoading = false;
}
},
async addProduct(productId, productName, price, quantity = 1, options = []) {
try {
this.isLoading = true;
const formData = new FormData();
formData.append("product_id", productId);
formData.append("quantity", quantity);
// TODO: Add support different types of options
options.forEach((option) => {
if (option.type === "checkbox" && Array.isArray(option.value)) {
option.value.forEach(item => {
formData.append(`option[${option.product_option_id}][]`, item.product_option_value_id);
});
} else if (option.type === "radio" && isNotEmpty(option.value)) {
formData.append(`option[${option.product_option_id}]`, option.value.product_option_value_id);
} else if (option.type === "select" && isNotEmpty(option.value)) {
formData.append(`option[${option.product_option_id}]`, option.value.product_option_value_id);
} else if ((option.type === "text" || option.type === 'textarea') && isNotEmpty(option.value)) {
formData.append(`option[${option.product_option_id}]`, option.value);
}
})
const response = await addToCart(formData);
if (response.error) {
throw new Error(JSON.stringify(response.error));
}
await this.getProducts();
} catch (error) {
console.log(error);
throw error;
} finally {
this.isLoading = false;
}
},
async removeItem(cartItem, rowId, index = 0) {
try {
this.isLoading = true;
const formData = new FormData();
formData.append('key', rowId);
await cartRemoveItem(formData);
useYaMetrikaStore().dataLayerPush({
"ecommerce": {
"currencyCode": useSettingsStore().currency_code,
"remove": {
"products": [
{
"id": cartItem.product_id,
"name": cartItem.name,
"quantity": cartItem.quantity,
"position": index
}
]
}
}
});
await this.getProducts();
} catch (error) {
console.error(error);
} finally {
this.isLoading = false;
}
},
async setQuantity(cartId, quantity) {
try {
this.isLoading = true;
const formData = new FormData();
formData.append(`quantity[${cartId}]`, quantity);
await cartEditItem(formData);
await this.getProducts();
} catch (error) {
console.log(error);
} finally {
this.isLoading = false;
}
},
async applyCoupon() {
try {
this.isLoading = true;
this.error_warning = '';
const response = await setCoupon(this.coupon);
if (response.error) {
this.error_warning = response.error;
} else {
await this.getProducts();
}
} catch (error) {
console.log(error);
this.error_warning = 'Возникла ошибка';
} finally {
this.isLoading = false;
}
},
async applyVoucher() {
try {
this.isLoading = true;
this.error_warning = '';
const response = await setVoucher(this.voucher);
if (response.error) {
this.error_warning = response.error;
} else {
await this.getProducts();
}
} catch (error) {
console.log(error);
this.error_warning = 'Возникла ошибка';
} finally {
this.isLoading = false;
}
},
},
});