sutty-base-jekyll-theme/_packs/controllers/cart_base_controller.js

271 lines
5.8 KiB
JavaScript
Raw Normal View History

2021-11-22 17:51:50 +00:00
import { Controller } from "stimulus";
import { Liquid } from "liquidjs";
2021-06-01 21:33:49 +00:00
/*
* Base controller, shared methods go here and other classes extend from
* this.
*/
export class CartBaseController extends Controller {
2021-11-22 17:51:50 +00:00
get spree() {
return window.spree;
2021-06-01 21:33:49 +00:00
}
/*
* Gets all products from storage
*
* @return [Array]
*/
2021-11-22 17:51:50 +00:00
get products() {
if (!this.cart) return [];
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
return this.cart.data.relationships.variants.data
.map((x) => JSON.parse(this.storage.getItem(`cart:item:${x.id}`)))
.filter((x) => x !== null);
2021-06-01 21:33:49 +00:00
}
/*
* The storage
*/
2021-11-22 17:51:50 +00:00
get storage() {
return window.localStorage;
2021-06-01 21:33:49 +00:00
}
/*
* Temporary storage
*/
2021-11-22 17:51:50 +00:00
get storageTemp() {
return window.sessionStorage;
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
get cart() {
return JSON.parse(this.storage.getItem("cart"));
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
set cart(response) {
this.storage.setItem("cart", JSON.stringify(response.success()));
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
get email() {
return this.storageTemp.getItem("email");
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
set email(email) {
this.storageTemp.setItem("email", email);
2021-06-01 21:33:49 +00:00
}
/*
* The orderToken
*
* @return [String]
*/
2021-11-22 17:51:50 +00:00
get token() {
return this.storage.getItem("token");
2021-06-01 21:33:49 +00:00
}
/*
* The bearerToken
*
* @return [String]
*/
2021-11-22 17:51:50 +00:00
get bearerToken() {
return this.storageTemp.getItem("bearerToken");
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
set bearerToken(token) {
this.storageTemp.setItem("bearerToken", token);
2021-06-01 21:33:49 +00:00
}
/*
* Liquid renderer
*
* @return Liquid
*/
2021-11-22 17:51:50 +00:00
get engine() {
if (!window.liquid) window.liquid = new Liquid();
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
return window.liquid;
2021-06-01 21:33:49 +00:00
}
/*
* Updates the item counter
*/
2021-11-22 17:51:50 +00:00
counterUpdate() {
const item_count = this.cart.data.attributes.item_count;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
window.dispatchEvent(
new CustomEvent("cart:counter", { detail: { item_count } })
);
this.storage.setItem("cart:counter", item_count);
2021-06-01 21:33:49 +00:00
}
/*
* Removes the brackets from the name or returns the name
*
* @return [String]
*/
2021-11-22 17:51:50 +00:00
idFromInputName(input) {
const matches = input.name.match(/\[([^\]]+)\]$/);
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
return matches === null ? input.name : matches[1];
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
async handleFailure(response) {
const data = { type: "primary" };
let template = "alert";
let notify = true;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
const site = window.site;
const fail = response.fail();
2021-06-01 21:33:49 +00:00
2021-11-10 22:47:05 +00:00
switch (fail.name) {
2021-11-22 17:51:50 +00:00
case "MisconfigurationError":
data.content = fail.message;
break;
case "NoResponseError":
data.content = site.i18n.alerts.no_response_error;
break;
case "SpreeError":
data.content = site.i18n.alerts.spree_error;
break;
case "BasicSpreeError":
2021-06-01 21:33:49 +00:00
// XXX: The order is missing, we need to start a new one
2021-11-10 22:47:05 +00:00
if (fail.serverResponse.status === 404) {
2021-11-22 17:51:50 +00:00
template = "recover_order";
data.content = site.i18n.alerts.recover_order;
2021-06-01 21:33:49 +00:00
} else {
2021-11-22 17:51:50 +00:00
data.content = response.fail().summary;
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
break;
case "ExpandedSpreeError":
const content = [];
2021-11-10 22:47:05 +00:00
// XXX: La API devuelve los mensajes de error tal cual en la
// llave `error` pero el cliente solo nos da acceso a `errors`.
for (const field of Object.keys(fail.errors)) {
if (!site.i18n.errors?.fields[field]) {
2021-11-22 17:51:50 +00:00
console.error("El campo no tiene traducción", field);
2021-11-10 22:47:05 +00:00
}
2021-11-22 17:51:50 +00:00
content.push(
`${site.i18n.errors?.fields[field]}: ${fail.errors[field].join(
", "
)}`
);
2021-11-10 22:47:05 +00:00
}
2021-11-22 17:51:50 +00:00
data.content = content.join(". ");
notify = false;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
break;
2021-06-01 21:33:49 +00:00
default:
2021-11-22 17:51:50 +00:00
data.content = fail.message;
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
if (notify) console.error(fail.name, data.content);
window.dispatchEvent(
new CustomEvent("notification", { detail: { template, data } })
);
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
set formDisabled(state) {
if (!this.hasFormTarget) return;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
this.formTarget.elements.forEach((x) => (x.disabled = !!state));
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
assignShippingAddress() {
if (!this.bearerToken) return;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
const bearerToken = this.bearerToken;
const orderToken = this.token;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
this.spree.sutty.assignOrderShippingAddress(
{ bearerToken },
{ orderToken }
);
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
notify(data = {}) {
window.dispatchEvent(
new CustomEvent("notification", { detail: { template: "alert", data } })
);
2021-06-01 21:33:49 +00:00
}
/*
* Visita una página con soporte para Turbolinks
*
* @param [String] URL
*/
2021-11-22 17:51:50 +00:00
visit(url) {
2021-06-01 21:33:49 +00:00
try {
2021-11-22 17:51:50 +00:00
Turbolinks.visit(url);
2021-06-01 21:33:49 +00:00
} catch {
2021-11-22 17:51:50 +00:00
window.location = url;
2021-06-01 21:33:49 +00:00
}
}
2021-11-22 17:51:50 +00:00
async firstAddress(bearerToken) {
2021-06-01 21:33:49 +00:00
if (!this._firstAddress) {
2021-11-22 17:51:50 +00:00
const addresses = await this.spree.account.addressesList({ bearerToken });
2021-06-01 21:33:49 +00:00
if (addresses.isFail()) {
2021-11-22 17:51:50 +00:00
this.handleFailure(addresses);
return;
2021-06-01 21:33:49 +00:00
}
// XXX: Asumimos que si se registró tiene una dirección que vamos
// a actualizar.
2021-11-22 17:51:50 +00:00
this._firstAddress = addresses.success().data[0];
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
return this._firstAddress;
2021-06-01 21:33:49 +00:00
}
async updateAddress(bearerToken, id, address) {
2021-11-22 17:51:50 +00:00
const updateAddress = await this.spree.account.updateAddress(
{ bearerToken },
id,
{ address }
);
2021-06-01 21:33:49 +00:00
if (updateAddress.isFail()) {
2021-11-22 17:51:50 +00:00
this.handleFailure(updateAddress);
return;
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
return updateAddress.success();
2021-06-01 21:33:49 +00:00
}
async shippingMethods(orderToken) {
2021-11-22 17:51:50 +00:00
const shippingMethods = await this.spree.checkout.shippingMethods(
{ orderToken },
{ include: "shipping_rates" }
);
2021-06-01 21:33:49 +00:00
if (shippingMethods.isFail()) {
2021-11-22 17:51:50 +00:00
this.handleFailure(shippingMethods);
return;
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
return shippingMethods.success();
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
fireCajon(state = "open", cajon = "cajon") {
window.dispatchEvent(
new CustomEvent("cajon", { detail: { cajon, state } })
);
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
formDataToObject(formData) {
const object = {};
2021-06-01 21:33:49 +00:00
for (const field of formData) {
2021-11-22 17:51:50 +00:00
if (field[0].startsWith("_ignore_")) continue;
2021-06-01 21:33:49 +00:00
2021-11-22 17:51:50 +00:00
object[field[0]] = field[1];
2021-06-01 21:33:49 +00:00
}
2021-11-22 17:51:50 +00:00
return object;
2021-06-01 21:33:49 +00:00
}
}