254 lines
6.3 KiB
JavaScript
254 lines
6.3 KiB
JavaScript
import { defineStore, storeToRefs } from "pinia";
|
|
import { computed, ref } from "vue";
|
|
import { useRouter } from "vue-router";
|
|
|
|
import { apiBack } from "src/boot/axios";
|
|
import { quasarNotify } from "src/functions/quasarNotify";
|
|
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
|
import { useFormStore } from "./forms";
|
|
|
|
export const useCartStore = defineStore("cart", () => {
|
|
const { push } = useRouter();
|
|
const { addItem, getItem } = useLocalStorage();
|
|
|
|
const formStore = useFormStore();
|
|
const { availability: availabilityForm } = storeToRefs(formStore);
|
|
|
|
//! Elements
|
|
const checkoutRef = ref(null);
|
|
const homeSection = ref(null);
|
|
|
|
const initialValues = [
|
|
{
|
|
id: null,
|
|
name: "",
|
|
price: null,
|
|
image: "",
|
|
description: "",
|
|
dateExpired: "",
|
|
isNew: null,
|
|
type: "",
|
|
postalCode: "",
|
|
order_position: null,
|
|
recommend: null,
|
|
},
|
|
];
|
|
|
|
//! Variables
|
|
const cart = ref(getItem("cart"));
|
|
const availability = ref(getItem("availability"));
|
|
|
|
const addCartLoadingBtn = ref(false);
|
|
const routeId = ref(null);
|
|
const products = ref({
|
|
data: initialValues,
|
|
prev: initialValues,
|
|
current: initialValues,
|
|
next: initialValues,
|
|
});
|
|
|
|
function transformOptionsToParams(options = {}) {
|
|
const optionsObj = {
|
|
postalCode: options.postalCode,
|
|
dateExpired: options.dateExpired,
|
|
type: options.type,
|
|
minPrice: options.minPrice,
|
|
maxPrice: options.maxPrice,
|
|
bigPrice: options.bigPrice,
|
|
lowPrice: options.lowPrice,
|
|
isNew: options.isNew,
|
|
order_crescent: options.order_crescent,
|
|
order_descending: options.order_descending,
|
|
recommend: options.recommend,
|
|
};
|
|
const validKeys = Object.keys(options).filter(
|
|
(key) => options[key] !== undefined
|
|
);
|
|
const params = validKeys.reduce((acc, key) => {
|
|
acc[key] = optionsObj[key];
|
|
return acc;
|
|
}, {});
|
|
|
|
return params;
|
|
}
|
|
|
|
const isEmpty = ref(false);
|
|
async function getProducts(
|
|
options = {
|
|
postalCode: undefined,
|
|
dateExpired: undefined,
|
|
type: undefined,
|
|
minPrice: undefined,
|
|
maxPrice: undefined,
|
|
bigPrice: undefined,
|
|
lowPrice: undefined,
|
|
isNew: undefined,
|
|
order_crescent: undefined,
|
|
order_descending: undefined,
|
|
recommend: undefined,
|
|
},
|
|
callback
|
|
) {
|
|
const params = transformOptionsToParams(options);
|
|
|
|
try {
|
|
const {
|
|
data: { data },
|
|
} = await apiBack.get("products", { params });
|
|
|
|
if (data.length === 0) {
|
|
isEmpty.value = true;
|
|
return quasarNotify({
|
|
message:
|
|
"No hay productos disponibles para la fecha y el código postal seleccionados",
|
|
type: "erro",
|
|
});
|
|
}
|
|
|
|
isEmpty.value = false;
|
|
products.value.data = data;
|
|
|
|
if (callback) {
|
|
callback();
|
|
}
|
|
|
|
console.groupCollapsed("%c PRODUCTS FETCHED!", "color: green;");
|
|
console.groupCollapsed("%c PRODUCTS DATA", "color: tomato;");
|
|
console.table(products.value.data);
|
|
console.groupEnd();
|
|
console.groupCollapsed("%c PREV PRODUCT", "color: tomato;");
|
|
console.table(products.value.prev);
|
|
console.groupEnd();
|
|
console.groupCollapsed(
|
|
`%c CURRENT PRODUCT: ${products.value.current.slug}`,
|
|
"color: tomato;"
|
|
);
|
|
console.table(products.value.current);
|
|
console.groupEnd();
|
|
console.groupCollapsed("%c NEXT PRODUCT", "color: tomato;");
|
|
console.table(products.value.next);
|
|
console.groupEnd();
|
|
console.groupEnd();
|
|
} catch (err) {
|
|
new Error(`FATAL ERROR ::: ${err}`);
|
|
}
|
|
}
|
|
|
|
async function getProduct(
|
|
id,
|
|
options = {
|
|
type: undefined,
|
|
postalCode: undefined,
|
|
dateExpired: undefined,
|
|
},
|
|
debug = false
|
|
) {
|
|
if (id) {
|
|
routeId.value = id;
|
|
try {
|
|
const params = transformOptionsToParams(options);
|
|
|
|
const promises = [
|
|
apiBack.get(`products/${+id - 1}`),
|
|
apiBack.get(`products/${+id}`),
|
|
apiBack.get(`products/${+id + 1}`),
|
|
];
|
|
const results = await Promise.allSettled(promises);
|
|
const [prev, current, next] = results.map((res) => {
|
|
const result = {
|
|
fulfilled: res.value?.data,
|
|
rejected: res.reason,
|
|
};
|
|
|
|
return result[res.status].data[0];
|
|
});
|
|
|
|
products.value.prev = prev;
|
|
products.value.current = current;
|
|
products.value.next = next;
|
|
|
|
if (!current) {
|
|
push({ name: "NotFound" });
|
|
}
|
|
|
|
if (debug) {
|
|
console.groupCollapsed(
|
|
`%c PRODUCT FETCHED! SLUG: ${routeId.value}`,
|
|
"color: green;"
|
|
);
|
|
console.table(products.value.prev);
|
|
console.table(products.value.current);
|
|
console.table(products.value.next);
|
|
console.groupEnd();
|
|
}
|
|
|
|
if (products.value.current.response?.status === 404) {
|
|
push({ name: "NotFound" });
|
|
}
|
|
} catch (err) {
|
|
console.error(`FATAL ERROR ::: ${err}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function addToCart(product, message) {
|
|
const params = transformOptionsToParams(
|
|
availabilityForm.value || availability.value
|
|
);
|
|
await getProducts(params);
|
|
|
|
const hasCurrentProduct = computed(() => {
|
|
return cart.value.find((p) => p.id === product.id);
|
|
});
|
|
|
|
if (isEmpty.value) {
|
|
push("/");
|
|
return quasarNotify({
|
|
message:
|
|
"No hay productos disponibles para la fecha y el código postal seleccionados",
|
|
type: "erro",
|
|
});
|
|
}
|
|
|
|
if (!products.value.data.some((item) => item.id === product.id)) {
|
|
push("/");
|
|
return quasarNotify({
|
|
message:
|
|
"Este producto no está disponible en su zona, intente añadir un nuevo código postal",
|
|
type: "erro",
|
|
});
|
|
}
|
|
|
|
if (hasCurrentProduct.value) {
|
|
return quasarNotify({
|
|
message: "Este producto ya está en el carrito",
|
|
type: "info",
|
|
});
|
|
}
|
|
|
|
const arr = [...cart.value];
|
|
arr.push({ ...product, message: message.value });
|
|
cart.value = arr;
|
|
addItem("cart", arr);
|
|
|
|
await push("/checkout");
|
|
quasarNotify({
|
|
message: "Producto añadido al carrito.",
|
|
type: "success",
|
|
});
|
|
}
|
|
|
|
return {
|
|
checkoutRef,
|
|
homeSection,
|
|
|
|
cart,
|
|
addCartLoadingBtn,
|
|
products,
|
|
|
|
getProducts,
|
|
addToCart,
|
|
getProduct,
|
|
};
|
|
});
|