floranet/src/hooks/usePostalCalendar.js

278 lines
7.6 KiB
JavaScript

import { toTypedSchema } from "@vee-validate/zod";
import { storeToRefs } from "pinia";
import { useForm } from "vee-validate";
import { computed, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { invertDate } from "src/functions/invertDate";
import { quasarNotify } from "src/functions/quasarNotify";
import { useCartStore } from "src/stores/cart";
import { useFormStore } from "src/stores/forms";
import { useModalStore } from "src/stores/modalStore";
import { useRangePriceStore } from "src/stores/rangePrice";
import { availabilitySchema } from "src/utils/zod/schemas";
import { rangePriceSchema } from "src/utils/zod/schemas/rangePriceSchema";
import { useLocalStorage } from "./useLocalStorage";
/**
* Custom hook for managing postal calendar functionality.
*
* @param {Object} options - The options for the hook.
* @param {string} options.modalItem - The modal item.
* @param {string} options.type - The type of the calendar.
* @returns {Object} - The hook functions and properties.
*/
export function usePostalCalendar({ modalItem = "", type = "home" }) {
const route = useRoute();
const { push, go } = useRouter();
const { addItem, getItem, removeItem } = useLocalStorage();
const rangePriceStore = useRangePriceStore();
const { rangeValue } = storeToRefs(rangePriceStore);
const modalStore = useModalStore();
const formStore = useFormStore();
const { sortProductFilters, availability: availabilityForm } =
storeToRefs(formStore);
const cartStore = useCartStore();
const { addToCart, getProducts } = cartStore;
const { products, cart } = storeToRefs(cartStore);
const min = 0;
const max = 200;
const category = ref(route.path.split("/")[2]);
const availability = ref(getItem("availability"));
const isAvailabilityEmpty = computed(() => {
return Object.keys(availability.value).length === 0;
});
const { handleSubmit, handleReset, defineField, errors, setValues } = useForm(
{
validateOnMount: false,
validationSchema: toTypedSchema(
type !== "filter" ? availabilitySchema : rangePriceSchema
),
initialValues: {
range: {
min,
max,
},
postalCode: "",
date: "",
},
initialTouched: {
date: false,
postalCode: true,
},
}
);
const options = {
validateOnBlur: false,
validateOnChange: false,
validateOnInput: false,
validateOnModelUpdate: false,
};
const [calendar, calendarAttrs] = defineField("date", options);
const [postalCode, postalCodeAttrs] = defineField("postalCode", options);
const [priceRange, priceRangeAttrs] = defineField("range", options);
const [dedication, dedicationAttrs] = defineField("dedication");
watch(errors, (newErrors) => {
const hasErrors = {
range: newErrors.range,
dedication: newErrors.dedication,
};
for (const [field, hasError] of Object.entries(hasErrors)) {
if (hasError) {
quasarNotify({ message: newErrors[field], type: "erro" });
}
}
});
watch([() => route.path, () => sortProductFilters.value], ([newPath]) => {
const categoryPath = newPath.split("/")[2];
category.value = categoryPath;
});
const removeCart = () => {
removeItem("cart");
cart.value = [];
};
const onSuccess = async (values) => {
const handleAvailability = async () => {
addItem("availability", {
postalCode: values.postalCode,
dateExpired: invertDate(values.date),
});
removeCart();
availabilityForm.value.dateExpired = invertDate(values.date);
availabilityForm.value.postalCode = values.postalCode;
await getProducts({
postalCode: values.postalCode,
dateExpired: invertDate(values.date),
});
};
const handleHome = async () => {
console.log(type);
addItem("availability", {
postalCode: values.postalCode,
dateExpired: invertDate(values.date),
});
availabilityForm.value.dateExpired = invertDate(values.date);
availabilityForm.value.postalCode = values.postalCode;
removeCart();
const callback = async () => {
await push("/categoria/all");
};
await getProducts(
{
postalCode: values.postalCode,
dateExpired: invertDate(values.date),
},
callback
);
};
const handleProduct = async () => {
console.log(type);
addItem("availability", {
postalCode: values.postalCode,
dateExpired: invertDate(values.date),
});
removeCart();
availabilityForm.value.dateExpired = invertDate(values.date);
availabilityForm.value.postalCode = values.postalCode;
await getProducts({
postalCode: values.postalCode,
dateExpired: invertDate(values.date),
});
const hasProduct = computed(() => {
return products.value.data.some((item) => {
const date = new Date(item.dateExpired);
const day = date.getDate();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const year = date.getFullYear();
const dateExpired = `${day}/${month}/${year}`;
const dateSelected = values.date.replaceAll("-", "/");
const id = +route.path.split("/")[2];
console.log(item.postalCode === values.postalCode);
console.log(item.id === id);
console.log(dateSelected <= dateExpired);
return (
item.postalCode === values.postalCode &&
item.id === id &&
dateSelected <= dateExpired
);
});
});
if (!hasProduct.value) {
quasarNotify({
message: "Código postal y fecha de caducidad añadidos con éxito",
type: "success",
});
return;
}
// go();
addToCart(products.value.current, dedication);
};
const handleFilter = async () => {
console.log(type);
rangeValue.value.max = values.range.max;
rangeValue.value.min = values.range.min;
const params = {
type: categoryObj[category.value],
minPrice: values.range.min,
maxPrice: values.range.max,
};
console.log(params);
if (category.value === "all") {
params.postalCode = availability.value.postalCode;
params.dateExpired = availability.value.dateExpired;
const { type, ...rest } = params;
await getProducts({ ...rest });
return;
}
getProducts(params);
};
const handleDefault = () => {
console.error(
`INVALID TYPE! TYPE: ${type}, ONLY HOME, PRODUCT AND FILTER ARE VALID!`
);
};
const handlers = {
availability: handleAvailability,
home: handleHome,
product: handleProduct,
filter: handleFilter,
default: handleDefault,
};
const handler = handlers[type] || handlers.default;
await handler();
if (modalItem) {
modalStore[modalItem] = false;
}
handleReset();
};
const onError = ({ values, errors, results }) => {
const hasErrors = {
postalCode: !!errors.postalCode,
date: !!errors.date,
};
for (const [field, hasError] of Object.entries(hasErrors)) {
if (hasError) {
quasarNotify({ message: errors[field], type: "erro" });
}
}
};
const onSubmit = handleSubmit(onSuccess, onError);
return {
onSubmit,
setValues,
handleReset,
modalStore,
isAvailabilityEmpty,
fields: {
calendar,
calendarAttrs,
postalCode,
postalCodeAttrs,
priceRange,
priceRangeAttrs,
dedication,
dedicationAttrs,
},
errors,
};
}