326 lines
9.1 KiB
JavaScript
326 lines
9.1 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 { fullCurrentDate } from "src/constants";
|
|
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 } = useRouter();
|
|
const { addItem, getItem, removeItem } = useLocalStorage();
|
|
|
|
const modalStore = useModalStore();
|
|
|
|
const rangePriceStore = useRangePriceStore();
|
|
const { rangeValue } = storeToRefs(rangePriceStore);
|
|
|
|
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 categoryObj = {
|
|
plantas: "Floranet Plantas",
|
|
ramos: "Floranet Ramos",
|
|
};
|
|
const availability = ref(getItem("availability"));
|
|
|
|
const availabilityFormKeys = computed(() => {
|
|
return Object.fromEntries(
|
|
Object.entries(availabilityForm.value).filter(
|
|
([key, value]) => value !== ""
|
|
)
|
|
);
|
|
});
|
|
|
|
const isAvailabilityEmpty = computed(() => {
|
|
return (
|
|
Object.keys(availability.value || availabilityFormKeys.value).length === 0
|
|
);
|
|
});
|
|
|
|
const isPostalCalendarEmpty = computed(() => {
|
|
if (category.value === "ramos" || category.value === "plantas") {
|
|
const isAvailabilityEmptyForm =
|
|
Object.keys(availabilityFormKeys.value).length === 0;
|
|
|
|
return isAvailabilityEmptyForm;
|
|
}
|
|
|
|
return isAvailabilityEmpty.value;
|
|
});
|
|
let DATE_INITIAL
|
|
const [YEAR, MONTH, DAY] = fullCurrentDate.replaceAll("/", "-").split("-");
|
|
const CURRENT_DATE = `${DAY}-${MONTH}-${YEAR}`;
|
|
DATE_INITIAL = CURRENT_DATE
|
|
if (availability.value.dateExpired) {
|
|
const [yearStorage, monthStorage, dayStorage] = availability.value.dateExpired.replaceAll("/", "-").split("-");
|
|
const STORAGE_DATE = `${dayStorage}-${monthStorage}-${yearStorage}`;
|
|
DATE_INITIAL = STORAGE_DATE
|
|
}
|
|
const POSTAL_CODE_INITIAL = availability.value.postalCode ? availability.value.postalCode : ""
|
|
|
|
const {
|
|
handleSubmit,
|
|
handleReset,
|
|
defineField,
|
|
errors,
|
|
setValues,
|
|
setFieldError,
|
|
} = useForm({
|
|
validateOnMount: false,
|
|
validationSchema: toTypedSchema(
|
|
type !== "filter" ? availabilitySchema : rangePriceSchema
|
|
),
|
|
initialValues: {
|
|
range: {
|
|
min,
|
|
max,
|
|
},
|
|
postalCode: POSTAL_CODE_INITIAL,
|
|
date: DATE_INITIAL,
|
|
},
|
|
initialTouched: {
|
|
date: availability.value.dateExpired ? true : 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;
|
|
availabilityForm.value.dateExpired = "";
|
|
availability.value.postalCode = "";
|
|
sortProductFilters.value.isOpenOrderFilter = false;
|
|
sortProductFilters.value.order = undefined;
|
|
});
|
|
|
|
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({
|
|
type: categoryObj[category.value],
|
|
postalCode: values.postalCode,
|
|
dateExpired: invertDate(values.date),
|
|
});
|
|
};
|
|
|
|
const handleHome = async () => {
|
|
|
|
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 () => {
|
|
|
|
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];
|
|
|
|
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 () => {
|
|
|
|
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,
|
|
postalCode: availabilityForm.value.postalCode,
|
|
dateExpired: availabilityForm.value.dateExpired,
|
|
};
|
|
|
|
if (category.value === "all") {
|
|
params.postalCode =
|
|
availability.value.postalCode || availabilityForm.value.postalCode;
|
|
params.dateExpired =
|
|
availability.value.dateExpired || availabilityForm.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,
|
|
setFieldError,
|
|
isAvailabilityEmpty,
|
|
isPostalCalendarEmpty,
|
|
availabilityFormKeys,
|
|
category,
|
|
fields: {
|
|
calendar,
|
|
calendarAttrs,
|
|
postalCode,
|
|
postalCodeAttrs,
|
|
priceRange,
|
|
priceRangeAttrs,
|
|
dedication,
|
|
dedicationAttrs,
|
|
},
|
|
errors,
|
|
};
|
|
}
|