diff --git a/Makefile b/Makefile index ef48681..dc44c94 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,12 @@ npx: ## Correr comandos con npx (args="run") npm: ## Correr comandos con npm (args="install -g paquete") $(MAKE) hain args="npm $(args)" +prettier: ## Arreglar JS (por ahora) + $(MAKE) yarn args="prettier --write _packs/" + +format-check: ## Verificar JS + $(MAKE) yarn args="prettier --check _packs/" + serve: /etc/hosts $(hain)/run/nginx/nginx.pid ## Servidor de desarrollo @echo "Iniciado servidor web en https://$(domain):4000/" diff --git a/_packs/controllers/cart_base_controller.js b/_packs/controllers/cart_base_controller.js index da43477..f489a61 100644 --- a/_packs/controllers/cart_base_controller.js +++ b/_packs/controllers/cart_base_controller.js @@ -1,13 +1,13 @@ -import { Controller } from 'stimulus' -import { Liquid } from 'liquidjs' +import { Controller } from "stimulus"; +import { Liquid } from "liquidjs"; /* * Base controller, shared methods go here and other classes extend from * this. */ export class CartBaseController extends Controller { - get spree () { - return window.spree + get spree() { + return window.spree; } /* @@ -15,40 +15,42 @@ export class CartBaseController extends Controller { * * @return [Array] */ - get products () { - if (!this.cart) return [] + get products() { + if (!this.cart) return []; - return this.cart.data.relationships.variants.data.map(x => JSON.parse(this.storage.getItem(`cart:item:${x.id}`))).filter(x => x !== null) + return this.cart.data.relationships.variants.data + .map((x) => JSON.parse(this.storage.getItem(`cart:item:${x.id}`))) + .filter((x) => x !== null); } /* * The storage */ - get storage () { - return window.localStorage + get storage() { + return window.localStorage; } /* * Temporary storage */ - get storageTemp () { - return window.sessionStorage + get storageTemp() { + return window.sessionStorage; } - get cart () { - return JSON.parse(this.storage.getItem('cart')) + get cart() { + return JSON.parse(this.storage.getItem("cart")); } - set cart (response) { - this.storage.setItem('cart', JSON.stringify(response.success())) + set cart(response) { + this.storage.setItem("cart", JSON.stringify(response.success())); } - get email () { - return this.storageTemp.getItem('email') + get email() { + return this.storageTemp.getItem("email"); } - set email (email) { - this.storageTemp.setItem('email', email) + set email(email) { + this.storageTemp.setItem("email", email); } /* @@ -56,8 +58,8 @@ export class CartBaseController extends Controller { * * @return [String] */ - get token () { - return this.storage.getItem('token') + get token() { + return this.storage.getItem("token"); } /* @@ -65,12 +67,12 @@ export class CartBaseController extends Controller { * * @return [String] */ - get bearerToken () { - return this.storageTemp.getItem('bearerToken') + get bearerToken() { + return this.storageTemp.getItem("bearerToken"); } - set bearerToken (token) { - this.storageTemp.setItem('bearerToken', token) + set bearerToken(token) { + this.storageTemp.setItem("bearerToken", token); } /* @@ -78,20 +80,22 @@ export class CartBaseController extends Controller { * * @return Liquid */ - get engine () { - if (!window.liquid) window.liquid = new Liquid() + get engine() { + if (!window.liquid) window.liquid = new Liquid(); - return window.liquid + return window.liquid; } /* * Updates the item counter */ - counterUpdate () { - const item_count = this.cart.data.attributes.item_count + counterUpdate() { + const item_count = this.cart.data.attributes.item_count; - window.dispatchEvent(new CustomEvent('cart:counter', { detail: { item_count }})) - this.storage.setItem('cart:counter', item_count) + window.dispatchEvent( + new CustomEvent("cart:counter", { detail: { item_count } }) + ); + this.storage.setItem("cart:counter", item_count); } /* @@ -99,81 +103,92 @@ export class CartBaseController extends Controller { * * @return [String] */ - idFromInputName (input) { - const matches = input.name.match(/\[([^\]]+)\]$/) + idFromInputName(input) { + const matches = input.name.match(/\[([^\]]+)\]$/); - return (matches === null) ? input.name : matches[1] + return matches === null ? input.name : matches[1]; } - async handleFailure (response) { - const data = { type: 'primary' } - let template = 'alert' - let notify = true + async handleFailure(response) { + const data = { type: "primary" }; + let template = "alert"; + let notify = true; - const site = window.site - const fail = response.fail() + const site = window.site; + const fail = response.fail(); switch (fail.name) { - 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': + 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": // XXX: The order is missing, we need to start a new one if (fail.serverResponse.status === 404) { - template = 'recover_order' - data.content = site.i18n.alerts.recover_order + template = "recover_order"; + data.content = site.i18n.alerts.recover_order; } else { - data.content = response.fail().summary + data.content = response.fail().summary; } - break - case 'ExpandedSpreeError': - const content = [] + break; + case "ExpandedSpreeError": + const content = []; // 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]) { - console.error('El campo no tiene traducción', field) + console.error("El campo no tiene traducción", field); } - content.push(`${site.i18n.errors?.fields[field]}: ${fail.errors[field].join(', ')}`) + content.push( + `${site.i18n.errors?.fields[field]}: ${fail.errors[field].join( + ", " + )}` + ); } - data.content = content.join('. ') - notify = false + data.content = content.join(". "); + notify = false; - break + break; default: - data.content = fail.message + data.content = fail.message; } - if (notify) console.error(fail.name, data.content) - window.dispatchEvent(new CustomEvent('notification', { detail: { template, data } })) + if (notify) console.error(fail.name, data.content); + window.dispatchEvent( + new CustomEvent("notification", { detail: { template, data } }) + ); } - set formDisabled (state) { - if (!this.hasFormTarget) return + set formDisabled(state) { + if (!this.hasFormTarget) return; - this.formTarget.elements.forEach(x => x.disabled = !!state) + this.formTarget.elements.forEach((x) => (x.disabled = !!state)); } - assignShippingAddress () { - if (!this.bearerToken) return + assignShippingAddress() { + if (!this.bearerToken) return; - const bearerToken = this.bearerToken - const orderToken = this.token + const bearerToken = this.bearerToken; + const orderToken = this.token; - this.spree.sutty.assignOrderShippingAddress({ bearerToken }, { orderToken }) + this.spree.sutty.assignOrderShippingAddress( + { bearerToken }, + { orderToken } + ); } - notify (data = {}) { - window.dispatchEvent(new CustomEvent('notification', { detail: { template: 'alert', data } })) + notify(data = {}) { + window.dispatchEvent( + new CustomEvent("notification", { detail: { template: "alert", data } }) + ); } /* @@ -181,66 +196,75 @@ export class CartBaseController extends Controller { * * @param [String] URL */ - visit (url) { + visit(url) { try { - Turbolinks.visit(url) + Turbolinks.visit(url); } catch { - window.location = url + window.location = url; } } - async firstAddress (bearerToken) { + async firstAddress(bearerToken) { if (!this._firstAddress) { - const addresses = await this.spree.account.addressesList({ bearerToken }) + const addresses = await this.spree.account.addressesList({ bearerToken }); if (addresses.isFail()) { - this.handleFailure(addresses) - return + this.handleFailure(addresses); + return; } // XXX: Asumimos que si se registró tiene una dirección que vamos // a actualizar. - this._firstAddress = addresses.success().data[0] + this._firstAddress = addresses.success().data[0]; } - return this._firstAddress + return this._firstAddress; } async updateAddress(bearerToken, id, address) { - const updateAddress = await this.spree.account.updateAddress({ bearerToken }, id, { address }) + const updateAddress = await this.spree.account.updateAddress( + { bearerToken }, + id, + { address } + ); if (updateAddress.isFail()) { - this.handleFailure(updateAddress) - return + this.handleFailure(updateAddress); + return; } - return updateAddress.success() + return updateAddress.success(); } async shippingMethods(orderToken) { - const shippingMethods = await this.spree.checkout.shippingMethods({ orderToken }, { include: 'shipping_rates' }) + const shippingMethods = await this.spree.checkout.shippingMethods( + { orderToken }, + { include: "shipping_rates" } + ); if (shippingMethods.isFail()) { - this.handleFailure(shippingMethods) - return + this.handleFailure(shippingMethods); + return; } - return shippingMethods.success() + return shippingMethods.success(); } - fireCajon (state = 'open', cajon = 'cajon') { - window.dispatchEvent(new CustomEvent('cajon', { detail: { cajon, state }})) + fireCajon(state = "open", cajon = "cajon") { + window.dispatchEvent( + new CustomEvent("cajon", { detail: { cajon, state } }) + ); } - formDataToObject (formData) { - const object = {} + formDataToObject(formData) { + const object = {}; for (const field of formData) { - if (field[0].startsWith('_ignore_')) continue + if (field[0].startsWith("_ignore_")) continue; - object[field[0]] = field[1] + object[field[0]] = field[1]; } - return object + return object; } } diff --git a/_packs/controllers/cart_confirmation_controller.js b/_packs/controllers/cart_confirmation_controller.js index c04d763..d58e4c2 100644 --- a/_packs/controllers/cart_confirmation_controller.js +++ b/_packs/controllers/cart_confirmation_controller.js @@ -1,41 +1,47 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; export default class extends CartBaseController { - static targets = [ 'order' ] + static targets = ["order"]; - async connect () { + async connect() { if (this.clear) { - this.storage.clear() - window.dispatchEvent(new CustomEvent('cart:counter', { detail: { item_count: 0 }})) + this.storage.clear(); + window.dispatchEvent( + new CustomEvent("cart:counter", { detail: { item_count: 0 } }) + ); } - if (!this.template) return + if (!this.template) return; if (this.storage.cart) { - const order = this.cart.data.attributes - const products = this.products - const site = window.site - const shipping_address = JSON.parse(this.storage.getItem('shipping_address')) + const order = this.cart.data.attributes; + const products = this.products; + const site = window.site; + const shipping_address = JSON.parse( + this.storage.getItem("shipping_address") + ); - const data = { order, products, site, shipping_address } + const data = { order, products, site, shipping_address }; - this.storage.setItem('confirmation', JSON.stringify(data)) + this.storage.setItem("confirmation", JSON.stringify(data)); } else { - data = JSON.parse(this.storage.getItem('confirmation')) + data = JSON.parse(this.storage.getItem("confirmation")); } - this.render(data) + this.render(data); } - render (data = {}) { - this.engine.parseAndRender(this.template, data).then(html => this.orderTarget.innerHTML = html) + render(data = {}) { + this.engine + .parseAndRender(this.template, data) + .then((html) => (this.orderTarget.innerHTML = html)); } - get clear () { - return this.element.dataset.clear + get clear() { + return this.element.dataset.clear; } - get template () { - return window.templates[this.element.dataset.template] + get template() { + return window.templates[this.element.dataset.template]; } } diff --git a/_packs/controllers/cart_contact_controller.js b/_packs/controllers/cart_contact_controller.js index b663c3e..8eae1fd 100644 --- a/_packs/controllers/cart_contact_controller.js +++ b/_packs/controllers/cart_contact_controller.js @@ -1,24 +1,24 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; export default class extends CartBaseController { - static targets = [ 'form', 'username' ] + static targets = ["form", "username"]; - connect () { - if (!this.hasUsernameTarget) return - if (!this.hasFormTarget) return + connect() { + if (!this.hasUsernameTarget) return; + if (!this.hasFormTarget) return; - this.formTarget.addEventListener('focusout', event => { + this.formTarget.addEventListener("focusout", (event) => { if (!this.formTarget.checkValidity()) { - this.formTarget.classList.add('was-validated') - return + this.formTarget.classList.add("was-validated"); + return; } - this.formTarget.classList.remove('was-validated') + this.formTarget.classList.remove("was-validated"); - const username = this.usernameTarget.value.trim() - if (username.length === 0) return + const username = this.usernameTarget.value.trim(); + if (username.length === 0) return; - this.email = username - }) + this.email = username; + }); } } diff --git a/_packs/controllers/cart_controller.js b/_packs/controllers/cart_controller.js index 97b43e2..b83a150 100644 --- a/_packs/controllers/cart_controller.js +++ b/_packs/controllers/cart_controller.js @@ -1,4 +1,4 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Manages the cart and its contents. @@ -17,10 +17,10 @@ import { CartBaseController } from './cart_base_controller' */ export default class extends CartBaseController { - static targets = [ 'quantity', 'subtotal', 'addedQuantity' ] + static targets = ["quantity", "subtotal", "addedQuantity"]; - connect () { - if (!this.hasQuantityTarget) return + connect() { + if (!this.hasQuantityTarget) return; /* * When the quantity selector changes, we update the order to have @@ -28,47 +28,51 @@ export default class extends CartBaseController { * * TODO: Go back to previous amount if there's not enough. */ - this.quantityTarget.addEventListener('change', async (event) => { - const quantity = event.target.value + this.quantityTarget.addEventListener("change", async (event) => { + const quantity = event.target.value; if (quantity < 1) return; - const orderToken = await this.tokenGetOrCreate() - const product = this.product + const orderToken = await this.tokenGetOrCreate(); + const product = this.product; - if (!product) return + if (!product) return; - event.target.disabled = true + event.target.disabled = true; - const response = await this.spree.cart.setQuantity({ orderToken }, { - line_item_id: product.line_item.id, - quantity, - include: 'line_items' - }) + const response = await this.spree.cart.setQuantity( + { orderToken }, + { + line_item_id: product.line_item.id, + quantity, + include: "line_items", + } + ); - event.target.disabled = false - event.target.focus() + event.target.disabled = false; + event.target.focus(); // If we're failing here it could be due to a missing order, so we // ask the user to decide what they want to do about it if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - this.cart = response - this.subtotalUpdate() - this.counterUpdate() - await this.itemStore() + this.cart = response; + this.subtotalUpdate(); + this.counterUpdate(); + await this.itemStore(); - if (!this.hasSubtotalTarget) return + if (!this.hasSubtotalTarget) return; - this.subtotalTarget.innerText = product.line_item.attributes.discounted_amount - }) + this.subtotalTarget.innerText = + product.line_item.attributes.discounted_amount; + }); } - subtotalUpdate () { - window.dispatchEvent(new Event('cart:subtotal:update')) + subtotalUpdate() { + window.dispatchEvent(new Event("cart:subtotal:update")); } /* @@ -76,20 +80,20 @@ export default class extends CartBaseController { * * @return [String] */ - async cartCreate () { - const response = await this.spree.cart.create() + async cartCreate() { + const response = await this.spree.cart.create(); // If we fail here it's probably a server error, so we inform the // user. if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - this.cart = response - this.storage.setItem('token', response.success().data.attributes.token) + this.cart = response; + this.storage.setItem("token", response.success().data.attributes.token); - return this.token + return this.token; } /* @@ -97,10 +101,10 @@ export default class extends CartBaseController { * * @return [String] */ - async tokenGetOrCreate () { - let token = this.storage.getItem('token') + async tokenGetOrCreate() { + let token = this.storage.getItem("token"); - return token || await this.cartCreate() + return token || (await this.cartCreate()); } /* @@ -108,18 +112,23 @@ export default class extends CartBaseController { * * @return [String] */ - get variantId () { - return this.data.get('variantId') + get variantId() { + return this.data.get("variantId"); } - get product () { - const product = JSON.parse(this.storage.getItem(this.storageId)) + get product() { + const product = JSON.parse(this.storage.getItem(this.storageId)); if (!product) { - console.error("El producto es nulo!", this.storageId, this.storage.length, this.cart) + console.error( + "El producto es nulo!", + this.storageId, + this.storage.length, + this.cart + ); } - return product + return product; } /* @@ -128,14 +137,18 @@ export default class extends CartBaseController { * * @return [Object] */ - findLineItem () { - const line_item = this.cart.included.find(x => (x.type === 'line_item' && x.relationships.variant.data.id == this.variantId)) + findLineItem() { + const line_item = this.cart.included.find( + (x) => + x.type === "line_item" && + x.relationships.variant.data.id == this.variantId + ); - return (line_item || {}) + return line_item || {}; } - get storageId () { - return `cart:item:${this.variantId}` + get storageId() { + return `cart:item:${this.variantId}`; } /* @@ -143,17 +156,20 @@ export default class extends CartBaseController { * * @see {./order_controller.js} */ - itemStore () { - this.storage.setItem(this.storageId, JSON.stringify({ - variant_id: this.variantId, - line_item: this.findLineItem(), - image: this.data.get('image'), - title: this.data.get('title'), - url: this.data.get('url'), - stock: this.data.get('stock'), - in_stock: this.data.get('inStock'), - extra: this.data.get('extra') ? this.data.get('extra').split('|') : [] - })) + itemStore() { + this.storage.setItem( + this.storageId, + JSON.stringify({ + variant_id: this.variantId, + line_item: this.findLineItem(), + image: this.data.get("image"), + title: this.data.get("title"), + url: this.data.get("url"), + stock: this.data.get("stock"), + in_stock: this.data.get("inStock"), + extra: this.data.get("extra") ? this.data.get("extra").split("|") : [], + }) + ); } /* @@ -164,26 +180,31 @@ export default class extends CartBaseController { * The item needs a variant ID to be added. */ async add(event, quantity = 1, floating_alert = true) { - const addedQuantity = this.addedQuantity() - if (addedQuantity > 1) quantity = addedQuantity + const addedQuantity = this.addedQuantity(); + if (addedQuantity > 1) quantity = addedQuantity; - const orderToken = await this.tokenGetOrCreate() - const response = await this.spree.cart.addItem({ orderToken }, { variant_id: this.variantId, quantity, include: 'line_items' }) + const orderToken = await this.tokenGetOrCreate(); + const response = await this.spree.cart.addItem( + { orderToken }, + { variant_id: this.variantId, quantity, include: "line_items" } + ); if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - this.cart = response - this.itemStore() - this.counterUpdate() - this.fireCajon() + this.cart = response; + this.itemStore(); + this.counterUpdate(); + this.fireCajon(); if (floating_alert) { - const site = window.site - const content = site.cart.added - window.dispatchEvent(new CustomEvent('floating:alert', { detail: { content }})) + const site = window.site; + const content = site.cart.added; + window.dispatchEvent( + new CustomEvent("floating:alert", { detail: { content } }) + ); } } @@ -191,92 +212,98 @@ export default class extends CartBaseController { * Remove the element from the cart. It contacts the API and if the * item is removed, it removes itself from the page and the storage. */ - async remove () { - const product = this.product + async remove() { + const product = this.product; - if (!product) return - if (!product.line_item) return + if (!product) return; + if (!product.line_item) return; - const orderToken = this.token - const response = await this.spree.cart.removeItem({ orderToken }, product.line_item.id, { include: 'line_items' }) + const orderToken = this.token; + const response = await this.spree.cart.removeItem( + { orderToken }, + product.line_item.id, + { include: "line_items" } + ); if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - this.cart = response - this.storage.removeItem(this.storageId) - this.element.remove() - this.subtotalUpdate() - this.counterUpdate() + this.cart = response; + this.storage.removeItem(this.storageId); + this.element.remove(); + this.subtotalUpdate(); + this.counterUpdate(); } /* * Shows variants */ - async variants () { - const template = 'variants' + async variants() { + const template = "variants"; const data = { product: { - variant_id: this.data.get('variantId'), - digital_variant_id: this.data.get('digitalVariantId'), - image: this.data.get('image'), - title: this.data.get('title'), - price: this.data.get('price'), - digital_price: this.data.get('digitalPrice'), - in_stock: this.data.get('inStock'), - extra: this.data.get('extra').split('|') - } - } + variant_id: this.data.get("variantId"), + digital_variant_id: this.data.get("digitalVariantId"), + image: this.data.get("image"), + title: this.data.get("title"), + price: this.data.get("price"), + digital_price: this.data.get("digitalPrice"), + in_stock: this.data.get("inStock"), + extra: this.data.get("extra").split("|"), + }, + }; - window.dispatchEvent(new CustomEvent('notification', { detail: { template, data } })) + window.dispatchEvent( + new CustomEvent("notification", { detail: { template, data } }) + ); } /* * Recovers the order if something failed */ - async recover () { - console.error('Recuperando pedido', this.token) + async recover() { + console.error("Recuperando pedido", this.token); // Removes the failing token - this.storage.removeItem('token') + this.storage.removeItem("token"); // Get a new token and cart - await this.tokenGetOrCreate() + await this.tokenGetOrCreate(); // Stores the previous cart - const cart = this.cart + const cart = this.cart; - if (!cart) return + if (!cart) return; // Add previous items and their quantities to the new cart by // mimicking user's actions // // XXX: We don't use forEach because it's not async for (const variant of cart.data.relationships.variants.data) { - this.data.set('variantId', variant.id) + this.data.set("variantId", variant.id); - const product = this.product + const product = this.product; - if (!product) continue + if (!product) continue; - this.data.set('image', product.image) - this.data.set('title', product.title) - this.data.set('extra', product.extra.join('|')) + this.data.set("image", product.image); + this.data.set("title", product.title); + this.data.set("extra", product.extra.join("|")); - await this.add(null, product.line_item.attributes.quantity, false) + await this.add(null, product.line_item.attributes.quantity, false); } } /* * Si le compradore aumenta la cantidad antes de agregar */ - addedQuantity () { - if (!this.hasAddedQuantityTarget) return 0 + addedQuantity() { + if (!this.hasAddedQuantityTarget) return 0; - const addedQuantity = parseInt(this.addedQuantityTarget.value) + const addedQuantity = parseInt(this.addedQuantityTarget.value); - return (isNaN(addedQuantity) ? 0 : addedQuantity) + return isNaN(addedQuantity) ? 0 : addedQuantity; } } diff --git a/_packs/controllers/cart_counter_controller.js b/_packs/controllers/cart_counter_controller.js index 0db1abd..0daf064 100644 --- a/_packs/controllers/cart_counter_controller.js +++ b/_packs/controllers/cart_counter_controller.js @@ -1,25 +1,28 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; export default class extends CartBaseController { - static targets = [ 'counter' ] + static targets = ["counter"]; - connect () { + connect() { if (!this.hasCounterTarget) { - console.error("Missing counter target") - return + console.error("Missing counter target"); + return; } - window.addEventListener('cart:counter', event => this.counter = event.detail.item_count) - window.addEventListener('storage', event => { - if (event.key == 'cart:counter') this.counter = event.newValue - }) + window.addEventListener( + "cart:counter", + (event) => (this.counter = event.detail.item_count) + ); + window.addEventListener("storage", (event) => { + if (event.key == "cart:counter") this.counter = event.newValue; + }); - if (!this.cart) return + if (!this.cart) return; - this.counter = this.cart.data.attributes.item_count + this.counter = this.cart.data.attributes.item_count; } - set counter (quantity) { - this.counterTarget.innerText = quantity + set counter(quantity) { + this.counterTarget.innerText = quantity; } } diff --git a/_packs/controllers/cart_coupon_controller.js b/_packs/controllers/cart_coupon_controller.js index 15edb3d..e51f63a 100644 --- a/_packs/controllers/cart_coupon_controller.js +++ b/_packs/controllers/cart_coupon_controller.js @@ -1,64 +1,73 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Retrieves shipping methods */ export default class extends CartBaseController { - static targets = [ 'couponCodeInvalid', 'preDiscount', 'total' ] + static targets = ["couponCodeInvalid", "preDiscount", "total"]; - connect () { - this.couponCode.addEventListener('input', event => { - this.couponCode.parentElement.classList.remove('was-validated') - this.couponCode.setCustomValidity('') - }) + connect() { + this.couponCode.addEventListener("input", (event) => { + this.couponCode.parentElement.classList.remove("was-validated"); + this.couponCode.setCustomValidity(""); + }); } - get couponCode () { - if (!this._couponCode) this._couponCode = this.element.elements.coupon_code + get couponCode() { + if (!this._couponCode) this._couponCode = this.element.elements.coupon_code; - return this._couponCode + return this._couponCode; } - get couponCodeInvalid () { - return this.hasCouponCodeInvalidTarget ? this.couponCodeInvalidTarget : document.querySelector('#coupon-code-invalid') + get couponCodeInvalid() { + return this.hasCouponCodeInvalidTarget + ? this.couponCodeInvalidTarget + : document.querySelector("#coupon-code-invalid"); } - get preDiscount () { - return this.hasPreDiscountTarget ? this.preDiscountTarget : document.querySelector('#pre-discount') + get preDiscount() { + return this.hasPreDiscountTarget + ? this.preDiscountTarget + : document.querySelector("#pre-discount"); } - get total () { - return this.hasTotalTarget ? this.totalTarget : document.querySelector('#total') + get total() { + return this.hasTotalTarget + ? this.totalTarget + : document.querySelector("#total"); } - set total (total) { - this.total.innerHTML = total + set total(total) { + this.total.innerHTML = total; } - async apply (event = undefined) { - event?.preventDefault() - event?.stopPropagation() + async apply(event = undefined) { + event?.preventDefault(); + event?.stopPropagation(); - const orderToken = this.token - const coupon_code = this.couponCode.value - const include = 'line_items' + const orderToken = this.token; + const coupon_code = this.couponCode.value; + const include = "line_items"; - const response = await window.spree.cart.applyCouponCode({ orderToken }, { coupon_code, include }) + const response = await window.spree.cart.applyCouponCode( + { orderToken }, + { coupon_code, include } + ); - this.element.elements.forEach(x => x.disabled = true) + this.element.elements.forEach((x) => (x.disabled = true)); if (response.isFail()) { - this.couponCodeInvalid.innerHTML = response.fail().summary - this.couponCode.setCustomValidity(response.fail().summary) - this.couponCode.parentElement.classList.add('was-validated') + this.couponCodeInvalid.innerHTML = response.fail().summary; + this.couponCode.setCustomValidity(response.fail().summary); + this.couponCode.parentElement.classList.add("was-validated"); - this.element.elements.forEach(x => x.disabled = false) + this.element.elements.forEach((x) => (x.disabled = false)); - return + return; } - this.cart = response - this.total = response.success().data.attributes.total - this.preDiscount.classList.remove('d-none') + this.cart = response; + this.total = response.success().data.attributes.total; + this.preDiscount.classList.remove("d-none"); } } diff --git a/_packs/controllers/cart_payment_methods_controller.js b/_packs/controllers/cart_payment_methods_controller.js index c9f882e..a294639 100644 --- a/_packs/controllers/cart_payment_methods_controller.js +++ b/_packs/controllers/cart_payment_methods_controller.js @@ -1,88 +1,92 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Retrieves payment methods and redirect to external checkouts */ export default class extends CartBaseController { - static targets = [ 'form', 'submit', 'specialInstructions' ] + static targets = ["form", "submit", "specialInstructions"]; - async connect () { - const orderToken = this.token - const response = await this.spree.checkout.paymentMethods({ orderToken }) + async connect() { + const orderToken = this.token; + const response = await this.spree.checkout.paymentMethods({ orderToken }); if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - const payment_methods = response.success().data - const site = window.site - const cart = this.cart - const next = { url: this.data.get('nextUrl') } - const back = { url: this.data.get('backUrl') } + const payment_methods = response.success().data; + const site = window.site; + const cart = this.cart; + const next = { url: this.data.get("nextUrl") }; + const back = { url: this.data.get("backUrl") }; - this.render({ payment_methods, site, cart, next, back }) + this.render({ payment_methods, site, cart, next, back }); } - async render (data = {}) { - const template = window.templates[this.data.get('template')] + async render(data = {}) { + const template = window.templates[this.data.get("template")]; - this.element.innerHTML = await this.engine.parseAndRender(template, data) + this.element.innerHTML = await this.engine.parseAndRender(template, data); - if (!this.hasSubmitTarget) return - this.formTarget.elements.forEach(p => p.addEventListener('change', e => this.submitTarget.disabled = false)) + if (!this.hasSubmitTarget) return; + this.formTarget.elements.forEach((p) => + p.addEventListener("change", (e) => (this.submitTarget.disabled = false)) + ); } - async pay (event) { - event.preventDefault() - event.stopPropagation() + async pay(event) { + event.preventDefault(); + event.stopPropagation(); - this.formDisabled = true + this.formDisabled = true; - const payment_method_id = this.formTarget.elements.payment_method_id.value - const orderToken = this.token - const special_instructions = this.specialInstructionsTarget.value.trim() + const payment_method_id = this.formTarget.elements.payment_method_id.value; + const orderToken = this.token; + const special_instructions = this.specialInstructionsTarget.value.trim(); // XXX: Currently SpreeClient expects us to send payment source // attributes as if it were a credit card. - let response = await this.spree.checkout.orderUpdate({ orderToken }, + let response = await this.spree.checkout.orderUpdate( + { orderToken }, { order: { special_instructions, - payments_attributes: [{ payment_method_id }] }, + payments_attributes: [{ payment_method_id }], payment_source: { [payment_method_id]: { - name: 'Pepitx', + name: "Pepitx", month: 12, - year: 2020 - } - } - } - }) + year: 2020, + }, + }, + }, + } + ); if (response.isFail()) { - this.handleFailure(response) - this.formDisabled = false - return + this.handleFailure(response); + this.formDisabled = false; + return; } - this.cart = response + this.cart = response; - response = await this.spree.checkout.complete({ orderToken }) + response = await this.spree.checkout.complete({ orderToken }); if (response.isFail()) { - this.handleFailure(response) - this.formDisabled = false - return + this.handleFailure(response); + this.formDisabled = false; + return; } - this.cart = response + this.cart = response; - const checkoutUrls = await this.spree.sutty.getCheckoutURL({ orderToken }) - let redirectUrl = this.data.get('nextUrl') + const checkoutUrls = await this.spree.sutty.getCheckoutURL({ orderToken }); + let redirectUrl = this.data.get("nextUrl"); - if (checkoutUrls.data.length > 0) redirectUrl = checkoutUrls.data[0] + if (checkoutUrls.data.length > 0) redirectUrl = checkoutUrls.data[0]; - window.location = redirectUrl + window.location = redirectUrl; } } diff --git a/_packs/controllers/cart_paypal_confirmation_controller.js b/_packs/controllers/cart_paypal_confirmation_controller.js index 9ac2777..85c9f8a 100644 --- a/_packs/controllers/cart_paypal_confirmation_controller.js +++ b/_packs/controllers/cart_paypal_confirmation_controller.js @@ -1,4 +1,4 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Replaces checkout.js. @@ -9,15 +9,22 @@ import { CartBaseController } from './cart_base_controller' * discarded. */ export default class extends CartBaseController { - async connect () { - if (this.params.PayerID === undefined) return + async connect() { + if (this.params.PayerID === undefined) return; - this.site = window.site - this.element.innerHTML = this.site.i18n.cart.layouts.paypal.confirming + this.site = window.site; + this.element.innerHTML = this.site.i18n.cart.layouts.paypal.confirming; fetch(this.executeURL) - .then(r => this.element.innerHTML = this.site.i18n.cart.layouts.paypal[(r.ok ? 'confirmed' : 'failure')]) - .catch(e => this.element.innerHTML = this.site.i18n.cart.layouts.paypal.failure) + .then( + (r) => + (this.element.innerHTML = + this.site.i18n.cart.layouts.paypal[r.ok ? "confirmed" : "failure"]) + ) + .catch( + (e) => + (this.element.innerHTML = this.site.i18n.cart.layouts.paypal.failure) + ); } /* @@ -25,18 +32,29 @@ export default class extends CartBaseController { * * @return [Object] */ - get params () { - if (this._params) return this._params + get params() { + if (this._params) return this._params; - this._params = Object.fromEntries(decodeURIComponent(window.location.search.replace('?', '')).split('&').map(x => x.split('='))) + this._params = Object.fromEntries( + decodeURIComponent(window.location.search.replace("?", "")) + .split("&") + .map((x) => x.split("=")) + ); - return this._params + return this._params; } /* * URL to contact the store and execute the payment. */ - get executeURL () { - return [ window.spree.host, 'paypal', 'execute', this.params.orderId, this.params.paymentId, this.params.PayerID ].join('/') + get executeURL() { + return [ + window.spree.host, + "paypal", + "execute", + this.params.orderId, + this.params.paymentId, + this.params.PayerID, + ].join("/"); } } diff --git a/_packs/controllers/cart_shipping_controller.js b/_packs/controllers/cart_shipping_controller.js index 64cc33f..403b211 100644 --- a/_packs/controllers/cart_shipping_controller.js +++ b/_packs/controllers/cart_shipping_controller.js @@ -1,110 +1,127 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; export default class extends CartBaseController { - static targets = [ 'methods', 'rates', 'form' ] + static targets = ["methods", "rates", "form"]; - connect () { - this.formTarget.addEventListener('formdata', event => this.processShippingAddress(event.formData)) + connect() { + this.formTarget.addEventListener("formdata", (event) => + this.processShippingAddress(event.formData) + ); } - async rates (event) { - event.preventDefault() - event.stopPropagation() + async rates(event) { + event.preventDefault(); + event.stopPropagation(); if (!this.formTarget.checkValidity()) { - this.adressTarget.classList.add('was-validated') - return + this.adressTarget.classList.add("was-validated"); + return; } - this.formTarget.classList.remove('was-validated') + this.formTarget.classList.remove("was-validated"); // FormDataEvent es muy reciente if (window.FormDataEvent) { // Esto lanza el evento formdata en el formulario - new FormData(event.target) + new FormData(event.target); } else { // Fallback - this.processShippingAddress(new FormData(event.target)) + this.processShippingAddress(new FormData(event.target)); } } - payment (event) { - event.preventDefault() - event.stopPropagation() + payment(event) { + event.preventDefault(); + event.stopPropagation(); // FormDataEvent es muy reciente if (window.FormDataEvent) { // Esto lanza el evento formdata en el formulario - new FormData(event.target) + new FormData(event.target); } else { - this.processShippingRate(new FormData(event.target)) + this.processShippingRate(new FormData(event.target)); } } - async processShippingAddress (formData) { - this.formDisabled = true + async processShippingAddress(formData) { + this.formDisabled = true; - const email = this.email - const orderToken = this.token + const email = this.email; + const orderToken = this.token; - const ship_address_attributes = this.formDataToObject(formData) - const bill_address_attributes = ship_address_attributes + const ship_address_attributes = this.formDataToObject(formData); + const bill_address_attributes = ship_address_attributes; - const response = await this.spree.checkout.orderUpdate({ orderToken }, { order: { email, ship_address_attributes, bill_address_attributes }}) + const response = await this.spree.checkout.orderUpdate( + { orderToken }, + { order: { email, ship_address_attributes, bill_address_attributes } } + ); if (response.isFail()) { - this.handleFailure(response) - this.formDisabled = false - return + this.handleFailure(response); + this.formDisabled = false; + return; } - const shippingMethods = await this.shippingMethods(orderToken) + const shippingMethods = await this.shippingMethods(orderToken); if (!shippingMethods) { - this.formDisabled = false - return + this.formDisabled = false; + return; } - const shipping_rates = shippingMethods.included.filter(x => x.type == 'shipping_rate') + const shipping_rates = shippingMethods.included.filter( + (x) => x.type == "shipping_rate" + ); // XXX: No hay varios paquetes - const shipping_method = shippingMethods.data[0] - const site = window.site + const shipping_method = shippingMethods.data[0]; + const site = window.site; - await this.render({ shipping_method, shipping_rates, site }) + await this.render({ shipping_method, shipping_rates, site }); - const nextStep = document.querySelector(`#${this.element.dataset.scrollTo}`) - if (nextStep) nextStep.scrollIntoView() + const nextStep = document.querySelector( + `#${this.element.dataset.scrollTo}` + ); + if (nextStep) nextStep.scrollIntoView(); } - async processShippingRate (formData) { - const rate = this.formDataToObject(formData) - const orderToken = this.token + async processShippingRate(formData) { + const rate = this.formDataToObject(formData); + const orderToken = this.token; // XXX: Deshabilitar el formulario después del evento FormData, de // lo contrario el objeto queda vacío. - this.ratesTarget.elements.forEach(x => x.disabled = true) + this.ratesTarget.elements.forEach((x) => (x.disabled = true)); - const response = await window.spree.checkout.orderUpdate({ orderToken }, { order: { shipments_attributes: [{ ...rate }] } }) + const response = await window.spree.checkout.orderUpdate( + { orderToken }, + { order: { shipments_attributes: [{ ...rate }] } } + ); if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - this.cart = response + this.cart = response; // Continue to next step try { - Turbolinks.visit(this.data.get('next')) + Turbolinks.visit(this.data.get("next")); } catch { - window.location = this.data.get('next') + window.location = this.data.get("next"); } } - async render (data = {}) { - const template = window.templates[this.data.get('template')] + async render(data = {}) { + const template = window.templates[this.data.get("template")]; - this.methodsTarget.innerHTML = await this.engine.parseAndRender(template, data) - this.ratesTarget.addEventListener('formdata', event => this.processShippingRate(event.formData)) + this.methodsTarget.innerHTML = await this.engine.parseAndRender( + template, + data + ); + this.ratesTarget.addEventListener("formdata", (event) => + this.processShippingRate(event.formData) + ); } } diff --git a/_packs/controllers/contact_controller.js b/_packs/controllers/contact_controller.js index 108119d..593d302 100644 --- a/_packs/controllers/contact_controller.js +++ b/_packs/controllers/contact_controller.js @@ -1,42 +1,42 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; /* * Sólo permite enviar el formulario de contacto después de unos * segundos, para evitar el spam. */ export default class extends Controller { - static targets = [ 'submit' ] + static targets = ["submit"]; - connect () { - if (!this.hasSubmitTarget) return + connect() { + if (!this.hasSubmitTarget) return; - this.submitTarget.disabled = true + this.submitTarget.disabled = true; - this._value = this.submitTarget.value + this._value = this.submitTarget.value; // Esperar un minuto desde que se carga la página hasta que se // permite enviar. this._interval = setInterval(() => { - const delay = this.delay + const delay = this.delay; if (this.delay == 0) { - clearInterval(this._interval) - this.submitTarget.disabled = false - this.submitTarget.value = this._value + clearInterval(this._interval); + this.submitTarget.disabled = false; + this.submitTarget.value = this._value; } else { - this.delay = delay - 1 + this.delay = delay - 1; } - }, 1000) + }, 1000); } - get delay () { - const delay = parseInt(this.element.dataset.delay) + get delay() { + const delay = parseInt(this.element.dataset.delay); - return isNaN(delay) ? 0 : delay + return isNaN(delay) ? 0 : delay; } - set delay (value) { - this.element.dataset.delay = value - this.submitTarget.value = `${this._value} (${value})` + set delay(value) { + this.element.dataset.delay = value; + this.submitTarget.value = `${this._value} (${value})`; } } diff --git a/_packs/controllers/country_controller.js b/_packs/controllers/country_controller.js index 6becb09..3b89fff 100644 --- a/_packs/controllers/country_controller.js +++ b/_packs/controllers/country_controller.js @@ -1,4 +1,4 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Populates a country field where users can type to filter and select @@ -6,96 +6,104 @@ import { CartBaseController } from './cart_base_controller' */ export default class extends CartBaseController { // All are required! - static targets = [ 'id', 'iso', 'list', 'name' ] + static targets = ["id", "iso", "list", "name"]; - async connect () { - const countries = await this.countries() + async connect() { + const countries = await this.countries(); - countries.forEach(country => { - const option = document.createElement('option') + countries.forEach((country) => { + const option = document.createElement("option"); - option.value = country.attributes.name - option.dataset.id = country.id - option.dataset.iso = country.attributes.iso - option.dataset.statesRequired = country.attributes.states_required - option.dataset.zipcodeRequired = country.attributes.zipcode_required + option.value = country.attributes.name; + option.dataset.id = country.id; + option.dataset.iso = country.attributes.iso; + option.dataset.statesRequired = country.attributes.states_required; + option.dataset.zipcodeRequired = country.attributes.zipcode_required; - this.listTarget.appendChild(option) - }) + this.listTarget.appendChild(option); + }); - const site = window.site + const site = window.site; // Only allow names on this list - this.nameTarget.pattern = countries.map(x => x.attributes.name).join('|') - this.nameTarget.addEventListener('input', event => this.nameTarget.setCustomValidity('')) - this.nameTarget.addEventListener('invalid', event => this.nameTarget.setCustomValidity(site.i18n.countries.validation)) + this.nameTarget.pattern = countries.map((x) => x.attributes.name).join("|"); + this.nameTarget.addEventListener("input", (event) => + this.nameTarget.setCustomValidity("") + ); + this.nameTarget.addEventListener("invalid", (event) => + this.nameTarget.setCustomValidity(site.i18n.countries.validation) + ); // When the input changes we update the actual value and also the // state list via an Event - this.nameTarget.addEventListener('change', event => { - const value = this.nameTarget.value.trim() + this.nameTarget.addEventListener("change", (event) => { + const value = this.nameTarget.value.trim(); - if (value === '') return + if (value === "") return; - const options = Array.from(this.nameTarget.list.options) - const option = options.find(x => x.value == value) + const options = Array.from(this.nameTarget.list.options); + const option = options.find((x) => x.value == value); // TODO: If no option is found, mark the field as invalid - if (!option) return + if (!option) return; - this.idTarget.value = option.dataset.id - this.isoTarget.value = option.dataset.iso + this.idTarget.value = option.dataset.id; + this.isoTarget.value = option.dataset.iso; - this.idTarget.dispatchEvent(new Event('change')) - this.isoTarget.dispatchEvent(new Event('change')) + this.idTarget.dispatchEvent(new Event("change")); + this.isoTarget.dispatchEvent(new Event("change")); - this.dispatchChangedEvent(option.dataset) + this.dispatchChangedEvent(option.dataset); // XXX: Prevent mixing data - delete this.nameTarget.dataset.selectedState - delete this.nameTarget.dataset.selectedZipcode - }) + delete this.nameTarget.dataset.selectedState; + delete this.nameTarget.dataset.selectedZipcode; + }); // The input is disabled at this point - this.nameTarget.disabled = false + this.nameTarget.disabled = false; // Load data if the input is autocompleted - if (this.nameTarget.value.trim() !== '') this.nameTarget.dispatchEvent(new CustomEvent('change')) + if (this.nameTarget.value.trim() !== "") + this.nameTarget.dispatchEvent(new CustomEvent("change")); } /* * Sends a `cart:country:update` event so other controllers can * subscribe to changes. */ - dispatchChangedEvent (data = {}) { - const event = new CustomEvent('cart:country:update', { + dispatchChangedEvent(data = {}) { + const event = new CustomEvent("cart:country:update", { detail: { id: this.idTarget.value, iso: this.isoTarget.value, - group: this.data.get('group'), + group: this.data.get("group"), selectedState: this.nameTarget.dataset.selectedState, selectedZipcode: this.nameTarget.dataset.selectedZipcode, - data - } - }) + data, + }, + }); - window.dispatchEvent(event) + window.dispatchEvent(event); } /* * Fetch the country list from storage or from API */ - async countries () { - const countries = JSON.parse(this.storageTemp.getItem('countries')) + async countries() { + const countries = JSON.parse(this.storageTemp.getItem("countries")); - if (countries) return countries + if (countries) return countries; - const response = await this.spree.countries.list() + const response = await this.spree.countries.list(); // TODO: Show error message - if (!response.success()) return + if (!response.success()) return; - this.storageTemp.setItem('countries', JSON.stringify(response.success().data)) + this.storageTemp.setItem( + "countries", + JSON.stringify(response.success().data) + ); - return response.success().data + return response.success().data; } } diff --git a/_packs/controllers/floating_alert_controller.js b/_packs/controllers/floating_alert_controller.js index d50317e..7509d26 100644 --- a/_packs/controllers/floating_alert_controller.js +++ b/_packs/controllers/floating_alert_controller.js @@ -1,18 +1,18 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; export default class extends Controller { - static targets = [ 'content' ] + static targets = ["content"]; - connect () { - window.addEventListener('toast', event => { - this.contentTarget.innerText = event.detail.content - this.element.classList.toggle('hide') - this.element.classList.toggle('show') + connect() { + window.addEventListener("toast", (event) => { + this.contentTarget.innerText = event.detail.content; + this.element.classList.toggle("hide"); + this.element.classList.toggle("show"); setTimeout(() => { - this.element.classList.toggle('hide') - this.element.classList.toggle('show') - }, 3000) - }) + this.element.classList.toggle("hide"); + this.element.classList.toggle("show"); + }, 3000); + }); } } diff --git a/_packs/controllers/menu_controller.js b/_packs/controllers/menu_controller.js index 3fe8794..c05585d 100644 --- a/_packs/controllers/menu_controller.js +++ b/_packs/controllers/menu_controller.js @@ -1,29 +1,31 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; export default class extends Controller { - static targets = [ 'item' ] + static targets = ["item"]; - connect () { - window.addEventListener('scroll:section', event => this.update(event.detail.id)) + connect() { + window.addEventListener("scroll:section", (event) => + this.update(event.detail.id) + ); } - get items () { + get items() { if (!this._items) { - this._items = {} + this._items = {}; for (const item of this.itemTargets) { - this._items[item.href.split('#')[1]] = item + this._items[item.href.split("#")[1]] = item; } } - return this._items + return this._items; } - update (id) { + update(id) { for (const item of Object.values(this.items)) { - item.classList.remove('active') + item.classList.remove("active"); } - if (this.items[id]) this.items[id].classList.add('active') + if (this.items[id]) this.items[id].classList.add("active"); } } diff --git a/_packs/controllers/notification_controller.js b/_packs/controllers/notification_controller.js index 4ef5456..9dbff80 100644 --- a/_packs/controllers/notification_controller.js +++ b/_packs/controllers/notification_controller.js @@ -1,43 +1,47 @@ -import { Controller } from 'stimulus' -import { Liquid } from 'liquidjs' +import { Controller } from "stimulus"; +import { Liquid } from "liquidjs"; /* * Waits for notifications and shows them by fetching and rendering * a template. */ export default class extends Controller { - connect () { - window.addEventListener('notification', async event => await this.render(event.detail.template, event.detail.data)) + connect() { + window.addEventListener( + "notification", + async (event) => + await this.render(event.detail.template, event.detail.data) + ); } /* * Renders and replaces notification contents and then shows it. Does * nothing if the template isn't found. */ - async render (name, data = {}) { - data.site = window.site + async render(name, data = {}) { + data.site = window.site; - const template = window.templates.alert - const html = await this.engine.parseAndRender(template, data) + const template = window.templates.alert; + const html = await this.engine.parseAndRender(template, data); - this.element.innerHTML = html - this.show() + this.element.innerHTML = html; + this.show(); } /* * Shows the notification */ - show () { - this.element.classList.add('show') - this.element.classList.remove('hide') + show() { + this.element.classList.add("show"); + this.element.classList.remove("hide"); } /* * Hides the notification */ - hide () { - this.element.classList.add('hide') - this.element.classList.remove('show') + hide() { + this.element.classList.add("hide"); + this.element.classList.remove("show"); } /* @@ -45,9 +49,9 @@ export default class extends Controller { * * @return Liquid */ - get engine () { - if (!window.liquid) window.liquid = new Liquid() + get engine() { + if (!window.liquid) window.liquid = new Liquid(); - return window.liquid + return window.liquid; } } diff --git a/_packs/controllers/order_controller.js b/_packs/controllers/order_controller.js index 08b7c50..7bedf71 100644 --- a/_packs/controllers/order_controller.js +++ b/_packs/controllers/order_controller.js @@ -1,4 +1,4 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Renders the order table. All products are stored on localStorage, so @@ -6,46 +6,48 @@ import { CartBaseController } from './cart_base_controller' * Liquid. */ export default class extends CartBaseController { - static targets = [ 'cart', 'subtotal', 'itemCount' ] + static targets = ["cart", "subtotal", "itemCount"]; - async connect () { - const products = this.products - const site = window.site + async connect() { + const products = this.products; + const site = window.site; - this.render({ products, site }) - this.subtotalUpdate() - this.itemCountUpdate() - this.subscribe() + this.render({ products, site }); + this.subtotalUpdate(); + this.itemCountUpdate(); + this.subscribe(); } /* * Subscribe to change on the storage to update the cart. */ - subscribe () { - window.addEventListener('storage', async event => { - if (!event.key?.startsWith('cart:item:')) return + subscribe() { + window.addEventListener("storage", async (event) => { + if (!event.key?.startsWith("cart:item:")) return; - const products = this.products - const site = window.site + const products = this.products; + const site = window.site; - this.render({ products, site }) - this.subtotalUpdate() - this.itemCountUpdate() - }) + this.render({ products, site }); + this.subtotalUpdate(); + this.itemCountUpdate(); + }); - window.addEventListener('cart:subtotal:update', event => { - this.itemCountUpdate() - this.subtotalUpdate() - }) + window.addEventListener("cart:subtotal:update", (event) => { + this.itemCountUpdate(); + this.subtotalUpdate(); + }); } /* * Download the item template and render the order */ - render (data = {}) { - const template = window.templates[this.data.get('itemTemplate')] + render(data = {}) { + const template = window.templates[this.data.get("itemTemplate")]; - this.engine.parseAndRender(template, data).then(html => this.cartTarget.innerHTML = html) + this.engine + .parseAndRender(template, data) + .then((html) => (this.cartTarget.innerHTML = html)); } /* @@ -53,16 +55,16 @@ export default class extends CartBaseController { * * XXX: This also updates the currency */ - subtotalUpdate () { - if (!this.cart) return + subtotalUpdate() { + if (!this.cart) return; - this.subtotalTarget.innerText = this.cart.data.attributes.display_total + this.subtotalTarget.innerText = this.cart.data.attributes.display_total; } - itemCountUpdate () { - if (!this.hasItemCountTarget) return - if (!this.cart) return + itemCountUpdate() { + if (!this.hasItemCountTarget) return; + if (!this.cart) return; - this.itemCountTarget.innerText = this.cart.data.attributes.item_count + this.itemCountTarget.innerText = this.cart.data.attributes.item_count; } } diff --git a/_packs/controllers/pay_what_you_can_controller.js b/_packs/controllers/pay_what_you_can_controller.js index 9602774..053674e 100644 --- a/_packs/controllers/pay_what_you_can_controller.js +++ b/_packs/controllers/pay_what_you_can_controller.js @@ -1,4 +1,4 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Al pagar lo que podamos, primero hay que crear una orden y luego @@ -7,29 +7,29 @@ import { CartBaseController } from './cart_base_controller' * proceso de pago. */ export default class extends CartBaseController { - static targets = [ 'form' ] + static targets = ["form"]; static values = { variantId: Number, currency: String, price: Number, - firstname: String - } + firstname: String, + }; - connect () { + connect() { this.paymentMethodByCurrency = { - ARS: 'Spree::PaymentMethod::MercadoPago', - USD: 'Spree::PaymentMethod::Paypal' - } + ARS: "Spree::PaymentMethod::MercadoPago", + USD: "Spree::PaymentMethod::Paypal", + }; } - store (event) { - const target = event.currentTarget || event.target + store(event) { + const target = event.currentTarget || event.target; - this[`${target.dataset.name}Value`] = target.value + this[`${target.dataset.name}Value`] = target.value; } - set formDisable (disable) { - this.formTarget.elements.forEach(x => x.disabled = disable) + set formDisable(disable) { + this.formTarget.elements.forEach((x) => (x.disabled = disable)); } /* @@ -45,162 +45,204 @@ export default class extends CartBaseController { * * Reenviar a confirmación * * Ejecutar el pago (si aplica) */ - async pay (event = undefined) { + async pay(event = undefined) { if (event) { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); } if (!this.formTarget.checkValidity()) { - this.formTarget.classList.add('was-validated') - return + this.formTarget.classList.add("was-validated"); + return; } - this.formDisable = true + this.formDisable = true; // Crear pedido. Todos los pedidos van a ser hechos desde // Argentina, no hay forma de cambiar esto. - const orderToken = await this.tempCartCreate() - const quantity = 1 - const include = 'line_items' - const currency = this.currencyValue - const price = this.priceValue - const email = 'noreply@sutty.nl' - const firstname = this.firstnameValue - const lastname = '-' - const address1 = '-' - const country_id = 250 // XXX: Internet - const city = '-' - const phone = '11111111' - const zipcode = '1111' - const ship_address_attributes = { firstname, lastname, address1, city, country_id, zipcode, phone } - const bill_address_attributes = ship_address_attributes - const confirmation_delivered = true - const custom_return_url = this.customReturnUrl() + const orderToken = await this.tempCartCreate(); + const quantity = 1; + const include = "line_items"; + const currency = this.currencyValue; + const price = this.priceValue; + const email = "noreply@sutty.nl"; + const firstname = this.firstnameValue; + const lastname = "-"; + const address1 = "-"; + const country_id = 250; // XXX: Internet + const city = "-"; + const phone = "11111111"; + const zipcode = "1111"; + const ship_address_attributes = { + firstname, + lastname, + address1, + city, + country_id, + zipcode, + phone, + }; + const bill_address_attributes = ship_address_attributes; + const confirmation_delivered = true; + const custom_return_url = this.customReturnUrl(); - let variant_id = this.variantIdValue + let variant_id = this.variantIdValue; // Crear la variante - const payWhatYouCanResponse = await this.spree.sutty.payWhatYouCan({ orderToken }, { variant_id, price, currency, quantity }) + const payWhatYouCanResponse = await this.spree.sutty.payWhatYouCan( + { orderToken }, + { variant_id, price, currency, quantity } + ); - variant_id = payWhatYouCanResponse.data.id + variant_id = payWhatYouCanResponse.data.id; if (!variant_id) { - this.formDisable = false - console.error('No se pudo generar la variante', { variant_id, price, currency, quantity }) - return + this.formDisable = false; + console.error("No se pudo generar la variante", { + variant_id, + price, + currency, + quantity, + }); + return; } // Configurar la moneda del pedido - let response = await this.spree.sutty.updateOrder({ orderToken }, { currency, confirmation_delivered, custom_return_url }) + let response = await this.spree.sutty.updateOrder( + { orderToken }, + { currency, confirmation_delivered, custom_return_url } + ); if (response.status > 299) { - console.error(response) - this.formDisable = false - return + console.error(response); + this.formDisable = false; + return; } // Agregar al carrito - response = await this.spree.cart.addItem({ orderToken }, { variant_id, quantity, include }) + response = await this.spree.cart.addItem( + { orderToken }, + { variant_id, quantity, include } + ); if (response.isFail()) { - this.handleFailure(response) - this.formDisable = false - return + this.handleFailure(response); + this.formDisable = false; + return; } // Actualizar la dirección - response = await this.spree.checkout.orderUpdate({ orderToken }, { order: { email, ship_address_attributes, bill_address_attributes }}) + response = await this.spree.checkout.orderUpdate( + { orderToken }, + { order: { email, ship_address_attributes, bill_address_attributes } } + ); if (response.isFail()) { - this.handleFailure(response) - this.formDisable = false - return + this.handleFailure(response); + this.formDisable = false; + return; } // Obtener los medios de envío - response = await this.spree.checkout.shippingMethods({ orderToken }, { include: 'shipping_rates' }) + response = await this.spree.checkout.shippingMethods( + { orderToken }, + { include: "shipping_rates" } + ); if (response.isFail()) { - this.handleFailure(response) - this.formDisable = false - return + this.handleFailure(response); + this.formDisable = false; + return; } // Elegir medio de envío - response = await this.spree.checkout.orderUpdate({ orderToken }, { - order: { - shipments_attributes: [{ - id: response.success().data[0].id, - selected_shipping_rate_id: response.success().included.filter(x => x.type == 'shipping_rate')[0].id - }] + response = await this.spree.checkout.orderUpdate( + { orderToken }, + { + order: { + shipments_attributes: [ + { + id: response.success().data[0].id, + selected_shipping_rate_id: response + .success() + .included.filter((x) => x.type == "shipping_rate")[0].id, + }, + ], + }, } - }) + ); // Elegir medio de pago - response = await this.spree.checkout.paymentMethods({ orderToken }) + response = await this.spree.checkout.paymentMethods({ orderToken }); if (response.isFail()) { - this.handleFailure(response) - this.formDisable = false - return + this.handleFailure(response); + this.formDisable = false; + return; } - const payment_method_id = response.success().data.find(x => this.paymentMethodByCurrency[this.currencyValue] == x.attributes.type).id + const payment_method_id = response + .success() + .data.find( + (x) => + this.paymentMethodByCurrency[this.currencyValue] == x.attributes.type + ).id; - response = await this.spree.checkout.orderUpdate({ orderToken }, + response = await this.spree.checkout.orderUpdate( + { orderToken }, { order: { payments_attributes: [{ payment_method_id }] }, payment_source: { [payment_method_id]: { - name: 'Pepitx', + name: "Pepitx", month: 12, - year: 2021 - } - } - }) + year: 2021, + }, + }, + } + ); if (response.isFail()) { - this.handleFailure(response) - this.formDisable = false - return + this.handleFailure(response); + this.formDisable = false; + return; } - response = await this.spree.checkout.complete({ orderToken }) + response = await this.spree.checkout.complete({ orderToken }); if (response.isFail()) { - this.handleFailure(response) - this.formDisable = false - return + this.handleFailure(response); + this.formDisable = false; + return; } // Reenviar al medio de pago - const checkoutUrls = await this.spree.sutty.getCheckoutURL({ orderToken }) - const redirectUrl = checkoutUrls.data[0] + const checkoutUrls = await this.spree.sutty.getCheckoutURL({ orderToken }); + const redirectUrl = checkoutUrls.data[0]; - Turbolinks.visit(redirectUrl) + Turbolinks.visit(redirectUrl); // Volver } - async tempCartCreate () { - const response = await this.spree.cart.create() + async tempCartCreate() { + const response = await this.spree.cart.create(); // If we fail here it's probably a server error, so we inform the // user. if (response.isFail()) { - this.handleFailure(response) - return + this.handleFailure(response); + return; } - return response.success().data.attributes.token + return response.success().data.attributes.token; } // @return [String] - customReturnUrl () { - const url = new URL(window.location.href) - url.searchParams.set('open', '') + customReturnUrl() { + const url = new URL(window.location.href); + url.searchParams.set("open", ""); - return url.toString() + return url.toString(); } } diff --git a/_packs/controllers/postal_code_controller.js b/_packs/controllers/postal_code_controller.js index 9a65db5..4e26707 100644 --- a/_packs/controllers/postal_code_controller.js +++ b/_packs/controllers/postal_code_controller.js @@ -1,11 +1,11 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; /* * Subscribes to the country change event and changes the validation * pattern of its input. */ export default class extends Controller { - static targets = [ 'code' ] + static targets = ["code"]; /* * Twitter CLDR is pretty big and we only need the postal codes @@ -13,26 +13,186 @@ export default class extends Controller { * * @see {https://github.com/twitter/twitter-cldr-npm/blob/4388dfc55900b0feb80eafcac030f9f26981a41d/full/core.js#L1999} */ - postal_codes = {"ad":"^AD\\d{3}$","am":"^(37)?\\d{4}$","ar":"^([A-HJ-NP-Z])?\\d{4}([A-Z]{3})?$","as":"^96799$","at":"^\\d{4}$","au":"^\\d{4}$","ax":"^22\\d{3}$","az":"^\\d{4}$","ba":"^\\d{5}$","bb":"^(BB\\d{5})?$","bd":"^\\d{4}$","be":"^\\d{4}$","bg":"^\\d{4}$","bh":"^((1[0-2]|[2-9])\\d{2})?$","bm":"^[A-Z]{2}[ ]?[A-Z0-9]{2}$","bn":"^[A-Z]{2}[ ]?\\d{4}$","br":"^\\d{5}[\\-]?\\d{3}$","by":"^\\d{6}$","ca":"^[ABCEGHJKLMNPRSTVXY]\\d[ABCEGHJ-NPRSTV-Z][ ]?\\d[ABCEGHJ-NPRSTV-Z]\\d$","cc":"^6799$","ch":"^\\d{4}$","ck":"^\\d{4}$","cl":"^\\d{7}$","cn":"^\\d{6}$","cr":"^\\d{4,5}|\\d{3}-\\d{4}$","cs":"^\\d{5}$","cv":"^\\d{4}$","cx":"^6798$","cy":"^\\d{4}$","cz":"^\\d{3}[ ]?\\d{2}$","de":"^\\d{5}$","dk":"^\\d{4}$","do":"^\\d{5}$","dz":"^\\d{5}$","ec":"^([A-Z]\\d{4}[A-Z]|(?:[A-Z]{2})?\\d{6})?$","ee":"^\\d{5}$","eg":"^\\d{5}$","es":"^\\d{5}$","et":"^\\d{4}$","fi":"^\\d{5}$","fk":"^FIQQ 1ZZ$","fm":"^(9694[1-4])([ \\-]\\d{4})?$","fo":"^\\d{3}$","fr":"^\\d{2}[ ]?\\d{3}$","gb":"^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\\d{1,4}$","ge":"^\\d{4}$","gf":"^9[78]3\\d{2}$","gg":"^GY\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$","gl":"^39\\d{2}$","gn":"^\\d{3}$","gp":"^9[78][01]\\d{2}$","gr":"^\\d{3}[ ]?\\d{2}$","gs":"^SIQQ 1ZZ$","gt":"^\\d{5}$","gu":"^969[123]\\d([ \\-]\\d{4})?$","gw":"^\\d{4}$","hm":"^\\d{4}$","hn":"^(?:\\d{5})?$","hr":"^\\d{5}$","ht":"^\\d{4}$","hu":"^\\d{4}$","id":"^\\d{5}$","il":"^\\d{5}$","im":"^IM\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$","in":"^\\d{6}$","io":"^BBND 1ZZ$","iq":"^\\d{5}$","is":"^\\d{3}$","it":"^\\d{5}$","je":"^JE\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$","jo":"^\\d{5}$","jp":"^\\d{3}-\\d{4}$","ke":"^\\d{5}$","kg":"^\\d{6}$","kh":"^\\d{5}$","kr":"^\\d{3}[\\-]\\d{3}$","kw":"^\\d{5}$","kz":"^\\d{6}$","la":"^\\d{5}$","lb":"^(\\d{4}([ ]?\\d{4})?)?$","li":"^(948[5-9])|(949[0-7])$","lk":"^\\d{5}$","lr":"^\\d{4}$","ls":"^\\d{3}$","lt":"^\\d{5}$","lu":"^\\d{4}$","lv":"^\\d{4}$","ma":"^\\d{5}$","mc":"^980\\d{2}$","md":"^\\d{4}$","me":"^8\\d{4}$","mg":"^\\d{3}$","mh":"^969[67]\\d([ \\-]\\d{4})?$","mk":"^\\d{4}$","mn":"^\\d{6}$","mp":"^9695[012]([ \\-]\\d{4})?$","mq":"^9[78]2\\d{2}$","mt":"^[A-Z]{3}[ ]?\\d{2,4}$","mu":"^(\\d{3}[A-Z]{2}\\d{3})?$","mv":"^\\d{5}$","mx":"^\\d{5}$","my":"^\\d{5}$","nc":"^988\\d{2}$","ne":"^\\d{4}$","nf":"^2899$","ng":"^(\\d{6})?$","ni":"^((\\d{4}-)?\\d{3}-\\d{3}(-\\d{1})?)?$","nl":"^\\d{4}[ ]?[A-Z]{2}$","no":"^\\d{4}$","np":"^\\d{5}$","nz":"^\\d{4}$","om":"^(PC )?\\d{3}$","pf":"^987\\d{2}$","pg":"^\\d{3}$","ph":"^\\d{4}$","pk":"^\\d{5}$","pl":"^\\d{2}-\\d{3}$","pm":"^9[78]5\\d{2}$","pn":"^PCRN 1ZZ$","pr":"^00[679]\\d{2}([ \\-]\\d{4})?$","pt":"^\\d{4}([\\-]\\d{3})?$","pw":"^96940$","py":"^\\d{4}$","re":"^9[78]4\\d{2}$","ro":"^\\d{6}$","rs":"^\\d{6}$","ru":"^\\d{6}$","sa":"^\\d{5}$","se":"^\\d{3}[ ]?\\d{2}$","sg":"^\\d{6}$","sh":"^(ASCN|STHL) 1ZZ$","si":"^\\d{4}$","sj":"^\\d{4}$","sk":"^\\d{3}[ ]?\\d{2}$","sm":"^4789\\d$","sn":"^\\d{5}$","so":"^\\d{5}$","sz":"^[HLMS]\\d{3}$","tc":"^TKCA 1ZZ$","th":"^\\d{5}$","tj":"^\\d{6}$","tm":"^\\d{6}$","tn":"^\\d{4}$","tr":"^\\d{5}$","tw":"^\\d{3}(\\d{2})?$","ua":"^\\d{5}$","us":"^\\d{5}([ \\-]\\d{4})?$","uy":"^\\d{5}$","uz":"^\\d{6}$","va":"^00120$","ve":"^\\d{4}$","vi":"^008(([0-4]\\d)|(5[01]))([ \\-]\\d{4})?$","wf":"^986\\d{2}$","xk":"^\\d{5}$","yt":"^976\\d{2}$","yu":"^\\d{5}$","za":"^\\d{4}$","zm":"^\\d{5}$"} + postal_codes = { + ad: "^AD\\d{3}$", + am: "^(37)?\\d{4}$", + ar: "^([A-HJ-NP-Z])?\\d{4}([A-Z]{3})?$", + as: "^96799$", + at: "^\\d{4}$", + au: "^\\d{4}$", + ax: "^22\\d{3}$", + az: "^\\d{4}$", + ba: "^\\d{5}$", + bb: "^(BB\\d{5})?$", + bd: "^\\d{4}$", + be: "^\\d{4}$", + bg: "^\\d{4}$", + bh: "^((1[0-2]|[2-9])\\d{2})?$", + bm: "^[A-Z]{2}[ ]?[A-Z0-9]{2}$", + bn: "^[A-Z]{2}[ ]?\\d{4}$", + br: "^\\d{5}[\\-]?\\d{3}$", + by: "^\\d{6}$", + ca: "^[ABCEGHJKLMNPRSTVXY]\\d[ABCEGHJ-NPRSTV-Z][ ]?\\d[ABCEGHJ-NPRSTV-Z]\\d$", + cc: "^6799$", + ch: "^\\d{4}$", + ck: "^\\d{4}$", + cl: "^\\d{7}$", + cn: "^\\d{6}$", + cr: "^\\d{4,5}|\\d{3}-\\d{4}$", + cs: "^\\d{5}$", + cv: "^\\d{4}$", + cx: "^6798$", + cy: "^\\d{4}$", + cz: "^\\d{3}[ ]?\\d{2}$", + de: "^\\d{5}$", + dk: "^\\d{4}$", + do: "^\\d{5}$", + dz: "^\\d{5}$", + ec: "^([A-Z]\\d{4}[A-Z]|(?:[A-Z]{2})?\\d{6})?$", + ee: "^\\d{5}$", + eg: "^\\d{5}$", + es: "^\\d{5}$", + et: "^\\d{4}$", + fi: "^\\d{5}$", + fk: "^FIQQ 1ZZ$", + fm: "^(9694[1-4])([ \\-]\\d{4})?$", + fo: "^\\d{3}$", + fr: "^\\d{2}[ ]?\\d{3}$", + gb: "^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\\d{1,4}$", + ge: "^\\d{4}$", + gf: "^9[78]3\\d{2}$", + gg: "^GY\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$", + gl: "^39\\d{2}$", + gn: "^\\d{3}$", + gp: "^9[78][01]\\d{2}$", + gr: "^\\d{3}[ ]?\\d{2}$", + gs: "^SIQQ 1ZZ$", + gt: "^\\d{5}$", + gu: "^969[123]\\d([ \\-]\\d{4})?$", + gw: "^\\d{4}$", + hm: "^\\d{4}$", + hn: "^(?:\\d{5})?$", + hr: "^\\d{5}$", + ht: "^\\d{4}$", + hu: "^\\d{4}$", + id: "^\\d{5}$", + il: "^\\d{5}$", + im: "^IM\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$", + in: "^\\d{6}$", + io: "^BBND 1ZZ$", + iq: "^\\d{5}$", + is: "^\\d{3}$", + it: "^\\d{5}$", + je: "^JE\\d[\\dA-Z]?[ ]?\\d[ABD-HJLN-UW-Z]{2}$", + jo: "^\\d{5}$", + jp: "^\\d{3}-\\d{4}$", + ke: "^\\d{5}$", + kg: "^\\d{6}$", + kh: "^\\d{5}$", + kr: "^\\d{3}[\\-]\\d{3}$", + kw: "^\\d{5}$", + kz: "^\\d{6}$", + la: "^\\d{5}$", + lb: "^(\\d{4}([ ]?\\d{4})?)?$", + li: "^(948[5-9])|(949[0-7])$", + lk: "^\\d{5}$", + lr: "^\\d{4}$", + ls: "^\\d{3}$", + lt: "^\\d{5}$", + lu: "^\\d{4}$", + lv: "^\\d{4}$", + ma: "^\\d{5}$", + mc: "^980\\d{2}$", + md: "^\\d{4}$", + me: "^8\\d{4}$", + mg: "^\\d{3}$", + mh: "^969[67]\\d([ \\-]\\d{4})?$", + mk: "^\\d{4}$", + mn: "^\\d{6}$", + mp: "^9695[012]([ \\-]\\d{4})?$", + mq: "^9[78]2\\d{2}$", + mt: "^[A-Z]{3}[ ]?\\d{2,4}$", + mu: "^(\\d{3}[A-Z]{2}\\d{3})?$", + mv: "^\\d{5}$", + mx: "^\\d{5}$", + my: "^\\d{5}$", + nc: "^988\\d{2}$", + ne: "^\\d{4}$", + nf: "^2899$", + ng: "^(\\d{6})?$", + ni: "^((\\d{4}-)?\\d{3}-\\d{3}(-\\d{1})?)?$", + nl: "^\\d{4}[ ]?[A-Z]{2}$", + no: "^\\d{4}$", + np: "^\\d{5}$", + nz: "^\\d{4}$", + om: "^(PC )?\\d{3}$", + pf: "^987\\d{2}$", + pg: "^\\d{3}$", + ph: "^\\d{4}$", + pk: "^\\d{5}$", + pl: "^\\d{2}-\\d{3}$", + pm: "^9[78]5\\d{2}$", + pn: "^PCRN 1ZZ$", + pr: "^00[679]\\d{2}([ \\-]\\d{4})?$", + pt: "^\\d{4}([\\-]\\d{3})?$", + pw: "^96940$", + py: "^\\d{4}$", + re: "^9[78]4\\d{2}$", + ro: "^\\d{6}$", + rs: "^\\d{6}$", + ru: "^\\d{6}$", + sa: "^\\d{5}$", + se: "^\\d{3}[ ]?\\d{2}$", + sg: "^\\d{6}$", + sh: "^(ASCN|STHL) 1ZZ$", + si: "^\\d{4}$", + sj: "^\\d{4}$", + sk: "^\\d{3}[ ]?\\d{2}$", + sm: "^4789\\d$", + sn: "^\\d{5}$", + so: "^\\d{5}$", + sz: "^[HLMS]\\d{3}$", + tc: "^TKCA 1ZZ$", + th: "^\\d{5}$", + tj: "^\\d{6}$", + tm: "^\\d{6}$", + tn: "^\\d{4}$", + tr: "^\\d{5}$", + tw: "^\\d{3}(\\d{2})?$", + ua: "^\\d{5}$", + us: "^\\d{5}([ \\-]\\d{4})?$", + uy: "^\\d{5}$", + uz: "^\\d{6}$", + va: "^00120$", + ve: "^\\d{4}$", + vi: "^008(([0-4]\\d)|(5[01]))([ \\-]\\d{4})?$", + wf: "^986\\d{2}$", + xk: "^\\d{5}$", + yt: "^976\\d{2}$", + yu: "^\\d{5}$", + za: "^\\d{4}$", + zm: "^\\d{5}$", + }; - connect () { - window.addEventListener('cart:country:update', event => { - if (this.data.get('group') !== event.detail.group) return + connect() { + window.addEventListener("cart:country:update", (event) => { + if (this.data.get("group") !== event.detail.group) return; - const zipcodeRequired = event.detail.data.zipcodeRequired == 'true' + const zipcodeRequired = event.detail.data.zipcodeRequired == "true"; - this.codeTarget.value = '' - this.codeTarget.disabled = !zipcodeRequired - this.codeTarget.required = zipcodeRequired + this.codeTarget.value = ""; + this.codeTarget.disabled = !zipcodeRequired; + this.codeTarget.required = zipcodeRequired; - if (!zipcodeRequired) return + if (!zipcodeRequired) return; - this.codeTarget.pattern = this.postal_codes[event.detail.iso.toLowerCase()] || '.*' + this.codeTarget.pattern = + this.postal_codes[event.detail.iso.toLowerCase()] || ".*"; if (event.detail.selectedZipcode) { - this.codeTarget.value = event.detail.selectedZipcode - this.codeTarget.dispatchEvent(new Event('change')) + this.codeTarget.value = event.detail.selectedZipcode; + this.codeTarget.dispatchEvent(new Event("change")); } - }) + }); } } diff --git a/_packs/controllers/scroll_controller.js b/_packs/controllers/scroll_controller.js index e6a6874..9e39831 100644 --- a/_packs/controllers/scroll_controller.js +++ b/_packs/controllers/scroll_controller.js @@ -1,4 +1,4 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; /* * Al navegar por el sitio y llegar a ciertas secciones, se van @@ -8,34 +8,40 @@ import { Controller } from 'stimulus' * a medida que van apareciendo secciones actualizamos el menú. */ export default class extends Controller { - static targets = [ 'section' ] + static targets = ["section"]; - connect () { + connect() { for (const section of this.sectionTargets) { - this.observer.observe(section) + this.observer.observe(section); } } /* * Solo nos interesa la primera */ - get observer () { - if (!this._observer) this._observer = new IntersectionObserver((entries, observer) => this.update(entries), this.options) + get observer() { + if (!this._observer) + this._observer = new IntersectionObserver( + (entries, observer) => this.update(entries), + this.options + ); - return this._observer + return this._observer; } - get options () { - if (!this._options) this._options = { threshold: 0, rootMargin: '0px' } + get options() { + if (!this._options) this._options = { threshold: 0, rootMargin: "0px" }; - return this._options + return this._options; } - update (entries) { - const section = entries.find(x => x.isIntersecting) + update(entries) { + const section = entries.find((x) => x.isIntersecting); - if (!section) return + if (!section) return; - window.dispatchEvent(new CustomEvent('scroll:section', { detail: { id: section.target.id }})) + window.dispatchEvent( + new CustomEvent("scroll:section", { detail: { id: section.target.id } }) + ); } } diff --git a/_packs/controllers/search_controller.js b/_packs/controllers/search_controller.js index 5608ab2..fcc8449 100644 --- a/_packs/controllers/search_controller.js +++ b/_packs/controllers/search_controller.js @@ -1,90 +1,96 @@ -import { Controller } from 'stimulus' -import { Liquid } from 'liquidjs' +import { Controller } from "stimulus"; +import { Liquid } from "liquidjs"; -const lunr = require("lunr") -require("lunr-languages/lunr.stemmer.support")(lunr) -require("lunr-languages/lunr.es")(lunr) +const lunr = require("lunr"); +require("lunr-languages/lunr.stemmer.support")(lunr); +require("lunr-languages/lunr.es")(lunr); export default class extends Controller { - static targets = [ 'q' ] + static targets = ["q"]; - get q () { - if (!this.hasQTarget) return - if (!this.qTarget.value.trim().length === 0) return + get q() { + if (!this.hasQTarget) return; + if (!this.qTarget.value.trim().length === 0) return; - return this.qTarget.value.trim().replaceAll(/[:~\*\^\+\-]/gi, '') + return this.qTarget.value.trim().replaceAll(/[:~\*\^\+\-]/gi, ""); } - connect () { - const q = new URLSearchParams(window.location.search).get('q')?.trim() + connect() { + const q = new URLSearchParams(window.location.search).get("q")?.trim(); if (q) { - this.qTarget.value = q - this.search() + this.qTarget.value = q; + this.search(); } } - async search (event) { + async search(event) { // Detiene el envío del formulario if (event) { - event.preventDefault() - event.stopPropagation() + event.preventDefault(); + event.stopPropagation(); } - this.formDisable = true + this.formDisable = true; // Obtiene el término de búsqueda - const q = this.q + const q = this.q; // Si no hay término de búsqueda, no hay búsqueda if (q) { // Trae el índice de búsqueda - await this.fetch() + await this.fetch(); // Hasta que no haya índice no buscamos nada, esto evita que se // aprete enter dos veces y se fallen cosas. - if (!window.index) return + if (!window.index) return; } - const main = document.querySelector('main') - const results = window.index.search(q).map(r => window.data.find(a => a.id == r.ref)) - const site = window.site - const template = window.templates.results - const html = await this.engine.parseAndRender(template, { q, site, results }) - const title = `${site.i18n.search.title} - ${q}` - const query = new URLSearchParams({ q }) + const main = document.querySelector("main"); + const results = window.index + .search(q) + .map((r) => window.data.find((a) => a.id == r.ref)); + const site = window.site; + const template = window.templates.results; + const html = await this.engine.parseAndRender(template, { + q, + site, + results, + }); + const title = `${site.i18n.search.title} - ${q}`; + const query = new URLSearchParams({ q }); - window.history.pushState({ q }, title, `?${query.toString()}`) - document.title = title + window.history.pushState({ q }, title, `?${query.toString()}`); + document.title = title; - main.innerHTML = html - this.formDisable = false + main.innerHTML = html; + this.formDisable = false; } - async fetch () { + async fetch() { // Solo permite descargar uno a la vez - if (this.fetching) return + if (this.fetching) return; - this.fetching = true - let response + this.fetching = true; + let response; // Si no existe el índice, lo descarga y procesa Lunr if (!window.data) { - response = await fetch('data.json') - window.data = await response.json() + response = await fetch("data.json"); + window.data = await response.json(); } if (!window.index) { - response = await fetch('idx.json') - const idx = await response.json() - window.index = lunr.Index.load(idx) + response = await fetch("idx.json"); + const idx = await response.json(); + window.index = lunr.Index.load(idx); } // Permitir volver a ejecutar - this.fetching = false + this.fetching = false; } - set formDisable (disable) { - this.element.elements.forEach(x => x.disabled = disable) + set formDisable(disable) { + this.element.elements.forEach((x) => (x.disabled = disable)); } /* @@ -92,9 +98,9 @@ export default class extends Controller { * * @return Liquid */ - get engine () { - if (!window.liquid) window.liquid = new Liquid() + get engine() { + if (!window.liquid) window.liquid = new Liquid(); - return window.liquid + return window.liquid; } } diff --git a/_packs/controllers/share_controller.js b/_packs/controllers/share_controller.js index b0d1486..4f45767 100644 --- a/_packs/controllers/share_controller.js +++ b/_packs/controllers/share_controller.js @@ -1,26 +1,26 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; export default class extends Controller { static values = { title: String, text: String, - url: String - } + url: String, + }; - async share (event = undefined) { - event?.preventDefault() - event?.stopPropagation() + async share(event = undefined) { + event?.preventDefault(); + event?.stopPropagation(); - const title = this.titleValue - const text = this.textValue - const url = this.urlValue - const data = { title, text, url } + const title = this.titleValue; + const text = this.textValue; + const url = this.urlValue; + const data = { title, text, url }; - if ('share' in navigator) { + if ("share" in navigator) { if (navigator.canShare(data)) { - navigator.share(data) + navigator.share(data); } else { - console.error('No se puede compartir', data) + console.error("No se puede compartir", data); } } } diff --git a/_packs/controllers/slider_controller.js b/_packs/controllers/slider_controller.js index 60a31c2..6103210 100644 --- a/_packs/controllers/slider_controller.js +++ b/_packs/controllers/slider_controller.js @@ -1,64 +1,73 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; /* * Slider con scroll automático */ export default class extends Controller { - static targets = [ 'control' ] + static targets = ["control"]; - connect () { - this.active(this.controlTargets.find(x => x.href.endsWith(window.location.hash))) + connect() { + this.active( + this.controlTargets.find((x) => x.href.endsWith(window.location.hash)) + ); - this.interval = setInterval(() => this.inViewport ? this.controlTargets[this.next].click() : null, this.duration * 1000) + this.interval = setInterval( + () => (this.inViewport ? this.controlTargets[this.next].click() : null), + this.duration * 1000 + ); } - get duration () { - const duration = parseInt(this.data.get('duration')) + get duration() { + const duration = parseInt(this.data.get("duration")); - return isNaN(duration) ? 15 : duration + return isNaN(duration) ? 15 : duration; } - disconnect () { - clearInterval(this.interval) + disconnect() { + clearInterval(this.interval); } - active (control) { - if (!control) return + active(control) { + if (!control) return; - this.controlTargets.forEach(other => other.classList.toggle('active', control.href === other.href)) - this.current = this.controlTargets.indexOf(control) + this.controlTargets.forEach((other) => + other.classList.toggle("active", control.href === other.href) + ); + this.current = this.controlTargets.indexOf(control); } - activate (event) { + activate(event) { // XXX: En Firefox, el target del evento también puede ser el // contenido del link :/ - let t = (event.target.href) ? event.target : event.target.parentElement + let t = event.target.href ? event.target : event.target.parentElement; - this.active(t) + this.active(t); } - get current () { - return parseInt(this.data.get('current')) || 0 + get current() { + return parseInt(this.data.get("current")) || 0; } - set current (value) { - this.data.set('current', value) + set current(value) { + this.data.set("current", value); } - get next () { - const next = this.current + 1 + get next() { + const next = this.current + 1; - return (this.controlTargets[next]) ? next : 0 + return this.controlTargets[next] ? next : 0; } - get inViewport () { + get inViewport() { const bounding = this.element.getBoundingClientRect(); return ( bounding.top >= 0 && bounding.left >= 0 && - bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - bounding.right <= (window.innerWidth || document.documentElement.clientWidth) + bounding.bottom <= + (window.innerHeight || document.documentElement.clientHeight) && + bounding.right <= + (window.innerWidth || document.documentElement.clientWidth) ); - }; + } } diff --git a/_packs/controllers/state_controller.js b/_packs/controllers/state_controller.js index e84a0e8..25bb5f6 100644 --- a/_packs/controllers/state_controller.js +++ b/_packs/controllers/state_controller.js @@ -1,4 +1,4 @@ -import { CartBaseController } from './cart_base_controller' +import { CartBaseController } from "./cart_base_controller"; /* * Populates a state field where users can type to filter and select @@ -7,85 +7,91 @@ import { CartBaseController } from './cart_base_controller' */ export default class extends CartBaseController { // All are required! - static targets = [ 'id', 'list', 'name' ] + static targets = ["id", "list", "name"]; - connect () { - window.addEventListener('cart:country:update', async event => { - if (this.data.get('group') !== event.detail.group) return + connect() { + window.addEventListener("cart:country:update", async (event) => { + if (this.data.get("group") !== event.detail.group) return; - this.idTarget.value = '' - this.nameTarget.value = '' - this.listTarget.innerHTML = '' + this.idTarget.value = ""; + this.nameTarget.value = ""; + this.listTarget.innerHTML = ""; - const statesRequired = event.detail.data.statesRequired == 'true' + const statesRequired = event.detail.data.statesRequired == "true"; - this.nameTarget.disabled = !statesRequired - this.nameTarget.required = statesRequired + this.nameTarget.disabled = !statesRequired; + this.nameTarget.required = statesRequired; - if (!statesRequired) return + if (!statesRequired) return; - const states = await this.states(event.detail.iso) - const site = window.site + const states = await this.states(event.detail.iso); + const site = window.site; - states.forEach(state => { - let option = document.createElement('option') - option.value = state.attributes.name - option.dataset.id = state.id + states.forEach((state) => { + let option = document.createElement("option"); + option.value = state.attributes.name; + option.dataset.id = state.id; - this.listTarget.appendChild(option) - }) + this.listTarget.appendChild(option); + }); - this.nameTarget.pattern = states.map(x => x.attributes.name).join('|') - this.nameTarget.addEventListener('input', event => this.nameTarget.setCustomValidity('')) - this.nameTarget.addEventListener('invalid', event => this.nameTarget.setCustomValidity(site.i18n.states.validation)) + this.nameTarget.pattern = states.map((x) => x.attributes.name).join("|"); + this.nameTarget.addEventListener("input", (event) => + this.nameTarget.setCustomValidity("") + ); + this.nameTarget.addEventListener("invalid", (event) => + this.nameTarget.setCustomValidity(site.i18n.states.validation) + ); if (event.detail.selectedState) { - this.nameTarget.value = event.detail.selectedState - this.nameTarget.dispatchEvent(new Event('change')) + this.nameTarget.value = event.detail.selectedState; + this.nameTarget.dispatchEvent(new Event("change")); } - }) + }); // When the input changes we update the actual value and also the // state list via an Event - this.nameTarget.addEventListener('change', event => { - const options = Array.from(this.listTarget.options) - const option = options.find(x => x.value == this.nameTarget.value) + this.nameTarget.addEventListener("change", (event) => { + const options = Array.from(this.listTarget.options); + const option = options.find((x) => x.value == this.nameTarget.value); // TODO: If no option is found, mark the field as invalid - if (!option) return + if (!option) return; - this.idTarget.value = option.dataset.id - this.idTarget.dispatchEvent(new Event('change')) - }) + this.idTarget.value = option.dataset.id; + this.idTarget.dispatchEvent(new Event("change")); + }); } /* * Fetch the state list from storage or from API using a country ISO * code */ - async states (countryIso) { - const stateId = `states:${countryIso}` - let states = JSON.parse(this.storageTemp.getItem(stateId)) + async states(countryIso) { + const stateId = `states:${countryIso}`; + let states = JSON.parse(this.storageTemp.getItem(stateId)); - if (states) return states + if (states) return states; // There's no state query, but we can fetch the country and include // its states. - const response = await this.spree.countries.show(countryIso, { include: 'states' }) + const response = await this.spree.countries.show(countryIso, { + include: "states", + }); // TODO: Show error message if (response.isFail()) { - this.handleFailure(response) - return {} + this.handleFailure(response); + return {}; } - states = response.success().included + states = response.success().included; // Order alphabetically by name - states.sort((x, y) => x.attributes.name > y.attributes.name) + states.sort((x, y) => x.attributes.name > y.attributes.name); - this.storageTemp.setItem(stateId, JSON.stringify(states)) + this.storageTemp.setItem(stateId, JSON.stringify(states)); - return states + return states; } } diff --git a/_packs/controllers/stock_controller.js b/_packs/controllers/stock_controller.js index d716913..736a480 100644 --- a/_packs/controllers/stock_controller.js +++ b/_packs/controllers/stock_controller.js @@ -1,4 +1,4 @@ -import { Controller } from 'stimulus' +import { Controller } from "stimulus"; /* * Mantiene el stock actualizado, consultando a la API. @@ -9,48 +9,48 @@ import { Controller } from 'stimulus' * * Deshabilita botón si no está en stock */ export default class extends Controller { - static targets = [ 'product' ] + static targets = ["product"]; - async connect () { - const all_skus = this.skus + async connect() { + const all_skus = this.skus; - if (all_skus.length === 0) return + if (all_skus.length === 0) return; // El paginado es para prevenir que la petición se haga muy grande y // falle entera. - const pages = Math.ceil(all_skus.length / this.per_page) + const pages = Math.ceil(all_skus.length / this.per_page); - let start = 0 - let end = this.per_page + let start = 0; + let end = this.per_page; for (let local_page = 1; local_page <= pages; local_page++) { - const skus = all_skus.slice(start, end).join(',') + const skus = all_skus.slice(start, end).join(","); - start = this.per_page * local_page - end = start + this.per_page + start = this.per_page * local_page; + end = start + this.per_page; - const filter = { skus } - let response = await window.spree.products.list({ filter }) + const filter = { skus }; + let response = await window.spree.products.list({ filter }); if (response.isFail()) { - console.error(response.fail()) - return + console.error(response.fail()); + return; } - this.update_local_products(response.success().data) + this.update_local_products(response.success().data); // Recorrer todas las páginas // XXX: Podríamos usar next pero la página 1 siempre se devuelve a // sí misma y entraríamos en un loop infinito. for (let page = 2; page <= response.success().meta.total_pages; page++) { - response = await window.spree.products.list({ filter, page }) + response = await window.spree.products.list({ filter, page }); if (response.isFail()) { - console.error(response.fail()) - continue + console.error(response.fail()); + continue; } - this.update_local_products(response.success().data) + this.update_local_products(response.success().data); } } } @@ -62,34 +62,56 @@ export default class extends Controller { * * @return [Array] */ - get skus () { - return [...new Set(this.productTargets.map(p=> p.dataset.sku).filter(x => x.length > 0))] + get skus() { + return [ + ...new Set( + this.productTargets + .map((p) => p.dataset.sku) + .filter((x) => x.length > 0) + ), + ]; } /* * La cantidad de productos por página que vamos a pedir */ - get per_page () { + get per_page() { if (!this._per_page) { - this._per_page = parseInt(this.element.dataset.perPage) - if (isNaN(this._per_page)) this._per_page = 100 + this._per_page = parseInt(this.element.dataset.perPage); + if (isNaN(this._per_page)) this._per_page = 100; } - return this._per_page + return this._per_page; } /* * Los productos pueden estar duplicados así que buscamos todos. */ - update_local_products (products) { + update_local_products(products) { for (const local of this.productTargets) { - for (const product of products.filter(p => local.dataset.cartVariantId === p.relationships.default_variant.data.id)) { - local.dataset.cartInStock = product.attributes.in_stock - local.dataset.cartPrice = product.attributes.price + for (const product of products.filter( + (p) => + local.dataset.cartVariantId === + p.relationships.default_variant.data.id + )) { + local.dataset.cartInStock = product.attributes.in_stock; + local.dataset.cartPrice = product.attributes.price; - local.querySelectorAll('[data-stock-add]').forEach(button => button.disabled = !product.attributes.in_stock) - local.querySelectorAll('[data-stock-price]').forEach(price => price.innerText = parseInt(product.attributes.price)) - local.querySelectorAll('[data-stock-currency]').forEach(currency => currency.innerText = product.attributes.currency) + local + .querySelectorAll("[data-stock-add]") + .forEach( + (button) => (button.disabled = !product.attributes.in_stock) + ); + local + .querySelectorAll("[data-stock-price]") + .forEach( + (price) => (price.innerText = parseInt(product.attributes.price)) + ); + local + .querySelectorAll("[data-stock-currency]") + .forEach( + (currency) => (currency.innerText = product.attributes.currency) + ); } } } diff --git a/_packs/endpoints/sutty.js b/_packs/endpoints/sutty.js index 3b9c834..136f96c 100644 --- a/_packs/endpoints/sutty.js +++ b/_packs/endpoints/sutty.js @@ -1,80 +1,81 @@ -import Axios from 'axios' -import * as qs from 'qs' +import Axios from "axios"; +import * as qs from "qs"; /* * XXX: We're copying code from @spree/storefront-api-v2-sdk/src/Http.ts * because we don't know how to mix Typescript :D */ export class Sutty { - constructor (host = 'http://localhost:3000') { - this.host = host + constructor(host = "http://localhost:3000") { + this.host = host; this.axios = Axios.create({ baseURL: this.host, - headers: { 'Content-Type': 'application/json' }, - paramsSerializer: params => qs.stringify(params, { arrayFormat: 'brackets' }) - }) + headers: { "Content-Type": "application/json" }, + paramsSerializer: (params) => + qs.stringify(params, { arrayFormat: "brackets" }), + }); } async getCheckoutURL(tokens = {}) { - const headers = this.spreeOrderHeaders(tokens) + const headers = this.spreeOrderHeaders(tokens); const axiosConfig = { - url: 'api/v2/storefront/checkout_redirect.json', + url: "api/v2/storefront/checkout_redirect.json", params: {}, - method: 'get', - headers - } + method: "get", + headers, + }; - return await this.axios(axiosConfig) + return await this.axios(axiosConfig); } async assignOrderOwnership(tokens = {}, params = {}) { - const headers = this.spreeOrderHeaders(tokens) + const headers = this.spreeOrderHeaders(tokens); const axiosConfig = { - url: 'api/v2/storefront/assign_order_ownership.json', + url: "api/v2/storefront/assign_order_ownership.json", params, - method: 'post', - headers - } + method: "post", + headers, + }; - return await this.axios(axiosConfig) + return await this.axios(axiosConfig); } async assignOrderShippingAddress(tokens = {}, params = {}) { - const headers = this.spreeOrderHeaders(tokens) + const headers = this.spreeOrderHeaders(tokens); const axiosConfig = { - url: 'api/v2/storefront/assign_order_shipping_address.json', + url: "api/v2/storefront/assign_order_shipping_address.json", params, - method: 'post', - headers - } + method: "post", + headers, + }; - return await this.axios(axiosConfig) + return await this.axios(axiosConfig); } async assignOrderBillingAddress(tokens = {}, params = {}) { - const headers = this.spreeOrderHeaders(tokens) + const headers = this.spreeOrderHeaders(tokens); const axiosConfig = { - url: 'api/v2/storefront/assign_order_billing_address.json', + url: "api/v2/storefront/assign_order_billing_address.json", params, - method: 'post', - headers - } + method: "post", + headers, + }; - return await this.axios(axiosConfig) + return await this.axios(axiosConfig); } spreeOrderHeaders(tokens) { - const header = {} + const header = {}; if (tokens.orderToken) { - header['X-Spree-Order-Token'] = tokens.orderToken + header["X-Spree-Order-Token"] = tokens.orderToken; } if (tokens.bearerToken) { - header['Authorization'] = `Bearer ${tokens.bearerToken}` + header["Authorization"] = `Bearer ${tokens.bearerToken}`; } - return header + return header; } } diff --git a/_packs/entry.js b/_packs/entry.js index 514c165..0665332 100644 --- a/_packs/entry.js +++ b/_packs/entry.js @@ -1,25 +1,25 @@ -import BotDetector from 'device-detector-js/dist/parsers/bot' -import { Notifier } from '@airbrake/browser' +import BotDetector from "device-detector-js/dist/parsers/bot"; +import { Notifier } from "@airbrake/browser"; -window.bot_detector = new BotDetector -const bot = window.bot_detector.parse(navigator.userAgent) +window.bot_detector = new BotDetector(); +const bot = window.bot_detector.parse(navigator.userAgent); if (!bot) { window.airbrake = new Notifier({ projectId: window.env.AIRBRAKE_PROJECT_ID, projectKey: window.env.AIRBRAKE_PROJECT_KEY, - host: 'https://panel.sutty.nl' - }) + host: "https://panel.sutty.nl", + }); - console.originalError = console.error + console.originalError = console.error; console.error = (...e) => { - window.airbrake.notify(e.join(' ')) - return console.originalError(...e) - } + window.airbrake.notify(e.join(" ")); + return console.originalError(...e); + }; } -import 'core-js/stable' -import 'regenerator-runtime/runtime' +import "core-js/stable"; +import "regenerator-runtime/runtime"; // Turbo acelera la navegación al no tener que recargar todo el JS y CSS // de la página, con lo que se siente más rápida y "nativa". @@ -27,46 +27,49 @@ import 'regenerator-runtime/runtime' // Cambiamos de turbolinks a turbo porque turbo soporta la función // fetch(), que luego es interceptada por el SW para obtener las // direcciones localmente. -import * as Turbo from "@hotwired/turbo" -Turbo.start() +import * as Turbo from "@hotwired/turbo"; +Turbo.start(); -import { Application } from 'stimulus' -import { definitionsFromContext } from "stimulus/webpack-helpers" +import { Application } from "stimulus"; +import { definitionsFromContext } from "stimulus/webpack-helpers"; -const application = Application.start() -const context = require.context("./controllers", true, /\.js$/) -application.load(definitionsFromContext(context)) +const application = Application.start(); +const context = require.context("./controllers", true, /\.js$/); +application.load(definitionsFromContext(context)); -import { makeClient } from '@spree/storefront-api-v2-sdk' -import { Sutty } from './endpoints/sutty' +import { makeClient } from "@spree/storefront-api-v2-sdk"; +import { Sutty } from "./endpoints/sutty"; -window.spree = makeClient({ host: window.env.SPREE_URL }) -window.spree.sutty = new Sutty(window.spree.host) +window.spree = makeClient({ host: window.env.SPREE_URL }); +window.spree.sutty = new Sutty(window.spree.host); try { - window.axe = require('axe-core/axe') -} catch(e) {} + window.axe = require("axe-core/axe"); +} catch (e) {} -if (window.axe) window.axe.configure({ locale: require('axe-core/locales/es.json') }) +if (window.axe) + window.axe.configure({ locale: require("axe-core/locales/es.json") }); -document.addEventListener('turbo:load', event => { - document.querySelectorAll("a[href^='http://'],a[href^='https://'],a[href^='//']").forEach(a => { - a.rel = "noopener" - a.target = "_blank" - }) +document.addEventListener("turbo:load", (event) => { + document + .querySelectorAll("a[href^='http://'],a[href^='https://'],a[href^='//']") + .forEach((a) => { + a.rel = "noopener"; + a.target = "_blank"; + }); - if (!window.axe) return + if (!window.axe) return; - window.axe.run().then(results => { - results.violations.forEach(violation => { - violation.nodes.forEach(node => { - node.target.forEach(target => { - document.querySelectorAll(target).forEach(element => { - element.classList.add('inaccesible') - element.ariaLabel = node.failureSummary - }) - }) - }) - }) - }) -}) + window.axe.run().then((results) => { + results.violations.forEach((violation) => { + violation.nodes.forEach((node) => { + node.target.forEach((target) => { + document.querySelectorAll(target).forEach((element) => { + element.classList.add("inaccesible"); + element.ariaLabel = node.failureSummary; + }); + }); + }); + }); + }); +}); diff --git a/package.json b/package.json index 85888a8..9ccebe5 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "device-detector-js": "^2.2.10", "dotenv-webpack": "^6.0.0", "liquidjs": "^9.14.0", + "prettier": "^2.4.1", "regenerator-runtime": "^0.13.5", "sassdoc": "^2.7.3", "sassdoc-theme-herman": "^4.0.2", diff --git a/yarn.lock b/yarn.lock index af4b4c9..cffdfb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5161,6 +5161,11 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= +prettier@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" + integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"